directives

directives

熱門

適用於 json-render 的預建自訂指令,涵蓋格式化、數學運算、字串操作與多國語言(i18n)。使用時機:使用 @json-render/directives、透過 defineDirective 定義自訂指令,或是需要在 spec 中加入 $format、$math、$concat、$count、$truncate、$pluralize、$join 或 $t 時。

1.6萬星標
853分支
更新於 2026/7/8
SKILL.md
唯讀
名稱
directives
描述

適用於 json-render 的預建自訂指令,涵蓋格式化、數學運算、字串操作與多國語言(i18n)。使用時機:使用 @json-render/directives、透過 defineDirective 定義自訂指令,或是需要在 spec 中加入 $format、$math、$concat、$count、$truncate、$pluralize、$join 或 $t 時。

@json-render/directives

專為 @json-render/core 打造的預建自訂指令。可以直接加入 catalog 與 renderer 中,輕鬆擴充格式化、數學運算、字串處理以及多國語言(i18n)功能。

快速開始

import { standardDirectives } from '@json-render/directives';

// 整合至 Prompt 生成流程
const prompt = catalog.prompt({ directives: standardDirectives });

// 整合至 Renderer(以 React 為例)
import { JSONUIProvider, Renderer } from '@json-render/react';

<JSONUIProvider registry={registry} directives={standardDirectives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>

若要加入像 createI18nDirective 這類工廠函式生成的指令,使用展開運算子即可:

import { standardDirectives, createI18nDirective } from '@json-render/directives';

const directives = [...standardDirectives, createI18nDirective(config)];

定義自訂指令

使用來自 @json-render/coredefineDirective

import { defineDirective, resolvePropValue } from '@json-render/core';
import { z } from 'zod';

const doubleDirective = defineDirective({
  name: '$double',
  description: 'Double a numeric value.',
  schema: z.object({
    $double: z.unknown(),
  }),
  resolve(value, ctx) {
    const resolved = resolvePropValue(value.$double, ctx);
    return (resolved as number) * 2;
  },
});

規則:

  • 名稱必須以 $ 開頭
  • 名稱不得與內建 Key 衝突(如 $state$cond$computed$template$item$index$bindState$bindItem
  • Resolver 應對子值呼叫 resolvePropValue 以支援指令組合

內建指令

$format — 依語系區域格式化數值

使用 Intl 格式化工具處理數值。支援 date(日期)、currency(貨幣)、number(數字)與 percent(百分比)。

{ "$format": "currency", "value": { "$state": "/cart/total" }, "currency": "USD" }
{ "$format": "date", "value": { "$state": "/user/createdAt" } }
{ "$format": "number", "value": 1234567, "notation": "compact" }
{ "$format": "percent", "value": 0.75 }
{ "$format": "date", "value": { "$state": "/post/createdAt" }, "style": "relative" }

欄位:$format (date | currency | number | percent)、value (任意運算式)、locale? (字串)、currency? (字串,預設 "USD")、notation? (字串)、style? (相對日期請設為 "relative")、options? (額外的 Intl 選項)。

$math — 算術運算

{ "$math": "add", "a": { "$state": "/subtotal" }, "b": { "$state": "/tax" } }
{ "$math": "round", "a": 3.7 }

支援運算:add(加)、subtract(減)、multiply(乘)、divide(除)、mod(取餘數)、min(最小值)、max(最大值)、round(四捨五入)、floor(無條件捨去)、ceil(無條件進位)、abs(絕對值)。單元運算(roundfloorceilabs)僅使用 a。除以零時回傳 0

欄位:$math (運算列舉)、a? (第一個運算元,預設 0)、b? (第二個運算元,預設 0)。

$concat — 字串串接

{ "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] }

欄位:$concat (包含要解析並串接成字串的數值陣列)。

$count — 陣列/字串長度

{ "$count": { "$state": "/cart/items" } }

回傳陣列或字串的 .length,若為其他型別則回傳 0

欄位:$count (要計算長度的值)。

$truncate — 文字截斷

{ "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." }

欄位:$truncate (要截斷的值)、length? (最大字數,預設 100)、suffix? (後綴字串,預設 "...")。

$pluralize — 單複數形式

{ "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" }

輸出範例:"3 items""1 item""no items"

欄位:$pluralize (數量值)、one (單數標籤)、other (複數標籤)、zero? (零數量標籤)。

$join — 陣列元素連接

{ "$join": { "$state": "/tags" }, "separator": ", " }

欄位:$join (要連接的陣列)、separator? (分隔字串,預設 ", ")。

createI18nDirective — 多國語言(i18n)工廠指令

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',
});

在 spec 中的用法:

{ "$t": "checkout.submit" }
{ "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }

欄位:$t (翻譯 Key)、params? (插值參數,其值接受運算式)。

設定項:locale (當前語系)、messages (Record<locale, Record<key, string>>)、fallbackLocale? (缺少 Key 時的備用語系)。

指令組合

指令之間可以自然地組合使用 — 每個 Resolver 都會對輸入呼叫 resolvePropValue,因此指令可以包裹其他指令或內建運算式:

{
  "$format": "currency",
  "value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
  "currency": "USD"
}

解析順序為由內而外:$state 從 state 讀取資料,$math 進行乘法計算,$format 將結果格式化為貨幣。

整合至 Renderer

所有四種 Renderer(React、Vue、Svelte、Solid)的 Provider 與 createRenderer 輸出皆接受 directives 參數:

// Provider 模式
<JSONUIProvider registry={registry} directives={directives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>

// createRenderer 模式
const MyRenderer = createRenderer(catalog, components);
<MyRenderer spec={spec} directives={directives} />

生成 Prompt 時,傳入相同的陣列即可:

const prompt = catalog.prompt({ directives });

核心匯出

匯出項目 用途
formatDirective $format 指令定義
mathDirective $math 指令定義
concatDirective $concat 指令定義
countDirective $count 指令定義
truncateDirective $truncate 指令定義
pluralizeDirective $pluralize 指令定義
joinDirective $join 指令定義
createI18nDirective $t i18n 指令的工廠函式
standardDirectives 包含所有 7 個非工廠指令的陣列
I18nConfig i18n 設定項的型別定義