关于 shadcn-components
面向使用 shadcn/ui 的团队,说明 Base UI、Radix 和 React Aria 的 API 与组合方式差异,并指导根据项目所用基础组件查阅对应注册表源。
主要功能
- 01Base UI、Radix 和 React Aria 指南
- 02按基础组件映射 API
- 03各基础组件的组件可用情况
- 04组合模式参考
- 05注册表查询流程
- 06表单与组件示例
适用场景
- 01识别项目使用的基础组件
- 02使用匹配的 API 构建组件
- 03检查某基础组件可用的组件
- 04添加组件前查找注册表源
MCP 相关
此 skill 要求通过 shadcn MCP 搜索和查看注册表组件,并获取添加命令。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fusengine/ agents --skill shadcn-components安装后在 Claude Code 中输入/shadcn-components确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/baseui-components.mdradix-components.mdreferences/templates/dialog-example.md详细介绍
需要先检测项目使用的原语(shadcn-detection),并查阅 shadcn MCP 获取注册表源代码,而不是手写组件内部实现。
shadcn 组件
Agent 工作流(必须遵循)
开始组件工作前,并行启动 Agent;每次调用一个 Agent,并指定 name:
- fuse-ai-pilot:explore-codebase - 查找现有组件
- fuse-ai-pilot:research-expert - 通过 Context7 验证组件 API
- mcp__shadcn__search_items_in_registries - 搜索可用组件
之后:运行 fuse-ai-pilot:sniper 进行验证。
概览
| 特性 | 描述 |
|---|---|
| Base UI 原语 | 自 2026-07-02 起为新项目的默认基础库(base-* 样式、@base-ui/react);init --defaults = Next.js 模板 + base 基础库上的 nova 预设 = base-nova |
| Radix 原语 | 最初的基础库(2023),仍受到全面支持(radix-* 样式、统一的 radix-ui 包);init -b radix |
| React Aria 原语 | 自 2026-07-17 起的第三种基础库(aria-* 样式、react-aria-components);init -b aria |
| 组件映射 | Base UI 和 Radix 使用相同的 shadcn 包装器名称;React Aria 包装器则不同(见下文) |
| API 差异 | render 与 asChild、触发器包装方式、部件命名、数据属性 |
cn 导入 | 组件从 cn 包导入 cn(2026 年 9 月);lib/utils.ts 为 export { cn } from "cn" |
通过 CLI 获取特定基础库的文档、示例和 API 链接:{runner} shadcn@latest docs dialog --base aria(--base base|radix|aria,默认使用项目的基础库)。组件页面:/docs/components/{base|radix|aria}/<name>,每个页面都包含一个组合树。
关键规则
- 组件工作前务必检测原语(
shadcn-detection) - 添加任何组件前务必查阅 MCP
- 绝不混用同一组件中的 Base UI、Radix 和 React Aria API
- 根据检测到的原语选择对应的组合模式
- 以注册表源代码为准,不要手动编写代码
架构
components/ui/
├── dialog.tsx # Adapted to detected primitive
├── select.tsx
├── accordion.tsx
└── ...
-> 完整组件请参阅 dialog-example.md
MCP 用法(必须遵循)
添加组件前务必查阅 shadcn MCP:
mcp__shadcn__search_items_in_registries -> find component
mcp__shadcn__view_items_in_registries -> view source
mcp__shadcn__get_add_command_for_items -> get install command
组件映射表
components/ui/*.tsx 中使用的原始组件(registry *-nova 源码,ui.shadcn.com/r/styles/<style>/<name>.json):
| 组件 | Radix 部件 | Base UI 部件 | React Aria 部件 |
|---|---|---|---|
| Dialog 内容 | Dialog.Content | Dialog.Popup | Modal > Dialog |
| Dialog 遮罩层 | Dialog.Overlay | Dialog.Backdrop | ModalOverlay |
| Select | Select.Content | Select.Positioner + Select.Popup (+ Select.List) | Select + Popover > ListBox |
| Tooltip | Tooltip.Content | Tooltip.Positioner + Tooltip.Popup | TooltipTrigger > Tooltip |
| Accordion | Accordion.Content | Accordion.Panel | DisclosureGroup > Disclosure > DisclosurePanel |
| Popover | Popover.Content | Popover.Positioner + Popover.Popup | DialogTrigger > Popover |
| Menu | DropdownMenu.Content | Menu.Positioner + Menu.Popup | MenuTrigger > Popover > Menu |
| Combobox | 无(使用 @base-ui/react Combobox) | Combobox.* | ComboBox + Popover > ListBox |
调用位置的封装组件 API(@/components/ui/*):
| 封装组件用法 | Base UI | Radix | React Aria |
|---|---|---|---|
| Dialog | Dialog > DialogTrigger + DialogContent | 与 Base UI 相同 | DialogTrigger > Button + Dialog(没有 DialogContent) |
| Popover / Tooltip / DropdownMenu | X > XTrigger + XContent | 相同 | XTrigger > Button + X(例如 DropdownMenuTrigger > Button + DropdownMenu) |
| Accordion | defaultValue={["a"]}、multiple | type="single" collapsible defaultValue="a"、type="multiple" | defaultExpandedKeys={["a"]}、allowsMultipleExpanded,项目使用 id |
| Select | Select 上的 items 属性,SelectItem value | SelectItem value | Select 上的 placeholder,SelectItem id |
| Combobox | items + ComboboxList 渲染函数 | 与 Base UI 相同 | ComboboxList 子项、renderEmptyState、ComboboxItem id |
| 事件 / 状态 | onClick、disabled、open/onOpenChange | 相同 | onPress、isDisabled、isOpen/onOpenChange |
| 原始数据属性 | data-open、data-starting-style、data-side | data-state="open"、data-side | data-entering/data-exiting、data-placement、data-focused、data-pressed |
共享的 data-open: / data-closed: / data-checked: Tailwind 变体(来自 shadcn/tailwind.css)同时匹配 [data-state=...] 和 [data-open]。
各基础库支持的组件
| 组件 | Base UI | Radix | React Aria |
|---|---|---|---|
Toast(@base-ui/react/toast、toast.add()) | 是(2026 年 7 月) | 否:使用 Sonner | 否:使用 Sonner |
| Sonner | registry 中存在该条目;文档指向 Toast | 是 | 是 |
| Menubar、Navigation Menu | 是 | 是 | 否(r/styles/aria-nova/{menubar,navigation-menu}.json → 404) |
Questionnaire(基于 @shadcn/react/questionnaire 设置样式) | 是 | 是 | 是 |
| MessageScroller、Message、Bubble、Attachment、Marker(聊天,2026 年 6 月) | 是 | 是 | 是(存在文档页面) |
Blocks(login-01、侧边栏、仪表板……) | 是 | 是 | 是(例如 r/styles/aria-nova/login-01.json);add 会选择项目的基础库 |
表单(/docs/forms):每个指南都基于 Field、FieldLabel、FieldDescription、FieldError、FieldGroup 构建,在 Field 上使用 data-invalid,并在控件上使用 aria-invalid — React Hook Form(Controller + Zod zodResolver)、TanStack Form(form.Field 渲染属性 + Zod)、Formisch(Form + Field、Valibot 架构)、Next.js(Server Action + useActionState、服务端 Zod)。
@shadcn/react = 无样式的无头原始组件(@shadcn/react/questionnaire、@shadcn/react/message-scroller);@shadcn/helpers(/ai-sdk、/tanstack-ai)= 用于演示/测试的脚本化 useChat 对话,而非 UI。渲染 Markdown 的排版:shadcn/typeset(一个 typeset.css,className="typeset")。
组合模式
Radix:asChild
<Dialog.Trigger asChild>
<Button variant="outline">Open</Button>
</Dialog.Trigger>
Base UI:render
<Dialog.Trigger render={<Button variant="outline" />}>
Open
</Dialog.Trigger>
React Aria:触发器包装器(无 asChild,无 render)
<DialogTrigger>
<Button variant="outline">Open</Button>
<Dialog>
<DialogHeader>
<DialogTitle>Title</DialogTitle>
</DialogHeader>
</Dialog>
</DialogTrigger>
参考指南
概念
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| Radix API | radix-components.md | 使用 Radix 基元进行构建 |
| Base UI API | baseui-components.md | 使用 Base UI 基元进行构建 |
| React Aria API | 上表 + dialog-example.md | 使用 React Aria 基元进行构建 |
模板
| 模板 | 适用场景 |
|---|---|
| dialog-example.md | 创建 Dialog 组件 |
最佳实践
应做事项
- 首先检测基元(使用 shadcn-detection)
- 编辑前,通过 MCP 查阅组件源代码
- 遵循项目中现有的命名约定
- 对检测到的基元使用正确的组合模式
不应做事项
- 不要在同一组件中混用 asChild、render 和 React Aria 触发器包装器
- 未经检测,不要假设使用的是 Radix(或新的默认选项 Base UI)
- 不要手动编写组件内部实现(使用 MCP)
- 添加新组件前,不要跳过 registry 检查