@qoretechnologies/reqraft 0.10.41-pr.95.g294e5aa → 0.10.41

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 (137) hide show
  1. package/.claude/CLAUDE.md +12 -0
  2. package/.tasks/INDEX.md +1 -0
  3. package/.tasks/TEMPLATE_TOKEN_GRAMMAR.md +72 -0
  4. package/dist/components/codeSize/index.d.ts +37 -0
  5. package/dist/components/codeSize/index.d.ts.map +1 -0
  6. package/dist/components/codeSize/index.js +87 -0
  7. package/dist/components/codeSize/index.js.map +1 -0
  8. package/dist/components/form/engine/CompactRow.d.ts +20 -1
  9. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  10. package/dist/components/form/engine/CompactRow.js +284 -42
  11. package/dist/components/form/engine/CompactRow.js.map +1 -1
  12. package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
  13. package/dist/components/form/engine/CompactToolbar.js +72 -72
  14. package/dist/components/form/engine/CompactToolbar.js.map +1 -1
  15. package/dist/components/form/engine/FormEngine.d.ts +48 -1
  16. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  17. package/dist/components/form/engine/FormEngine.js +163 -75
  18. package/dist/components/form/engine/FormEngine.js.map +1 -1
  19. package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
  20. package/dist/components/form/engine/_structuredData/SchemaDataView.js +102 -87
  21. package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
  22. package/dist/components/form/engine/compactRowStyles.d.ts +2 -0
  23. package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
  24. package/dist/components/form/engine/compactRowStyles.js +22 -5
  25. package/dist/components/form/engine/compactRowStyles.js.map +1 -1
  26. package/dist/components/form/engine/compactToolbarContext.d.ts +8 -0
  27. package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
  28. package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
  29. package/dist/components/form/engine/readFirst.d.ts +57 -1
  30. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  31. package/dist/components/form/engine/readFirst.js +143 -4
  32. package/dist/components/form/engine/readFirst.js.map +1 -1
  33. package/dist/components/form/fields/Field.d.ts.map +1 -1
  34. package/dist/components/form/fields/Field.js +1 -1
  35. package/dist/components/form/fields/Field.js.map +1 -1
  36. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts +12 -2
  37. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
  38. package/dist/components/form/fields/allowed-values/AllowedValues.js +16 -6
  39. package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
  40. package/dist/components/form/fields/array/ArrayAuto.d.ts.map +1 -1
  41. package/dist/components/form/fields/array/ArrayAuto.js +44 -26
  42. package/dist/components/form/fields/array/ArrayAuto.js.map +1 -1
  43. package/dist/components/form/fields/array/ArrayAutoField.d.ts.map +1 -1
  44. package/dist/components/form/fields/array/ArrayAutoField.js +42 -25
  45. package/dist/components/form/fields/array/ArrayAutoField.js.map +1 -1
  46. package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
  47. package/dist/components/form/fields/auto/AutoFormField.js +32 -4
  48. package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
  49. package/dist/components/form/fields/long-string/LongString.d.ts +9 -1
  50. package/dist/components/form/fields/long-string/LongString.d.ts.map +1 -1
  51. package/dist/components/form/fields/long-string/LongString.js +25 -4
  52. package/dist/components/form/fields/long-string/LongString.js.map +1 -1
  53. package/dist/components/form/fields/template/ExampleValueModal.d.ts +29 -0
  54. package/dist/components/form/fields/template/ExampleValueModal.d.ts.map +1 -0
  55. package/dist/components/form/fields/template/ExampleValueModal.js +122 -0
  56. package/dist/components/form/fields/template/ExampleValueModal.js.map +1 -0
  57. package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts.map +1 -1
  58. package/dist/components/form/fields/template/ReadOnlyTemplateTag.js +3 -3
  59. package/dist/components/form/fields/template/ReadOnlyTemplateTag.js.map +1 -1
  60. package/dist/components/form/fields/template/TemplateField.d.ts.map +1 -1
  61. package/dist/components/form/fields/template/TemplateField.js +35 -6
  62. package/dist/components/form/fields/template/TemplateField.js.map +1 -1
  63. package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts +2 -0
  64. package/dist/components/form/fields/template/__fixtures__/longExampleValue.d.ts.map +1 -0
  65. package/dist/components/form/fields/template/__fixtures__/longExampleValue.js +9 -0
  66. package/dist/components/form/fields/template/__fixtures__/longExampleValue.js.map +1 -0
  67. package/dist/components/form/index.d.ts +1 -0
  68. package/dist/components/form/index.d.ts.map +1 -1
  69. package/dist/components/form/index.js +1 -0
  70. package/dist/components/form/index.js.map +1 -1
  71. package/dist/helpers/common.d.ts +8 -1
  72. package/dist/helpers/common.d.ts.map +1 -1
  73. package/dist/helpers/common.js +9 -1
  74. package/dist/helpers/common.js.map +1 -1
  75. package/dist/helpers/optionUiTypes.d.ts +30 -0
  76. package/dist/helpers/optionUiTypes.d.ts.map +1 -0
  77. package/dist/helpers/optionUiTypes.js +148 -0
  78. package/dist/helpers/optionUiTypes.js.map +1 -0
  79. package/dist/helpers/options.d.ts +19 -0
  80. package/dist/helpers/options.d.ts.map +1 -1
  81. package/dist/helpers/options.js +25 -1
  82. package/dist/helpers/options.js.map +1 -1
  83. package/dist/helpers/providerValue.d.ts +68 -0
  84. package/dist/helpers/providerValue.d.ts.map +1 -0
  85. package/dist/helpers/providerValue.js +50 -0
  86. package/dist/helpers/providerValue.js.map +1 -0
  87. package/dist/helpers/singleLineString.d.ts +37 -0
  88. package/dist/helpers/singleLineString.d.ts.map +1 -0
  89. package/dist/helpers/singleLineString.js +66 -0
  90. package/dist/helpers/singleLineString.js.map +1 -0
  91. package/dist/helpers/templates.d.ts +100 -0
  92. package/dist/helpers/templates.d.ts.map +1 -1
  93. package/dist/helpers/templates.js +237 -4
  94. package/dist/helpers/templates.js.map +1 -1
  95. package/dist/helpers/validations.d.ts +103 -2
  96. package/dist/helpers/validations.d.ts.map +1 -1
  97. package/dist/helpers/validations.js +858 -91
  98. package/dist/helpers/validations.js.map +1 -1
  99. package/dist/index.d.ts +2 -1
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +3 -1
  102. package/dist/index.js.map +1 -1
  103. package/package.json +1 -1
  104. package/src/components/codeSize/index.tsx +79 -0
  105. package/src/components/form/engine/CompactRow.tsx +407 -34
  106. package/src/components/form/engine/CompactToolbar.tsx +105 -98
  107. package/src/components/form/engine/FormEngine.stories.tsx +863 -12
  108. package/src/components/form/engine/FormEngine.tsx +183 -33
  109. package/src/components/form/engine/_structuredData/SchemaDataView.stories.tsx +110 -103
  110. package/src/components/form/engine/_structuredData/SchemaDataView.tsx +132 -80
  111. package/src/components/form/engine/compactRowStyles.ts +44 -1
  112. package/src/components/form/engine/compactToolbarContext.ts +8 -0
  113. package/src/components/form/engine/readFirst.ts +163 -4
  114. package/src/components/form/fields/Field.tsx +3 -1
  115. package/src/components/form/fields/allowed-values/AllowedValues.tsx +24 -2
  116. package/src/components/form/fields/array/ArrayAuto.tsx +23 -4
  117. package/src/components/form/fields/array/ArrayAutoField.stories.tsx +134 -0
  118. package/src/components/form/fields/array/ArrayAutoField.tsx +22 -4
  119. package/src/components/form/fields/auto/AutoFormField.tsx +31 -1
  120. package/src/components/form/fields/long-string/LongString.tsx +46 -5
  121. package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +5 -0
  122. package/src/components/form/fields/template/ExampleValueModal.stories.tsx +114 -0
  123. package/src/components/form/fields/template/ExampleValueModal.tsx +99 -0
  124. package/src/components/form/fields/template/ReadOnlyTemplateTag.tsx +8 -4
  125. package/src/components/form/fields/template/TemplateField.stories.tsx +314 -1
  126. package/src/components/form/fields/template/TemplateField.tsx +47 -8
  127. package/src/components/form/fields/template/__fixtures__/longExampleValue.ts +7 -0
  128. package/src/components/form/index.tsx +1 -0
  129. package/src/helpers/common.ts +11 -1
  130. package/src/helpers/optionUiTypes.ts +153 -0
  131. package/src/helpers/options.ts +23 -0
  132. package/src/helpers/providerValue.ts +125 -0
  133. package/src/helpers/singleLineString.ts +61 -0
  134. package/src/helpers/templates.ts +272 -3
  135. package/src/helpers/validations.ts +1177 -109
  136. package/src/hooks/useWebSocket/useWebsocket.stories.tsx +23 -2
  137. package/src/index.tsx +2 -0
@@ -202,7 +202,7 @@ var StyledCommitDock = styled_components_1.default.div(templateObject_2 || (temp
202
202
  return "".concat((0, colors_1.changeDarkness)($bg, 0.4)).concat((0, colors_1.percentToHexAlpha)(55));
203
203
  });
204
204
  var getType = function (type, operators, operator) {
205
- var finalType = getTypeFromOperator(operators, (0, exports.fixOperatorValue)(operator)) || type;
205
+ var finalType = getTypeFromOperator(operators, (0, common_1.fixOperatorValue)(operator)) || type;
206
206
  var resolvedType = (0, isArray_1.default)(finalType) ? finalType[0] : finalType;
207
207
  // A value can be received before its server-driven option schema. Keep the
208
208
  // renderer type-safe during that transition without guessing a concrete type.
@@ -216,10 +216,11 @@ var getTypeFromOperator = function (operators, operatorData) {
216
216
  }
217
217
  return ((_a = operators[(0, lodash_1.last)(operatorData)]) === null || _a === void 0 ? void 0 : _a.type) || null;
218
218
  };
219
- var fixOperatorValue = function (operator) {
220
- return (0, isArray_1.default)(operator) ? operator : [operator];
221
- };
222
- exports.fixOperatorValue = fixOperatorValue;
219
+ /** Re-exported from `helpers/common` so existing importers keep working; it
220
+ * lives there because `helpers/validations` needs it and cannot import this
221
+ * module (this module imports the validators). */
222
+ var common_2 = require("../../../helpers/common");
223
+ Object.defineProperty(exports, "fixOperatorValue", { enumerable: true, get: function () { return common_2.fixOperatorValue; } });
223
224
  var getOptionSchemaStorageType = function (option, isRendererOnly) {
224
225
  if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
225
226
  return (((0, readFirst_1.isFixedCompactAllowedValueOption)(option)
@@ -253,7 +254,7 @@ var fixOptions = function (value, options, operators, isRendererOnly) {
253
254
  return fixedValue;
254
255
  }
255
256
  (0, lodash_1.forEach)(options, function (option, name) {
256
- var _a, _b, _c, _d, _f, _g, _h;
257
+ var _a, _b, _c, _d, _f, _g, _h, _j;
257
258
  if (option.value ||
258
259
  option.required_groups ||
259
260
  ((option.required || option.preselected) && !fixedValue[name]) ||
@@ -264,14 +265,30 @@ var fixOptions = function (value, options, operators, isRendererOnly) {
264
265
  ((_c = fixedValue[name]) === null || _c === void 0 ? void 0 : _c.value) === undefined) {
265
266
  obj = option.default_value;
266
267
  }
268
+ else if (option.default_view === 'expression' &&
269
+ ((_d = fixedValue[name]) === null || _d === void 0 ? void 0 : _d.value) === undefined) {
270
+ // A field the schema declares as opening in expression mode starts as an
271
+ // EMPTY expression, not as its raw default. `isDefaultFunction` already
272
+ // makes the renderer open that way, so without this the data disagreed
273
+ // with what the operator was looking at: an expression editor whose
274
+ // value was still the plain default, and no `is_expression` on the field
275
+ // until the first edit.
276
+ obj = {
277
+ type: type,
278
+ value: {
279
+ args: [],
280
+ },
281
+ is_expression: true,
282
+ };
283
+ }
267
284
  else {
268
285
  obj = {
269
286
  type: type,
270
- value: (_g = (_f = (typeof fixedValue[name] === 'object' ?
271
- (_d = fixedValue[name]) === null || _d === void 0 ? void 0 : _d.value
272
- : fixedValue[name])) !== null && _f !== void 0 ? _f : option.value) !== null && _g !== void 0 ? _g : (0, common_1.getDefaultValue)(option),
287
+ value: (_h = (_g = (typeof fixedValue[name] === 'object' ?
288
+ (_f = fixedValue[name]) === null || _f === void 0 ? void 0 : _f.value
289
+ : fixedValue[name])) !== null && _g !== void 0 ? _g : option.value) !== null && _h !== void 0 ? _h : (0, common_1.getDefaultValue)(option),
273
290
  };
274
- if ((_h = fixedValue[name]) === null || _h === void 0 ? void 0 : _h.is_expression) {
291
+ if ((_j = fixedValue[name]) === null || _j === void 0 ? void 0 : _j.is_expression) {
275
292
  obj.is_expression = true;
276
293
  }
277
294
  }
@@ -280,7 +297,7 @@ var fixOptions = function (value, options, operators, isRendererOnly) {
280
297
  });
281
298
  var res = (0, reduce_1.default)(fixedValue, function (newValue, option, optionName) {
282
299
  var _a;
283
- var _b, _c, _d, _f, _g, _h;
300
+ var _b, _c, _d, _f, _g, _h, _j;
284
301
  var newOption = option;
285
302
  if (!(0, lodash_1.isPlainObject)(newOption) || !(newOption === null || newOption === void 0 ? void 0 : newOption.type)) {
286
303
  var isUntypedEnvelope = (0, lodash_1.isPlainObject)(newOption) && 'value' in newOption;
@@ -303,17 +320,27 @@ var fixOptions = function (value, options, operators, isRendererOnly) {
303
320
  // every value declared the bare way: the collapsed row still showed its
304
321
  // display name while the editor showed "—" and the value never reached
305
322
  // the submitted data.
323
+ // `allowed_values: []` is NOT "no value is permitted" — it is the server
324
+ // saying it has no reference values to offer right now (the app-action
325
+ // catalogue ships exactly that, with an
326
+ // `option_reference_values_unavailable` message attached). An empty array
327
+ // is truthy, so testing the array itself made every such option erase the
328
+ // operator's stored value on the first render, before the
329
+ // connection-refreshed schema arrived to say otherwise — and the emptied
330
+ // form then autosaved over the draft, so the value was gone for good.
331
+ // Only an option that actually declares choices can have a value that is
332
+ // not one of them.
306
333
  if (newOption.value !== undefined &&
307
- ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values) &&
334
+ ((_d = (_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values) === null || _d === void 0 ? void 0 : _d.length) &&
308
335
  !(0, readFirst_1.findAllowedValueOption)(newOption.value, options === null || options === void 0 ? void 0 : options[optionName]) &&
309
336
  !(0, TemplateField_1.isValueTemplate)(newOption.value) &&
310
- !((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.multiselect) &&
311
- !((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.allowed_values_creatable)) {
337
+ !((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.multiselect) &&
338
+ !((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.allowed_values_creatable)) {
312
339
  newOption.value = undefined;
313
340
  }
314
341
  if (newOption.value &&
315
- ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.readonly) &&
316
- ((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.default_value) &&
342
+ ((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.readonly) &&
343
+ ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.default_value) &&
317
344
  (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]) !== newOption.value) {
318
345
  newOption.value = (0, common_1.getDefaultValue)(options[optionName]);
319
346
  }
@@ -372,12 +399,12 @@ var FormEngineImpl = function (_a) {
372
399
  var _b, _c, _d, _f, _g, _h;
373
400
  var name = _a.name, uniqueName = _a.uniqueName, value = _a.value, onChange = _a.onChange, onSingleOptionsChange = _a.onSingleOptionsChange, onDependableOptionChange = _a.onDependableOptionChange, placeholder = _a.placeholder, noValueString = _a.noValueString, // eslint-disable-line @typescript-eslint/no-unused-vars
374
401
  isValid = _a.isValid, // eslint-disable-line @typescript-eslint/no-unused-vars
375
- url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _j = _a.allowTemplates, allowTemplates = _j === void 0 ? true : _j, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, forceDropdown = _a.forceDropdown, _k = _a.showTypeToggle, showTypeToggle = _k === void 0 ? true : _k, compact = _a.compact, _l = _a.compactFlush, compactFlush = _l === void 0 ? false : _l, _m = _a.compactNested, compactNested = _m === void 0 ? false : _m, compactPanelProps = _a.compactPanelProps, _o = _a.commitMode, commitMode = _o === void 0 ? 'immediate' : _o, _p = _a.expandMode, expandMode = _p === void 0 ? 'single' : _p, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, _q = _a.optionActionsCollapse, optionActionsCollapse = _q === void 0 ? 'auto' : _q, componentOverrides = _a.componentOverrides, codePreviewRenderer = _a.codePreviewRenderer,
402
+ url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _j = _a.allowTemplates, allowTemplates = _j === void 0 ? true : _j, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, forceDropdown = _a.forceDropdown, _k = _a.showTypeToggle, showTypeToggle = _k === void 0 ? true : _k, compact = _a.compact, _l = _a.compactFlush, compactFlush = _l === void 0 ? false : _l, _m = _a.compactNested, compactNested = _m === void 0 ? false : _m, compactPanelProps = _a.compactPanelProps, _o = _a.compactCollapsedGroups, compactCollapsedGroups = _o === void 0 ? ['optional'] : _o, _p = _a.compactToolbar, compactToolbar = _p === void 0 ? true : _p, _q = _a.commitMode, commitMode = _q === void 0 ? 'immediate' : _q, _r = _a.expandMode, expandMode = _r === void 0 ? 'single' : _r, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, _s = _a.optionActionsCollapse, optionActionsCollapse = _s === void 0 ? 'auto' : _s, componentOverrides = _a.componentOverrides, codePreviewRenderer = _a.codePreviewRenderer,
376
403
  // consumed by the wrapper below, which publishes it to every description this
377
404
  // form draws; destructured here only so it cannot reach `rest` and be spread
378
405
  // onto a DOM node
379
406
  _markdownRenderer = _a.markdownRenderer, // eslint-disable-line @typescript-eslint/no-unused-vars
380
- rendererOnlyUiTypes = _a.rendererOnlyUiTypes, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, expandFirstRequired = _a.expandFirstRequired, initialExpandedOptions = _a.initialExpandedOptions, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "forceDropdown", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "optionActionsCollapse", "componentOverrides", "codePreviewRenderer", "markdownRenderer", "rendererOnlyUiTypes", "inheritedFromParent", "autoFocusFirstRequired", "expandFirstRequired", "initialExpandedOptions"]);
407
+ rendererOnlyUiTypes = _a.rendererOnlyUiTypes, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, expandFirstRequired = _a.expandFirstRequired, initialExpandedOptions = _a.initialExpandedOptions, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "forceDropdown", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "compactCollapsedGroups", "compactToolbar", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "optionActionsCollapse", "componentOverrides", "codePreviewRenderer", "markdownRenderer", "rendererOnlyUiTypes", "inheritedFromParent", "autoFocusFirstRequired", "expandFirstRequired", "initialExpandedOptions"]);
381
408
  // Built-ins + whatever the consumer declared for its own injected editors.
382
409
  var isRendererOnly = (0, react_2.useMemo)(function () { return (0, rendererTypes_1.createRendererOnlyUiTypeCheck)(rendererOnlyUiTypes); }, [JSON.stringify(rendererOnlyUiTypes)]);
383
410
  // Pointer CAPABILITY and viewport WIDTH are different questions and both
@@ -395,30 +422,30 @@ var FormEngineImpl = function (_a) {
395
422
  var collapseOptionActions = optionActionsCollapse === 'always' ? true
396
423
  : optionActionsCollapse === 'never' ? false
397
424
  : !isHoverCapable || !!isMobile;
398
- var _r = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _r[0], setOptions = _r[1];
425
+ var _t = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _t[0], setOptions = _t[1];
399
426
  // optionsLoader lifecycle: loading feeds the skeleton gate, error the banner.
400
- var _s = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _s[0], setOptionsLoading = _s[1];
401
- var _t = (0, react_2.useState)(), optionsError = _t[0], setOptionsError = _t[1];
427
+ var _u = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _u[0], setOptionsLoading = _u[1];
428
+ var _v = (0, react_2.useState)(), optionsError = _v[0], setOptionsError = _v[1];
402
429
  // Operators: prop-provided (compact) or fetched via operatorsUrl (dpql,
403
430
  // ported from IDE Options) — the fetch overrides the seeded prop value.
404
- var _u = (0, react_2.useState)(operatorsProp), operators = _u[0], setOperators = _u[1];
431
+ var _w = (0, react_2.useState)(operatorsProp), operators = _w[0], setOperators = _w[1];
405
432
  // Remote-fetch loading (ported from IDE Options); only relevant when one of
406
433
  // the fetch urls is set — schema-as-props consumers never see the skeleton.
407
- var _v = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _v[0], setLoading = _v[1];
434
+ var _x = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _x[0], setLoading = _x[1];
408
435
  var confirmAction = (0, reqore_1.useReqoreProperty)('confirmAction');
409
436
  var theme = (0, reqore_1.useReqoreTheme)();
410
- var _w = (0, react_2.useState)(), focusedEditing = _w[0], setFocusedEditing = _w[1];
411
- var _x = (0, react_2.useState)(false), showFieldTypes = _x[0], setShowFieldTypes = _x[1];
437
+ var _y = (0, react_2.useState)(), focusedEditing = _y[0], setFocusedEditing = _y[1];
438
+ var _z = (0, react_2.useState)(false), showFieldTypes = _z[0], setShowFieldTypes = _z[1];
412
439
  // Global toggle (toolbar ⓘ): reveal the short-description info panel on every
413
440
  // field that has a short_desc. Per-row ⓘ overrides still win over it.
414
441
  // Global field-info visibility, tri-state: `undefined` = default (critical
415
442
  // messages auto-open, the rest closed); `true` = show all; `false` = hide all
416
443
  // (even message fields). The toolbar ⓘ drives it.
417
- var _y = (0, react_2.useState)(undefined), showAllDescriptions = _y[0], setShowAllDescriptions = _y[1];
418
- var _z = (0, react_2.useState)(), showHelpForOption = _z[0], setShowHelpForOption = _z[1];
419
- var _0 = (0, react_2.useState)(false), showInvalidOptionsOnly = _0[0], setShowInvalidOptionsOnly = _0[1];
444
+ var _0 = (0, react_2.useState)(undefined), showAllDescriptions = _0[0], setShowAllDescriptions = _0[1];
445
+ var _1 = (0, react_2.useState)(), showHelpForOption = _1[0], setShowHelpForOption = _1[1];
446
+ var _2 = (0, react_2.useState)(false), showInvalidOptionsOnly = _2[0], setShowInvalidOptionsOnly = _2[1];
420
447
  // Which options are expanded into their editor (several can be open at once).
421
- var _1 = (0, react_2.useState)([]), expandedOptions = _1[0], setExpandedOptions = _1[1];
448
+ var _3 = (0, react_2.useState)([]), expandedOptions = _3[0], setExpandedOptions = _3[1];
422
449
  // --- Reveal a status box's content when it is opened ----------------------
423
450
  //
424
451
  // The status boxes stack, so the last one ("Optional", which holds every
@@ -434,7 +461,7 @@ var FormEngineImpl = function (_a) {
434
461
  // box has not grown and there is nothing to scroll to. A layout effect runs
435
462
  // after the DOM is updated and before paint, which makes the reveal
436
463
  // deterministic instead of a guessed delay.
437
- var _2 = (0, react_2.useState)(undefined), openedStatusBox = _2[0], setOpenedStatusBox = _2[1];
464
+ var _4 = (0, react_2.useState)(undefined), openedStatusBox = _4[0], setOpenedStatusBox = _4[1];
438
465
  var statusBoxRefs = (0, react_2.useRef)({});
439
466
  (0, react_2.useLayoutEffect)(function () {
440
467
  var _a, _b;
@@ -465,13 +492,13 @@ var FormEngineImpl = function (_a) {
465
492
  var settledBucket = (0, react_2.useRef)({});
466
493
  // Measured form width (not viewport — the form lives in drawers/panels of
467
494
  // arbitrary width) drives the stacked narrow layout.
468
- var _3 = (0, react_use_1.useMeasure)(), compactWrapRef = _3[0], compactWrapWidth = _3[1].width;
495
+ var _5 = (0, react_use_1.useMeasure)(), compactWrapRef = _5[0], compactWrapWidth = _5[1].width;
469
496
  // Own handle on the scroll wrap (useMeasure's ref is a callback, no `.current`)
470
497
  // so the label-column measurement can publish its CSS var on the element. It's
471
498
  // STATE, not a ref: the wrap mounts only after the loading-skeleton gate
472
499
  // resolves, so the measurement effect must re-run when the node appears — a
473
500
  // ref wouldn't retrigger it.
474
- var _4 = (0, react_2.useState)(null), compactWrapNode = _4[0], setCompactWrapNode = _4[1];
501
+ var _6 = (0, react_2.useState)(null), compactWrapNode = _6[0], setCompactWrapNode = _6[1];
475
502
  // Ref mirror of the wrap node for callbacks that must not re-create when it
476
503
  // mounts (flashOptions reads it inside a rAF).
477
504
  var compactWrapNodeRef = (0, react_2.useRef)(null);
@@ -525,8 +552,8 @@ var FormEngineImpl = function (_a) {
525
552
  var readRowHeights = (0, react_2.useRef)({});
526
553
  // Required-groups linkage: hovering a group chip highlights every member row;
527
554
  // clicking a sibling in the chip's popover scrolls to it and flashes it.
528
- var _5 = (0, react_2.useState)([]), highlightedOptions = _5[0], setHighlightedOptions = _5[1];
529
- var _6 = (0, react_2.useState)([]), flashedOptions = _6[0], setFlashedOptions = _6[1];
555
+ var _7 = (0, react_2.useState)([]), highlightedOptions = _7[0], setHighlightedOptions = _7[1];
556
+ var _8 = (0, react_2.useState)([]), flashedOptions = _8[0], setFlashedOptions = _8[1];
530
557
  var flashTimeout = (0, react_2.useRef)();
531
558
  var flashOptions = (0, react_2.useCallback)(function (optionNames, scrollToFirst) {
532
559
  if (scrollToFirst === void 0) { scrollToFirst = false; }
@@ -575,16 +602,16 @@ var FormEngineImpl = function (_a) {
575
602
  });
576
603
  var compactNarrow = !!compactWrapWidth && compactWrapWidth < 480;
577
604
  // Info panels auto-open on Tier-1 content; the per-row user override sticks.
578
- var _7 = (0, react_2.useState)({}), infoPanelOverrides = _7[0], setInfoPanelOverrides = _7[1];
605
+ var _9 = (0, react_2.useState)({}), infoPanelOverrides = _9[0], setInfoPanelOverrides = _9[1];
579
606
  // Toolbar filters affect the listed rows only — the meter reflects the full set.
580
- var _8 = (0, react_2.useState)(false), requiredOnly = _8[0], setRequiredOnly = _8[1];
581
- var _9 = (0, react_2.useState)(''), compactQuery = _9[0], setCompactQuery = _9[1];
607
+ var _10 = (0, react_2.useState)(false), requiredOnly = _10[0], setRequiredOnly = _10[1];
608
+ var _11 = (0, react_2.useState)(''), compactQuery = _11[0], setCompactQuery = _11[1];
582
609
  // Compact field sort (Fields menu → "Sort by"); 'schema' = declared order.
583
- var _10 = (0, react_2.useState)('schema'), compactSort = _10[0], setCompactSort = _10[1];
584
- var _11 = (0, react_2.useState)(function () { return ({
610
+ var _12 = (0, react_2.useState)('schema'), compactSort = _12[0], setCompactSort = _12[1];
611
+ var _13 = (0, react_2.useState)(function () { return ({
585
612
  fields: (0, exports.fixOptions)(value, options || {}, undefined, isRendererOnly),
586
613
  meta: undefined,
587
- }); }), localValue = _11[0], setLocalValue = _11[1];
614
+ }); }), localValue = _13[0], setLocalValue = _13[1];
588
615
  var originalValue = (0, react_2.useRef)();
589
616
  // Track the last value we emitted via onChange so we can skip re-applying fixOptions
590
617
  // when the parent echoes it back as the new value prop (controlled component loop prevention)
@@ -593,7 +620,7 @@ var FormEngineImpl = function (_a) {
593
620
  originalValue.current = localValue.fields;
594
621
  }
595
622
  var unavailableOptionsCount = (0, react_2.useRef)(0);
596
- var _12 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _12.compactValue, typesLoading = _12.loading;
623
+ var _14 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _14.compactValue, typesLoading = _14.loading;
597
624
  var templates = (0, useTemplates_1.useTemplates)(allowTemplates, rest.stringTemplates, interfaceContext);
598
625
  (0, react_2.useEffect)(function () {
599
626
  if ((0, lodash_1.isEqual)(localValue.fields, value)) {
@@ -861,7 +888,7 @@ var FormEngineImpl = function (_a) {
861
888
  var handleOperatorChange = (0, react_2.useCallback)(function (optionName, currentValue, operator, index) {
862
889
  var _a;
863
890
  setLocalValue === null || setLocalValue === void 0 ? void 0 : setLocalValue({
864
- fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, exports.fixOperatorValue)(currentValue[optionName].op).map(function (op, idx) {
891
+ fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, common_1.fixOperatorValue)(currentValue[optionName].op).map(function (op, idx) {
865
892
  if (idx === index) {
866
893
  return operator;
867
894
  }
@@ -873,14 +900,14 @@ var FormEngineImpl = function (_a) {
873
900
  var handleAddOperator = (0, react_2.useCallback)(function (optionName, currentValue, index) {
874
901
  var _a;
875
902
  setLocalValue === null || setLocalValue === void 0 ? void 0 : setLocalValue({
876
- fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, common_1.insertAtIndex)((0, exports.fixOperatorValue)(currentValue[optionName].op), index, null) }), _a)),
903
+ fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, common_1.insertAtIndex)((0, common_1.fixOperatorValue)(currentValue[optionName].op), index, null) }), _a)),
877
904
  meta: undefined,
878
905
  });
879
906
  }, []);
880
907
  var handleRemoveOperator = (0, react_2.useCallback)(function (optionName, currentValue, index) {
881
908
  var _a;
882
909
  setLocalValue === null || setLocalValue === void 0 ? void 0 : setLocalValue({
883
- fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, exports.fixOperatorValue)(currentValue[optionName].op).filter(function (_op, idx) { return idx !== index; }) }), _a)),
910
+ fields: __assign(__assign({}, currentValue), (_a = {}, _a[optionName] = __assign(__assign({}, currentValue[optionName]), { op: (0, common_1.fixOperatorValue)(currentValue[optionName].op).filter(function (_op, idx) { return idx !== index; }) }), _a)),
884
911
  meta: undefined,
885
912
  });
886
913
  }, []);
@@ -1420,9 +1447,9 @@ var FormEngineImpl = function (_a) {
1420
1447
  // The info panel below the row keeps showing schema messages while editing —
1421
1448
  // rendering them in the editor too would balloon a one-line edit.
1422
1449
  suppressSchemaMessages) {
1423
- var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
1450
+ var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1424
1451
  var type = _a.type, other = __rest(_a, ["type"]);
1425
- var operatorParts = (0, exports.fixOperatorValue)(other.op);
1452
+ var operatorParts = (0, common_1.fixOperatorValue)(other.op);
1426
1453
  // The RENDERER type for this row — which editor mounts. Distinct from the
1427
1454
  // storage type on the value envelope: a `richtext` field stores a string
1428
1455
  // but must render the richtext editor, so `ui_type` wins here.
@@ -1520,8 +1547,14 @@ var FormEngineImpl = function (_a) {
1520
1547
  // `[localValue, onChange]` — an inline lambda resets the pending emit
1521
1548
  // every render and the typed value can starve.
1522
1549
  handleValueChange, key: optionName, arg_schema: (_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.arg_schema, noSoft: !!(rest === null || rest === void 0 ? void 0 : rest.options), value: other.value, isFunction: other.is_expression, isDefaultFunction: ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.default_view) === 'expression', sensitive: (_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.sensitive, default_value: (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), isDefaultTemplate: ((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.default_view) === 'template', allowed_values: (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.allowed_values, allowed_values_creatable: (_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.allowed_values_creatable, disabled: ((_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.disabled) ||
1550
+ (
1551
+ // a system-owned field states that as `readonly`; only the older
1552
+ // compat projection also sent `disabled`, so honouring only
1553
+ // `disabled` rendered an editable control for a value the user
1554
+ // cannot change (see CompactRow's `fieldReadonly`)
1555
+ (_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.readonly) ||
1523
1556
  readOnly ||
1524
- !(0, validations_1.hasAllDependenciesFullfilled)((_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_s = options === null || options === void 0 ? void 0 : options[optionName]) === null || _s === void 0 ? void 0 : _s.ui_type) === 'any' ?
1557
+ !(0, validations_1.hasAllDependenciesFullfilled)((_s = options === null || options === void 0 ? void 0 : options[optionName]) === null || _s === void 0 ? void 0 : _s.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_t = options === null || options === void 0 ? void 0 : options[optionName]) === null || _t === void 0 ? void 0 : _t.ui_type) === 'any' ?
1525
1558
  getCustomMenuTemplateItems(optionName)
1526
1559
  : undefined }, templateFieldProps, { forceDropdown: effectiveForceDropdown })), (0, jsx_runtime_1.jsx)(OptionFieldMessages_1.OptionFieldMessages, { schema: options || {}, allOptions: availableOptions, name: optionName, option: __assign({ type: resolvedType }, other), getType: getTypeForOption }), operators && (0, size_1.default)(operators) && (0, size_1.default)(other.op) ?
1527
1560
  (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreMessage, { size: 'small', children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreTagGroup, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', labelKey: 'WHERE', label: optionName }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', labelKey: 'IS', label: operatorParts.join(' ') }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', intent: 'info', label: other.value ?
@@ -1670,6 +1703,14 @@ var FormEngineImpl = function (_a) {
1670
1703
  cInfo,
1671
1704
  cBg,
1672
1705
  ]);
1706
+ // `compactToolbar` resolved to a full object, so neither the context type nor
1707
+ // the toolbar itself has to re-default anything. `null` means no toolbar.
1708
+ var compactToolbarParts = (0, react_2.useMemo)(function () {
1709
+ if (compactToolbar === false)
1710
+ return null;
1711
+ var all = { completion: true, search: true, fields: true, help: true };
1712
+ return compactToolbar === true ? all : __assign(__assign({}, all), compactToolbar);
1713
+ }, [JSON.stringify(compactToolbar)]);
1673
1714
  var compactToolbarContextValue = (0, react_2.useMemo)(function () { return ({
1674
1715
  readOnly: readOnly,
1675
1716
  invalidCount: (0, size_1.default)(validityData.invalidFields),
@@ -1677,6 +1718,7 @@ var FormEngineImpl = function (_a) {
1677
1718
  completion: readFirstCompletion,
1678
1719
  showInvalidOnly: showInvalidOptionsOnly,
1679
1720
  onToggleInvalidOnly: handleToggleInvalidOnly,
1721
+ parts: compactToolbarParts !== null && compactToolbarParts !== void 0 ? compactToolbarParts : { completion: false, search: false, fields: false, help: false },
1680
1722
  hasMultipleOptions: (0, size_1.default)(availableOptions) > 1,
1681
1723
  compactQuery: compactQuery,
1682
1724
  setCompactQuery: setCompactQuery,
@@ -1724,8 +1766,9 @@ var FormEngineImpl = function (_a) {
1724
1766
  ]);
1725
1767
  // The engine's own toolbar action, plus whatever the consumer added through
1726
1768
  // `compactPanelProps.actions` — appended, so an outside action can never
1727
- // knock the form's toolbar out of the header.
1728
- var compactHeaderActions = (0, react_2.useMemo)(function () { return __spreadArray([{ as: CompactToolbar_1.CompactToolbar, responsive: false }], ((compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.actions) || []), true); }, [compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.actions]);
1769
+ // knock the form's toolbar out of the header. Only `compactToolbar={false}`
1770
+ // removes it, and then the header carries just the consumer's own actions.
1771
+ var compactHeaderActions = (0, react_2.useMemo)(function () { return __spreadArray(__spreadArray([], (compactToolbarParts ? [{ as: CompactToolbar_1.CompactToolbar, responsive: false }] : []), true), ((compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.actions) || []), true); }, [compactPanelProps === null || compactPanelProps === void 0 ? void 0 : compactPanelProps.actions, compactToolbarParts]);
1729
1772
  var renderCompact = function () {
1730
1773
  var headerBg = "".concat((0, colors_1.changeDarkness)((0, colors_1.getMainBackgroundColor)(theme), 0.02)).concat((0, colors_1.percentToHexAlpha)(88));
1731
1774
  // Toolbar filters narrow the listed rows; the meter reflects the full set.
@@ -1736,8 +1779,40 @@ var FormEngineImpl = function (_a) {
1736
1779
  if (requiredOnly && !((schema === null || schema === void 0 ? void 0 : schema.required) || (schema === null || schema === void 0 ? void 0 : schema.required_groups))) {
1737
1780
  return false;
1738
1781
  }
1739
- return matchesQuery(optionName);
1782
+ // A field that absorbs a sibling also answers for it: searching
1783
+ // "language" has to surface the row that now holds the language control,
1784
+ // or the field becomes unreachable through the filter.
1785
+ if (matchesQuery(optionName))
1786
+ return true;
1787
+ var absorb = schema === null || schema === void 0 ? void 0 : schema.absorb_fields;
1788
+ return !!(absorb === null || absorb === void 0 ? void 0 : absorb.some(function (absorbedName) { return matchesQuery(absorbedName); }));
1740
1789
  };
1790
+ // Fields a sibling absorbs into its own container.
1791
+ //
1792
+ // A field declaring `absorb_fields: ['language']` renders that sibling's
1793
+ // control inside its own row instead of letting it have a row of its own.
1794
+ // The pair this exists for is a code editor and its language: they are one
1795
+ // decision — "what is this code, and in what language" — and reading them
1796
+ // as two unrelated rows one above the other is what the layout used to say.
1797
+ //
1798
+ // Absorbed fields stay in `grouped`, and therefore in the Set / Optional /
1799
+ // Needs-attention counts and in the completion meter. Only the ROW is
1800
+ // skipped. Dropping them from the buckets instead would leave the meter
1801
+ // ("13/18 set", computed from `availableOptions`) disagreeing with the box
1802
+ // badge beside it, which counts row entries.
1803
+ var absorbedBy = {};
1804
+ (0, lodash_1.forEach)(options, function (option, optionName) {
1805
+ var absorb = option === null || option === void 0 ? void 0 : option.absorb_fields;
1806
+ if (!(absorb === null || absorb === void 0 ? void 0 : absorb.length))
1807
+ return;
1808
+ absorb.forEach(function (absorbedName) {
1809
+ // Only absorb a sibling that exists and is not already spoken for; a
1810
+ // schema naming a missing field must not make the field disappear.
1811
+ if ((options === null || options === void 0 ? void 0 : options[absorbedName]) && !absorbedBy[absorbedName]) {
1812
+ absorbedBy[absorbedName] = optionName;
1813
+ }
1814
+ });
1815
+ });
1741
1816
  // Group the options by their raw `group` key, remembering the order groups
1742
1817
  // first appear in the schema. Each row carries a `hidden` flag.
1743
1818
  var groupOrder = [];
@@ -1869,18 +1944,30 @@ var FormEngineImpl = function (_a) {
1869
1944
  // together at the first member's slot and rendered as a connected rail (flat
1870
1945
  // rows — no wrapper — so the value surface applies normally; the rail + nodes
1871
1946
  // are drawn per member). Narrow stacks fall back to flat rows.
1947
+ // The absorbed siblings a host row must render, in schema order. Empty for
1948
+ // every row that absorbs nothing, which is all of them by default.
1949
+ var absorbedNamesFor = function (hostName) {
1950
+ return Object.keys(absorbedBy).filter(function (absorbedName) { return absorbedBy[absorbedName] === hostName; });
1951
+ };
1872
1952
  var renderGroupRows = function (names) {
1873
1953
  var renderRow = function (entry, clustered, clusterFirst, clusterLast) { return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1874
1954
  {
1875
1955
  type: getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[entry.name], isRendererOnly),
1876
1956
  value: undefined,
1877
1957
  }
1878
- : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name)); };
1958
+ : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast,
1959
+ // The siblings this row renders inside itself instead of leaving
1960
+ // them a row of their own — see `absorbedBy`.
1961
+ absorbedFields: absorbedNamesFor(entry.name) }, entry.name)); };
1879
1962
  // (Clustering runs in narrow mode too now — the "One of the below is
1880
1963
  // required" box wraps the members regardless of width; it no longer relies
1881
1964
  // on a contiguous rail.)
1882
1965
  var emitted = new Set();
1883
1966
  var groupOf = function (name) { var _a, _b; return (_b = (_a = options === null || options === void 0 ? void 0 : options[name]) === null || _a === void 0 ? void 0 : _a.required_groups) === null || _b === void 0 ? void 0 : _b[0]; };
1967
+ // An absorbed field keeps its place in the buckets — so the Set /
1968
+ // Optional counts and the completion meter still see it — but its host
1969
+ // renders its control, so it gets no row of its own here.
1970
+ names = names.filter(function (entry) { return !absorbedBy[entry.name]; });
1884
1971
  return names.map(function (entry) {
1885
1972
  var grp = groupOf(entry.name);
1886
1973
  if (!grp)
@@ -1903,12 +1990,10 @@ var FormEngineImpl = function (_a) {
1903
1990
  });
1904
1991
  };
1905
1992
  return ((0, jsx_runtime_1.jsx)(exports.OptionsContext.Provider, { value: { schema: options, value: availableOptions }, children: (0, jsx_runtime_1.jsx)(compactRowContext_1.CompactRowContext.Provider, { value: compactRowContextValue, children: (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreErrorBoundary, { children: [showHelpForOption && ((0, jsx_runtime_1.jsx)(OptionsHelpDialog_1.OptionsHelpDialog, { onClose: function () { return setShowHelpForOption(undefined); }, option: options[showHelpForOption] })), (0, jsx_runtime_1.jsx)(compactToolbarContext_1.CompactToolbarContext.Provider, { value: compactToolbarContextValue, children: (0, jsx_runtime_1.jsxs)(StyledCompactWrap, { ref: setCompactWrap, className: 'options-readfirst-scroll', "$flush": compactFlush || compactNested, children: [(0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledCompactPanel
1906
- // The top-level form scrolls, so its toolbar STICKS and carries a
1907
- // dark blurred backdrop so content ghosts cleanly beneath it. A
1908
- // nested (arg_schema) sub-form owns no scroll context — drop the
1909
- // sticky, the backdrop, and the stacking context so its header is
1910
- // transparent inside the parent's card.
1911
- , __assign({ "$headerBg": compactNested ? 'transparent' : headerBg, "$nested": compactNested, flat: true, raised: true, minimal: true,
1993
+ // Mirrors the toolbar's own search-row gate: when no search
1994
+ // row renders, the header is a thin strip and sits tight to
1995
+ // the first status box (see StyledCompactPanel).
1996
+ , __assign({ "$tightHeader": !((compactToolbarParts === null || compactToolbarParts === void 0 ? void 0 : compactToolbarParts.search) && (0, size_1.default)(availableOptions) > 1), "$headerBg": compactNested ? 'transparent' : headerBg, "$nested": compactNested, flat: true, raised: true, minimal: true,
1912
1997
  // No panel background: the form sits transparently on whatever
1913
1998
  // hosts it (page, drawer, or — for an arg_schema field — the
1914
1999
  // parent's edit card) instead of stacking its own dark surface.
@@ -1938,24 +2023,27 @@ var FormEngineImpl = function (_a) {
1938
2023
  onCollapseChange: function (collapsed) {
1939
2024
  return setOpenedStatusBox(collapsed ? undefined : box.key);
1940
2025
  }, flat: true, minimal: true, collapseButtonProps: { flat: true, minimal: true, size: 'small' }, collapsible: true,
1941
- // The Optional box now holds every not-yet-added field, so
1942
- // it starts COLLAPSED to keep the form focused on what's in
1943
- // use. But a SEARCH must surface matching addable fields —
1944
- // and ReqorePanel unmounts collapsed content — so force it
1945
- // open whenever a query is active. (isCollapsed is the
1946
- // panel's controllable state; manual toggling still works
1947
- // when no query is set.)
1948
- // The Optional box starts collapsed so a form opens on what
1949
- // is in use — but only when there IS something else to
1950
- // open on. When every field is optional it is the whole
1951
- // form, and collapsing it renders a card that looks empty
1952
- // and broken: an auth profile's Authorization block, whose
1953
- // nine requirement fields are all optional, showed as a
1954
- // titled card containing one collapsed "Optional 9" strip
1955
- // and nothing else. A search still forces it open
1956
- // (ReqorePanel unmounts collapsed content, so a match
1957
- // inside it would be unreachable otherwise).
1958
- isCollapsed: box.key === 'optional' && !query && !onlyOptionalRows, label: (0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledGroupHeader, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { effect: { weight: 'bold' }, size: 'normal', children: box.label }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', minimal: true, compact: true, intent: box.intent, label: String(count) })] }), icon: box.icon, className: 'options-readfirst-group', padded: false, contentStyle: { padding: '4px 4px 6px' }, children: (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledGroupBody, { "$divider": cDivider, "$hover": cHover, "$focus": cWarning, "$success": cSuccess, "$rowBg": cRowBg, "$lineColor": cGroupLine, className: compactNarrow ? 'readfirst-narrow' : undefined, children: groupsInBox.map(function (groupName) {
2026
+ // Which boxes start closed is the consumer's call
2027
+ // (`compactCollapsedGroups`, default `['optional']`: the
2028
+ // Optional box holds every not-yet-added field, so a form
2029
+ // opens on what is in use). Two rules override it:
2030
+ //
2031
+ // A SEARCH forces every box open — ReqorePanel unmounts
2032
+ // collapsed content, so a match inside a closed box would
2033
+ // be unreachable. (isCollapsed is the panel's controllable
2034
+ // state; manual toggling still works with no query set.)
2035
+ //
2036
+ // The Optional box stays open when it is the ONLY box,
2037
+ // because collapsing it renders a card that looks empty and
2038
+ // broken: an auth profile's Authorization block, whose nine
2039
+ // requirement fields are all optional, showed as a titled
2040
+ // card containing one collapsed "Optional 9" strip and
2041
+ // nothing else. This does not generalise to the other two —
2042
+ // a lone Set box collapsed is a deliberate ask, and its
2043
+ // header still reports what is in there.
2044
+ isCollapsed: compactCollapsedGroups.includes(box.key) &&
2045
+ !query &&
2046
+ !(box.key === 'optional' && onlyOptionalRows), label: (0, jsx_runtime_1.jsxs)(compactRowStyles_1.StyledGroupHeader, { children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { effect: { weight: 'bold' }, size: 'normal', children: box.label }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreTag, { size: 'small', minimal: true, compact: true, intent: box.intent, label: String(count) })] }), icon: box.icon, className: 'options-readfirst-group', padded: false, contentStyle: { padding: '4px 4px 6px' }, children: (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledGroupBody, { "$divider": cDivider, "$hover": cHover, "$focus": cWarning, "$success": cSuccess, "$rowBg": cRowBg, "$lineColor": cGroupLine, className: compactNarrow ? 'readfirst-narrow' : undefined, children: groupsInBox.map(function (groupName) {
1959
2047
  var groupConfig = groups === null || groups === void 0 ? void 0 : groups[groupName];
1960
2048
  return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [showGroupSubLabel(groupName) ?
1961
2049
  (0, jsx_runtime_1.jsx)(compactRowStyles_1.StyledStatusBoxGroupLabel, { children: (0, readFirst_1.getOptionGroupLabel)(groupName, groups) })