directives について
@json-render/directives は、JSON UIを構築する開発者向けに、@json-render/core のカタログやレンダラーで使える既成ディレクティブを提供します。書式設定、算術、文字列操作、国際化に対応し、組み合わせて解決できるほか、カスタムディレクティブも定義できます。
主な機能
- 01ロケールに応じた日付や数値の書式設定
- 02算術演算の実行
- 03テキストの連結と切り詰め
- 04配列や文字列の件数取得と連結
- 05単数形と複数形の処理
- 06ファクトリーによる i18n ディレクティブ設定
活用シーン
- 01ローカライズされた日付や通貨の表示
- 02レンダリングデータ内での価格や税額の計算
- 03記事テキストの短縮と項目数の表示
- 04画面文言の翻訳設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vercel-labs/ json-render --skill directivesインストール後、Claude Code で/directivesを入力して読み込まれたか確認します。
詳細
@json-render/directives
@json-render/core 用の、あらかじめ用意されたカスタムディレクティブです。カタログとレンダラーに追加して、書式設定、数学演算、文字列操作、i18n を利用できます。
クイックスタート
import { standardDirectives } from '@json-render/directives';
// Wire into prompt generation
const prompt = catalog.prompt({ directives: standardDirectives });
// Wire into the renderer (React example)
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/core の defineDirective を使用します。
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;
},
});
ルール:
- 名前は
$で始める必要があります - 組み込みキー(
$state、$cond、$computed、$template、$item、$index、$bindState、$bindItem)と競合してはいけません - 合成に対応するには、リゾルバーでサブ値に対して
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。単項演算(round、floor、ceil、abs)では a のみを使用します。ゼロ除算の場合は 0 を返します。
フィールド:$math(演算の列挙型)、a?(第 1 オペランド、デフォルトは 0)、b?(第 2 オペランド、デフォルトは 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 — 国際化ファクトリ
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',
});
仕様での使用方法:
{ "$t": "checkout.submit" }
{ "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }
フィールド:$t(翻訳キー)、params?(補間パラメーター。値には式を使用できます)。
設定:locale(現在のロケール)、messages(Record<locale, Record<key, string>>)、fallbackLocale?(キーが見つからない場合のフォールバック)。
合成
各リゾルバーは入力に対して resolvePropValue を呼び出すため、ディレクティブは自然に合成されます。これにより、ディレクティブを別のディレクティブや組み込み式でラップできます。
{
"$format": "currency",
"value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
"currency": "USD"
}
内側から順に解決されます。$state が state から値を読み取り、$math が乗算し、$format が通貨として書式設定します。
レンダラーへの組み込み
4 つのレンダラー(React、Vue、Svelte、Solid)はすべて、プロバイダーと createRenderer の出力で directives を受け取ります。
// Provider pattern
<JSONUIProvider registry={registry} directives={directives}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>
// createRenderer pattern
const MyRenderer = createRenderer(catalog, components);
<MyRenderer spec={spec} directives={directives} />
プロンプト生成では、同じ配列を渡します。
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 設定の型 |