| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- import { pageMetadata } from "@/lib/page-metadata"
- export const metadata = pageMetadata("docs/api/directives")
- # @json-render/directives
- Pre-built custom directives for `@json-render/core`. Drop them into your catalog and renderer to add formatting, math, string manipulation, and i18n.
- ## Install
- ```bash
- npm install @json-render/directives
- ```
- ## Quick Start
- ```typescript
- import { standardDirectives } from '@json-render/directives';
- // Wire into prompt generation
- const prompt = catalog.prompt({ directives: standardDirectives });
- // Wire into the renderer
- <JSONUIProvider spec={spec} directives={standardDirectives}>
- ...
- </JSONUIProvider>
- ```
- To add factory directives like `createI18nDirective`, spread the array:
- ```typescript
- import { standardDirectives, createI18nDirective } from '@json-render/directives';
- const directives = [...standardDirectives, createI18nDirective(config)];
- ```
- ## Directives
- ### `$format` — Locale-aware value formatting
- Formats values using `Intl` formatters. Supports `date`, `currency`, `number`, and `percent`.
- ```json
- { "$format": "currency", "value": { "$state": "/cart/total" }, "currency": "USD" }
- ```
- ```json
- { "$format": "date", "value": { "$state": "/user/createdAt" } }
- ```
- ```json
- { "$format": "number", "value": 1234567, "notation": "compact" }
- ```
- ```json
- { "$format": "percent", "value": 0.75 }
- ```
- Relative dates are also supported:
- ```json
- { "$format": "date", "value": { "$state": "/post/createdAt" }, "style": "relative" }
- ```
- This returns strings like `"3h ago"`, `"2d from now"`, or `"just now"`.
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$format</code></td>
- <td><code>{'\"date\" | \"currency\" | \"number\" | \"percent\"'}</code></td>
- <td>Format type.</td>
- </tr>
- <tr>
- <td><code>value</code></td>
- <td><code>unknown</code></td>
- <td>Value to format. Accepts any dynamic expression.</td>
- </tr>
- <tr>
- <td><code>locale</code></td>
- <td><code>string</code></td>
- <td>Optional. Locale for formatting (e.g. <code>"en-US"</code>).</td>
- </tr>
- <tr>
- <td><code>currency</code></td>
- <td><code>string</code></td>
- <td>Optional. Currency code for <code>"currency"</code> format. Default: <code>"USD"</code>.</td>
- </tr>
- <tr>
- <td><code>notation</code></td>
- <td><code>string</code></td>
- <td>Optional. Notation for <code>"number"</code> format (e.g. <code>"compact"</code>).</td>
- </tr>
- <tr>
- <td><code>style</code></td>
- <td><code>string</code></td>
- <td>Optional. Set to <code>"relative"</code> for relative date formatting.</td>
- </tr>
- <tr>
- <td><code>options</code></td>
- <td><code>{'Record<string, unknown>'}</code></td>
- <td>Optional. Extra <code>Intl</code> formatter options.</td>
- </tr>
- </tbody>
- </table>
- ### `$math` — Arithmetic operations
- Performs arithmetic on one or two operands. Operands accept any dynamic expression.
- ```json
- { "$math": "add", "a": { "$state": "/subtotal" }, "b": { "$state": "/tax" } }
- ```
- ```json
- { "$math": "round", "a": 3.7 }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$math</code></td>
- <td><code>{'\"add\" | \"subtract\" | \"multiply\" | \"divide\" | \"mod\" | \"min\" | \"max\" | \"round\" | \"floor\" | \"ceil\" | \"abs\"'}</code></td>
- <td>Operation to perform.</td>
- </tr>
- <tr>
- <td><code>a</code></td>
- <td><code>unknown</code></td>
- <td>First operand. Defaults to <code>0</code> if missing.</td>
- </tr>
- <tr>
- <td><code>b</code></td>
- <td><code>unknown</code></td>
- <td>Second operand (binary ops only). Defaults to <code>0</code> if missing.</td>
- </tr>
- </tbody>
- </table>
- Unary operations (`round`, `floor`, `ceil`, `abs`) only use `a`. Division by zero returns `0`.
- ### `$concat` — String concatenation
- Concatenates multiple values into a single string. Each element is resolved then joined.
- ```json
- { "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$concat</code></td>
- <td><code>{'unknown[]'}</code></td>
- <td>Array of values to concatenate. Each is resolved, converted to string, and joined.</td>
- </tr>
- </tbody>
- </table>
- ### `$count` — Array/string length
- Returns the length of an array or string. Returns `0` for other types.
- ```json
- { "$count": { "$state": "/cart/items" } }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$count</code></td>
- <td><code>unknown</code></td>
- <td>Value to count. Accepts arrays and strings.</td>
- </tr>
- </tbody>
- </table>
- ### `$truncate` — Text truncation
- Truncates text to a maximum length with a configurable suffix.
- ```json
- { "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$truncate</code></td>
- <td><code>unknown</code></td>
- <td>Value to truncate.</td>
- </tr>
- <tr>
- <td><code>length</code></td>
- <td><code>number</code></td>
- <td>Optional. Max character length. Default: <code>100</code>.</td>
- </tr>
- <tr>
- <td><code>suffix</code></td>
- <td><code>string</code></td>
- <td>Optional. Suffix to append when truncated. Default: <code>"..."</code>.</td>
- </tr>
- </tbody>
- </table>
- ### `$pluralize` — Singular/plural forms
- Selects a singular, plural, or zero form based on a count.
- ```json
- { "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" }
- ```
- Output: `"3 items"`, `"1 item"`, or `"no items"`.
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$pluralize</code></td>
- <td><code>unknown</code></td>
- <td>Count value. Accepts dynamic expressions.</td>
- </tr>
- <tr>
- <td><code>one</code></td>
- <td><code>string</code></td>
- <td>Singular form label.</td>
- </tr>
- <tr>
- <td><code>other</code></td>
- <td><code>string</code></td>
- <td>Plural form label.</td>
- </tr>
- <tr>
- <td><code>zero</code></td>
- <td><code>string</code></td>
- <td>Optional. Label for count of zero. If omitted, uses <code>"0 {'<other>'}"</code>.</td>
- </tr>
- </tbody>
- </table>
- ### `$join` — Join array elements
- Joins array elements with a separator string.
- ```json
- { "$join": { "$state": "/tags" }, "separator": ", " }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$join</code></td>
- <td><code>unknown</code></td>
- <td>Array to join. Non-array values are converted to string.</td>
- </tr>
- <tr>
- <td><code>separator</code></td>
- <td><code>string</code></td>
- <td>Optional. Separator between elements. Default: <code>", "</code>.</td>
- </tr>
- </tbody>
- </table>
- ### `createI18nDirective` — Internationalization
- Factory function that creates a `$t` directive for translations with `{'{{param}}'}` interpolation.
- ```typescript
- import { createI18nDirective } from '@json-render/directives';
- const tDirective = createI18nDirective({
- locale: 'en',
- messages: {
- en: { "greeting": "Hello, {'{{name}}'}!", "checkout.submit": "Place Order" },
- es: { "greeting": "Hola, {'{{name}}'}!", "checkout.submit": "Realizar Pedido" },
- },
- fallbackLocale: 'en',
- });
- ```
- Usage in specs:
- ```json
- { "$t": "checkout.submit" }
- ```
- ```json
- { "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }
- ```
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>$t</code></td>
- <td><code>string</code></td>
- <td>Translation key.</td>
- </tr>
- <tr>
- <td><code>params</code></td>
- <td><code>{'Record<string, unknown>'}</code></td>
- <td>Optional. Interpolation parameters. Values accept dynamic expressions.</td>
- </tr>
- </tbody>
- </table>
- #### `I18nConfig`
- <table>
- <thead>
- <tr>
- <th>Field</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>locale</code></td>
- <td><code>string</code></td>
- <td>Current locale (e.g. <code>"en"</code>).</td>
- </tr>
- <tr>
- <td><code>messages</code></td>
- <td><code>{'Record<string, Record<string, string>>'}</code></td>
- <td>Map of locale to key-value translation pairs.</td>
- </tr>
- <tr>
- <td><code>fallbackLocale</code></td>
- <td><code>string</code></td>
- <td>Optional. Fallback locale when a key is missing in the current locale.</td>
- </tr>
- </tbody>
- </table>
- ## Composition
- Directives compose naturally. Each resolver calls `resolvePropValue` on its inputs, so you can nest directives:
- ```json
- {
- "$format": "currency",
- "value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
- "currency": "USD"
- }
- ```
- ```json
- {
- "$pluralize": { "$count": { "$state": "/items" } },
- "one": "item",
- "other": "items"
- }
- ```
|