diff --git a/docs/docs/core/content-manager/hooks/use-drag-and-drop.mdx b/docs/docs/core/content-manager/hooks/use-drag-and-drop.mdx index e95588de76..a38ae7b7ec 100644 --- a/docs/docs/core/content-manager/hooks/use-drag-and-drop.mdx +++ b/docs/docs/core/content-manager/hooks/use-drag-and-drop.mdx @@ -132,7 +132,16 @@ import { ConnectDropTarget, ConnectDragSource, ConnectDragPreview } from 'react- interface UseDragAndDropOptions { index: number; onMoveItem: (newIndex: number, currentIndex: number) => void; + /** + * @default "regular" + * Defines whether the change in index should be immediately over another + * dropzone or half way over it (regular). + */ + dropSensitivity?: 'immediate' | 'regular'; item?: object; + /** + * @default 'STRAPI_DND' + */ type?: string; onCancel?: (index: number) => void; onDropItem?: (index: number) => void; diff --git a/packages/core/admin/admin/src/content-manager/components/RelationInput/RelationInput.js b/packages/core/admin/admin/src/content-manager/components/RelationInput/RelationInput.js index 2a1b3ca4bd..ff329b1c8d 100644 --- a/packages/core/admin/admin/src/content-manager/components/RelationInput/RelationInput.js +++ b/packages/core/admin/admin/src/content-manager/components/RelationInput/RelationInput.js @@ -352,9 +352,7 @@ const RelationInput = ({ relations, updatePositionOfRelation: handleUpdatePositionOfRelation, }} - itemKey={(index, { relations: relationsItems }) => - `${relationsItems[index].mainField}_${relationsItems[index].id}` - } + itemKey={(index) => `${relations[index].mainField}_${relations[index].id}`} innerElementType="ol" > {ListItem} diff --git a/packages/core/admin/admin/src/content-manager/components/RelationInput/components/RelationItem.js b/packages/core/admin/admin/src/content-manager/components/RelationInput/components/RelationItem.js index 9cf761ddae..64fde5e50e 100644 --- a/packages/core/admin/admin/src/content-manager/components/RelationInput/components/RelationItem.js +++ b/packages/core/admin/admin/src/content-manager/components/RelationInput/components/RelationItem.js @@ -50,11 +50,13 @@ export const RelationItem = ({ item: { displayedValue: displayValue, status, + id, }, onGrabItem, onDropItem, onCancel, onMoveItem: updatePositionOfRelation, + dropSensitivity: 'immediate', }); const composedRefs = composeRefs(relationRef, dragRef); diff --git a/packages/core/admin/admin/src/content-manager/hooks/useDragAndDrop.js b/packages/core/admin/admin/src/content-manager/hooks/useDragAndDrop.js index 28c233af83..d9f1a1aeec 100644 --- a/packages/core/admin/admin/src/content-manager/hooks/useDragAndDrop.js +++ b/packages/core/admin/admin/src/content-manager/hooks/useDragAndDrop.js @@ -12,6 +12,7 @@ import { useKeyboardDragAndDrop } from './useKeyboardDragAndDrop'; * item?: object, * onStart?: () => void, * onEnd?: () => void, + * dropSensitivity?: 'regular' | 'immediate' * } & import('./useKeyboardDragAndDrop').UseKeyboardDragAndDropCallbacks} */ @@ -39,6 +40,7 @@ export const useDragAndDrop = ( onDropItem, onCancel, onMoveItem, + dropSensitivity = 'regular', } ) => { const objectRef = useRef(null); @@ -62,19 +64,21 @@ export const useDragAndDrop = ( return; } - const hoverBoundingRect = objectRef.current.getBoundingClientRect(); - const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; - const clientOffset = monitor.getClientOffset(); - const hoverClientY = clientOffset.y - hoverBoundingRect.top; + if (dropSensitivity === 'regular') { + const hoverBoundingRect = objectRef.current.getBoundingClientRect(); + const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; + const clientOffset = monitor.getClientOffset(); + const hoverClientY = clientOffset.y - hoverBoundingRect.top; - // Dragging downwards - if (dragIndex < newInd && hoverClientY < hoverMiddleY) { - return; - } + // Dragging downwards + if (dragIndex < newInd && hoverClientY < hoverMiddleY) { + return; + } - // Dragging upwards - if (dragIndex > newInd && hoverClientY > hoverMiddleY) { - return; + // Dragging upwards + if (dragIndex > newInd && hoverClientY > hoverMiddleY) { + return; + } } // Time to actually perform the action @@ -104,6 +108,16 @@ export const useDragAndDrop = ( } }, canDrag: active, + /** + * This is for useful when the item is in a virtualized list. + * However, if we don't have an ID then we want the libraries + * defaults to take care of this. + */ + isDragging: item.id + ? (monitor) => { + return item.id === monitor.getItem().id; + } + : undefined, collect: (monitor) => ({ isDragging: monitor.isDragging(), }),