210 lines
5.9 KiB
Markdown
210 lines
5.9 KiB
Markdown
---
|
||
name: customization-theming
|
||
description: shadcn/ui 定制与主题系统文档
|
||
metadata:
|
||
type: reference
|
||
---
|
||
|
||
# 定制与主题
|
||
|
||
组件引用语义化的 CSS 变量令牌。修改变量即可更改所有组件。
|
||
|
||
## 目录
|
||
|
||
- 工作原理(CSS 变量 → Tailwind 工具类 → 组件)
|
||
- 颜色变量与 OKLCH 格式
|
||
- 深色模式设置
|
||
- 更改主题(预设、CSS 变量)
|
||
- 添加自定义颜色(Tailwind v3 和 v4)
|
||
- 边框圆角
|
||
- 定制组件(变体、className、包装器)
|
||
- 检查更新
|
||
|
||
---
|
||
|
||
## 工作原理
|
||
|
||
1. 在 `:root`(浅色)和 `.dark`(深色模式)中定义 CSS 变量。
|
||
2. Tailwind 将其映射为工具类:`bg-primary`、`text-muted-foreground` 等。
|
||
3. 组件使用这些工具类——更改某个变量即可更改所有引用它的组件。
|
||
|
||
---
|
||
|
||
## 颜色变量
|
||
|
||
每种颜色遵循 `name` / `name-foreground` 命名约定。基础变量用于背景,`-foreground` 用于该背景上的文本/图标。
|
||
|
||
| 变量 | 用途 |
|
||
| -------------------------------------------- | -------------------------------- |
|
||
| `--background` / `--foreground` | 页面背景与默认文本 |
|
||
| `--card` / `--card-foreground` | 卡片表面 |
|
||
| `--primary` / `--primary-foreground` | 主要按钮与操作 |
|
||
| `--secondary` / `--secondary-foreground` | 次要操作 |
|
||
| `--muted` / `--muted-foreground` | 弱化/禁用状态 |
|
||
| `--accent` / `--accent-foreground` | 悬停与强调状态 |
|
||
| `--destructive` / `--destructive-foreground` | 错误与破坏性操作 |
|
||
| `--border` | 默认边框颜色 |
|
||
| `--input` | 表单输入边框 |
|
||
| `--ring` | 聚焦环颜色 |
|
||
| `--chart-1` 至 `--chart-5` | 图表/数据可视化 |
|
||
| `--sidebar-*` | 侧边栏专用颜色 |
|
||
| `--surface` / `--surface-foreground` | 次级表面 |
|
||
|
||
颜色使用 OKLCH 格式:`--primary: oklch(0.205 0 0)`,其中各值分别为明度(0–1)、色度(0 = 灰色)和色相(0–360)。
|
||
|
||
---
|
||
|
||
## 深色模式
|
||
|
||
通过根元素上的 `.dark` 类进行切换。在 Next.js 中,使用 `next-themes`:
|
||
|
||
```tsx
|
||
import { ThemeProvider } from "next-themes"
|
||
|
||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||
{children}
|
||
</ThemeProvider>
|
||
```
|
||
|
||
---
|
||
|
||
## 更改主题
|
||
|
||
```bash
|
||
# 应用来自 ui.shadcn.com 的预设代码。
|
||
npx shadcn@latest init --preset a2r6bw --force
|
||
|
||
# 切换到命名预设。
|
||
npx shadcn@latest init --preset radix-nova --force
|
||
npx shadcn@latest init --reinstall # 更新现有组件以匹配
|
||
|
||
# 使用自定义主题 URL。
|
||
npx shadcn@latest init --preset "https://ui.shadcn.com/init?base=radix&style=nova&theme=blue&..." --force
|
||
```
|
||
|
||
或者直接在 `globals.css` 中编辑 CSS 变量。
|
||
|
||
---
|
||
|
||
## 添加自定义颜色
|
||
|
||
将变量添加到 `npx shadcn@latest info` 返回的 `tailwindCssFile` 所指向的文件中(通常为 `globals.css`)。切勿为此创建新的 CSS 文件。
|
||
|
||
```css
|
||
/* 1. 在全局 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);
|
||
}
|
||
```
|
||
|
||
```css
|
||
/* 2a. 在 Tailwind v4 中注册(@theme inline)。 */
|
||
@theme inline {
|
||
--color-warning: var(--warning);
|
||
--color-warning-foreground: var(--warning-foreground);
|
||
}
|
||
```
|
||
|
||
当 `tailwindVersion` 为 `"v3"` 时(通过 `npx shadcn@latest info` 检查),改为在 `tailwind.config.js` 中注册:
|
||
|
||
```js
|
||
// 2b. 在 Tailwind v3 中注册(tailwind.config.js)。
|
||
module.exports = {
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
warning: "oklch(var(--warning) / <alpha-value>)",
|
||
"warning-foreground":
|
||
"oklch(var(--warning-foreground) / <alpha-value>)",
|
||
},
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
```tsx
|
||
// 3. 在组件中使用。
|
||
<div className="bg-warning text-warning-foreground">Warning</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 边框圆角
|
||
|
||
`--radius` 全局控制边框圆角。组件从其派生值(`rounded-lg` = `var(--radius)`,`rounded-md` = `calc(var(--radius) - 2px)`)。
|
||
|
||
---
|
||
|
||
## 定制组件
|
||
|
||
另请参阅:[rules/styling.md](./rules/styling.md) 中的错误/正确示例。
|
||
|
||
按以下顺序优先选择这些方法:
|
||
|
||
### 1. 内置变体
|
||
|
||
```tsx
|
||
<Button variant="outline" size="sm">Click</Button>
|
||
```
|
||
|
||
### 2. 通过 `className` 使用 Tailwind 类
|
||
|
||
```tsx
|
||
<Card className="max-w-md mx-auto">...</Card>
|
||
```
|
||
|
||
### 3. 添加新变体
|
||
|
||
编辑组件源码,通过 `cva` 添加变体:
|
||
|
||
```tsx
|
||
// components/ui/button.tsx
|
||
warning: "bg-warning text-warning-foreground hover:bg-warning/90",
|
||
```
|
||
|
||
### 4. 包装器组件
|
||
|
||
将 shadcn/ui 基础组件组合成更高级的组件:
|
||
|
||
```tsx
|
||
export function ConfirmDialog({ title, description, onConfirm, children }) {
|
||
return (
|
||
<AlertDialog>
|
||
<AlertDialogTrigger asChild>{children}</AlertDialogTrigger>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>{title}</AlertDialogTitle>
|
||
<AlertDialogDescription>{description}</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||
<AlertDialogAction onClick={onConfirm}>Confirm</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 检查更新
|
||
|
||
```bash
|
||
npx shadcn@latest add button --diff
|
||
```
|
||
|
||
要在更新前预览具体变化,请使用 `--dry-run` 和 `--diff`:
|
||
|
||
```bash
|
||
npx shadcn@latest add button --dry-run # 查看所有受影响的文件
|
||
npx shadcn@latest add button --diff button.tsx # 查看特定文件的差异
|
||
```
|
||
|
||
完整智能合并工作流请参阅 [SKILL.md 中的更新组件](./SKILL.md#updating-components)。
|