返回全部 Skills

shadcn

开发工具

管理 shadcn 组件和项目——包括添加、搜索、修复、调试、样式化和组合 UI(含聊天界面)。提供项目上下文、组件文档及使用示例。适用于使用 shadcn/ui、组件注册表、预设、`--preset` 代码或任何包含 `components.json` 文件的项目。同样在 `"shadcn init"`、`"create an app with --preset"` 或 `"switch to --preset"` 时触发。

131.5k

下载量

AI SkillHub 能力展示图

安装方式

命令行安装

在项目根目录执行以下命令,完成 Skill 安装。

npx bzskills add shadcn/ui --skill shadcn

skill.md

name: shadcn
description: 管理 shadcn 组件和项目——包括添加、搜索、修复、调试、样式化和组合 UI(含聊天界面)。提供项目上下文、组件文档及使用示例。适用于使用 shadcn/ui、组件注册表、预设、`--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@latestpnpm dlx shadcn@latestbunx --bun shadcn@latest — 具体取决于项目的 packageManager。以下示例使用 npx shadcn@latest,但请替换为项目对应的运行器。

当前项目上下文

!`npx shadcn@latest info --json`

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

原则

  1. 优先使用现有组件。 在编写自定义UI之前,使用 npx shadcn@latest search 检查注册表。同时检查社区注册表。
  2. 组合而非重造。 设置页面 = Tabs + Card + 表单控件。仪表盘 = Sidebar + Card + Chart + Table。
  3. 优先使用内置变体而非自定义样式。 variant="outline", size="sm" 等。
  4. 使用语义化颜色。 bg-primary, text-muted-foreground — 绝不使用像 bg-blue-500 这样的原始值。

关键规则

这些规则始终强制执行。每条规则都链接到一个包含错误/正确代码对的文件。

样式与 Tailwind → styling.md

  • 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() 处理条件类名。 不要手动编写模板字面量三元表达式。
  • 在覆盖组件上不要手动设置 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 通过 sonner 实现。 使用 sonnertoast()
  • 使用 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},而不是字符串查找。

聊天与消息 → chat.md

  • 聊天 UI 由聊天基元组成。 对话使用 MessageScroller,行使用 Message,表面使用 Bubble。不要手工编写气泡 div 或原始的滚动容器。
  • MessageScroller 负责滚动行为。 流式跟随、锚定和跳转至最新(MessageScrollerButton)都是内置的。不要编写 useStickToBottom/ResizeObserver 钩子。
  • 附件使用 Attachment;系统注释和分隔符使用 Marker 不要使用 Item 卡片或 Separator 加标签。

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 代码的最常见模式。对于边界情况,请参阅上面链接的规则文件。

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

// 验证:在 Field 上使用 data-invalid,在控件上使用 aria-invalid。
<Field data-invalid>
  <FieldLabel>Email</FieldLabel>
  <Input aria-invalid />
  <FieldDescription>Invalid email.</FieldDescription>
</Field>

// 按钮中的图标:使用 data-icon,不使用尺寸类。
<Button>
  <SearchIcon data-icon="inline-start" />
  Search
</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 变体或语义化 token,而不是原始颜色。
<Badge variant="secondary">+20.1%</Badge>    // 正确
<span className="text-emerald-600">+20.1%</span> // 错误

组件选择

需求使用
按钮/操作Button 配合适当的 variant
表单输入InputSelectComboboxSwitchCheckboxRadioGroupTextareaInputOTPSlider
在 2-5 个选项间切换ToggleGroup + ToggleGroupItem
数据展示TableCardBadgeAvatar
导航SidebarNavigationMenuBreadcrumbTabsPagination
覆盖层Dialog(模态框)、Sheet(侧面板)、Drawer(底部抽屉)、AlertDialog(确认框)
反馈sonner(toast)、AlertProgressSkeletonSpinner
命令面板Dialog 内部的 Command
图表Chart(包装 Recharts)
布局CardSeparatorResizableScrollAreaAccordionCollapsible
空状态Empty
菜单DropdownMenuContextMenuMenubar
工具提示/信息TooltipHoverCardPopover
聊天/对话 UIMessageScrollerMessageBubbleAttachmentMarker

关键字段

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

  • 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-reacttabler 使用 @tabler/icons-react 等。不要假设为 lucide-react
  • resolvedPaths → 组件、工具、hooks 等精确的文件系统目标路径。
  • framework → 路由和文件约定(例如 Next.js App Router 与 Vite SPA)。
  • packageManager → 用于任何非 shadcn 依赖的安装(例如 pnpm add date-fnsnpm install date-fns)。
  • preset → 当前项目解析后的预设代码和值。当你只需要预设信息时使用 npx shadcn@latest preset resolve --json

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

组件文档、示例和使用

运行 npx shadcn@latest docs <component> 获取组件的文档、示例和 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 <component> 获取 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. 审查添加的组件 — 从任何注册表添加组件或块后,始终阅读添加的文件并验证其正确性。检查是否缺少子组件(例如没有 SelectGroupSelectItem)、缺少导入、结构错误或违反关键规则。同时,将任何图标导入替换为项目上下文中 iconLibrary 指定的图标库(例如,如果注册表项目使用 lucide-react 但项目使用 hugeicons,则相应交换导入和图标名称)。在继续之前修复所有问题。
  8. 注册表必须明确声明 — 当用户要求添加块或组件时,不要猜测注册表。如果没有指定注册表(例如用户说“添加一个登录块”而没有指定 @shadcn@tailarkowner/repo 等),询问使用哪个注册表。永远不要替用户默认选择注册表。
  9. 切换预设 — 首先询问用户:覆盖部分合并还是跳过
  • 检查当前预设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 组件。支持的值是 themefont;允许逗号分隔的组合。有意不支持 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 中的当前库(baseradix)。如果必须使用临时目录(例如用于 --dry-run 比较),请显式传递 --base <current-base> — 预设代码不编码库信息。

更新组件

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

  1. 运行 npx shadcn@latest add <component> --dry-run 查看所有可能受影响的文件。
  2. 对于每个文件,运行 npx shadcn@latest add <component> --diff <file> 查看上游与本地之间的差异。
  3. 根据差异逐文件决定:
  • 没有本地更改 → 可以安全覆盖。
  • 有本地更改 → 阅读本地文件,分析差异,并应用上游更新同时保留本地修改。
  • 用户说“直接全部更新” → 使用 --overwrite,但先确认。
  1. 未经用户明确批准,切勿使用 --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=nova(隐含 base 样式)

# 向现有项目应用预设。
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

# 检查预设代码和项目预设状态。
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

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

# 在添加/更新前预览更改。
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

# 搜索注册表。
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                          # 所有已配置的注册表
npx shadcn@latest search @shadcn -q "menu" -t ui  # 按项目类型过滤

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

# 查看注册表项目详情(针对尚未安装的项目)。
npx shadcn@latest view @shadcn/button
npx shadcn@latest view owner/repo/item

命名预设: novavegamaialyramiraluma

模板: nextvitestartreact-routerastro(全部支持 --monorepo)和 laravel(不支持 monorepo)

预设代码: 版本前缀的 base62 字符串(例如 a2r6bwb0),来自 ui.shadcn.com

详细参考

  • rules/forms.md — FieldGroup、Field、InputGroup、ToggleGroup、FieldSet、验证状态
  • rules/composition.md — Groups、覆盖层、Card、Tabs、Avatar、Alert、Empty、Toast、Separator、Skeleton、Badge、Button 加载
  • rules/chat.md — MessageScroller、Message、Bubble、Attachment、Marker;流式、锚定、跳转至最新
  • rules/icons.md — data-icon、图标尺寸、将图标作为对象传递
  • rules/styling.md — 语义化颜色、变体、className、间距、size、truncate、深色模式、cn()、z-index
  • rules/base-vs-radix.md — asChild 与 render、Select、ToggleGroup、Slider、Accordion
  • cli.md — 命令、标志、预设、模板
  • registry.md — 编写源注册表、include、项目定义、依赖、GitHub 注册表规则
  • customization.md — 主题、CSS 变量、扩展组件