| name | shadcn |
| description | 管理 shadcn 组件和项目——添加、搜索、修复、调试、样式化和组合 UI。提供项目上下文、组件文档和使用示例。适用于使用 shadcn/ui、组件注册表 (registries)、预设 (presets)、--preset 代码或任何包含 components.json 文件的项目。也可由 "shadcn init"、"create an app with --preset" 或 "switch to --preset" 触发。 |
| user-invocable | false |
| allowed-tools | Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *) |
shadcn/ui
一个用于构建 UI、组件和设计系统的框架。组件通过 CLI 以源码形式添加到用户的项目中。
重要提示: 请使用项目的包运行器执行所有 CLI 命令:npx shadcn@latest、pnpm dlx shadcn@latest 或 bunx --bun shadcn@latest —— 取决于项目的 packageManager。以下示例使用 npx shadcn@latest,但在实际操作中请替换为项目正确的运行器。
当前项目上下文
!`npx shadcn@latest info --json`
上面的 JSON 包含了项目配置和已安装的组件。使用 npx shadcn@latest docs <component> 获取任何组件的文档和示例 URL。
原则
- 优先使用现有组件。 在编写自定义 UI 之前,先运行
npx shadcn@latest search 检查注册表。同时也检查社区注册表。
- 组合而非重造。 设置页面 = Tabs + Card + 表单控件。仪表板 = Sidebar + Card + Chart + Table。
- 优先使用内置变体而非自定义样式。 如
variant="outline", size="sm" 等。
- 使用语义化颜色。 如
bg-primary, text-muted-foreground —— 绝不使用原始值如 bg-blue-500。
关键规则
这些规则是 强制执行 的。每个链接都指向包含“错误/正确”代码示例的文件。
className 用于布局而非样式。 绝不覆盖组件的颜色或字体。
- 禁止使用
space-x-* 或 space-y-*。 使用 flex 搭配 gap-*。对于垂直堆叠,使用 flex flex-col gap-*。
- 当宽高相等时使用
size-*。 使用 size-10 而非 w-10 h-10。
- 使用
truncate 简写。 而非 overflow-hidden text-ellipsis whitespace-nowrap。
- 禁止手动使用
dark: 颜色覆盖。 使用语义化 Token(bg-background, text-muted-foreground)。
- 使用
cn() 处理条件类名。 不要手动编写模板字符串三元表达式。
- 禁止在覆盖层 (overlay) 组件上手动设置
z-index。 Dialog, Sheet, Popover 等组件会自行处理层级。
- 表单使用
FieldGroup + Field。 绝不使用原始 div 配合 space-y-* 或 grid gap-* 进行表单布局。
InputGroup 使用 InputGroupInput/InputGroupTextarea。 在 InputGroup 内部绝不使用原始 Input/Textarea。
- 输入框内的按钮使用
InputGroup + InputGroupAddon。
- 选项集(2–7 个选项)使用
ToggleGroup。 不要循环渲染带有手动激活状态的 Button。
- 使用
FieldSet + FieldLegend 对相关复选框/单选框进行分组。 不要使用带有标题的 div。
- 字段验证使用
data-invalid + aria-invalid。 在 Field 上使用 data-invalid,在控件上使用 aria-invalid。禁用状态同理:Field 使用 data-disabled,控件使用 disabled。
- 子项始终位于其分组 (Group) 内部。
SelectItem → SelectGroup。DropdownMenuItem → DropdownMenuGroup。CommandItem → CommandGroup。
- 自定义触发器使用
asChild (Radix) 或 render (Base)。 通过 npx shadcn@latest info 检查 base 字段。 → base-vs-radix.md
- Dialog, Sheet 和 Drawer 始终需要标题。 出于无障碍考虑,必须包含
DialogTitle, SheetTitle, DrawerTitle。如果视觉上需要隐藏,请使用 className="sr-only"。
- 使用完整的 Card 组合。
CardHeader/CardTitle/CardDescription/CardContent/CardFooter。不要将所有内容塞进 CardContent。
- Button 没有
isPending/isLoading。 使用 Spinner + data-icon + disabled 进行组合。
TabsTrigger 必须位于 TabsList 内部。 绝不直接在 Tabs 中渲染触发器。
Avatar 始终需要 AvatarFallback。 以防图片加载失败。
- 优先使用现有组件。 在编写带有样式的
div 之前,先检查组件是否存在。
- 提示框使用
Alert。 不要构建自定义样式的 div。
- 空状态使用
Empty。 不要构建自定义空状态标记。
- 通过
sonner 发送 Toast。 使用来自 sonner 的 toast()。
- 使用
Separator 而非 <hr> 或 <div className="border-t">。
- 使用
Skeleton 作为加载占位符。不要使用自定义的 animate-pulse div。
- 使用
Badge 而非自定义样式的 span。
Button 中的图标使用 data-icon。 在图标上使用 data-icon="inline-start" 或 data-icon="inline-end"。
- 禁止在组件内部的图标上使用尺寸类。 组件通过 CSS 处理图标尺寸。禁止使用
size-4 或 w-4 h-4。
- 以对象形式传递图标,而非字符串键。 使用
icon={CheckIcon},而非字符串查找。
CLI
- 禁止手动解码或获取预设代码。 对于现有项目直接传递给
npx shadcn@latest apply --preset <code>,或在初始化时使用 npx shadcn@latest init --preset <code>。
关键模式
这些是正确 shadcn/ui 代码中最常见的差异化模式。对于特殊情况,请参阅上面链接的规则文件。
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>无效的邮箱。</FieldDescription>
</Field>
<Button>
<SearchIcon data-icon="inline-start" />
搜索
</Button>
<div className="flex flex-col gap-4"> // 正确
<div className="space-y-4"> // 错误
// 相等维度:使用 size-*,而非 w-* h-*。
<Avatar className="size-10"> // 正确
<Avatar className="w-10 h-10"> // 错误
// 状态颜色:使用 Badge 变体或语义化 Token,而非原始颜色。
<Badge variant="secondary">+20.1%</Badge> // 正确
<span className="text-emerald-600">+20.1%</span> // 错误
组件选择
| 需求 | 使用 |
|---|
| 按钮/操作 | 带有适当变体的 Button |
| 表单输入 | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, InputOTP, Slider |
| 2–5 个选项切换 | ToggleGroup + ToggleGroupItem |
| 数据显示 | Table, Card, Badge, Avatar |
| 导航 | Sidebar, NavigationMenu, Breadcrumb, Tabs, Pagination |
| 覆盖层 | Dialog (模态), Sheet (侧边栏), Drawer (底部抽屉), AlertDialog (确认框) |
| 反馈 | sonner (toast), Alert, Progress, Skeleton, Spinner |
| 命令面板 | Dialog 内部的 Command |
| 图表 | Chart (包装 Recharts) |
| 布局 | Card, Separator, Resizable, ScrollArea, Accordion, Collapsible |
| 空状态 | Empty |
| 菜单 | DropdownMenu, ContextMenu, Menubar |
| 提示/信息 | Tooltip, HoverCard, Popover |
关键字段
注入的项目上下文包含以下关键字段:
aliases → 使用实际的导入别名前缀(如 @/, ~/),绝不硬编码。
isRSC → 当为 true 时,使用 useState, useEffect, 事件处理器或浏览器 API 的组件需要在文件顶部添加 "use client"。在建议指令时务必参考此字段。
tailwindVersion → "v4" 使用 @theme inline 块; "v3" 使用 tailwind.config.js。
tailwindCssFile → 定义自定义 CSS 变量的全局 CSS 文件。始终编辑此文件,绝不创建新文件。
style → 组件视觉处理(如 nova, vega)。
base → 基础库(radix 或 base)。影响组件 API 和可用 Props。
iconLibrary → 决定图标导入。lucide 使用 lucide-react,tabler 使用 @tabler/icons-react 等。绝不假设是 lucide-react。
resolvedPaths → 组件、工具类、Hooks 等的准确文件系统目标。
framework → 路由和文件约定(如 Next.js App Router vs Vite SPA)。
packageManager → 用于任何非 shadcn 的依赖安装(如 pnpm add date-fns vs npm install date-fns)。
完整字段参考见 cli.md — info 命令。
组件文档、示例与用法
运行 npx shadcn@latest docs <component> 获取组件的文档、示例和 API 参考 URL。获取这些 URL 以获取实际内容。
npx shadcn@latest docs button dialog select
在创建、修复、调试或使用组件时,务必先运行 npx shadcn@latest docs 并获取 URL。 这能确保你基于正确的 API 和用法模式工作,而非凭空猜测。
工作流
- 获取项目上下文 —— 已在上方注入。如需刷新,请再次运行
npx shadcn@latest info。
- 优先检查已安装组件 —— 在运行
add 之前,始终从项目上下文中检查 components 列表或列出 resolvedPaths.ui 目录。不要导入尚未添加的组件,也不要重复添加已安装的组件。
- 查找组件 ——
npx shadcn@latest search。
- 获取文档与示例 —— 运行
npx shadcn@latest docs <component> 获取 URL 并提取内容。使用 npx shadcn@latest view 浏览尚未安装的注册表项。要预览已安装组件的更改,使用 npx shadcn@latest add --diff。
- 安装或更新 ——
npx shadcn@latest add。更新现有组件时,使用 --dry-run 和 --diff 预检更改(见下文 更新组件)。
- 修复第三方组件的导入 —— 从社区注册表(如
@bundui, @magicui)添加组件后,检查新增的非 UI 文件中是否存在硬编码的导入路径(如 @/components/ui/...)。这些可能与项目实际别名不符。使用 npx shadcn@latest info 获取正确的 ui 别名(如 @workspace/ui/components)并重写导入。CLI 会重写其自身 UI 文件的导入,但第三方注册表组件可能使用不匹配的默认路径。
- 检查新增组件 —— 从任何注册表添加组件或区块后,务必阅读新增文件并验证其正确性。检查是否缺少子组件(如只有
SelectItem 缺少 SelectGroup)、缺少导入、组合错误或违反了 关键规则。同时根据项目上下文中的 iconLibrary 替换图标导入。在继续之前修复所有问题。
- 注册表必须明确 —— 当用户要求添加区块或组件时,不要猜测注册表。如果没有指定注册表(如用户说“添加登录区块”而未指明
@shadcn, @tailark 等),请询问使用哪个注册表。绝不代表用户默认选择注册表。
- 切换预设 —— 先询问用户:覆盖 (overwrite)、部分 (partial)、合并 (merge) 还是 跳过 (skip)?
- 覆盖:
npx shadcn@latest apply --preset <code>。覆盖检测到的组件、字体和 CSS 变量。
- 部分:
npx shadcn@latest apply --preset <code> --only theme,font。仅更新选定的预设部分,不重新安装 UI 组件。支持的值为 theme 和 font;允许逗号分隔的组合。icon 故意不予支持,因为图标更改可能需要全组件重新安装和转换。
- 合并:执行
npx shadcn@latest init --preset <code> --force --no-reinstall,然后运行 npx shadcn@latest info 列出已安装组件,接着对每个已安装组件使用 --dry-run 和 --diff 进行智能合并。
- 跳过:
npx shadcn@latest init --preset <code> --force --no-reinstall。仅更新配置和 CSS,保留组件不变。
- 重要提示:始终在用户项目目录内运行预设命令。
apply 仅适用于已有 components.json 文件的现有项目。CLI 会自动保留 components.json 中的当前基础(base vs radix)。如果必须使用临时目录(如进行 --dry-run 对比),请显式传递 --base <current-base> —— 预设代码不包含基础库信息。
更新组件
当用户要求从上游更新组件并保留本地修改时,使用 --dry-run 和 --diff 进行智能合并。绝不手动从 GitHub 获取原始文件 —— 始终使用 CLI。
- 运行
npx shadcn@latest add <component> --dry-run 查看受影响的文件。
- 对每个文件,运行
npx shadcn@latest add <component> --diff <file> 查看上游与本地的差异。
- 根据差异决定:
- 无本地修改 → 可安全覆盖。
- 有本地修改 → 阅读本地文件,分析差异,并在保留本地修改的同时应用上游更新。
- 用户说“全部更新” → 使用
--overwrite,但需先确认。
- 未经用户明确同意,绝不使用
--overwrite。
快速参考
npx shadcn@latest init --name my-app --preset base-nova
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
npx shadcn@latest init --name my-app --preset base-nova --monorepo
npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo
npx shadcn@latest init --preset base-nova
npx shadcn@latest init --defaults
npx shadcn@latest apply --preset a2r6bw
npx shadcn@latest apply a2r6bw
npx shadcn@latest apply --preset a2r6bw --only theme
npx shadcn@latest apply --preset a2r6bw --only font
npx shadcn@latest apply --preset a2r6bw --only theme,font
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button
npx shadcn@latest add --all
npx shadcn@latest add button --dry-run
npx shadcn@latest add button --diff button.tsx
npx shadcn@latest add @acme/form --view button.tsx
npx shadcn@latest search @shadcn -q "sidebar"
npx shadcn@latest search @tailark -q "stats"
npx shadcn@latest docs button dialog select
npx shadcn@latest view @shadcn/button
命名预设 (Named presets): nova, vega, maia, lyra, mira, luma
模板 (Templates): next, vite, start, react-router, astro (均支持 --monorepo) 以及 laravel (不支持 monorepo)
预设代码 (Preset codes): 版本前缀的 base62 字符串 (如 a2r6bw 或 b0),来自 ui.shadcn.com。
详细参考
- rules/forms.md — FieldGroup, Field, InputGroup, ToggleGroup, FieldSet, 验证状态
- rules/composition.md — 分组, 覆盖层, Card, Tabs, Avatar, Alert, Empty, Toast, Separator, Skeleton, Badge, Button 加载状态
- rules/icons.md — data-icon, 图标尺寸, 以对象形式传递图标
- rules/styling.md — 语义化颜色, 变体, className, 间距, 尺寸, truncate, 暗黑模式, cn(), z-index
- rules/base-vs-radix.md — asChild vs render, Select, ToggleGroup, Slider, Accordion
- cli.md — 命令, 标志, 预设, 模板
- customization.md — 主题化, CSS 变量, 扩展组件