@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.md CHANGED
@@ -1,19 +1,18 @@
1
1
  # @soybeanjs/shadcn-theme
2
2
 
3
- 一个功能强大且灵活的 shadcn/ui 主题生成器,支持动态 CSS 变量注入、预设配色方案和深浅模式切换。
3
+ 一个功能强大且灵活的 shadcn/ui 主题 CSS 变量生成器,提供预设配色方案、深浅模式输出,以及可选的自定义预设扩展。
4
4
 
5
5
  [English](./README.en_US.md)
6
6
 
7
7
  ## ✨ 特性
8
8
 
9
- - 🎨 **丰富的预设主题** - 提供多种基础色板、主题色和反馈色预设
10
- - 🌗 **深浅模式支持** - 内置深色模式支持,可自动生成深色变体
11
- - 🎯 **灵活的配色方案** - 支持 HSL OKLCH 两种颜色格式
12
- - 🔧 **高度可定制** - 支持完全自定义主题颜色配置
13
- - 📦 **零运行时依赖** - 仅依赖 `@soybeanjs/colord` 进行颜色处理
14
- - 🚀 **即插即用** - 自动将 CSS 变量注入到 DOM 中
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
- // 使用默认预设(slate + indigo + classic)
32
- createShadcnTheme();
30
+ // 使用默认预设(gray + indigo + classic + extended
31
+ const theme = createShadcnTheme();
32
+ const css = theme.getCss();
33
33
 
34
34
  // 自定义预设组合
35
- createShadcnTheme({
36
- presets: {
37
- base: 'zinc', // 基础色板:stone | zinc | neutral | gray | slate
38
- theme: 'blue', // 主题色:任意 Tailwind 色板名称
39
- feedback: 'vivid' // 反馈色风格:classic | vivid | subtle | warm | cool 等
40
- },
41
- radius: '0.5rem', // 圆角大小
42
- darkSelector: 'class', // 深色模式选择器:'class' | 'media' | 自定义
43
- format: 'hsl' // 颜色格式:'hsl' | 'oklch'
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
- theme: {
88
+ const theme = createShadcnTheme({
89
+ preset: {
52
90
  light: {
53
- background: 'oklch(100% 0 0)',
54
- foreground: 'oklch(20% 0 0)',
55
- primary: 'oklch(50% 0.2 250)',
56
- primaryForeground: 'oklch(100% 0 0)',
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: 'oklch(20% 0 0)',
62
- foreground: 'oklch(100% 0 0)',
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
- | `presets` | `PresetConfig` | - | 预设配置,优先级高于 `theme` |
80
- | `theme` | `ThemeConfig` | - | 自定义主题颜色配置 |
81
- | `radius` | `string` | `'0.625rem'` | 全局圆角大小 |
82
- | `styleId` | `string` | `'SHADCN_THEME_STYLES'` | 注入的 style 标签 ID |
83
- | `styleTarget` | `'html' \| ':root'` | `':root'` | CSS 变量挂载目标 |
84
- | `darkSelector` | `string` | `'class'` | 深色模式选择器 |
85
- | `format` | `'hsl' \| 'oklch'` | `'hsl'` | 颜色输出格式 |
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?: 'stone' | 'zinc' | 'neutral' | 'gray' | 'slate'; // 默认: 'slate'
92
- theme?: TailwindPaletteKey; // 任意 Tailwind 色板,默认: 'indigo'
93
- feedback?: FeedbackPaletteKey; // 反馈色风格,默认: 'classic'
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` | 现代简约 | 现代感强,适合科技产品和 SaaS 应用 |
108
- | `vibrant` | 活力四射 | 高能量配色,适合运动、游戏类应用 |
109
- | `professional` | 商务专业 | 稳重大气,适合企业级应用和 B2B 产品 |
110
- | `soft` | 梦幻柔美 | 柔和色调,适合设计工具和创意平台 |
111
- | `bold` | 大胆醒目 | 高对比度,适合需要强烈视觉冲击的场景 |
112
- | `calm` | 平静舒缓 | 低饱和度,适合长时间使用的应用 |
113
- | `candy` | 糖果色彩 | 明快可爱,适合儿童产品和趣味应用 |
114
- | `deep` | 深邃神秘 | 深色调,适合暗黑主题和神秘风格 |
115
- | `light` | 清新淡雅 | 浅色调,适合简洁清爽的界面 |
116
-
117
- ### 主题颜色配置(ThemeColors)
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
- presets: {
191
- base: 'slate',
192
- theme: 'blue',
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
- presets: {
205
- base: 'zinc',
206
- theme: 'violet',
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
- theme: {
220
- light: {
221
- background: 'oklch(100% 0 0)',
222
- foreground: 'oklch(20% 0 0)',
223
- primary: 'oklch(50% 0.25 280)', // 自定义品牌紫色
224
- primaryForeground: 'oklch(100% 0 0)',
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
- presets: {
239
- base: 'slate',
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
- presets: {
251
- base: 'slate',
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
- 调用 `createShadcnTheme()` 后,会自动在 `<head>` 中注入包含以下变量的 `<style>` 标签:
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
- createShadcnTheme({
297
- presets: { base: 'slate', theme: 'blue' }
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
- // 运行时切换到深色主题(通过切换 class)
301
- document.documentElement.classList.add('dark');
467
+ // 初始
468
+ apply(theme.getCss());
302
469
 
303
- // 切换到另一个主题
304
- createShadcnTheme({
305
- presets: { base: 'zinc', theme: 'purple' }
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 中使用