关于 json-render-catalog
json-render Component Catalogs 是用于构建受约束组件目录的技能,面向使用 json-render 的开发者。重点包括从 Storybook 导入目录,以及安全使用指令扩展渲染能力。
主要功能
- 01从 Storybook 故事导入目录
- 02用 Zod 限定组件和属性
- 03使用内置及自定义指令
- 04支持嵌套内容插槽
- 05将规格渲染到多种界面
适用场景
- 01从现有 Storybook 配置生成目录
- 02将 AI 生成的界面限制为获准组件
- 03安全计算格式化或翻译后的值
MCP 相关
README 提到 @json-render/mcp 可将 MCP 工具 JSON 转为对话中的交互式 iframe,也提到同一规格可通过 MCP 集成渲染到多种界面。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill json-render-catalog安装后在 Claude Code 中输入/json-render-catalog确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
test-cases.jsonreferences/ork-delta.mdpackage-ecosystem.mdstorybook-fixture.jsonstorybook-import.mdrules/_sections.md_template.mdcatalog-definition.mdprop-constraints.mdtoken-optimization.mdscripts/storybook-to-catalog.mjs详细介绍
上游版本参考:@json-render/core 0.21.0(2026-09-30)。
json-render 组件目录
json-render(Vercel Labs,12.9K 星,Apache-2.0)是一个用于构建 AI 安全生成式 UI 的框架。AI 会生成受开发者定义的目录约束的扁平树 JSON(或 YAML)规范——目录是设计系统与 AI 输出之间的契约。如果某个组件或属性不在目录中,AI 就无法生成它。
Storybook → 目录导入(#1529,2026-04)
当项目配置了 Storybook 时,应从 Storybook 故事导入目录,而不是手动编写。内置导入器 scripts/storybook-to-catalog.mjs 会读取 @storybook/addon-mcp 的 list-all-documentation 清单,并生成由 Zod 类型化的 catalog.ts 和 components.tsx 注册表。
node "${CLAUDE_SKILL_DIR}/scripts/storybook-to-catalog.mjs" storybook-manifest.json \
--out src/genui/catalog.ts \
--components src/genui/components.tsx \
--project-root .
Storybook 成为唯一事实来源——添加一个故事,就会自动扩展 AI 获准使用的范围;移除一个故事,范围就会缩小。导入时会强制执行 AI 安全规则:回调、原始对象属性和 z.any() 都会被丢弃。完整映射见 references/storybook-import.md。用于测试的配套夹具:references/storybook-fixture.json。
2026-04 → 2026-08 新增内容(json-render 0.14 → 0.20)
- 命名插槽(0.20) —
UIElement新增slots?: Record<string, string[]>,目录通过slots: ["default", "header", "footer"]声明自己接受哪些插槽,而 React 注册表组件通过slots?.header接收命名内容,children仍对应默认插槽。建议使用此功能,而不是将布局区域编码为单独的同级元素。 - 嵌套重复与项级可见性(0.20) —
repeat.statePath接受项相对形式{"$item": "employees"}(新增RepeatStatePath类型以及resolveRepeatStatePath/resolveRepeatItemStatePath),并且现在同一元素上的repeat与visible: {"$item": "status", "eq": "todo"}组合会筛选项,而不再报错。validateSpec新增invalid_visible、repeat_without_children、repeat_item_outside_scope和repeat_state_mismatch问题代码。 - 自定义指令 API(0.19) —
@json-render/core现已提供defineDirective,让你可以声明新的 JSON 结构(例如$format、$math),在渲染时将其解析为计算值。指令可通过嵌套组合,并从内向外解析。四种渲染器(React、Vue、Svelte、Solid)均内置指令解析功能。这是无需将目录放宽为z.any(),即可实现计算值的安全扩展方式。 @json-render/directives包(0.19) — 提供七种现成指令:$format(通过Intl处理日期 / 货币 / 数字 / 百分比)、$math(加、减、乘、除、取模、最小值、最大值、四舍五入、向下取整、向上取整、绝对值)、$concat、$count、$truncate、$pluralize、$join。此外,还提供用于通过{{param}}插值处理$t翻译键的createI18nDirective,以及用于一行注册的standardDirectives。注册一次,即可在任意 spec 中使用——AI 不再需要拼接字符串或重复字面值。- 开发工具生态(0.18) — 新增五个包:
@json-render/devtools核心包,以及适用于 React、Vue、Svelte、Solid 的框架适配器。检查器面板有六个标签页(Spec、State、Actions、Stream、Catalog、Pick),包含可映射回 spec 键的 DOM 元素拾取功能。生产环境中会被摇树优化为null。同时发布了配套的 Next.js 演示应用,集成 AI 聊天与目录。还公开了操作观察器基础设施,供适配器将事件同步到面板。 - 修复 Zod 4 问题(0.18) —
formatZodType现在能正确处理z.record()、z.default()和z.literal()(此前会生成空白或错误的提示词输出)。 - 三种编辑模式(0.14) — 提供
patch(RFC 6902)、merge(RFC 7396)、diff(统一格式)三种模式,用于渐进式 AI 优化。@json-render/core中提供buildEditUserPrompt()+diffToPatches()+deepMergeSpec()。 @json-render/yaml(0.14) — 官方 YAML 传输格式和流式解析器;buildUserPrompt({ format: 'yaml' })。@json-render/ink(0.15) — 使用相同的 spec 将目录渲染为终端 UI(基于 Ink,包含 20 多个组件)。@json-render/next(0.16) — 根据单个 spec 生成完整的 Next.js 应用(路由、布局、SSR、元数据)。@json-render/shadcn-svelte(0.16) — 与 React shadcn 目录对应的 Svelte 5 + Tailwind 镜像,包含 36 个组件。- shadcn 目录现有 36 个组件(此前文档写为 29 个——即使在 0.13 版本时,这个数量也有误)。可直接使用
@json-render/shadcn,也可以将shadcnComponentDefinitions与你自己的定义展开合并使用。 @json-render/react-three-fiber提供 19 个组件(已于 2026-07-31 根据上游 skill 验证;此处不再重述组件列表,请参阅上游覆盖范围)。@json-render/mcp— 将普通的 MCP 工具 JSON 升级为交互式 iframe,嵌入 Claude/Cursor/ChatGPT 对话中。请参阅ork:mcp-visual-outputskill。- MCP 多端渲染:同一 spec 可渲染为 React、PDF(
@json-render/react-pdf)、电子邮件(@json-render/react-email)、终端(Ink)、Next.js 应用和 Remotion 视频。
Directives — @json-render/directives (0.19)
Directives 是处理计算值的安全逃生通道。AI 会输出带 $ 前缀的对象,渲染器会在组件接收 props 前从内向外解析它;catalog 保持严格(不通过 z.any() 放宽),规范也保持声明式。@json-render/directives 包提供七个预置 directive 和一个 i18n 工厂;standardDirectives 将它们导出为一个数组,可一行完成注册。Directives 可以自由嵌套(例如 $format 包裹 $math),并由全部四种渲染器集成(React、Vue、Svelte、Solid)解析。
注册
import { defineRegistry, JSONUIProvider, Renderer } from '@json-render/react'
import { standardDirectives, createI18nDirective } from '@json-render/directives'
const directives = [
...standardDirectives,
createI18nDirective({
locale: 'en',
fallbackLocale: 'en',
messages: { en: { greeting: 'Hello, {{name}}!' } },
}),
]
const { registry } = defineRegistry(catalog, { components })
// directives register on the provider (RendererProps has no directives prop)
<JSONUIProvider registry={registry} directives={directives}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>
七个预置 directive
| Directive | 用途 | 最简用法 |
|---|---|---|
$format | 基于 Intl 对 date、currency、number、percent 进行格式化。支持 locale、currency、notation,以及用于生成易读日期差值的 style: "relative"。 | { "$format": "currency", "value": 1299, "currency": "USD" } → $1,299.00 |
$math | 算术运算——add、subtract、multiply、divide、mod、min、max、round、floor、ceil、abs。除以零时返回 0;非数值输入会转换为 0。 | { "$math": "multiply", "a": { "$state": "/qty" }, "b": 9.99 } |
$concat | 将动态值数组拼接为字符串,并先通过 directive 管道解析每个元素。 | { "$concat": ["Hello, ", { "$state": "/user/name" }, "!"] } |
$count | 返回数组或字符串的长度;其他任何值都返回 0。 | { "$count": { "$state": "/items" } } |
$truncate | 截断至 length 指定的长度(默认为 100),并可选指定 suffix(默认为 ...)。如果内容已经足够短,则不做处理。 | { "$truncate": { "$state": "/bio" }, "length": 80 } |
$pluralize | 选择单数、复数或零值形式。自动在前面添加数量("3 items"、"1 item" 或字面量 zero 形式)。 | { "$pluralize": { "$state": "/cart/count" }, "zero": "no items", "one": "item", "other": "items" } |
$join | 使用 separator 拼接数组(默认为 ", ")。 | { "$join": { "$state": "/tags" }, "separator": " · " } |
createI18nDirective({ locale, messages, fallbackLocale? }) 会注册一个 $t directive,并支持 {{param}} 插值:{ "$t": "greeting", "params": { "name": "Ada" } }。
通过 defineDirective 创建自定义 directive
defineDirective 位于 @json-render/core(0.19+)中。Directive 声明用于描述其 JSON 结构的 Zod schema 和 resolve(raw, ctx) 函数——计算前可使用 resolvePropValue(raw.field, ctx) 递归解析任意嵌套的 directive 或状态引用。
import { defineDirective, resolvePropValue } from '@json-render/core'
import { z } from 'zod'
export const initialsDirective = defineDirective({
name: '$initials',
description: 'First letter of each word, uppercased.',
schema: z.object({ $initials: z.unknown() }),
resolve(raw, ctx) {
const text = String(resolvePropValue(raw.$initials, ctx) ?? '')
return text.split(/\s+/).map((w) => w[0]?.toUpperCase() ?? '').join('')
},
})
与 standardDirectives 一起展开并传入渲染器:directives={[...standardDirectives, initialsDirective]}。请保持 schema 严格——directive 是 AI 唯一可以输出非 catalog JSON 的地方,因此应像组件 prop 一样由 Zod 强制校验结构。
上游内容覆盖(无需重述)
json-render 为每个包提供专属技能。本技能对其进行封装,只保留差异内容:我们的 Storybook 导入路径、我们的目录约束,以及记录在 references/ork-delta.md 中的经验教训。请勿将供应商清单或 API 表格复制到此处。
| 主题 | 一手资料 |
|---|---|
核心 API(defineSchema、defineCatalog、提示词、规范流式传输、验证、StateStore) | https://github.com/vercel-labs/json-render skills/core/SKILL.md |
规范格式、动态属性表达式($state / $bindState / $cond / $template / $computed)、watch、可见性 | https://github.com/vercel-labs/json-render skills/core/SKILL.md 和 skills/react/SKILL.md |
内置操作(setState、pushState、removeState、validateForm)和事件系统 | https://github.com/vercel-labs/json-render skills/react/SKILL.md |
| shadcn 组件清单和属性架构(36 个组件,React 和 Svelte) | vercel:shadcn 技能,以及 https://github.com/vercel-labs/json-render skills/shadcn/SKILL.md 和 skills/shadcn-svelte/SKILL.md |
| 各渲染器的组件和 API(Vue、Svelte、Solid、React Native、Ink、Next.js、PDF、邮件、图像、Remotion、react-three-fiber) | https://github.com/vercel-labs/json-render skills/<package>/SKILL.md |
| YAML 线格式、代码围栏、流式编译器、编辑模式 | https://github.com/vercel-labs/json-render skills/yaml/SKILL.md |
状态适配器(zustandStateStore、reduxStateStore、jotaiStateStore、xstateStoreStateStore) | https://github.com/vercel-labs/json-render skills/zustand/SKILL.md、skills/redux/SKILL.md、skills/jotai/SKILL.md、skills/xstate/SKILL.md |
MCP Apps 集成(createMcpApp、iframe 客户端) | ork:mcp-visual-output,以及 https://github.com/vercel-labs/json-render skills/mcp/SKILL.md |
| 迁移手写的 JSON 到组件映射器 | https://github.com/vercel-labs/json-render skills/core/SKILL.md(目录 + 规范契约是目标形式) |
我们的差异内容,即上游文档未涵盖的部分:references/ork-delta.md。
快速参考
| 类别 | 规则 | 影响 | 使用场景 |
|---|---|---|---|
| 目录定义 | 1 | 高 | 使用 Zod 定义组件目录 |
| 属性约束 | 1 | 高 | 限制 AI 生成的属性以确保安全 |
| 令牌优化 | 1 | 中 | 使用 YAML 模式减少令牌用量 |
共计:3 个类别中的 3 条规则
json-render 的工作原理
- 开发者定义目录 — 使用 Zod 类型化的组件定义,并约束其属性
- AI 生成规范 — 扁平树 JSON/YAML,仅引用目录中的组件
- 运行时渲染规范 —
<Renderer>组件验证并渲染每个元素
目录是安全边界。AI 只能引用目录中存在的类型,属性会在运行时根据 Zod 架构进行验证。这可以防止虚构的组件和无效属性进入 UI。
快速入门 — 3 个步骤
步骤 1:定义目录
import { defineCatalog } from '@json-render/core'
import { schema } from '@json-render/react/schema'
import { z } from 'zod'
export const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({
title: z.string(),
description: z.string().optional(),
}),
children: true,
},
Button: {
props: z.object({
label: z.string(),
variant: z.enum(['default', 'destructive', 'outline', 'ghost']),
}),
children: false,
},
StatGrid: {
props: z.object({
items: z.array(z.object({
label: z.string(),
value: z.string(),
trend: z.enum(['up', 'down', 'flat']).optional(),
})).max(20),
}),
children: false,
},
},
})
LLM 结构化输出兼容性
使用 jsonSchema({ strict: true }) 导出与 LLM 结构化输出 API(OpenAI、Anthropic、Gemini)兼容的目录架构:
// jsonSchema is a METHOD on the Catalog instance, not a top-level export.
const schema = catalog.jsonSchema({ strict: true })
// Pass to OpenAI response_format, Anthropic tool_use, or Gemini structured output
步骤 2:实现组件
import type { InferCatalogComponents } from '@json-render/core'
import type { catalog } from './catalog'
export const components: InferCatalogComponents<typeof catalog> = {
Card: ({ title, description, children }) => (
<div className="rounded-lg border p-4">
<h3 className="font-semibold">{title}</h3>
{description && <p className="text-muted-foreground">{description}</p>}
{children}
</div>
),
Button: ({ label, variant }) => (
<button className={cn('btn', `btn-${variant}`)}>{label}</button>
),
StatGrid: ({ items }) => (
<div className="grid grid-cols-3 gap-4">
{items.map((item) => (
<div key={item.label}>
<span>{item.label}</span>
<strong>{item.value}</strong>
</div>
))}
</div>
),
}
步骤 3:渲染规范
import { defineRegistry, Renderer } from '@json-render/react'
import { catalog } from './catalog'
import { components } from './components'
// defineRegistry returns DefineRegistryResult — destructure `registry`
const { registry } = defineRegistry(catalog, { components })
function App({ spec }: { spec: JsonRenderSpec }) {
return <Renderer spec={spec} registry={registry} />
}
规范格式
JSON 规范是一棵扁平树——没有嵌套,只有 ID 和引用。字段级文档(root、elements、props、children、on、watch、state,以及 $state / $bindState / $cond / $template / $computed 表达式)请参阅上游文档:https://github.com/vercel-labs/json-render skills/core/SKILL.md。
{
"root": "card-1",
"elements": {
"card-1": {
"type": "Card",
"props": { "title": "Dashboard" },
"children": ["chart-1", "btn-1"]
},
"btn-1": {
"type": "Button",
"props": { "label": "View Details", "variant": "default" }
}
}
}
带交互功能(on / watch / state)
{
"root": "card-1",
"elements": {
"card-1": {
"type": "Card",
"props": { "title": "Dashboard" },
"children": ["chart-1", "btn-1"],
"on": { "press": { "action": "setState", "path": "/view", "value": "detail" } },
"watch": { "/data": { "action": "load_data", "url": "/api/stats" } }
}
},
"state": { "/activeTab": "overview" }
}
事件处理器、watch 绑定、内置操作(setState、pushState、
removeState、validateForm)和状态适配器均在上游
https://github.com/vercel-labs/json-render skills/react/SKILL.md 和各适配器
的技能中。此处不再重复列出;原因请参阅 references/ork-delta.md。
YAML 模式 — 减少 30% 的 Token
对于独立(非流式)生成,YAML 规范比 JSON 少用约 30% 的 Token:
root: card-1
elements:
card-1:
type: Card
props:
title: Dashboard
children: [chart-1, btn-1]
btn-1:
type: Button
props:
label: View Details
variant: default
内联模式/流式处理请使用 JSON(JSONL 上的 JSON Patch RFC 6902 要求使用 JSON)。在关注 Token 成本的独立模式下请使用 YAML。有关选择标准,请加载 rules/token-optimization.md。
渐进式流式渲染
json-render 支持在流式处理期间渐进式渲染。AI 生成规范元素时,这些元素会立即渲染,用户可以实时看到 UI 逐步构建。此功能通过在 JSONL 上流式传输 JSON Patch(RFC 6902)操作实现:
{"op":"add","path":"/elements/card-1","value":{"type":"Card","props":{"title":"Dashboard"},"children":[]}}
{"op":"add","path":"/elements/btn-1","value":{"type":"Button","props":{"label":"Save","variant":"default"}}}
{"op":"add","path":"/elements/card-1/children/-","value":"btn-1"}
属性一旦完整,元素就会立即渲染,无需等待完整规范生成完毕。
@json-render/shadcn — 36 个预构建组件
@json-render/shadcn 包提供包含 36 个组件的生产就绪目录,且已定义 Zod 架构。
组件列表和属性架构位于上游
https://github.com/vercel-labs/json-render skills/shadcn/SKILL.md;shadcn/ui
本身的组合方式则由 vercel:shadcn 技能提供。
Svelte:
@json-render/shadcn-svelte(在 0.16 中添加)为 Svelte 5 + Tailwind 项目提供相同的 36 个组件。
import { shadcnComponentDefinitions, shadcnComponents } from '@json-render/shadcn'
import { defineRegistry, Renderer } from '@json-render/react'
// Use as-is
const { registry } = defineRegistry(shadcnComponentDefinitions, { components: shadcnComponents })
<Renderer spec={spec} registry={registry} />
// Or merge with custom components
const catalog = { ...shadcnComponentDefinitions, ...customCatalog }
感知样式的目录
shadcn 目录中的组件使用默认 Tailwind 类。当项目使用特定的 shadcn v4 样式(Luma、Nova 等)时,请覆盖组件实现以匹配样式:
import { shadcnComponentDefinitions, shadcnComponents } from '@json-render/shadcn'
import type { InferCatalogComponents } from '@json-render/core'
// Override shadcn component implementations for Luma style
const lumaComponents: Partial<InferCatalogComponents<typeof shadcnComponentDefinitions>> = {
Card: ({ title, description, children }) => (
<div className="rounded-4xl border shadow-md ring-1 ring-foreground/5 p-6">
<h3 className="font-semibold">{title}</h3>
{description && <p className="text-muted-foreground">{description}</p>}
<div className="mt-6">{children}</div>
</div>
),
Button: ({ label, variant }) => (
<button className={cn('rounded-4xl', buttonVariants({ variant }))}>{label}</button>
),
}
// Merge: catalog schema unchanged, only rendering adapts to style
const components = { ...shadcnComponents, ...lumaComponents }
**检测方式:**读取 components.json 中的 "style" 字段,以确定要应用哪些覆盖。特定样式的类名:Luma(rounded-4xl、shadow-md、gap-6)、Nova(紧凑的 px-2 py-1)、Lyra(rounded-none)。
编辑模式 — patch / merge / diff(0.14+)
首次渲染后更新规范(AI 驱动的优化、用户编辑、部分重新生成)时,核心提供三种通用编辑模式:
| 模式 | 规范 | 适用场景 |
|---|---|---|
patch | RFC 6902 JSON Patch | 精确的流式差异(渐进式流式渲染已使用) |
merge | RFC 7396 JSON Merge Patch | 更简单的更新、整字段替换 |
diff | 序列化规范的统一差异 | 模型偏好纯文本差异时的 AI 原生输出 |
import { deepMergeSpec, diffToPatches, buildEditUserPrompt } from '@json-render/core'
// Ask the model for an edit in whichever format it finds easiest
const prompt = buildEditUserPrompt(currentSpec, instruction, { format: 'yaml', mode: 'merge' })
// Normalize any edit mode to RFC 6902 patches for application
const patches = diffToPatches(aiResponse)
const next = deepMergeSpec(currentSpec, patches)
buildUserPrompt() 在 0.14 中还新增了 format 和 serializer 选项——独立规范选择 YAML,流式处理选择 JSON。
软件包生态系统
核心包 + 23 个渲染器/集成包,涵盖 Web、移动端、终端、3D、代码生成和状态管理。按类别整理的完整列表请加载 references/package-ecosystem.md。
自 0.13 以来新增:
@json-render/yaml(0.14)— YAML 线格式 + 流式解析器@json-render/ink(0.15)— 终端 UI 渲染器(基于 Ink,包含 20 多个组件)@json-render/next(0.16)— 生成完整的 Next.js 应用(路由、布局、SSR、元数据)@json-render/shadcn-svelte(0.16)— 与 React shadcn 目录对应的 36 组件 Svelte 5 版本@json-render/react-three-fiber提供 19 个组件(已于 2026-07-31 验证;组件列表位于上游)@json-render/devtools+ 框架适配器(0.18)— 六标签页检查面板、DOM 选择器,在生产环境中会经 tree-shaking 移除为null@json-render/directives(0.19)— 七个 Intl/数学/字符串指令 +createI18nDirective+standardDirectives注册辅助函数
适用场景与不适用场景
适合使用 json-render 的场景:
- AI 生成 UI,且你需要限制它能生成的内容
- 你希望使用经过运行时验证的规范,防止生成幻觉组件
- 你需要跨平台渲染(React、Vue、Svelte、React Native、PDF、电子邮件)
- 你正在构建生成式 UI 功能(根据自然语言生成仪表板、报告和表单)
不适合使用 json-render 的场景:
- 构建由开发者编写的静态 UI——直接使用组件
- AI 生成代码(JSX/TSX)而非规范——使用标准代码生成
- 你需要不受目录约束的完全创作自由——json-render 有意采用严格限制
- 在包含数千个元素的场景中进行性能关键型渲染——扁平树抽象会增加开销
从自定义 GenUI 迁移
如果你已有自定义生成式 UI(手动编写的 JSON 到组件映射),目标结构是目录加扁平树规范契约,详见上游文档
https://github.com/vercel-labs/json-render skills/core/SKILL.md。建议按以下顺序迁移:
盘点现有类型,为每种类型在 defineCatalog 中提供 Zod 架构,将嵌套规范展平为 root 加 elements,将处理器属性移至
on 字段,然后将现有组件封装为目录实现。
规则详情
目录定义
如何使用 defineCatalog() 和 Zod 架构定义目录。
| 规则 | 文件 | 关键模式 |
|---|---|---|
| 目录定义 | rules/catalog-definition.md | 使用 Zod 架构和子元素类型的 defineCatalog |
属性约束
约束属性以防止 AI 生成幻觉内容。
| 规则 | 文件 | 关键模式 |
|---|---|---|
| 属性约束 | rules/prop-constraints.md | z.enum、z.string().max()、z.array().max() |
令牌优化
选择 JSON 或 YAML,以提高令牌效率。
| 规则 | 文件 | 关键模式 |
|---|---|---|
| 令牌优化 | rules/token-optimization.md | 独立模式使用 YAML,内联/流式处理使用 JSON |
关键决策
| 决策 | 建议 |
|---|---|
| 自定义目录与 shadcn 目录 | 从 shadcn 开始,再通过自定义类型扩展领域专用组件 |
| JSON 与 YAML 规范格式 | 独立模式使用 YAML(令牌减少 30%),内联/流式处理使用 JSON |
| Zod 约束严格程度 | 越严格越好——使用 z.enum 而非 z.string,使用 z.array().max() 而非无界数组 |
| 状态管理适配器 | 与应用现有的状态库保持一致(Zustand、Redux、Jotai、XState) |
常见错误
- 在目录属性中使用
z.any()或z.unknown()——这会违背目录约束的目的,AI 可以生成任何内容 - 始终使用 JSON 规范——不需要内联/流式处理时会浪费 30% 的令牌(独立模式请使用 YAML)
- 嵌套组件定义——json-render 使用扁平树;所有元素都是通过 ID 引用的同级元素
- 不扩展
shadcnComponentDefinitions,而是重新声明 shadcn 组件——这样会丢失上游的 Zod 边界约束 - 不为数组设置
.max()——AI 可能生成无界列表,导致布局错乱
相关技能
ork:ai-ui-generation— v0、Bolt、Cursor 的 AI 辅助 UI 生成模式ork:ui-components— shadcn/ui 组件模式和 CVA 变体ork:component-search— 查找和评估 React/Vue 组件ork:design-to-code— 将设计转换为生产代码