@react-querybuilder/dnd
Version:
Drag-and-drop-enabled version of react-querybuilder (DnD-library-agnostic)
1 lines • 37.5 kB
Source Map (JSON)
{"version":3,"file":"react-querybuilder_dnd.mjs","names":[],"sources":["../src/adapter.ts","../src/flipAnimation.ts","../src/QueryBuilderDndContext.ts","../src/InlineCombinatorDnD.tsx","../src/RuleDnD.tsx","../src/RuleGroupDnD.tsx","../src/QueryBuilderDnD.tsx","../src/useShadowQuery.ts"],"sourcesContent":["import type { Ref } from 'react';\nimport type {\n DropEffect,\n Path,\n QueryActions,\n RuleGroupTypeAny,\n RuleType,\n Schema,\n} from 'react-querybuilder';\nimport type { CustomCanDropParams, OnRuleDropCallback } from './types';\n\n/**\n * Parameters for the adapter's `useRuleDnD` hook.\n */\nexport interface DndAdapterRuleDnDParams {\n path: Path;\n disabled: boolean;\n // oxlint-disable-next-line typescript/no-explicit-any\n schema: Schema<any, any>;\n actions: QueryActions;\n rule: RuleType;\n canDrop?: (params: CustomCanDropParams) => boolean;\n copyModeModifierKey: string;\n copyModeAfterHoverMs?: number;\n groupModeModifierKey: string;\n groupModeAfterHoverMs?: number;\n hideDefaultDragPreview?: boolean;\n onRuleDrop?: OnRuleDropCallback;\n}\n\n/**\n * Parameters for the adapter's `useRuleGroupDnD` hook.\n */\nexport interface DndAdapterRuleGroupDnDParams {\n path: Path;\n disabled: boolean;\n // oxlint-disable-next-line typescript/no-explicit-any\n schema: Schema<any, any>;\n actions: QueryActions;\n ruleGroup: RuleGroupTypeAny;\n canDrop?: (params: CustomCanDropParams) => boolean;\n copyModeModifierKey: string;\n copyModeAfterHoverMs?: number;\n groupModeModifierKey: string;\n groupModeAfterHoverMs?: number;\n hideDefaultDragPreview?: boolean;\n onRuleDrop?: OnRuleDropCallback;\n}\n\n/**\n * Parameters for the adapter's `useInlineCombinatorDnD` hook.\n */\nexport interface DndAdapterInlineCombinatorDnDParams {\n path: Path;\n // oxlint-disable-next-line typescript/no-explicit-any\n schema: Schema<any, any>;\n rules?: (RuleType | RuleGroupTypeAny | string)[];\n canDrop?: (params: CustomCanDropParams) => boolean;\n copyModeModifierKey: string;\n copyModeAfterHoverMs?: number;\n groupModeModifierKey: string;\n groupModeAfterHoverMs?: number;\n}\n\n/**\n * Return type for the adapter's `useRuleDnD` hook. Matches the existing\n * `UseRuleDnD` interface from `react-querybuilder`.\n */\nexport interface AdapterUseRuleDnDResult {\n isDragging: boolean;\n dragMonitorId: string | symbol;\n isOver: boolean;\n dropMonitorId: string | symbol;\n dragRef: Ref<HTMLSpanElement>;\n dndRef: Ref<HTMLDivElement>;\n dropEffect?: DropEffect;\n groupItems?: boolean;\n dropNotAllowed?: boolean;\n}\n\n/**\n * Return type for the adapter's `useRuleGroupDnD` hook. Matches the existing\n * `UseRuleGroupDnD` interface from `react-querybuilder`.\n */\nexport interface AdapterUseRuleGroupDnDResult {\n isDragging: boolean;\n dragMonitorId: string | symbol;\n isOver: boolean;\n dropMonitorId: string | symbol;\n previewRef: Ref<HTMLDivElement>;\n dragRef: Ref<HTMLSpanElement>;\n dropRef: Ref<HTMLDivElement>;\n dropEffect?: DropEffect;\n groupItems?: boolean;\n dropNotAllowed?: boolean;\n}\n\n/**\n * Return type for the adapter's `useInlineCombinatorDnD` hook.\n */\nexport interface AdapterUseInlineCombinatorDnDResult {\n isOver: boolean;\n dropMonitorId: string | symbol | null;\n dropRef: Ref<HTMLDivElement>;\n dropEffect?: DropEffect;\n groupItems?: boolean;\n dropNotAllowed?: boolean;\n}\n\n/**\n * Props for the adapter's DnD context provider component.\n */\nexport interface DndAdapterProviderProps {\n debugMode?: boolean;\n /**\n * When `true`, the adapter should enable update-while-dragging behavior:\n * computing a shadow query on hover and committing it on drop instead of\n * using the standard drop-indicator approach.\n */\n updateWhileDragging?: boolean;\n /**\n * Milliseconds after hovering a drop target before the drop effect\n * automatically switches to \"copy\".\n */\n copyModeAfterHoverMs?: number;\n /**\n * Milliseconds after hovering a drop target before the drop will\n * automatically create a new group.\n */\n groupModeAfterHoverMs?: number;\n children: React.ReactNode;\n}\n\n/**\n * The DnD adapter interface. Implementations of this interface provide\n * drag-and-drop functionality for react-querybuilder using a specific\n * DnD library.\n *\n * Built-in adapters: {@link createReactDnDAdapter} (for `react-dnd`)\n * and {@link createDndKitAdapter} (for `@dnd-kit/core`).\n *\n * @group DnD\n */\nexport interface DndAdapter {\n /**\n * Provider component that wraps the query builder tree with the\n * DnD library's context.\n */\n DndProvider: React.ComponentType<DndAdapterProviderProps>;\n\n /**\n * Hook providing drag-and-drop behavior for a rule component.\n * Returns refs and state to attach to the rule's DOM elements.\n */\n useRuleDnD: (params: DndAdapterRuleDnDParams) => AdapterUseRuleDnDResult;\n\n /**\n * Hook providing drag-and-drop behavior for a rule group component.\n * Returns refs and state to attach to the group's DOM elements.\n */\n useRuleGroupDnD: (params: DndAdapterRuleGroupDnDParams) => AdapterUseRuleGroupDnDResult;\n\n /**\n * Hook providing drop-target behavior for an inline combinator.\n * Returns a drop ref and hover state.\n */\n useInlineCombinatorDnD: (\n params: DndAdapterInlineCombinatorDnDParams\n ) => AdapterUseInlineCombinatorDnDResult;\n}\n\n/**\n * Type guard to check if a value is a {@link DndAdapter}.\n */\nexport const isDndAdapter = (value: unknown): value is DndAdapter =>\n typeof value === 'object' &&\n value !== null &&\n 'DndProvider' in value &&\n 'useRuleDnD' in value &&\n 'useRuleGroupDnD' in value &&\n 'useInlineCombinatorDnD' in value;\n","/**\n * FLIP (First, Last, Invert, Play) animation utility.\n *\n * Captures the positions of elements before a DOM update, then after the\n * update animates them from their old positions to their new ones using\n * CSS transforms, producing a smooth layout transition.\n *\n * @example\n * ```ts\n * const flip = createFlipAnimator('.rule, .ruleGroup');\n * flip.captureFirst(containerEl);\n * // ... React re-render happens ...\n * useLayoutEffect(() => { flip.playLast(containerEl); }, [shadowQuery]);\n * ```\n */\n\nconst FLIP_DURATION_MS = 150;\nconst FLIP_EASING = 'ease';\n\nexport interface FlipAnimator {\n /** Capture the \"first\" positions of all matching elements. */\n captureFirst: (container: HTMLElement) => void;\n /**\n * Measure \"last\" positions, compute deltas, and animate.\n * Call this in `useLayoutEffect` after React has committed the new DOM.\n */\n playLast: (container: HTMLElement) => void;\n}\n\nconst getElementKey = (el: Element): string | null =>\n el.getAttribute('data-rule-id') ?? el.getAttribute('data-testid') ?? null;\n\n/**\n * Creates a FLIP animator that tracks elements matching the given CSS selector\n * within a container. Elements are identified by their `data-rule-id` or `data-testid`\n * attribute.\n */\nexport const createFlipAnimator = (selector: string): FlipAnimator => {\n let firstPositions = new Map<string, DOMRect>();\n\n const captureFirst = (container: HTMLElement): void => {\n firstPositions = new Map();\n const elements = container.querySelectorAll(selector);\n for (const el of elements) {\n const key = getElementKey(el);\n if (key) {\n firstPositions.set(key, el.getBoundingClientRect());\n }\n }\n };\n\n const playLast = (container: HTMLElement): void => {\n const elements = container.querySelectorAll(selector);\n for (const el of elements) {\n const key = getElementKey(el);\n if (!key) continue;\n\n const firstRect = firstPositions.get(key);\n if (!firstRect) continue;\n\n const lastRect = el.getBoundingClientRect();\n const deltaX = firstRect.left - lastRect.left;\n const deltaY = firstRect.top - lastRect.top;\n\n if (deltaX === 0 && deltaY === 0) continue;\n\n // Invert: place element at its old position\n const htmlEl = el as HTMLElement;\n htmlEl.style.transform = `translate(${deltaX}px, ${deltaY}px)`;\n htmlEl.style.transition = 'none';\n\n // Play: animate to new position\n requestAnimationFrame(() => {\n htmlEl.style.transition = `transform ${FLIP_DURATION_MS}ms ${FLIP_EASING}`;\n htmlEl.style.transform = '';\n\n const handleTransitionEnd = (): void => {\n htmlEl.style.transition = '';\n htmlEl.removeEventListener('transitionend', handleTransitionEnd);\n };\n htmlEl.addEventListener('transitionend', handleTransitionEnd);\n });\n }\n\n firstPositions = new Map();\n };\n\n return { captureFirst, playLast };\n};\n","import type { Context } from 'react';\nimport { createContext } from 'react';\nimport { defaultControlElements } from 'react-querybuilder';\nimport type { QueryBuilderDndContextProps } from './types';\n\nconst { rule, ruleGroup, combinatorSelector } = defaultControlElements;\n\n/**\n * @group Components\n */\nexport const QueryBuilderDndContext: Context<QueryBuilderDndContextProps> =\n createContext<QueryBuilderDndContextProps>({\n baseControls: { rule, ruleGroup, combinatorSelector },\n });\n","import * as React from 'react';\nimport { useContext } from 'react';\nimport type { InlineCombinatorProps } from 'react-querybuilder';\nimport { standardClassnames, TestID } from 'react-querybuilder';\nimport { DragPreviewContext } from './DragPreviewContext';\nimport { QueryBuilderDndContext } from './QueryBuilderDndContext';\n\n/**\n * The drag-and-drop-enabled inline combinator component.\n *\n * @group Components\n */\nexport const InlineCombinatorDnD = ({\n component: CombinatorSelectorComponent,\n ...props\n}: InlineCombinatorProps): React.JSX.Element => {\n const {\n adapter,\n canDrop,\n copyModeModifierKey,\n copyModeAfterHoverMs,\n groupModeModifierKey,\n groupModeAfterHoverMs,\n } = useContext(QueryBuilderDndContext);\n const { dragPreviewState } = useContext(DragPreviewContext);\n\n // When updateWhileDragging is active, suppress drop indicator\n const isUpdateWhileDragging = dragPreviewState !== null;\n\n const { dropRef, dropMonitorId, isOver } = adapter!.useInlineCombinatorDnD({\n path: props.path,\n schema: props.schema,\n rules: props.rules,\n canDrop,\n copyModeModifierKey: copyModeModifierKey ?? 'alt',\n copyModeAfterHoverMs,\n groupModeModifierKey: groupModeModifierKey ?? 'ctrl',\n groupModeAfterHoverMs,\n });\n\n // Suppress isOver when updateWhileDragging is active\n // v8 ignore next -- same pattern as RuleDnD/RuleGroupDnD; IC only used in specific mode\n const effectiveIsOver = isUpdateWhileDragging ? false : isOver;\n\n const wrapperClassName = [\n props.schema.suppressStandardClassnames || standardClassnames.betweenRules,\n (effectiveIsOver && !props.schema.classNames.dndOver) || false,\n (effectiveIsOver && !props.schema.suppressStandardClassnames && standardClassnames.dndOver) ||\n false,\n ]\n .filter(c => typeof c === 'string')\n .join(' ');\n\n return (\n <div\n key=\"dnd\"\n ref={dropRef}\n className={wrapperClassName}\n data-dropmonitorid={dropMonitorId}\n data-testid={TestID.inlineCombinator}>\n <CombinatorSelectorComponent {...props} testID={TestID.combinators} />\n </div>\n );\n};\n\n/**\n * @group Hooks\n * @deprecated Access via the adapter instead: `adapter.useInlineCombinatorDnD(params)`.\n */\nexport { type AdapterUseInlineCombinatorDnDResult as UseInlineCombinatorDnDResult } from './adapter';\n","import * as React from 'react';\nimport { useContext } from 'react';\nimport type { RuleProps } from 'react-querybuilder';\nimport { DragPreviewContext } from './DragPreviewContext';\nimport { QueryBuilderDndContext } from './QueryBuilderDndContext';\n\n/**\n * Rule component for drag-and-drop. Renders the provided rule component\n * ({@link react-querybuilder!Rule Rule} by default), but forwards the\n * drag-and-drop context.\n *\n * @group Components\n */\nexport const RuleDnD = (props: RuleProps): React.JSX.Element => {\n const rqbDndContext = useContext(QueryBuilderDndContext);\n const { dragPreviewState } = useContext(DragPreviewContext);\n\n const {\n adapter,\n canDrop,\n copyModeModifierKey,\n copyModeAfterHoverMs,\n groupModeModifierKey,\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n onRuleDrop,\n } = rqbDndContext;\n\n const disabled = !!props.parentDisabled || !!props.disabled;\n\n const dndRefs = adapter!.useRuleDnD({\n path: props.path,\n disabled,\n schema: props.schema,\n actions: props.actions,\n rule: props.rule,\n canDrop,\n copyModeModifierKey: copyModeModifierKey ?? 'alt',\n copyModeAfterHoverMs,\n groupModeModifierKey: groupModeModifierKey ?? 'ctrl',\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n onRuleDrop,\n });\n\n // When updateWhileDragging is active, suppress isDragging and isOver\n // indicators — the visual feedback is the item moving in the tree.\n const overriddenDndRefs = dragPreviewState\n ? { ...dndRefs, isDragging: false, isOver: false, dropNotAllowed: false }\n : dndRefs;\n\n const { rule: BaseRuleComponent } = rqbDndContext.baseControls;\n\n return (\n <QueryBuilderDndContext.Provider value={rqbDndContext}>\n <BaseRuleComponent {...props} {...overriddenDndRefs} />\n </QueryBuilderDndContext.Provider>\n );\n};\n\n/**\n * @group Hooks\n * @deprecated Access via the adapter instead: `adapter.useRuleDnD(params)`.\n */\nexport { type AdapterUseRuleDnDResult as UseRuleDnDResult } from './adapter';\n","import * as React from 'react';\nimport { useContext, useMemo } from 'react';\nimport type { RuleGroupProps } from 'react-querybuilder';\nimport { DragPreviewContext } from './DragPreviewContext';\nimport { QueryBuilderDndContext } from './QueryBuilderDndContext';\n\n/**\n * Rule group component for drag-and-drop. Renders the provided rule group component\n * ({@link react-querybuilder!RuleGroup RuleGroup} by default), but forwards the drag-and-drop\n * context so that child rules and groups will render within the appropriate drag-and-drop wrappers.\n *\n * @group Components\n */\nexport const RuleGroupDnD = (props: RuleGroupProps): React.JSX.Element => {\n const rqbDndContext = useContext(QueryBuilderDndContext);\n const { dragPreviewState } = useContext(DragPreviewContext);\n\n const {\n adapter,\n canDrop,\n baseControls: { ruleGroup: BaseRuleGroupComponent },\n copyModeModifierKey,\n copyModeAfterHoverMs,\n groupModeModifierKey,\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n onRuleDrop,\n } = rqbDndContext;\n\n // When updateWhileDragging is active and this is the root group,\n // swap ruleGroup/rules with the shadow query so the tree re-renders\n // with the dragged item at its preview position.\n const effectiveProps = useMemo(() => {\n if (props.path.length === 0 && dragPreviewState) {\n const sq = dragPreviewState.shadowQuery;\n return {\n ...props,\n ruleGroup: sq,\n rules: sq.rules,\n };\n }\n return props;\n }, [props, dragPreviewState]);\n\n const dndRefs = adapter!.useRuleGroupDnD({\n disabled: !!effectiveProps.parentDisabled || !!effectiveProps.disabled,\n path: effectiveProps.path,\n schema: effectiveProps.schema,\n actions: effectiveProps.actions,\n ruleGroup: effectiveProps.ruleGroup,\n canDrop,\n copyModeModifierKey: copyModeModifierKey ?? 'alt',\n copyModeAfterHoverMs,\n groupModeModifierKey: groupModeModifierKey ?? 'ctrl',\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n onRuleDrop,\n });\n\n // When updateWhileDragging is active, suppress isDragging and isOver\n // indicators — the visual feedback is the item moving in the tree.\n const overriddenDndRefs = dragPreviewState\n ? { ...dndRefs, isDragging: false, isOver: false, dropNotAllowed: false }\n : dndRefs;\n\n return <BaseRuleGroupComponent {...effectiveProps} {...overriddenDndRefs} />;\n};\n\n/**\n * @group Hooks\n * @deprecated Access via the adapter instead: `adapter.useRuleGroupDnD(params)`.\n */\nexport { type AdapterUseRuleGroupDnDResult as UseRuleGroupDnDResult } from './adapter';\n","import * as React from 'react';\nimport { useContext, useEffect, useMemo, useState } from 'react';\nimport type { QueryBuilderContextProps } from 'react-querybuilder';\nimport {\n messages,\n preferAnyProp,\n preferProp,\n QueryBuilderContext,\n useMergedContext,\n} from 'react-querybuilder';\nimport type { DndAdapter } from './adapter';\nimport { isDndAdapter } from './adapter';\nimport { createReactDnDAdapter } from './adapters/react-dnd';\nimport { InlineCombinatorDnD } from './InlineCombinatorDnD';\nimport { isTouchDevice } from './isTouchDevice';\nimport { QueryBuilderDndContext } from './QueryBuilderDndContext';\nimport { RuleDnD } from './RuleDnD';\nimport { RuleGroupDnD } from './RuleGroupDnD';\nimport type {\n DndProp,\n QueryBuilderDndContextProps,\n QueryBuilderDndProps,\n UseReactDnD,\n} from './types';\n\n/**\n * Context provider to enable drag-and-drop. If the application already implements\n * `react-dnd`, use {@link QueryBuilderDndWithoutProvider} instead.\n *\n * @group Components\n */\nexport const QueryBuilderDnD = (props: QueryBuilderDndProps): React.JSX.Element => {\n const {\n controlClassnames,\n controlElements,\n debugMode,\n enableDragAndDrop: enableDragAndDropProp,\n enableMountQueryChange,\n translations,\n } = props;\n\n const rqbContext = useMergedContext({\n controlClassnames,\n controlElements,\n debugMode,\n enableDragAndDrop: enableDragAndDropProp ?? true,\n enableMountQueryChange,\n translations: translations ?? {},\n });\n const { enableDragAndDrop } = rqbContext;\n\n // Resolve the adapter: either directly provided, wrapped from legacy DndProp, or async-loaded\n const adapter = useResolvedAdapter(props.dnd);\n const key = enableDragAndDrop && adapter ? 'dnd' : 'no-dnd';\n\n const contextWithoutDnD = useMemo(\n () => ({ ...rqbContext, enableDragAndDrop: false, debugMode }),\n [rqbContext, debugMode]\n );\n const contextWithDnD = useMemo(\n () => ({ ...rqbContext, enableDragAndDrop, debugMode }),\n [rqbContext, debugMode, enableDragAndDrop]\n );\n\n if (!enableDragAndDrop || !adapter) {\n return (\n <QueryBuilderContext.Provider key={key} value={contextWithoutDnD}>\n {props.children}\n </QueryBuilderContext.Provider>\n );\n }\n\n const { DndProvider } = adapter;\n\n return (\n <DndProvider\n key={key}\n debugMode={debugMode}\n updateWhileDragging={props.updateWhileDragging}\n copyModeAfterHoverMs={props.copyModeAfterHoverMs}\n groupModeAfterHoverMs={props.groupModeAfterHoverMs}>\n <QueryBuilderContext.Provider key={key} value={contextWithDnD}>\n <QueryBuilderDndWithoutProvider\n dnd={adapter}\n canDrop={props.canDrop}\n copyModeModifierKey={props.copyModeModifierKey}\n copyModeAfterHoverMs={props.copyModeAfterHoverMs}\n groupModeModifierKey={props.groupModeModifierKey}\n groupModeAfterHoverMs={props.groupModeAfterHoverMs}\n hideDefaultDragPreview={props.hideDefaultDragPreview}\n updateWhileDragging={props.updateWhileDragging}\n onDragMove={props.onDragMove}\n onRuleDrop={props.onRuleDrop}>\n {props.children}\n </QueryBuilderDndWithoutProvider>\n </QueryBuilderContext.Provider>\n </DndProvider>\n );\n};\n\n/**\n * Context provider to enable drag-and-drop. Only use this provider if the application\n * already implements `react-dnd`, otherwise use {@link QueryBuilderDnD}.\n *\n * @group Components\n */\nexport const QueryBuilderDndWithoutProvider = (props: QueryBuilderDndProps): React.JSX.Element => {\n const rqbContext = useContext(QueryBuilderContext);\n const rqbDndContext = useContext(QueryBuilderDndContext);\n const adapter = useResolvedAdapter(props.dnd) ?? rqbDndContext.adapter;\n const copyModeModifierKey = preferAnyProp(\n undefined,\n props.copyModeModifierKey,\n rqbDndContext.copyModeModifierKey\n );\n const groupModeModifierKey = preferAnyProp(\n undefined,\n props.groupModeModifierKey,\n rqbDndContext.groupModeModifierKey\n );\n const copyModeAfterHoverMs = preferAnyProp(\n undefined,\n props.copyModeAfterHoverMs,\n rqbDndContext.copyModeAfterHoverMs\n );\n const groupModeAfterHoverMs = preferAnyProp(\n undefined,\n props.groupModeAfterHoverMs,\n rqbDndContext.groupModeAfterHoverMs\n );\n const enableDragAndDrop = preferProp(true, props.enableDragAndDrop, rqbContext.enableDragAndDrop);\n const debugMode = preferProp(false, props.debugMode, rqbContext.debugMode);\n const hideDefaultDragPreview = preferProp(\n false,\n props.hideDefaultDragPreview,\n rqbDndContext.hideDefaultDragPreview\n );\n const canDrop = preferAnyProp(undefined, props.canDrop, rqbDndContext.canDrop);\n const updateWhileDragging = preferProp(\n false,\n props.updateWhileDragging,\n rqbDndContext.updateWhileDragging\n );\n const onDragMove = preferAnyProp(undefined, props.onDragMove, rqbDndContext.onDragMove);\n const onRuleDrop = preferAnyProp(undefined, props.onRuleDrop, rqbDndContext.onRuleDrop);\n const key = enableDragAndDrop && adapter ? 'dnd' : 'no-dnd';\n\n const baseControls = useMemo(\n () => ({\n rule:\n props.controlElements?.rule ??\n rqbContext.controlElements?.rule ??\n rqbDndContext.baseControls.rule,\n ruleGroup:\n props.controlElements?.ruleGroup ??\n rqbContext.controlElements?.ruleGroup ??\n rqbDndContext.baseControls.ruleGroup,\n combinatorSelector:\n props.controlElements?.combinatorSelector ??\n rqbContext.controlElements?.combinatorSelector ??\n rqbDndContext.baseControls.combinatorSelector,\n }),\n [\n props.controlElements?.combinatorSelector,\n props.controlElements?.rule,\n props.controlElements?.ruleGroup,\n rqbContext.controlElements?.combinatorSelector,\n rqbContext.controlElements?.rule,\n rqbContext.controlElements?.ruleGroup,\n rqbDndContext.baseControls.combinatorSelector,\n rqbDndContext.baseControls.rule,\n rqbDndContext.baseControls.ruleGroup,\n ]\n );\n\n const newContext: QueryBuilderContextProps = useMemo(\n () => ({\n ...rqbContext,\n enableDragAndDrop,\n debugMode,\n controlElements: {\n ...rqbContext.controlElements,\n ruleGroup: RuleGroupDnD,\n rule: RuleDnD,\n inlineCombinator: InlineCombinatorDnD,\n },\n }),\n [debugMode, enableDragAndDrop, rqbContext]\n );\n\n const dndContextValue: QueryBuilderDndContextProps = useMemo(\n () => ({\n baseControls,\n canDrop,\n copyModeModifierKey,\n copyModeAfterHoverMs,\n groupModeModifierKey,\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n updateWhileDragging,\n onDragMove,\n onRuleDrop,\n adapter,\n }),\n [\n baseControls,\n canDrop,\n copyModeModifierKey,\n copyModeAfterHoverMs,\n groupModeModifierKey,\n groupModeAfterHoverMs,\n hideDefaultDragPreview,\n updateWhileDragging,\n onDragMove,\n onRuleDrop,\n adapter,\n ]\n );\n\n const contextWithoutDnD = useMemo(\n () => ({ ...rqbContext, enableDragAndDrop: false, debugMode }),\n [rqbContext, debugMode]\n );\n\n if (!enableDragAndDrop || !adapter) {\n return (\n <QueryBuilderContext.Provider key={key} value={contextWithoutDnD}>\n {props.children}\n </QueryBuilderContext.Provider>\n );\n }\n\n return (\n <QueryBuilderContext.Provider key={key} value={newContext}>\n <QueryBuilderDndContext.Provider value={dndContextValue}>\n {props.children}\n </QueryBuilderDndContext.Provider>\n </QueryBuilderContext.Provider>\n );\n};\n\nlet didWarnEnabledDndWithoutReactDnD = false;\n\n/**\n * Resolves a `dnd` prop (which may be a {@link DndAdapter}, a legacy {@link DndProp},\n * or `undefined`) into a {@link DndAdapter} or `null`.\n *\n * Hooks are always called in the same order regardless of the `dndParam` value\n * to satisfy the Rules of Hooks.\n */\nconst useResolvedAdapter = (dndParam?: DndAdapter | DndProp): DndAdapter | null => {\n const directAdapter = dndParam && isDndAdapter(dndParam) ? dndParam : null;\n\n // Always call useMemo (returns null when not applicable)\n const legacyAdapter = useMemo(\n () => (dndParam && !isDndAdapter(dndParam) ? createReactDnDAdapter(dndParam) : null),\n [dndParam]\n );\n\n // Always call the async hook, but skip loading when an explicit adapter exists\n const asyncAdapter = useAsyncReactDnDAdapter(directAdapter !== null || legacyAdapter !== null);\n\n return directAdapter ?? legacyAdapter ?? asyncAdapter;\n};\n\nconst useAsyncReactDnDAdapter = (skip: boolean): DndAdapter | null => {\n const [adapter, setAdapter] = useState<DndAdapter | null>(null);\n\n useEffect(() => {\n if (skip) return undefined;\n\n let didCancel = false;\n\n const loadDnD = async () => {\n const [reactDnD, reactDndHTML5Be, reactDndTouchBe] = await Promise.all(\n ['', '-html5-backend', '-touch-backend'].map(pn =>\n import(/* @vite-ignore */ `react-dnd${pn}`).catch(\n /* v8 ignore next -- @preserve */ () => null\n )\n )\n );\n\n // v8 ignore else\n if (!didCancel) {\n // v8 ignore else -- react-dnd is always importable in the test environment\n if (reactDnD) {\n let dndExports: DndProp;\n // v8 ignore next\n if (reactDndHTML5Be && (!reactDndTouchBe || (reactDndTouchBe && !isTouchDevice()))) {\n dndExports = {\n ...reactDnD,\n ...reactDndHTML5Be,\n ...reactDndTouchBe,\n ReactDndBackend: reactDndHTML5Be.HTML5Backend,\n };\n } else if (reactDndTouchBe) {\n dndExports = {\n ...reactDnD,\n ...reactDndTouchBe,\n ...reactDndHTML5Be,\n ReactDndBackend: reactDndTouchBe.TouchBackend,\n };\n } else {\n return;\n }\n setAdapter(() => createReactDnDAdapter(dndExports));\n } else {\n if (process.env.NODE_ENV !== 'production' && !didWarnEnabledDndWithoutReactDnD) {\n console.error(messages.errorEnabledDndWithoutReactDnD);\n didWarnEnabledDndWithoutReactDnD = true;\n }\n }\n }\n };\n\n if (!adapter) {\n loadDnD();\n }\n\n return () => {\n didCancel = true;\n };\n }, [adapter, skip]);\n\n return skip ? null : adapter;\n};\n\n/**\n * @group Hooks\n * @deprecated Use `createReactDnDAdapter` instead. This hook is kept for backward compatibility.\n */\nexport const useReactDnD = (dndParam?: DndProp): UseReactDnD | null => {\n const [dnd, setDnd] = useState(dndParam ?? null);\n\n useEffect(() => {\n let didCancel = false;\n\n const getDnD = async () => {\n const [reactDnD, reactDndHTML5Be, reactDndTouchBe] = await Promise.all(\n ['', '-html5-backend', '-touch-backend'].map(pn =>\n import(/* @vite-ignore */ `react-dnd${pn}`).catch(() => null)\n )\n );\n\n // v8 ignore else\n if (!didCancel) {\n if (reactDnD) {\n // Only prefer HTML5 backend if not touch device or we don't have the touch backend\n // (Can't test this since jsdom unconditionally defines `window.ontouchstart`.)\n // v8 ignore next\n if (reactDndHTML5Be && (!reactDndTouchBe || (reactDndTouchBe && !isTouchDevice()))) {\n setDnd(() => ({\n ...reactDnD,\n ...reactDndHTML5Be,\n ...reactDndTouchBe,\n ReactDndBackend: reactDndHTML5Be.HTML5Backend,\n }));\n } else if (reactDndTouchBe) {\n setDnd(() => ({\n ...reactDnD,\n ...reactDndTouchBe,\n ...reactDndHTML5Be,\n ReactDndBackend: reactDndTouchBe.TouchBackend,\n }));\n }\n } else {\n // v8 ignore else\n if (process.env.NODE_ENV !== 'production' && !didWarnEnabledDndWithoutReactDnD) {\n console.error(messages.errorEnabledDndWithoutReactDnD);\n didWarnEnabledDndWithoutReactDnD = true;\n }\n }\n }\n };\n\n if (!dnd) {\n getDnD();\n }\n\n return () => {\n didCancel = true;\n };\n }, [dnd]);\n\n // v8 ignore next\n if (dnd && !dnd.ReactDndBackend) {\n // Prefer touch backend if this is a touch device\n dnd.ReactDndBackend = isTouchDevice()\n ? (dnd.TouchBackend ?? dnd.HTML5Backend)\n : (dnd.HTML5Backend ?? dnd.TouchBackend);\n }\n\n return dnd as UseReactDnD;\n};\n","import { useContext } from 'react';\nimport type { RuleGroupTypeAny } from 'react-querybuilder';\nimport { DragPreviewContext } from './DragPreviewContext';\n\n/**\n * Hook for consuming the shadow query during an active drag with\n * `updateWhileDragging` enabled.\n *\n * @returns The shadow query if a drag is in progress, otherwise `undefined`.\n *\n * @group Hooks\n */\nexport const useShadowQuery = (): RuleGroupTypeAny | undefined => {\n const { dragPreviewState } = useContext(DragPreviewContext);\n return dragPreviewState?.shadowQuery;\n};\n"],"mappings":"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"}