{"version":3,"file":"useDragAndDrop.mjs","sources":["../../../../../admin/src/routes/settings/hooks/useDragAndDrop.ts"],"sourcesContent":["import * as React from 'react';\n\nimport {\n  useDrag,\n  useDrop,\n  type HandlerManager,\n  type ConnectDragSource,\n  type ConnectDropTarget,\n  type ConnectDragPreview,\n  type DragSourceMonitor,\n} from 'react-dnd';\n\nimport {\n  useKeyboardDragAndDrop,\n  type UseKeyboardDragAndDropCallbacks,\n} from './useKeyboardDragAndDrop';\n\nimport type { Data } from '@strapi/types';\n\nconst DIRECTIONS = {\n  UPWARD: 'upward',\n  DOWNWARD: 'downward',\n} as const;\n\nconst DROP_SENSITIVITY = {\n  REGULAR: 'regular',\n  IMMEDIATE: 'immediate',\n} as const;\n\ninterface UseDragAndDropOptions<\n  TIndex extends number | Array<number> = number,\n  TItem extends { index: TIndex } = { index: TIndex },\n> extends UseKeyboardDragAndDropCallbacks<TIndex> {\n  type?: string;\n  index: TIndex;\n  item?: TItem;\n  onStart?: () => void;\n  onEnd?: () => void;\n  dropSensitivity?: (typeof DROP_SENSITIVITY)[keyof typeof DROP_SENSITIVITY];\n}\n\ntype Identifier = ReturnType<HandlerManager['getHandlerId']>;\n\ntype UseDragAndDropReturn<E extends Element = HTMLElement> = [\n  props: {\n    handlerId: Identifier;\n    isDragging: boolean;\n    handleKeyDown: <E extends Element>(event: React.KeyboardEvent<E>) => void;\n    isOverDropTarget: boolean;\n    direction: (typeof DIRECTIONS)[keyof typeof DIRECTIONS] | null;\n  },\n  objectRef: React.RefObject<E>,\n  dropRef: ConnectDropTarget,\n  dragRef: ConnectDragSource,\n  dragPreviewRef: ConnectDragPreview,\n];\n\ntype DropCollectedProps = {\n  handlerId: Identifier;\n  isOver: boolean;\n};\n\n/**\n * A utility hook abstracting the general drag and drop hooks from react-dnd.\n * Centralising the same behaviours and by default offering keyboard support.\n */\nconst useDragAndDrop = <\n  TIndex extends number | Array<number>,\n  TItem extends { index: TIndex; id?: Data.ID; [key: string]: unknown } = {\n    index: TIndex;\n    [key: string]: unknown;\n  },\n  E extends Element = HTMLElement,\n>(\n  active: boolean,\n  {\n    type = 'STRAPI_DND',\n    index,\n    item,\n    onStart,\n    onEnd,\n    onGrabItem,\n    onDropItem,\n    onCancel,\n    onMoveItem,\n    dropSensitivity = DROP_SENSITIVITY.REGULAR,\n  }: UseDragAndDropOptions<TIndex, TItem>\n): UseDragAndDropReturn<E> => {\n  const objectRef = React.useRef<E>(null);\n\n  const [{ handlerId, isOver }, dropRef] = useDrop<TItem, void, DropCollectedProps>({\n    accept: type,\n    collect(monitor) {\n      return {\n        handlerId: monitor.getHandlerId(),\n        isOver: monitor.isOver({ shallow: true }),\n      };\n    },\n    drop(item) {\n      const draggedIndex = item.index;\n      const newIndex = index;\n\n      if (isOver && onDropItem) {\n        onDropItem(draggedIndex, newIndex);\n      }\n    },\n    hover(item, monitor) {\n      if (!objectRef.current || !onMoveItem) {\n        return;\n      }\n\n      const dragIndex = item.index;\n      const newIndex = index;\n\n      const hoverBoundingRect = objectRef.current?.getBoundingClientRect();\n      const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;\n      const clientOffset = monitor.getClientOffset();\n      if (!clientOffset) return;\n\n      const hoverClientY = clientOffset && clientOffset.y - hoverBoundingRect.top;\n      if (typeof dragIndex === 'number' && typeof newIndex === 'number') {\n        if (dragIndex === newIndex) {\n          // Don't replace items with themselves\n          return;\n        }\n\n        if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {\n          // Dragging downwards\n          if (dragIndex < newIndex && hoverClientY < hoverMiddleY) {\n            return;\n          }\n\n          // Dragging upwards\n          if (dragIndex > newIndex && hoverClientY > hoverMiddleY) {\n            return;\n          }\n        }\n\n        // Time to actually perform the action\n        onMoveItem(newIndex, dragIndex);\n        item.index = newIndex;\n      } else {\n        // Using numbers as indices doesn't work for nested list items with path like [1, 1, 0]\n        if (Array.isArray(dragIndex) && Array.isArray(newIndex)) {\n          // Indices comparison to find item position in nested list\n          const minLength = Math.min(dragIndex.length, newIndex.length);\n          let areEqual = true;\n          let isLessThan = false;\n          let isGreaterThan = false;\n\n          for (let i = 0; i < minLength; i++) {\n            if (dragIndex[i] < newIndex[i]) {\n              isLessThan = true;\n              areEqual = false;\n              break;\n            } else if (dragIndex[i] > newIndex[i]) {\n              isGreaterThan = true;\n              areEqual = false;\n              break;\n            }\n          }\n\n          // Don't replace items with themselves\n          if (areEqual && dragIndex.length === newIndex.length) {\n            return;\n          }\n\n          if (dropSensitivity === DROP_SENSITIVITY.REGULAR) {\n            // Dragging downwards\n            if (isLessThan && !isGreaterThan && hoverClientY < hoverMiddleY) {\n              return;\n            }\n\n            // Dragging upwards\n            if (isGreaterThan && !isLessThan && hoverClientY > hoverMiddleY) {\n              return;\n            }\n          }\n        }\n\n        onMoveItem(newIndex, dragIndex);\n        item.index = newIndex;\n      }\n    },\n  });\n\n  const getDragDirection = (monitor: DragSourceMonitor<TItem, void>) => {\n    if (\n      monitor &&\n      monitor.isDragging() &&\n      !monitor.didDrop() &&\n      monitor.getInitialClientOffset() &&\n      monitor.getClientOffset()\n    ) {\n      const deltaY = monitor.getInitialClientOffset()!.y - monitor.getClientOffset()!.y;\n\n      if (deltaY > 0) return DIRECTIONS.UPWARD;\n\n      if (deltaY < 0) return DIRECTIONS.DOWNWARD;\n\n      return null;\n    }\n\n    return null;\n  };\n\n  const [{ isDragging, direction }, dragRef, dragPreviewRef] = useDrag({\n    type,\n    item() {\n      if (onStart) {\n        onStart();\n      }\n\n      /**\n       * This will be attached and it helps define the preview sizes\n       * when a component is flexy e.g. Relations\n       */\n      const { width } = objectRef.current?.getBoundingClientRect() ?? {};\n\n      return { index, width, ...item };\n    },\n    end() {\n      if (onEnd) {\n        onEnd();\n      }\n    },\n    canDrag: active,\n    /**\n     * This is useful when the item is in a virtualized list.\n     * However, if we don't have an ID then we want the libraries\n     * defaults to take care of this.\n     */\n    isDragging: item?.id\n      ? (monitor) => {\n          return item.id === monitor.getItem().id;\n        }\n      : undefined,\n    collect: (monitor) => ({\n      isDragging: monitor.isDragging(),\n      initialOffset: monitor.getInitialClientOffset(),\n      currentOffset: monitor.getClientOffset(),\n      direction: getDragDirection(monitor),\n    }),\n  });\n\n  const handleKeyDown = useKeyboardDragAndDrop(active, index, {\n    onGrabItem,\n    onDropItem,\n    onCancel,\n    onMoveItem,\n  });\n\n  return [\n    { handlerId, isDragging, handleKeyDown, isOverDropTarget: isOver, direction },\n    objectRef,\n    dropRef,\n    dragRef,\n    dragPreviewRef,\n  ];\n};\n\nexport {\n  useDragAndDrop,\n  UseDragAndDropReturn,\n  UseDragAndDropOptions,\n  DIRECTIONS,\n  DROP_SENSITIVITY,\n};\n"],"names":["DIRECTIONS","UPWARD","DOWNWARD","DROP_SENSITIVITY","REGULAR","useDragAndDrop","active","type","index","item","onStart","onEnd","onGrabItem","onDropItem","onCancel","onMoveItem","dropSensitivity","objectRef","React","useRef","handlerId","isOver","dropRef","useDrop","accept","collect","monitor","getHandlerId","shallow","drop","draggedIndex","newIndex","hover","current","dragIndex","hoverBoundingRect","getBoundingClientRect","hoverMiddleY","bottom","top","clientOffset","getClientOffset","hoverClientY","y","Array","isArray","minLength","Math","min","length","areEqual","isLessThan","isGreaterThan","i","getDragDirection","isDragging","didDrop","getInitialClientOffset","deltaY","direction","dragRef","dragPreviewRef","useDrag","width","end","canDrag","id","getItem","undefined","initialOffset","currentOffset","handleKeyDown","useKeyboardDragAndDrop","isOverDropTarget"],"mappings":"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"}