{"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","IMMEDIATE","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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"}