SKILL.md
readonly只读
name
shadcn-ui
description
提供完整的 shadcn/ui 组件库模式,包括安装、配置和可访问 React 组件的实现。适用于设置 shadcn/ui、安装组件、使用 React Hook Form 和 Zod 构建表单、使用 Tailwind CSS 自定义主题,或实现按钮、对话框、下拉菜单、表格和复杂表单布局等 UI 模式。
shadcn/ui 组件模式
使用 shadcn/ui、Radix UI 和 Tailwind CSS 构建可访问、可定制的 UI 组件。
概述
- 组件会复制到你的项目中——你拥有并可以自定义代码
- 基于 Radix UI 原语构建,完全可访问
- 使用 Tailwind CSS 和 CSS 变量进行主题样式设计
- 基于 CLI 的安装:
npx shadcn@latest add <component>
何时使用
当用户请求涉及以下内容时激活:
- "设置 shadcn/ui"、"初始化 shadcn"、"添加 shadcn 组件"
- "安装 button/input/form/dialog/card/select/toast/table/chart"
- "React Hook Form"、"Zod 验证"、"带验证的表单"
- "可访问组件"、"Radix UI"、"Tailwind 主题"
- "shadcn button"、"shadcn dialog"、"shadcn sheet"、"shadcn table"
- "暗色模式"、"CSS 变量"、"自定义主题"
- "使用 Recharts 的图表"、"柱状图"、"折线图"、"饼图"
快速参考
可用组件
| 组件 | 安装命令 | 描述 |
|---|---|---|
button |
npx shadcn@latest add button |
变体:default、destructive、outline、secondary、ghost、link |
input |
npx shadcn@latest add input |
文本输入字段 |
form |
npx shadcn@latest add form |
集成 React Hook Form 并带验证 |
card |
npx shadcn@latest add card |
包含 header、content、footer 的容器 |
dialog |
npx shadcn@latest add dialog |
模态覆盖层 |
sheet |
npx shadcn@latest add sheet |
滑出面板(上/右/下/左) |
select |
npx shadcn@latest add select |
下拉选择 |
toast |
npx shadcn@latest add toast |
通知提示 |
table |
npx shadcn@latest add table |
数据表格 |
menubar |
npx shadcn@latest add menubar |
桌面风格菜单栏 |
chart |
npx shadcn@latest add chart |
带主题的 Recharts 封装 |
textarea |
npx shadcn@latest add textarea |
多行文本输入 |
checkbox |
npx shadcn@latest add checkbox |
复选框输入 |
label |
npx shadcn@latest add label |
可访问的表单标签 |
说明
初始化项目
# 新建 Next.js 项目
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
cd my-app
npx shadcn@latest init
# 已有项目
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
npx shadcn@latest init
# 安装组件
npx shadcn@latest add button input form card dialog select toast
基本组件用法
// 带变体和尺寸的按钮
import { Button } from "@/components/ui/button"
<Button variant="default">默认</Button>
<Button variant="destructive" size="sm">删除</Button>
<Button variant="outline" disabled>加载中...</Button>
带 Zod 验证的表单
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
email: z.string().email("无效的邮箱"),
password: z.string().min(8, "密码至少需要8个字符"),
})
export function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: { email: "", password: "" },
})
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(console.log)} className="space-y-4">
<FormField name="email" control={form.control} render={({ field }) => (
<FormItem>
<FormLabel>邮箱</FormLabel>
<FormControl><Input type="email" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField name="password" control={form.control} render={({ field }) => (
<FormItem>
<FormLabel>密码</FormLabel>
<FormControl><Input type="password" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<Button type="submit">登录</Button>
</form>
</Form>
)
}
参见 references/forms-and-validation.md 了解高级多字段表单、带 API 提交的联系表单和登录卡片模式。
对话框(模态框)
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">打开</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>编辑资料</DialogTitle>
</DialogHeader>
{/* 内容 */}
</DialogContent>
</Dialog>
Toast 通知
// 1. 在 app/layout.tsx 中添加 <Toaster />
import { Toaster } from "@/components/ui/toaster"
// 2. 在组件中使用
import { useToast } from "@/components/ui/use-toast"
const { toast } = useToast()
toast({ title: "成功", description: "更改已保存。" })
toast({ variant: "destructive", title: "错误", description: "出错了。" })
柱状图
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "桌面端", color: "var(--chart-1)" },
} satisfies import("@/components/ui/chart").ChartConfig
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={data}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
参见 references/charts-components.md 了解折线图、面积图和饼图示例。
示例
带验证的登录表单
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
email: z.string().email("无效的邮箱"),
password: z.string().min(8, "至少8个字符"),
})
export function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: { email: "", password: "" },
})
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(console.log)} className="space-y-4">
<FormField name="email" control={form.control} render={({ field }) => (
<FormItem>
<FormLabel>邮箱</FormLabel>
<FormControl><Input type="email" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField name="password" control={form.control} render={({ field }) => (
<FormItem>
<FormLabel>密码</FormLabel>
<FormControl><Input type="password" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<Button type="submit">登录</Button>
</form>
</Form>
)
}
带操作的数据表格
import { ColumnDef } from "@tanstack/react-table"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { DataTable } from "@/components/ui/data-table"
const columns: ColumnDef<User>[] = [
{ id: "select", header: ({ table }) => (
<Checkbox checked={table.getIsAllPageRowsSelected()} />
), cell: ({ row }) => (
<Checkbox checked={row.getIsSelected()} />
)},
{ accessorKey: "name", header: "姓名" },
{ accessorKey: "email", header: "邮箱" },
{ id: "actions", cell: ({ row }) => (
<Button variant="ghost" size="sm">编辑</Button>
)},
]
带表单的对话框
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">添加用户</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>添加新用户</DialogTitle>
</DialogHeader>
{/* <LoginForm /> */}
</DialogContent>
</Dialog>
Toast 通知
import { useToast } from "@/components/ui/use-toast"
import { Button } from "@/components/ui/button"
const { toast } = useToast()
toast({ title: "已保存", description: "更改已成功保存。" })
toast({ variant: "destructive", title: "错误", description: "保存失败。" })
最佳实践
- 可访问性:使用 Radix UI 原语——ARIA 属性已内置
- 客户端组件:为交互式组件(hooks、事件)添加
"use client" - 类型安全:使用 TypeScript 和 Zod 模式进行表单验证
- 主题:在
globals.css中配置 CSS 变量以实现一致的设计 - 自定义:直接修改组件文件——你拥有代码
- 路径别名:确保在
tsconfig.json中配置了@别名 - 注册表安全:仅从受信任的注册表安装组件;在生产使用前审查生成的代码
- 暗色模式:使用 CSS 变量策略和
next-themes设置 - 表单:始终一起使用
Form、FormField、FormItem、FormLabel、FormMessage - Toaster:在根布局中添加一次
<Toaster />
约束与警告
- 不是 NPM 包:组件被复制到你的项目中;它们不是版本化的依赖
- 注册表安全:从
npx shadcn@latest add获取的组件是远程获取的;在安装前始终验证注册表源是否受信任 - 客户端组件:大多数交互式组件需要
"use client"指令 - Radix 依赖:确保所有
@radix-ui包已安装 - 需要 Tailwind:组件依赖 Tailwind CSS 工具类
- 路径别名:在
tsconfig.json中配置@别名以用于导入
参考
查阅以下文件以获取详细模式和代码示例:
- references/setup-and-configuration.md — 完整安装、tsconfig、tailwind 配置、CSS 变量
- references/ui-components.md — Button、Input、Card、Dialog、Sheet、Select、Toast、Table、Menubar
- references/forms-and-validation.md — React Hook Form + Zod、高级表单、登录卡片、联系表单
- references/charts-components.md — 柱状图、折线图、面积图、饼图,带 ChartContainer 和主题
- references/nextjs-integration.md — App Router、服务器/客户端组件、暗色模式、元数据
- references/customization.md — 自定义变体、CSS 变量、cn() 工具函数、扩展组件






