@qoretechnologies/reqraft 0.10.15 → 0.10.17

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 (54) hide show
  1. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  2. package/dist/components/form/engine/CompactRow.js +82 -3
  3. package/dist/components/form/engine/CompactRow.js.map +1 -1
  4. package/dist/components/form/engine/FormEngine.d.ts +57 -11
  5. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  6. package/dist/components/form/engine/FormEngine.js +199 -110
  7. package/dist/components/form/engine/FormEngine.js.map +1 -1
  8. package/dist/components/form/engine/compactRowContext.d.ts +8 -0
  9. package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
  10. package/dist/components/form/engine/compactRowContext.js.map +1 -1
  11. package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
  12. package/dist/components/form/engine/compactRowStyles.js +1 -1
  13. package/dist/components/form/engine/compactRowStyles.js.map +1 -1
  14. package/dist/components/form/engine/optionActions.d.ts +28 -0
  15. package/dist/components/form/engine/optionActions.d.ts.map +1 -0
  16. package/dist/components/form/engine/optionActions.js +18 -0
  17. package/dist/components/form/engine/optionActions.js.map +1 -0
  18. package/dist/components/form/engine/readFirst.d.ts +9 -2
  19. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  20. package/dist/components/form/engine/readFirst.js +15 -3
  21. package/dist/components/form/engine/readFirst.js.map +1 -1
  22. package/dist/components/form/engine/rendererTypes.d.ts +35 -0
  23. package/dist/components/form/engine/rendererTypes.d.ts.map +1 -0
  24. package/dist/components/form/engine/rendererTypes.js +63 -0
  25. package/dist/components/form/engine/rendererTypes.js.map +1 -0
  26. package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
  27. package/dist/components/form/fields/auto/AutoFormField.js +6 -1
  28. package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
  29. package/dist/components/form/index.d.ts +2 -0
  30. package/dist/components/form/index.d.ts.map +1 -1
  31. package/dist/components/form/index.js +2 -0
  32. package/dist/components/form/index.js.map +1 -1
  33. package/dist/hooks/useMediaQuery.d.ts +24 -0
  34. package/dist/hooks/useMediaQuery.d.ts.map +1 -0
  35. package/dist/hooks/useMediaQuery.js +56 -0
  36. package/dist/hooks/useMediaQuery.js.map +1 -0
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +7 -1
  40. package/dist/index.js.map +1 -1
  41. package/package.json +2 -2
  42. package/src/components/form/engine/CompactRow.tsx +139 -0
  43. package/src/components/form/engine/FormEngine.stories.tsx +73 -0
  44. package/src/components/form/engine/FormEngine.tsx +270 -70
  45. package/src/components/form/engine/FormEngineRemote.stories.tsx +329 -0
  46. package/src/components/form/engine/compactRowContext.ts +8 -0
  47. package/src/components/form/engine/compactRowStyles.ts +30 -0
  48. package/src/components/form/engine/optionActions.ts +40 -0
  49. package/src/components/form/engine/readFirst.ts +25 -6
  50. package/src/components/form/engine/rendererTypes.ts +55 -0
  51. package/src/components/form/fields/auto/AutoFormField.tsx +6 -1
  52. package/src/components/form/index.tsx +2 -0
  53. package/src/hooks/useMediaQuery.ts +61 -0
  54. package/src/index.tsx +7 -0
@@ -102,6 +102,9 @@ var react_1 = require("react");
102
102
  var jsx_runtime_1 = require("react/jsx-runtime");
103
103
  var reqore_1 = require("@qoretechnologies/reqore");
104
104
  var colors_1 = require("@qoretechnologies/reqore/dist/helpers/colors");
105
+ var optionActions_1 = require("./optionActions");
106
+ var rendererTypes_1 = require("./rendererTypes");
107
+ var useMediaQuery_1 = require("../../../hooks/useMediaQuery");
105
108
  var lodash_1 = require("lodash");
106
109
  var isArray_1 = __importDefault(require("lodash/isArray"));
107
110
  var map_1 = __importDefault(require("lodash/map"));
@@ -200,7 +203,10 @@ var StyledCommitDock = styled_components_1.default.div(templateObject_2 || (temp
200
203
  });
201
204
  var getType = function (type, operators, operator) {
202
205
  var finalType = getTypeFromOperator(operators, (0, exports.fixOperatorValue)(operator)) || type;
203
- return ((0, isArray_1.default)(finalType) ? finalType[0] : finalType);
206
+ var resolvedType = (0, isArray_1.default)(finalType) ? finalType[0] : finalType;
207
+ // A value can be received before its server-driven option schema. Keep the
208
+ // renderer type-safe during that transition without guessing a concrete type.
209
+ return (resolvedType || 'any');
204
210
  };
205
211
  exports.getType = getType;
206
212
  var getTypeFromOperator = function (operators, operatorData) {
@@ -214,15 +220,36 @@ var fixOperatorValue = function (operator) {
214
220
  return (0, isArray_1.default)(operator) ? operator : [operator];
215
221
  };
216
222
  exports.fixOperatorValue = fixOperatorValue;
223
+ var getOptionSchemaStorageType = function (option, isRendererOnly) {
224
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
225
+ return ((isRendererOnly(option === null || option === void 0 ? void 0 : option.ui_type)
226
+ ? (option === null || option === void 0 ? void 0 : option.type) || (option === null || option === void 0 ? void 0 : option.ui_type)
227
+ : (option === null || option === void 0 ? void 0 : option.ui_type) || (option === null || option === void 0 ? void 0 : option.type)) || 'any');
228
+ };
229
+ var getOptionFieldStorageType = function (optionName, fieldType, schema, operators, operatorData, isRendererOnly) {
230
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
231
+ var schemaOption = schema === null || schema === void 0 ? void 0 : schema[optionName];
232
+ var storedType = fieldType && !(fieldType === (schemaOption === null || schemaOption === void 0 ? void 0 : schemaOption.ui_type) && isRendererOnly(fieldType))
233
+ ? fieldType
234
+ : getOptionSchemaStorageType(schemaOption, isRendererOnly);
235
+ return (0, exports.getType)(storedType, operators, operatorData);
236
+ };
217
237
  var hasRequiredOptions = function (options) {
218
238
  if (options === void 0) { options = {}; }
219
239
  return !!(0, lodash_1.findKey)(options, function (option) { return option.required; });
220
240
  };
221
241
  exports.hasRequiredOptions = hasRequiredOptions;
222
242
  exports.OptionsContext = (0, use_context_selector_1.createContext)({});
223
- var fixOptions = function (value, options, operators) {
243
+ var fixOptions = function (value, options, operators, isRendererOnly) {
224
244
  if (value === void 0) { value = {}; }
245
+ if (isRendererOnly === void 0) { isRendererOnly = rendererTypes_1.isRendererOnlyUiType; }
225
246
  var fixedValue = (0, lodash_1.cloneDeep)(value);
247
+ // Server-driven schemas can arrive after the persisted value. Preserve that
248
+ // value verbatim until its schema is available instead of manufacturing
249
+ // partially typed form fields that can crash the following render.
250
+ if (!(0, size_1.default)(options)) {
251
+ return fixedValue;
252
+ }
226
253
  (0, lodash_1.forEach)(options, function (option, name) {
227
254
  var _a, _b, _c, _d, _f, _g, _h;
228
255
  if (option.value ||
@@ -230,7 +257,7 @@ var fixOptions = function (value, options, operators) {
230
257
  ((option.required || option.preselected) && !fixedValue[name]) ||
231
258
  ((option.required || option.preselected) && option.default_value && !option.value)) {
232
259
  var obj = void 0;
233
- var type = (0, exports.getType)((option.ui_type || option.type), operators, (_a = fixedValue[name]) === null || _a === void 0 ? void 0 : _a.op);
260
+ var type = (0, exports.getType)(getOptionSchemaStorageType(option, isRendererOnly), operators, (_a = fixedValue[name]) === null || _a === void 0 ? void 0 : _a.op);
234
261
  if (((_b = option.default_value) === null || _b === void 0 ? void 0 : _b.is_expression) &&
235
262
  ((_c = fixedValue[name]) === null || _c === void 0 ? void 0 : _c.value) === undefined) {
236
263
  obj = option.default_value;
@@ -251,29 +278,32 @@ var fixOptions = function (value, options, operators) {
251
278
  });
252
279
  var res = (0, reduce_1.default)(fixedValue, function (newValue, option, optionName) {
253
280
  var _a;
254
- var _b, _c, _d, _f, _g, _h, _j, _k, _l;
281
+ var _b, _c, _d, _f, _g, _h, _j, _k;
255
282
  var newOption = option;
256
283
  if (!(0, lodash_1.isPlainObject)(newOption) || !(newOption === null || newOption === void 0 ? void 0 : newOption.type)) {
257
- var fixedOption = {
258
- type: (0, exports.getType)((((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) || ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type)), operators, newOption === null || newOption === void 0 ? void 0 : newOption.op),
259
- value: newOption,
260
- };
261
- if (newOption === null || newOption === void 0 ? void 0 : newOption.is_expression) {
262
- fixedOption.is_expression = true;
263
- }
284
+ var isUntypedEnvelope = (0, lodash_1.isPlainObject)(newOption) && 'value' in newOption;
285
+ var untypedFieldValue = isUntypedEnvelope ? newOption.value : newOption;
286
+ // Spread the original envelope first so every key it carried survives —
287
+ // rebuilding from just {type, value} silently dropped `op`, `is_expression`
288
+ // and anything else a field needs to render, which emptied the card.
289
+ var fixedOption = __assign(__assign({}, ((0, lodash_1.isPlainObject)(newOption) ? newOption : {})), { type: (0, exports.getType)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), operators, newOption === null || newOption === void 0 ? void 0 : newOption.op), value: untypedFieldValue });
264
290
  newOption = fixedOption;
265
291
  }
292
+ else if (newOption.type === ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) &&
293
+ isRendererOnly(newOption.type)) {
294
+ newOption = __assign(__assign({}, newOption), { type: (0, exports.getType)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), operators, newOption.op) });
295
+ }
266
296
  if (newOption.value !== undefined &&
267
- ((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.allowed_values) &&
268
- !((_g = (_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.allowed_values) === null || _g === void 0 ? void 0 : _g.find(function (allowedValue) { var _a; return ((_a = allowedValue.value) === null || _a === void 0 ? void 0 : _a.value) === newOption.value || allowedValue.name === newOption.value; })) &&
297
+ ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values) &&
298
+ !((_f = (_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.allowed_values) === null || _f === void 0 ? void 0 : _f.find(function (allowedValue) { var _a; return ((_a = allowedValue.value) === null || _a === void 0 ? void 0 : _a.value) === newOption.value || allowedValue.name === newOption.value; })) &&
269
299
  !(0, TemplateField_1.isValueTemplate)(newOption.value) &&
270
- !((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.multiselect) &&
271
- !((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.allowed_values_creatable)) {
300
+ !((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.multiselect) &&
301
+ !((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.allowed_values_creatable)) {
272
302
  newOption.value = undefined;
273
303
  }
274
304
  if (newOption.value &&
275
- ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.readonly) &&
276
- ((_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.default_value) &&
305
+ ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.readonly) &&
306
+ ((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.default_value) &&
277
307
  (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]) !== newOption.value) {
278
308
  newOption.value = (0, common_1.getDefaultValue)(options[optionName]);
279
309
  }
@@ -332,44 +362,53 @@ var FormEngine = function (_a) {
332
362
  var _b, _c, _d, _f, _g;
333
363
  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
334
364
  isValid = _a.isValid, // eslint-disable-line @typescript-eslint/no-unused-vars
335
- url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _h = _a.allowTemplates, allowTemplates = _h === void 0 ? true : _h, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, _j = _a.showTypeToggle, showTypeToggle = _j === void 0 ? true : _j, compact = _a.compact, _k = _a.compactFlush, compactFlush = _k === void 0 ? false : _k, _l = _a.compactNested, compactNested = _l === void 0 ? false : _l, compactPanelProps = _a.compactPanelProps, _m = _a.commitMode, commitMode = _m === void 0 ? 'immediate' : _m, _o = _a.expandMode, expandMode = _o === void 0 ? 'single' : _o, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, componentOverrides = _a.componentOverrides, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "componentOverrides", "inheritedFromParent", "autoFocusFirstRequired"]);
336
- var _p = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _p[0], setOptions = _p[1];
365
+ url = _a.url, customUrl = _a.customUrl, operatorsUrl = _a.operatorsUrl, onOptionsLoaded = _a.onOptionsLoaded, recordRequiresSearchOptions = _a.recordRequiresSearchOptions, readOnly = _a.readOnly, _h = _a.allowTemplates, allowTemplates = _h === void 0 ? true : _h, interfaceContext = _a.interfaceContext, templateFieldProps = _a.templateFieldProps, _j = _a.showTypeToggle, showTypeToggle = _j === void 0 ? true : _j, compact = _a.compact, _k = _a.compactFlush, compactFlush = _k === void 0 ? false : _k, _l = _a.compactNested, compactNested = _l === void 0 ? false : _l, compactPanelProps = _a.compactPanelProps, _m = _a.commitMode, commitMode = _m === void 0 ? 'immediate' : _m, _o = _a.expandMode, expandMode = _o === void 0 ? 'single' : _o, onCommit = _a.onCommit, operatorsProp = _a.operators, groups = _a.groups, optionsLoader = _a.optionsLoader, onValidityChange = _a.onValidityChange, optionActions = _a.optionActions, _p = _a.optionActionsCollapse, optionActionsCollapse = _p === void 0 ? 'auto' : _p, componentOverrides = _a.componentOverrides, rendererOnlyUiTypes = _a.rendererOnlyUiTypes, inheritedFromParent = _a.inheritedFromParent, autoFocusFirstRequired = _a.autoFocusFirstRequired, initialExpandedOptions = _a.initialExpandedOptions, rest = __rest(_a, ["name", "uniqueName", "value", "onChange", "onSingleOptionsChange", "onDependableOptionChange", "placeholder", "noValueString", "isValid", "url", "customUrl", "operatorsUrl", "onOptionsLoaded", "recordRequiresSearchOptions", "readOnly", "allowTemplates", "interfaceContext", "templateFieldProps", "showTypeToggle", "compact", "compactFlush", "compactNested", "compactPanelProps", "commitMode", "expandMode", "onCommit", "operators", "groups", "optionsLoader", "onValidityChange", "optionActions", "optionActionsCollapse", "componentOverrides", "rendererOnlyUiTypes", "inheritedFromParent", "autoFocusFirstRequired", "initialExpandedOptions"]);
366
+ // Built-ins + whatever the consumer declared for its own injected editors.
367
+ var isRendererOnly = (0, react_2.useMemo)(function () { return (0, rendererTypes_1.createRendererOnlyUiTypeCheck)(rendererOnlyUiTypes); }, [JSON.stringify(rendererOnlyUiTypes)]);
368
+ // Resolved once here rather than per row — every CompactRow reads the answer
369
+ // off the context instead of opening its own matchMedia subscription.
370
+ var canHover = (0, useMediaQuery_1.useCanHover)();
371
+ var isNarrowViewport = (0, useMediaQuery_1.useIsNarrowViewport)();
372
+ var collapseOptionActions = optionActionsCollapse === 'always' ? true
373
+ : optionActionsCollapse === 'never' ? false
374
+ : !canHover || isNarrowViewport;
375
+ var _q = (0, react_2.useState)((rest === null || rest === void 0 ? void 0 : rest.options) || undefined), options = _q[0], setOptions = _q[1];
337
376
  // optionsLoader lifecycle: loading feeds the skeleton gate, error the banner.
338
- var _q = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _q[0], setOptionsLoading = _q[1];
339
- var _r = (0, react_2.useState)(), optionsError = _r[0], setOptionsError = _r[1];
377
+ var _r = (0, react_2.useState)(!!optionsLoader && !(rest === null || rest === void 0 ? void 0 : rest.options)), optionsLoading = _r[0], setOptionsLoading = _r[1];
378
+ var _s = (0, react_2.useState)(), optionsError = _s[0], setOptionsError = _s[1];
340
379
  // Operators: prop-provided (compact) or fetched via operatorsUrl (dpql,
341
380
  // ported from IDE Options) — the fetch overrides the seeded prop value.
342
- var _s = (0, react_2.useState)(operatorsProp), operators = _s[0], setOperators = _s[1];
381
+ var _t = (0, react_2.useState)(operatorsProp), operators = _t[0], setOperators = _t[1];
343
382
  // Remote-fetch loading (ported from IDE Options); only relevant when one of
344
383
  // the fetch urls is set — schema-as-props consumers never see the skeleton.
345
- var _t = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _t[0], setLoading = _t[1];
384
+ var _u = (0, react_2.useState)(!!(url || customUrl || operatorsUrl)), loading = _u[0], setLoading = _u[1];
346
385
  var confirmAction = (0, reqore_1.useReqoreProperty)('confirmAction');
347
386
  var theme = (0, reqore_1.useReqoreTheme)();
348
- var _u = (0, react_2.useState)(), focusedEditing = _u[0], setFocusedEditing = _u[1];
349
- var _v = (0, react_2.useState)(false), showFieldTypes = _v[0], setShowFieldTypes = _v[1];
387
+ var _v = (0, react_2.useState)(), focusedEditing = _v[0], setFocusedEditing = _v[1];
388
+ var _w = (0, react_2.useState)(false), showFieldTypes = _w[0], setShowFieldTypes = _w[1];
350
389
  // Global toggle (toolbar ⓘ): reveal the short-description info panel on every
351
390
  // field that has a short_desc. Per-row ⓘ overrides still win over it.
352
391
  // Global field-info visibility, tri-state: `undefined` = default (critical
353
392
  // messages auto-open, the rest closed); `true` = show all; `false` = hide all
354
393
  // (even message fields). The toolbar ⓘ drives it.
355
- var _w = (0, react_2.useState)(undefined), showAllDescriptions = _w[0], setShowAllDescriptions = _w[1];
356
- var _x = (0, react_2.useState)(), showHelpForOption = _x[0], setShowHelpForOption = _x[1];
357
- var _y = (0, react_2.useState)(false), showInvalidOptionsOnly = _y[0], setShowInvalidOptionsOnly = _y[1];
394
+ var _x = (0, react_2.useState)(undefined), showAllDescriptions = _x[0], setShowAllDescriptions = _x[1];
395
+ var _y = (0, react_2.useState)(), showHelpForOption = _y[0], setShowHelpForOption = _y[1];
396
+ var _z = (0, react_2.useState)(false), showInvalidOptionsOnly = _z[0], setShowInvalidOptionsOnly = _z[1];
358
397
  // Which options are expanded into their editor (several can be open at once).
359
- var _z = (0, react_2.useState)([]), expandedOptions = _z[0], setExpandedOptions = _z[1];
398
+ var _0 = (0, react_2.useState)([]), expandedOptions = _0[0], setExpandedOptions = _0[1];
360
399
  // Remembers each row's last settled status box, so an actively-edited field
361
400
  // stays put when its status flips (e.g. becomes valid) instead of jumping to
362
401
  // another box mid-edit and stealing focus. Keyed by option name.
363
402
  var settledBucket = (0, react_2.useRef)({});
364
403
  // Measured form width (not viewport — the form lives in drawers/panels of
365
404
  // arbitrary width) drives the stacked narrow layout.
366
- var _0 = (0, react_use_1.useMeasure)(), compactWrapRef = _0[0], compactWrapWidth = _0[1].width;
405
+ var _1 = (0, react_use_1.useMeasure)(), compactWrapRef = _1[0], compactWrapWidth = _1[1].width;
367
406
  // Own handle on the scroll wrap (useMeasure's ref is a callback, no `.current`)
368
407
  // so the label-column measurement can publish its CSS var on the element. It's
369
408
  // STATE, not a ref: the wrap mounts only after the loading-skeleton gate
370
409
  // resolves, so the measurement effect must re-run when the node appears — a
371
410
  // ref wouldn't retrigger it.
372
- var _1 = (0, react_2.useState)(null), compactWrapNode = _1[0], setCompactWrapNode = _1[1];
411
+ var _2 = (0, react_2.useState)(null), compactWrapNode = _2[0], setCompactWrapNode = _2[1];
373
412
  var setCompactWrap = (0, react_2.useCallback)(function (node) {
374
413
  compactWrapRef(node);
375
414
  setCompactWrapNode(function (prev) { return (prev === node ? prev : node); });
@@ -406,8 +445,8 @@ var FormEngine = function (_a) {
406
445
  var readRowHeights = (0, react_2.useRef)({});
407
446
  // Required-groups linkage: hovering a group chip highlights every member row;
408
447
  // clicking a sibling in the chip's popover scrolls to it and flashes it.
409
- var _2 = (0, react_2.useState)([]), highlightedOptions = _2[0], setHighlightedOptions = _2[1];
410
- var _3 = (0, react_2.useState)([]), flashedOptions = _3[0], setFlashedOptions = _3[1];
448
+ var _3 = (0, react_2.useState)([]), highlightedOptions = _3[0], setHighlightedOptions = _3[1];
449
+ var _4 = (0, react_2.useState)([]), flashedOptions = _4[0], setFlashedOptions = _4[1];
411
450
  var flashTimeout = (0, react_2.useRef)();
412
451
  var flashOptions = (0, react_2.useCallback)(function (optionNames, scrollToFirst) {
413
452
  if (scrollToFirst === void 0) { scrollToFirst = false; }
@@ -449,16 +488,16 @@ var FormEngine = function (_a) {
449
488
  });
450
489
  var compactNarrow = !!compactWrapWidth && compactWrapWidth < 480;
451
490
  // Info panels auto-open on Tier-1 content; the per-row user override sticks.
452
- var _4 = (0, react_2.useState)({}), infoPanelOverrides = _4[0], setInfoPanelOverrides = _4[1];
491
+ var _5 = (0, react_2.useState)({}), infoPanelOverrides = _5[0], setInfoPanelOverrides = _5[1];
453
492
  // Toolbar filters affect the listed rows only — the meter reflects the full set.
454
- var _5 = (0, react_2.useState)(false), requiredOnly = _5[0], setRequiredOnly = _5[1];
455
- var _6 = (0, react_2.useState)(''), compactQuery = _6[0], setCompactQuery = _6[1];
493
+ var _6 = (0, react_2.useState)(false), requiredOnly = _6[0], setRequiredOnly = _6[1];
494
+ var _7 = (0, react_2.useState)(''), compactQuery = _7[0], setCompactQuery = _7[1];
456
495
  // Compact field sort (Fields menu → "Sort by"); 'schema' = declared order.
457
- var _7 = (0, react_2.useState)('schema'), compactSort = _7[0], setCompactSort = _7[1];
458
- var _8 = (0, react_2.useState)(function () { return ({
459
- fields: (0, exports.fixOptions)(value, options || {}),
496
+ var _8 = (0, react_2.useState)('schema'), compactSort = _8[0], setCompactSort = _8[1];
497
+ var _9 = (0, react_2.useState)(function () { return ({
498
+ fields: (0, exports.fixOptions)(value, options || {}, undefined, isRendererOnly),
460
499
  meta: undefined,
461
- }); }), localValue = _8[0], setLocalValue = _8[1];
500
+ }); }), localValue = _9[0], setLocalValue = _9[1];
462
501
  var originalValue = (0, react_2.useRef)();
463
502
  // Track the last value we emitted via onChange so we can skip re-applying fixOptions
464
503
  // when the parent echoes it back as the new value prop (controlled component loop prevention)
@@ -467,7 +506,7 @@ var FormEngine = function (_a) {
467
506
  originalValue.current = localValue.fields;
468
507
  }
469
508
  var unavailableOptionsCount = (0, react_2.useRef)(0);
470
- var _9 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _9.compactValue, typesLoading = _9.loading;
509
+ var _10 = (0, useQorusTypes_1.useQorusTypes)(), compactValue = _10.compactValue, typesLoading = _10.loading;
471
510
  var templates = (0, useTemplates_1.useTemplates)(allowTemplates, rest.stringTemplates, interfaceContext);
472
511
  (0, react_2.useEffect)(function () {
473
512
  if ((0, lodash_1.isEqual)(localValue.fields, value)) {
@@ -541,7 +580,7 @@ var FormEngine = function (_a) {
541
580
  setOptions({});
542
581
  return [2 /*return*/];
543
582
  }
544
- setLocalValue({ fields: (0, exports.fixOptions)(value, data.data), meta: undefined });
583
+ setLocalValue({ fields: (0, exports.fixOptions)(value, data.data, undefined, isRendererOnly), meta: undefined });
545
584
  if (!operatorsUrl) {
546
585
  setLoading(false);
547
586
  }
@@ -600,7 +639,7 @@ var FormEngine = function (_a) {
600
639
  }
601
640
  setOptions(data.data);
602
641
  onOptionsLoaded === null || onOptionsLoaded === void 0 ? void 0 : onOptionsLoaded(data.data);
603
- setLocalValue({ fields: (0, exports.fixOptions)({}, data.data), meta: undefined });
642
+ setLocalValue({ fields: (0, exports.fixOptions)({}, data.data, undefined, isRendererOnly), meta: undefined });
604
643
  return [2 /*return*/];
605
644
  }
606
645
  });
@@ -633,7 +672,7 @@ var FormEngine = function (_a) {
633
672
  }
634
673
  }, [operatorsUrl]);
635
674
  (0, react_use_1.useUpdateEffect)(function () {
636
- var fixedValue = (0, exports.fixOptions)(value, options || {});
675
+ var fixedValue = (0, exports.fixOptions)(value, options || {}, undefined, isRendererOnly);
637
676
  // When the value we're receiving is the one we just emitted AND fixOptions has nothing to
638
677
  // meaningfully add or change, skip the update. This breaks the controlled-component loop for
639
678
  // arg_schema fields while still allowing required/preselected options to be restored (in that
@@ -652,21 +691,23 @@ var FormEngine = function (_a) {
652
691
  originalValue.current = fixedValue;
653
692
  }
654
693
  setLocalValue === null || setLocalValue === void 0 ? void 0 : setLocalValue({ fields: fixedValue, meta: undefined });
655
- }, [JSON.stringify(options), JSON.stringify(value)]);
694
+ }, [JSON.stringify(options), JSON.stringify(value), isRendererOnly]);
656
695
  var handleValueChange = (0, react_2.useCallback)(function (optionName, val, _type, isFunction) {
657
696
  setLocalValue(function (_a) {
658
697
  var _b, _c;
659
- var _d, _f, _g, _h, _j, _k, _l, _m, _o;
660
- var _p = _a.fields, fields = _p === void 0 ? {} : _p;
661
- var schemaType = (((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.ui_type) ||
662
- ((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.type));
698
+ var _d, _f, _g, _h, _j, _k, _l, _m, _o, _p;
699
+ var _q = _a.fields, fields = _q === void 0 ? {} : _q;
700
+ var schemaType = getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly);
663
701
  var isAnyLike = schemaType === 'any' || schemaType === 'auto';
664
702
  // For any/auto schema types, preserve the user's chosen type stored in the field
665
- var resolvedSchemaType = isAnyLike && ((_g = fields[optionName]) === null || _g === void 0 ? void 0 : _g.type) ?
666
- fields[optionName].type
667
- : schemaType || ((_h = fields[optionName]) === null || _h === void 0 ? void 0 : _h.type);
703
+ var resolvedSchemaType = isAnyLike && ((_d = fields[optionName]) === null || _d === void 0 ? void 0 : _d.type)
704
+ ? fields[optionName].type
705
+ : ((_f = fields[optionName]) === null || _f === void 0 ? void 0 : _f.type) === ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.ui_type) &&
706
+ isRendererOnly((_h = fields[optionName]) === null || _h === void 0 ? void 0 : _h.type)
707
+ ? schemaType
708
+ : schemaType || ((_j = fields[optionName]) === null || _j === void 0 ? void 0 : _j.type);
668
709
  var type = _type ||
669
- (0, exports.getTypeAndCanBeNull)(resolvedSchemaType, (_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.allowed_values).type;
710
+ (0, exports.getTypeAndCanBeNull)(resolvedSchemaType, (_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.allowed_values).type;
670
711
  if (!fields[optionName]) {
671
712
  var defaultOperators = (0, reduce_1.default)(operators || {}, function (filteredOperators, operator, operatorKey) {
672
713
  if (operator.selected) {
@@ -695,9 +736,9 @@ var FormEngine = function (_a) {
695
736
  delete updatedValue[optionName].is_expression;
696
737
  }
697
738
  var meta = {};
698
- if (((_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.has_dependents) &&
739
+ if (((_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.has_dependents) &&
699
740
  val !== undefined &&
700
- val !== ((_l = fields[optionName]) === null || _l === void 0 ? void 0 : _l.value)) {
741
+ val !== ((_m = fields[optionName]) === null || _m === void 0 ? void 0 : _m.value)) {
701
742
  (0, lodash_1.forEach)(options, function (option, depName) {
702
743
  if (option.depends_on &&
703
744
  (0, lodash_1.flatten)(option.depends_on).includes(optionName) &&
@@ -707,8 +748,8 @@ var FormEngine = function (_a) {
707
748
  });
708
749
  onDependableOptionChange === null || onDependableOptionChange === void 0 ? void 0 : onDependableOptionChange(optionName, val, updatedValue, options);
709
750
  }
710
- if ((0, size_1.default)((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.on_change)) {
711
- meta.events = (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.on_change;
751
+ if ((0, size_1.default)((_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.on_change)) {
752
+ meta.events = (_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.on_change;
712
753
  }
713
754
  onSingleOptionsChange === null || onSingleOptionsChange === void 0 ? void 0 : onSingleOptionsChange(optionName, updatedValue[optionName]);
714
755
  return {
@@ -719,6 +760,7 @@ var FormEngine = function (_a) {
719
760
  }, [
720
761
  onSingleOptionsChange,
721
762
  onDependableOptionChange,
763
+ isRendererOnly,
722
764
  JSON.stringify(options),
723
765
  JSON.stringify(operators),
724
766
  ]);
@@ -796,9 +838,8 @@ var FormEngine = function (_a) {
796
838
  setExpandedOptions(function (prev) { return prev.filter(function (name) { return name !== optionName; }); });
797
839
  }, []);
798
840
  var handleAddOptionalFieldChange = (0, react_2.useCallback)(function (_name, optionName) {
799
- var _a, _b, _c;
800
- handleValueChange(optionName, (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), (0, exports.getTypeAndCanBeNull)((((_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
801
- ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.type)), (_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.allowed_values).type);
841
+ var _a;
842
+ handleValueChange(optionName, (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), (0, exports.getTypeAndCanBeNull)(getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[optionName], isRendererOnly), (_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.allowed_values).type);
802
843
  }, [JSON.stringify(options), handleValueChange]);
803
844
  var availableOptions = (0, react_2.useMemo)(function () {
804
845
  if (!options) {
@@ -820,22 +861,18 @@ var FormEngine = function (_a) {
820
861
  removeSelectedOption(optionName);
821
862
  return newValue;
822
863
  }
823
- var schemaType = (0, exports.getType)((options[optionName].ui_type || options[optionName].type), operators, option === null || option === void 0 ? void 0 : option.op);
864
+ var rendererType = (0, exports.getType)((options[optionName].ui_type || options[optionName].type), operators, option === null || option === void 0 ? void 0 : option.op);
865
+ var storageType = getOptionFieldStorageType(optionName, option === null || option === void 0 ? void 0 : option.type, options, operators, option === null || option === void 0 ? void 0 : option.op, isRendererOnly);
824
866
  if (!(0, lodash_1.isPlainObject)(option)) {
825
867
  return __assign(__assign({}, newValue), (_a = {}, _a[optionName] = {
826
- type: schemaType,
868
+ type: storageType || rendererType,
827
869
  value: option,
828
870
  }, _a));
829
871
  }
830
- // any/auto: preserve the user-picked type; otherwise normalize to the
831
- // schema type (ui_type wins) so rendering and validation agree.
832
- var isAnyLike = schemaType === 'any' || schemaType === 'auto';
833
- var effectiveType = isAnyLike && (option === null || option === void 0 ? void 0 : option.type) ?
834
- option.type
835
- : schemaType;
836
- return __assign(__assign({}, newValue), (_b = {}, _b[optionName] = __assign(__assign({}, option), { type: effectiveType }), _b));
872
+ return __assign(__assign({}, newValue), (_b = {}, _b[optionName] = __assign(__assign({}, option), { type: storageType || rendererType }), _b));
837
873
  }, {});
838
874
  }, [
875
+ isRendererOnly,
839
876
  JSON.stringify(fixedValue),
840
877
  JSON.stringify(options),
841
878
  unavailableOptionsCount.current,
@@ -904,13 +941,11 @@ var FormEngine = function (_a) {
904
941
  }, [JSON.stringify(options), JSON.stringify(availableOptions), JSON.stringify(localValue.fields)]);
905
942
  var getValidityData = (0, react_2.useCallback)(function () {
906
943
  var fields = (0, reduce_1.default)(availableOptions, function (result, option, optionName) {
907
- var _a, _b, _c, _d;
908
- var type = option.type ||
909
- ((_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.ui_type) ||
910
- ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.type);
944
+ var _a, _b;
945
+ var type = getOptionFieldStorageType(optionName, option.type, options, operators, option.op, isRendererOnly);
911
946
  var optionValue = option.value;
912
- var isRequired = (_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.required;
913
- var hasRequiredGroups = !!((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.required_groups);
947
+ var isRequired = (_a = options === null || options === void 0 ? void 0 : options[optionName]) === null || _a === void 0 ? void 0 : _a.required;
948
+ var hasRequiredGroups = !!((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.required_groups);
914
949
  var isEmpty = optionValue === undefined || optionValue === '';
915
950
  var validation;
916
951
  if (!isRequired && !hasRequiredGroups && isEmpty) {
@@ -936,8 +971,10 @@ var FormEngine = function (_a) {
936
971
  invalidFields: invalidFields,
937
972
  };
938
973
  }, [
974
+ isRendererOnly,
939
975
  JSON.stringify(availableOptions),
940
976
  JSON.stringify(options),
977
+ JSON.stringify(operators),
941
978
  JSON.stringify(localValue.fields),
942
979
  ]);
943
980
  var validityData = (0, react_2.useMemo)(function () { return getValidityData(); }, [getValidityData]);
@@ -948,15 +985,19 @@ var FormEngine = function (_a) {
948
985
  var shownOptions = (0, react_2.useMemo)(function () {
949
986
  return (0, reduce_1.default)(availableOptions, function (newValue, option, optionName) {
950
987
  var _a;
951
- var _b, _c;
952
988
  if (showInvalidOptionsOnly &&
953
- isOptionValid(optionName, ((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type) ||
954
- ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type), option.value)) {
989
+ isOptionValid(optionName, getOptionFieldStorageType(optionName, option.type, options, operators, option.op, isRendererOnly), option.value)) {
955
990
  return newValue;
956
991
  }
957
992
  return __assign(__assign({}, newValue), (_a = {}, _a[optionName] = option, _a));
958
993
  }, {});
959
- }, [showInvalidOptionsOnly, JSON.stringify(availableOptions)]);
994
+ }, [
995
+ showInvalidOptionsOnly,
996
+ isRendererOnly,
997
+ JSON.stringify(availableOptions),
998
+ JSON.stringify(options),
999
+ JSON.stringify(operators),
1000
+ ]);
960
1001
  // Read-first STATUS / BOX for one option — lifted to component scope so the
961
1002
  // status boxes (renderCompact) and the header's "needs attention" count share
962
1003
  // exactly one definition. One-of group members travel together (bucket by the
@@ -971,13 +1012,13 @@ var FormEngine = function (_a) {
971
1012
  return undefined;
972
1013
  }, [JSON.stringify(options)]);
973
1014
  var getOptionStatus = (0, react_2.useCallback)(function (name, hidden) {
974
- var _a;
1015
+ var _a, _b, _c;
975
1016
  if (hidden === void 0) { hidden = false; }
976
1017
  if (hidden)
977
1018
  return 'optional';
978
1019
  var schema = options === null || options === void 0 ? void 0 : options[name];
979
- var type = ((schema === null || schema === void 0 ? void 0 : schema.ui_type) || (schema === null || schema === void 0 ? void 0 : schema.type));
980
- var value = (_a = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _a === void 0 ? void 0 : _a.value;
1020
+ var type = getOptionFieldStorageType(name, (_a = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _a === void 0 ? void 0 : _a.type, options, operators, (_b = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _b === void 0 ? void 0 : _b.op, isRendererOnly);
1021
+ var value = (_c = availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[name]) === null || _c === void 0 ? void 0 : _c.value;
981
1022
  var empty = (0, readFirst_1.isOptionValueEmpty)(value);
982
1023
  var reqGroups = (schema === null || schema === void 0 ? void 0 : schema.required_groups) || [];
983
1024
  var required = !!((schema === null || schema === void 0 ? void 0 : schema.required) || reqGroups.length);
@@ -996,8 +1037,10 @@ var FormEngine = function (_a) {
996
1037
  warned: msgIntent === 'warning',
997
1038
  });
998
1039
  }, [
1040
+ isRendererOnly,
999
1041
  JSON.stringify(options),
1000
1042
  JSON.stringify(availableOptions),
1043
+ JSON.stringify(operators),
1001
1044
  isOptionValid,
1002
1045
  requiredGroupsInfo,
1003
1046
  schemaMsgIntent,
@@ -1074,6 +1117,31 @@ var FormEngine = function (_a) {
1074
1117
  : __spreadArray(__spreadArray([], prev, true), [optionName], false);
1075
1118
  });
1076
1119
  }, [expandMode]);
1120
+ // --- Caller-named starting rows (opt-in) ----------------------------------
1121
+ // `initialExpandedOptions` lets a consumer name the rows that must already
1122
+ // be open when the form first paints — the case where the expanded row is
1123
+ // part of an address rather than a click (see the prop's docs).
1124
+ //
1125
+ // One-shot for the same reason autofocus is: it fires on the first render
1126
+ // that actually has rows (so an async-loaded schema is covered) and then
1127
+ // never again, so a row the user collapses afterwards stays collapsed and a
1128
+ // later schema reload does not reopen it.
1129
+ var hasAppliedInitialExpansionRef = (0, react_2.useRef)(false);
1130
+ (0, react_2.useEffect)(function () {
1131
+ if (!(initialExpandedOptions === null || initialExpandedOptions === void 0 ? void 0 : initialExpandedOptions.length) || !compact || hasAppliedInitialExpansionRef.current) {
1132
+ return;
1133
+ }
1134
+ var names = Object.keys(availableOptions);
1135
+ if (!names.length) {
1136
+ return;
1137
+ }
1138
+ hasAppliedInitialExpansionRef.current = true;
1139
+ var toExpand = initialExpandedOptions.filter(function (name) { return names.includes(name); });
1140
+ if (!toExpand.length) {
1141
+ return;
1142
+ }
1143
+ setExpandedOptions(function (prev) { return __spreadArray(__spreadArray([], prev, true), toExpand.filter(function (name) { return !prev.includes(name); }), true); });
1144
+ }, [initialExpandedOptions, compact, availableOptions]);
1077
1145
  // --- First-attention-field autofocus (opt-in) -----------------------------
1078
1146
  // With `autoFocusFirstRequired`, drop the user straight into the first field
1079
1147
  // they must fix. We reuse the engine's own ordering (`availableOptions`), the
@@ -1198,10 +1266,10 @@ var FormEngine = function (_a) {
1198
1266
  next[optionName] = value;
1199
1267
  }
1200
1268
  });
1201
- return { fields: (0, exports.fixOptions)(next, options || {}, operators), meta: undefined };
1269
+ return { fields: (0, exports.fixOptions)(next, options || {}, operators, isRendererOnly), meta: undefined };
1202
1270
  });
1203
1271
  setRequiredOnly(false);
1204
- }, [JSON.stringify(options), JSON.stringify(operators)]);
1272
+ }, [JSON.stringify(options), JSON.stringify(operators), isRendererOnly]);
1205
1273
  var getCustomMenuTemplateItems = (0, react_2.useCallback)(function (optionName) {
1206
1274
  return compactValue === null || compactValue === void 0 ? void 0 : compactValue.map(function (type) { return ({
1207
1275
  label: type.display_name,
@@ -1220,9 +1288,27 @@ var FormEngine = function (_a) {
1220
1288
  // The info panel below the row keeps showing schema messages while editing —
1221
1289
  // rendering them in the editor too would balloon a one-line edit.
1222
1290
  suppressSchemaMessages) {
1223
- var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1291
+ var _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1224
1292
  var type = _a.type, other = __rest(_a, ["type"]);
1225
1293
  var operatorParts = (0, exports.fixOperatorValue)(other.op);
1294
+ // The RENDERER type for this row — which editor mounts. Distinct from the
1295
+ // storage type on the value envelope: a `richtext` field stores a string
1296
+ // but must render the richtext editor, so `ui_type` wins here.
1297
+ //
1298
+ // The exception is an any-like `ui_type`. Those schemas say
1299
+ // `ui_type: 'any'` precisely so the user can pick a concrete type, and
1300
+ // that pick lives on the field's stored `type` — letting 'any' win would
1301
+ // pin the row to the untyped editor forever.
1302
+ //
1303
+ // The trailing fallbacks keep the row rendering when a server-driven
1304
+ // schema has not arrived yet (`type` undefined) instead of crashing.
1305
+ var schemaUiType = (_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.ui_type;
1306
+ var uiTypeIsAnyLike = schemaUiType === 'any' || schemaUiType === 'auto';
1307
+ var resolvedType = (schemaUiType && !uiTypeIsAnyLike ? schemaUiType : undefined) ||
1308
+ type ||
1309
+ schemaUiType ||
1310
+ ((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.type) ||
1311
+ 'any';
1226
1312
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(function () {
1227
1313
  var _a;
1228
1314
  var schemaMsgs = (suppressSchemaMessages ?
@@ -1257,7 +1343,7 @@ var FormEngine = function (_a) {
1257
1343
  (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { disabled: readOnly, icon: 'DeleteBinLine', effect: NegativeColorEffect, fixed: true, onClick: function () { return handleRemoveOperator(optionName, fixedValue, index); } })
1258
1344
  : null] }, index));
1259
1345
  }) }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 })] })
1260
- : null, (0, react_1.createElement)(TemplateField_1.TemplateField, __assign({ fluid: true }, options === null || options === void 0 ? void 0 : options[optionName], resolveInheritProps((_b = options === null || options === void 0 ? void 0 : options[optionName]) === null || _b === void 0 ? void 0 : _b.inherit_props, availableOptions, inheritedFromParent), {
1346
+ : null, (0, react_1.createElement)(TemplateField_1.TemplateField, __assign({ fluid: true }, options === null || options === void 0 ? void 0 : options[optionName], resolveInheritProps((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.inherit_props, availableOptions, inheritedFromParent), {
1261
1347
  // qorus#347-followup (scope forwarding): merge accumulated
1262
1348
  // inheritance (`inheritedFromParent`) with THIS field's freshly
1263
1349
  // resolved inherit_props, and pass down as a single bag so any
@@ -1269,26 +1355,30 @@ var FormEngine = function (_a) {
1269
1355
  // `inherit_props: { language: 'language' }`, the list renderer
1270
1356
  // forwards it into each row, and the row's body resolves against
1271
1357
  // the accumulated bag.
1272
- inheritedFromParent: __assign(__assign({}, inheritedFromParent), resolveInheritProps((_c = options === null || options === void 0 ? void 0 : options[optionName]) === null || _c === void 0 ? void 0 : _c.inherit_props, availableOptions, inheritedFromParent)),
1358
+ inheritedFromParent: __assign(__assign({}, inheritedFromParent), resolveInheritProps((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.inherit_props, availableOptions, inheritedFromParent)),
1273
1359
  // Propagate compact so an arg_schema field renders a COMPACT sub-form
1274
1360
  // (consistent with the parent) rather than the classic FormEngine.
1275
1361
  compact: compact,
1276
1362
  // SEAM: forwarded through TemplateField's rest-spread to AutoFormField,
1277
1363
  // which renders consumer-injected editors by field type/ui_type.
1278
- componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((_d = options === null || options === void 0 ? void 0 : options[optionName]) === null || _d === void 0 ? void 0 : _d.supports_templates)), allowFunctions: !!((_f = options === null || options === void 0 ? void 0 : options[optionName]) === null || _f === void 0 ? void 0 : _f.supports_expressions),
1364
+ componentOverrides: componentOverrides, allowTemplates: !!(allowTemplates && ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.supports_templates)), allowFunctions: !!((_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.supports_expressions),
1279
1365
  // reqraft: form-level expression fields get the Visual/Text shell
1280
1366
  // (DPQL text mode); opt out per-form via `templateFieldProps`.
1281
- allowTextExpressions: true, allowCustomValues: ((_g = options === null || options === void 0 ? void 0 : options[optionName]) === null || _g === void 0 ? void 0 : _g.supports_custom_values) !== false && type !== 'any', templates: templates.value }, (0, exports.getTypeAndCanBeNull)(type, (_h = options === null || options === void 0 ? void 0 : options[optionName]) === null || _h === void 0 ? void 0 : _h.allowed_values, other.op), { ui_type: type, name: optionName, uniqueName: "".concat(uniqueName ? "".concat(uniqueName, ".") : "".concat(name ? "".concat(name, ".") : '')).concat(optionName), onChange:
1367
+ allowTextExpressions: true, allowCustomValues: ((_j = options === null || options === void 0 ? void 0 : options[optionName]) === null || _j === void 0 ? void 0 : _j.supports_custom_values) !== false && resolvedType !== 'any', templates: templates.value }, (0, exports.getTypeAndCanBeNull)(
1368
+ // The RENDERER type picks the editor — the storage type lives on
1369
+ // the value envelope. Passing storage here rendered a `richtext`
1370
+ // field as a plain string input.
1371
+ resolvedType, (_k = options === null || options === void 0 ? void 0 : options[optionName]) === null || _k === void 0 ? void 0 : _k.allowed_values, other.op), { ui_type: resolvedType, name: optionName, uniqueName: "".concat(uniqueName ? "".concat(uniqueName, ".") : "".concat(name ? "".concat(name, ".") : '')).concat(optionName), onChange:
1282
1372
  // Identity-stable on purpose: the typed fields debounce on
1283
1373
  // `[localValue, onChange]` — an inline lambda resets the pending emit
1284
1374
  // every render and the typed value can starve.
1285
- 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, disabled: ((_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.disabled) ||
1375
+ handleValueChange, key: optionName, arg_schema: (_l = options === null || options === void 0 ? void 0 : options[optionName]) === null || _l === void 0 ? void 0 : _l.arg_schema, noSoft: !!(rest === null || rest === void 0 ? void 0 : rest.options), value: other.value, isFunction: other.is_expression, isDefaultFunction: ((_m = options === null || options === void 0 ? void 0 : options[optionName]) === null || _m === void 0 ? void 0 : _m.default_view) === 'expression', sensitive: (_o = options === null || options === void 0 ? void 0 : options[optionName]) === null || _o === void 0 ? void 0 : _o.sensitive, default_value: (0, common_1.getDefaultValue)(options === null || options === void 0 ? void 0 : options[optionName]), isDefaultTemplate: ((_p = options === null || options === void 0 ? void 0 : options[optionName]) === null || _p === void 0 ? void 0 : _p.default_view) === 'template', allowed_values: (_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.allowed_values, disabled: ((_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.disabled) ||
1286
1376
  readOnly ||
1287
- !(0, validations_1.hasAllDependenciesFullfilled)((_q = options === null || options === void 0 ? void 0 : options[optionName]) === null || _q === void 0 ? void 0 : _q.depends_on, availableOptions, options || {}), readOnly: readOnly, size: editorSize || rest.size, menuItems: ((_r = options === null || options === void 0 ? void 0 : options[optionName]) === null || _r === void 0 ? void 0 : _r.ui_type) === 'any' ?
1377
+ !(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' ?
1288
1378
  getCustomMenuTemplateItems(optionName)
1289
- : undefined }, templateFieldProps)), (0, jsx_runtime_1.jsx)(OptionFieldMessages_1.OptionFieldMessages, { schema: options || {}, allOptions: availableOptions, name: optionName, option: __assign({ type: type }, other), getType: getTypeForOption }), operators && (0, size_1.default)(operators) && (0, size_1.default)(other.op) ?
1379
+ : undefined }, templateFieldProps)), (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) ?
1290
1380
  (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 ?
1291
- type === 'richtext' ?
1381
+ resolvedType === 'richtext' ?
1292
1382
  (0, common_1.richtextToString)(other.value)
1293
1383
  : JSON.stringify(other.value)
1294
1384
  : '' })] }) })] })
@@ -1369,6 +1459,8 @@ var FormEngine = function (_a) {
1369
1459
  getTypeForOption: getTypeForOption,
1370
1460
  isOptionValid: isOptionValid,
1371
1461
  confirmAction: confirmAction,
1462
+ optionActions: optionActions,
1463
+ collapseOptionActions: collapseOptionActions,
1372
1464
  renderOption: renderOption,
1373
1465
  theme: theme,
1374
1466
  cText: cText,
@@ -1413,6 +1505,8 @@ var FormEngine = function (_a) {
1413
1505
  getTypeForOption,
1414
1506
  isOptionValid,
1415
1507
  confirmAction,
1508
+ optionActions,
1509
+ collapseOptionActions,
1416
1510
  renderOption,
1417
1511
  theme,
1418
1512
  cText,
@@ -1535,7 +1629,7 @@ var FormEngine = function (_a) {
1535
1629
  var isUnset_1 = function (name) { var _a; return (0, readFirst_1.isOptionValueEmpty)((_a = shownOptions[name]) === null || _a === void 0 ? void 0 : _a.value); };
1536
1630
  var isFieldInvalid_1 = function (name) {
1537
1631
  var _a, _b, _c;
1538
- return !isOptionValid(name, (((_a = options === null || options === void 0 ? void 0 : options[name]) === null || _a === void 0 ? void 0 : _a.ui_type) || ((_b = options === null || options === void 0 ? void 0 : options[name]) === null || _b === void 0 ? void 0 : _b.type)), (_c = shownOptions[name]) === null || _c === void 0 ? void 0 : _c.value);
1632
+ return !isOptionValid(name, getOptionFieldStorageType(name, (_a = shownOptions[name]) === null || _a === void 0 ? void 0 : _a.type, options, operators, (_b = shownOptions[name]) === null || _b === void 0 ? void 0 : _b.op, isRendererOnly), (_c = shownOptions[name]) === null || _c === void 0 ? void 0 : _c.value);
1539
1633
  };
1540
1634
  var comparator_1 = function (a, b) {
1541
1635
  switch (compactSort) {
@@ -1623,15 +1717,12 @@ var FormEngine = function (_a) {
1623
1717
  // rows — no wrapper — so the value surface applies normally; the rail + nodes
1624
1718
  // are drawn per member). Narrow stacks fall back to flat rows.
1625
1719
  var renderGroupRows = function (names) {
1626
- var renderRow = function (entry, clustered, clusterFirst, clusterLast) {
1627
- var _a, _b;
1628
- return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1629
- {
1630
- type: (((_a = options === null || options === void 0 ? void 0 : options[entry.name]) === null || _a === void 0 ? void 0 : _a.ui_type) || ((_b = options === null || options === void 0 ? void 0 : options[entry.name]) === null || _b === void 0 ? void 0 : _b.type)),
1631
- value: undefined,
1632
- }
1633
- : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name));
1634
- };
1720
+ var renderRow = function (entry, clustered, clusterFirst, clusterLast) { return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1721
+ {
1722
+ type: getOptionSchemaStorageType(options === null || options === void 0 ? void 0 : options[entry.name], isRendererOnly),
1723
+ value: undefined,
1724
+ }
1725
+ : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name)); };
1635
1726
  // (Clustering runs in narrow mode too now — the "One of the below is
1636
1727
  // required" box wraps the members regardless of width; it no longer relies
1637
1728
  // on a contiguous rail.)
@@ -1797,13 +1888,11 @@ var FormEngine = function (_a) {
1797
1888
  options[optionName].stretch,
1798
1889
  size: 'small',
1799
1890
  floatingActions: true,
1800
- actions: __spreadArray(__spreadArray([], (typeof optionActions === 'function' ?
1801
- optionActions({
1802
- name: optionName,
1803
- schema: options[optionName],
1804
- value: availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[optionName],
1805
- })
1806
- : (optionActions !== null && optionActions !== void 0 ? optionActions : [])), true), [
1891
+ actions: __spreadArray(__spreadArray([], (0, optionActions_1.resolveOptionActions)(optionActions, {
1892
+ name: optionName,
1893
+ schema: options[optionName],
1894
+ value: availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[optionName],
1895
+ }), true), [
1807
1896
  {
1808
1897
  size: 'tiny',
1809
1898
  icon: 'FullscreenLine',