Unify toolbox drag and drop reorder behavior
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
a6d35c6e6b
commit
1879b245fb
17 changed files with 1258 additions and 929 deletions
|
|
@ -3,7 +3,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|||
import { createPortal } from "react-dom";
|
||||
import { CompactDropdown } from "../../../components/CompactDropdown.jsx";
|
||||
import { Icon } from "../../../components/Icon.jsx";
|
||||
import { usePointerReorder } from "../../../hooks/usePointerReorder.js";
|
||||
import { useGroupedReorder } from "../../../hooks/useGroupedReorder.js";
|
||||
import { lockBodyScroll } from "../../../utils/bodyScrollLock.js";
|
||||
import { CalculatorModule } from "./CalculatorModule.jsx";
|
||||
import { ChecklistModule } from "./ChecklistModule.jsx";
|
||||
|
|
@ -180,14 +180,18 @@ export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onUp
|
|||
const moduleElementsRef = useRef(new Map());
|
||||
const moduleIdSignature = useMemo(() => toolbox.modules.map((module) => module.id).join("|"), [toolbox.modules]);
|
||||
const {
|
||||
draggingId: draggingModuleId,
|
||||
dropTarget,
|
||||
startDrag: startModuleDrag
|
||||
} = usePointerReorder({
|
||||
targetSelector: ".module",
|
||||
getTargetId: (target) => target.dataset.moduleId,
|
||||
canDropOn: (target) => target.dataset.toolboxId === toolbox.id,
|
||||
onMove
|
||||
itemReorder,
|
||||
getItemProps,
|
||||
isItemDragging,
|
||||
isItemDropTarget,
|
||||
getDropPlacement
|
||||
} = useGroupedReorder({
|
||||
namespace: "toolbox-modules",
|
||||
items: toolbox.modules,
|
||||
getItemId: (module) => module.id,
|
||||
getParentId: () => toolbox.id,
|
||||
onItemMove: (operation) => onMove(operation.sourceId, operation.targetId, operation.placement),
|
||||
hierarchy: { enabled: true, stickyParents: true }
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -246,9 +250,7 @@ export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onUp
|
|||
toolbox={toolbox}
|
||||
module={module}
|
||||
context={context}
|
||||
draggingModuleId={draggingModuleId}
|
||||
dropTarget={dropTarget}
|
||||
onDragStart={startModuleDrag}
|
||||
reorder={{ itemReorder, getItemProps, isItemDragging, isItemDropTarget, getDropPlacement }}
|
||||
onRename={onRename}
|
||||
onUpdateModule={onUpdateModule}
|
||||
onDelete={onDelete}
|
||||
|
|
@ -273,9 +275,7 @@ export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onUp
|
|||
toolbox={toolbox}
|
||||
module={module}
|
||||
context={context}
|
||||
draggingModuleId={draggingModuleId}
|
||||
dropTarget={dropTarget}
|
||||
onDragStart={startModuleDrag}
|
||||
reorder={{ itemReorder, getItemProps, isItemDragging, isItemDropTarget, getDropPlacement }}
|
||||
onRename={onRename}
|
||||
onUpdateModule={onUpdateModule}
|
||||
onDelete={onDelete}
|
||||
|
|
@ -289,27 +289,24 @@ export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onUp
|
|||
);
|
||||
}
|
||||
|
||||
function ModuleShell({ toolbox, module, context, draggingModuleId, dropTarget, onDragStart, onRename, onUpdateModule, onDelete, registerModuleElement }) {
|
||||
function ModuleShell({ toolbox, module, context, reorder, onRename, onUpdateModule, onDelete, registerModuleElement }) {
|
||||
const definition = MODULE_COMPONENTS[module.type] || MODULE_COMPONENTS.notepad;
|
||||
const Component = definition.Component;
|
||||
const label = definition.label || module.type;
|
||||
const [editing, setEditing] = useState(false);
|
||||
const scrollable = definition.scrollable && module.scrollable === true;
|
||||
const isDragging = draggingModuleId === module.id;
|
||||
const isDropTarget = dropTarget.id === module.id;
|
||||
const className = [
|
||||
"module",
|
||||
isDragging ? "is-dragging" : "",
|
||||
isDropTarget ? "is-drop-target" : "",
|
||||
isDropTarget && dropTarget.placement === "after" ? "drop-after" : "",
|
||||
reorder.isItemDragging(module.id) ? "is-dragging" : "",
|
||||
reorder.isItemDropTarget(module.id) ? "is-drop-target" : "",
|
||||
reorder.getDropPlacement("item", module.id) === "after" ? "drop-after" : "",
|
||||
scrollable ? "is-scrollable" : ""
|
||||
].filter(Boolean).join(" ");
|
||||
|
||||
return (
|
||||
<article
|
||||
className={className}
|
||||
data-toolbox-id={toolbox.id}
|
||||
data-module-id={module.id}
|
||||
{...reorder.getItemProps({ itemId: module.id, parentId: toolbox.id })}
|
||||
ref={(element) => registerModuleElement?.(module.id, element)}
|
||||
>
|
||||
<header>
|
||||
|
|
@ -317,7 +314,7 @@ function ModuleShell({ toolbox, module, context, draggingModuleId, dropTarget, o
|
|||
<button
|
||||
className="module-drag-handle"
|
||||
type="button"
|
||||
onPointerDown={(event) => onDragStart(event, module.id)}
|
||||
onPointerDown={(event) => reorder.itemReorder.startDrag(event, module.id)}
|
||||
aria-label={`Déplacer ${module.title || label}`}
|
||||
title="Déplacer"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue