🚀 快速安装

复制以下命令并运行,立即安装此 Skill:

npx @anthropic-ai/skills install shadcn/ui/shadcn

💡 提示:需要 Node.js 和 NPM

shadcn/ui

一个用于构建用户界面、组件和设计系统的框架。组件通过 CLI 以源代码形式添加到用户项目中。

重要提示: 所有 CLI 命令都应使用项目的包管理器运行:npx shadcn@latestpnpm dlx shadcn@latestbunx --bun shadcn@latest — 具体取决于项目的 packageManager 字段。以下示例使用 npx shadcn@latest,但请根据项目替换为正确的运行器。

当前项目上下文

!`npx shadcn@latest info --json 2>/dev/null || echo '{"error": "未找到 shadcn 项目。请先运行 shadcn init。"}'`

上述 JSON 包含了项目配置和已安装的组件。可以使用 npx shadcn@latest docs <组件名> 获取任何组件的文档和示例 URL。

设计原则

  1. 优先使用现有组件。 在编写自定义 UI 前,使用 npx shadcn@latest search 检查注册表。也要检查社区注册表。
  2. 组合,而非重新发明。 设置页面 = Tabs + Card + 表单控件。仪表盘 = Sidebar + Card + Chart + Table。
  3. 优先使用内置变体,再考虑自定义样式。variant="outline"size="sm" 等。
  4. 使用语义化颜色。 bg-primarytext-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: 颜色覆盖。 使用语义化令牌(bg-backgroundtext-muted-foreground)。
  • 使用 cn() 处理条件类名。 不要手动编写模板字符串三元表达式。
  • 不在覆盖层组件上手动设置 z-index Dialog、Sheet、Popover 等组件自己处理层级。

表单与输入 → forms.md

  • 表单使用 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-invalidField 上使用 data-invalid,在控件上使用 aria-invalid。对于禁用状态:在 Field 上使用 data-disabled,在控件上使用 disabled

组件结构 → composition.md

  • 项目始终放在其 Group 内部。 SelectItemSelectGroupDropdownMenuItemDropdownMenuGroupCommandItemCommandGroup
  • 自定义触发器使用 asChild (radix) 或 render (base)。npx shadcn@latest info 检查 base 字段。 → base-vs-radix.md
  • Dialog、Sheet 和 Drawer 必须包含 Title。 出于可访问性考虑,DialogTitleSheetTitleDrawerTitle 是必需的。如果视觉上需要隐藏,可使用 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 使用 sonnersonner 导入并使用 toast() 函数。
  • 使用 Separator 代替 <hr><div className="border-t">
  • 使用 Skeleton 作为加载占位符。不要自定义 animate-pulse div。
  • 使用 Badge 代替自定义样式的 span。

图标 → icons.md

  • Button 中的图标使用 data-icon 属性。 在图标元素上设置 data-icon="inline-start"data-icon="inline-end"
  • 组件内部的图标不应用尺寸类。 组件通过 CSS 处理图标大小。不要添加 size-4w-4 h-4
  • 以对象形式传递图标,而非字符串键。 使用 icon={CheckIcon},而不是字符串查找。

CLI

  • 绝不手动解码或获取预设代码。 直接将它们传给 npx shadcn@latest init --preset <代码>

关键模式

以下是区分正确 shadcn/ui 代码的最常见模式。对于边缘情况,请参阅上面链接的规则文件。

// 表单布局:使用 FieldGroup + Field,而不是 div + Label。
<FieldGroup>
  <Field>
    <FieldLabel htmlFor="email">邮箱</FieldLabel>
    <Input id="email" />
  </Field>
</FieldGroup>

// 验证:在 Field 上使用 data-invalid,在控件上使用 aria-invalid。
<Field data-invalid>
  <FieldLabel>邮箱</FieldLabel>
  <Input aria-invalid />
  <FieldDescription>邮箱无效。</FieldDescription>
</Field>

// 按钮中的图标:使用 data-icon,不加尺寸类。
<Button>
  <SearchIcon data-icon="inline-start" />
  搜索
</Button>

// 间距:使用 gap-*,不使用 space-y-*。
<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 变体或语义化令牌,而非原始颜色。
<Badge variant="secondary">+20.1%</Badge>    // 正确
<span className="text-emerald-600">+20.1%</span> // 错误

组件选择指南

需求 使用
按钮/操作 Button,并使用适当的变体
表单输入 InputSelectComboboxSwitchCheckboxRadioGroupTextareaInputOTPSlider
在 2–5 个选项间切换 ToggleGroup + ToggleGroupItem
数据展示 TableCardBadgeAvatar
导航 SidebarNavigationMenuBreadcrumbTabsPagination
覆盖层 Dialog(模态框),Sheet(侧面板),Drawer(底部弹窗),AlertDialog(确认对话框)
反馈 sonner(Toast 通知),AlertProgressSkeletonSpinner
命令面板 Command 放在 Dialog
图表 Chart(封装了 Recharts)
布局 CardSeparatorResizableScrollAreaAccordionCollapsible
空状态 Empty
菜单 DropdownMenuContextMenuMenubar
工具提示/信息 TooltipHoverCardPopover

关键字段

注入的项目上下文包含以下关键字段:

  • aliases → 使用实际的别名前缀进行导入(例如 @/~/),绝不硬编码。
  • isRSC → 当为 true 时,使用 useStateuseEffect、事件处理程序或浏览器 API 的组件需要在文件顶部添加 "use client"。在建议添加指令时,务必参考此字段。
  • tailwindVersion"v4" 使用 @theme inline 块;"v3" 使用 tailwind.config.js
  • tailwindCssFile → 定义了自定义 CSS 变量的全局 CSS 文件。始终编辑此文件,不要创建新文件。
  • style → 组件的视觉样式(例如 novavega)。
  • base → 基础库(radixbase)。这会影响组件 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)。

完整字段参考请见 cli.md — info 命令

组件文档、示例和使用方法

运行 npx shadcn@latest docs <组件名> 可获取组件文档、示例和 API 参考的 URL。获取这些 URL 以获取实际内容。

npx shadcn@latest docs button dialog select

在创建、修复、调试或使用组件时,务必先运行 npx shadcn@latest docs 并获取 URL。 这确保您使用的是正确的 API 和使用模式,而不是靠猜测。

工作流程

  1. 获取项目上下文 — 上面已注入。如果需要刷新,可再次运行 npx shadcn@latest info
  2. 首先检查已安装的组件 — 在运行 add 之前,始终检查项目上下文中的 components 列表或列出 resolvedPaths.ui 目录。不要导入尚未添加的组件,也不要重复添加已安装的组件。
  3. 查找组件npx shadcn@latest search
  4. 获取文档和示例 — 运行 npx shadcn@latest docs <组件名> 获取 URL,然后获取它们。使用 npx shadcn@latest view 浏览尚未安装的注册表项目。要预览对已安装组件的更改,请使用 npx shadcn@latest add --diff
  5. 安装或更新npx shadcn@latest add。更新现有组件时,先使用 --dry-run--diff 预览更改(参见下文 更新组件)。
  6. 修复第三方组件中的导入 — 从社区注册表(例如 @bundui@magicui)添加组件后,检查添加的非 UI 文件中是否有硬编码的导入路径,如 @/components/ui/...。这些可能与项目的实际别名不匹配。使用 npx shadcn@latest info 获取正确的 ui 别名(例如 @workspace/ui/components),并相应地重写导入。CLI 会为其自己的 UI 文件重写导入,但第三方注册表组件可能使用与项目不匹配的默认路径。
  7. 审查添加的组件 — 从任何注册表添加组件或代码块后,务必阅读添加的文件并验证其正确性。检查是否缺少子组件(例如 SelectItem 缺少 SelectGroup)、缺少导入、组合不正确或违反了 核心规则。同时,将所有图标导入替换为项目上下文中指定的 iconLibrary(例如,如果注册表项目使用 lucide-react 但项目使用 hugeicons,则相应地替换导入和图标名称)。在继续之前修复所有问题。
  8. 必须明确指定注册表 — 当用户要求添加代码块或组件时,不要猜测注册表。如果未指定注册表(例如用户说”添加一个登录块”但没有指定 @shadcn@tailark 等),询问要使用哪个注册表。绝不代用户默认选择一个注册表。
  9. 切换预设 — 首先询问用户:重新安装合并 还是 跳过
    • 重新安装npx shadcn@latest init --preset <代码> --force --reinstall。覆盖所有组件。
    • 合并npx shadcn@latest init --preset <代码> --force --no-reinstall,然后运行 npx shadcn@latest info 列出已安装组件,然后对每个已安装组件使用 --dry-run--diff 进行智能合并
    • 跳过npx shadcn@latest init --preset <代码> --force --no-reinstall。仅更新配置和 CSS,组件保持不变。

更新组件

当用户要求从上游更新组件但保留本地更改时,使用 --dry-run--diff 进行智能合并。绝不手动从 GitHub 获取原始文件 — 始终使用 CLI。

  1. 运行 npx shadcn@latest add <组件名> --dry-run 查看所有会受影响的文件。
  2. 对于每个文件,运行 npx shadcn@latest add <组件名> --diff <文件> 查看上游与本地文件的差异。
  3. 根据差异决定每个文件的处理方式:
    • 无本地更改 → 安全地覆盖。
    • 有本地更改 → 读取本地文件,分析差异,并在保留本地修改的同时应用上游更新。
    • 用户说”直接全部更新” → 使用 --overwrite,但需先确认。
  4. 未经用户明确同意,绝不使用 --overwrite

快速参考

# 创建新项目。
npx shadcn@latest init --name my-app --preset base-nova
npx shadcn@latest init --name my-app --preset a2r6bw --template vite

# 创建 monorepo 项目。
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  # 快捷方式:--template=next --preset=base-nova

# 添加组件。
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"

# 获取组件文档和示例 URL。
npx shadcn@latest docs button dialog select

# 查看注册表项目详情(适用于尚未安装的项目)。
npx shadcn@latest view @shadcn/button

命名预设: base-novaradix-nova
模板: nextvitestartreact-routerastro(都支持 --monorepo)和 laravel(不支持 monorepo)
预设代码: Base62 字符串,以 a 开头(例如 a2r6bw),来自 ui.shadcn.com

详细参考

  • rules/forms.md — FieldGroup、Field、InputGroup、ToggleGroup、FieldSet、验证状态
  • rules/composition.md — 分组、覆盖层、Card、Tabs、Avatar、Alert、Empty、Toast、Separator、Skeleton、Badge、按钮加载状态
  • rules/icons.md — data-icon、图标尺寸、将图标作为对象传递
  • rules/styling.md — 语义化颜色、变体、className、间距、尺寸、truncate、暗黑模式、cn()、z-index
  • rules/base-vs-radix.md — asChild 对比 render、Select、ToggleGroup、Slider、Accordion
  • cli.md — 命令、标志、预设、模板
  • customization.md — 主题、CSS 变量、扩展组件

📄 原始文档

完整文档(英文):

https://skills.sh/shadcn/ui/shadcn

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。