@react-querybuilder/core 8.23.0 → 8.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +507 -448
  2. package/dist/cjs/react-querybuilder_core.cjs.development.js +169 -6
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  4. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +507 -448
  5. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  7. package/dist/derivations.d.mts +288 -237
  8. package/dist/derivations.d.ts +288 -237
  9. package/dist/derivations.js +137 -4
  10. package/dist/derivations.js.map +1 -1
  11. package/dist/derivations.mjs +136 -5
  12. package/dist/derivations.mjs.map +1 -1
  13. package/dist/formatQuery.d.mts +1 -1
  14. package/dist/formatQuery.d.ts +1 -1
  15. package/dist/formatQuery.js +7 -4
  16. package/dist/formatQuery.js.map +1 -1
  17. package/dist/formatQuery.mjs +7 -4
  18. package/dist/formatQuery.mjs.map +1 -1
  19. package/dist/{index-OF2Q1gTp.d.mts → index-94yESPHr.d.mts} +4 -2
  20. package/dist/{index-XueTy_XQ.d.ts → index-D41_Ba4j.d.ts} +4 -2
  21. package/dist/parseCEL.d.mts +110 -110
  22. package/dist/parseCEL.d.ts +110 -110
  23. package/dist/parseCEL.js +4 -4
  24. package/dist/parseCEL.js.map +1 -1
  25. package/dist/parseCEL.mjs +4 -4
  26. package/dist/parseCEL.mjs.map +1 -1
  27. package/dist/parseCypher.d.mts +7 -7
  28. package/dist/parseCypher.d.ts +7 -7
  29. package/dist/parseGremlin.d.mts +4 -4
  30. package/dist/parseGremlin.d.ts +4 -4
  31. package/dist/parseJSONata.d.mts +37 -37
  32. package/dist/parseJSONata.d.ts +37 -37
  33. package/dist/parseJSONata.js +2 -2
  34. package/dist/parseJSONata.mjs +2 -2
  35. package/dist/parseJsonLogic.d.mts +8 -8
  36. package/dist/parseJsonLogic.d.ts +8 -8
  37. package/dist/parseJsonLogic.js +3 -3
  38. package/dist/parseJsonLogic.mjs +3 -3
  39. package/dist/parseMongoDB.d.mts +7 -7
  40. package/dist/parseMongoDB.d.ts +7 -7
  41. package/dist/parseMongoDB.js +3 -3
  42. package/dist/parseMongoDB.mjs +3 -3
  43. package/dist/parseSPARQL.d.mts +4 -4
  44. package/dist/parseSPARQL.d.ts +4 -4
  45. package/dist/parseSQL.d.mts +61 -61
  46. package/dist/parseSQL.d.ts +61 -61
  47. package/dist/parseSQL.js +4 -4
  48. package/dist/parseSQL.js.map +1 -1
  49. package/dist/parseSQL.mjs +4 -4
  50. package/dist/parseSQL.mjs.map +1 -1
  51. package/dist/parseSpEL.d.mts +55 -55
  52. package/dist/parseSpEL.d.ts +55 -55
  53. package/dist/parseSpEL.js +4 -4
  54. package/dist/parseSpEL.js.map +1 -1
  55. package/dist/parseSpEL.mjs +4 -4
  56. package/dist/parseSpEL.mjs.map +1 -1
  57. package/dist/{parserUtils-DbBXyAht.js → parserUtils-2VtG7m8L.js} +3 -3
  58. package/dist/{parserUtils-DbBXyAht.js.map → parserUtils-2VtG7m8L.js.map} +1 -1
  59. package/dist/{parserUtils-BKPstAaO.mjs → parserUtils-BlafvoFb.mjs} +3 -3
  60. package/dist/{parserUtils-BKPstAaO.mjs.map → parserUtils-BlafvoFb.mjs.map} +1 -1
  61. package/dist/{prepareQueryObjects-Dj9cTl9D.js → prepareQueryObjects-DJ_VjOLb.js} +2 -2
  62. package/dist/{prepareQueryObjects-Dj9cTl9D.js.map → prepareQueryObjects-DJ_VjOLb.js.map} +1 -1
  63. package/dist/{prepareQueryObjects-Dmyf3Wi_.mjs → prepareQueryObjects-DawsH4e3.mjs} +2 -2
  64. package/dist/{prepareQueryObjects-Dmyf3Wi_.mjs.map → prepareQueryObjects-DawsH4e3.mjs.map} +1 -1
  65. package/dist/react-querybuilder_core.d.mts +507 -448
  66. package/dist/react-querybuilder_core.legacy-esm.d.ts +507 -448
  67. package/dist/react-querybuilder_core.legacy-esm.js +172 -14
  68. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  69. package/dist/react-querybuilder_core.mjs +168 -7
  70. package/dist/react-querybuilder_core.mjs.map +1 -1
  71. package/dist/react-querybuilder_core.production.d.mts +507 -448
  72. package/dist/react-querybuilder_core.production.mjs +1 -1
  73. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  74. package/dist/{utils-e-7KHkjV.js → utils-B4E1-ZvU.js} +12 -2
  75. package/dist/utils-B4E1-ZvU.js.map +1 -0
  76. package/dist/{utils-CP5Jqy1P.mjs → utils-DLZCoyAh.mjs} +12 -2
  77. package/dist/utils-DLZCoyAh.mjs.map +1 -0
  78. package/package.json +20 -19
  79. package/dist/utils-CP5Jqy1P.mjs.map +0 -1
  80. package/dist/utils-e-7KHkjV.js.map +0 -1
@@ -44,6 +44,7 @@ const controlKeys = [
44
44
  "ruleGroupHeaderElements",
45
45
  "shiftActions",
46
46
  "undoRedoActions",
47
+ "ungroupAction",
47
48
  "valueEditor",
48
49
  "valueSelector",
49
50
  "valueSourceSelector"
@@ -454,6 +455,7 @@ const controlPropKeys = {
454
455
  "toggleLockGroup",
455
456
  "toggleMuteGroup",
456
457
  "translations",
458
+ "ungroup",
457
459
  "validationClassName",
458
460
  "validationResult"
459
461
  ],
@@ -501,6 +503,7 @@ const controlPropKeys = {
501
503
  "toggleLockGroup",
502
504
  "toggleMuteGroup",
503
505
  "translations",
506
+ "ungroup",
504
507
  "validationClassName",
505
508
  "validationResult"
506
509
  ],
@@ -537,6 +540,22 @@ const controlPropKeys = {
537
540
  "titles",
538
541
  "validation"
539
542
  ],
543
+ ungroupAction: [
544
+ "className",
545
+ "context",
546
+ "disabled",
547
+ "disabledTranslation",
548
+ "handleOnClick",
549
+ "label",
550
+ "level",
551
+ "path",
552
+ "ruleOrGroup",
553
+ "rules",
554
+ "schema",
555
+ "testID",
556
+ "title",
557
+ "validation"
558
+ ],
540
559
  valueEditor: [
541
560
  "className",
542
561
  "context",
@@ -637,6 +656,7 @@ const controlKind = {
637
656
  ruleGroupHeaderElements: null,
638
657
  shiftActions: null,
639
658
  undoRedoActions: null,
659
+ ungroupAction: "action",
640
660
  valueEditor: null,
641
661
  valueSelector: null,
642
662
  valueSourceSelector: "selector"
@@ -764,6 +784,10 @@ const defaultTranslations = {
764
784
  label: "⧉",
765
785
  title: "Clone group"
766
786
  },
787
+ ungroupRuleGroup: {
788
+ label: "⊟",
789
+ title: "Ungroup"
790
+ },
767
791
  shiftActionUp: {
768
792
  label: "˄",
769
793
  title: "Shift up"
@@ -1091,6 +1115,7 @@ const standardClassnames = {
1091
1115
  addGroup: "ruleGroup-addGroup",
1092
1116
  cloneRule: "rule-cloneRule",
1093
1117
  cloneGroup: "ruleGroup-cloneGroup",
1118
+ ungroup: "ruleGroup-ungroup",
1094
1119
  removeGroup: "ruleGroup-remove",
1095
1120
  notToggle: "ruleGroup-notToggle",
1096
1121
  rule: "rule",
@@ -1145,6 +1170,7 @@ const defaultControlClassnames = {
1145
1170
  addGroup: "",
1146
1171
  cloneRule: "",
1147
1172
  cloneGroup: "",
1173
+ ungroup: "",
1148
1174
  removeGroup: "",
1149
1175
  notToggle: "",
1150
1176
  rule: "",
@@ -1206,6 +1232,7 @@ const TestID = {
1206
1232
  addGroup: "add-group",
1207
1233
  removeGroup: "remove-group",
1208
1234
  cloneGroup: "clone-group",
1235
+ ungroup: "ungroup",
1209
1236
  cloneRule: "clone-rule",
1210
1237
  addRule: "add-rule",
1211
1238
  removeRule: "remove-rule",
@@ -1237,11 +1264,13 @@ const LogType = {
1237
1264
  onMoveRuleFalse: "onMoveRule callback returned false",
1238
1265
  onMoveGroupFalse: "onMoveGroup callback returned false",
1239
1266
  onRemoveFalse: "onRemove callback returned false",
1267
+ onUngroupFalse: "onUngroup callback returned false",
1240
1268
  add: "rule or group added",
1241
1269
  remove: "rule or group removed",
1242
1270
  update: "rule or group updated",
1243
1271
  move: "rule or group moved",
1244
- group: "rule or group grouped with another"
1272
+ group: "rule or group grouped with another",
1273
+ ungroup: "group replaced by its own rules"
1245
1274
  };
1246
1275
  /**
1247
1276
  * The {@link Path} of the root group.
@@ -1274,6 +1303,7 @@ const queryBuilderFlagDefaults = {
1274
1303
  showNotToggle: false,
1275
1304
  showShiftActions: false,
1276
1305
  showUndoRedo: false,
1306
+ showUngroupButtons: false,
1277
1307
  suppressStandardClassnames: false
1278
1308
  };
1279
1309
  /**
@@ -1305,6 +1335,7 @@ const strictAbortReasons = [
1305
1335
  "target-not-found",
1306
1336
  "parent-not-found",
1307
1337
  "parent-not-a-group",
1338
+ "target-not-a-group",
1308
1339
  "destination-not-found",
1309
1340
  "root-not-allowed",
1310
1341
  "not-a-combinator-slot",
@@ -1632,6 +1663,7 @@ const ruleGroupClassnameSources = {
1632
1663
  addRule: ["actionElement", "addRule"],
1633
1664
  addGroup: ["actionElement", "addGroup"],
1634
1665
  cloneGroup: ["actionElement", "cloneGroup"],
1666
+ ungroup: ["actionElement", "ungroup"],
1635
1667
  lockGroup: ["actionElement", "lockGroup"],
1636
1668
  muteGroup: ["actionElement", "muteGroup"],
1637
1669
  removeGroup: ["actionElement", "removeGroup"],
@@ -3452,7 +3484,9 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
3452
3484
  *
3453
3485
  * At the top level, filter rules produce chained `.has()` steps (implicit AND).
3454
3486
  * Nested groups use `.and()` / `.or()` / `.not()` compound traversals with
3455
- * `__` anonymous traversal prefixes.
3487
+ * `__` anonymous traversal prefixes. Since `not()` accepts exactly one
3488
+ * traversal, negated groups with multiple predicates wrap them in a single
3489
+ * `__.and()`/`__.or()` sub-traversal.
3456
3490
  *
3457
3491
  * @group Export
3458
3492
  */
@@ -3489,9 +3523,10 @@ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
3489
3523
  }
3490
3524
  if (predicates.length === 0) return "";
3491
3525
  const combinator = rg.combinator ?? "and";
3492
- const prefix = rg.not ? "not" : combinator;
3493
3526
  if (predicates.length === 1 && !rg.not) return predicates[0];
3494
- return `.${prefix}(${predicates.map((p) => p.startsWith(".") ? `__${p}` : p).join(", ")})`;
3527
+ const args = predicates.map((p) => p.startsWith(".") ? `__${p}` : p).join(", ");
3528
+ if (rg.not) return predicates.length === 1 ? `.not(${args})` : `.not(__.${combinator}(${args}))`;
3529
+ return `.${combinator}(${args})`;
3495
3530
  };
3496
3531
  if (!isRuleOrGroupValid(ruleGroup, validationMap[ruleGroup.id ?? /* v8 ignore start -- @preserve */ ""])) return fallbackExpression;
3497
3532
  const steps = [];
@@ -6282,6 +6317,7 @@ const mergeClassnames = (...args) => ({
6282
6317
  addGroup: joinClassnamesByName("addGroup", args),
6283
6318
  cloneRule: joinClassnamesByName("cloneRule", args),
6284
6319
  cloneGroup: joinClassnamesByName("cloneGroup", args),
6320
+ ungroup: joinClassnamesByName("ungroup", args),
6285
6321
  removeGroup: joinClassnamesByName("removeGroup", args),
6286
6322
  rule: joinClassnamesByName("rule", args),
6287
6323
  fields: joinClassnamesByName("fields", args),
@@ -6844,6 +6880,81 @@ const removeInPlace = (query, pathOrID, options = {}) => {
6844
6880
  } else parent.rules.splice(index, 1);
6845
6881
  return query;
6846
6882
  };
6883
+ /**
6884
+ * Replaces a group with its own rules in its parent group, without mutating the original query.
6885
+ *
6886
+ * The group's `combinator`, `not`, `id`, `muted`, and `disabled` properties are discarded; its
6887
+ * rules keep their `id`s since they remain in the same query. An empty group is simply removed.
6888
+ *
6889
+ * @returns A new query with the group's rules promoted into its parent group.
6890
+ *
6891
+ * @group Query Tools
6892
+ */
6893
+ const ungroup = (query, pathOrID, options = {}) => producerFor(options.freeze)(query, (q) => ungroupInPlace(q, pathOrID, options));
6894
+ /**
6895
+ * Replaces a group with its own rules in its parent group, in place.
6896
+ *
6897
+ * @returns The query (mutated in place) with the group's rules promoted into its parent group.
6898
+ *
6899
+ * @group Query Tools
6900
+ */
6901
+ const ungroupInPlace = (query, pathOrID, options = {}) => {
6902
+ const { onAbort } = options;
6903
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
6904
+ if (!path) {
6905
+ onAbort?.({
6906
+ reason: "target-not-found",
6907
+ operation: "ungroup",
6908
+ pathOrID
6909
+ });
6910
+ return query;
6911
+ }
6912
+ if (path.length === 0) {
6913
+ onAbort?.({
6914
+ reason: "root-not-allowed",
6915
+ operation: "ungroup",
6916
+ pathOrID
6917
+ });
6918
+ return query;
6919
+ }
6920
+ const ungroupGuardReason = getGuardAbortReason(query, path, options);
6921
+ if (ungroupGuardReason) {
6922
+ onAbort?.({
6923
+ reason: ungroupGuardReason,
6924
+ operation: "ungroup",
6925
+ pathOrID
6926
+ });
6927
+ return query;
6928
+ }
6929
+ const target = findPath(path, query);
6930
+ if (!target) {
6931
+ onAbort?.({
6932
+ reason: "target-not-found",
6933
+ operation: "ungroup",
6934
+ pathOrID
6935
+ });
6936
+ return query;
6937
+ }
6938
+ if (!isRuleGroup(target)) {
6939
+ onAbort?.({
6940
+ reason: "target-not-a-group",
6941
+ operation: "ungroup",
6942
+ pathOrID
6943
+ });
6944
+ return query;
6945
+ }
6946
+ const index = path.at(-1);
6947
+ const parent = findPath(getParentPath(path), query);
6948
+ if (target.rules.length === 0) {
6949
+ if (!isRuleGroupType(parent) && parent.rules.length > 1) {
6950
+ const idxStartDelete = index === 0 ? 0 : index - 1;
6951
+ parent.rules.splice(idxStartDelete, 2);
6952
+ } else parent.rules.splice(index, 1);
6953
+ return query;
6954
+ }
6955
+ parent.rules.splice(index, 1, ...target.rules);
6956
+ return query;
6957
+ };
6847
6958
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
6848
6959
  if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
6849
6960
  const ic = isRuleGroupTypeIC(query);
@@ -7182,7 +7293,7 @@ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
7182
7293
  //#endregion
7183
7294
  //#region src/utils/queryActions.ts
7184
7295
  /**
7185
- * Builds the query builder's six mutation handlers as pure functions of the current query.
7296
+ * Builds the query builder's seven mutation handlers as pure functions of the current query.
7186
7297
  *
7187
7298
  * This is the framework-agnostic core of the action handlers in `useQueryBuilderSchema`. It owns
7188
7299
  * the policy that surrounds the query tools—disabled gating, the confirmation callback protocol,
@@ -7192,7 +7303,7 @@ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
7192
7303
  * @group Query Tools
7193
7304
  */
7194
7305
  const createQueryActions = (config = {}) => {
7195
- const { qbId, combinators, idGenerator, maxLevels = Infinity, queryDisabled, respectDisabled = true, disabledPaths, resetOnFieldChange, resetOnOperatorChange, getRuleDefaultOperator, getValueSources, getRuleDefaultValue, getMatchModes, freeze, onAddRule, onAddGroup, onRemove, onMoveRule, onMoveGroup, onGroupRule, onGroupGroup, onLog } = config;
7306
+ const { qbId, combinators, idGenerator, maxLevels = Infinity, queryDisabled, respectDisabled = true, disabledPaths, resetOnFieldChange, resetOnOperatorChange, getRuleDefaultOperator, getValueSources, getRuleDefaultValue, getMatchModes, freeze, onAddRule, onAddGroup, onRemove, onMoveRule, onMoveGroup, onGroupRule, onGroupGroup, onUngroup, onLog } = config;
7196
7307
  const log = (payload) => onLog?.({
7197
7308
  qbId,
7198
7309
  ...payload
@@ -7432,6 +7543,39 @@ const createQueryActions = (config = {}) => {
7432
7543
  clone
7433
7544
  });
7434
7545
  return newQuery;
7546
+ },
7547
+ ungroupRuleGroup: (query, path, context) => {
7548
+ if (blocked(query, path)) {
7549
+ log({
7550
+ type: LogType.pathDisabled,
7551
+ path,
7552
+ query
7553
+ });
7554
+ return;
7555
+ }
7556
+ const ruleGroup = findPath(path, query);
7557
+ if (path.length === 0 || !isRuleGroup(ruleGroup)) return void 0;
7558
+ const nextQuery = ungroup(query, path, { freeze });
7559
+ const callbackResult = onUngroup ? onUngroup(ruleGroup, path, query, nextQuery, context) : true;
7560
+ if (!callbackResult) {
7561
+ log({
7562
+ type: LogType.onUngroupFalse,
7563
+ ruleGroup,
7564
+ path,
7565
+ query,
7566
+ nextQuery
7567
+ });
7568
+ return;
7569
+ }
7570
+ const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;
7571
+ log({
7572
+ type: LogType.ungroup,
7573
+ query,
7574
+ newQuery,
7575
+ path,
7576
+ ruleGroup
7577
+ });
7578
+ return newQuery;
7435
7579
  }
7436
7580
  };
7437
7581
  };
@@ -7999,6 +8143,23 @@ var QueryManager = class QueryManager {
7999
8143
  return this;
8000
8144
  }
8001
8145
  /**
8146
+ * Replaces the group at `pathOrID` with its own rules in the parent group. The group's
8147
+ * `combinator`, `not`, `id`, `muted`, and `disabled` properties are discarded; an empty group
8148
+ * is simply removed.
8149
+ */
8150
+ ungroup(pathOrID, options = {}) {
8151
+ const { strict, onInvalidTarget, ...toolOptions } = options;
8152
+ this.commit(ungroup(this.state.query, pathOrID, {
8153
+ ...this.toolOptions(),
8154
+ ...toolOptions,
8155
+ onAbort: this.onAbort({
8156
+ strict,
8157
+ onInvalidTarget
8158
+ })
8159
+ }));
8160
+ return this;
8161
+ }
8162
+ /**
8002
8163
  * The options currently in effect, as a frozen shallow copy. Reflects everything applied by
8003
8164
  * the constructor and any subsequent {@link QueryManager.reconfigure} calls, but not the
8004
8165
  * defaults filled in for options that were never provided.
@@ -8763,6 +8924,8 @@ exports.toFullOptionMap = toFullOptionMap;
8763
8924
  exports.transformQuery = transformQuery;
8764
8925
  exports.trimIfString = trimIfString;
8765
8926
  exports.unchangedSignature = unchangedSignature;
8927
+ exports.ungroup = ungroup;
8928
+ exports.ungroupInPlace = ungroupInPlace;
8766
8929
  exports.uniqByIdentifier = uniqByIdentifier;
8767
8930
  exports.uniqByName = uniqByName;
8768
8931
  exports.uniqOptGroups = uniqOptGroups;