This commit is contained in:
parent
34523e78b1
commit
5c86fd2ceb
19 changed files with 724 additions and 519 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Icon } from "../../../components/Icon.jsx";
|
||||
import { usePointerReorder } from "../../../hooks/usePointerReorder.js";
|
||||
import { ChecklistModule } from "./ChecklistModule.jsx";
|
||||
import { CountersModule } from "./CountersModule.jsx";
|
||||
import { LinksModule } from "./LinksModule.jsx";
|
||||
|
|
@ -174,11 +175,19 @@ export function AddToolControls({ onAdd }) {
|
|||
}
|
||||
|
||||
export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onDelete, onMove }) {
|
||||
const [draggingModuleId, setDraggingModuleId] = useState("");
|
||||
const [dropTarget, setDropTarget] = useState({ id: "", placement: "before" });
|
||||
const [measuredSplitIndex, setMeasuredSplitIndex] = useState(() => Math.ceil(toolbox.modules.length / 2));
|
||||
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
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setMeasuredSplitIndex(Math.ceil(toolbox.modules.length / 2));
|
||||
|
|
@ -219,51 +228,6 @@ export function ToolboxModules({ toolbox, moduleColumns, context, onRename, onDe
|
|||
};
|
||||
}, [moduleColumns, toolbox.id, moduleIdSignature, toolbox.modules.length]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!draggingModuleId) return undefined;
|
||||
|
||||
function getDropTarget(event) {
|
||||
const element = document.elementFromPoint(event.clientX, event.clientY);
|
||||
const target = element?.closest?.(".module");
|
||||
if (!target || target.dataset.toolboxId !== toolbox.id || target.dataset.moduleId === draggingModuleId) {
|
||||
return { id: "", placement: "before" };
|
||||
}
|
||||
const rect = target.getBoundingClientRect();
|
||||
return {
|
||||
id: target.dataset.moduleId,
|
||||
placement: event.clientY > rect.top + rect.height / 2 ? "after" : "before"
|
||||
};
|
||||
}
|
||||
|
||||
function handlePointerMove(event) {
|
||||
setDropTarget(getDropTarget(event));
|
||||
}
|
||||
|
||||
function handlePointerUp(event) {
|
||||
const target = getDropTarget(event);
|
||||
if (target.id) onMove(draggingModuleId, target.id, target.placement);
|
||||
setDraggingModuleId("");
|
||||
setDropTarget({ id: "", placement: "before" });
|
||||
}
|
||||
|
||||
window.addEventListener("pointermove", handlePointerMove);
|
||||
window.addEventListener("pointerup", handlePointerUp, { once: true });
|
||||
window.addEventListener("pointercancel", handlePointerUp, { once: true });
|
||||
return () => {
|
||||
window.removeEventListener("pointermove", handlePointerMove);
|
||||
window.removeEventListener("pointerup", handlePointerUp);
|
||||
window.removeEventListener("pointercancel", handlePointerUp);
|
||||
};
|
||||
}, [draggingModuleId, onMove, toolbox.id]);
|
||||
|
||||
function startModuleDrag(event, moduleId) {
|
||||
if (event.button !== 0) return;
|
||||
event.preventDefault();
|
||||
event.currentTarget.setPointerCapture?.(event.pointerId);
|
||||
setDraggingModuleId(moduleId);
|
||||
setDropTarget({ id: "", placement: "before" });
|
||||
}
|
||||
|
||||
function registerModuleElement(moduleId, element) {
|
||||
if (element) {
|
||||
moduleElementsRef.current.set(moduleId, element);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue