UNPKG

@react-querybuilder/dnd

Version:

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

1 lines 37.7 kB
{"version":3,"file":"pragmatic-dnd-Bp-MQRoE.mjs","names":[],"sources":["../src/quadrantDetection.ts","../src/adapters/pragmatic-dnd.tsx"],"sourcesContent":["/**\n * Determines whether the cursor is in the upper quadrant (top 25%),\n * lower quadrant (bottom 25%), or middle zone (center 50%) of an element.\n *\n * Returns `null` when the cursor is in the middle zone, indicating\n * no positional change should occur.\n */\nexport const getQuadrant = (element: HTMLElement, clientY: number): 'upper' | 'lower' | null => {\n const rect = element.getBoundingClientRect();\n const quarterHeight = rect.height / 4;\n if (clientY < rect.top + quarterHeight) return 'upper';\n if (clientY > rect.bottom - quarterHeight) return 'lower';\n return null;\n};\n","import type { combine as combineImport } from '@atlaskit/pragmatic-drag-and-drop/combine';\nimport type {\n draggable as draggableImport,\n dropTargetForElements as dropTargetForElementsImport,\n monitorForElements as monitorForElementsImport,\n} from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\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 { getQuadrant } from '../quadrantDetection';\nimport { computeShadowQuery } from '../shadowQuery';\nimport type { DragPreviewState, OnDragMoveCallback, OnRuleDropCallback } from '../types';\n\n/**\n * The `@atlaskit/pragmatic-drag-and-drop` exports needed by the adapter.\n *\n * @group DnD\n */\nexport type PragmaticDndExports = {\n draggable: typeof draggableImport;\n dropTargetForElements: typeof dropTargetForElementsImport;\n monitorForElements: typeof monitorForElementsImport;\n combine: typeof combineImport;\n};\n\n// #region Internal context\n\ninterface PragmaticDragState {\n activeDragItem: DraggedItem | null;\n timerCopyMode: boolean;\n timerGroupMode: boolean;\n}\n\nconst defaultDragState: PragmaticDragState = {\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// #endregion\n\n/**\n * Creates a {@link DndAdapter} backed by `@atlaskit/pragmatic-drag-and-drop`.\n *\n * @example\n * ```tsx\n * import { QueryBuilderDnD } from '@react-querybuilder/dnd';\n * import { createPragmaticDndAdapter } from '@react-querybuilder/dnd/pragmatic-dnd';\n * import { draggable, dropTargetForElements, monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';\n * import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';\n *\n * const adapter = createPragmaticDndAdapter({ draggable, dropTargetForElements, monitorForElements, combine });\n *\n * <QueryBuilderDnD dnd={adapter}>\n * <QueryBuilder />\n * </QueryBuilderDnD>\n * ```\n *\n * @group DnD\n */\nexport const createPragmaticDndAdapter = (pdndExports: PragmaticDndExports): DndAdapter => {\n const { draggable, dropTargetForElements, monitorForElements, combine } = pdndExports;\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 the target hasn't changed, don't restart timers\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 // Track last target to avoid redundant recomputations\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 // Skip if same target and quadrant\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 already 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 // Commit the shadow query as the real query via schema.dispatchQuery.\n // This fires onQueryChange once with the final result.\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 useEffect(() => {\n const cleanup = monitorForElements({\n onDragStart({ source }: { source: { data: Record<string, unknown> } }) {\n const data = source.data;\n if (data.__rqbPath && data.__rqbSchema) {\n // oxlint-disable-next-line typescript/no-explicit-any\n const item = getDragItem(data.__rqbPath as number[], data.__rqbSchema as any);\n activeDragItemRef.current = item;\n setActiveDragItem(item);\n\n // Initialize shadow query state if updateWhileDragging is enabled\n if (updateWhileDragging) {\n // oxlint-disable-next-line typescript/no-explicit-any\n const schema = data.__rqbSchema as Schema<any, any>;\n dragSchemaRef.current = schema;\n const originalQuery = schema.getQuery();\n const initialState: DragPreviewState = {\n shadowQuery: originalQuery,\n originalQuery,\n draggedPath: data.__rqbPath as Path,\n previewPath: data.__rqbPath as Path,\n dropEffect: 'move',\n groupItems: false,\n qbId: schema.qbId,\n };\n dragPreviewStateRef.current = initialState;\n setDragPreviewState(initialState);\n }\n }\n },\n onDrag({\n location,\n }: {\n source: { data: Record<string, unknown> };\n location: {\n current: {\n dropTargets: { data: Record<string, unknown>; element: Element }[];\n input: { clientX: number; clientY: number };\n };\n };\n }) {\n const dropTargets = location.current.dropTargets;\n\n // Manage hover timers for copy/group mode\n if (dropTargets.length > 0) {\n const target = dropTargets[0];\n const targetType = target.data.__rqbType as DndDropTargetType | undefined;\n const targetPath = target.data.__rqbPath 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 (dropTargets.length === 0) return;\n\n const target = dropTargets[0];\n const targetType = target.data.__rqbType as DndDropTargetType | undefined;\n const targetPath = target.data.__rqbPath as Path | undefined;\n\n if (!targetType || !targetPath) return;\n\n const quadrant =\n targetType === 'ruleGroup'\n ? ('upper' as const)\n : getQuadrant(target.element as HTMLElement, location.current.input.clientY);\n\n // Cursor is in the middle zone — no update\n if (!quadrant) return;\n\n // Validate the drop is allowed\n const dragItem = activeDragItemRef.current;\n // v8 ignore next\n if (!dragItem) return;\n\n const validate = target.data.__rqbValidate as\n | ((item: DraggedItem) => boolean)\n | undefined;\n if (validate && !validate(dragItem)) return;\n\n updatePreviewPosition(targetPath, targetType, quadrant);\n },\n onDrop({\n source,\n location,\n }: {\n source: { data: Record<string, unknown> };\n location: { current: { dropTargets: { data: Record<string, unknown> }[] } };\n }) {\n const dragItem = activeDragItemRef.current;\n const sourceData = source.data;\n const dropTargets = location.current.dropTargets;\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 (dropTargets.length > 0) {\n // Dropped on a valid target — commit the shadow query\n commitDrag();\n } else {\n // Released outside any target — cancel (revert to original)\n cancelDrag();\n }\n } else if (dragItem && dropTargets.length > 0) {\n // Standard drop behavior\n const targetData = dropTargets[0].data;\n const validate = targetData.__rqbValidate as\n | ((item: DraggedItem) => boolean)\n | undefined;\n\n if (validate?.(dragItem)) {\n const getDropResultFn = targetData.__rqbGetDropResult as (() => unknown) | undefined;\n const dropResult = getDropResultFn?.();\n handleDrop({\n item: dragItem,\n dropResult: dropResult as ReturnType<typeof buildDropResult> | null,\n // oxlint-disable-next-line typescript/no-explicit-any\n schema: sourceData.__rqbSchema as any,\n // oxlint-disable-next-line typescript/no-explicit-any\n actions: sourceData.__rqbActions as any,\n copyModeModifierKey: sourceData.__rqbCopyModeModifierKey as string,\n groupModeModifierKey: sourceData.__rqbGroupModeModifierKey as string,\n copyModeOverride: copyOverride,\n groupModeOverride: groupOverride,\n onRuleDrop: sourceData.__rqbOnRuleDrop as OnRuleDropCallback | undefined,\n });\n }\n }\n\n activeDragItemRef.current = null;\n setActiveDragItem(null);\n },\n });\n\n return () => {\n cleanup();\n clearHoverTimers();\n };\n }, [\n updateWhileDragging,\n commitDrag,\n cancelDrag,\n updatePreviewPosition,\n startHoverTimers,\n clearHoverTimers,\n ]);\n\n const dragStateValue = useMemo<PragmaticDragState>(\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 <DragStateContext.Provider value={dragStateValue}>\n <DragPreviewContext.Provider value={dragPreviewContextValue}>\n {children}\n </DragPreviewContext.Provider>\n </DragStateContext.Provider>\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 containerNodeRef = useRef<HTMLDivElement>(null);\n const handleNodeRef = useRef<HTMLSpanElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [isOver, setIsOver] = useState(false);\n\n const dragId = getDragId('rule', params.path, params.schema.qbId);\n const dropId = getDropId('rule', params.path, params.schema.qbId);\n\n const paramsRef = useRef(params);\n paramsRef.current = params;\n\n useEffect(() => {\n const container = containerNodeRef.current;\n const handle = handleNodeRef.current;\n if (!container || !handle) return undefined;\n\n return combine(\n draggable({\n element: container,\n dragHandle: handle,\n canDrag: () => !paramsRef.current.disabled,\n getInitialData: () => ({\n __rqbPath: paramsRef.current.path,\n __rqbSchema: paramsRef.current.schema,\n __rqbActions: paramsRef.current.actions,\n __rqbCopyModeModifierKey: paramsRef.current.copyModeModifierKey,\n __rqbGroupModeModifierKey: paramsRef.current.groupModeModifierKey,\n __rqbOnRuleDrop: paramsRef.current.onRuleDrop,\n }),\n onDragStart: () => setIsDragging(true),\n onDrop: () => setIsDragging(false),\n }),\n dropTargetForElements({\n element: container,\n getData: () => ({\n __rqbType: 'rule' as DndDropTargetType,\n __rqbPath: paramsRef.current.path,\n __rqbValidate: (dragging: DraggedItem) => {\n const cp = paramsRef.current;\n return canDropOnRule({\n dragging,\n path: cp.path,\n schema: cp.schema,\n canDrop: cp.canDrop,\n groupModeModifierKey: cp.groupModeModifierKey,\n disabled: cp.disabled,\n rule: cp.rule,\n });\n },\n __rqbGetDropResult: () => {\n const cp = paramsRef.current;\n return buildDropResult({\n type: 'rule',\n path: cp.path,\n schema: cp.schema,\n copyModeModifierKey: cp.copyModeModifierKey,\n groupModeModifierKey: cp.groupModeModifierKey,\n });\n },\n }),\n onDragEnter: () => setIsOver(true),\n onDragLeave: () => setIsOver(false),\n onDrop: () => setIsOver(false),\n })\n );\n }, [params.path, params.schema.qbId, params.disabled]);\n\n const canDropHere =\n isOver &&\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 validatedIsOver = isOver && canDropHere;\n const dropNotAllowed = isOver && !canDropHere;\n\n const dndRef: React.RefCallback<HTMLDivElement> = useCallback((node: HTMLDivElement | null) => {\n containerNodeRef.current = node;\n }, []);\n\n const dragRef: React.RefCallback<HTMLSpanElement> = useCallback(\n (node: HTMLSpanElement | null) => {\n handleNodeRef.current = node;\n },\n []\n );\n\n return {\n isDragging,\n dragMonitorId: dragId,\n isOver: validatedIsOver,\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 previewNodeRef = useRef<HTMLDivElement>(null);\n const handleNodeRef = useRef<HTMLSpanElement>(null);\n const dropNodeRef = useRef<HTMLDivElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [isOver, setIsOver] = useState(false);\n\n const isDragDisabled = params.disabled || params.path.length === 0;\n\n const dragId = getDragId('ruleGroup', params.path, params.schema.qbId);\n const dropId = getDropId('ruleGroup', params.path, params.schema.qbId);\n\n const paramsRef = useRef(params);\n paramsRef.current = params;\n\n // Register draggable on the preview element with handle\n useEffect(() => {\n const previewEl = previewNodeRef.current;\n const handleEl = handleNodeRef.current;\n if (!previewEl || !handleEl || isDragDisabled) return undefined;\n\n return draggable({\n element: previewEl,\n dragHandle: handleEl,\n canDrag: () => !paramsRef.current.disabled && paramsRef.current.path.length > 0,\n getInitialData: () => ({\n __rqbPath: paramsRef.current.path,\n __rqbSchema: paramsRef.current.schema,\n __rqbActions: paramsRef.current.actions,\n __rqbCopyModeModifierKey: paramsRef.current.copyModeModifierKey,\n __rqbGroupModeModifierKey: paramsRef.current.groupModeModifierKey,\n __rqbOnRuleDrop: paramsRef.current.onRuleDrop,\n }),\n onDragStart: () => setIsDragging(true),\n onDrop: () => setIsDragging(false),\n });\n }, [isDragDisabled, params.path, params.schema.qbId]);\n\n // Register drop target on the drop element (header)\n useEffect(() => {\n const dropEl = dropNodeRef.current;\n if (!dropEl) return undefined;\n\n return dropTargetForElements({\n element: dropEl,\n getData: () => ({\n __rqbType: 'ruleGroup' as DndDropTargetType,\n __rqbPath: paramsRef.current.path,\n __rqbValidate: (dragging: DraggedItem) => {\n const cp = paramsRef.current;\n return canDropOnRuleGroup({\n dragging,\n path: cp.path,\n schema: cp.schema,\n canDrop: cp.canDrop,\n disabled: cp.disabled,\n ruleGroup: cp.ruleGroup,\n });\n },\n __rqbGetDropResult: () => {\n const cp = paramsRef.current;\n return buildDropResult({\n type: 'ruleGroup',\n path: cp.path,\n schema: cp.schema,\n copyModeModifierKey: cp.copyModeModifierKey,\n groupModeModifierKey: cp.groupModeModifierKey,\n });\n },\n }),\n onDragEnter: () => setIsOver(true),\n onDragLeave: () => setIsOver(false),\n onDrop: () => setIsOver(false),\n });\n }, [params.path, params.schema.qbId, params.disabled]);\n\n const canDropHere =\n isOver &&\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 validatedIsOver = isOver && canDropHere;\n const dropNotAllowed = isOver && !canDropHere;\n\n const previewRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n previewNodeRef.current = node;\n },\n []\n );\n\n const dropRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n dropNodeRef.current = node;\n },\n []\n );\n\n const dragRef: React.RefCallback<HTMLSpanElement> = useCallback(\n (node: HTMLSpanElement | null) => {\n handleNodeRef.current = node;\n },\n []\n );\n\n return {\n isDragging,\n dragMonitorId: dragId,\n isOver: validatedIsOver,\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 const { dragPreviewState } = useContext(DragPreviewContext);\n const dropNodeRef = useRef<HTMLDivElement>(null);\n const [isOver, setIsOver] = useState(false);\n\n const dropId = getDropId('inlineCombinator', params.path, params.schema.qbId);\n\n // When updateWhileDragging is active, disable inline combinator drop targets\n const isUpdateWhileDragging = dragPreviewState !== null;\n\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 paramsRef = useRef(params);\n paramsRef.current = params;\n\n useEffect(() => {\n const dropEl = dropNodeRef.current;\n if (!dropEl || isUpdateWhileDragging) return undefined;\n\n return dropTargetForElements({\n element: dropEl,\n getData: () => ({\n __rqbType: 'inlineCombinator' as DndDropTargetType,\n __rqbValidate: (dragging: DraggedItem) => {\n const cp = paramsRef.current;\n const hItem = (cp.rules ?? [])[cp.path.at(-1)! - 1] as RuleType | RuleGroupTypeAny;\n return canDropOnInlineCombinator({\n dragging,\n path: cp.path,\n schema: cp.schema,\n canDrop: cp.canDrop,\n groupModeModifierKey: cp.groupModeModifierKey,\n hoveringItem: hItem,\n });\n },\n __rqbGetDropResult: () => {\n const cp = paramsRef.current;\n return buildDropResult({\n type: 'inlineCombinator',\n path: cp.path,\n schema: cp.schema,\n copyModeModifierKey: cp.copyModeModifierKey,\n groupModeModifierKey: cp.groupModeModifierKey,\n });\n },\n }),\n onDragEnter: () => setIsOver(true),\n onDragLeave: () => setIsOver(false),\n onDrop: () => setIsOver(false),\n });\n }, [params.path, params.schema.qbId, isUpdateWhileDragging]);\n\n const canDropHere =\n !isUpdateWhileDragging &&\n isOver &&\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 validatedIsOver = isOver && canDropHere;\n const dropNotAllowed = !isUpdateWhileDragging && isOver && !canDropHere;\n\n const dropRef: React.RefCallback<HTMLDivElement> = useCallback(\n (node: HTMLDivElement | null) => {\n dropNodeRef.current = node;\n },\n []\n );\n\n return {\n dropRef,\n dropMonitorId: dropId,\n isOver: validatedIsOver,\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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"}