UNPKG

@react-querybuilder/dnd

Version:

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

1 lines 14.6 kB
{"version":3,"file":"react-dnd-Ded7Ym3k.mjs","names":[],"sources":["../src/isTouchDevice.ts","../src/adapters/react-dnd.tsx"],"sourcesContent":["/* v8 ignore file -- @preserve */\n/* oxlint-disable prefer-global-this */\n\nexport const isTouchDevice = (): boolean =>\n (typeof window !== 'undefined' && 'ontouchstart' in window) ||\n (typeof navigator !== 'undefined' && navigator.maxTouchPoints > 0);\n","import * as React from 'react';\nimport { useRef } from 'react';\nimport type { ConnectDragPreview, ConnectDragSource, useDrag as useDragOriginal } from 'react-dnd';\nimport type * as ReactDnD from 'react-dnd';\nimport type * as ReactDndHtml5Backend from 'react-dnd-html5-backend';\nimport type {\n DndDropTargetType,\n DragCollection,\n DraggedItem,\n DropCollection,\n DropResult,\n RuleGroupTypeAny,\n RuleType,\n} from 'react-querybuilder';\nimport { findPath } 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 handleDrop,\n} from '../dndLogic';\nimport { isHotkeyPressed } from '../isHotkeyPressed';\nimport { isTouchDevice } from '../isTouchDevice';\nimport type { DndProp } from '../types';\n\ntype ReactDndBackendFactory = typeof ReactDndHtml5Backend.HTML5Backend;\n\nlet emptyImage: HTMLImageElement;\n\nconst getEmptyImage = (): HTMLImageElement => {\n if (!emptyImage) {\n emptyImage = new Image();\n emptyImage.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';\n }\n return emptyImage;\n};\n\nconst ruleGroupAndRuleAccept: [DndDropTargetType, DndDropTargetType] = ['rule', 'ruleGroup'];\n\n// #region Internal hooks\n\nconst useRuleDragCommon = (\n params: DndAdapterRuleDnDParams | DndAdapterRuleGroupDnDParams,\n type: DndDropTargetType,\n useDrag: typeof useDragOriginal\n): [DragCollection, ConnectDragSource, ConnectDragPreview] =>\n useDrag<DraggedItem, DropResult, DragCollection>(\n () => ({\n type,\n item: () => ({\n ...findPath(params.path, params.schema.getQuery())!,\n path: params.path,\n qbId: params.schema.qbId,\n }),\n canDrag: !params.disabled,\n previewOptions: { captureDraggingState: !!params.hideDefaultDragPreview },\n collect: monitor => ({\n isDragging: !params.disabled && monitor.isDragging(),\n dragMonitorId: monitor.getHandlerId() ?? '',\n }),\n end: (item, monitor) => {\n handleDrop({\n item,\n dropResult: monitor.getDropResult(),\n schema: params.schema,\n actions: params.actions,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n onRuleDrop: params.onRuleDrop,\n });\n },\n }),\n [params.actions.groupRule, params.actions.moveRule, params.disabled, params.path]\n );\n\n// #endregion\n\n/**\n * Creates a {@link DndAdapter} backed by `react-dnd`.\n *\n * @example\n * ```tsx\n * import { QueryBuilderDnD } from '@react-querybuilder/dnd';\n * import { createReactDnDAdapter } from '@react-querybuilder/dnd/react-dnd';\n * import * as ReactDnD from 'react-dnd';\n * import * as ReactDnDHTML5Backend from 'react-dnd-html5-backend';\n *\n * const adapter = createReactDnDAdapter({ ...ReactDnD, ...ReactDnDHTML5Backend });\n *\n * <QueryBuilderDnD dnd={adapter}>\n * <QueryBuilder />\n * </QueryBuilderDnD>\n * ```\n *\n * @group DnD\n */\nexport const createReactDnDAdapter = (dndExports: DndProp): DndAdapter => {\n const {\n useDrag,\n useDrop,\n DndProvider: RDndProvider,\n DndContext,\n } = dndExports as typeof ReactDnD & DndProp;\n\n // Select backend: prefer touch on touch devices\n let backend: ReactDndBackendFactory | undefined = dndExports.ReactDndBackend;\n if (!backend) {\n // v8 ignore next -- jsdom unconditionally defines `window.ontouchstart`\n backend = isTouchDevice()\n ? (dndExports.TouchBackend ?? dndExports.HTML5Backend)\n : (dndExports.HTML5Backend ?? dndExports.TouchBackend);\n }\n\n const DndProvider = ({ debugMode, children }: DndAdapterProviderProps): React.JSX.Element => (\n <RDndProvider backend={backend!} debugMode={debugMode}>\n <DndContext.Consumer>{() => <>{children}</>}</DndContext.Consumer>\n </RDndProvider>\n );\n\n const useRuleDnD = (params: DndAdapterRuleDnDParams): AdapterUseRuleDnDResult => {\n const dndRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<HTMLSpanElement>(null);\n\n const [{ isDragging, dragMonitorId }, drag, preview] = useRuleDragCommon(\n params,\n 'rule',\n useDrag\n );\n\n const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop<\n DraggedItem,\n DropResult,\n DropCollection\n >(\n () => ({\n accept: ruleGroupAndRuleAccept,\n canDrop: dragging =>\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 collect: monitor => ({\n dropNotAllowed: monitor.isOver() && !monitor.canDrop(),\n isOver: monitor.canDrop() && monitor.isOver(),\n dropMonitorId: monitor.getHandlerId() ?? '',\n dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n groupItems: isHotkeyPressed(params.groupModeModifierKey),\n }),\n drop: () =>\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 params.disabled,\n params.actions.moveRule,\n params.path,\n params.canDrop,\n params.rule,\n params.schema,\n ]\n );\n\n React.useEffect(() => {\n drag(dragRef);\n drop(dndRef);\n preview(params.hideDefaultDragPreview ? getEmptyImage() : dndRef);\n }, [drag, drop, params.hideDefaultDragPreview, preview]);\n\n return {\n isDragging,\n dragMonitorId,\n isOver,\n dropMonitorId,\n dndRef,\n dragRef,\n dropEffect,\n groupItems,\n dropNotAllowed,\n };\n };\n\n const useRuleGroupDnD = (params: DndAdapterRuleGroupDnDParams): AdapterUseRuleGroupDnDResult => {\n const previewRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<HTMLSpanElement>(null);\n const dropRef = useRef<HTMLDivElement>(null);\n\n const [{ isDragging, dragMonitorId }, drag, preview] = useRuleDragCommon(\n params,\n 'ruleGroup',\n useDrag\n );\n\n const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop<\n DraggedItem,\n DropResult,\n DropCollection\n >(\n () => ({\n accept: ruleGroupAndRuleAccept,\n canDrop: dragging =>\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 collect: monitor => ({\n dropNotAllowed: monitor.isOver() && !monitor.canDrop(),\n isOver: monitor.canDrop() && monitor.isOver(),\n dropMonitorId: monitor.getHandlerId() ?? '',\n dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n groupItems: isHotkeyPressed(params.groupModeModifierKey),\n }),\n drop: () =>\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 params.disabled,\n params.actions.groupRule,\n params.actions.moveRule,\n params.path,\n params.canDrop,\n params.ruleGroup,\n params.schema,\n ]\n );\n\n React.useEffect(() => {\n if (params.path.length > 0) {\n drag(dragRef);\n preview(params.hideDefaultDragPreview ? getEmptyImage() : previewRef);\n }\n drop(dropRef);\n }, [drag, drop, params.hideDefaultDragPreview, params.path.length, preview]);\n\n return {\n isDragging,\n dragMonitorId,\n isOver,\n dropMonitorId,\n previewRef,\n dragRef,\n dropRef,\n dropEffect,\n groupItems,\n dropNotAllowed,\n };\n };\n\n const useInlineCombinatorDnD = (\n params: DndAdapterInlineCombinatorDnDParams\n ): AdapterUseInlineCombinatorDnDResult => {\n const dropRef = useRef<HTMLDivElement>(null);\n\n // The \"hovering\" item is the rule or group which precedes 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 [{ isOver, dropMonitorId, dropEffect, dropNotAllowed }, drop] = useDrop<\n DraggedItem,\n DropResult,\n DropCollection\n >(\n () => ({\n accept: ['rule', 'ruleGroup'] as DndDropTargetType[],\n canDrop: dragging =>\n canDropOnInlineCombinator({\n dragging,\n path: params.path,\n schema: params.schema,\n canDrop: params.canDrop,\n groupModeModifierKey: params.groupModeModifierKey,\n hoveringItem,\n }),\n collect: monitor => ({\n dropNotAllowed: monitor.isOver() && !monitor.canDrop(),\n isOver: monitor.canDrop() && monitor.isOver(),\n dropMonitorId: monitor.getHandlerId() ?? '',\n dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? 'copy' : 'move',\n groupItems: isHotkeyPressed(params.groupModeModifierKey),\n }),\n drop: () =>\n buildDropResult({\n type: 'inlineCombinator',\n path: params.path,\n schema: params.schema,\n copyModeModifierKey: params.copyModeModifierKey,\n groupModeModifierKey: params.groupModeModifierKey,\n }),\n }),\n [params.canDrop, hoveringItem, params.path, params.schema]\n );\n\n drop(dropRef);\n\n return { dropRef, dropMonitorId, isOver, dropEffect, dropNotAllowed };\n };\n\n return {\n DndProvider,\n useRuleDnD,\n useRuleGroupDnD,\n useInlineCombinatorDnD,\n };\n};\n"],"mappings":"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"}