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
|
|
@ -1,7 +1,7 @@
|
|||
// Rôle : fournit l'outil images avec import, collage, libellés et annotation rapide.
|
||||
import { useState } from "react";
|
||||
import { Icon } from "../../../components/Icon.jsx";
|
||||
import { usePointerReorder } from "../../../hooks/usePointerReorder.js";
|
||||
import { moveItem, useGroupedReorder } from "../../../hooks/useGroupedReorder.js";
|
||||
|
||||
export function ImagesModule({ toolboxId, moduleId, context, editing }) {
|
||||
const data = context.getModuleData(toolboxId, moduleId, { images: [] });
|
||||
|
|
@ -9,24 +9,23 @@ export function ImagesModule({ toolboxId, moduleId, context, editing }) {
|
|||
const [dragOver, setDragOver] = useState(false);
|
||||
const pastePlaceholder = textContent.pastePlaceholder || "Coller une image ici";
|
||||
const {
|
||||
draggingId: draggingImageId,
|
||||
dropTarget,
|
||||
startDrag
|
||||
} = usePointerReorder({
|
||||
targetSelector: "[data-image-id]",
|
||||
getTargetId: (target) => target.dataset.imageId,
|
||||
canDropOn: (target) => target.dataset.imageModuleId === moduleId,
|
||||
getPlacement: (event, target) => {
|
||||
const rect = target.getBoundingClientRect();
|
||||
return event.clientX > rect.left + rect.width / 2 ? "after" : "before";
|
||||
itemReorder,
|
||||
getItemProps,
|
||||
isItemDragging,
|
||||
isItemDropTarget,
|
||||
getDropPlacement
|
||||
} = useGroupedReorder({
|
||||
namespace: "images",
|
||||
items: data.images,
|
||||
getItemId: (image) => image.id,
|
||||
getParentId: () => moduleId,
|
||||
orientation: "horizontal",
|
||||
onItemMove: (operation) => {
|
||||
context.setModuleData(toolboxId, moduleId, {
|
||||
images: moveItem(data.images, operation.sourceId, operation.targetId, operation.placement)
|
||||
});
|
||||
},
|
||||
onMove: (draggingId, targetId, placement) => {
|
||||
const nextImages = data.images.filter((image) => image.id !== draggingId);
|
||||
const targetIndex = nextImages.findIndex((image) => image.id === targetId);
|
||||
if (targetIndex === -1) return;
|
||||
nextImages.splice(placement === "after" ? targetIndex + 1 : targetIndex, 0, data.images.find((image) => image.id === draggingId));
|
||||
context.setModuleData(toolboxId, moduleId, { images: nextImages.filter(Boolean) });
|
||||
}
|
||||
hierarchy: { enabled: true, stickyParents: true }
|
||||
});
|
||||
|
||||
async function addFiles(files) {
|
||||
|
|
@ -90,20 +89,18 @@ export function ImagesModule({ toolboxId, moduleId, context, editing }) {
|
|||
)}
|
||||
<div className="images">
|
||||
{data.images.map((image) => {
|
||||
const isDragging = draggingImageId === image.id;
|
||||
const isDropTarget = dropTarget.id === image.id;
|
||||
const className = [
|
||||
isDragging ? "is-dragging" : "",
|
||||
isDropTarget ? "is-drop-target" : "",
|
||||
isDropTarget && dropTarget.placement === "after" ? "drop-after" : ""
|
||||
isItemDragging(image.id) ? "is-dragging" : "",
|
||||
isItemDropTarget(image.id) ? "is-drop-target" : "",
|
||||
getDropPlacement("item", image.id) === "after" ? "drop-after" : ""
|
||||
].filter(Boolean).join(" ");
|
||||
|
||||
return (
|
||||
<figure key={image.id} className={className} data-image-id={image.id} data-image-module-id={moduleId}>
|
||||
<figure key={image.id} className={className} {...getItemProps({ itemId: image.id, parentId: moduleId })}>
|
||||
<button
|
||||
className="image-drag-handle"
|
||||
type="button"
|
||||
onPointerDown={(event) => startDrag(event, image.id)}
|
||||
onPointerDown={(event) => itemReorder.startDrag(event, image.id)}
|
||||
aria-label={textContent.reorderAriaLabel || "Déplacer l'image"}
|
||||
title={textContent.reorderTitle || "Déplacer"}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue