shadcn-ui

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

shadcn/ui

shadcn/ui

Copy-paste component library built on Radix UI + Tailwind CSS. Components are NOT imported from a package—they're copied into your project for full ownership.
基于Radix UI + Tailwind CSS构建的复制粘贴式组件库。组件并非从包中导入——而是直接复制到你的项目中,让你拥有完全的控制权。

Quick Reference

快速参考

bash
undefined
bash
undefined

Initialize project

初始化项目

npx shadcn@latest init
npx shadcn@latest init

Add components

添加组件

npx shadcn@latest add button card dialog
npx shadcn@latest add button card dialog

Add all components

添加所有组件

npx shadcn@latest add -a
npx shadcn@latest add -a

View component source before adding

添加前查看组件源码

npx shadcn@latest view button
undefined
npx shadcn@latest view button
undefined

CLI Commands

CLI命令

init

init

bash
npx shadcn@latest init [options]

Options:
  -t, --template <template>    # next, vite, start, next-monorepo
  -b, --base-color <color>     # neutral, gray, zinc, stone, slate
  --css-variables              # Use CSS variables (default)
  --no-css-variables           # Inline Tailwind classes
  -y, --yes                    # Skip prompts
bash
npx shadcn@latest init [options]

选项:
  -t, --template <template>    # next, vite, start, next-monorepo
  -b, --base-color <color>     # neutral, gray, zinc, stone, slate
  --css-variables              # 使用CSS变量(默认)
  --no-css-variables           # 内联Tailwind类
  -y, --yes                    # 跳过提示

add

add

bash
npx shadcn@latest add [components...]

Options:
  -y, --yes          # Skip confirmation
  -o, --overwrite    # Overwrite existing
  -a, --all          # Add all components
  -p, --path <path>  # Custom install path
bash
npx shadcn@latest add [components...]

选项:
  -y, --yes          # 跳过确认
  -o, --overwrite    # 覆盖现有组件
  -a, --all          # 添加所有组件
  -p, --path <path>  # 自定义安装路径

Theming System

主题系统

shadcn/ui uses CSS variables with OKLCH color format for perceptual uniformity.
shadcn/ui采用CSS变量结合OKLCH色彩格式,实现感知上的色彩一致性。

CSS Variables Structure

CSS变量结构

css
/* app/globals.css */
:root {
  --radius: 0.625rem;
  
  /* Semantic colors */
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.985 0 0);
  --primary-foreground: oklch(0.205 0 0);
  /* ... inverted values */
}

/* Map to Tailwind */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  /* ... all semantic colors */
}
css
/* app/globals.css */
:root {
  --radius: 0.625rem;
  
  /* 语义化颜色 */
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.985 0 0);
  --primary-foreground: oklch(0.205 0 0);
  /* ... 反转后的数值 */
}

/* 映射到Tailwind */
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  /* ... 所有语义化颜色 */
}

OKLCH Format

OKLCH格式

oklch(lightness chroma hue)
     0-1       0-0.4   0-360°
  • Lightness: 0 = black, 1 = white
  • Chroma: 0 = gray, higher = more saturated
  • Hue: Color angle (0=red, 120=green, 240=blue)
oklch(lightness chroma hue)
     0-1       0-0.4   0-360°
  • Lightness(亮度): 0 = 黑色, 1 = 白色
  • Chroma(彩度): 0 = 灰色, 值越高饱和度越高
  • Hue(色相): 颜色角度 (0=红色, 120=绿色, 240=蓝色)

Adding Custom Colors

添加自定义颜色

css
:root {
  --warning: oklch(0.84 0.16 84);
  --warning-foreground: oklch(0.28 0.07 46);
}

.dark {
  --warning: oklch(0.41 0.11 46);
  --warning-foreground: oklch(0.99 0.02 95);
}

@theme inline {
  --color-warning: var(--warning);
  --color-warning-foreground: var(--warning-foreground);
}
Usage:
className="bg-warning text-warning-foreground"
css
:root {
  --warning: oklch(0.84 0.16 84);
  --warning-foreground: oklch(0.28 0.07 46);
}

.dark {
  --warning: oklch(0.41 0.11 46);
  --warning-foreground: oklch(0.99 0.02 95);
}

@theme inline {
  --color-warning: var(--warning);
  --color-warning-foreground: var(--warning-foreground);
}
使用方式:
className="bg-warning text-warning-foreground"

Base Color Palettes

基础色调板

Choose in
components.json
:
  • neutral: Pure achromatic
  • stone: Warm grayscale
  • zinc: Cool grayscale
  • gray: Balanced with slight tint
  • slate: Blue-tinted gray
components.json
中选择:
  • neutral: 纯无彩色
  • stone: 暖灰色调
  • zinc: 冷灰色调
  • gray: 平衡色调,略带色彩倾向
  • slate: 偏蓝灰色调

Configuration

配置

components.json

components.json

json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "iconLibrary": "lucide"
}
json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "iconLibrary": "lucide"
}

Component Patterns

组件模式

CVA Variants

CVA变体

Components use class-variance-authority for variant management:
tsx
import { cva, type VariantProps } from "class-variance-authority"

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium transition-all disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-white hover:bg-destructive/90",
        outline: "border bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3 text-xs",
        lg: "h-10 px-6",
        icon: "h-9 w-9",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)
组件使用class-variance-authority进行变体管理:
tsx
import { cva, type VariantProps } from "class-variance-authority"

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium transition-all disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-white hover:bg-destructive/90",
        outline: "border bg-background hover:bg-accent",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 px-3 text-xs",
        lg: "h-10 px-6",
        icon: "h-9 w-9",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

cn Utility

cn工具函数

Merges classes intelligently, resolving Tailwind conflicts:
tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
智能合并类名,解决Tailwind类名冲突:
tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Compound Components

复合组件

tsx
<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
    <CardDescription>Description</CardDescription>
  </CardHeader>
  <CardContent>Content here</CardContent>
  <CardFooter>Footer actions</CardFooter>
</Card>
tsx
<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
    <CardDescription>Description</CardDescription>
  </CardHeader>
  <CardContent>Content here</CardContent>
  <CardFooter>Footer actions</CardFooter>
</Card>

Data Attributes

数据属性

Components include
data-slot
for semantic styling:
tsx
<div data-slot="card" className={cn(...)}>
<button data-slot="button" data-variant="default">
组件包含
data-slot
用于语义化样式:
tsx
<div data-slot="card" className={cn(...)}>
<button data-slot="button" data-variant="default">

Customization

自定义

Override Component Styles

覆盖组件样式

tsx
// The className prop merges with defaults
<Button className="w-full rounded-full" />
tsx
// className属性会与默认样式合并
<Button className="w-full rounded-full" />

Extend Variants

扩展变体

Edit the component file directly:
tsx
const buttonVariants = cva(baseClasses, {
  variants: {
    variant: {
      // existing...
      success: "bg-green-600 text-white hover:bg-green-700",
    },
  },
})
直接编辑组件文件:
tsx
const buttonVariants = cva(baseClasses, {
  variants: {
    variant: {
      // 现有变体...
      success: "bg-green-600 text-white hover:bg-green-700",
    },
  },
})

Dark Mode

暗黑模式

Uses class strategy. Toggle
.dark
on html/body:
tsx
// Toggle dark mode
document.documentElement.classList.toggle('dark')
采用类策略。在html/body上切换
.dark
类:
tsx
// 切换暗黑模式
document.documentElement.classList.toggle('dark')

Dependencies

依赖

Required packages (installed by init):
  • class-variance-authority
    - Variant management
  • clsx
    - Class concatenation
  • tailwind-merge
    - Conflict resolution
  • lucide-react
    - Icons
  • tw-animate-css
    - Animations
  • @radix-ui/*
    - Accessible primitives (per component)
初始化时自动安装的必备包:
  • class-variance-authority
    - 变体管理
  • clsx
    - 类名拼接
  • tailwind-merge
    - 冲突解决
  • lucide-react
    - 图标库
  • tw-animate-css
    - 动画库
  • @radix-ui/*
    - 无障碍基础组件(按需安装)

Common Tasks

常见任务

Change Theme Colors

修改主题颜色

  1. Edit CSS variables in
    globals.css
  2. Both
    :root
    (light) and
    .dark
    (dark) selectors
  3. Use OKLCH values for best results
  1. 编辑
    globals.css
    中的CSS变量
  2. 同时修改
    :root
    (亮色模式)和
    .dark
    (暗色模式)选择器下的变量
  3. 建议使用OKLCH格式的值以获得最佳效果

Add New Semantic Color

添加新的语义化颜色

  1. Define CSS variable in
    :root
    and
    .dark
  2. Map in
    @theme inline
    block
  3. Use with Tailwind:
    bg-{name} text-{name}-foreground
  1. :root
    .dark
    中定义CSS变量
  2. @theme inline
    块中完成映射
  3. 使用Tailwind类名:
    bg-{name} text-{name}-foreground

Switch Base Palette

切换基础色调板

Update
components.json
:
json
"tailwind": {
  "baseColor": "zinc"
}
Then re-run
npx shadcn@latest init
or manually update CSS variables.
更新
components.json
:
json
"tailwind": {
  "baseColor": "zinc"
}
然后重新运行
npx shadcn@latest init
或手动更新CSS变量。

Attribution

致谢

Based on shadcn/ui by shadcn.
基于shadcn/ui by shadcn。