shadcn-ui-expert
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseshadcn-ui Expert
shadcn-ui 专家指南
shadcn-ui is a collection of beautifully-designed, accessible React components built with TypeScript, Tailwind CSS, and Radix UI primitives. This skill guides you through component selection, implementation, customization, and best practices.
shadcn-ui是一套使用TypeScript、Tailwind CSS和Radix UI原语构建的设计精美、具备可访问性的React组件集合。本指南将指导你完成组件选择、实现、自定义及最佳实践。
Quick Start
快速开始
Installation
安装
First, initialize shadcn-ui in your project:
bash
npx shadcn-ui@latest initThis creates a file for configuration. Choose your framework:
components.json- Next.js (App Router recommended)
- Vite
- Remix
- Astro
- Laravel
- Gatsby
- React Router
- TanStack Router/Start
首先,在你的项目中初始化shadcn-ui:
bash
npx shadcn-ui@latest init这会创建一个配置文件。选择你的框架:
components.json- Next.js(推荐使用App Router)
- Vite
- Remix
- Astro
- Laravel
- Gatsby
- React Router
- TanStack Router/Start
Installing Components
安装组件
Use the CLI to install individual components:
bash
undefined使用CLI安装单个组件:
bash
undefinedInstall a button component
安装按钮组件
npx shadcn-ui@latest add button
npx shadcn-ui@latest add button
Install form components
安装表单组件
npx shadcn-ui@latest add form input select checkbox
npx shadcn-ui@latest add form input select checkbox
Install a data table
安装数据表格
npx shadcn-ui@latest add data-table
Or ask me directly to "add a login form" - I can use the MCP server to handle installation with natural language.npx shadcn-ui@latest add data-table
或者直接告诉我“添加登录表单”——我可以使用MCP服务器通过自然语言处理安装操作。Component Categories
组件分类
Form & Input Components
表单与输入组件
Use for: Data collection, user input, validation
- - Complex forms with React Hook Form
form - - Text fields
input - - Multi-line text
textarea - - Dropdown selections
select - - Boolean inputs
checkbox - - Single selection from options
radio-group - - Toggle boolean states
switch - - Date selection
date-picker - - Searchable select with autocomplete
combobox
适用场景:数据收集、用户输入、验证
- - 基于React Hook Form的复杂表单
form - - 文本输入框
input - - 多行文本框
textarea - - 下拉选择器
select - - 布尔值输入框
checkbox - - 单选选项组
radio-group - - 布尔值切换开关
switch - - 日期选择器
date-picker - - 带自动补全的可搜索选择器
combobox
Layout & Navigation
布局与导航
Use for: App structure, navigation flows, content organization
- - Collapsible side navigation
sidebar - - Tabbed content
tabs - - Collapsible sections
accordion - - Navigation path
breadcrumb - - Dropdown menus
navigation-menu - - Custom scrollable regions
scroll-area
适用场景:应用结构、导航流程、内容组织
- - 可折叠侧边导航
sidebar - - 标签页内容
tabs - - 可折叠区块
accordion - - 导航路径
breadcrumb - - 下拉菜单
navigation-menu - - 自定义可滚动区域
scroll-area
Overlays & Dialogs
浮层与对话框
Use for: Modals, confirmations, floating content
- - Modal dialogs
dialog - - Confirmation prompts
alert-dialog - - Mobile-friendly side panels
drawer - - Floating popovers
popover - - Hover information
tooltip - - Menu dropdowns
dropdown-menu - - Right-click menus
context-menu
适用场景:模态框、确认提示、浮动内容
- - 模态对话框
dialog - - 确认提示框
alert-dialog - - 移动端友好的侧边面板
drawer - - 浮动弹出框
popover - - 悬停提示信息
tooltip - - 下拉菜单
dropdown-menu - - 右键菜单
context-menu
Data Display
数据展示
Use for: Showing structured data
- - Basic HTML tables
table - - Advanced tables with sorting/filtering/pagination
data-table - - User profile images
avatar - - Status labels
badge - - Content containers
card
适用场景:展示结构化数据
- - 基础HTML表格
table - - 支持排序/筛选/分页的高级表格
data-table - - 用户头像
avatar - - 状态标签
badge - - 内容容器
card
Feedback & Status
反馈与状态
Use for: User feedback, loading states, alerts
- - Alert messages
alert - - Notifications
toast - - Progress bars
progress - - Loading placeholders
skeleton - - Loading indicators
spinner
适用场景:用户反馈、加载状态、提醒
- - 提醒消息
alert - - 通知提示
toast - - 进度条
progress - - 加载占位符
skeleton - - 加载指示器
spinner
Component Selection Guide
组件选择指南
Ask yourself these questions to choose the right component:
-
What is the user interacting with?
- Text input → use
input - Choosing from options → use or
selectcombobox - Yes/no decision → use or
checkboxswitch - Multiple fields → use
form
- Text input → use
-
How should it be displayed?
- Inline with other content → ,
inputselect - Centered on screen →
dialog - Slide from side →
drawer - Information tooltip →
tooltip
- Inline with other content →
-
What's the context?
- Inside a form → use component with
fieldform - Standalone button → use
button - Inside a table → use table row cell or
data-table
- Inside a form → use
-
Does it need validation?
- Yes → combine +
form+ React Hook Formfield - No → use simple components (,
input)select
- Yes → combine
通过以下问题选择合适的组件:
-
用户需要进行什么交互?
- 文本输入 → 使用
input - 从选项中选择 → 使用或
selectcombobox - 是/否选择 → 使用或
checkboxswitch - 多个输入字段 → 使用
form
- 文本输入 → 使用
-
组件应该如何展示?
- 与其他内容内联 → 、
inputselect - 居中显示在屏幕上 →
dialog - 从侧边滑入 →
drawer - 悬停显示信息 →
tooltip
- 与其他内容内联 →
-
使用场景是什么?
- 在表单内 → 结合组件与
field使用form - 独立按钮 → 使用
button - 在表格内 → 使用表格单元格或
data-table
- 在表单内 → 结合
-
是否需要验证?
- 是 → 结合+
form+ React Hook Formfield - 否 → 使用简单组件(、
input)select
- 是 → 结合
Common Implementation Patterns
常见实现模式
Basic Form with Validation
带验证的基础表单
tsx
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Form, FormField, FormItem, FormLabel, FormControl } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
export function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="you@example.com" {...field} />
</FormControl>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}tsx
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Form, FormField, FormItem, FormLabel, FormControl } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
export function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="you@example.com" {...field} />
</FormControl>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}Dialog Pattern
对话框模式
tsx
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
export function DeleteDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">Delete</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
This action cannot be undone.
</DialogDescription>
</DialogHeader>
<div className="flex gap-3 justify-end">
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Delete</Button>
</div>
</DialogContent>
</Dialog>
)
}tsx
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
export function DeleteDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">Delete</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
This action cannot be undone.
</DialogDescription>
</DialogHeader>
<div className="flex gap-3 justify-end">
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Delete</Button>
</div>
</DialogContent>
</Dialog>
)
}Styling & Customization
样式与自定义
All components use Tailwind CSS for styling. Customize appearance through:
所有组件均使用Tailwind CSS进行样式设置。可通过以下方式自定义外观:
1. Tailwind Classes
1. Tailwind 类名
Add classes directly to components:
tsx
<Button className="w-full text-lg">Full Width</Button>
<Input className="rounded-lg border-2" />直接为组件添加类名:
tsx
<Button className="w-full text-lg">Full Width</Button>
<Input className="rounded-lg border-2" />2. CSS Variables (Theme Colors)
2. CSS变量(主题颜色)
shadcn/ui uses CSS variables for theming. Edit :
app/globals.csscss
@layer base {
:root {
--primary: 222.2 47.4% 11.2%;
--secondary: 210 40% 96%;
}
}shadcn/ui使用CSS变量进行主题设置。编辑:
app/globals.csscss
@layer base {
:root {
--primary: 222.2 47.4% 11.2%;
--secondary: 210 40% 96%;
}
}3. Dark Mode
3. 暗黑模式
Enable dark mode in your framework:
- Next.js: Configure in
next.config.js - Vite: Add dark class detection in
tailwind.config.js - Components automatically respond to class
dark
在你的框架中启用暗黑模式:
- Next.js:在中配置
next.config.js - Vite:在中添加暗黑类检测
tailwind.config.js - 组件会自动响应类
dark
4. Component Variants
4. 组件变体
Many components have built-in variants:
tsx
<Button variant="outline" />
<Button variant="ghost" />
<Button variant="destructive" />
<Badge variant="secondary" />许多组件内置多种变体:
tsx
<Button variant="outline" />
<Button variant="ghost" />
<Button variant="destructive" />
<Badge variant="secondary" />Composition & Best Practices
组合与最佳实践
1. Composition Over Customization
1. 优先组合而非自定义
Combine small components rather than modifying large ones:
tsx
// ✅ Good: Compose components
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
<Form>...</Form>
</CardContent>
</Card>
// ❌ Avoid: Over-modifying single component
<CustomDialog withHeader={true} withForm={true} />组合小型组件而非修改大型组件:
tsx
// ✅ 推荐:组合组件
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
<Form>...</Form>
</CardContent>
</Card>
// ❌ 避免:过度修改单个组件
<CustomDialog withHeader={true} withForm={true} />2. Use Type Safety
2. 使用类型安全
Leverage TypeScript for prop safety:
tsx
import { Button } from "@/components/ui/button"
import type { ButtonProps } from "@/components/ui/button"
type CustomButtonProps = ButtonProps & {
label: string
}利用TypeScript确保属性安全:
tsx
import { Button } from "@/components/ui/button"
import type { ButtonProps } from "@/components/ui/button"
type CustomButtonProps = ButtonProps & {
label: string
}3. Accessibility Built-in
3. 内置可访问性
shadcn/ui uses Radix UI primitives with accessibility built-in:
- Keyboard navigation
- ARIA attributes
- Screen reader support
- Focus management
Just use components correctly; accessibility comes free.
shadcn-ui使用Radix UI原语,内置可访问性支持:
- 键盘导航
- ARIA属性
- 屏幕阅读器支持
- 焦点管理
只需正确使用组件,即可获得内置的可访问性支持。
4. Performance
4. 性能
- Components are small and modular
- Tree-shakeable
- No runtime overhead beyond Radix UI
- Use for frequently-rerendered components if needed
React.memo
- 组件小巧且模块化
- 支持摇树优化
- 除Radix UI外无额外运行时开销
- 若需要,可对频繁重渲染的组件使用
React.memo
Framework-Specific Notes
框架特定说明
Next.js
Next.js
- Use for React Hook Form integration
shadcn-ui@latest add form - Combine with Server Actions for form submissions
- Dark mode works via
next-themes
- 使用集成React Hook Form
shadcn-ui@latest add form - 结合Server Actions处理表单提交
- 暗黑模式可通过实现
next-themes
Vite
Vite
- Ensure includes component paths
tailwind.config.js - Use Vite's HMR for fast development
- 确保包含组件路径
tailwind.config.js - 使用Vite的HMR实现快速开发
Remix
Remix
- Forms work with form actions
remix - Use route transitions for optimistic updates
- 表单可与表单操作配合使用
remix - 使用路由过渡实现乐观更新
Common Customization Tasks
常见自定义任务
Changing Primary Color
修改主色调
Edit during init or manually update CSS variables in .
components.jsonglobals.css在初始化时编辑,或手动更新中的CSS变量。
components.jsonglobals.cssAdding Custom Components
添加自定义组件
Create your own components in following shadcn/ui patterns:
components/ui/tsx
// components/ui/my-component.tsx
import * as React from "react"
export interface MyComponentProps
extends React.HTMLAttributes<HTMLDivElement> {}
const MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>(
({ className, ...props }, ref) => (
<div
ref={ref}
className={className}
{...props}
/>
)
)
MyComponent.displayName = "MyComponent"
export { MyComponent }按照shadcn-ui的模式在目录下创建自己的组件:
components/ui/tsx
// components/ui/my-component.tsx
import * as React from "react"
export interface MyComponentProps
extends React.HTMLAttributes<HTMLDivElement> {}
const MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>(
({ className, ...props }, ref) => (
<div
ref={ref}
className={className}
{...props}
/>
)
)
MyComponent.displayName = "MyComponent"
export { MyComponent }Theming for Multiple Brands
多品牌主题
Use CSS variable layers:
css
.brand-a {
--primary: 220 90% 56%;
--secondary: 0 0% 100%;
}
.brand-b {
--primary: 0 100% 50%;
--secondary: 200 100% 50%;
}使用CSS变量层级:
css
.brand-a {
--primary: 220 90% 56%;
--secondary: 0 0% 100%;
}
.brand-b {
--primary: 0 100% 50%;
--secondary: 200 100% 50%;
}Validation & Forms
验证与表单
With React Hook Form + Zod
结合React Hook Form + Zod
Best practice for complex forms with client-side validation:
bash
npm install react-hook-form zod @hookform/resolvers这是构建带客户端验证的复杂表单的最佳实践:
bash
npm install react-hook-form zod @hookform/resolversWith TanStack Form
结合TanStack Form
Alternative for advanced form requirements:
bash
npm install @tanstack/react-formAsk me for specific form patterns (login, signup, multi-step, etc.)
针对高级表单需求的替代方案:
bash
npm install @tanstack/react-form如需特定表单模式(登录、注册、多步骤等),可随时咨询我。
Troubleshooting
故障排除
Components Not Styling Correctly
组件样式未正确显示
- ✅ Verify Tailwind is configured in
tailwind.config.js - ✅ Check has correct
components.jsonsettingpath - ✅ Run after adding components
npm install
- ✅ 验证中已配置Tailwind
tailwind.config.js - ✅ 检查中的
components.json设置是否正确path - ✅ 添加组件后运行
npm install
TypeScript Errors
TypeScript错误
- ✅ Ensure components are imported from
/components/ui/name - ✅ Components have proper TypeScript support built-in
- ✅ 确保组件从导入
/components/ui/name - ✅ 组件内置完善的TypeScript支持
Form Validation Not Working
表单验证不生效
- ✅ Install and
zod@hookform/resolvers - ✅ Use with
zodResolveruseForm
- ✅ 安装和
zod@hookform/resolvers - ✅ 在中使用
useFormzodResolver
Next Steps
下一步
For detailed guidance on specific tasks:
- COMPONENT_GUIDE.md - Deep dive into each component
- FORMS_GUIDE.md - Building complex forms
- PATTERNS.md - Common UI patterns and combinations
- CUSTOMIZATION.md - Theming and styling guide
如需特定任务的详细指导:
- COMPONENT_GUIDE.md - 深入了解每个组件
- FORMS_GUIDE.md - 构建复杂表单
- PATTERNS.md - 常见UI模式与组合
- CUSTOMIZATION.md - 主题与样式指南