@qoretechnologies/reqraft 0.10.16 → 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 (53) 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 +37 -11
  5. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  6. package/dist/components/form/engine/FormEngine.js +174 -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 +1 -1
  42. package/src/components/form/engine/CompactRow.tsx +139 -0
  43. package/src/components/form/engine/FormEngine.tsx +222 -70
  44. package/src/components/form/engine/FormEngineRemote.stories.tsx +329 -0
  45. package/src/components/form/engine/compactRowContext.ts +8 -0
  46. package/src/components/form/engine/compactRowStyles.ts +30 -0
  47. package/src/components/form/engine/optionActions.ts +40 -0
  48. package/src/components/form/engine/readFirst.ts +25 -6
  49. package/src/components/form/engine/rendererTypes.ts +55 -0
  50. package/src/components/form/fields/auto/AutoFormField.tsx +6 -1
  51. package/src/components/form/index.tsx +2 -0
  52. package/src/hooks/useMediaQuery.ts +61 -0
  53. 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, 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", "componentOverrides", "inheritedFromParent", "autoFocusFirstRequired", "initialExpandedOptions"]);
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,
@@ -1223,10 +1266,10 @@ var FormEngine = function (_a) {
1223
1266
  next[optionName] = value;
1224
1267
  }
1225
1268
  });
1226
- return { fields: (0, exports.fixOptions)(next, options || {}, operators), meta: undefined };
1269
+ return { fields: (0, exports.fixOptions)(next, options || {}, operators, isRendererOnly), meta: undefined };
1227
1270
  });
1228
1271
  setRequiredOnly(false);
1229
- }, [JSON.stringify(options), JSON.stringify(operators)]);
1272
+ }, [JSON.stringify(options), JSON.stringify(operators), isRendererOnly]);
1230
1273
  var getCustomMenuTemplateItems = (0, react_2.useCallback)(function (optionName) {
1231
1274
  return compactValue === null || compactValue === void 0 ? void 0 : compactValue.map(function (type) { return ({
1232
1275
  label: type.display_name,
@@ -1245,9 +1288,27 @@ var FormEngine = function (_a) {
1245
1288
  // The info panel below the row keeps showing schema messages while editing —
1246
1289
  // rendering them in the editor too would balloon a one-line edit.
1247
1290
  suppressSchemaMessages) {
1248
- 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;
1249
1292
  var type = _a.type, other = __rest(_a, ["type"]);
1250
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';
1251
1312
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(function () {
1252
1313
  var _a;
1253
1314
  var schemaMsgs = (suppressSchemaMessages ?
@@ -1282,7 +1343,7 @@ var FormEngine = function (_a) {
1282
1343
  (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, { disabled: readOnly, icon: 'DeleteBinLine', effect: NegativeColorEffect, fixed: true, onClick: function () { return handleRemoveOperator(optionName, fixedValue, index); } })
1283
1344
  : null] }, index));
1284
1345
  }) }), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreVerticalSpacer, { height: 5 })] })
1285
- : 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), {
1286
1347
  // qorus#347-followup (scope forwarding): merge accumulated
1287
1348
  // inheritance (`inheritedFromParent`) with THIS field's freshly
1288
1349
  // resolved inherit_props, and pass down as a single bag so any
@@ -1294,26 +1355,30 @@ var FormEngine = function (_a) {
1294
1355
  // `inherit_props: { language: 'language' }`, the list renderer
1295
1356
  // forwards it into each row, and the row's body resolves against
1296
1357
  // the accumulated bag.
1297
- 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)),
1298
1359
  // Propagate compact so an arg_schema field renders a COMPACT sub-form
1299
1360
  // (consistent with the parent) rather than the classic FormEngine.
1300
1361
  compact: compact,
1301
1362
  // SEAM: forwarded through TemplateField's rest-spread to AutoFormField,
1302
1363
  // which renders consumer-injected editors by field type/ui_type.
1303
- 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),
1304
1365
  // reqraft: form-level expression fields get the Visual/Text shell
1305
1366
  // (DPQL text mode); opt out per-form via `templateFieldProps`.
1306
- 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:
1307
1372
  // Identity-stable on purpose: the typed fields debounce on
1308
1373
  // `[localValue, onChange]` — an inline lambda resets the pending emit
1309
1374
  // every render and the typed value can starve.
1310
- 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) ||
1311
1376
  readOnly ||
1312
- !(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' ?
1313
1378
  getCustomMenuTemplateItems(optionName)
1314
- : 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) ?
1315
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 ?
1316
- type === 'richtext' ?
1381
+ resolvedType === 'richtext' ?
1317
1382
  (0, common_1.richtextToString)(other.value)
1318
1383
  : JSON.stringify(other.value)
1319
1384
  : '' })] }) })] })
@@ -1394,6 +1459,8 @@ var FormEngine = function (_a) {
1394
1459
  getTypeForOption: getTypeForOption,
1395
1460
  isOptionValid: isOptionValid,
1396
1461
  confirmAction: confirmAction,
1462
+ optionActions: optionActions,
1463
+ collapseOptionActions: collapseOptionActions,
1397
1464
  renderOption: renderOption,
1398
1465
  theme: theme,
1399
1466
  cText: cText,
@@ -1438,6 +1505,8 @@ var FormEngine = function (_a) {
1438
1505
  getTypeForOption,
1439
1506
  isOptionValid,
1440
1507
  confirmAction,
1508
+ optionActions,
1509
+ collapseOptionActions,
1441
1510
  renderOption,
1442
1511
  theme,
1443
1512
  cText,
@@ -1560,7 +1629,7 @@ var FormEngine = function (_a) {
1560
1629
  var isUnset_1 = function (name) { var _a; return (0, readFirst_1.isOptionValueEmpty)((_a = shownOptions[name]) === null || _a === void 0 ? void 0 : _a.value); };
1561
1630
  var isFieldInvalid_1 = function (name) {
1562
1631
  var _a, _b, _c;
1563
- 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);
1564
1633
  };
1565
1634
  var comparator_1 = function (a, b) {
1566
1635
  switch (compactSort) {
@@ -1648,15 +1717,12 @@ var FormEngine = function (_a) {
1648
1717
  // rows — no wrapper — so the value surface applies normally; the rail + nodes
1649
1718
  // are drawn per member). Narrow stacks fall back to flat rows.
1650
1719
  var renderGroupRows = function (names) {
1651
- var renderRow = function (entry, clustered, clusterFirst, clusterLast) {
1652
- var _a, _b;
1653
- return ((0, jsx_runtime_1.jsx)(CompactRow_1.CompactRow, { optionName: entry.name, optionField: entry.hidden ?
1654
- {
1655
- 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)),
1656
- value: undefined,
1657
- }
1658
- : shownOptions[entry.name], hidden: entry.hidden, clustered: clustered, clusterFirst: clusterFirst, clusterLast: clusterLast }, entry.name));
1659
- };
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)); };
1660
1726
  // (Clustering runs in narrow mode too now — the "One of the below is
1661
1727
  // required" box wraps the members regardless of width; it no longer relies
1662
1728
  // on a contiguous rail.)
@@ -1822,13 +1888,11 @@ var FormEngine = function (_a) {
1822
1888
  options[optionName].stretch,
1823
1889
  size: 'small',
1824
1890
  floatingActions: true,
1825
- actions: __spreadArray(__spreadArray([], (typeof optionActions === 'function' ?
1826
- optionActions({
1827
- name: optionName,
1828
- schema: options[optionName],
1829
- value: availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions[optionName],
1830
- })
1831
- : (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), [
1832
1896
  {
1833
1897
  size: 'tiny',
1834
1898
  icon: 'FullscreenLine',