UNPKG

@react-querybuilder/dnd

Version:

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

253 lines (252 loc) 7.67 kB
import { i as canDropOnRuleGroup, n as canDropOnInlineCombinator, o as handleDrop, r as canDropOnRule, s as isHotkeyPressed, t as buildDropResult } from "./dndLogic-Cg0Rq-DI.mjs"; import * as React from "react"; import { useRef } from "react"; import { findPath } from "react-querybuilder"; //#region src/isTouchDevice.ts /* v8 ignore file -- @preserve */ const isTouchDevice = () => typeof window !== "undefined" && "ontouchstart" in window || typeof navigator !== "undefined" && navigator.maxTouchPoints > 0; //#endregion //#region src/adapters/react-dnd.tsx let emptyImage; const getEmptyImage = () => { if (!emptyImage) { emptyImage = new Image(); emptyImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; } return emptyImage; }; const ruleGroupAndRuleAccept = ["rule", "ruleGroup"]; const useRuleDragCommon = (params, type, useDrag) => useDrag(() => ({ type, item: () => ({ ...findPath(params.path, params.schema.getQuery()), path: params.path, qbId: params.schema.qbId }), canDrag: !params.disabled, previewOptions: { captureDraggingState: !!params.hideDefaultDragPreview }, collect: (monitor) => ({ isDragging: !params.disabled && monitor.isDragging(), dragMonitorId: monitor.getHandlerId() ?? "" }), end: (item, monitor) => { handleDrop({ item, dropResult: monitor.getDropResult(), schema: params.schema, actions: params.actions, copyModeModifierKey: params.copyModeModifierKey, groupModeModifierKey: params.groupModeModifierKey, onRuleDrop: params.onRuleDrop }); } }), [ params.actions.groupRule, params.actions.moveRule, params.disabled, params.path ]); /** * Creates a {@link DndAdapter} backed by `react-dnd`. * * @example * ```tsx * import { QueryBuilderDnD } from '@react-querybuilder/dnd'; * import { createReactDnDAdapter } from '@react-querybuilder/dnd/react-dnd'; * import * as ReactDnD from 'react-dnd'; * import * as ReactDnDHTML5Backend from 'react-dnd-html5-backend'; * * const adapter = createReactDnDAdapter({ ...ReactDnD, ...ReactDnDHTML5Backend }); * * <QueryBuilderDnD dnd={adapter}> * <QueryBuilder /> * </QueryBuilderDnD> * ``` * * @group DnD */ const createReactDnDAdapter = (dndExports) => { const { useDrag, useDrop, DndProvider: RDndProvider, DndContext } = dndExports; let backend = dndExports.ReactDndBackend; if (!backend) // v8 ignore next -- jsdom unconditionally defines `window.ontouchstart` backend = isTouchDevice() ? dndExports.TouchBackend ?? dndExports.HTML5Backend : dndExports.HTML5Backend ?? dndExports.TouchBackend; const DndProvider = ({ debugMode, children }) => /* @__PURE__ */ React.createElement(RDndProvider, { backend, debugMode }, /* @__PURE__ */ React.createElement(DndContext.Consumer, null, () => /* @__PURE__ */ React.createElement(React.Fragment, null, children))); const useRuleDnD = (params) => { const dndRef = useRef(null); const dragRef = useRef(null); const [{ isDragging, dragMonitorId }, drag, preview] = useRuleDragCommon(params, "rule", useDrag); const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop(() => ({ accept: ruleGroupAndRuleAccept, canDrop: (dragging) => canDropOnRule({ dragging, path: params.path, schema: params.schema, canDrop: params.canDrop, groupModeModifierKey: params.groupModeModifierKey, disabled: params.disabled, rule: params.rule }), collect: (monitor) => ({ dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: monitor.getHandlerId() ?? "", dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(params.groupModeModifierKey) }), drop: () => buildDropResult({ type: "rule", path: params.path, schema: params.schema, copyModeModifierKey: params.copyModeModifierKey, groupModeModifierKey: params.groupModeModifierKey }) }), [ params.disabled, params.actions.moveRule, params.path, params.canDrop, params.rule, params.schema ]); React.useEffect(() => { drag(dragRef); drop(dndRef); preview(params.hideDefaultDragPreview ? getEmptyImage() : dndRef); }, [ drag, drop, params.hideDefaultDragPreview, preview ]); return { isDragging, dragMonitorId, isOver, dropMonitorId, dndRef, dragRef, dropEffect, groupItems, dropNotAllowed }; }; const useRuleGroupDnD = (params) => { const previewRef = useRef(null); const dragRef = useRef(null); const dropRef = useRef(null); const [{ isDragging, dragMonitorId }, drag, preview] = useRuleDragCommon(params, "ruleGroup", useDrag); const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop(() => ({ accept: ruleGroupAndRuleAccept, canDrop: (dragging) => canDropOnRuleGroup({ dragging, path: params.path, schema: params.schema, canDrop: params.canDrop, disabled: params.disabled, ruleGroup: params.ruleGroup }), collect: (monitor) => ({ dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: monitor.getHandlerId() ?? "", dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(params.groupModeModifierKey) }), drop: () => buildDropResult({ type: "ruleGroup", path: params.path, schema: params.schema, copyModeModifierKey: params.copyModeModifierKey, groupModeModifierKey: params.groupModeModifierKey }) }), [ params.disabled, params.actions.groupRule, params.actions.moveRule, params.path, params.canDrop, params.ruleGroup, params.schema ]); React.useEffect(() => { if (params.path.length > 0) { drag(dragRef); preview(params.hideDefaultDragPreview ? getEmptyImage() : previewRef); } drop(dropRef); }, [ drag, drop, params.hideDefaultDragPreview, params.path.length, preview ]); return { isDragging, dragMonitorId, isOver, dropMonitorId, previewRef, dragRef, dropRef, dropEffect, groupItems, dropNotAllowed }; }; const useInlineCombinatorDnD = (params) => { const dropRef = useRef(null); const hoveringItem = (params.rules ?? [])[params.path.at(-1) - 1]; const [{ isOver, dropMonitorId, dropEffect, dropNotAllowed }, drop] = useDrop(() => ({ accept: ["rule", "ruleGroup"], canDrop: (dragging) => canDropOnInlineCombinator({ dragging, path: params.path, schema: params.schema, canDrop: params.canDrop, groupModeModifierKey: params.groupModeModifierKey, hoveringItem }), collect: (monitor) => ({ dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: monitor.getHandlerId() ?? "", dropEffect: isHotkeyPressed(params.copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(params.groupModeModifierKey) }), drop: () => buildDropResult({ type: "inlineCombinator", path: params.path, schema: params.schema, copyModeModifierKey: params.copyModeModifierKey, groupModeModifierKey: params.groupModeModifierKey }) }), [ params.canDrop, hoveringItem, params.path, params.schema ]); drop(dropRef); return { dropRef, dropMonitorId, isOver, dropEffect, dropNotAllowed }; }; return { DndProvider, useRuleDnD, useRuleGroupDnD, useInlineCombinatorDnD }; }; //#endregion export { isTouchDevice as n, createReactDnDAdapter as t }; //# sourceMappingURL=react-dnd-llotf5dK.mjs.map