@soybeanjs/shadcn-theme 0.0.11 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en_US.md +305 -122
- package/README.md +315 -124
- package/dist/index.d.ts +102 -78
- package/dist/index.js +1 -1
- package/package.json +26 -25
package/README.md
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
# @soybeanjs/shadcn-theme
|
|
2
2
|
|
|
3
|
-
一个功能强大且灵活的 shadcn/ui
|
|
3
|
+
一个功能强大且灵活的 shadcn/ui 主题 CSS 变量生成器,提供预设配色方案、深浅模式输出,以及可选的自定义预设扩展。
|
|
4
4
|
|
|
5
5
|
[English](./README.en_US.md)
|
|
6
6
|
|
|
7
7
|
## ✨ 特性
|
|
8
8
|
|
|
9
|
-
- 🎨 **丰富的预设主题** -
|
|
10
|
-
- 🌗
|
|
11
|
-
- 🎯
|
|
12
|
-
- 🔧
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- 🌈 **颜色调色板生成** - 自动生成主要颜色的渐变色板(50-950)
|
|
9
|
+
- 🎨 **丰富的预设主题** - 内置 base / primary / feedback 多种预设组合
|
|
10
|
+
- 🌗 **深浅模式输出** - 支持 `.dark` / `@media (prefers-color-scheme: dark)` / 自定义选择器
|
|
11
|
+
- 🎯 **灵活的颜色格式** - 支持 `hsl` 与 `oklch` 输出
|
|
12
|
+
- 🔧 **可扩展** - 通过 `preset` 注入自定义配色(含 sidebar / chart 等扩展字段)
|
|
13
|
+
- 🌈 **色板变量生成** - 自动生成 primary/destructive/success/warning/info/carbon 的 50-950 色阶变量
|
|
14
|
+
- 📦 **轻量依赖** - 仅依赖 `@soybeanjs/colord` 进行颜色与色板处理
|
|
15
|
+
- 🧩 **纯生成器** - 仅返回 CSS 字符串,不会自动操作 DOM(可自行注入 style 标签)
|
|
17
16
|
|
|
18
17
|
## 📦 安装
|
|
19
18
|
|
|
@@ -28,97 +27,240 @@ pnpm add @soybeanjs/shadcn-theme
|
|
|
28
27
|
```typescript
|
|
29
28
|
import { createShadcnTheme } from '@soybeanjs/shadcn-theme';
|
|
30
29
|
|
|
31
|
-
// 使用默认预设(
|
|
32
|
-
createShadcnTheme();
|
|
30
|
+
// 使用默认预设(gray + indigo + classic + extended)
|
|
31
|
+
const theme = createShadcnTheme();
|
|
32
|
+
const css = theme.getCss();
|
|
33
33
|
|
|
34
34
|
// 自定义预设组合
|
|
35
|
-
createShadcnTheme({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
darkSelector: 'class',
|
|
43
|
-
format: 'hsl'
|
|
35
|
+
const custom = createShadcnTheme({
|
|
36
|
+
base: 'zinc',
|
|
37
|
+
primary: 'blue',
|
|
38
|
+
feedback: 'vivid',
|
|
39
|
+
sidebar: 'extended',
|
|
40
|
+
radius: '0.625rem',
|
|
41
|
+
styleTarget: ':root',
|
|
42
|
+
darkSelector: 'class',
|
|
43
|
+
format: 'hsl'
|
|
44
44
|
});
|
|
45
|
+
|
|
46
|
+
const customCss = custom.getCss();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
###(可选)注入到 DOM
|
|
50
|
+
|
|
51
|
+
本库默认只生成 CSS 字符串。如果你希望在浏览器里动态切换主题,可以自行把生成结果写入 `<style>`:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createShadcnTheme } from '@soybeanjs/shadcn-theme';
|
|
55
|
+
|
|
56
|
+
const theme = createShadcnTheme({ primary: 'indigo' });
|
|
57
|
+
|
|
58
|
+
function applyTheme(cssText: string, styleId = 'SHADCN_THEME_STYLE') {
|
|
59
|
+
const el = document.getElementById(styleId) ?? document.createElement('style');
|
|
60
|
+
el.id = styleId;
|
|
61
|
+
el.textContent = cssText;
|
|
62
|
+
document.head.appendChild(el);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
applyTheme(theme.getCss());
|
|
66
|
+
// 之后只要更新 style 内容即可实现主题切换
|
|
67
|
+
applyTheme(theme.getCss({ primary: 'emerald' }));
|
|
45
68
|
```
|
|
46
69
|
|
|
47
|
-
###
|
|
70
|
+
### 自定义预设
|
|
71
|
+
|
|
72
|
+
通过 `preset` 参数,你可以使用完整的自定义颜色配置,覆盖内置的 base/primary/feedback/sidebar 预设。当使用自定义预设时,需要同时提供完整的颜色定义。
|
|
73
|
+
|
|
74
|
+
#### 1) 何时使用自定义预设
|
|
75
|
+
|
|
76
|
+
- 当内置预设组合无法满足设计需求时,可以使用 `preset` 传入完整的自定义颜色配置。
|
|
77
|
+
- 使用自定义预设时,所有 base/primary/feedback/sidebar 相关的参数将被忽略,仅使用 `preset` 中的配置。
|
|
78
|
+
|
|
79
|
+
#### 2) 颜色值与 `format`
|
|
80
|
+
|
|
81
|
+
- 预设里每个颜色值都支持三种写法:Tailwind 色板引用(如 `slate.500`)、`hsl(...)`、`oklch(...)`、或内置允许的颜色名称(`inherit`、`currentColor`、`transparent`、`black`、`white`)。
|
|
82
|
+
- `format: 'hsl'`:输出变量值为 `h s l [/ alpha]`(不含 `hsl(...)` 外层);如果输入是 `oklch(...)` 会转换为 hsl。
|
|
83
|
+
- `format: 'oklch'`:输出变量值包含 `oklch(...)` 外层;如果输入是 `hsl(...)` 会转换为 oklch。
|
|
84
|
+
|
|
85
|
+
#### 快速示例:完整的自定义预设
|
|
48
86
|
|
|
49
87
|
```typescript
|
|
50
|
-
createShadcnTheme({
|
|
51
|
-
|
|
88
|
+
const theme = createShadcnTheme({
|
|
89
|
+
preset: {
|
|
52
90
|
light: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
91
|
+
// 基础颜色
|
|
92
|
+
background: 'white',
|
|
93
|
+
foreground: 'slate.950',
|
|
94
|
+
card: 'white',
|
|
95
|
+
cardForeground: 'slate.950',
|
|
96
|
+
popover: 'white',
|
|
97
|
+
popoverForeground: 'slate.950',
|
|
98
|
+
primaryForeground: 'slate.50',
|
|
99
|
+
secondary: 'slate.100',
|
|
100
|
+
secondaryForeground: 'slate.900',
|
|
101
|
+
muted: 'slate.100',
|
|
102
|
+
mutedForeground: 'slate.500',
|
|
103
|
+
accent: 'slate.100',
|
|
104
|
+
accentForeground: 'slate.900',
|
|
105
|
+
destructiveForeground: 'slate.50',
|
|
106
|
+
successForeground: 'slate.50',
|
|
107
|
+
warningForeground: 'slate.50',
|
|
108
|
+
infoForeground: 'slate.50',
|
|
109
|
+
carbon: 'slate.800',
|
|
110
|
+
carbonForeground: 'slate.50',
|
|
111
|
+
border: 'slate.200',
|
|
112
|
+
input: 'slate.200',
|
|
113
|
+
// 主题颜色
|
|
114
|
+
primary: 'blue.600',
|
|
115
|
+
destructive: 'red.500',
|
|
116
|
+
success: 'green.500',
|
|
117
|
+
warning: 'amber.500',
|
|
118
|
+
info: 'blue.500',
|
|
119
|
+
ring: 'blue.400',
|
|
120
|
+
// 图表颜色
|
|
121
|
+
chart1: 'orange.600',
|
|
122
|
+
chart2: 'teal.600',
|
|
123
|
+
chart3: 'cyan.900',
|
|
124
|
+
chart4: 'amber.400',
|
|
125
|
+
chart5: 'amber.500',
|
|
126
|
+
// 侧边栏颜色
|
|
127
|
+
sidebar: 'slate.50',
|
|
128
|
+
sidebarForeground: 'slate.900',
|
|
129
|
+
sidebarPrimary: 'blue.600',
|
|
130
|
+
sidebarPrimaryForeground: 'slate.50',
|
|
131
|
+
sidebarAccent: 'slate.100',
|
|
132
|
+
sidebarAccentForeground: 'slate.900',
|
|
133
|
+
sidebarBorder: 'slate.200',
|
|
134
|
+
sidebarRing: 'blue.400'
|
|
58
135
|
},
|
|
59
136
|
dark: {
|
|
60
|
-
//
|
|
61
|
-
background: '
|
|
62
|
-
foreground: '
|
|
63
|
-
|
|
137
|
+
// 基础颜色
|
|
138
|
+
background: 'slate.950',
|
|
139
|
+
foreground: 'slate.50',
|
|
140
|
+
card: 'slate.900',
|
|
141
|
+
cardForeground: 'slate.50',
|
|
142
|
+
popover: 'slate.900',
|
|
143
|
+
popoverForeground: 'slate.50',
|
|
144
|
+
primaryForeground: 'slate.900',
|
|
145
|
+
secondary: 'slate.800',
|
|
146
|
+
secondaryForeground: 'slate.50',
|
|
147
|
+
muted: 'slate.800',
|
|
148
|
+
mutedForeground: 'slate.400',
|
|
149
|
+
accent: 'slate.800',
|
|
150
|
+
accentForeground: 'slate.50',
|
|
151
|
+
destructiveForeground: 'slate.900',
|
|
152
|
+
successForeground: 'slate.900',
|
|
153
|
+
warningForeground: 'slate.900',
|
|
154
|
+
infoForeground: 'slate.900',
|
|
155
|
+
carbon: 'slate.100',
|
|
156
|
+
carbonForeground: 'slate.900',
|
|
157
|
+
border: 'oklch(100% 0 0 / 0.1)',
|
|
158
|
+
input: 'oklch(100% 0 0 / 0.15)',
|
|
159
|
+
// 主题颜色
|
|
160
|
+
primary: 'blue.400',
|
|
161
|
+
destructive: 'red.400',
|
|
162
|
+
success: 'green.400',
|
|
163
|
+
warning: 'amber.400',
|
|
164
|
+
info: 'blue.400',
|
|
165
|
+
ring: 'blue.500',
|
|
166
|
+
// 图表颜色
|
|
167
|
+
chart1: 'orange.500',
|
|
168
|
+
chart2: 'teal.500',
|
|
169
|
+
chart3: 'cyan.400',
|
|
170
|
+
chart4: 'amber.500',
|
|
171
|
+
chart5: 'amber.600',
|
|
172
|
+
// 侧边栏颜色
|
|
173
|
+
sidebar: 'slate.950',
|
|
174
|
+
sidebarForeground: 'slate.50',
|
|
175
|
+
sidebarPrimary: 'blue.400',
|
|
176
|
+
sidebarPrimaryForeground: 'slate.950',
|
|
177
|
+
sidebarAccent: 'slate.900',
|
|
178
|
+
sidebarAccentForeground: 'slate.50',
|
|
179
|
+
sidebarBorder: 'slate.800',
|
|
180
|
+
sidebarRing: 'blue.500'
|
|
64
181
|
}
|
|
65
182
|
}
|
|
66
183
|
});
|
|
184
|
+
|
|
185
|
+
const css = theme.getCss();
|
|
67
186
|
```
|
|
68
187
|
|
|
188
|
+
#### 注意事项
|
|
189
|
+
|
|
190
|
+
- 当提供 `preset` 参数时,`base`、`primary`、`feedback`、`sidebar` 参数将被忽略。
|
|
191
|
+
- 预设必须包含 `light` 和 `dark` 两个模式的完整色值定义。
|
|
192
|
+
- 建议从内置预设的结构开始,根据设计需求进行修改。
|
|
193
|
+
|
|
69
194
|
## 📖 API 文档
|
|
70
195
|
|
|
71
196
|
### `createShadcnTheme(options?: ThemeOptions)`
|
|
72
197
|
|
|
73
|
-
|
|
198
|
+
主函数,用于创建主题 CSS 生成器。
|
|
199
|
+
|
|
200
|
+
返回值:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
const theme = createShadcnTheme();
|
|
204
|
+
|
|
205
|
+
theme.getCss(config?: PresetConfig, radius?: string): string
|
|
206
|
+
theme.getColorCss(config: PresetConfig): string
|
|
207
|
+
theme.getRadiusCss(radius?: string): string
|
|
208
|
+
```
|
|
74
209
|
|
|
75
210
|
#### ThemeOptions
|
|
76
211
|
|
|
77
|
-
| 参数
|
|
78
|
-
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
212
|
+
| 参数 | 类型 | 默认值 | 描述 |
|
|
213
|
+
| -------------- | ------------------------------ | ------------ | ---------------------------------------------------------------- |
|
|
214
|
+
| `base` | `BuiltinBasePresetKey` | `'neutral'` | base 预设 key |
|
|
215
|
+
| `primary` | `BuiltinPrimaryPresetKey` | `'indigo'` | primary 预设 key |
|
|
216
|
+
| `feedback` | `BuiltinFeedbackPresetKey` | `'classic'` | feedback 预设 key |
|
|
217
|
+
| `sidebar` | `'extended'` | `'extended'` | 侧边栏模式;`extended` 表示由 base/primary 自动派生 |
|
|
218
|
+
| `preset` | `ThemeColorPresetItem` | - | 自定义完整颜色预设(提供时将忽略 base/primary/feedback/sidebar) |
|
|
219
|
+
| `radius` | `string` | `'0.625rem'` | 全局圆角 |
|
|
220
|
+
| `styleTarget` | `'html' \| ':root'` | `':root'` | CSS 变量挂载目标选择器 |
|
|
221
|
+
| `darkSelector` | `'class' \| 'media' \| string` | `'class'` | 深色模式选择器(支持自定义字符串) |
|
|
222
|
+
| `format` | `'hsl' \| 'oklch'` | `'hsl'` | 颜色输出格式 |
|
|
86
223
|
|
|
87
224
|
### 预设配置(PresetConfig)
|
|
88
225
|
|
|
89
226
|
```typescript
|
|
90
227
|
interface PresetConfig {
|
|
91
|
-
base?:
|
|
92
|
-
|
|
93
|
-
feedback?:
|
|
228
|
+
base?: BuiltinBasePresetKey | 'custom';
|
|
229
|
+
primary?: BuiltinPrimaryPresetKey | 'custom';
|
|
230
|
+
feedback?: BuiltinFeedbackPresetKey | 'custom';
|
|
231
|
+
sidebar?: 'extended' | 'custom';
|
|
232
|
+
preset?: ThemeColorPresetItem;
|
|
94
233
|
}
|
|
95
234
|
```
|
|
96
235
|
|
|
236
|
+
当使用 `preset` 参数时,其他配置参数(base/primary/feedback/sidebar)将被忽略。
|
|
237
|
+
|
|
97
238
|
#### 反馈色风格(FeedbackPaletteKey)
|
|
98
239
|
|
|
99
|
-
| 风格
|
|
100
|
-
|
|
101
|
-
| `classic`
|
|
102
|
-
| `vivid`
|
|
103
|
-
| `subtle`
|
|
104
|
-
| `warm`
|
|
105
|
-
| `cool`
|
|
106
|
-
| `nature`
|
|
107
|
-
| `modern`
|
|
108
|
-
| `vibrant`
|
|
109
|
-
| `professional` | 商务专业 | 稳重大气,适合企业级应用和 B2B 产品
|
|
110
|
-
| `soft`
|
|
111
|
-
| `bold`
|
|
112
|
-
| `calm`
|
|
113
|
-
| `candy`
|
|
114
|
-
| `deep`
|
|
115
|
-
| `light`
|
|
116
|
-
|
|
117
|
-
###
|
|
240
|
+
| 风格 | 描述 | 适用场景 |
|
|
241
|
+
| -------------- | -------- | ------------------------------------ |
|
|
242
|
+
| `classic` | 经典标准 | 最常见的组合,适用于大多数场景 |
|
|
243
|
+
| `vivid` | 鲜艳活力 | 高饱和度,适合年轻化产品和创意应用 |
|
|
244
|
+
| `subtle` | 柔和优雅 | 低对比度,适合高端品牌和优雅界面 |
|
|
245
|
+
| `warm` | 暖色温馨 | 暖色调为主,营造友好温暖的氛围 |
|
|
246
|
+
| `cool` | 冷色专业 | 冷色调为主,适合科技和专业应用 |
|
|
247
|
+
| `nature` | 自然清新 | 自然色系,适合环保、健康类产品 |
|
|
248
|
+
| `modern` | 现代简约 | 现代感强,适合科技产品和 SaaS 应用 |
|
|
249
|
+
| `vibrant` | 活力四射 | 高能量配色,适合运动、游戏类应用 |
|
|
250
|
+
| `professional` | 商务专业 | 稳重大气,适合企业级应用和 B2B 产品 |
|
|
251
|
+
| `soft` | 梦幻柔美 | 柔和色调,适合设计工具和创意平台 |
|
|
252
|
+
| `bold` | 大胆醒目 | 高对比度,适合需要强烈视觉冲击的场景 |
|
|
253
|
+
| `calm` | 平静舒缓 | 低饱和度,适合长时间使用的应用 |
|
|
254
|
+
| `candy` | 糖果色彩 | 明快可爱,适合儿童产品和趣味应用 |
|
|
255
|
+
| `deep` | 深邃神秘 | 深色调,适合暗黑主题和神秘风格 |
|
|
256
|
+
| `light` | 清新淡雅 | 浅色调,适合简洁清爽的界面 |
|
|
257
|
+
|
|
258
|
+
### 主题颜色(ThemeColors)
|
|
118
259
|
|
|
119
260
|
支持配置以下颜色变量:
|
|
120
261
|
|
|
121
262
|
#### 基础颜色
|
|
263
|
+
|
|
122
264
|
- `background` - 背景色
|
|
123
265
|
- `foreground` - 前景色(文本)
|
|
124
266
|
- `card` - 卡片背景
|
|
@@ -140,12 +282,14 @@ interface PresetConfig {
|
|
|
140
282
|
- `ring` - 聚焦环颜色
|
|
141
283
|
|
|
142
284
|
#### 扩展颜色
|
|
285
|
+
|
|
143
286
|
- `success` / `successForeground` - 成功状态
|
|
144
287
|
- `warning` / `warningForeground` - 警告状态
|
|
145
288
|
- `info` / `infoForeground` - 信息状态
|
|
146
289
|
- `carbon` / `carbonForeground` - 碳色(额外的深色系)
|
|
147
290
|
|
|
148
291
|
#### 侧边栏颜色
|
|
292
|
+
|
|
149
293
|
- `sidebar` - 侧边栏背景
|
|
150
294
|
- `sidebarForeground` - 侧边栏前景
|
|
151
295
|
- `sidebarPrimary` - 侧边栏主色
|
|
@@ -156,6 +300,7 @@ interface PresetConfig {
|
|
|
156
300
|
- `sidebarRing` - 侧边栏聚焦环
|
|
157
301
|
|
|
158
302
|
#### 图表颜色
|
|
303
|
+
|
|
159
304
|
- `chart1` ~ `chart5` - 图表配色
|
|
160
305
|
|
|
161
306
|
### 颜色值格式(ColorValue)
|
|
@@ -163,22 +308,25 @@ interface PresetConfig {
|
|
|
163
308
|
支持三种颜色值格式:
|
|
164
309
|
|
|
165
310
|
1. **HSL 格式**
|
|
311
|
+
|
|
166
312
|
```typescript
|
|
167
|
-
'hsl(0 0% 100%)'
|
|
168
|
-
'hsl(0 0% 100% / 0.5)' // 带透明度
|
|
313
|
+
'hsl(0 0% 100%)';
|
|
314
|
+
'hsl(0 0% 100% / 0.5)'; // 带透明度
|
|
169
315
|
```
|
|
170
316
|
|
|
171
317
|
2. **OKLCH 格式**
|
|
318
|
+
|
|
172
319
|
```typescript
|
|
173
|
-
'oklch(100% 0 0)'
|
|
174
|
-
'oklch(100% 0 0 / 0.5)' // 带透明度
|
|
320
|
+
'oklch(100% 0 0)';
|
|
321
|
+
'oklch(100% 0 0 / 0.5)'; // 带透明度
|
|
175
322
|
```
|
|
176
323
|
|
|
177
324
|
3. **Tailwind 色板引用**
|
|
325
|
+
|
|
178
326
|
```typescript
|
|
179
|
-
'slate.500'
|
|
180
|
-
'blue.600'
|
|
181
|
-
'red.50'
|
|
327
|
+
'slate.500';
|
|
328
|
+
'blue.600';
|
|
329
|
+
'red.50';
|
|
182
330
|
```
|
|
183
331
|
|
|
184
332
|
## 🎨 使用示例
|
|
@@ -186,78 +334,78 @@ interface PresetConfig {
|
|
|
186
334
|
### 示例 1: 经典蓝色主题
|
|
187
335
|
|
|
188
336
|
```typescript
|
|
189
|
-
createShadcnTheme({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
feedback: 'classic'
|
|
194
|
-
},
|
|
337
|
+
const theme = createShadcnTheme({
|
|
338
|
+
base: 'slate',
|
|
339
|
+
primary: 'blue',
|
|
340
|
+
feedback: 'classic',
|
|
195
341
|
radius: '0.5rem',
|
|
196
342
|
darkSelector: 'class'
|
|
197
343
|
});
|
|
344
|
+
|
|
345
|
+
const css = theme.getCss();
|
|
198
346
|
```
|
|
199
347
|
|
|
200
348
|
### 示例 2: 现代紫色主题
|
|
201
349
|
|
|
202
350
|
```typescript
|
|
203
|
-
createShadcnTheme({
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
feedback: 'modern'
|
|
208
|
-
},
|
|
351
|
+
const theme = createShadcnTheme({
|
|
352
|
+
base: 'zinc',
|
|
353
|
+
primary: 'violet',
|
|
354
|
+
feedback: 'modern',
|
|
209
355
|
radius: '0.75rem',
|
|
210
356
|
darkSelector: 'class',
|
|
211
357
|
format: 'oklch'
|
|
212
358
|
});
|
|
359
|
+
|
|
360
|
+
const css = theme.getCss();
|
|
213
361
|
```
|
|
214
362
|
|
|
215
|
-
### 示例 3:
|
|
363
|
+
### 示例 3: 覆盖单次生成的配色组合
|
|
216
364
|
|
|
217
365
|
```typescript
|
|
218
|
-
createShadcnTheme({
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
secondary: 'oklch(95% 0.01 280)',
|
|
226
|
-
secondaryForeground: 'oklch(30% 0 0)',
|
|
227
|
-
// ... 其他颜色
|
|
228
|
-
}
|
|
229
|
-
// dark 可选,不提供会自动生成
|
|
230
|
-
}
|
|
231
|
-
});
|
|
366
|
+
const theme = createShadcnTheme({ base: 'slate', primary: 'indigo', feedback: 'classic' });
|
|
367
|
+
|
|
368
|
+
// 默认组合
|
|
369
|
+
const css1 = theme.getCss();
|
|
370
|
+
|
|
371
|
+
// 仅这一次生成使用另一套组合(不会改变 theme 内部的默认项)
|
|
372
|
+
const css2 = theme.getCss({ primary: 'emerald', feedback: 'vivid' });
|
|
232
373
|
```
|
|
233
374
|
|
|
234
375
|
### 示例 4: 媒体查询深色模式
|
|
235
376
|
|
|
236
377
|
```typescript
|
|
237
|
-
createShadcnTheme({
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
theme: 'indigo'
|
|
241
|
-
},
|
|
378
|
+
const theme = createShadcnTheme({
|
|
379
|
+
base: 'slate',
|
|
380
|
+
primary: 'indigo',
|
|
242
381
|
darkSelector: 'media' // 使用系统偏好
|
|
243
382
|
});
|
|
383
|
+
|
|
384
|
+
const css = theme.getCss();
|
|
244
385
|
```
|
|
245
386
|
|
|
246
387
|
### 示例 5: 自定义深色模式选择器
|
|
247
388
|
|
|
248
389
|
```typescript
|
|
249
|
-
createShadcnTheme({
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
theme: 'emerald'
|
|
253
|
-
},
|
|
390
|
+
const theme = createShadcnTheme({
|
|
391
|
+
base: 'slate',
|
|
392
|
+
primary: 'emerald',
|
|
254
393
|
darkSelector: '[data-theme="dark"]' // 自定义选择器
|
|
255
394
|
});
|
|
395
|
+
|
|
396
|
+
const css = theme.getCss();
|
|
256
397
|
```
|
|
257
398
|
|
|
258
399
|
## 🎯 生成的 CSS 变量
|
|
259
400
|
|
|
260
|
-
调用 `
|
|
401
|
+
调用 `getCss()` 会返回包含以下变量的 CSS 字符串。
|
|
402
|
+
|
|
403
|
+
当 `format: 'hsl'` 时,颜色变量值是 `h s l [/ alpha]`(不包含外层 `hsl(...)`):
|
|
404
|
+
|
|
405
|
+
补充说明:
|
|
406
|
+
|
|
407
|
+
- 当 `format: 'hsl'` 且颜色 key 为 `border`、`input`、`sidebarBorder` 时,如果颜色值包含透明度(例如 `hsl(... / 0.1)` 或 `oklch(... / 0.1)`),会额外生成对应的透明度变量:`--border-alpha`、`--input-alpha`、`--sidebar-border-alpha`。同时 `--border` / `--input` / `--sidebar-border` 本身会只保留不带透明度的 `h s l` 值。
|
|
408
|
+
- 会为 `primary`、`destructive`、`success`、`warning`、`info`、`carbon` 生成 50-950 共 11 个色阶变量:`50/100/200/300/400/500/600/700/800/900/950`。
|
|
261
409
|
|
|
262
410
|
```css
|
|
263
411
|
:root {
|
|
@@ -265,9 +413,13 @@ createShadcnTheme({
|
|
|
265
413
|
--background: 0 0% 100%;
|
|
266
414
|
--foreground: 222.2 84% 4.9%;
|
|
267
415
|
--primary: 221.2 83.2% 53.3%;
|
|
416
|
+
|
|
417
|
+
/* hsl 下:border/input/sidebarBorder 会额外输出 alpha 变量 */
|
|
418
|
+
--border: 214.3 31.8% 91.4%;
|
|
419
|
+
--border-alpha: 0.1;
|
|
268
420
|
/* ... 更多变量 */
|
|
269
421
|
|
|
270
|
-
/*
|
|
422
|
+
/* 自动生成的色板(50-950 共 11 个) */
|
|
271
423
|
--primary-50: 239 84% 97%;
|
|
272
424
|
--primary-100: 237 84% 94%;
|
|
273
425
|
/* ... primary-200 到 primary-950 */
|
|
@@ -287,23 +439,39 @@ createShadcnTheme({
|
|
|
287
439
|
}
|
|
288
440
|
```
|
|
289
441
|
|
|
442
|
+
当 `format: 'oklch'` 时,颜色变量值会包含 `oklch(...)` 外层括号:
|
|
443
|
+
|
|
444
|
+
```css
|
|
445
|
+
:root {
|
|
446
|
+
--background: oklch(100% 0 0);
|
|
447
|
+
--foreground: oklch(20% 0 0);
|
|
448
|
+
--border: oklch(100% 0 0 / 0.1);
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
290
452
|
## 💡 高级用法
|
|
291
453
|
|
|
292
454
|
### 动态切换主题
|
|
293
455
|
|
|
294
456
|
```typescript
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
457
|
+
const theme = createShadcnTheme();
|
|
458
|
+
|
|
459
|
+
function apply(cssText: string) {
|
|
460
|
+
const id = 'SHADCN_THEME_STYLE';
|
|
461
|
+
const el = document.getElementById(id) ?? document.createElement('style');
|
|
462
|
+
el.id = id;
|
|
463
|
+
el.textContent = cssText;
|
|
464
|
+
document.head.appendChild(el);
|
|
465
|
+
}
|
|
299
466
|
|
|
300
|
-
//
|
|
301
|
-
|
|
467
|
+
// 初始
|
|
468
|
+
apply(theme.getCss());
|
|
302
469
|
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
470
|
+
// 切换到另一个配色组合
|
|
471
|
+
apply(theme.getCss({ base: 'zinc', primary: 'purple' }));
|
|
472
|
+
|
|
473
|
+
// 深色模式切换仍由你的 darkSelector 控制(例如默认是给 html 加 .dark)
|
|
474
|
+
document.documentElement.classList.add('dark');
|
|
307
475
|
```
|
|
308
476
|
|
|
309
477
|
### 在 Tailwind CSS 中使用
|
|
@@ -321,19 +489,42 @@ module.exports = {
|
|
|
321
489
|
DEFAULT: 'hsl(var(--primary))',
|
|
322
490
|
foreground: 'hsl(var(--primary-foreground))',
|
|
323
491
|
50: 'hsl(var(--primary-50))',
|
|
324
|
-
100: 'hsl(var(--primary-100))'
|
|
492
|
+
100: 'hsl(var(--primary-100))'
|
|
325
493
|
// ... 更多色阶
|
|
326
|
-
}
|
|
494
|
+
}
|
|
327
495
|
// ... 其他颜色
|
|
328
496
|
},
|
|
329
497
|
borderRadius: {
|
|
330
498
|
lg: 'var(--radius)',
|
|
331
499
|
md: 'calc(var(--radius) - 2px)',
|
|
332
|
-
sm: 'calc(var(--radius) - 4px)'
|
|
500
|
+
sm: 'calc(var(--radius) - 4px)'
|
|
333
501
|
}
|
|
334
502
|
}
|
|
335
503
|
}
|
|
336
|
-
}
|
|
504
|
+
};
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
当你使用 `format: 'hsl'` 时,“透明度需要单独处理”,尤其是 `border` / `input` / `sidebarBorder`:
|
|
508
|
+
|
|
509
|
+
- 这些变量本身输出的是 `h s l`(不含 `/ alpha`),如果存在透明度,会额外生成 `--border-alpha` / `--input-alpha` / `--sidebar-border-alpha`。
|
|
510
|
+
- 在 Tailwind 中使用时,推荐用带斜杠的写法把透明度拼回去:
|
|
511
|
+
|
|
512
|
+
```js
|
|
513
|
+
// 固定使用生成出来的 alpha
|
|
514
|
+
border: 'hsl(var(--border) / var(--border-alpha))';
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
如果你希望 Tailwind 的透明度修饰符(例如 `border-border/50`)生效,可以使用 `<alpha-value>` 占位符(这种情况下通常不需要使用 `--border-alpha`):
|
|
518
|
+
|
|
519
|
+
```js
|
|
520
|
+
// 让 Tailwind 注入透明度
|
|
521
|
+
border: 'hsl(var(--border) / <alpha-value>)';
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
如果你使用 `format: 'oklch'`,由于变量值本身已经是 `oklch(...)`,在 Tailwind 中直接使用 `var(--xxx)` 即可(不需要再包一层 `oklch(...)`):
|
|
525
|
+
|
|
526
|
+
```js
|
|
527
|
+
background: 'var(--background)';
|
|
337
528
|
```
|
|
338
529
|
|
|
339
530
|
### 在 CSS 中使用
|