关于 shadcn
shadcn 是使用 shadcn/ui 构建界面的技能,通过 CLI 将组件源代码添加到项目。它依据项目现有配置和组件 API,指导组件选择、组合、样式及无障碍实现。
主要功能
- 01检查项目配置和组件
- 02复用现有组件与模式
- 03组合 UI 基础组件
- 04采用语义化样式约定
- 05遵循组件 API 与无障碍要求
- 06通过 CLI 使用预设和文档
适用场景
- 01向现有项目添加组件
- 02构建表单、导航或覆盖层
- 03按项目样式调整组件
- 04检查组件组合的无障碍性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marcellocurto/ skills --skill shadcn安装后在 Claude Code 中输入/shadcn确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
cli.mdcustomization.mdmcp.mdregistry.mdagents/openai.yamlevals/evals.jsonrules/base-vs-radix.mdchat.mdcomposition.mdforms.mdicons.mdstyling.md详细介绍
shadcn/ui
用于构建 UI、组件和设计系统的框架。组件通过 CLI 以源代码的形式添加到用户的项目中。
使用项目的包运行器执行 CLI 命令:npx shadcn@latest、pnpm dlx shadcn@latest 或 bunx --bun shadcn@latest。在获取项目上下文之前,先根据 package.json 和仓库惯例确定使用哪个运行器。以下示例使用 npx shadcn@latest;请替换为项目使用的运行器。
当前项目上下文
如果当前项目已有可用的实际输出,请复用相关项目上下文。如果输出缺失或已过时(包括不支持注入 shell 命令的主机),请在目标项目中使用其包运行器执行以下命令。技能中的命令文本本身不能证明命令已运行:
npx shadcn@latest info --json
检查结果中的配置、已安装组件和已解析路径。当项目、配置或已安装组件集合发生变化时刷新结果,而不是每次调整样式时都刷新。如果 info 不可用,请直接读取 package.json、components.json、相关的已安装组件源代码和主题文件。说明重要但尚未确认的事实;不要捏造注入的输出,也不要仅为获取上下文而初始化项目。
原则
- 优先使用现有组件。 检查已安装的组件及其附近的用法。需要的组件缺失时,搜索已解析的注册表;如果用户请求或项目上下文支持使用社区注册表,也可以查阅。
- 根据所需界面进行组合。 复用适合任务和周边产品的基础组件,而不是强加固定的页面方案。
- 优先使用内置变体,而非自定义样式。 例如
variant="outline"、size="sm"等。 - 优先使用语义化颜色。 使用
bg-primary和text-muted-foreground等令牌来表示主题角色。如果明确的设计要求和既有项目惯例支持采用不同处理方式,则遵循这些要求和惯例。
API 和无障碍要求
已安装的源代码、类型和选定的基础组件库共同定义了组件 API。保留必需的组合方式、无障碍名称、键盘行为、焦点处理和状态语义。不要把样式偏好当作 API 要求,也不要仅为匹配较新的示例而更改可正常工作的 API。
- 自定义触发器: 使用项目基础组件和已安装组件所支持的组合 API,例如 Radix 的
asChild或 Base UI 的render。当项目使用这些基础组件时,请参阅 base-vs-radix.md。 - 叠层名称: 通过受支持的标题机制为 Dialog、Sheet 和 Drawer 提供无障碍名称。使用
DialogTitle、SheetTitle或DrawerTitle;如果标题应在视觉上隐藏,请使用className="sr-only"。自定义这些组件时,保留焦点和键盘行为。 - 控件语义: 为输入控件添加标签,以语义化方式对相关控件分组,并通过已安装控件支持的 API 暴露无效和禁用状态。
data-invalid和data-disabled可用于控件样式,但不能替代aria-invalid或实际的禁用行为。请参阅 forms.md。 - 必需的结构和属性: 保留已安装实现所要求的父组件和子组件,例如
TabsTrigger必须位于TabsList内,或 InputGroup 必须使用专用输入组件。根据所选基础组件确认要求;不要假设每个建议的分组包装器都是必需的。请参阅 composition.md。 - 受支持的加载状态: 使用
isPending或isLoading前,请检查本地 Button API。如果没有这些属性,请使用受支持的 spinner、图标位置和禁用状态组合出真实的待处理行为。
样式与组合默认规范
在符合请求的设计和现有代码时,采用以下默认规范。若用户明确提出选择或项目已有约定,则以其为准,同时保留 API 和无障碍要求。不要仅因有效替代方案与这些示例不同,就将其报告为缺陷。
- 样式: 优先使用内置变体和语义化令牌,用
gap-*设置 flex/grid 间距,用size-*设置相等尺寸,并使用truncate和项目的cn()工具。使用className设置布局和合理的局部样式。添加覆盖规则前,先检查现有覆盖层的堆叠顺序。参见 styling.md 和 customization.md。 - 表单: 在适用时,优先使用现有的
FieldGroup/Field和InputGroup组合。根据交互含义选择 ToggleGroup、RadioGroup、Checkbox 或 Switch,而不应仅依据选项数量。使用项目的 fieldset 模式保留语义分组。参见 forms.md。 - 卡片与分组: 仅当内容确实属于 Card 时才使用 Card 分区;省略空的描述或页脚。根据组件 API 或内容之间的关系,选择合适的分组组件。如果图像不可用会导致有用的身份信息丢失,请提供恰当的头像备用内容。参见 composition.md。
- 反馈与装饰: 当现有 Alert、Empty、Separator、Skeleton 和 Badge 组件的行为及语义符合需求时,优先使用它们。保留项目现有的 toast 实现。不要仅为补全某种模式而添加组件或状态。
- 图标: 遵循已配置的图标库,以及已安装组件的尺寸和放置约定;支持时包括
data-icon。请求的设计有需要时,可自定义尺寸。除非现有数据契约需要标识符,否则优先使用组件引用,而不是字符串查找机制。参见 icons.md。 - 聊天: 在可用且适用时,复用 MessageScroller、Message、Bubble、Attachment 和 Marker。使用这些组件时保留其必需的嵌套结构,并优先使用它们的滚动和状态 API,而不是重复实现。仅因为存在这些基础组件,不必替换现有聊天 UI。参见 chat.md。
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>。
关键模式
以下示例展示了上述默认规范。样式方面的替代方案并非自动视为错误;应保留已安装的 API 和请求的设计。
// Default form layout with the project's Field components.
<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 htmlFor="invalid-email">Email</FieldLabel>
<Input id="invalid-email" aria-invalid aria-describedby="invalid-email-error" />
<FieldDescription id="invalid-email-error">Invalid email.</FieldDescription>
</Field>
// Icon placement when supported by the installed Button.
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
// Prefer gap for a flex layout; preserve an intentional block layout.
<div className="flex flex-col gap-4">...</div>
// Concise equal dimensions.
<Avatar className="size-10" />
// Prefer an existing status presentation when it fits.
<Badge variant="secondary">+20.1%</Badge>
组件选择
| 需求 | 使用 |
|---|---|
| 按钮/操作 | 带有适当变体的 Button |
| 表单输入 | Input、Select、Combobox、Switch、Checkbox、RadioGroup、Textarea、InputOTP、Slider |
| 相关切换选项 | 适用切换语义时使用 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 |
| 聊天/对话 UI | MessageScroller、Message、Bubble、Attachment、Marker |
关键字段
info 中的项目上下文可能包含以下字段。直接读取配置时,应从相关文件中确认对应信息,而不要假设所有字段都存在:
aliases→ 导入时使用实际的别名前缀(例如@/、~/),切勿硬编码。project.rsc→ 值为true时,使用useState、useEffect、事件处理器或浏览器 API 的组件需要在文件顶部添加"use client"。就该指令提供建议时,务必参考此字段。tailwindVersion→"v4"使用@theme inline代码块;"v3"使用tailwind.config.js。project.tailwindCss→ 现有主题样式表。应将共享变量放在项目的主题所有者中,而不是另建一个相互竞争的全局样式表。style→ 组件的视觉风格(例如nova、vega)。base→ 选定的原语库。它会影响组件 API 和可用属性;请使用适用于该原语库的指南。iconLibrary→ 决定图标导入方式。lucide使用lucide-react,tabler使用@tabler/icons-react,以此类推。切勿假设使用lucide-react。resolvedPaths→ 组件、工具函数、钩子等的精确文件系统路径。framework→ 路由和文件约定(例如 Next.js App Router 与 Vite SPA)。- 包管理器 →
info不会报告此信息。在安装任何非 shadcn 依赖项之前(例如pnpm add date-fns与npm install date-fns),请先读取锁文件(bun.lock、pnpm-lock.yaml、yarn.lock、package-lock.json)。 preset→ 当前项目已解析的预设代码和值。若只需预设信息,请使用npx shadcn@latest preset resolve --json。
完整字段参考请参阅 cli.md — info command。
组件文档、示例和用法
先阅读已安装的组件及其附近的用法。添加不熟悉的组件、更改依赖 API 的行为、对比上游更新,或解决本地源码无法解答的问题时,运行 npx shadcn@latest docs <component> 并获取返回的文档。
npx shadcn@latest docs button dialog select
如果已获取的文档仍与相关基础版本和组件版本匹配,则重复使用。若本地源码和既定约定足以解答问题,则进行简单的间距、颜色或排版编辑时无需重新获取文档。仅在相关上下文发生变化或仍有 API 问题时刷新文档。如果无法获取文档,请根据充分的本地证据继续,并说明任何重要的信息缺口。
确定注册表
遵循明确指定的注册表或条目地址。否则,检查 components.json、已记录的约定、附近组件的来源,以及用户之前的决定。如果这些证据明确指向既定来源,请使用该来源并简要说明选择。配置了多个注册表并不意味着存在首选项;只有在剩余选项会实质性地改变组件或来源时才询问。
对可能的已配置来源进行只读搜索,可能有助于确定选择。添加条目前,请先确定具体的注册表;必要时使用带命名空间的名称、GitHub 条目地址或 URL 来表达。不要仅因名称相同,就悄悄从其他注册表安装组件。地址语义请参阅 registry.md。
工作流
仅采用与任务相关的步骤。本地样式编辑可能不需要搜索注册表、安装或预设操作。
- 获取项目上下文 — 复用适用的已观察上下文,或按上述说明获取。不要假定 shell 注入已运行。
- 先检查已安装的组件 — 运行
add之前,务必先检查项目上下文中的components列表,或列出resolvedPaths.ui目录。不要导入尚未添加的组件,也不要重复添加已安装的组件。 - 解析注册表并查找组件 — 按照解析注册表中的说明操作,然后按需搜索所选来源。
- 解决 API 问题 — 根据上述标准查阅本地源代码和适用文档。使用
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 文件的导入,但第三方注册表组件可能使用与项目不符的默认路径。 - 检查新增组件 — 阅读新增文件,并验证导入、必需的组合方式,以及 API 和无障碍要求。根据请求的设计和项目规范调整图标导入与样式。修复具体缺陷,但不要将所有偏离样式默认值的情况都视为缺陷。
- 切换预设 — 在选择操作前,检查当前预设和待应用的预设。尊重已获授权的覆盖、部分更新、合并或跳过选择。只有当请求未明确关键选择,或实际覆盖范围超出授权时,才提出询问;首先具体说明受影响的文件以及主题/配置变更。
- 检查当前预设:
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或radix)。如果必须使用临时目录,请使用npx shadcn@latest init --preset <code> --base <current-base>初始化(预设代码不包含基础信息),然后在其中运行add --dry-run或--diff;apply没有--base或--dry-run标志。
- 检查当前预设:
更新组件
当用户要求在保留本地更改的同时从上游更新组件时,使用 --dry-run 和 --diff 进行智能合并。切勿手动从 GitHub 获取原始文件——始终使用 CLI。
- 运行
npx shadcn@latest add <component> --dry-run,查看所有将受影响的文件。 - 对每个文件运行
npx shadcn@latest add <component> --diff <file>,查看上游与本地之间的更改。 - 根据用户授权的范围,比较受影响的文件、依赖项、主题和配置。在该范围内更新未修改的上游文件;合并已自定义的文件时保留本地行为,除非用户明确授权替换这些自定义内容。笼统的“更新所有内容”请求本身并不代表用户授权丢弃自定义内容。
- 仅当将要替换的每个文件都在范围内,且用户明确授权丢失任何本地自定义内容时,才使用
--overwrite。授权可以来自最初的请求,也可以来自对具体替换方案的先前批准;无需再次征求授权。如果预览显示还会影响范围之外的文件,或会丢失范围之外的自定义内容,只需询问尚未明确的决定,并在问题解决前保留这些文件。
快速参考
# Create a new project.
npx shadcn@latest init --name my-app --preset nova --base base
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
# Create a monorepo project.
npx shadcn@latest init --name my-app --preset nova --base base --monorepo
npx shadcn@latest init --name my-app --preset nova --base base --template next --monorepo
# Initialize existing project.
npx shadcn@latest init --preset nova --base base
npx shadcn@latest init --defaults # shortcut: --template=next --base=base --preset=nova
# 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、sera、rhea。基础样式是单独的 --base 选项;base-nova 是 components.json 中生成的 style 值,而不是预设名称。
模板: 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;流式输出、锚定、跳转到最新消息
- 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 注册表规则 - mcp.md —
shadcn mcp服务设置和工具 - customization.md — 主题化、CSS 变量、扩展组件