@qlover/tailwind-theme 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # @qlover/tailwind-theme
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ #### ♻️ Refactors
8
+
9
+ - **theme:** rename ui-theme to tailwind-theme and update dependencies ([6eb08ac](https://github.com/qlover/fe-base/commit/6eb08ac6d7f808b900365407b24ec6fa7a033ce1)) ([#609](https://github.com/qlover/fe-base/pull/609))
10
+ - Replaced all instances of '@qlover/ui-theme' with '@qlover/tailwind-theme' across various files to reflect the new package name.
11
+ - Updated the pnpm-lock.yaml to link the new tailwind-theme package and adjust dependencies accordingly.
12
+ - Modified configuration files and example projects to utilize the new tailwind-theme for improved theming support.
13
+ - Enhanced documentation in README files to guide users on the new theme integration.
14
+
15
+ These changes aim to streamline the theming experience and ensure consistency across the application.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # @qlover/tailwind-theme
2
+
3
+ 面向 Tailwind CSS v4 的设计令牌与主题 CSS 生成器。提供内置多主题色板、`data-theme` 切换、以及可编程生成 CSS 文件。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add @qlover/tailwind-theme
9
+ # 或
10
+ npm install @qlover/tailwind-theme
11
+ ```
12
+
13
+ ## 特性
14
+
15
+ - 内置主题:`light`、`dark`、`pink`、`amber`、`forest`、`ocean`
16
+ - 通道色值(RGB 分量)+ 派生语义 token(如 `color-primary-bg`)
17
+ - 生成 `@layer base` 主题变量与 Tailwind v4 `@theme` 工具类映射
18
+ - 支持自定义 `themes`、`tokenMapping`、`cssSelector`
19
+ - 可导出预构建 CSS,或在构建脚本中调用 `generateThemeFile` 重新生成
20
+ - 可选 PostCSS 插件,在入口样式中自动注入主题 CSS
21
+
22
+ ## 快速开始(Web / Next / Vite)
23
+
24
+ 在 Tailwind 入口中引入完整主题:
25
+
26
+ ```css
27
+ /* src/styles/tailwind.css */
28
+ @import 'tailwindcss';
29
+ @import '@qlover/tailwind-theme/theme.css';
30
+ ```
31
+
32
+ 在根节点切换主题(与 `corekit-bridge` 的 `ThemeService` 一致):
33
+
34
+ ```html
35
+ <html data-theme="dark">
36
+ ```
37
+
38
+ 组件中使用 Tailwind 语义类名:
39
+
40
+ ```tsx
41
+ <div className="bg-primary text-primary-text border-primary-border">
42
+ <button className="bg-brand text-on-brand hover:bg-brand-hover">Submit</button>
43
+ </div>
44
+ ```
45
+
46
+ 暗色模式可与 `data-theme` 配合:
47
+
48
+ ```css
49
+ @custom-variant dark (&:where(html[data-theme='dark'], html[data-theme='dark'] *));
50
+ ```
51
+
52
+ ## 预构建 CSS 导出
53
+
54
+ | 路径 | 说明 |
55
+ |------|------|
56
+ | `@qlover/tailwind-theme/theme.css` | 完整主题(`@layer base` + `@theme`),推荐默认使用 |
57
+ | `@qlover/tailwind-theme/theme-layer-base.css` | 仅各主题的 `--fe-*` 通道变量 |
58
+ | `@qlover/tailwind-theme/theme-block.css` | 仅 Tailwind `@theme` 工具类映射 |
59
+
60
+ 安装包后直接使用上述路径;在 monorepo 中需先在本包执行 `pnpm build` 生成 `dist/`。
61
+
62
+ ## 编程式生成 CSS
63
+
64
+ 从主入口导入生成函数:
65
+
66
+ ```typescript
67
+ import {
68
+ generateThemeCSS,
69
+ generateLayerBaseCSS,
70
+ generateThemeBlockCSS,
71
+ generateThemeFile,
72
+ generateThemeFiles,
73
+ builtinThemes,
74
+ getDefaultSelector
75
+ } from '@qlover/tailwind-theme';
76
+ ```
77
+
78
+ ### 生成字符串
79
+
80
+ ```typescript
81
+ // 完整 CSS(与 theme.css 等价)
82
+ const css = generateThemeCSS({
83
+ defaultTheme: 'light',
84
+ themes: { ...builtinThemes, /* 覆盖或扩展 */ }
85
+ });
86
+
87
+ // 仅 base 层
88
+ const base = generateLayerBaseCSS();
89
+
90
+ // 仅 @theme 块
91
+ const block = generateThemeBlockCSS();
92
+ ```
93
+
94
+ ### 写入文件
95
+
96
+ ```typescript
97
+ await generateThemeFile({
98
+ variant: 'full', // 'layer-base' | 'theme-block' | 'full'
99
+ outputPath: './src/styles/theme.generated.css',
100
+ defaultTheme: 'light',
101
+ overwrite: true
102
+ });
103
+
104
+ // 一次生成三种 variant 到目录
105
+ await generateThemeFiles({
106
+ outputDir: './dist',
107
+ overwrite: true
108
+ });
109
+ ```
110
+
111
+ ## 自定义配置
112
+
113
+ `UiThemeOptions` 常用字段:
114
+
115
+ | 选项 | 默认值 | 说明 |
116
+ |------|--------|------|
117
+ | `prefix` | `'fe'` | CSS 变量前缀,如 `--fe-color-brand` |
118
+ | `defaultTheme` | 第一个主题名 | 默认主题,用于 `:root` 选择器 |
119
+ | `themes` | `builtinThemes` | 与内置主题 deep merge |
120
+ | `tokenMapping` | `defaultTokenMapping` | Tailwind `@theme` 名 → CSS 值 |
121
+ | `cssSelector` | `getDefaultSelector` | `(themeName, isRoot) => string` |
122
+
123
+ 自定义选择器示例(类名主题,适用于部分小程序场景):
124
+
125
+ ```typescript
126
+ await generateThemeFile({
127
+ variant: 'layer-base',
128
+ outputPath: './src/styles/taro-weapp-theme.css',
129
+ cssSelector: (themeName) => `.fe-theme.theme-${themeName}`,
130
+ defaultTheme: 'light',
131
+ overwrite: true
132
+ });
133
+ ```
134
+
135
+ 自定义 token 示例:
136
+
137
+ ```typescript
138
+ generateThemeCSS({
139
+ themes: {
140
+ light: {
141
+ 'color-brand': '37 99 235'
142
+ }
143
+ },
144
+ tokenMapping: {
145
+ 'color-brand': 'rgb(var(--${prefix}-color-brand))'
146
+ }
147
+ });
148
+ ```
149
+
150
+ 模板中的 `${prefix}` 会在生成时替换为实际前缀。
151
+
152
+ ## PostCSS 插件
153
+
154
+ 在 PostCSS 配置中注入主题(默认仅处理以 `/styles/index.css` 或 `/styles/tailwind.css` 结尾的文件):
155
+
156
+ ```javascript
157
+ import themePlugin from '@qlover/tailwind-theme/plugin';
158
+
159
+ export default {
160
+ plugins: [
161
+ themePlugin({
162
+ defaultTheme: 'light',
163
+ includePaths: ['/styles/tailwind.css']
164
+ })
165
+ ]
166
+ };
167
+ ```
168
+
169
+ ## 与 ThemeService 配合
170
+
171
+ `@qlover/corekit-bridge` 的 `ThemeService` 默认使用本包的 `builtinThemes` 作为 `themeTokens`。Web 项目建议:
172
+
173
+ - `domAttribute: 'data-theme'`
174
+ - 样式入口 `@import '@qlover/tailwind-theme/theme.css'`
175
+
176
+ ## Taro / 微信小程序
177
+
178
+ H5 端与普通 Web 相同,使用 `theme.css` + `data-theme`。
179
+
180
+ 小程序根节点宜使用 class(如 `fe-theme theme-dark`),可额外生成一份仅含 class 选择器的 base 层 CSS,参见 monorepo 内 `examples/taro-seed/scripts/generate-theme-css.mjs`:
181
+
182
+ ```css
183
+ @import '@qlover/tailwind-theme/theme.css';
184
+ @import './themes/taro-weapp-theme.css'; /* pnpm generate:theme */
185
+ ```
186
+
187
+ ## 开发(monorepo)
188
+
189
+ ```bash
190
+ cd packages/tailwind-theme
191
+ pnpm build # tsup + 生成 dist/*.css
192
+ pnpm test
193
+ pnpm type-check
194
+ ```
195
+
196
+ ## 许可证
197
+
198
+ ISC
package/README_EN.md ADDED
@@ -0,0 +1,109 @@
1
+ # @qlover/tailwind-theme
2
+
3
+ Design tokens and theme CSS generator for Tailwind CSS v4. Ships built-in multi-theme palettes, `data-theme` switching, and programmatic CSS file generation.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @qlover/tailwind-theme
9
+ # or
10
+ npm install @qlover/tailwind-theme
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - Built-in themes: `light`, `dark`, `pink`, `amber`, `forest`, `ocean`
16
+ - Channel colors (RGB components) plus derived semantic tokens (e.g. `color-primary-bg`)
17
+ - Generates `@layer base` variables and Tailwind v4 `@theme` utility mappings
18
+ - Custom `themes`, `tokenMapping`, and `cssSelector`
19
+ - Pre-built CSS exports or regenerate via `generateThemeFile`
20
+ - Optional PostCSS plugin to inject theme CSS into entry stylesheets
21
+
22
+ ## Quick start (Web / Next / Vite)
23
+
24
+ ```css
25
+ /* src/styles/tailwind.css */
26
+ @import 'tailwindcss';
27
+ @import '@qlover/tailwind-theme/theme.css';
28
+ ```
29
+
30
+ Set theme on the document root (aligned with `ThemeService` in `@qlover/corekit-bridge`):
31
+
32
+ ```html
33
+ <html data-theme="dark">
34
+ ```
35
+
36
+ Use semantic Tailwind classes:
37
+
38
+ ```tsx
39
+ <div className="bg-primary text-primary-text border-primary-border">
40
+ <button className="bg-brand text-on-brand hover:bg-brand-hover">Submit</button>
41
+ </div>
42
+ ```
43
+
44
+ ## Pre-built CSS exports
45
+
46
+ | Import path | Description |
47
+ |-------------|-------------|
48
+ | `@qlover/tailwind-theme/theme.css` | Full theme (`@layer base` + `@theme`), recommended |
49
+ | `@qlover/tailwind-theme/theme-layer-base.css` | Per-theme `--fe-*` channel variables only |
50
+ | `@qlover/tailwind-theme/theme-block.css` | Tailwind `@theme` utility mapping only |
51
+
52
+ Run `pnpm build` in this package inside the monorepo before consuming `dist/`.
53
+
54
+ ## Programmatic API
55
+
56
+ ```typescript
57
+ import {
58
+ generateThemeCSS,
59
+ generateLayerBaseCSS,
60
+ generateThemeBlockCSS,
61
+ generateThemeFile,
62
+ generateThemeFiles,
63
+ builtinThemes
64
+ } from '@qlover/tailwind-theme';
65
+
66
+ const css = generateThemeCSS({ defaultTheme: 'light' });
67
+
68
+ await generateThemeFile({
69
+ variant: 'full', // 'layer-base' | 'theme-block' | 'full'
70
+ outputPath: './src/styles/theme.generated.css',
71
+ overwrite: true
72
+ });
73
+ ```
74
+
75
+ ### Custom `cssSelector` (e.g. Taro class-based root)
76
+
77
+ ```typescript
78
+ await generateThemeFile({
79
+ variant: 'layer-base',
80
+ outputPath: './src/styles/taro-weapp-theme.css',
81
+ cssSelector: (themeName) => `.fe-theme.theme-${themeName}`,
82
+ defaultTheme: 'light',
83
+ overwrite: true
84
+ });
85
+ ```
86
+
87
+ See `examples/taro-seed/scripts/generate-theme-css.mjs` in the monorepo.
88
+
89
+ ## PostCSS plugin
90
+
91
+ ```javascript
92
+ import themePlugin from '@qlover/tailwind-theme/plugin';
93
+
94
+ export default {
95
+ plugins: [themePlugin({ defaultTheme: 'light' })]
96
+ };
97
+ ```
98
+
99
+ ## Development
100
+
101
+ ```bash
102
+ cd packages/tailwind-theme
103
+ pnpm build
104
+ pnpm test
105
+ ```
106
+
107
+ ## License
108
+
109
+ ISC
package/dist/index.cjs ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";var j=Object.create;var m=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var E=(r,e)=>{for(var o in e)m(r,o,{get:e[o],enumerable:!0})},k=(r,e,o,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of D(e))!A.call(r,a)&&a!==o&&m(r,a,{get:()=>e[a],enumerable:!(t=B(e,a))||t.enumerable});return r};var $=(r,e,o)=>(o=r!=null?j(G(r)):{},k(e||!r||!r.__esModule?m(o,"default",{value:r,enumerable:!0}):o,r)),_=r=>k(m({},"__esModule",{value:!0}),r);var Y={};E(Y,{builtinThemes:()=>C,defaultConfig:()=>S,defaultTokenMapping:()=>l,generateLayerBaseCSS:()=>f,generateThemeBlockCSS:()=>y,generateThemeCSS:()=>v,generateThemeFile:()=>q,generateThemeFiles:()=>I,getConfig:()=>g,getDefaultSelector:()=>w,getDerivedTokens:()=>x});module.exports=_(Y);function O(r,e){return r.replace(/\$\{prefix\}/g,e)}function d(r,e){let o={...r};for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)){let a=e[t],n=o[t];a&&typeof a=="object"&&!Array.isArray(a)&&n&&typeof n=="object"?o[t]=d(n,a):o[t]=a}return o}var H={light:"0.08",dark:"0.12",pink:"0.12",amber:"0.12",forest:"0.1",ocean:"0.1"},C={light:{"color-primary":"246 248 250","color-secondary":"255 255 255","color-elevated":"240 242 244","color-primary-text":"31 35 40","color-primary-text-hover":"101 109 118","color-secondary-text":"101 109 118","color-tertiary-text":"140 149 159","color-primary-border":"208 215 222","color-brand":"124 58 237","color-brand-hover":"109 40 217","color-brand-active":"91 33 182","color-success":"#1a7f37","color-warning":"#faad14","color-error":"#cf222e","border-radius":"6px"},dark:{"color-primary":"15 17 21","color-secondary":"22 27 34","color-elevated":"33 38 45","color-primary-text":"230 237 243","color-primary-text-hover":"139 148 158","color-secondary-text":"139 148 158","color-tertiary-text":"110 118 129","color-primary-border":"48 54 61","color-brand":"139 92 246","color-brand-hover":"124 58 237","color-brand-active":"109 40 217","color-success":"#3fb950","color-warning":"#faad14","color-error":"#f85149","border-radius":"6px"},pink:{"color-primary":"26 13 20","color-secondary":"37 16 27","color-elevated":"48 21 34","color-primary-text":"252 232 240","color-primary-text-hover":"196 144 168","color-secondary-text":"196 144 168","color-tertiary-text":"138 88 112","color-primary-border":"92 45 66","color-brand":"244 114 182","color-brand-hover":"236 72 153","color-brand-active":"219 39 119","color-success":"#34d399","color-warning":"#faad14","color-error":"#fb7185","border-radius":"8px"},amber:{"color-primary":"30 18 0","color-secondary":"40 26 0","color-elevated":"50 31 0","color-primary-text":"242 232 213","color-primary-text-hover":"184 166 138","color-secondary-text":"184 166 138","color-tertiary-text":"122 106 86","color-primary-border":"74 56 0","color-brand":"232 148 58","color-brand-hover":"208 120 40","color-brand-active":"180 100 30","color-success":"#5aad6e","color-warning":"#faad14","color-error":"#c85a4a","border-radius":"6px"},forest:{"color-primary":"6 21 8","color-secondary":"12 31 14","color-elevated":"19 39 22","color-primary-text":"216 240 220","color-primary-text-hover":"136 173 142","color-secondary-text":"136 173 142","color-tertiary-text":"90 122 94","color-primary-border":"44 66 48","color-brand":"74 222 128","color-brand-hover":"34 197 94","color-brand-active":"22 163 74","color-success":"#86efac","color-warning":"#faad14","color-error":"#f87171","border-radius":"6px"},ocean:{"color-primary":"6 14 26","color-secondary":"13 26 46","color-elevated":"18 36 62","color-primary-text":"218 238 255","color-primary-text-hover":"122 181 212","color-secondary-text":"122 181 212","color-tertiary-text":"74 126 154","color-primary-border":"30 58 92","color-brand":"56 189 248","color-brand-hover":"14 165 233","color-brand-active":"2 132 199","color-success":"#34d399","color-warning":"#faad14","color-error":"#f87171","border-radius":"6px"}},x=(r,e)=>{let o=e?H[e]??"0.1":"0.1";return{"color-bg-container":`rgb(var(--${r}-color-secondary))`,"color-text":`rgb(var(--${r}-color-primary-text) / 0.85)`,"color-text-heading":`rgb(var(--${r}-color-primary-text))`,"color-text-disabled":`rgb(var(--${r}-color-primary-text) / 0.25)`,"color-primary-hover":`rgb(var(--${r}-color-brand-hover))`,"color-primary-active":`rgb(var(--${r}-color-brand-active))`,"color-primary-bg":`rgb(var(--${r}-color-brand) / ${o})`,"line-height":"1.5715"}},l={"color-primary":"rgb(var(--${prefix}-color-primary))","color-primary-active":"rgb(var(--${prefix}-color-primary-active))","color-primary-hover":"rgb(var(--${prefix}-color-primary-hover))","color-primary-bg":"rgb(var(--${prefix}-color-primary-bg))","color-secondary":"rgb(var(--${prefix}-color-secondary))","color-elevated":"rgb(var(--${prefix}-color-elevated))","color-primary-text":"rgb(var(--${prefix}-color-primary-text))","color-primary-text-hover":"rgb(var(--${prefix}-color-primary-text-hover))","color-secondary-text":"rgb(var(--${prefix}-color-secondary-text))","color-tertiary-text":"rgb(var(--${prefix}-color-tertiary-text))","color-primary-border":"rgb(var(--${prefix}-color-primary-border))","color-brand":"rgb(var(--${prefix}-color-brand))","color-brand-hover":"rgb(var(--${prefix}-color-brand-hover))","color-brand-active":"rgb(var(--${prefix}-color-brand-active))","color-on-brand":"#ffffff","color-progress-track":"rgb(var(--${prefix}-color-primary-border) / 0.5)","color-bg-container":"rgb(var(--${prefix}-color-bg-container))","font-sans":'var(--font-inter), ui-sans-serif, system-ui, "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei", "Noto Sans SC", sans-serif',"animate-dashboard-skeleton-shimmer":"dashboard-skeleton-shimmer 1.6s ease-in-out infinite"};function w(r,e){return e?`:root, html[data-theme="${r}"], [data-theme="${r}"]`:`html[data-theme="${r}"], [data-theme="${r}"]`}var S={prefix:"fe",themes:{},tokenMapping:l,cssSelector:w};function g(r){let e=d(C,r?.themes||{}),o=d(l,r?.tokenMapping||{}),t=Object.assign({},S,r,{themes:e,tokenMapping:o});return!t.defaultTheme&&t.themes&&(t.defaultTheme=Object.keys(t.themes)[0]),t}function f(r={}){let e=g(r),{prefix:o,themes:t,cssSelector:a,defaultTheme:n}=e,c="";for(let[i,h]of Object.entries(t)){let u=a(i,i===n),V=x(o,i),P={...h,...V};c+=`${u} {
2
+ `;for(let[R,F]of Object.entries(P))c+=` --${o}-${R}: ${F};
3
+ `;c+=`}
4
+
5
+ `}return c}function y(r={}){let e=g(r),{prefix:o,tokenMapping:t=l}=e,a=`@theme {
6
+ `;for(let[n,c]of Object.entries(t)){let i=O(c,o);a+=` --${n}: ${i};
7
+ `}return a+=`}
8
+ `,a}function v(r={}){let e="",o=f(r);return o&&(e+=`@layer base {
9
+ `+o+`}
10
+
11
+ `),e+=y(r),e}var p=$(require("fs"),1),s=$(require("path"),1);var T={"layer-base":"theme-layer-base.css","theme-block":"theme-block.css",full:"theme.css"};function M(r,e){switch(r){case"layer-base":{let o=f(e);return o?`@layer base {
12
+ ${o}}
13
+ `:""}case"theme-block":return y(e);case"full":return v(e);default:return r}}async function U(r,e,o){if(p.default.existsSync(r))if(o)console.warn(`\u26A0\uFE0F Warning: File already exists at ${r}. It will be overwritten.`);else throw new Error(`File already exists at ${r} and overwrite is set to false.`);let t=s.default.dirname(r);p.default.existsSync(t)||p.default.mkdirSync(t,{recursive:!0}),await p.default.promises.writeFile(r,e,"utf-8"),console.log(`\u2705 Theme CSS generated at ${r}`)}function L(r,e){return e.outputPath?s.default.resolve(process.cwd(),e.outputPath):s.default.resolve(process.cwd(),T[r])}async function q(r={}){let{variant:e="full",overwrite:o=!0,outputPath:t,...a}=r,n=t?s.default.resolve(process.cwd(),t):L(e,r),c=M(e,a);return await U(n,c,o),n}async function I(r={}){let{outputDir:e=".",outputPaths:o={},overwrite:t=!0,...a}=r,n=Object.keys(T),c={};for(let i of n){let h=o[i]??s.default.join(e,T[i]),b=s.default.resolve(process.cwd(),h),u=M(i,a);await U(b,u,t),c[i]=b}return c}0&&(module.exports={builtinThemes,defaultConfig,defaultTokenMapping,generateLayerBaseCSS,generateThemeBlockCSS,generateThemeCSS,generateThemeFile,generateThemeFiles,getConfig,getDefaultSelector,getDerivedTokens});
@@ -0,0 +1,88 @@
1
+ type RGBChannels = string;
2
+ type ColorValue = string;
3
+ type ThemeTokens = Record<string, ColorValue | RGBChannels>;
4
+ /** Named themes → token sets (avoids index-signature confusion with `Record<string, ThemeTokens>`) */
5
+ type ThemesMap = Record<string, ThemeTokens>;
6
+ /**
7
+ * Token mapping for the theme.
8
+ *
9
+ * @example
10
+ * {
11
+ * 'color-primary': 'rgb(var(--${prefix}-color-primary))',
12
+ * 'color-secondary': 'rgb(var(--${prefix}-color-secondary))',
13
+ * 'color-elevated': 'rgb(var(--${prefix}-color-elevated))',
14
+ * 'color-primary-text': 'rgb(var(--${prefix}-color-primary-text))',
15
+ * 'color-primary-text-hover': 'rgb(var(--${prefix}-color-primary-text-hover))',
16
+ * 'color-secondary-text': 'rgb(var(--${prefix}-color-secondary-text))',
17
+ * 'color-tertiary-text': 'rgb(var(--${prefix}-color-tertiary-text))',
18
+ * }
19
+ *
20
+ * 最后结果可能=>
21
+ * {
22
+ * '--color-primary': 'rgb(var(--fe-color-primary))',
23
+ * '--color-secondary': 'rgb(var(--fe-color-secondary))',
24
+ * '--color-elevated': 'rgb(var(--fe-color-elevated))',
25
+ * '--color-primary-text': 'rgb(var(--fe-color-primary-text))',
26
+ * '--color-primary-text-hover': 'rgb(var(--fe-color-primary-text-hover))',
27
+ * '--color-secondary-text': 'rgb(var(--fe-color-secondary-text))',
28
+ * '--color-tertiary-text': 'rgb(var(--fe-color-tertiary-text))',
29
+ * }
30
+ */
31
+ type TokenMapping = Record<string, string>;
32
+ interface UiThemeOptions {
33
+ prefix?: string;
34
+ defaultTheme?: string;
35
+ themes?: ThemesMap;
36
+ tokenMapping?: TokenMapping;
37
+ cssSelector?: (themeName: string, root: boolean) => string;
38
+ outputPath?: string;
39
+ overwrite?: boolean;
40
+ }
41
+ declare const builtinThemes: ThemesMap;
42
+ declare const getDerivedTokens: (prefix: string, themeName?: string) => ThemeTokens;
43
+ declare const defaultTokenMapping: TokenMapping;
44
+ declare function getDefaultSelector(themeName: string, root: boolean): string;
45
+ declare const defaultConfig: UiThemeOptions;
46
+ declare function getConfig(options?: UiThemeOptions): Required<UiThemeOptions>;
47
+
48
+ /**
49
+ * 生成 @layer base 中的主题变量 CSS
50
+ * @param options 配置选项 (prefix, themes, cssSelector, defaultTheme)
51
+ * @returns CSS 字符串(不包含外层 @layer 包裹,但包含每个选择器的变量块)
52
+ */
53
+ declare function generateLayerBaseCSS(options?: UiThemeOptions): string;
54
+ /**
55
+ * 生成 @theme 块(供 Tailwind 工具类使用)
56
+ * @param options 配置选项 (prefix, tokenMapping)
57
+ * @returns CSS 字符串
58
+ */
59
+ declare function generateThemeBlockCSS(options?: UiThemeOptions): string;
60
+ /**
61
+ * 生成完整的主题 CSS(包含 @layer base 和 @theme)
62
+ * @param options 配置选项
63
+ * @returns 完整 CSS 字符串
64
+ */
65
+ declare function generateThemeCSS(options?: UiThemeOptions): string;
66
+
67
+ /** CSS variant aligned with {@link core.ts} generators */
68
+ type ThemeCssVariant = 'layer-base' | 'theme-block' | 'full';
69
+ interface GenerateThemeFileOptions extends UiThemeOptions {
70
+ /** Which CSS generator to use. Default: `full` */
71
+ variant?: ThemeCssVariant;
72
+ }
73
+ interface GenerateThemeFilesOptions extends UiThemeOptions {
74
+ /** Directory for default output file names. Default: `.` (cwd) */
75
+ outputDir?: string;
76
+ /** Override output path per variant (relative to cwd unless absolute) */
77
+ outputPaths?: Partial<Record<ThemeCssVariant, string>>;
78
+ }
79
+ /**
80
+ * Write theme CSS to a file using the selected core generator variant.
81
+ */
82
+ declare function generateThemeFile(options?: GenerateThemeFileOptions): Promise<string>;
83
+ /**
84
+ * Write all three theme CSS variants (layer-base, theme-block, full) to files.
85
+ */
86
+ declare function generateThemeFiles(options?: GenerateThemeFilesOptions): Promise<Record<ThemeCssVariant, string>>;
87
+
88
+ export { type ColorValue, type GenerateThemeFileOptions, type GenerateThemeFilesOptions, type RGBChannels, type ThemeCssVariant, type ThemeTokens, type ThemesMap, type TokenMapping, type UiThemeOptions, builtinThemes, defaultConfig, defaultTokenMapping, generateLayerBaseCSS, generateThemeBlockCSS, generateThemeCSS, generateThemeFile, generateThemeFiles, getConfig, getDefaultSelector, getDerivedTokens };