{"version":3,"file":"useRowDrag.mjs","names":[],"sources":["../../../../package/common/virtualList/useRowDrag.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\n\nimport styles from './virtualList.module.pcss';\nimport { resolveReorderTarget, resolveTreeDropTarget, lastDescendantIndex } from './virtualList.utils';\nimport type { TreeDropPosition, TreeDropTarget } from './virtualList.types';\nimport type { ListViewportRect } from './useVirtualWindow';\n\ninterface UseRowDragArgs {\n  reorderable: boolean;\n  treeReorder: boolean;\n  onReorder?: (fromIndex: number, toIndex: number) => void;\n  onTreeDrop?: (dragKey: string | number, target: TreeDropTarget) => void;\n  longPressDelay: number;\n  dragHandle: boolean;\n  treeIndentPx: number;\n  /** Current flat ordering and depth tags (mouse handlers read these directly). */\n  keys: (string | number)[];\n  depths: number[];\n  isGroupAt: (index: number) => boolean;\n  rootRef: React.RefObject<HTMLDivElement | null>;\n  /** Latest keys for async (touch / rAF) consumers — owned by useVirtualWindow. */\n  keysRef: React.RefObject<(string | number)[]>;\n  /** Where the list is on screen, which is not its own box once it rides a\n   *  scrollport — owned by useVirtualWindow, as is `scrollBy`. */\n  getVisibleRect: () => ListViewportRect | null;\n  scrollBy: (dy: number) => void;\n}\n\n/** The drag-related props the parent spreads onto a given row. */\nexport interface RowDragProps {\n  reorderable: boolean;\n  /** Native mouse DnD is active for the list (independent of which row is armed). */\n  mouseDragEnabled: boolean;\n  draggable: boolean | undefined;\n  isDragging: boolean;\n  onMouseDown: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n  onMouseOver: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n  onMouseLeave: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n  onDragStart: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n  onDragOver: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n  onDragEnd: (() => void) | undefined;\n  onDrop: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n  onTouchStart: ((e: React.TouchEvent<HTMLDivElement>) => void) | undefined;\n  dropPosition: TreeDropPosition | undefined;\n  dropIndentPx: number | undefined;\n}\n\ninterface UseRowDragResult {\n  /** True while a row is being dragged (for the root reordering style). */\n  draggingKey: string | number | null;\n  /** Whether either drag mode is active. */\n  dragEnabled: boolean;\n  /** Drag props for the row at `index` / `key`. */\n  getRowDragProps: (index: number, key: string | number) => RowDragProps;\n  /** Returns true (and resets) if the next click should be swallowed (post-drag). */\n  consumeSuppressedClick: () => boolean;\n}\n\n/**\n * Row drag-and-drop for both modes:\n * - `reorderable` (flat): native HTML5 drag on desktop; rows move live via\n *   `onReorder` with midpoint hysteresis.\n * - `treeReorder`: a drop indicator (before/after/inside) is shown during the\n *   drag and `onTreeDrop` fires once on release; dropping onto the dragged\n *   node's own subtree is forbidden.\n * Touch uses a long-press → lifted-clone → pointer-move path with edge\n * auto-scroll. `dragHandle` restricts initiation to `[data-drag-handle]`.\n */\nexport function useRowDrag({\n  reorderable,\n  treeReorder,\n  onReorder,\n  onTreeDrop,\n  longPressDelay,\n  dragHandle,\n  treeIndentPx,\n  keys,\n  depths,\n  isGroupAt,\n  rootRef,\n  keysRef,\n  getVisibleRect,\n  scrollBy,\n}: UseRowDragArgs): UseRowDragResult {\n  // The dragged item is tracked by its stable key (indices shift after each\n  // live reorder); the ref drives the logic, the state drives the row's style.\n  const dragKeyRef = useRef<string | number | null>(null);\n  const [draggingKey, setDraggingKey] = useState<string | number | null>(null);\n  // Tree-reorder drop indicator. Unlike flat reorder (which moves rows live),\n  // tree mode shows where the drop will land and commits once on release.\n  const [dropTarget, setDropTarget] = useState<TreeDropTarget | null>(null);\n  const dropTargetRef = useRef<TreeDropTarget | null>(null);\n  const onReorderRef = useRef(onReorder);\n  const onTreeDropRef = useRef(onTreeDrop);\n  const treeModeRef = useRef(treeReorder);\n  const depthsRef = useRef<number[]>(depths);\n  const isGroupAtRef = useRef<(i: number) => boolean>(isGroupAt);\n  // When `dragHandle` is on, a mousedown sets this to whether it landed on a\n  // `[data-drag-handle]` element, gating whether the ensuing dragstart is honoured.\n  const dragFromHandleRef = useRef(true);\n  // In `dragHandle` mode the `draggable` attribute is only on the row whose\n  // handle the pointer is currently over (\"armed\"). A permanently `draggable`\n  // row breaks mouse text selection (caret placement, double-click word select,\n  // drag select) inside any child input in Firefox — see Mozilla bugs 739071 /\n  // 800050 / 1189486. Arming on hover rather than on mousedown means the\n  // attribute is already in place before the press, so the browser never has to\n  // notice it appearing mid-gesture, and any pointer move re-derives it.\n  const armedKeyRef = useRef<string | number | null>(null);\n  const [armedKey, setArmedKeyState] = useState<string | number | null>(null);\n  const longPressRef = useRef<number | null>(null);\n  const touchActiveRef = useRef(false);\n  const touchStartYRef = useRef<number | null>(null);\n  const pointerXRef = useRef(0);\n  const pointerYRef = useRef(0);\n  const autoScrollRef = useRef<number | null>(null);\n  const suppressNextClickRef = useRef(false);\n  // Floating clone that follows the finger during a touch drag.\n  const dragCloneRef = useRef<HTMLElement | null>(null);\n  const grabOffsetYRef = useRef(0);\n  const cloneLeftRef = useRef(0);\n  const dragHeightRef = useRef(0);\n  // The native `draggable` attribute (mouse DnD) makes a long-press start the\n  // browser's own drag on touch devices, which hijacks our touch handlers. So\n  // expose it only where the primary pointer is fine (mouse/trackpad); touch\n  // devices use the touch handlers below instead.\n  const [isCoarsePointer] = useState(() =>\n    typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n      ? window.matchMedia('(pointer: coarse)').matches\n      : false,\n  );\n\n  useLayoutEffect(() => {\n    onReorderRef.current = onReorder;\n    onTreeDropRef.current = onTreeDrop;\n    treeModeRef.current = treeReorder;\n    depthsRef.current = depths;\n    dropTargetRef.current = dropTarget;\n    isGroupAtRef.current = isGroupAt;\n  });\n\n  // ── Mouse / shared start ──────────────────────────────────────────────────\n\n  /** Move the `draggable` attribute to `next` (or off entirely for `null`). */\n  function arm(next: string | number | null) {\n    // Arming exists purely to place the native `draggable` attribute, which is\n    // never set on a coarse pointer (touch uses the handlers below instead). A\n    // tap still synthesises mouseover/mousedown, so without this a touch device\n    // would re-render the list on every handle tap to no effect whatsoever.\n    if (isCoarsePointer) return;\n    if (armedKeyRef.current === next) return; // mouseover fires constantly — no-op\n    armedKeyRef.current = next;\n    setArmedKeyState(next);\n  }\n\n  // Arm while the pointer rests on this row's handle, disarm as it moves off.\n  // `buttons !== 0` means a press is already in progress: the pointer can drift\n  // off the handle before the browser reaches its drag threshold, so hover is\n  // ignored until release rather than disarming a drag that is about to start.\n  function handleRowMouseOver(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n    if (e.buttons !== 0) return;\n    arm((e.target as HTMLElement).closest('[data-drag-handle]') ? key : null);\n  }\n\n  function handleRowMouseLeave(e: React.MouseEvent<HTMLDivElement>) {\n    if (e.buttons !== 0) return;\n    arm(null);\n  }\n\n  // With `dragHandle`, remember on mousedown whether the press landed on a\n  // handle, so the dragstart that follows can be ignored if it didn't. Arming\n  // here too covers a handle that came to sit under an already-stationary cursor\n  // (the list scrolled), which produces no mouseover.\n  function handleRowMouseDown(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n    if (e.button !== 0) return; // only a primary press can begin a drag\n    const fromHandle = !!(e.target as HTMLElement).closest('[data-drag-handle]');\n    dragFromHandleRef.current = fromHandle;\n    if (fromHandle) arm(key);\n  }\n\n  function handleReorderStart(key: string | number, e: React.DragEvent<HTMLDivElement>) {\n    if (dragHandle && !dragFromHandleRef.current) {\n      e.preventDefault(); // not started from a handle — let the row stay put\n      return;\n    }\n    dragKeyRef.current = key;\n    setDraggingKey(key);\n    if (treeReorder) setDropTarget(null);\n  }\n\n  // ── Tree mode ─────────────────────────────────────────────────────────────\n\n  /** Resolve the tree drop target for the row at `overIndex` under pointer `y`. */\n  function computeTreeDrop(overIndex: number, y: number, rect: DOMRect): TreeDropTarget | null {\n    const dragKey = dragKeyRef.current;\n    if (dragKey == null) return null;\n    const fromIndex = keys.indexOf(dragKey);\n    // Forbid dropping onto the dragged node or anything in its own subtree.\n    if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, depths)) {\n      return null;\n    }\n    const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAt(overIndex));\n    return { key: keys[overIndex], position };\n  }\n\n  function handleTreeDragOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n    e.preventDefault(); // allow the drop\n    const rect = e.currentTarget.getBoundingClientRect();\n    const next = computeTreeDrop(overIndex, e.clientY, rect);\n    setDropTarget((prev) => (prev?.key === next?.key && prev?.position === next?.position ? prev : next));\n  }\n\n  function commitTreeDrop() {\n    const dragKey = dragKeyRef.current;\n    const target = dropTargetRef.current;\n    if (dragKey != null && target && target.key !== dragKey) onTreeDrop?.(dragKey, target);\n  }\n\n  function handleTreeDrop(e: React.DragEvent<HTMLDivElement>) {\n    e.preventDefault();\n    commitTreeDrop();\n    setDropTarget(null);\n    dragKeyRef.current = null;\n    setDraggingKey(null);\n    arm(null);\n  }\n\n  function handleTreeDragEnd() {\n    // Fires after `drop` (or on its own when released off a valid target).\n    setDropTarget(null);\n    dragKeyRef.current = null;\n    setDraggingKey(null);\n    arm(null);\n  }\n\n  // ── Flat mode ─────────────────────────────────────────────────────────────\n\n  function handleReorderOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n    e.preventDefault(); // allow the drop\n    const dragKey = dragKeyRef.current;\n    if (dragKey == null) return;\n    const fromIndex = keys.indexOf(dragKey);\n    // Midpoint hysteresis (see resolveReorderTarget): a move only happens once\n    // the pointer crosses the centre of the row it's over. After a swap the\n    // dragged row sits under the cursor, so moving again needs real pointer\n    // travel — this stops the oscillation that made dragging feel jumpy.\n    const rect = e.currentTarget.getBoundingClientRect();\n    const target = resolveReorderTarget(fromIndex, overIndex, e.clientY, rect.top, rect.height);\n    if (target != null) onReorder?.(fromIndex, target);\n  }\n\n  function handleReorderEnd() {\n    dragKeyRef.current = null;\n    setDraggingKey(null);\n    arm(null);\n  }\n\n  // ── Touch reordering (long-press to arm, then drag) ──────────────────────────\n  // These handlers run from window listeners during a touch drag, so they read\n  // mutable state from refs and are stable across renders.\n\n  const reorderAtPoint = useCallback(\n    (x: number) => {\n      const dragKey = dragKeyRef.current;\n      const root = rootRef.current;\n      if (dragKey == null || !root) return;\n      // Reorder against the centre of the lifted clone, not the raw finger — the\n      // finger sits below the clone's top by the grab offset, so using it would\n      // make the top (and bottom) rows unreachable. The clone is what the user\n      // aims with, so match it.\n      const y = dragCloneRef.current\n        ? pointerYRef.current - grabOffsetYRef.current + dragHeightRef.current / 2\n        : pointerYRef.current;\n      const el = document.elementFromPoint(x, y) as HTMLElement | null;\n      const rowEl = el && root.contains(el) ? el.closest<HTMLElement>('[data-index]') : null;\n      if (!rowEl) return;\n      const overIndex = Number(rowEl.dataset.index);\n      if (Number.isNaN(overIndex)) return;\n      const fromIndex = keysRef.current.indexOf(dragKey);\n      const rect = rowEl.getBoundingClientRect();\n      if (treeModeRef.current) {\n        // Tree mode: don't move live — just track where the drop will land.\n        const ks = keysRef.current;\n        const ds = depthsRef.current;\n        if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, ds)) {\n          setDropTarget(null);\n          return;\n        }\n        const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAtRef.current(overIndex));\n        const next: TreeDropTarget = { key: ks[overIndex], position };\n        setDropTarget((prev) => (prev?.key === next.key && prev?.position === next.position ? prev : next));\n        return;\n      }\n      const target = resolveReorderTarget(fromIndex, overIndex, y, rect.top, rect.height);\n      if (target != null) onReorderRef.current?.(fromIndex, target);\n    },\n    [rootRef, keysRef],\n  );\n\n  // Keep the floating clone glued under the finger (same grab point).\n  const positionDragClone = useCallback(() => {\n    const clone = dragCloneRef.current;\n    if (!clone) return;\n    clone.style.transform = `translate(${cloneLeftRef.current}px, ${pointerYRef.current - grabOffsetYRef.current}px)`;\n  }, []);\n\n  // While the finger sits near a top/bottom edge (and within the list's width),\n  // scroll the list and keep reordering against the rows now passing under it.\n  const autoScrollTick = useCallback(() => {\n    const rect = touchActiveRef.current ? getVisibleRect() : null;\n    if (!rect) {\n      autoScrollRef.current = null;\n      return;\n    }\n    const x = pointerXRef.current;\n    const y = pointerYRef.current;\n    const EDGE = 48;\n    let dy = 0;\n    // Only auto-scroll while the finger is actually over the list — moving it\n    // outside (any direction) stops the scroll instead of running away; pinning\n    // the dragged row keeps touch events alive so it resumes when you come back.\n    const inside = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n    if (inside) {\n      if (y < rect.top + EDGE) dy = -Math.min(18, Math.ceil((rect.top + EDGE - y) / 3));\n      else if (y > rect.bottom - EDGE) dy = Math.min(18, Math.ceil((y - (rect.bottom - EDGE)) / 3));\n    }\n    if (dy !== 0) {\n      scrollBy(dy);\n      reorderAtPoint(x);\n    }\n    autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n  }, [reorderAtPoint, getVisibleRect, scrollBy]);\n\n  const endTouchDrag = useCallback(() => {\n    if (longPressRef.current != null) {\n      clearTimeout(longPressRef.current);\n      longPressRef.current = null;\n    }\n    window.removeEventListener('touchmove', handleTouchMove);\n    window.removeEventListener('touchend', endTouchDrag);\n    window.removeEventListener('touchcancel', endTouchDrag);\n    if (autoScrollRef.current != null) {\n      cancelAnimationFrame(autoScrollRef.current);\n      autoScrollRef.current = null;\n    }\n    if (dragCloneRef.current) {\n      dragCloneRef.current.remove();\n      dragCloneRef.current = null;\n    }\n    // Restore native scrolling that was locked for the duration of the drag.\n    document.body.style.touchAction = '';\n    document.body.style.overscrollBehavior = '';\n    if (touchActiveRef.current) {\n      // A real drag happened — swallow the click the browser fires afterwards\n      // so it doesn't, e.g., toggle row selection.\n      suppressNextClickRef.current = true;\n      setTimeout(() => {\n        suppressNextClickRef.current = false;\n      }, 350);\n      // Tree mode commits the pending drop on release (flat mode already moved\n      // rows live during the drag, so there's nothing to commit here).\n      if (treeModeRef.current) {\n        const dk = dragKeyRef.current;\n        const target = dropTargetRef.current;\n        if (dk != null && target && target.key !== dk) onTreeDropRef.current?.(dk, target);\n      }\n    }\n    setDropTarget(null);\n    touchActiveRef.current = false;\n    touchStartYRef.current = null;\n    dragKeyRef.current = null;\n    setDraggingKey(null);\n    // handleTouchMove and endTouchDrag remove each other’s listeners, so neither can list\n    // the other without a cycle.\n    // oxlint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  const handleTouchMove = useCallback(\n    (e: TouchEvent) => {\n      const t = e.touches[0];\n      if (!t) return;\n      pointerXRef.current = t.clientX;\n      pointerYRef.current = t.clientY;\n      if (!touchActiveRef.current) {\n        // Before the long-press fires: if the finger travels, the user means to\n        // scroll, so disarm and let the browser handle it (we don't preventDefault).\n        const sy = touchStartYRef.current;\n        if (sy != null && Math.abs(t.clientY - sy) > 10 && longPressRef.current != null) {\n          clearTimeout(longPressRef.current);\n          longPressRef.current = null;\n        }\n        return;\n      }\n      // Non-passive listener: preventDefault cancels the native scroll for this\n      // gesture — the only reliable way once touch-action has been latched at\n      // touchstart. This is what makes the drag actually move on touch devices.\n      if (e.cancelable) e.preventDefault();\n      positionDragClone();\n      reorderAtPoint(t.clientX);\n    },\n    [reorderAtPoint, positionDragClone],\n  );\n\n  function handleRowTouchStart(key: string | number, e: React.TouchEvent<HTMLDivElement>) {\n    if (!reorderable && !treeReorder) return;\n    // With a drag handle, only a press that starts on it arms the drag, so the\n    // rest of the row stays free for tapping/typing into inputs.\n    if (dragHandle && !(e.target as HTMLElement).closest('[data-drag-handle]')) return;\n    if (longPressRef.current != null || touchActiveRef.current) return; // ignore extra fingers\n    const t = e.touches[0];\n    if (!t) return;\n    touchStartYRef.current = t.clientY;\n    pointerXRef.current = t.clientX;\n    pointerYRef.current = t.clientY;\n    window.addEventListener('touchmove', handleTouchMove, { passive: false });\n    window.addEventListener('touchend', endTouchDrag);\n    window.addEventListener('touchcancel', endTouchDrag);\n    longPressRef.current = window.setTimeout(() => {\n      longPressRef.current = null;\n      touchActiveRef.current = true;\n      dragKeyRef.current = key;\n      setDraggingKey(key);\n      navigator.vibrate?.(10);\n      // Lock native scrolling for the whole gesture — relying on per-move\n      // preventDefault isn't enough once the finger leaves and re-enters the\n      // list (the browser commits to a scroll and ignores it). We do all the\n      // scrolling ourselves via autoScrollTick.\n      document.body.style.touchAction = 'none';\n      document.body.style.overscrollBehavior = 'none';\n      createDragClone(key);\n      if (autoScrollRef.current == null) autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n    }, longPressDelay);\n  }\n\n  // Build a floating copy of the picked-up row that tracks the finger, so the\n  // drag has a visible \"lifted\" element (the original row stays dimmed in place\n  // as a drop placeholder).\n  function createDragClone(key: string | number) {\n    const root = rootRef.current;\n    if (!root) return;\n    const idx = keysRef.current.indexOf(key);\n    const src = root.querySelector<HTMLElement>(`[data-index=\"${idx}\"]`);\n    if (!src) return;\n    const r = src.getBoundingClientRect();\n    grabOffsetYRef.current = pointerYRef.current - r.top;\n    cloneLeftRef.current = r.left;\n    dragHeightRef.current = r.height;\n    const clone = src.cloneNode(true) as HTMLElement;\n    clone.removeAttribute('data-index');\n    clone.setAttribute('data-drag-clone', 'true');\n    clone.setAttribute('aria-hidden', 'true');\n    clone.classList.add(styles.virtualListDragClone);\n    Object.assign(clone.style, {\n      position: 'fixed',\n      left: '0',\n      top: '0',\n      width: `${r.width}px`,\n      height: `${r.height}px`,\n      margin: '0',\n      opacity: '1',\n      pointerEvents: 'none',\n      // Above the sticky header (z-index 2) and any focused row (z-index 1).\n      zIndex: '3',\n      background: 'var(--background)',\n      boxShadow: 'var(--card-shadow)',\n      borderRadius: 'var(--default-border-radius)',\n    } as Partial<CSSStyleDeclaration>);\n    // Appended inside the list so it inherits the active theme's CSS variables;\n    // position:fixed keeps it in viewport coordinates regardless.\n    root.appendChild(clone);\n    dragCloneRef.current = clone;\n    positionDragClone();\n  }\n\n  // Tear down any in-flight touch drag if the component unmounts mid-gesture.\n  useEffect(() => endTouchDrag, [endTouchDrag]);\n\n  // Either drag mode arms the same row gestures; the handlers above branch on\n  // `treeReorder` for the differing target resolution / commit behaviour.\n  const dragEnabled = reorderable || treeReorder;\n  // Native mouse DnD is in play for this list. Row-level fallbacks that must\n  // cover *every* row — swallowing the browser's own drop and context menu —\n  // key off this, not off `draggable`, which in `dragHandle` mode is only ever\n  // on the single armed row.\n  const mouseDragEnabled = dragEnabled && !isCoarsePointer;\n\n  function getRowDragProps(index: number, key: string | number): RowDragProps {\n    // The drop indicator only renders on the row currently targeted. `before`/\n    // `after` lines indent to the target's depth so they sit under where the\n    // dropped content will start; `inside` highlights the whole row instead.\n    const rowDrop = treeReorder && dropTarget?.key === key ? dropTarget.position : undefined;\n    return {\n      // Drives the row-wide grab cursor. With `dragHandle`, only the handle\n      // initiates a drag, so the cursor belongs on the handle (styled by the\n      // consumer), not across the whole row.\n      reorderable: dragEnabled && !dragHandle,\n      mouseDragEnabled,\n      // In `dragHandle` mode the attribute only goes on the row the pointer has\n      // armed, so rows stay text-selectable in Firefox the rest of the time.\n      draggable: (mouseDragEnabled && (!dragHandle || key === armedKey)) || undefined,\n      isDragging: dragEnabled && key === draggingKey,\n      onMouseDown: dragEnabled && dragHandle ? (e) => handleRowMouseDown(key, e) : undefined,\n      onMouseOver: dragEnabled && dragHandle ? (e) => handleRowMouseOver(key, e) : undefined,\n      onMouseLeave: dragEnabled && dragHandle ? handleRowMouseLeave : undefined,\n      onDragStart: dragEnabled ? (e) => handleReorderStart(key, e) : undefined,\n      onDragOver: treeReorder\n        ? (e) => handleTreeDragOver(index, e)\n        : reorderable\n          ? (e) => handleReorderOver(index, e)\n          : undefined,\n      onDragEnd: treeReorder ? handleTreeDragEnd : reorderable ? handleReorderEnd : undefined,\n      onDrop: treeReorder ? handleTreeDrop : undefined,\n      onTouchStart: dragEnabled ? (e) => handleRowTouchStart(key, e) : undefined,\n      dropPosition: rowDrop,\n      dropIndentPx: rowDrop ? (depths[index] ?? 0) * treeIndentPx : undefined,\n    };\n  }\n\n  function consumeSuppressedClick(): boolean {\n    if (suppressNextClickRef.current) {\n      suppressNextClickRef.current = false;\n      return true;\n    }\n    return false;\n  }\n\n  return { draggingKey, dragEnabled, getRowDragProps, consumeSuppressedClick };\n}\n"],"mappings":"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"}