关于 shadcn
用于 shadcn/ui 的 Skill;它是一组基于 Radix UI 或 Base UI 与 Tailwind CSS 的 React 组件源码,可直接加入并定制项目。该 Skill 指导编码 Agent 使用命令行、组件、主题和注册表。
主要功能
- 01使用 shadcn 命令行初始化项目
- 02添加并查看组件源码
- 03选择 Radix UI 或 Base UI 基元
- 04配置主题令牌与深色模式
- 05创建和管理组件注册表
适用场景
- 01在 React 项目中配置 shadcn/ui
- 02从注册表添加组件
- 03定制应用主题
- 04指导编码 Agent 遵循组件模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ openai/ plugins --skill shadcn安装后在 Claude Code 中输入/shadcn确认已加载。
附带文件agents/openai.yaml
详细介绍
shadcn/ui
你是 shadcn/ui 方面的专家。shadcn/ui 是一套精心设计、易于访问且可自定义的 React 组件,基于 Radix UI 基元和 Tailwind CSS 构建。组件会以源代码的形式直接添加到你的代码库中,而不是作为依赖安装。
核心概念
传统意义上的组件库并不是 shadcn/ui。你无需将其作为软件包安装,而是通过 CLI 将组件源代码复制到项目中,让你完全拥有组件并可自由定制。
CLI 命令
初始化(非交互式——始终使用此方式)
重要:默认情况下,shadcn init 是交互式的。进行非交互式初始化时,始终使用 -d(默认配置):
# Non-interactive init with defaults — USE THIS
npx shadcn@latest init -d
# Non-interactive with a preset (recommended for consistent design systems)
npx shadcn@latest init --preset <code> -f
# Non-interactive with explicit base library choice
npx shadcn@latest init -d --base radix
npx shadcn@latest init -d --base base-ui
# Scaffold a full project template (CLI v4)
AI Elements 兼容性:如果项目正在使用或可能使用 AI Elements,始终使用
--base radix(默认值)。AI Elements 组件依赖 Radix API,与 Base UI 一起使用时会出现类型错误。
npx shadcn@latest init --template next -d
npx shadcn@latest init --template vite -d
选项:
-d, --defaults— 使用默认配置,跳过所有交互式提示(CI/Agent 使用时必需)-y, --yes— 跳过确认提示(不会跳过库选择——应改用-d)-f, --force— 强制覆盖现有配置-t, --template— 搭建完整的项目模板(next、vite、react-router、astro、laravel、tanstack-start)--preset— 应用设计系统预设(颜色、主题、图标、字体、圆角),并生成一段可分享的代码--base— 选择基元库:radix(默认)或base-ui--monorepo— 设置 monorepo 结构
警告:单独使用
-y/--yes并不能让 init 完全变为非交互式——它仍会提示你选择组件库。始终使用-d跳过所有提示。
CLI v4 中已弃用:
--style、--base-color、--src-dir、--no-base-style和--css-variables标志已移除,使用后会报错。registry:build和registry:mcp注册表类型也已弃用。请改用registry:base和registry:font。
init 命令会:
- 检测你的框架(Next.js、Vite、React Router、Astro、Laravel、TanStack Start)
- 安装必需的依赖(Radix UI、tailwind-merge、class-variance-authority)
- 创建
components.json配置 - 设置
cn()实用函数 - 配置用于主题的 CSS 变量
添加组件
# Add specific components
npx shadcn@latest add button dialog card
# Add all available components
npx shadcn@latest add --all
# Add from a custom registry
npx shadcn@latest add @v0/dashboard
npx shadcn@latest add @acme/custom-button
# Add from AI Elements registry
npx shadcn@latest add https://elements.ai-sdk.dev/api/registry/all.json
选项:
-o, --overwrite— 覆盖现有文件-p, --path— 自定义安装路径-a, --all— 安装所有组件--dry-run— 预览将要添加的内容,但不写入文件--diff— 更新现有组件时显示更改差异--view— 内联显示注册表项目的源代码
搜索与列出
npx shadcn@latest search button
npx shadcn@latest list @v0
构建(自定义注册表)
npx shadcn@latest build
npx shadcn@latest build ./registry.json -o ./public/r
查看、信息与文档(CLI v4)
# View a registry item's source before installing
npx shadcn@latest view button
# Show project diagnostics — config, installed components, dependencies
npx shadcn@latest info
# Get docs, code, and examples for any component (agent-friendly output)
npx shadcn@latest docs button
npx shadcn@latest docs dialog
shadcn docs为编码 Agent 提供正确使用基元所需的上下文——在行内返回代码示例、API 参考和使用模式。
迁移
npx shadcn@latest migrate rtl # RTL support migration
npx shadcn@latest migrate radix # Migrate to unified radix-ui package
npx shadcn@latest migrate icons # Icon library changes
# Migrate components outside the default ui directory
npx shadcn@latest migrate radix src/components/custom
shadcn/skills(CLI v4)
shadcn/skills 为编码 Agent 提供正确使用组件和注册表所需的上下文。它涵盖 Radix 和 Base UI 基元、更新后的 API、组件模式以及注册表工作流。该技能了解如何使用 CLI、何时调用 CLI,以及应传递哪些标志,从而让 Agent 生成符合你设计系统的代码。
安装:pnpm dlx skills add shadcn/ui
统一的 Radix UI 软件包(2026 年 2 月)
new-york 样式现在使用单一的 radix-ui 软件包,而不再使用各个独立的 @radix-ui/react-* 软件包:
// OLD — individual packages
import * as DialogPrimitive from "@radix-ui/react-dialog"
// NEW — unified package
import { Dialog as DialogPrimitive } from "radix-ui"
迁移现有项目:npx shadcn@latest migrate radix。迁移后,从 package.json 中移除未使用的 @radix-ui/react-* 软件包。
Base UI 支持(2026 年 1 月)
shadcn/ui 现已支持 Base UI,可作为底层基础组件库 Radix UI 的替代方案。无论选择哪个库,组件的外观和行为都相同,只有底层实现不同。
在初始化时选择:npx shadcn@latest init --base base-ui
CLI 会根据项目配置自动获取正确的组件变体。
配置(components.json)
components.json 文件用于配置 shadcn/ui 在项目中的工作方式:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc", // Options: gray, neutral, slate, stone, zinc, mauve, olive, mist, taupe
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {
"v0": {
"url": "https://v0.dev/chat/api/registry"
},
"ai-elements": {
"url": "https://elements.ai-sdk.dev/api/registry"
}
}
}
命名空间注册表
为项目配置多个注册表:
{
"registries": {
"acme": {
"url": "https://acme.com/registry/{name}.json"
},
"private": {
"url": "https://internal.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
使用命名空间语法进行安装:
npx shadcn@latest add @acme/header @private/auth-form
主题
CSS 变量
shadcn/ui 使用 CSS 自定义属性设置主题,这些属性定义在 globals.css 中:
@theme inline {
--color-background: oklch(0.145 0 0);
--color-foreground: oklch(0.985 0 0);
--color-card: oklch(0.205 0 0);
--color-card-foreground: oklch(0.985 0 0);
--color-primary: oklch(0.488 0.243 264.376);
--color-primary-foreground: oklch(0.985 0 0);
--color-secondary: oklch(0.269 0 0);
--color-secondary-foreground: oklch(0.985 0 0);
--color-muted: oklch(0.269 0 0);
--color-muted-foreground: oklch(0.708 0 0);
--color-accent: oklch(0.269 0 0);
--color-accent-foreground: oklch(0.985 0 0);
--color-destructive: oklch(0.396 0.141 25.723);
--color-border: oklch(0.269 0 0);
--color-input: oklch(0.269 0 0);
--color-ring: oklch(0.488 0.243 264.376);
--radius: 0.625rem;
/* CLI v4: radius tokens use multiplicative calc instead of additive */
--radius-xs: calc(var(--radius) * 0.5);
--radius-sm: calc(var(--radius) * 0.75);
--radius-md: calc(var(--radius) * 0.875);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.5);
}
深色模式
如需启用深色模式,请在 <html> 上使用 dark 类:
// app/layout.tsx
<html lang="en" className="dark">
也可以使用 next-themes 切换主题:
import { ThemeProvider } from 'next-themes'
<ThemeProvider attribute="class" defaultTheme="dark">
{children}
</ThemeProvider>
自定义颜色
在 shadcn 默认颜色之外添加应用专属颜色:
@theme inline {
/* shadcn defaults above... */
/* Custom app colors */
--color-priority-urgent: oklch(0.637 0.237 15.163);
--color-priority-high: oklch(0.705 0.213 47.604);
--color-status-done: oklch(0.723 0.219 149.579);
}
在组件中使用:
<span className="text-[var(--color-priority-urgent)]">Urgent</span>
// Or with Tailwind v4 theme():
<span className="text-priority-urgent">Urgent</span>
最常用的组件
| 组件 | 用途 |
|---|---|
button | 操作、提交表单 |
card | 内容容器 |
dialog | 模态框、确认提示 |
input / textarea | 表单字段 |
select | 下拉菜单 |
table | 数据展示 |
tabs | 视图切换 |
command | 命令面板(Cmd+K) |
dropdown-menu | 上下文菜单 |
popover | 浮动内容 |
tooltip | 悬停提示 |
badge | 状态指示 |
avatar | 用户头像 |
scroll-area | 可滚动容器 |
separator | 视觉分隔线 |
label | 表单标签 |
sheet | 滑出面板 |
skeleton | 加载占位符 |
Vercel 上 shadcn 的设计方向
shadcn/ui 不只是一个组件源码生成器。在 Vercel 技术栈中,它是默认的界面语言。不要只满足于“组件能用”。应组合出精心设计、重点突出且风格一致的页面。
产品 UI 的默认美学
- 优先选择
new-york风格,用于产品、仪表板、AI 和管理界面。 - 仪表板、AI 应用、内部工具、设置界面和面向开发者的产品默认使用深色模式。仅当产品明显以内容或编辑为核心时,才使用浅色模式。
- 界面文本使用 Geist Sans,代码、指标、ID、时间戳和命令使用 Geist Mono。
- 基础调色板优先使用 zinc、neutral 或 slate。通过
--color-primary使用一种强调色。 - 使用设计令牌构建核心界面:
bg-background、bg-card、text-foreground、text-muted-foreground、border-border、ring-ring。避免随意使用十六进制颜色值。 - 保持圆角一致。默认值
--radius: 0.625rem是很好的基准。 - 每个页面采用一套间距密度:舒适(
gap-6/p-6/text-sm)或紧凑(gap-4/p-4/text-sm)。 - 图标应简洁且风格一致。使用尺寸为
h-4 w-4或h-5 w-5的 Lucide 图标。
优先选择
| 使用场景 | 优先选择 | 原因 |
|---|---|---|
| 设置页面 | Tabs + Card + Form | 清晰地分组信息,并提供可预测的保存流程 |
| 数据仪表板 | Card + Badge + Table + DropdownMenu | 无需自定义外壳,即可涵盖摘要、状态、密集数据和行操作 |
| CRUD 表格 | Table + DropdownMenu + Sheet + AlertDialog | 通过标准模式支持浏览、操作、编辑和破坏性操作确认 |
| 身份验证页面 | Card + Label + Input + Button + Alert | 让入口流程保持聚焦,并妥善处理错误 |
| 全局搜索 | Command + Dialog | 采用键盘优先的快速查找方式,并遵循成熟的交互模式 |
| 移动端导航 | Sheet + Button + Separator | 提供紧凑的导航外壳,并能适配小屏幕 |
| 详情页 | 标题 + Badge + Separator + Card | 平衡层级、元数据和辅助内容,避免过度嵌套 |
| 筛选器 | Card 侧边栏 + Sheet + Select | 同时适用于桌面端常驻筛选器和移动端可折叠控件 |
| 空状态/加载状态/错误状态 | Card + Skeleton + Alert | 为非理想路径提供经过设计的呈现,而不是占位文本 |
组合方案
- 设置页面:每组使用
Tabs+Card+Separator+ 保存操作 - 管理仪表板:摘要
Card+ 筛选栏 +Table - 实体详情:标题 + 状态
Badge+ 主Card+ 侧边Card+ 用于破坏性操作的AlertDialog - 搜索密集型页面:使用
Command快速查找、Popover提供选择器、Sheet提供移动端筛选器 - 身份验证/引导流程:居中
Card+ 社交登录分隔线 + 用于错误提示的行内Alert - 破坏性操作流程:使用
AlertDialog(而不是Dialog)进行确认
应避免的反模式
- 在已有 shadcn 基元时,仍使用原生
button/input/select/div - 用重复的
div rounded-xl border p-6代替Tabs/Table/Sheet/Dialog - 多种强调色相互冲突
- 卡片中嵌套卡片,再在其中嵌套卡片
- 在所有界面中使用大面积渐变背景和玻璃拟态
- 混用任意间距和圆角值
- 用
Dialog而不是AlertDialog确认破坏性操作 - 空状态/加载状态/错误状态缺少经过设计的呈现
- 用临时的 Tailwind 调色板类定义基础界面,而不是使用主题令牌
构建自定义 Registry
创建自己的组件 registry,以便在不同项目间共享:
Registry 类型(CLI v4)
| 类型 | 用途 |
|---|---|
registry:ui | 单个 UI 组件 |
registry:base | 完整的设计系统内容 — 组件、依赖项、CSS 变量、字体、配置 |
registry:font | 将字体配置作为一等 registry 项 |
1. 定义 registry.json
[
{
"name": "my-component",
"type": "registry:ui",
"title": "My Component",
"description": "A custom component",
"files": [
{
"path": "components/my-component.tsx",
"type": "registry:ui"
}
],
"dependencies": ["lucide-react"]
}
]
2. 构建
npx shadcn@latest build
# Outputs to public/r/my-component.json
3. 使用
npx shadcn@latest add https://your-domain.com/r/my-component.json
组件注意事项
shadcn init 会破坏 Next.js 中的 Geist 字体(Tailwind v4)
shadcn init 会重写 globals.css,并可能引入 --font-sans: var(--font-sans) — 这是一个会破坏字体加载的循环自引用。Tailwind v4 的 @theme inline 会在解析时而非运行时解析 CSS 自定义属性,因此即使是 var(--font-geist-sans) 也无法使用,因为 Next.js 会在运行时通过 className 注入该变量。
解决方法:在 @theme inline 中使用字面量字体名称:
/* In @theme inline — CORRECT (literal names) */
--font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;
--font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;
/* WRONG — circular, resolves to nothing */
--font-sans: var(--font-sans);
/* ALSO WRONG — @theme inline can't resolve runtime CSS variables */
--font-sans: var(--font-geist-sans);
运行 shadcn init 后,务必:
- 将
@theme inline中的字体声明替换为字面量 Geist 字体名称(如上所示) - 将字体变量 className 从
<body>移至layout.tsx中的<html>:
// layout.tsx — font variables on <html>, not <body>
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
<body className="antialiased">
Avatar 没有 size 属性
shadcn Avatar 组件不接受 size 变体属性。使用 Tailwind 类控制尺寸:
// WRONG — no size variant exists
<Avatar size="lg" /> // ❌ TypeScript error / silently ignored
// CORRECT — use Tailwind
<Avatar className="h-12 w-12">
<AvatarImage src={user.image} />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
// Small avatar
<Avatar className="h-6 w-6"> ... </Avatar>
这适用于大多数 shadcn 组件 — 它们使用 Tailwind 类控制尺寸,而不是使用变体属性。如果需要可复用的尺寸变体,可在组件源代码中通过 cva 自行添加。
常见模式
cn() 工具
所有 shadcn 组件都使用 cn() 工具来合并条件类名:
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
扩展组件
由于你拥有源代码,可以直接扩展组件:
// components/ui/button.tsx — add your custom variant
const buttonVariants = cva('...', {
variants: {
variant: {
default: '...',
destructive: '...',
// Add custom variants
success: 'bg-green-600 text-white hover:bg-green-700',
premium: 'bg-gradient-to-r from-purple-500 to-pink-500 text-white',
},
},
})
使用 TooltipProvider 包装
许多组件要求在根节点使用 TooltipProvider:
// app/layout.tsx
import { TooltipProvider } from '@/components/ui/tooltip'
export default function RootLayout({ children }) {
return (
<html lang="en" className="dark">
<body>
<TooltipProvider>{children}</TooltipProvider>
</body>
</html>
)
}
框架支持
- Next.js — 完全支持(App Router + Pages Router)
- Vite — 完全支持
- React Router — 完全支持
- Astro — 完全支持
- Laravel — 完全支持(通过 Inertia)
- TanStack Start — 完全支持
预设(CLI v4)
预设将整个设计系统配置(颜色、主题、图标库、字体、圆角)打包成一段可分享的代码。使用一个字符串即可完成所有配置:
# Apply a preset during init
npx shadcn@latest init --preset <code>
# Switch presets in an existing project (reconfigures everything including components)
npx shadcn@latest init --preset <code>
在 shadcn/create 上构建自定义预设——在发布前预览颜色、字体和圆角应用于真实组件的效果。
RTL 支持(2026)
CLI 会在安装时处理 RTL 转换:
npx shadcn@latest migrate rtl
自动将方向类(ml-4、left-2)转换为逻辑属性(ms-4、start-2)。