@object-ui/react 13.2.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @object-ui/react
2
2
 
3
+ ## 14.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 86c69c3: ADR-0089: read the canonical `visibleWhen` conditional-visibility predicate in the form + page renderers.
8
+
9
+ `@objectstack/spec` now unifies conditional visibility under a single canonical key, `visibleWhen`, and folds the deprecated `visibleOn` (view form) / `visibility` (page component) aliases into it at parse. This updates ObjectUI to read the canonical key:
10
+
11
+ - **Page renderer** (`SchemaRenderer`) — evaluates `visibleWhen` first (show-when-truthy), then the deprecated `visibleOn` / `visibility` as a defensive read for raw / un-normalized metadata. `visibleWhen` is stripped from DOM props.
12
+ - **Spec→node bridges** — the page bridge maps a component's `visibleWhen ?? visibility` onto the node's canonical `visibleWhen`; the form-view bridge maps a field's `visibleWhen ?? visibleOn` onto the ObjectForm view-level predicate slot.
13
+ - **Form renderers** — the `@object-ui/react` `FormRenderer` prefers `visibleWhen` over the `visibleOn` alias. (`ObjectForm`/`form.tsx` already evaluated `visibleWhen`.)
14
+ - **Types** — the component base schema (`BaseSchema` / `base.zod`) gains the canonical `visibleWhen`; `visibleOn` is marked `@deprecated`.
15
+
16
+ Fully back-compat: existing `visibleOn` / `visibility` metadata keeps working through the alias reads.
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [443360a]
21
+ - Updated dependencies [c70bca7]
22
+ - Updated dependencies [86c69c3]
23
+ - Updated dependencies [05e56ca]
24
+ - Updated dependencies [5971cc4]
25
+ - Updated dependencies [6a74160]
26
+ - @object-ui/core@14.0.0
27
+ - @object-ui/i18n@14.0.0
28
+ - @object-ui/types@14.0.0
29
+ - @object-ui/data-objectstack@14.0.0
30
+
3
31
  ## 13.2.0
4
32
 
5
33
  ### Patch Changes
@@ -216,18 +216,25 @@ export const SchemaRenderer = forwardRef(({ schema, ...props }, _ref) => {
216
216
  }
217
217
  newSchema.props = newProps;
218
218
  }
219
- // Evaluate visibility: visible / visibleOn / visibility / hidden / hiddenOn
219
+ // Evaluate visibility: visible / visibleWhen / visibleOn / visibility / hidden / hiddenOn
220
220
  const shouldHide = (() => {
221
221
  if (newSchema.visible !== undefined) {
222
222
  return !evaluator.evaluateCondition(newSchema.visible);
223
223
  }
224
+ // `visibleWhen` is the single canonical conditional-visibility predicate
225
+ // across every layer since ADR-0089 (show-when-truthy). The spec folds the
226
+ // deprecated `visibleOn` (view) / `visibility` (page) aliases into it at
227
+ // parse, so it is checked FIRST; the aliases below remain as a defensive
228
+ // read for any raw / un-normalized metadata reaching the renderer.
229
+ if (newSchema.visibleWhen !== undefined) {
230
+ return !evaluator.evaluateCondition(newSchema.visibleWhen);
231
+ }
232
+ // @deprecated ADR-0089 → `visibleWhen`.
224
233
  if (newSchema.visibleOn !== undefined) {
225
234
  return !evaluator.evaluateCondition(newSchema.visibleOn);
226
235
  }
227
- // `visibility` is the spec-canonical predicate (PageComponentSchema.visibility,
228
- // an ExpressionInput) — show-when-truthy, same semantics as `visibleOn`. The
229
- // spec→node bridge preserves it verbatim on the node, so this is where it
230
- // finally gates rendering (previously it was inert and leaked as a DOM prop).
236
+ // @deprecated ADR-0089 → `visibleWhen` (was PageComponentSchema.visibility,
237
+ // an ExpressionInput) — show-when-truthy, same semantics as `visibleOn`.
231
238
  if (newSchema.visibility !== undefined) {
232
239
  return !evaluator.evaluateCondition(newSchema.visibility);
233
240
  }
@@ -291,7 +298,7 @@ export const SchemaRenderer = forwardRef(({ schema, ...props }, _ref) => {
291
298
  // Note: We don't forward the ref to the Component because components in the registry
292
299
  // may not support refs. The SchemaRenderer itself can still receive refs for its own use.
293
300
  // Extract schema metadata properties that should NOT be passed as React props
294
- const { type: _type, children: _children, body: _body, schema: _schema, visible: _visible, visibleOn: _visibleOn, visibility: _visibility, hidden: _hidden, hiddenOn: _hiddenOn, disabled: _disabled, disabledOn: _disabledOn, _hidden: __hidden, // stripped: internal visibility flag
301
+ const { type: _type, children: _children, body: _body, schema: _schema, visible: _visible, visibleWhen: _visibleWhen, visibleOn: _visibleOn, visibility: _visibility, hidden: _hidden, hiddenOn: _hiddenOn, disabled: _disabled, disabledOn: _disabledOn, _hidden: __hidden, // stripped: internal visibility flag
295
302
  _disabled: __disabled, // stripped: internal disabled flag
296
303
  responsiveStyles: _responsiveStyles, // stripped: compiled to scoped CSS, not a DOM prop
297
304
  ...componentProps } = evaluatedSchema;
@@ -69,11 +69,14 @@ function evaluateFieldVisibility(fieldConfig, formValues) {
69
69
  if (fieldConfig.hidden) {
70
70
  return false;
71
71
  }
72
- // Evaluate visibleOn expression
73
- if (fieldConfig.visibleOn) {
72
+ // Evaluate the conditional-visibility predicate. `visibleWhen` is canonical
73
+ // (ADR-0089); `visibleOn` is the deprecated alias, kept as a fallback for raw
74
+ // / un-normalized metadata.
75
+ const visiblePredicate = fieldConfig.visibleWhen ?? fieldConfig.visibleOn;
76
+ if (visiblePredicate) {
74
77
  try {
75
78
  const evaluator = new ExpressionEvaluator({ data: formValues, form: formValues });
76
- return evaluator.evaluateCondition(fieldConfig.visibleOn);
79
+ return evaluator.evaluateCondition(visiblePredicate);
77
80
  }
78
81
  catch {
79
82
  // On error, default to visible
@@ -99,7 +102,7 @@ const FormSectionRenderer = ({ section, methods, disabled = false, }) => {
99
102
  return section.fields.some((field) => {
100
103
  if (typeof field === 'string')
101
104
  return false;
102
- return !!field.dependsOn || !!field.visibleOn;
105
+ return !!field.dependsOn || !!field.visibleWhen || !!field.visibleOn;
103
106
  });
104
107
  }, [section.fields]);
105
108
  // Watch form values for conditional field evaluation
@@ -17,6 +17,9 @@ interface FormField {
17
17
  colSpan?: number;
18
18
  widget?: string;
19
19
  dependsOn?: string[];
20
+ /** Canonical conditional-visibility predicate (ADR-0089). */
21
+ visibleWhen?: string;
22
+ /** @deprecated ADR-0089 → `visibleWhen`. */
20
23
  visibleOn?: string;
21
24
  }
22
25
  interface FormSection {
@@ -26,8 +26,13 @@ function mapField(field) {
26
26
  mapped.widget = field.widget;
27
27
  if (field.dependsOn)
28
28
  mapped.dependsOn = field.dependsOn;
29
- if (field.visibleOn)
30
- mapped.visibleOn = field.visibleOn;
29
+ // ADR-0089: `visibleWhen` is the canonical view-form-field visibility predicate
30
+ // (the spec folds the deprecated `visibleOn` into it at parse). Prefer it and
31
+ // fall back to `visibleOn` for raw / un-normalized metadata. The ObjectForm
32
+ // renderer reads this view-level predicate from the node's `visibleOn` slot.
33
+ const visiblePredicate = field.visibleWhen ?? field.visibleOn;
34
+ if (visiblePredicate)
35
+ mapped.visibleOn = visiblePredicate;
31
36
  return mapped;
32
37
  }
33
38
  function mapSection(section) {
@@ -15,6 +15,9 @@ interface PageComponent {
15
15
  style?: Record<string, any>;
16
16
  responsiveStyles?: Record<string, any>;
17
17
  className?: string;
18
+ /** Canonical conditional-visibility predicate (ADR-0089). */
19
+ visibleWhen?: string;
20
+ /** @deprecated ADR-0089 → `visibleWhen`. */
18
21
  visibility?: string;
19
22
  dataSource?: any;
20
23
  responsive?: any;
@@ -38,8 +38,13 @@ function mapComponent(component) {
38
38
  }
39
39
  if (component.events)
40
40
  node.events = component.events;
41
- if (component.visibility)
42
- node.visibility = component.visibility;
41
+ // ADR-0089: `visibleWhen` is the canonical conditional-visibility predicate;
42
+ // the spec folds the deprecated `visibility` alias into it at parse, so prefer
43
+ // it and fall back to `visibility` for raw / un-normalized metadata. SchemaRenderer
44
+ // reads `visibleWhen` first (show-when-truthy).
45
+ const visiblePredicate = component.visibleWhen ?? component.visibility;
46
+ if (visiblePredicate)
47
+ node.visibleWhen = visiblePredicate;
43
48
  if (component.dataSource)
44
49
  node.dataSource = component.dataSource;
45
50
  if (component.responsive)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/react",
3
- "version": "13.2.0",
3
+ "version": "14.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "React bindings and SchemaRenderer component for Object UI",
@@ -24,12 +24,12 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@objectstack/spec": "^14.3.0",
27
+ "@objectstack/spec": "^14.6.0",
28
28
  "react-hook-form": "^7.81.0",
29
- "@object-ui/core": "13.2.0",
30
- "@object-ui/data-objectstack": "13.2.0",
31
- "@object-ui/i18n": "13.2.0",
32
- "@object-ui/types": "13.2.0"
29
+ "@object-ui/core": "14.0.0",
30
+ "@object-ui/data-objectstack": "14.0.0",
31
+ "@object-ui/i18n": "14.0.0",
32
+ "@object-ui/types": "14.0.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0 || ^19.0.0",