@react-querybuilder/dnd
Version:
Drag-and-drop-enabled version of react-querybuilder
679 lines (669 loc) • 21.9 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) => {
const hk = lc(hotkey.trim());
return currentlyPressedKeys.has(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 src/InlineCombinatorDnD.tsx
/**
* The drag-and-drop-enabled inline combinator component.
*
* @group Components
*/
const InlineCombinatorDnD = ({ component: CombinatorSelectorComponent, ...props }) => {
const { canDrop, useDrop, copyModeModifierKey, groupModeModifierKey } = useContext(QueryBuilderDndContext);
const { dropRef, dropMonitorId, isOver } = useInlineCombinatorDnD({
...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, {
...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 ?? [])[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: {
...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) => ({
dropNotAllowed: monitor.isOver() && !monitor.canDrop(),
isOver: monitor.canDrop() && monitor.isOver(),
dropMonitorId: 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: () => ({
...findPath(path, schema.getQuery()),
path,
qbId: schema.qbId
}),
canDrag: !disabled,
previewOptions: { captureDraggingState: !!hideDefaultDragPreview },
collect: (monitor) => ({
isDragging: !disabled && monitor.isDragging(),
dragMonitorId: 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({
...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, {
...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: {
...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) => ({
dropNotAllowed: monitor.isOver() && !monitor.canDrop(),
isOver: monitor.canDrop() && monitor.isOver(),
dropMonitorId: 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({
...props,
disabled: !!props.parentDisabled || !!props.disabled,
useDrag,
useDrop,
canDrop,
copyModeModifierKey,
groupModeModifierKey,
hideDefaultDragPreview
});
return /* @__PURE__ */ React.createElement(BaseRuleGroupComponent, {
...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: {
...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) => ({
dropNotAllowed: monitor.isOver() && !monitor.canDrop(),
isOver: monitor.canDrop() && monitor.isOver(),
dropMonitorId: 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 ?? true,
enableMountQueryChange,
translations: translations ?? {}
});
const { enableDragAndDrop } = rqbContext;
const dnd = useReactDnD(props.dnd);
const key = enableDragAndDrop && dnd ? "dnd" : "no-dnd";
const { DndProvider, ReactDndBackend } = dnd ?? emptyObject;
const contextWithoutDnD = useMemo(() => ({
...rqbContext,
enableDragAndDrop: false,
debugMode
}), [rqbContext, debugMode]);
const contextWithDnD = useMemo(() => ({
...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) => {
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(() => ({
rule: props.controlElements?.rule ?? rqbContext.controlElements?.rule ?? rqbDndContext.baseControls.rule,
ruleGroup: props.controlElements?.ruleGroup ?? rqbContext.controlElements?.ruleGroup ?? rqbDndContext.baseControls.ruleGroup,
combinatorSelector: props.controlElements?.combinatorSelector ?? rqbContext.controlElements?.combinatorSelector ?? rqbDndContext.baseControls.combinatorSelector
}), [
props.controlElements?.combinatorSelector,
props.controlElements?.rule,
props.controlElements?.ruleGroup,
rqbContext.controlElements?.combinatorSelector,
rqbContext.controlElements?.rule,
rqbContext.controlElements?.ruleGroup,
rqbDndContext.baseControls.combinatorSelector,
rqbDndContext.baseControls.rule,
rqbDndContext.baseControls.ruleGroup
]);
const newContext = useMemo(() => ({
...rqbContext,
enableDragAndDrop,
debugMode,
controlElements: {
...rqbContext.controlElements,
ruleGroup: RuleGroupDnD,
rule: RuleDnD,
inlineCombinator: InlineCombinatorDnD
}
}), [
debugMode,
enableDragAndDrop,
rqbContext
]);
const { DndContext, useDrag, useDrop } = dnd ?? {};
const dndContextValue = useMemo(() => ({
baseControls,
canDrop,
copyModeModifierKey,
groupModeModifierKey,
hideDefaultDragPreview,
useDrag,
useDrop
}), [
baseControls,
canDrop,
copyModeModifierKey,
groupModeModifierKey,
hideDefaultDragPreview,
useDrag,
useDrop
]);
const contextWithoutDnD = useMemo(() => ({
...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);
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(() => ({
...reactDnD,
...reactDndHTML5Be,
...reactDndTouchBe,
ReactDndBackend: reactDndHTML5Be.HTML5Backend
}));
else if (reactDndTouchBe) setDnd(() => ({
...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) dnd.ReactDndBackend = isTouchDevice() ? dnd.TouchBackend ?? dnd.HTML5Backend : dnd.HTML5Backend ?? dnd.TouchBackend;
return dnd;
};
//#endregion
export { InlineCombinatorDnD, QueryBuilderDnD, QueryBuilderDndWithoutProvider, RuleDnD, RuleGroupDnD, useInlineCombinatorDnD, useReactDnD, useRuleDnD, useRuleGroupDnD };
//# sourceMappingURL=react-querybuilder_dnd.mjs.map