关于 shadcn
shadcn 是用于使用 shadcn/ui 组件构建界面的 Agent 技能。它指导开发者依据项目配置选择组件、使用 CLI,并遵循样式、表单、组合、图标和聊天界面的实现规则。
主要功能
- 01检查项目配置与已安装组件
- 02查找组件文档和示例
- 03指导 CLI 组件及预设操作
- 04提供样式与表单实现规则
- 05涵盖组合、图标和聊天界面
适用场景
- 01为新界面选择组件
- 02在现有项目中应用 shadcn/ui 组件
- 03按项目规范实现表单和聊天界面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill shadcn安装后在 Claude Code 中输入/shadcn确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
cli.mdcustomization.mddesign-system-page.mddesign-system.mdmcp.mdregistry.mdagents/openai.ymlassets/showcase/color-pair.tsxpreview-states.cssstate-matrix.tsxevals/evals.jsonrules/base-vs-radix.mdchat.mdcomposition.mdforms.mdicons.mdstyling.mdscripts/showcase-coverage.mjs详细介绍
shadcn/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之类的原始值。
关键规则
这些规则始终强制执行。每条规则都链接到一个包含错误/正确代码对比的文件。
样式与 Tailwind → styling.md
className用于布局,而非样式。 切勿覆盖组件的颜色或排版。- 不要使用
space-x-*或space-y-*。 请使用带gap-*的flex。垂直堆叠则用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()。 不要手写模板字符串三元表达式。 - 不要在浮层组件上手动设置
z-index。 Dialog、Sheet、Popover 等会自行处理层叠关系。
表单与输入 → forms.md
- 表单使用
FieldGroup+Field。 表单布局不要直接使用带space-y-*或grid gap-*的原始div。 InputGroup使用InputGroupInput/InputGroupTextarea。 不要在InputGroup中直接使用原始的Input/Textarea。- 输入框内的按钮使用
InputGroup+InputGroupAddon。 - 选项集(2–7 个选项)使用
ToggleGroup。 不要通过循环Button并手动管理激活状态。 - 对相关的复选框/单选框分组时使用
FieldSet+FieldLegend。 不要用带标题的div。 - 字段校验使用
data-invalid+aria-invalid。data-invalid设在Field上,aria-invalid设在控件上。禁用时:data-disabled设在Field上,disabled设在控件上。
组件结构 → composition.md
- 条目必须位于其分组内。
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。 用于图片加载失败时的回退显示。
使用组件,而非自定义标记 → composition.md
- 优先使用现有组件,再考虑自定义标记。 编写带样式的
div前,先检查是否已有对应组件。 - 提示框使用
Alert。 不要构建带自定义样式的 div。 - 空状态使用
Empty。 不要构建自定义空状态标记。 - Toast 遵循项目基础规范。 对于 Base UI 项目,使用
toast组件中的toast。对于 Radix 和 React Aria 项目,使用sonner中的toast()。 - 使用
Separator,而不是<hr>或<div className="border-t">。 - 使用
Skeleton作为加载占位符。不要使用自定义的animate-pulsediv。 - 使用
Badge,而不是带自定义样式的 span。
图标 → icons.md
Button中的图标使用data-icon。 在图标上设置data-icon="inline-start"或data-icon="inline-end"。- 组件内的图标不要设置尺寸类。 组件会通过 CSS 处理图标尺寸。不要使用
size-4或w-4 h-4。 - 将图标作为对象传入,而不是字符串键。 使用
icon={CheckIcon},而不是字符串查找。
聊天与消息 → chat.md
- 聊天 UI 由聊天原语组件组合而成。 对话使用
MessageScroller,消息行使用Message,消息表面使用Bubble。不要手动编写气泡div,也不要使用原始滚动容器。 MessageScroller负责滚动行为。 流式内容跟随、锚定和跳转到最新消息(MessageScrollerButton)均为内置功能。不要编写useStickToBottom/ResizeObserver钩子。- 附件使用
Attachment;系统备注和分隔符使用Marker。 不要使用Item卡片,或使用Separator加标签。 - 助手活动使用
Trace。 推理、工具调用、来源和步骤都应作为Trace中的TraceLine,每组消息部分对应一个Trace。行为包装在该行外部:使用TraceCollapsible、弹出层触发器或链接。不要手动编写Collapsible或使用Marker。
CLI
- 绝不要手动解码预设代码或构建预设 URL。 使用
npx shadcn@latest preset decode <code>、preset url <code>或preset open <code>。如需根据项目检测预设,请使用npx shadcn@latest preset resolve。 - 使用 CLI 直接应用预设代码。 对于现有项目,使用
npx shadcn@latest apply <code>;初始化项目时,使用npx shadcn@latest init --preset <code>。
关键模式
以下是最常见、能区分正确 shadcn/ui 代码的模式。边缘情况请参阅上方链接的规则文件。
// Form layout: FieldGroup + Field, not div + Label.
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
// Validation: data-invalid on Field, aria-invalid on the control.
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Invalid email.</FieldDescription>
</Field>
// Icons in buttons: data-icon, no sizing classes.
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
// Spacing: gap-*, not space-y-*.
<div className="flex flex-col gap-4"> // correct
<div className="space-y-4"> // wrong
// Equal dimensions: size-*, not w-* h-*.
<Avatar className="size-10"> // correct
<Avatar className="w-10 h-10"> // wrong
// Status colors: Badge variants or semantic tokens, not raw colors.
<Badge variant="secondary">+20.1%</Badge> // correct
<span className="text-emerald-600">+20.1%</span> // wrong
组件选择
| 需求 | 使用 |
|---|---|
| 按钮/操作 | 采用合适变体的 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(确认) |
| 反馈 | toast(Base UI)、sonner(Radix/Aria)、Alert、Progress、Skeleton、Spinner |
| 命令面板 | 在 Dialog 中使用 Command |
| 图表 | Chart(封装 Recharts) |
| 布局 | Card、Separator、Resizable、ScrollArea、Accordion、Collapsible |
| 空状态 | Empty |
| 菜单 | DropdownMenu、ContextMenu、Menubar |
| 工具提示/信息 | Tooltip、HoverCard、Popover |
| 聊天/对话界面 | MessageScroller、Message、Bubble、Attachment、Marker、Trace |
关键字段
注入的项目上下文包含以下关键字段:
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 和可用属性。iconLibrary→ 决定图标导入方式。使用lucide时采用lucide-react,使用tabler时采用@tabler/icons-react,以此类推。切勿默认使用lucide-react。resolvedPaths→ 组件、工具函数、钩子等的确切文件系统路径。framework→ 路由和文件约定(例如 Next.js App Router 与 Vite SPA)。packageManager→ 安装任何非 shadcn 依赖时使用此字段(例如使用pnpm add date-fns,而非npm install date-fns)。preset→ 当前项目已解析的 preset 代码和取值。仅需 preset 信息时,使用npx shadcn@latest preset resolve --json。
完整字段说明请参阅 cli.md — info command。
组件文档、示例与用法
运行 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,然后抓取这些 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不一致(例如注册表项使用lucide-react,而项目使用hugeicons),请根据项目上下文将图标导入和图标名称替换为项目所用的图标库。在继续之前修复所有问题。 - 注册表必须明确:用户要求添加区块或组件时,不要猜测注册表。如果用户未指定注册表(例如用户只说“添加一个登录区块”,而未指定
@shadcn、@tailark、owner/repo等),请询问使用哪个注册表。切勿代替用户默认选择注册表。 - 切换预设:先询问用户:覆盖、部分、合并还是跳过?
- 检查当前预设:
npx shadcn@latest preset resolve。需要结构化值时使用--json。 - 检查待应用的预设:
npx shadcn@latest preset decode <code>。使用preset url <code>或preset open <code>分享或打开预设构建器。 - 覆盖:
npx shadcn@latest apply <code>。覆盖已检测到的组件、字体和 CSS 变量。 - 部分:
npx shadcn@latest apply <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(base或radix)。如果必须使用临时目录(例如进行--dry-run对比),请显式传入--base <current-base>,因为预设代码不编码 base 信息。
- 检查当前预设:
基于 DESIGN.md 构建设计系统
当用户要求基于 DESIGN.md(或品牌规范)构建设计系统时,无论是否指定预设,都应从头到尾遵循 design-system.md:
init --preset <code> --template <vite|next> --name <app> --no-monorepo -y。如果没有预设代码,选择最接近的风格,并传入--base base --preset <style>。然后执行add --all -y。- 编辑前,先阅读 DESIGN.md 的 frontmatter、“Do's and Don'ts”以及“Known Gaps”。
- 将其中的设计令牌映射到
tailwindCssFile中的 shadcn 变量。固定圆角比例、阴影、字体和type-*工具类。 - 通过编辑组件的
cva变体来重新设置样式。同步调整控件高度。 - 按照 design-system-page.md 构建设计系统页面:经过对比度检查的颜色角色、字体样例、固定状态矩阵、边缘情况、正反示例和配方。使用
scripts/showcase-coverage.mjs检查覆盖范围。 - 在浏览器中验证:类型检查通过、无控制台错误、页面从顶部开始加载、无水平溢出、支持深色模式。
更新组件
当用户要求在保留本地修改的同时,将组件更新到上游版本时,使用 --dry-run 和 --diff 进行智能合并。切勿手动从 GitHub 获取原始文件——始终使用 CLI。
- 运行
npx shadcn@latest add <component> --dry-run,查看所有将受影响的文件。 - 对每个文件运行
npx shadcn@latest add <component> --diff <file>,查看上游与本地的差异。 - 根据差异逐个文件决定:
- 没有本地修改 → 可以安全覆盖。
- 存在本地修改 → 读取本地文件、分析差异,并在保留本地修改的同时应用上游更新。
- 用户说“全部直接更新” → 使用
--overwrite,但要先确认。
- 未经用户明确批准,绝不要使用
--overwrite。
快速参考
# Create a new project.
npx shadcn@latest init --name my-app --preset base-nova
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
# Create a design system app (then follow design-system.md).
npx shadcn@latest init --name my-ds --preset b0 --template vite --no-monorepo -y
npx shadcn@latest init --name my-ds --base base --preset maia --template vite --no-monorepo -y
npx shadcn@latest add --all -y
# Create a monorepo project.
npx shadcn@latest init --name my-app --preset base-nova --monorepo
npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo
# Initialize existing project.
npx shadcn@latest init --preset base-nova
npx shadcn@latest init --defaults # shortcut: --template=next --preset=nova (base style implied)
# Apply a preset to an existing project.
npx shadcn@latest apply a2r6bw
npx shadcn@latest apply a2r6bw --only theme
npx shadcn@latest apply a2r6bw --only font
npx shadcn@latest apply a2r6bw --only theme,font
# Inspect preset codes and project preset state.
npx shadcn@latest preset decode a2r6bw
npx shadcn@latest preset url a2r6bw
npx shadcn@latest preset open a2r6bw
npx shadcn@latest preset resolve
npx shadcn@latest preset resolve --json
# Add components.
npx shadcn@latest add button card dialog
npx shadcn@latest add @magicui/shimmer-button
npx shadcn@latest add owner/repo/item
npx shadcn@latest add --all
# Preview changes before adding/updating.
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 add owner/repo/item --dry-run
# Search registries.
npx shadcn@latest search @shadcn -q "sidebar"
npx shadcn@latest search @tailark -q "stats"
npx shadcn@latest search owner/repo -q "login"
npx shadcn@latest search # all configured registries
npx shadcn@latest search @shadcn -q "menu" -t ui # filter by item type
# Get component docs and example URLs.
npx shadcn@latest docs button dialog select
# View registry item details (for items not yet installed).
npx shadcn@latest view @shadcn/button
npx shadcn@latest view owner/repo/item
命名预设: nova、vega、maia、lyra、mira、luma
模板: next、vite、start、react-router、astro(均支持 --monorepo)以及 laravel(不支持 monorepo)
预设代码: 带版本前缀的 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、按钮加载状态
- rules/chat.md — MessageScroller、Message、Bubble、Attachment、Marker、Trace;流式传输、锚定、跳转到最新消息、助手活动行
- rules/icons.md — data-icon、图标尺寸、将图标作为对象传递
- rules/styling.md — 语义颜色、变体、className、间距、尺寸、截断、深色模式、cn()、z-index
- rules/base-vs-radix.md — asChild 与 render、Select、ToggleGroup、Slider、Accordion
- cli.md — 命令、标志、预设、模板
- registry.md — 编写源注册表、
include、条目定义、依赖项、GitHub 注册表规则 - customization.md — 主题、CSS 变量、扩展组件
- design-system.md:将 DESIGN.md(无论是否指定预设)转化为带主题的应用:风格选择、令牌映射、圆角、字体、字体比例、控件高度、展示陷阱、验证
- design-system-page.md:设计系统页面应包含的内容及实现方式:基础样式、组件层级、固定状态矩阵、对比度组合、边缘情况、正反示例、配方