shadcn-ui 是做什么的?
安装和配置 React 项目中的 shadcn/ui 组件。指导组件选择、安装顺序、依赖管理、使用语义化 token 进行定制,以及常见 UI 方案(表单、数据表格、导航、模态框)。在 tailwind-theme-builder 完成主题基础设施搭建后使用,用于添加组件、构建表单、创建数据表格或设置导航。
概述
本技能帮助你在 React 项目中安装和配置 shadcn/ui 组件。它提供逐步指导,涵盖组件选择、安装顺序、依赖管理、通过语义化 token 进行定制,以及常见 UI 方案(表单、数据表格、导航、模态框)。建议在 tailwind-theme-builder 技能完成主题基础设施搭建后再运行此技能。
组件安装
安装 shadcn/ui CLI
npx shadcn@latest init
安装组件
npx shadcn@latest add [component-name]
示例:
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add form
安装顺序
推荐安装顺序:
- 基础组件:
button,card,input,label - 布局组件:
container,grid,flex - 表单组件:
form,select,checkbox,radio-group - 反馈组件:
dialog,alert,toast - 导航组件:
navigation-menu,tabs,breadcrumb - 数据表格:
table,pagination,dropdown-menu
依赖管理
shadcn/ui 依赖以下包:
react(>=18)react-dom(>=18)tailwindcss(>=3.4)tailwind-mergeclass-variance-authorityclsx
通过语义化 token 定制主题
无需手动编辑 CSS 变量,使用语义化 token 进行定制:
export const themeTokens = {
colors: {
primary: {
DEFAULT: '#3b82f6',
foreground: '#ffffff',
},
secondary: {
DEFAULT: '#6b7280',
foreground: '#ffffff',
},
destructive: {
DEFAULT: '#ef4444',
foreground: '#ffffff',
},
},
};
常见 UI 方案
表单
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function LoginForm() {
return (
<form>
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">邮箱</Label>
<Input type="email" id="email" placeholder="请输入邮箱" />
</div>
<div className="grid w-full max-w-sm items-center gap-1.5 mt-4">
<Label htmlFor="password">密码</Label>
<Input type="password" id="password" placeholder="请输入密码" />
</div>
<Button type="submit" className="mt-4">登录</Button>
</form>
)
}
数据表格
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
export function DataTable() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>姓名</TableHead>
<TableHead>邮箱</TableHead>
<TableHead>角色</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>张三</TableCell>
<TableCell>[email protected]</TableCell>
<TableCell>管理员</TableCell>
</TableRow>
</TableBody>
</Table>
)
}
导航
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
} from "@/components/ui/navigation-menu"
export function Navigation() {
return (
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink href="/">首页</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="/about">关于</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="/contact">联系</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
)
}
模态框
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
export function ConfirmDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">打开对话框</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>确认操作</DialogTitle>
<DialogDescription>
你确定要执行此操作吗?此操作无法撤销。
</DialogDescription>
</DialogHeader>
<div className="flex justify-end gap-4">
<Button variant="outline">取消</Button>
<Button variant="destructive">确认</Button>
</div>
</DialogContent>
</Dialog>
)
}
最佳实践
- 保持组件简单:仅安装你需要的组件
- 遵循命名约定:使用 shadcn/ui 默认的命名空间
- 使用语义化 token:利用 CSS 变量实现主题一致性
- 顺序安装:按照依赖顺序安装组件以避免冲突
- 测试:在集成后始终测试组件行为