shadcn-ui-expert

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

shadcn-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 init
This creates a
components.json
file for configuration. Choose your framework:
  • 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
undefined

Install 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
  • form
    - Complex forms with React Hook Form
  • input
    - Text fields
  • textarea
    - Multi-line text
  • select
    - Dropdown selections
  • checkbox
    - Boolean inputs
  • radio-group
    - Single selection from options
  • switch
    - Toggle boolean states
  • date-picker
    - Date selection
  • combobox
    - Searchable select with autocomplete
适用场景:数据收集、用户输入、验证
  • form
    - 基于React Hook Form的复杂表单
  • input
    - 文本输入框
  • textarea
    - 多行文本框
  • select
    - 下拉选择器
  • checkbox
    - 布尔值输入框
  • radio-group
    - 单选选项组
  • switch
    - 布尔值切换开关
  • date-picker
    - 日期选择器
  • combobox
    - 带自动补全的可搜索选择器

Layout & Navigation

布局与导航

Use for: App structure, navigation flows, content organization
  • sidebar
    - Collapsible side navigation
  • tabs
    - Tabbed content
  • accordion
    - Collapsible sections
  • breadcrumb
    - Navigation path
  • navigation-menu
    - Dropdown menus
  • scroll-area
    - Custom scrollable regions
适用场景:应用结构、导航流程、内容组织
  • sidebar
    - 可折叠侧边导航
  • tabs
    - 标签页内容
  • accordion
    - 可折叠区块
  • breadcrumb
    - 导航路径
  • navigation-menu
    - 下拉菜单
  • scroll-area
    - 自定义可滚动区域

Overlays & Dialogs

浮层与对话框

Use for: Modals, confirmations, floating content
  • dialog
    - Modal dialogs
  • alert-dialog
    - Confirmation prompts
  • drawer
    - Mobile-friendly side panels
  • popover
    - Floating popovers
  • tooltip
    - Hover information
  • dropdown-menu
    - Menu dropdowns
  • context-menu
    - Right-click menus
适用场景:模态框、确认提示、浮动内容
  • dialog
    - 模态对话框
  • alert-dialog
    - 确认提示框
  • drawer
    - 移动端友好的侧边面板
  • popover
    - 浮动弹出框
  • tooltip
    - 悬停提示信息
  • dropdown-menu
    - 下拉菜单
  • context-menu
    - 右键菜单

Data Display

数据展示

Use for: Showing structured data
  • table
    - Basic HTML tables
  • data-table
    - Advanced tables with sorting/filtering/pagination
  • avatar
    - User profile images
  • badge
    - Status labels
  • card
    - Content containers
适用场景:展示结构化数据
  • table
    - 基础HTML表格
  • data-table
    - 支持排序/筛选/分页的高级表格
  • avatar
    - 用户头像
  • badge
    - 状态标签
  • card
    - 内容容器

Feedback & Status

反馈与状态

Use for: User feedback, loading states, alerts
  • alert
    - Alert messages
  • toast
    - Notifications
  • progress
    - Progress bars
  • skeleton
    - Loading placeholders
  • spinner
    - Loading indicators
适用场景:用户反馈、加载状态、提醒
  • alert
    - 提醒消息
  • toast
    - 通知提示
  • progress
    - 进度条
  • skeleton
    - 加载占位符
  • spinner
    - 加载指示器

Component Selection Guide

组件选择指南

Ask yourself these questions to choose the right component:
  1. What is the user interacting with?
    • Text input → use
      input
    • Choosing from options → use
      select
      or
      combobox
    • Yes/no decision → use
      checkbox
      or
      switch
    • Multiple fields → use
      form
  2. How should it be displayed?
    • Inline with other content →
      input
      ,
      select
    • Centered on screen →
      dialog
    • Slide from side →
      drawer
    • Information tooltip →
      tooltip
  3. What's the context?
    • Inside a form → use
      field
      component with
      form
    • Standalone button → use
      button
    • Inside a table → use table row cell or
      data-table
  4. Does it need validation?
    • Yes → combine
      form
      +
      field
      + React Hook Form
    • No → use simple components (
      input
      ,
      select
      )
通过以下问题选择合适的组件:
  1. 用户需要进行什么交互?
    • 文本输入 → 使用
      input
    • 从选项中选择 → 使用
      select
      combobox
    • 是/否选择 → 使用
      checkbox
      switch
    • 多个输入字段 → 使用
      form
  2. 组件应该如何展示?
    • 与其他内容内联 →
      input
      select
    • 居中显示在屏幕上 →
      dialog
    • 从侧边滑入 →
      drawer
    • 悬停显示信息 →
      tooltip
  3. 使用场景是什么?
    • 在表单内 → 结合
      field
      组件与
      form
      使用
    • 独立按钮 → 使用
      button
    • 在表格内 → 使用表格单元格或
      data-table
  4. 是否需要验证?
    • 是 → 结合
      form
      +
      field
      + React Hook Form
    • 否 → 使用简单组件(
      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.css
:
css
@layer base {
  :root {
    --primary: 222.2 47.4% 11.2%;
    --secondary: 210 40% 96%;
  }
}
shadcn/ui使用CSS变量进行主题设置。编辑
app/globals.css
css
@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
    dark
    class
在你的框架中启用暗黑模式:
  • 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
    React.memo
    for frequently-rerendered components if needed
  • 组件小巧且模块化
  • 支持摇树优化
  • 除Radix UI外无额外运行时开销
  • 若需要,可对频繁重渲染的组件使用
    React.memo

Framework-Specific Notes

框架特定说明

Next.js

Next.js

  • Use
    shadcn-ui@latest add form
    for React Hook Form integration
  • Combine with Server Actions for form submissions
  • Dark mode works via
    next-themes
  • 使用
    shadcn-ui@latest add form
    集成React Hook Form
  • 结合Server Actions处理表单提交
  • 暗黑模式可通过
    next-themes
    实现

Vite

Vite

  • Ensure
    tailwind.config.js
    includes component paths
  • Use Vite's HMR for fast development
  • 确保
    tailwind.config.js
    包含组件路径
  • 使用Vite的HMR实现快速开发

Remix

Remix

  • Forms work with
    remix
    form actions
  • Use route transitions for optimistic updates
  • 表单可与
    remix
    表单操作配合使用
  • 使用路由过渡实现乐观更新

Common Customization Tasks

常见自定义任务

Changing Primary Color

修改主色调

Edit
components.json
during init or manually update CSS variables in
globals.css
.
在初始化时编辑
components.json
,或手动更新
globals.css
中的CSS变量。

Adding Custom Components

添加自定义组件

Create your own components in
components/ui/
following shadcn/ui patterns:
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/resolvers

With TanStack Form

结合TanStack Form

Alternative for advanced form requirements:
bash
npm install @tanstack/react-form
Ask 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
    components.json
    has correct
    path
    setting
  • ✅ Run
    npm install
    after adding components
  • ✅ 验证
    tailwind.config.js
    中已配置Tailwind
  • ✅ 检查
    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
    zod
    and
    @hookform/resolvers
  • ✅ Use
    zodResolver
    with
    useForm
  • ✅ 安装
    zod
    @hookform/resolvers
  • ✅ 在
    useForm
    中使用
    zodResolver

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 - 主题与样式指南

Resources

资源