UNPKG

@react-querybuilder/dnd

Version:

Drag-and-drop-enabled version of react-querybuilder

760 lines (743 loc) 28.6 kB
import * as React from "react"; import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react"; import { QueryBuilderContext, TestID, add, defaultControlElements, findPath, getParentPath, group, insert, isAncestor, lc, messages, pathsAreEqual, preferAnyProp, preferProp, standardClassnames, useMergedContext } from "react-querybuilder"; //#region src/isHotkeyPressed.ts /** * Adapted from * https://github.com/JohannesKlauss/react-hotkeys-hook/blob/bc55a281f1d212d09de786aeb5cd236c58d9531d/src/isHotkeyPressed.ts * and * https://github.com/JohannesKlauss/react-hotkeys-hook/blob/bc55a281f1d212d09de786aeb5cd236c58d9531d/src/parseHotkey.ts */ const reservedModifierKeywords = new Set([ "shift", "alt", "meta", "mod", "ctrl" ]); const mappedKeys = { esc: "escape", return: "enter", ".": "period", ",": "comma", "-": "slash", " ": "space", "`": "backquote", "#": "backslash", "+": "bracketright", ShiftLeft: "shift", ShiftRight: "shift", AltLeft: "alt", AltRight: "alt", MetaLeft: "meta", MetaRight: "meta", OSLeft: "meta", OSRight: "meta", ControlLeft: "ctrl", ControlRight: "ctrl" }; const mapKey = (key) => lc((key && mappedKeys[key] || key || "").trim()).replace(/key|digit|numpad|arrow/, ""); const isHotkeyModifier = (key) => reservedModifierKeywords.has(key); const keyAliases = { "⌘": "meta", cmd: "meta", command: "meta", "⊞": "meta", win: "meta", windows: "meta", "⇧": "shift", "⌥": "alt", "⌃": "ctrl", control: "ctrl" }; (() => { if (typeof document !== "undefined") { document.addEventListener("keydown", (e) => { if (e.key === void 0) return; pushToCurrentlyPressedKeys([mapKey(e.key), mapKey(e.code)]); }); document.addEventListener("keyup", (e) => { if (e.key === void 0) return; removeFromCurrentlyPressedKeys([mapKey(e.key), mapKey(e.code)]); }); } if (typeof window !== "undefined") window.addEventListener("blur", () => { currentlyPressedKeys.clear(); }); })(); const currentlyPressedKeys = /* @__PURE__ */ new Set(); const isReadonlyArray = (value) => Array.isArray(value); const isHotkeyPressed = (key, splitKey = ",") => (isReadonlyArray(key) ? key : key.split(splitKey)).every((hotkey) => { var _keyAliases$hk; const hk = lc(hotkey.trim()); return currentlyPressedKeys.has((_keyAliases$hk = keyAliases[hk]) !== null && _keyAliases$hk !== void 0 ? _keyAliases$hk : hk); }); const pushToCurrentlyPressedKeys = (key) => { const hotkeyArray = Array.isArray(key) ? key : [key]; if (currentlyPressedKeys.has("meta")) { for (const key$1 of currentlyPressedKeys) if (!isHotkeyModifier(key$1)) currentlyPressedKeys.delete(lc(key$1)); } for (const hotkey of hotkeyArray) currentlyPressedKeys.add(lc(hotkey)); }; const removeFromCurrentlyPressedKeys = (key) => { const hotkeyArray = Array.isArray(key) ? key : [key]; if (key === "meta") currentlyPressedKeys.clear(); else for (const hotkey of hotkeyArray) currentlyPressedKeys.delete(lc(hotkey)); }; //#endregion //#region src/QueryBuilderDndContext.ts const { rule, ruleGroup, combinatorSelector } = defaultControlElements; /** * @group Components */ const QueryBuilderDndContext = createContext({ baseControls: { rule, ruleGroup, combinatorSelector } }); //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/objectWithoutPropertiesLoose.js function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/objectWithoutProperties.js function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) { return typeof o$1; } : function(o$1) { return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1; }, _typeof(o); } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/toPrimitive.js function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/toPropertyKey.js function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/defineProperty.js function _defineProperty(e, r, t) { return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } //#endregion //#region \0@oxc-project+runtime@0.99.0/helpers/objectSpread2.js function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function(r$1) { return Object.getOwnPropertyDescriptor(e, r$1).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) { _defineProperty(e, r$1, t[r$1]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) { Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1)); }); } return e; } //#endregion //#region src/InlineCombinatorDnD.tsx const _excluded = ["component"]; /** * The drag-and-drop-enabled inline combinator component. * * @group Components */ const InlineCombinatorDnD = (_ref) => { let { component: CombinatorSelectorComponent } = _ref, props = _objectWithoutProperties(_ref, _excluded); const { canDrop, useDrop, copyModeModifierKey, groupModeModifierKey } = useContext(QueryBuilderDndContext); const { dropRef, dropMonitorId, isOver } = useInlineCombinatorDnD(_objectSpread2(_objectSpread2({}, props), {}, { component: CombinatorSelectorComponent, useDrop, canDrop, copyModeModifierKey, groupModeModifierKey })); const wrapperClassName = [ props.schema.suppressStandardClassnames || standardClassnames.betweenRules, isOver && !props.schema.classNames.dndOver || false, isOver && !props.schema.suppressStandardClassnames && standardClassnames.dndOver || false ].filter((c) => typeof c === "string").join(" "); return /* @__PURE__ */ React.createElement("div", { key: "dnd", ref: dropRef, className: wrapperClassName, "data-dropmonitorid": dropMonitorId, "data-testid": TestID.inlineCombinator }, /* @__PURE__ */ React.createElement(CombinatorSelectorComponent, _objectSpread2(_objectSpread2({}, props), {}, { testID: TestID.combinators }))); }; /** * @group Hooks */ const useInlineCombinatorDnD = (params) => { const dropRef = useRef(null); const { path, canDrop, schema, useDrop, rules, copyModeModifierKey = "alt", groupModeModifierKey = "ctrl" } = params; const hoveringItem = (rules !== null && rules !== void 0 ? rules : [])[path.at(-1) - 1]; const [{ isOver, dropMonitorId, dropEffect, dropNotAllowed }, drop] = useDrop(() => ({ accept: ["rule", "ruleGroup"], canDrop: (dragging) => { const { path: itemPath } = dragging; if (isHotkeyPressed(groupModeModifierKey) || dragging && typeof canDrop === "function" && !canDrop({ dragging, hovering: _objectSpread2(_objectSpread2({}, hoveringItem), {}, { path, qbId: schema.qbId }) })) return false; const parentHoverPath = getParentPath(path); const parentItemPath = getParentPath(itemPath); const hoverIndex = path.at(-1); const itemIndex = itemPath.at(-1); return !(isAncestor(itemPath, path) || pathsAreEqual(itemPath, path) || pathsAreEqual(parentHoverPath, parentItemPath) && hoverIndex - 1 === itemIndex || schema.independentCombinators && pathsAreEqual(parentHoverPath, parentItemPath) && hoverIndex === itemIndex - 1); }, collect: (monitor) => { var _monitor$getHandlerId; return { dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: (_monitor$getHandlerId = monitor.getHandlerId()) !== null && _monitor$getHandlerId !== void 0 ? _monitor$getHandlerId : "", dropEffect: isHotkeyPressed(copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(groupModeModifierKey) }; }, drop: () => { const { qbId, getQuery, dispatchQuery } = schema; const dropEffect$1 = isHotkeyPressed(copyModeModifierKey) ? "copy" : "move"; return { type: "inlineCombinator", path, qbId, getQuery, dispatchQuery, groupItems: isHotkeyPressed(groupModeModifierKey), dropEffect: dropEffect$1 }; } }), [ canDrop, hoveringItem, path, schema ]); drop(dropRef); return { dropRef, dropMonitorId, isOver, dropEffect, dropNotAllowed }; }; //#endregion //#region src/isTouchDevice.ts /* istanbul ignore file */ const isTouchDevice = () => typeof window !== "undefined" && "ontouchstart" in window || typeof navigator !== "undefined" && navigator.maxTouchPoints > 0; //#endregion //#region src/getEmptyImage.ts let emptyImage; const getEmptyImage = () => { if (!emptyImage) { emptyImage = new Image(); emptyImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; } return emptyImage; }; //#endregion //#region src/useDragCommon.ts /** * @group Hooks */ const useDragCommon = ({ type, path, disabled, actions, schema, useDrag, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview }) => useDrag(() => ({ type, item: () => _objectSpread2(_objectSpread2({}, findPath(path, schema.getQuery())), {}, { path, qbId: schema.qbId }), canDrag: !disabled, previewOptions: { captureDraggingState: !!hideDefaultDragPreview }, collect: (monitor) => { var _monitor$getHandlerId; return { isDragging: !disabled && monitor.isDragging(), dragMonitorId: (_monitor$getHandlerId = monitor.getHandlerId()) !== null && _monitor$getHandlerId !== void 0 ? _monitor$getHandlerId : "" }; }, end: (item, monitor) => { const dropResult = monitor.getDropResult(); if (!dropResult) return; const dropEffect = isHotkeyPressed(copyModeModifierKey) ? "copy" : "move"; const groupItems = isHotkeyPressed(groupModeModifierKey); const parentHoverPath = getParentPath(dropResult.path); const hoverIndex = dropResult.path.at(-1); const destinationPath = groupItems ? dropResult.path : dropResult.type === "ruleGroup" ? [...dropResult.path, 0] : dropResult.type === "inlineCombinator" ? [...parentHoverPath, hoverIndex] : [...parentHoverPath, hoverIndex + 1]; if (schema.qbId === dropResult.qbId) if (groupItems) actions.groupRule(item.path, destinationPath, dropEffect === "copy"); else actions.moveRule(item.path, destinationPath, dropEffect === "copy"); else { const otherBuilderQuery = dropResult.getQuery(); // istanbul ignore else if (otherBuilderQuery) { if (groupItems) dropResult.dispatchQuery(group(add(otherBuilderQuery, item, []), [otherBuilderQuery.rules.length], destinationPath, { clone: false })); else dropResult.dispatchQuery(insert(otherBuilderQuery, item, destinationPath)); // istanbul ignore else if (dropEffect !== "copy") actions.onRuleRemove(item.path); } } } }), [ actions.groupRule, actions.moveRule, disabled, path ]); //#endregion //#region src/RuleDnD.tsx /** * Rule component for drag-and-drop. Renders the provided rule component * ({@link react-querybuilder!Rule Rule} by default), but forwards the * drag-and-drop context. * * @group Components */ const RuleDnD = (props) => { const rqbDndContext = useContext(QueryBuilderDndContext); const { canDrop, useDrag, useDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview } = rqbDndContext; const disabled = !!props.parentDisabled || !!props.disabled; const dndRefs = useRuleDnD(_objectSpread2(_objectSpread2({}, props), {}, { disabled, useDrag, useDrop, canDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview })); const { rule: BaseRuleComponent } = rqbDndContext.baseControls; return /* @__PURE__ */ React.createElement(QueryBuilderDndContext.Provider, { value: rqbDndContext }, /* @__PURE__ */ React.createElement(BaseRuleComponent, _objectSpread2(_objectSpread2({}, props), dndRefs))); }; const accept$1 = ["rule", "ruleGroup"]; /** * @group Hooks */ const useRuleDnD = (params) => { const dndRef = useRef(null); const dragRef = useRef(null); const { path, rule: rule$1, disabled, schema, actions, useDrag, useDrop, canDrop, copyModeModifierKey = "alt", groupModeModifierKey = "ctrl", hideDefaultDragPreview } = params; const [{ isDragging, dragMonitorId }, drag, preview] = useDragCommon({ type: "rule", path, disabled, independentCombinators: schema.independentCombinators, schema, actions, useDrag, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview }); const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop(() => ({ accept: accept$1, canDrop: (dragging) => { if (isHotkeyPressed(groupModeModifierKey) && disabled || dragging && typeof canDrop === "function" && !canDrop({ dragging, hovering: _objectSpread2(_objectSpread2({}, rule$1), {}, { path, qbId: schema.qbId }) })) return false; if (schema.qbId !== dragging.qbId) return true; const parentHoverPath = getParentPath(path); const parentItemPath = getParentPath(dragging.path); const hoverIndex = path.at(-1); const itemIndex = dragging.path.at(-1); return !(isAncestor(dragging.path, path) || pathsAreEqual(path, dragging.path) || !isHotkeyPressed(groupModeModifierKey) && pathsAreEqual(parentHoverPath, parentItemPath) && (hoverIndex === itemIndex - 1 || schema.independentCombinators && hoverIndex === itemIndex - 2)); }, collect: (monitor) => { var _monitor$getHandlerId; return { dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: (_monitor$getHandlerId = monitor.getHandlerId()) !== null && _monitor$getHandlerId !== void 0 ? _monitor$getHandlerId : "", dropEffect: isHotkeyPressed(copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(groupModeModifierKey) }; }, drop: () => { const { qbId, getQuery, dispatchQuery } = schema; const dropEffect$1 = isHotkeyPressed(copyModeModifierKey) ? "copy" : "move"; return { type: "rule", path, qbId, getQuery, dispatchQuery, groupItems: isHotkeyPressed(groupModeModifierKey), dropEffect: dropEffect$1 }; } }), [ disabled, actions.moveRule, path, canDrop, rule$1, schema ]); React.useEffect(() => { drag(dragRef); drop(dndRef); preview(hideDefaultDragPreview ? getEmptyImage() : dndRef); }, [ drag, drop, hideDefaultDragPreview, preview ]); return { isDragging, dragMonitorId, isOver, dropMonitorId, dndRef, dragRef, dropEffect, groupItems, dropNotAllowed }; }; //#endregion //#region src/RuleGroupDnD.tsx /** * Rule group component for drag-and-drop. Renders the provided rule group component * ({@link react-querybuilder!RuleGroup RuleGroup} by default), but forwards the drag-and-drop * context so that child rules and groups will render within the appropriate drag-and-drop wrappers. * * @group Components */ const RuleGroupDnD = (props) => { const { canDrop, baseControls: { ruleGroup: BaseRuleGroupComponent }, useDrag, useDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview } = useContext(QueryBuilderDndContext); const dndRefs = useRuleGroupDnD(_objectSpread2(_objectSpread2({}, props), {}, { disabled: !!props.parentDisabled || !!props.disabled, useDrag, useDrop, canDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview })); return /* @__PURE__ */ React.createElement(BaseRuleGroupComponent, _objectSpread2(_objectSpread2({}, props), dndRefs)); }; const accept = ["rule", "ruleGroup"]; /** * @group Hooks */ const useRuleGroupDnD = (params) => { const previewRef = useRef(null); const dragRef = useRef(null); const dropRef = useRef(null); const { disabled, path, ruleGroup: ruleGroup$1, schema, actions, useDrag, useDrop, canDrop, copyModeModifierKey = "alt", groupModeModifierKey = "ctrl", hideDefaultDragPreview } = params; const [{ isDragging, dragMonitorId }, drag, preview] = useDragCommon({ type: "ruleGroup", path, disabled, independentCombinators: schema.independentCombinators, schema, actions, useDrag, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview }); const [{ isOver, dropMonitorId, dropEffect, groupItems, dropNotAllowed }, drop] = useDrop(() => ({ accept, canDrop: (dragging) => { if (disabled || dragging && typeof canDrop === "function" && !canDrop({ dragging, hovering: _objectSpread2(_objectSpread2({}, ruleGroup$1), {}, { path, qbId: schema.qbId }) })) return false; if (schema.qbId !== dragging.qbId) return true; const parentItemPath = getParentPath(dragging.path); const itemIndex = dragging.path.at(-1); return !(isAncestor(dragging.path, path) || pathsAreEqual(path, parentItemPath) && itemIndex === 0 || pathsAreEqual(path, dragging.path)); }, collect: (monitor) => { var _monitor$getHandlerId; return { dropNotAllowed: monitor.isOver() && !monitor.canDrop(), isOver: monitor.canDrop() && monitor.isOver(), dropMonitorId: (_monitor$getHandlerId = monitor.getHandlerId()) !== null && _monitor$getHandlerId !== void 0 ? _monitor$getHandlerId : "", dropEffect: isHotkeyPressed(copyModeModifierKey) ? "copy" : "move", groupItems: isHotkeyPressed(groupModeModifierKey) }; }, drop: () => { const { qbId, getQuery, dispatchQuery } = schema; const dropEffect$1 = isHotkeyPressed(copyModeModifierKey) ? "copy" : "move"; return { type: "ruleGroup", path, qbId, getQuery, dispatchQuery, groupItems: isHotkeyPressed(groupModeModifierKey), dropEffect: dropEffect$1 }; } }), [ disabled, actions.groupRule, actions.moveRule, path, canDrop, ruleGroup$1, schema ]); React.useEffect(() => { if (path.length > 0) { drag(dragRef); preview(hideDefaultDragPreview ? getEmptyImage() : previewRef); } drop(dropRef); }, [ drag, drop, hideDefaultDragPreview, path.length, preview ]); return { isDragging, dragMonitorId, isOver, dropMonitorId, previewRef, dragRef, dropRef, dropEffect, groupItems, dropNotAllowed }; }; //#endregion //#region src/QueryBuilderDnD.tsx const emptyObject = {}; /** * Context provider to enable drag-and-drop. If the application already implements * `react-dnd`, use {@link QueryBuilderDndWithoutProvider} instead. * * @group Components */ const QueryBuilderDnD = (props) => { const { controlClassnames, controlElements, debugMode, enableDragAndDrop: enableDragAndDropProp, enableMountQueryChange, translations } = props; const rqbContext = useMergedContext({ controlClassnames, controlElements, debugMode, enableDragAndDrop: enableDragAndDropProp !== null && enableDragAndDropProp !== void 0 ? enableDragAndDropProp : true, enableMountQueryChange, translations: translations !== null && translations !== void 0 ? translations : {} }); const { enableDragAndDrop } = rqbContext; const dnd = useReactDnD(props.dnd); const key = enableDragAndDrop && dnd ? "dnd" : "no-dnd"; const { DndProvider, ReactDndBackend } = dnd !== null && dnd !== void 0 ? dnd : emptyObject; const contextWithoutDnD = useMemo(() => _objectSpread2(_objectSpread2({}, rqbContext), {}, { enableDragAndDrop: false, debugMode }), [rqbContext, debugMode]); const contextWithDnD = useMemo(() => _objectSpread2(_objectSpread2({}, rqbContext), {}, { enableDragAndDrop, debugMode }), [ rqbContext, debugMode, enableDragAndDrop ]); if (!enableDragAndDrop || !dnd || !DndProvider || !ReactDndBackend) return /* @__PURE__ */ React.createElement(QueryBuilderContext.Provider, { key, value: contextWithoutDnD }, props.children); return /* @__PURE__ */ React.createElement(DndProvider, { key, backend: ReactDndBackend, debugMode }, /* @__PURE__ */ React.createElement(QueryBuilderContext.Provider, { key, value: contextWithDnD }, /* @__PURE__ */ React.createElement(QueryBuilderDndWithoutProvider, { dnd, canDrop: props.canDrop, copyModeModifierKey: props.copyModeModifierKey, groupModeModifierKey: props.groupModeModifierKey, hideDefaultDragPreview: props.hideDefaultDragPreview }, props.children))); }; /** * Context provider to enable drag-and-drop. Only use this provider if the application * already implements `react-dnd`, otherwise use {@link QueryBuilderDnD}. * * @group Components */ const QueryBuilderDndWithoutProvider = (props) => { var _props$controlElement7, _props$controlElement8, _props$controlElement9, _rqbContext$controlEl4, _rqbContext$controlEl5, _rqbContext$controlEl6; const rqbContext = useContext(QueryBuilderContext); const rqbDndContext = useContext(QueryBuilderDndContext); const dnd = useReactDnD(props.dnd); const copyModeModifierKey = preferAnyProp(void 0, props.copyModeModifierKey, rqbDndContext.copyModeModifierKey); const groupModeModifierKey = preferAnyProp(void 0, props.groupModeModifierKey, rqbDndContext.groupModeModifierKey); const enableDragAndDrop = preferProp(true, props.enableDragAndDrop, rqbContext.enableDragAndDrop); const debugMode = preferProp(false, props.debugMode, rqbContext.debugMode); const hideDefaultDragPreview = preferProp(false, props.hideDefaultDragPreview, rqbDndContext.hideDefaultDragPreview); const canDrop = preferAnyProp(void 0, props.canDrop, rqbDndContext.canDrop); const key = enableDragAndDrop && dnd ? "dnd" : "no-dnd"; const baseControls = useMemo(() => { var _ref, _props$controlElement, _props$controlElement2, _rqbContext$controlEl, _ref2, _props$controlElement3, _props$controlElement4, _rqbContext$controlEl2, _ref3, _props$controlElement5, _props$controlElement6, _rqbContext$controlEl3; return { rule: (_ref = (_props$controlElement = (_props$controlElement2 = props.controlElements) === null || _props$controlElement2 === void 0 ? void 0 : _props$controlElement2.rule) !== null && _props$controlElement !== void 0 ? _props$controlElement : (_rqbContext$controlEl = rqbContext.controlElements) === null || _rqbContext$controlEl === void 0 ? void 0 : _rqbContext$controlEl.rule) !== null && _ref !== void 0 ? _ref : rqbDndContext.baseControls.rule, ruleGroup: (_ref2 = (_props$controlElement3 = (_props$controlElement4 = props.controlElements) === null || _props$controlElement4 === void 0 ? void 0 : _props$controlElement4.ruleGroup) !== null && _props$controlElement3 !== void 0 ? _props$controlElement3 : (_rqbContext$controlEl2 = rqbContext.controlElements) === null || _rqbContext$controlEl2 === void 0 ? void 0 : _rqbContext$controlEl2.ruleGroup) !== null && _ref2 !== void 0 ? _ref2 : rqbDndContext.baseControls.ruleGroup, combinatorSelector: (_ref3 = (_props$controlElement5 = (_props$controlElement6 = props.controlElements) === null || _props$controlElement6 === void 0 ? void 0 : _props$controlElement6.combinatorSelector) !== null && _props$controlElement5 !== void 0 ? _props$controlElement5 : (_rqbContext$controlEl3 = rqbContext.controlElements) === null || _rqbContext$controlEl3 === void 0 ? void 0 : _rqbContext$controlEl3.combinatorSelector) !== null && _ref3 !== void 0 ? _ref3 : rqbDndContext.baseControls.combinatorSelector }; }, [ (_props$controlElement7 = props.controlElements) === null || _props$controlElement7 === void 0 ? void 0 : _props$controlElement7.combinatorSelector, (_props$controlElement8 = props.controlElements) === null || _props$controlElement8 === void 0 ? void 0 : _props$controlElement8.rule, (_props$controlElement9 = props.controlElements) === null || _props$controlElement9 === void 0 ? void 0 : _props$controlElement9.ruleGroup, (_rqbContext$controlEl4 = rqbContext.controlElements) === null || _rqbContext$controlEl4 === void 0 ? void 0 : _rqbContext$controlEl4.combinatorSelector, (_rqbContext$controlEl5 = rqbContext.controlElements) === null || _rqbContext$controlEl5 === void 0 ? void 0 : _rqbContext$controlEl5.rule, (_rqbContext$controlEl6 = rqbContext.controlElements) === null || _rqbContext$controlEl6 === void 0 ? void 0 : _rqbContext$controlEl6.ruleGroup, rqbDndContext.baseControls.combinatorSelector, rqbDndContext.baseControls.rule, rqbDndContext.baseControls.ruleGroup ]); const newContext = useMemo(() => _objectSpread2(_objectSpread2({}, rqbContext), {}, { enableDragAndDrop, debugMode, controlElements: _objectSpread2(_objectSpread2({}, rqbContext.controlElements), {}, { ruleGroup: RuleGroupDnD, rule: RuleDnD, inlineCombinator: InlineCombinatorDnD }) }), [ debugMode, enableDragAndDrop, rqbContext ]); const { DndContext, useDrag, useDrop } = dnd !== null && dnd !== void 0 ? dnd : {}; const dndContextValue = useMemo(() => ({ baseControls, canDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview, useDrag, useDrop }), [ baseControls, canDrop, copyModeModifierKey, groupModeModifierKey, hideDefaultDragPreview, useDrag, useDrop ]); const contextWithoutDnD = useMemo(() => _objectSpread2(_objectSpread2({}, rqbContext), {}, { enableDragAndDrop: false, debugMode }), [rqbContext, debugMode]); if (!enableDragAndDrop || !DndContext) return /* @__PURE__ */ React.createElement(QueryBuilderContext.Provider, { key, value: contextWithoutDnD }, props.children); return /* @__PURE__ */ React.createElement(DndContext.Consumer, { key }, () => /* @__PURE__ */ React.createElement(QueryBuilderContext.Provider, { key, value: newContext }, /* @__PURE__ */ React.createElement(QueryBuilderDndContext.Provider, { value: dndContextValue }, props.children))); }; let didWarnEnabledDndWithoutReactDnD = false; /** * @group Hooks */ const useReactDnD = (dndParam) => { const [dnd, setDnd] = useState(dndParam !== null && dndParam !== void 0 ? dndParam : null); useEffect(() => { let didCancel = false; const getDnD = async () => { const [reactDnD, reactDndHTML5Be, reactDndTouchBe] = await Promise.all([ "", "-html5-backend", "-touch-backend" ].map((pn) => import( /* @vite-ignore */ `react-dnd${pn}` ).catch(() => null))); // istanbul ignore else if (!didCancel) { if (reactDnD) { // istanbul ignore next if (reactDndHTML5Be && (!reactDndTouchBe || reactDndTouchBe && !isTouchDevice())) setDnd(() => _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, reactDnD), reactDndHTML5Be), reactDndTouchBe), {}, { ReactDndBackend: reactDndHTML5Be.HTML5Backend })); else if (reactDndTouchBe) setDnd(() => _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, reactDnD), reactDndTouchBe), reactDndHTML5Be), {}, { ReactDndBackend: reactDndTouchBe.TouchBackend })); } else if (process.env.NODE_ENV !== "production" && !didWarnEnabledDndWithoutReactDnD) { console.error(messages.errorEnabledDndWithoutReactDnD); didWarnEnabledDndWithoutReactDnD = true; } } }; if (!dnd) getDnD(); return () => { didCancel = true; }; }, [dnd]); // istanbul ignore next if (dnd && !dnd.ReactDndBackend) { var _dnd$TouchBackend, _dnd$HTML5Backend; dnd.ReactDndBackend = isTouchDevice() ? (_dnd$TouchBackend = dnd.TouchBackend) !== null && _dnd$TouchBackend !== void 0 ? _dnd$TouchBackend : dnd.HTML5Backend : (_dnd$HTML5Backend = dnd.HTML5Backend) !== null && _dnd$HTML5Backend !== void 0 ? _dnd$HTML5Backend : dnd.TouchBackend; } return dnd; }; //#endregion export { InlineCombinatorDnD, QueryBuilderDnD, QueryBuilderDndWithoutProvider, RuleDnD, RuleGroupDnD, useInlineCombinatorDnD, useReactDnD, useRuleDnD, useRuleGroupDnD }; //# sourceMappingURL=react-querybuilder_dnd.legacy-esm.js.map