@react-querybuilder/dnd
Version:
Drag-and-drop-enabled version of react-querybuilder
760 lines (743 loc) • 28.6 kB
JavaScript
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