| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import { pageMetadata } from "@/lib/page-metadata"
- export const metadata = pageMetadata("docs/computed-values")
- # Computed Values
- Derive dynamic prop values using registered functions or string templates.
- ## `$template` — String Interpolation
- Use `{ "$template": "..." }` to embed state values into a string. References use `${/path}` syntax where the path is a JSON Pointer:
- ```json
- {
- "type": "Text",
- "props": {
- "text": { "$template": "Hello, ${/user/name}! You have ${/inbox/count} messages." }
- },
- "children": []
- }
- ```
- If state is `{ "user": { "name": "Alice" }, "inbox": { "count": 3 } }`, the text renders as "Hello, Alice! You have 3 messages."
- Missing paths resolve to an empty string.
- ## `$computed` — Registered Functions
- Use `{ "$computed": "<name>", "args": { ... } }` to call a named function registered in your catalog. Each arg can be a literal value or any prop expression (`$state`, `$item`, `$cond`, etc.):
- ```json
- {
- "type": "Text",
- "props": {
- "text": {
- "$computed": "fullName",
- "args": {
- "first": { "$state": "/form/firstName" },
- "last": { "$state": "/form/lastName" }
- }
- }
- },
- "children": []
- }
- ```
- ### Registering Functions
- Functions are registered in the catalog and provided at runtime.
- **Catalog definition (for AI prompt generation):**
- ```typescript
- import { defineCatalog } from '@json-render/core';
- import { schema } from '@json-render/react/schema';
- const catalog = defineCatalog(schema, {
- components: { /* ... */ },
- functions: {
- fullName: {
- description: 'Combines first and last name into a full name',
- },
- formatCurrency: {
- description: 'Formats a number as currency',
- },
- },
- });
- ```
- **Runtime implementation:**
- ```tsx
- import { JSONUIProvider } from '@json-render/react';
- const functions = {
- fullName: (args) => `${args.first ?? ''} ${args.last ?? ''}`.trim(),
- formatCurrency: (args) => {
- const value = Number(args.value ?? 0);
- return new Intl.NumberFormat('en-US', {
- style: 'currency',
- currency: (args.currency as string) ?? 'USD',
- }).format(value);
- },
- };
- <JSONUIProvider registry={registry} functions={functions}>
- <Renderer spec={spec} registry={registry} />
- </JSONUIProvider>
- ```
- ### Using with `createRenderer`
- ```tsx
- const MyRenderer = createRenderer(catalog, components);
- <MyRenderer
- spec={spec}
- functions={functions}
- />
- ```
- ## Combining Expressions
- `$computed` args can use any expression type. This example computes a total from repeat item fields:
- ```json
- {
- "$computed": "lineTotal",
- "args": {
- "price": { "$item": "price" },
- "quantity": { "$item": "quantity" }
- }
- }
- ```
- ## Next
- - [Watchers](/docs/watchers) — react to state changes with cascading actions
- - [Data Binding](/docs/data-binding) — all expression types
- - [Validation](/docs/validation) — validate form inputs
|