diff --git a/content/docs/guide/architecture.md b/content/docs/guide/architecture.md index 9bdb84df9..35c560cf5 100644 --- a/content/docs/guide/architecture.md +++ b/content/docs/guide/architecture.md @@ -253,12 +253,18 @@ ObjectUI includes a powerful expression engine for dynamic UIs: ```json { - "type": "badge", - "text": "${orders.length} Orders", - "variant": "${orders.length > 10 ? 'success' : 'warning'}" + "type": "statistic", + "label": "Orders", + "value": "${orders.length}", + "description": "${orders.length > 10 ? 'Above target' : 'On track'}" } ``` +`statistic` rather than `badge`: an expression is evaluated only on a key the node's own +type carries, and `expressionBindableTextKeysFor` gives `statistic` the rows `label`, +`value` and `description` while giving `badge` none. A badge's text is its `label`, and it +has to arrive already resolved. + See the [Expressions Guide](/docs/guide/expressions) for complete details. ## Data Flow diff --git a/content/docs/guide/layout.md b/content/docs/guide/layout.md index 7a8c7511c..f54c7cd88 100644 --- a/content/docs/guide/layout.md +++ b/content/docs/guide/layout.md @@ -508,11 +508,11 @@ Omit `sidebar` and the content fills the width under the top bar. ```json { "type": "page", - "title": "${record.name}", + "title": "Acme Corporation", "breadcrumbs": [ { "label": "Home", "href": "/" }, { "label": "Customers", "href": "/customers" }, - { "label": "${record.name}" } + { "label": "Acme Corporation" } ], "actions": [ { diff --git a/content/docs/guide/schema-rendering.md b/content/docs/guide/schema-rendering.md index 70cdb10ae..61257c6cb 100644 --- a/content/docs/guide/schema-rendering.md +++ b/content/docs/guide/schema-rendering.md @@ -182,12 +182,19 @@ Object UI includes a powerful expression system for dynamic behavior: ```json { - "type": "badge", - "text": "${status === 'active' ? 'Active' : 'Inactive'}", - "variant": "${status === 'active' ? 'success' : 'default'}" + "type": "card", + "title": "${status === 'active' ? 'Active' : 'Inactive'}", + "description": "${status === 'active' ? 'This record is in use.' : 'This record is archived.'}" } ``` +`card` here rather than `badge`, because an expression is evaluated only on a key the +node's own type carries. `expressionBindableTextKeysFor` — the lookup `SchemaRenderer` +consumes out of `@objectstack/spec` — gives `card` the rows `title` and `description`, +and gives `badge` no rows at all, so a `${…}` written on a badge reaches the DOM as the +characters you typed. Resolve a badge's text before you hand the schema over, and author +it on `label`: `text` is not a `BadgeSchema` key. + ### Visibility Control ```json @@ -203,15 +210,26 @@ Object UI includes a powerful expression system for dynamic behavior: ```json { "type": "alert", - "message": "Welcome!", - "variant": "${ - user.isNew ? 'info' : - user.tasks.length === 0 ? 'warning' : - 'success' - }" + "variant": "default", + "title": "Welcome!", + "body": { + "type": "text", + "content": "${ + user.isNew ? 'Start with the quick tour.' : + user.tasks.length === 0 ? 'You are all caught up.' : + 'You have tasks waiting.' + }" + } } ``` +The branch sits on the nested `text` node's `content`, which `SchemaRenderer` evaluates +on every node type — the escape hatch for a component that carries no expression rows of +its own, and `alert` is one of those. Its severity could not be chosen by expression in +any case: `AlertSchema.variant` is the closed set `default` | `destructive`, so `info`, +`warning` and `success` are not values it accepts. Pick the variant in the host and +author it as a literal. + ## Event Handling Components can emit events that you handle in React: @@ -411,12 +429,19 @@ Always type your schemas for better IDE support and fewer runtime errors. ```json { "type": "alert", - "variant": "error", + "variant": "destructive", "visibleOn": "${error}", - "message": "${error.message}" + "title": "Something went wrong", + "body": { "type": "text", "content": "${error.message}" } } ``` +`visibleOn` is a condition key and is evaluated on every node type. The message text is a +nested `text` node because `alert` carries no expression rows — and `message` is not an +`AlertSchema` key at all: the alert's own text keys are `title` and `description`, and the +renderer falls back from `description` to `body`. `destructive` is the variant this state +wants; `error` is not in the closed set. + ## Next Steps - [Component Registry](./component-registry.md) - Learn about component registration