UNPKG

@react-querybuilder/dnd

Version:

Drag-and-drop-enabled version of react-querybuilder (DnD-library-agnostic)

1 lines 37.4 kB
{"version":3,"file":"dnd-kit-D5Ge4yu_.mjs","names":[],"sources":["../src/adapters/dnd-kit.tsx"],"sourcesContent":["import type {\n DndContext as DndContextImport,\n KeyboardSensor as KeyboardSensorImport,\n PointerSensor as PointerSensorImport,\n useDraggable as useDraggableImport,\n useDroppable as useDroppableImport,\n useSensor as useSensorImport,\n useSensors as useSensorsImport,\n} from '@dnd-kit/core';\nimport * as React from 'react';\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type {\n DndDropTargetType,\n DraggedItem,\n Path,\n RuleGroupTypeAny,\n RuleType,\n Schema,\n} from 'react-querybuilder';\nimport type {\n AdapterUseInlineCombinatorDnDResult,\n AdapterUseRuleDnDResult,\n AdapterUseRuleGroupDnDResult,\n DndAdapter,\n DndAdapterInlineCombinatorDnDParams,\n DndAdapterProviderProps,\n DndAdapterRuleDnDParams,\n DndAdapterRuleGroupDnDParams,\n} from '../adapter';\nimport {\n buildDropResult,\n canDropOnInlineCombinator,\n canDropOnRule,\n canDropOnRuleGroup,\n getDragItem,\n handleDrop,\n} from '../dndLogic';\nimport { DragPreviewContext } from '../DragPreviewContext';\nimport type { DragPreviewContextValue } from '../DragPreviewContext';\nimport { isHotkeyPressed } from '../isHotkeyPressed';\nimport { computeShadowQuery } from '../shadowQuery';\nimport type { DragPreviewState, OnDragMoveCallback } from '../types';\n\n/**\n * The `@dnd-kit/core` exports needed by the adapter.\n *\n * @group DnD\n */\nexport type DndKitExports = {\n DndContext: typeof DndContextImport;\n useDraggable: typeof useDraggableImport;\n useDroppable: typeof useDroppableImport;\n PointerSensor: typeof PointerSensorImport;\n KeyboardSensor: typeof KeyboardSensorImport;\n useSensor: typeof useSensorImport;\n useSensors: typeof useSensorsImport;\n};\n\n// #region Internal context\n\ninterface DndKitDragState {\n activeDragItem: DraggedItem | null;\n timerCopyMode: boolean;\n timerGroupMode: boolean;\n}\n\nconst defaultDragState: DndKitDragState = {\n activeDragItem: null,\n timerCopyMode: false,\n timerGroupMode: false,\n};\nconst DragStateContext = createContext(defaultDragState);\n\n// #endregion\n\n// #region Helpers\n\nconst getDragId = (type: DndDropTargetType, path: number[], qbId: string): string =>\n `drag-${type}-${qbId}-${path.join('_')}`;\n\nconst getDropId = (\n type: DndDropTargetType | 'inlineCombinator',\n path: number[],\n qbId: string\n): string => `drop-${type}-${qbId}-${path.join('_')}`;\n\n/**\n * Attaches dnd-kit's React synthetic event listeners (e.g. `onPointerDown`)\n * as native DOM event listeners on the given node. This bridges the gap\n * between the ref-based adapter interface and dnd-kit's listener-based API.\n */\nconst useNativeListeners = (\n nodeRef: React.RefObject<HTMLElement | null>,\n listeners: Record<string, Function> | undefined\n): void => {\n useEffect(() => {\n const node = nodeRef.current;\n if (!node || !listeners) return undefined;\n\n const nativeHandlers: [string, EventListener][] = [];\n\n for (const [reactEventName, handler] of Object.entries(listeners)) {\n const nativeEventName = reactEventName.slice(2).toLowerCase();\n const nativeHandler: EventListener = e => {\n // Need to make sure the instance type stays the same, so add property\n // instead of create new event with nativeEvent property\n (e as Event & { nativeEvent: Event }).nativeEvent = e;\n return handler(e);\n };\n node.addEventListener(nativeEventName, nativeHandler);\n nativeHandlers.push([nativeEventName, nativeHandler]);\n }\n\n return () => {\n for (const [name, handler] of nativeHandlers) {\n node.removeEventListener(name, handler);\n }\n };\n }, [nodeRef, listeners]);\n};\n\n// #endregion\n\n/**\n * Creates a {@link DndAdapter} backed by `@dnd-kit/core`.\n *\n * The adapter uses `setActivatorNodeRef` for drag handles, so sensor listeners\n * are automatically attached to the correct element without imperative DOM\n * manipulation.\n *\n * @example\n * ```tsx\n * import { QueryBuilderDnD } from '@react-querybuilder/dnd';\n * import { createDndKitAdapter } from '@react-querybuilder/dnd/dnd-kit';\n * import * as DndKit from '@dnd-kit/core';\n *\n * const adapter = createDndKitAdapter(DndKit);\n *\n * <QueryBuilderDnD dnd={adapter}>\n * <QueryBuilder />\n * </QueryBuilderDnD>\n * ```\n *\n * @group DnD\n */\nexport const createDndKitAdapter = (dndKitExports: DndKitExports): DndAdapter => {\n const {\n DndContext,\n useDraggable,\n useDroppable,\n PointerSensor,\n KeyboardSensor,\n useSensor,\n useSensors,\n } = dndKitExports;\n\n // #region DndProvider\n\n const DndProvider = ({\n children,\n updateWhileDragging,\n copyModeAfterHoverMs,\n groupModeAfterHoverMs,\n }: DndAdapterProviderProps): React.JSX.Element => {\n const [activeDragItem, setActiveDragItem] = useState<DraggedItem | null>(null);\n const activeDragItemRef = useRef<DraggedItem | null>(null);\n // oxlint-disable-next-line typescript/no-explicit-any\n const dragSchemaRef = useRef<Schema<any, any> | null>(null);\n\n // --- Hover timer state ---\n const [timerCopyMode, setTimerCopyMode] = useState(false);\n const [timerGroupMode, setTimerGroupMode] = useState(false);\n const timerCopyModeRef = useRef(false);\n const timerGroupModeRef = useRef(false);\n const copyTimerIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const groupTimerIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastHoverTargetIdRef = useRef<string | null>(null);\n\n const clearHoverTimers = useCallback(() => {\n if (copyTimerIdRef.current !== null) {\n clearTimeout(copyTimerIdRef.current);\n copyTimerIdRef.current = null;\n }\n if (groupTimerIdRef.current !== null) {\n clearTimeout(groupTimerIdRef.current);\n groupTimerIdRef.current = null;\n }\n timerCopyModeRef.current = false;\n timerGroupModeRef.current = false;\n setTimerCopyMode(false);\n setTimerGroupMode(false);\n lastHoverTargetIdRef.current = null;\n }, []);\n\n const startHoverTimers = useCallback(\n (targetId: string) => {\n if (lastHoverTargetIdRef.current === targetId) return;\n\n clearHoverTimers();\n lastHoverTargetIdRef.current = targetId;\n\n if (copyModeAfterHoverMs && copyModeAfterHoverMs > 0) {\n copyTimerIdRef.current = setTimeout(() => {\n timerCopyModeRef.current = true;\n setTimerCopyMode(true);\n copyTimerIdRef.current = null;\n }, copyModeAfterHoverMs);\n }\n if (groupModeAfterHoverMs && groupModeAfterHoverMs > 0) {\n groupTimerIdRef.current = setTimeout(() => {\n timerGroupModeRef.current = true;\n setTimerGroupMode(true);\n groupTimerIdRef.current = null;\n }, groupModeAfterHoverMs);\n }\n },\n [clearHoverTimers, copyModeAfterHoverMs, groupModeAfterHoverMs]\n );\n\n // --- Update-while-dragging state ---\n const [dragPreviewState, setDragPreviewState] = useState<DragPreviewState | null>(null);\n const dragPreviewStateRef = useRef<DragPreviewState | null>(null);\n const onDragMoveRef = useRef<OnDragMoveCallback | undefined>(undefined);\n const lastTargetRef = useRef<{\n targetPath: Path;\n targetType: DndDropTargetType;\n quadrant: 'upper' | 'lower';\n } | null>(null);\n\n const updatePreviewPosition = useCallback(\n (targetPath: Path, targetType: DndDropTargetType, quadrant: 'upper' | 'lower') => {\n const currentPreview = dragPreviewStateRef.current;\n // v8 ignore next\n if (!currentPreview || !updateWhileDragging) return;\n\n const last = lastTargetRef.current;\n if (\n last &&\n last.quadrant === quadrant &&\n last.targetType === targetType &&\n last.targetPath.length === targetPath.length &&\n last.targetPath.every((v, i) => v === targetPath[i])\n ) {\n return;\n }\n lastTargetRef.current = { targetPath, targetType, quadrant };\n\n // v8 ignore next -- hotkey branch tested in hotkey-specific tests\n const dropEffect =\n timerCopyModeRef.current ||\n isHotkeyPressed(currentPreview.dropEffect === 'copy' ? 'alt' : '')\n ? 'copy'\n : 'move';\n const groupItems = timerGroupModeRef.current || isHotkeyPressed('ctrl');\n\n const result = computeShadowQuery({\n originalQuery: currentPreview.originalQuery,\n draggedItem: activeDragItemRef.current!,\n draggedPath: currentPreview.draggedPath,\n targetPath,\n targetType,\n quadrant,\n dropEffect,\n groupItems,\n });\n\n if (result) {\n const newState: DragPreviewState = {\n ...currentPreview,\n shadowQuery: result.shadowQuery,\n previewPath: result.previewPath,\n dropEffect,\n groupItems,\n };\n dragPreviewStateRef.current = newState;\n setDragPreviewState(newState);\n\n onDragMoveRef.current?.({\n draggedItem: activeDragItemRef.current!,\n shadowQuery: result.shadowQuery,\n originalQuery: currentPreview.originalQuery,\n previewPath: result.previewPath,\n });\n }\n },\n [updateWhileDragging]\n );\n\n const commitDrag = useCallback(() => {\n const preview = dragPreviewStateRef.current;\n // v8 ignore next\n if (!preview) return;\n\n const schema = dragSchemaRef.current;\n if (schema && preview.shadowQuery !== preview.originalQuery) {\n schema.dispatchQuery(preview.shadowQuery);\n }\n\n dragSchemaRef.current = null;\n dragPreviewStateRef.current = null;\n lastTargetRef.current = null;\n setDragPreviewState(null);\n }, []);\n\n const cancelDrag = useCallback(() => {\n dragSchemaRef.current = null;\n dragPreviewStateRef.current = null;\n lastTargetRef.current = null;\n setDragPreviewState(null);\n }, []);\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor)\n );\n\n const handleDragStart = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (event: any) => {\n const data = event.active?.data?.current;\n if (data?.path && data?.schema) {\n const item = getDragItem(data.path, data.schema);\n activeDragItemRef.current = item;\n setActiveDragItem(item);\n\n if (updateWhileDragging) {\n dragSchemaRef.current = data.schema;\n const originalQuery = data.schema.getQuery();\n const initialState: DragPreviewState = {\n shadowQuery: originalQuery,\n originalQuery,\n draggedPath: data.path as Path,\n previewPath: data.path as Path,\n dropEffect: 'move',\n groupItems: false,\n qbId: data.schema.qbId,\n };\n dragPreviewStateRef.current = initialState;\n setDragPreviewState(initialState);\n }\n }\n },\n [updateWhileDragging]\n );\n\n // Handle continuous drag movement for updateWhileDragging\n const handleDragOver = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (event: any) => {\n const { over } = event;\n\n // Manage hover timers for copy/group mode\n if (over) {\n const targetData = over.data?.current;\n const targetType = targetData?.type as DndDropTargetType | undefined;\n const targetPath = targetData?.path as Path | undefined;\n if (targetType && targetPath) {\n const targetId = `${targetType}-${targetPath.join('_')}`;\n startHoverTimers(targetId);\n }\n } else {\n clearHoverTimers();\n }\n\n // v8 ignore next\n if (!updateWhileDragging || !dragPreviewStateRef.current) return;\n\n if (!over) return;\n\n const { activatorEvent, delta } = event;\n const targetData = over.data?.current;\n const targetType = targetData?.type as DndDropTargetType | undefined;\n const targetPath = targetData?.path as Path | undefined;\n\n if (!targetType || !targetPath) return;\n\n // Compute current clientY from activator event + delta\n // v8 ignore next -- activatorEvent and delta always provided by dnd-kit\n const initialY = (activatorEvent as PointerEvent | undefined)?.clientY ?? 0;\n // v8 ignore next\n const clientY = initialY + (delta?.y ?? 0);\n\n // For rule groups, always use 'upper' (insert as first child).\n // For rules, use quadrant detection on the droppable's rect.\n let quadrant: 'upper' | 'lower' | null;\n if (targetType === 'ruleGroup') {\n quadrant = 'upper';\n } else {\n // over.rect is the droppable container's bounding rect from dnd-kit\n const rect = over.rect;\n if (rect) {\n // v8 ignore next -- rect always has height from dnd-kit\n const height = rect.height ?? rect.bottom - rect.top;\n const quarterHeight = height / 4;\n // v8 ignore next -- rect always has top from dnd-kit\n const top = rect.top ?? rect.offsetTop ?? 0;\n const bottom = top + height;\n if (clientY < top + quarterHeight) {\n quadrant = 'upper';\n } else if (clientY > bottom - quarterHeight) {\n quadrant = 'lower';\n } else {\n quadrant = null;\n }\n } else {\n quadrant = null;\n }\n }\n\n if (!quadrant) return;\n\n const dragItem = activeDragItemRef.current;\n // v8 ignore next\n if (!dragItem) return;\n\n const validate = targetData?.validate as ((item: DraggedItem) => boolean) | undefined;\n if (validate && !validate(dragItem)) return;\n\n updatePreviewPosition(targetPath, targetType, quadrant);\n },\n [updateWhileDragging, updatePreviewPosition, startHoverTimers, clearHoverTimers]\n );\n\n const handleDragEnd = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (event: any) => {\n const dragItem = activeDragItemRef.current;\n const { over, active } = event;\n\n // Capture timer overrides before clearing\n const copyOverride = timerCopyModeRef.current;\n const groupOverride = timerGroupModeRef.current;\n clearHoverTimers();\n\n if (updateWhileDragging && dragPreviewStateRef.current) {\n if (over) {\n commitDrag();\n } else {\n cancelDrag();\n }\n } else if (over && dragItem) {\n const sourceData = active?.data?.current;\n const targetData = over?.data?.current;\n\n if (sourceData && targetData?.validate?.(dragItem)) {\n const dropResult = targetData.getDropResult();\n handleDrop({\n item: dragItem,\n dropResult,\n schema: sourceData.schema,\n actions: sourceData.actions,\n copyModeModifierKey: sourceData.copyModeModifierKey,\n groupModeModifierKey: sourceData.groupModeModifierKey,\n copyModeOverride: copyOverride,\n groupModeOverride: groupOverride,\n onRuleDrop: sourceData.onRuleDrop,\n });\n }\n }\n\n activeDragItemRef.current = null;\n setActiveDragItem(null);\n },\n [updateWhileDragging, commitDrag, cancelDrag, clearHoverTimers]\n );\n\n const handleDragCancel = useCallback(() => {\n clearHoverTimers();\n if (updateWhileDragging && dragPreviewStateRef.current) {\n cancelDrag();\n }\n activeDragItemRef.current = null;\n setActiveDragItem(null);\n }, [updateWhileDragging, cancelDrag, clearHoverTimers]);\n\n const dragStateValue = useMemo<DndKitDragState>(\n () => ({ activeDragItem, timerCopyMode, timerGroupMode }),\n [activeDragItem, timerCopyMode, timerGroupMode]\n );\n\n const dragPreviewContextValue = useMemo<DragPreviewContextValue>(\n () => ({\n dragPreviewState,\n updatePreviewPosition,\n commitDrag,\n cancelDrag,\n }),\n [dragPreviewState, updatePreviewPosition, commitDrag, cancelDrag]\n );\n\n return (\n <DndContext\n sensors={sensors}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onDragCancel={handleDragCancel}>\n <DragStateContext.Provider value={dragStateValue}>\n <DragPreviewContext.Provider value={dragPreviewContextValue}>\n {children}\n </DragPreviewContext.Provider>\n </DragStateContext.Provider>\n </DndContext>\n );\n };\n\n // #endregion\n\n // #region useRuleDnD\n\n const useRuleDnD = (params: DndAdapterRuleDnDParams): AdapterUseRuleDnDResult => {\n const { activeDragItem, timerCopyMode, timerGroupMode } = useContext(DragStateContext);\n const activatorNodeRef = useRef<HTMLSpanElement>(null);\n const containerNodeRef = useRef<HTMLDivElement>(null);\n\n const dragId = getDragId('rule', params.path, params.schema.qbId);\n const dropId = getDropId('rule', params.path, params.schema.qbId);\n\n const {\n setNodeRef: setDragNodeRef,\n setActivatorNodeRef,\n isDragging,\n listeners,\n attributes,\n } = useDraggable({\n id: dragId,\n disabled: params.disabled,\n data: {\n path: params.path,\n schema: params.schema,\n actions: params.actions,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n onRuleDrop: params.onRuleDrop,\n },\n });\n\n const { setNodeRef: setDropNodeRef, isOver: rawIsOver } = useDroppable({\n id: dropId,\n data: {\n type: 'rule' as DndDropTargetType,\n path: params.path,\n schema: params.schema,\n validate: (dragging: DraggedItem) =>\n canDropOnRule({\n dragging,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n groupModeModifierKey: params.groupModeModifierKey,\n disabled: params.disabled,\n rule: params.rule,\n }),\n getDropResult: () =>\n buildDropResult({\n type: 'rule',\n path: params.path,\n schema: params.schema,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n }),\n },\n });\n\n // Compute validated isOver + dropNotAllowed\n const canDropHere =\n rawIsOver &&\n !!activeDragItem &&\n canDropOnRule({\n dragging: activeDragItem,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n groupModeModifierKey: params.groupModeModifierKey,\n disabled: params.disabled,\n rule: params.rule,\n });\n const isOver = rawIsOver && canDropHere;\n const dropNotAllowed = rawIsOver && !canDropHere;\n\n // Combined container ref: both draggable and droppable\n const dndRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n containerNodeRef.current = node;\n setDragNodeRef(node);\n setDropNodeRef(node);\n },\n [setDragNodeRef, setDropNodeRef]\n );\n\n // Drag handle ref: activator node\n const dragRef: React.RefCallback<HTMLSpanElement> = useCallback(\n (node: HTMLSpanElement | null) => {\n activatorNodeRef.current = node;\n setActivatorNodeRef(node);\n },\n [setActivatorNodeRef]\n );\n\n // Set ARIA attributes on drag handle\n useEffect(() => {\n const node = activatorNodeRef.current;\n if (!node || !attributes) return;\n for (const [key, value] of Object.entries(attributes)) {\n if (value != null) {\n node.setAttribute(key === 'tabIndex' ? 'tabindex' : key, String(value));\n }\n }\n }, [attributes]);\n\n // Attach sensor listeners (e.g. onPointerDown) to the drag handle\n useNativeListeners(activatorNodeRef, listeners);\n\n return {\n isDragging,\n dragMonitorId: dragId,\n isOver,\n dropMonitorId: dropId,\n dndRef,\n dragRef,\n dropEffect: timerCopyMode || isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n groupItems: timerGroupMode || isHotkeyPressed(params.groupModeModifierKey),\n dropNotAllowed,\n };\n };\n\n // #endregion\n\n // #region useRuleGroupDnD\n\n const useRuleGroupDnD = (params: DndAdapterRuleGroupDnDParams): AdapterUseRuleGroupDnDResult => {\n const { activeDragItem, timerCopyMode, timerGroupMode } = useContext(DragStateContext);\n const activatorNodeRef = useRef<HTMLSpanElement>(null);\n\n const dragId = getDragId('ruleGroup', params.path, params.schema.qbId);\n const dropId = getDropId('ruleGroup', params.path, params.schema.qbId);\n\n const isDragDisabled = params.disabled || params.path.length === 0;\n\n const {\n setNodeRef: setDragNodeRef,\n setActivatorNodeRef,\n isDragging,\n listeners,\n attributes,\n } = useDraggable({\n id: dragId,\n disabled: isDragDisabled,\n data: {\n path: params.path,\n schema: params.schema,\n actions: params.actions,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n onRuleDrop: params.onRuleDrop,\n },\n });\n\n const { setNodeRef: setDropNodeRef, isOver: rawIsOver } = useDroppable({\n id: dropId,\n data: {\n type: 'ruleGroup' as DndDropTargetType,\n path: params.path,\n schema: params.schema,\n validate: (dragging: DraggedItem) =>\n canDropOnRuleGroup({\n dragging,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n disabled: params.disabled,\n ruleGroup: params.ruleGroup,\n }),\n getDropResult: () =>\n buildDropResult({\n type: 'ruleGroup',\n path: params.path,\n schema: params.schema,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n }),\n },\n });\n\n // Compute validated isOver + dropNotAllowed\n const canDropHere =\n rawIsOver &&\n !!activeDragItem &&\n canDropOnRuleGroup({\n dragging: activeDragItem,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n disabled: params.disabled,\n ruleGroup: params.ruleGroup,\n });\n const isOver = rawIsOver && canDropHere;\n const dropNotAllowed = rawIsOver && !canDropHere;\n\n // Preview ref: draggable container (for visual measurement)\n const previewRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n setDragNodeRef(node);\n },\n [setDragNodeRef]\n );\n\n // Drop ref: header element\n const dropRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n setDropNodeRef(node);\n },\n [setDropNodeRef]\n );\n\n // Drag handle ref: activator node\n const dragRef: React.RefCallback<HTMLSpanElement> = useCallback(\n (node: HTMLSpanElement | null) => {\n activatorNodeRef.current = node;\n setActivatorNodeRef(node);\n },\n [setActivatorNodeRef]\n );\n\n // Set ARIA attributes on drag handle\n useEffect(() => {\n const node = activatorNodeRef.current;\n if (!node || !attributes || isDragDisabled) return;\n for (const [key, value] of Object.entries(attributes)) {\n if (value != null) {\n node.setAttribute(key === 'tabIndex' ? 'tabindex' : key, String(value));\n }\n }\n }, [attributes, isDragDisabled]);\n\n // Attach sensor listeners (e.g. onPointerDown) to the drag handle\n useNativeListeners(activatorNodeRef, listeners);\n\n return {\n isDragging,\n dragMonitorId: dragId,\n isOver,\n dropMonitorId: dropId,\n previewRef,\n dragRef,\n dropRef,\n dropEffect: timerCopyMode || isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n groupItems: timerGroupMode || isHotkeyPressed(params.groupModeModifierKey),\n dropNotAllowed,\n };\n };\n\n // #endregion\n\n // #region useInlineCombinatorDnD\n\n const useInlineCombinatorDnD = (\n params: DndAdapterInlineCombinatorDnDParams\n ): AdapterUseInlineCombinatorDnDResult => {\n const { activeDragItem, timerCopyMode } = useContext(DragStateContext);\n\n const dropId = getDropId('inlineCombinator', params.path, params.schema.qbId);\n\n // The \"hovering\" item is the rule/group preceding this inline combinator.\n const hoveringItem = (params.rules ??\n /* v8 ignore start -- @preserve */ []) /* v8 ignore stop -- @preserve */[\n params.path.at(-1)! - 1\n ] as RuleType | RuleGroupTypeAny;\n\n const { setNodeRef: setDropNodeRef, isOver: rawIsOver } = useDroppable({\n id: dropId,\n data: {\n type: 'inlineCombinator' as DndDropTargetType,\n path: params.path,\n schema: params.schema,\n validate: (dragging: DraggedItem) =>\n canDropOnInlineCombinator({\n dragging,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n groupModeModifierKey: params.groupModeModifierKey,\n hoveringItem,\n }),\n getDropResult: () =>\n buildDropResult({\n type: 'inlineCombinator',\n path: params.path,\n schema: params.schema,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n }),\n },\n });\n\n // Compute validated isOver + dropNotAllowed\n const canDropHere =\n rawIsOver &&\n !!activeDragItem &&\n canDropOnInlineCombinator({\n dragging: activeDragItem,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n groupModeModifierKey: params.groupModeModifierKey,\n hoveringItem,\n });\n const isOver = rawIsOver && canDropHere;\n const dropNotAllowed = rawIsOver && !canDropHere;\n\n const dropRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n setDropNodeRef(node);\n },\n [setDropNodeRef]\n );\n\n return {\n dropRef,\n dropMonitorId: dropId,\n isOver,\n dropEffect: timerCopyMode || isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n dropNotAllowed,\n };\n };\n\n // #endregion\n\n return {\n DndProvider,\n useRuleDnD,\n useRuleGroupDnD,\n useInlineCombinatorDnD,\n };\n};\n"],"mappings":"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"}