@qlover/tailwind-theme 0.2.1 → 0.3.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 +14 -0
- package/dist/generater.cjs +383 -0
- package/dist/generater.d.cts +68 -0
- package/dist/generater.d.ts +68 -0
- package/dist/generater.js +347 -0
- package/dist/index.cjs +9 -11
- package/dist/index.d.ts +6 -22
- package/dist/index.js +14 -87
- package/dist/plugin.cjs +14 -3
- package/dist/plugin.d.cts +5 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +14 -3
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @qlover/tailwind-theme
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
#### ✨ Features
|
|
8
|
+
|
|
9
|
+
- **tailwind-theme:** Introduce 'generater' module for theme generation ([24e2345](https://github.com/qlover/fe-base/commit/24e2345d7cc1162702362ea3c29b61b6788d7861)) ([#658](https://github.com/qlover/fe-base/pull/658))
|
|
10
|
+
|
|
11
|
+
- **next-oauth:** enhance styling and theme generation for improved UI consistency ([c225d16](https://github.com/qlover/fe-base/commit/c225d164d09c5c71070c309022203295a840c024)) ([#657](https://github.com/qlover/fe-base/pull/657))
|
|
12
|
+
|
|
13
|
+
#### ♻️ Refactors
|
|
14
|
+
|
|
15
|
+
- **UserService, UserStore:** Simplify session persistence logic ([5de703d](https://github.com/qlover/fe-base/commit/5de703daf5a0b96e269a46e4b9360401da657d6d)) ([#669](https://github.com/qlover/fe-base/pull/669))
|
|
16
|
+
|
|
3
17
|
## 0.2.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/generater.ts
|
|
31
|
+
var generater_exports = {};
|
|
32
|
+
__export(generater_exports, {
|
|
33
|
+
generateThemeFile: () => generateThemeFile,
|
|
34
|
+
generateThemeFiles: () => generateThemeFiles
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(generater_exports);
|
|
37
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
38
|
+
var import_path = __toESM(require("path"), 1);
|
|
39
|
+
|
|
40
|
+
// src/utils.ts
|
|
41
|
+
function resolveTokenValue(value, prefix) {
|
|
42
|
+
return value.replace(/\$\{prefix\}/g, prefix);
|
|
43
|
+
}
|
|
44
|
+
function deepMerge(target, source) {
|
|
45
|
+
const result = { ...target };
|
|
46
|
+
for (const key in source) {
|
|
47
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
48
|
+
const sourceVal = source[key];
|
|
49
|
+
const targetVal = result[key];
|
|
50
|
+
if (sourceVal && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal && typeof targetVal === "object") {
|
|
51
|
+
result[key] = deepMerge(
|
|
52
|
+
targetVal,
|
|
53
|
+
sourceVal
|
|
54
|
+
);
|
|
55
|
+
} else {
|
|
56
|
+
result[key] = sourceVal;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/config.ts
|
|
64
|
+
var themePrimaryBgOpacity = {
|
|
65
|
+
light: "0.08",
|
|
66
|
+
dark: "0.12",
|
|
67
|
+
pink: "0.12",
|
|
68
|
+
amber: "0.12",
|
|
69
|
+
forest: "0.1",
|
|
70
|
+
ocean: "0.1"
|
|
71
|
+
};
|
|
72
|
+
var builtinThemes = {
|
|
73
|
+
light: {
|
|
74
|
+
"color-primary": "246 248 250",
|
|
75
|
+
"color-secondary": "255 255 255",
|
|
76
|
+
"color-elevated": "240 242 244",
|
|
77
|
+
"color-primary-text": "31 35 40",
|
|
78
|
+
"color-primary-text-hover": "101 109 118",
|
|
79
|
+
"color-secondary-text": "101 109 118",
|
|
80
|
+
"color-tertiary-text": "140 149 159",
|
|
81
|
+
"color-primary-border": "208 215 222",
|
|
82
|
+
"color-brand": "124 58 237",
|
|
83
|
+
"color-brand-hover": "109 40 217",
|
|
84
|
+
"color-brand-active": "91 33 182",
|
|
85
|
+
"color-success": "#1a7f37",
|
|
86
|
+
"color-warning": "#faad14",
|
|
87
|
+
"color-error": "#cf222e",
|
|
88
|
+
"border-radius": "6px"
|
|
89
|
+
},
|
|
90
|
+
dark: {
|
|
91
|
+
"color-primary": "15 17 21",
|
|
92
|
+
"color-secondary": "22 27 34",
|
|
93
|
+
"color-elevated": "33 38 45",
|
|
94
|
+
"color-primary-text": "230 237 243",
|
|
95
|
+
"color-primary-text-hover": "139 148 158",
|
|
96
|
+
"color-secondary-text": "139 148 158",
|
|
97
|
+
"color-tertiary-text": "110 118 129",
|
|
98
|
+
"color-primary-border": "48 54 61",
|
|
99
|
+
"color-brand": "139 92 246",
|
|
100
|
+
"color-brand-hover": "124 58 237",
|
|
101
|
+
"color-brand-active": "109 40 217",
|
|
102
|
+
"color-success": "#3fb950",
|
|
103
|
+
"color-warning": "#faad14",
|
|
104
|
+
"color-error": "#f85149",
|
|
105
|
+
"border-radius": "6px"
|
|
106
|
+
},
|
|
107
|
+
pink: {
|
|
108
|
+
"color-primary": "26 13 20",
|
|
109
|
+
"color-secondary": "37 16 27",
|
|
110
|
+
"color-elevated": "48 21 34",
|
|
111
|
+
"color-primary-text": "252 232 240",
|
|
112
|
+
"color-primary-text-hover": "196 144 168",
|
|
113
|
+
"color-secondary-text": "196 144 168",
|
|
114
|
+
"color-tertiary-text": "138 88 112",
|
|
115
|
+
"color-primary-border": "92 45 66",
|
|
116
|
+
"color-brand": "244 114 182",
|
|
117
|
+
"color-brand-hover": "236 72 153",
|
|
118
|
+
"color-brand-active": "219 39 119",
|
|
119
|
+
"color-success": "#34d399",
|
|
120
|
+
"color-warning": "#faad14",
|
|
121
|
+
"color-error": "#fb7185",
|
|
122
|
+
"border-radius": "8px"
|
|
123
|
+
},
|
|
124
|
+
amber: {
|
|
125
|
+
"color-primary": "30 18 0",
|
|
126
|
+
"color-secondary": "40 26 0",
|
|
127
|
+
"color-elevated": "50 31 0",
|
|
128
|
+
"color-primary-text": "242 232 213",
|
|
129
|
+
"color-primary-text-hover": "184 166 138",
|
|
130
|
+
"color-secondary-text": "184 166 138",
|
|
131
|
+
"color-tertiary-text": "122 106 86",
|
|
132
|
+
"color-primary-border": "74 56 0",
|
|
133
|
+
"color-brand": "232 148 58",
|
|
134
|
+
"color-brand-hover": "208 120 40",
|
|
135
|
+
"color-brand-active": "180 100 30",
|
|
136
|
+
"color-success": "#5aad6e",
|
|
137
|
+
"color-warning": "#faad14",
|
|
138
|
+
"color-error": "#c85a4a",
|
|
139
|
+
"border-radius": "6px"
|
|
140
|
+
},
|
|
141
|
+
forest: {
|
|
142
|
+
"color-primary": "6 21 8",
|
|
143
|
+
"color-secondary": "12 31 14",
|
|
144
|
+
"color-elevated": "19 39 22",
|
|
145
|
+
"color-primary-text": "216 240 220",
|
|
146
|
+
"color-primary-text-hover": "136 173 142",
|
|
147
|
+
"color-secondary-text": "136 173 142",
|
|
148
|
+
"color-tertiary-text": "90 122 94",
|
|
149
|
+
"color-primary-border": "44 66 48",
|
|
150
|
+
"color-brand": "74 222 128",
|
|
151
|
+
"color-brand-hover": "34 197 94",
|
|
152
|
+
"color-brand-active": "22 163 74",
|
|
153
|
+
"color-success": "#86efac",
|
|
154
|
+
"color-warning": "#faad14",
|
|
155
|
+
"color-error": "#f87171",
|
|
156
|
+
"border-radius": "6px"
|
|
157
|
+
},
|
|
158
|
+
ocean: {
|
|
159
|
+
"color-primary": "6 14 26",
|
|
160
|
+
"color-secondary": "13 26 46",
|
|
161
|
+
"color-elevated": "18 36 62",
|
|
162
|
+
"color-primary-text": "218 238 255",
|
|
163
|
+
"color-primary-text-hover": "122 181 212",
|
|
164
|
+
"color-secondary-text": "122 181 212",
|
|
165
|
+
"color-tertiary-text": "74 126 154",
|
|
166
|
+
"color-primary-border": "30 58 92",
|
|
167
|
+
"color-brand": "56 189 248",
|
|
168
|
+
"color-brand-hover": "14 165 233",
|
|
169
|
+
"color-brand-active": "2 132 199",
|
|
170
|
+
"color-success": "#34d399",
|
|
171
|
+
"color-warning": "#faad14",
|
|
172
|
+
"color-error": "#f87171",
|
|
173
|
+
"border-radius": "6px"
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
var getDerivedTokens = (prefix, themeName) => {
|
|
177
|
+
const opacity = themeName ? themePrimaryBgOpacity[themeName] ?? "0.1" : "0.1";
|
|
178
|
+
return {
|
|
179
|
+
"color-bg-container": `rgb(var(--${prefix}-color-secondary))`,
|
|
180
|
+
"color-text": `rgb(var(--${prefix}-color-primary-text) / 0.85)`,
|
|
181
|
+
"color-text-heading": `rgb(var(--${prefix}-color-primary-text))`,
|
|
182
|
+
"color-text-disabled": `rgb(var(--${prefix}-color-primary-text) / 0.25)`,
|
|
183
|
+
"color-primary-hover": `rgb(var(--${prefix}-color-brand-hover))`,
|
|
184
|
+
"color-primary-active": `rgb(var(--${prefix}-color-brand-active))`,
|
|
185
|
+
"color-primary-bg": `rgb(var(--${prefix}-color-brand) / ${opacity})`,
|
|
186
|
+
"line-height": "1.5715"
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
var defaultTokenMapping = {
|
|
190
|
+
"color-primary": "rgb(var(--${prefix}-color-primary))",
|
|
191
|
+
"color-primary-active": "rgb(var(--${prefix}-color-primary-active))",
|
|
192
|
+
"color-primary-hover": "rgb(var(--${prefix}-color-primary-hover))",
|
|
193
|
+
"color-primary-bg": "rgb(var(--${prefix}-color-primary-bg))",
|
|
194
|
+
"color-secondary": "rgb(var(--${prefix}-color-secondary))",
|
|
195
|
+
"color-elevated": "rgb(var(--${prefix}-color-elevated))",
|
|
196
|
+
"color-primary-text": "rgb(var(--${prefix}-color-primary-text))",
|
|
197
|
+
"color-primary-text-hover": "rgb(var(--${prefix}-color-primary-text-hover))",
|
|
198
|
+
"color-secondary-text": "rgb(var(--${prefix}-color-secondary-text))",
|
|
199
|
+
"color-tertiary-text": "rgb(var(--${prefix}-color-tertiary-text))",
|
|
200
|
+
"color-primary-border": "rgb(var(--${prefix}-color-primary-border))",
|
|
201
|
+
"color-brand": "rgb(var(--${prefix}-color-brand))",
|
|
202
|
+
"color-brand-hover": "rgb(var(--${prefix}-color-brand-hover))",
|
|
203
|
+
"color-brand-active": "rgb(var(--${prefix}-color-brand-active))",
|
|
204
|
+
/** Text/icons on brand-colored surfaces (buttons, badges) */
|
|
205
|
+
"color-on-brand": "#ffffff",
|
|
206
|
+
"color-progress-track": "rgb(var(--${prefix}-color-primary-border) / 0.5)",
|
|
207
|
+
"color-bg-container": "rgb(var(--${prefix}-color-bg-container))",
|
|
208
|
+
"font-sans": 'var(--font-inter), ui-sans-serif, system-ui, "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei", "Noto Sans SC", sans-serif',
|
|
209
|
+
"animate-dashboard-skeleton-shimmer": "dashboard-skeleton-shimmer 1.6s ease-in-out infinite"
|
|
210
|
+
};
|
|
211
|
+
function getDefaultSelector(themeName, root) {
|
|
212
|
+
if (root) {
|
|
213
|
+
return `:root, html[data-theme="${themeName}"], [data-theme="${themeName}"]`;
|
|
214
|
+
}
|
|
215
|
+
return `html[data-theme="${themeName}"], [data-theme="${themeName}"]`;
|
|
216
|
+
}
|
|
217
|
+
var defaultConfig = {
|
|
218
|
+
prefix: "fe",
|
|
219
|
+
themes: {},
|
|
220
|
+
tokenMapping: defaultTokenMapping,
|
|
221
|
+
cssSelector: getDefaultSelector
|
|
222
|
+
};
|
|
223
|
+
function getConfig(options) {
|
|
224
|
+
let allThemes = deepMerge(builtinThemes, options?.themes || {});
|
|
225
|
+
const includeThemes = options?.includeThemes;
|
|
226
|
+
if (includeThemes?.length) {
|
|
227
|
+
const filtered = {};
|
|
228
|
+
for (const name of includeThemes) {
|
|
229
|
+
if (allThemes[name]) {
|
|
230
|
+
filtered[name] = allThemes[name];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
allThemes = filtered;
|
|
234
|
+
}
|
|
235
|
+
const allMappings = deepMerge(
|
|
236
|
+
defaultTokenMapping,
|
|
237
|
+
options?.tokenMapping || {}
|
|
238
|
+
);
|
|
239
|
+
const config = Object.assign(
|
|
240
|
+
{},
|
|
241
|
+
defaultConfig,
|
|
242
|
+
options,
|
|
243
|
+
{
|
|
244
|
+
themes: allThemes,
|
|
245
|
+
tokenMapping: allMappings,
|
|
246
|
+
includeThemes: includeThemes ?? []
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
if (!config.defaultTheme || !config.themes[config.defaultTheme]) {
|
|
250
|
+
config.defaultTheme = Object.keys(config.themes)[0];
|
|
251
|
+
}
|
|
252
|
+
return config;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/core.ts
|
|
256
|
+
function generateLayerBaseCSS(options = {}) {
|
|
257
|
+
const config = getConfig(options);
|
|
258
|
+
const { prefix, themes, cssSelector, defaultTheme } = config;
|
|
259
|
+
let css = "";
|
|
260
|
+
for (const [themeName, vars] of Object.entries(themes)) {
|
|
261
|
+
const isDefault = themeName === defaultTheme;
|
|
262
|
+
const selector = cssSelector(themeName, isDefault);
|
|
263
|
+
const themeDerived = getDerivedTokens(prefix, themeName);
|
|
264
|
+
const merged = {
|
|
265
|
+
...vars,
|
|
266
|
+
...themeDerived
|
|
267
|
+
};
|
|
268
|
+
css += `${selector} {
|
|
269
|
+
`;
|
|
270
|
+
for (const [varName, value] of Object.entries(merged)) {
|
|
271
|
+
css += ` --${prefix}-${varName}: ${value};
|
|
272
|
+
`;
|
|
273
|
+
}
|
|
274
|
+
css += "}\n\n";
|
|
275
|
+
}
|
|
276
|
+
return css;
|
|
277
|
+
}
|
|
278
|
+
function generateThemeBlockCSS(options = {}) {
|
|
279
|
+
const config = getConfig(options);
|
|
280
|
+
const { prefix, tokenMapping = defaultTokenMapping } = config;
|
|
281
|
+
let css = "@theme {\n";
|
|
282
|
+
for (const [tokenName, tokenValue] of Object.entries(tokenMapping)) {
|
|
283
|
+
const finalValue = resolveTokenValue(tokenValue, prefix);
|
|
284
|
+
css += ` --${tokenName}: ${finalValue};
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
css += "}\n";
|
|
288
|
+
return css;
|
|
289
|
+
}
|
|
290
|
+
function generateThemeCSS(options = {}) {
|
|
291
|
+
let css = "";
|
|
292
|
+
const layerBaseContent = generateLayerBaseCSS(options);
|
|
293
|
+
if (layerBaseContent) {
|
|
294
|
+
css += "@layer base {\n" + layerBaseContent + "}\n\n";
|
|
295
|
+
}
|
|
296
|
+
css += generateThemeBlockCSS(options);
|
|
297
|
+
return css;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/generater.ts
|
|
301
|
+
var DEFAULT_OUTPUT_PATHS = {
|
|
302
|
+
"layer-base": "theme-layer-base.css",
|
|
303
|
+
"theme-block": "theme-block.css",
|
|
304
|
+
full: "theme.css"
|
|
305
|
+
};
|
|
306
|
+
function resolveCssContent(variant, options) {
|
|
307
|
+
switch (variant) {
|
|
308
|
+
case "layer-base": {
|
|
309
|
+
const layerBaseContent = generateLayerBaseCSS(options);
|
|
310
|
+
return layerBaseContent ? `@layer base {
|
|
311
|
+
${layerBaseContent}}
|
|
312
|
+
` : "";
|
|
313
|
+
}
|
|
314
|
+
case "theme-block":
|
|
315
|
+
return generateThemeBlockCSS(options);
|
|
316
|
+
case "full":
|
|
317
|
+
return generateThemeCSS(options);
|
|
318
|
+
default: {
|
|
319
|
+
const _exhaustive = variant;
|
|
320
|
+
return _exhaustive;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async function writeCssFile(absolutePath, css, overwrite) {
|
|
325
|
+
if (import_fs.default.existsSync(absolutePath)) {
|
|
326
|
+
if (overwrite) {
|
|
327
|
+
console.warn(
|
|
328
|
+
`\u26A0\uFE0F Warning: File already exists at ${absolutePath}. It will be overwritten.`
|
|
329
|
+
);
|
|
330
|
+
} else {
|
|
331
|
+
throw new Error(
|
|
332
|
+
`File already exists at ${absolutePath} and overwrite is set to false.`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const dir = import_path.default.dirname(absolutePath);
|
|
337
|
+
if (!import_fs.default.existsSync(dir)) {
|
|
338
|
+
import_fs.default.mkdirSync(dir, { recursive: true });
|
|
339
|
+
}
|
|
340
|
+
await import_fs.default.promises.writeFile(absolutePath, css, "utf-8");
|
|
341
|
+
console.log(`\u2705 Theme CSS generated at ${absolutePath}`);
|
|
342
|
+
}
|
|
343
|
+
function resolveOutputPath(variant, options) {
|
|
344
|
+
if (options.outputPath) {
|
|
345
|
+
return import_path.default.resolve(process.cwd(), options.outputPath);
|
|
346
|
+
}
|
|
347
|
+
return import_path.default.resolve(process.cwd(), DEFAULT_OUTPUT_PATHS[variant]);
|
|
348
|
+
}
|
|
349
|
+
async function generateThemeFile(options = {}) {
|
|
350
|
+
const {
|
|
351
|
+
variant = "full",
|
|
352
|
+
overwrite = true,
|
|
353
|
+
outputPath,
|
|
354
|
+
...restOptions
|
|
355
|
+
} = options;
|
|
356
|
+
const absolutePath = outputPath ? import_path.default.resolve(process.cwd(), outputPath) : resolveOutputPath(variant, options);
|
|
357
|
+
const css = resolveCssContent(variant, restOptions);
|
|
358
|
+
await writeCssFile(absolutePath, css, overwrite);
|
|
359
|
+
return absolutePath;
|
|
360
|
+
}
|
|
361
|
+
async function generateThemeFiles(options = {}) {
|
|
362
|
+
const {
|
|
363
|
+
outputDir = ".",
|
|
364
|
+
outputPaths = {},
|
|
365
|
+
overwrite = true,
|
|
366
|
+
...restOptions
|
|
367
|
+
} = options;
|
|
368
|
+
const variants = Object.keys(DEFAULT_OUTPUT_PATHS);
|
|
369
|
+
const result = {};
|
|
370
|
+
for (const variant of variants) {
|
|
371
|
+
const relativePath = outputPaths[variant] ?? import_path.default.join(outputDir, DEFAULT_OUTPUT_PATHS[variant]);
|
|
372
|
+
const absolutePath = import_path.default.resolve(process.cwd(), relativePath);
|
|
373
|
+
const css = resolveCssContent(variant, restOptions);
|
|
374
|
+
await writeCssFile(absolutePath, css, overwrite);
|
|
375
|
+
result[variant] = absolutePath;
|
|
376
|
+
}
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
380
|
+
0 && (module.exports = {
|
|
381
|
+
generateThemeFile,
|
|
382
|
+
generateThemeFiles
|
|
383
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
/**
|
|
37
|
+
* When set, only these theme names are emitted (after merging builtins).
|
|
38
|
+
* Use to keep app CSS small when the package ships extra demo themes.
|
|
39
|
+
*/
|
|
40
|
+
includeThemes?: string[];
|
|
41
|
+
tokenMapping?: TokenMapping;
|
|
42
|
+
cssSelector?: (themeName: string, root: boolean) => string;
|
|
43
|
+
outputPath?: string;
|
|
44
|
+
overwrite?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** CSS variant aligned with {@link core.ts} generators */
|
|
48
|
+
type ThemeCssVariant = 'layer-base' | 'theme-block' | 'full';
|
|
49
|
+
interface GenerateThemeFileOptions extends UiThemeOptions {
|
|
50
|
+
/** Which CSS generator to use. Default: `full` */
|
|
51
|
+
variant?: ThemeCssVariant;
|
|
52
|
+
}
|
|
53
|
+
interface GenerateThemeFilesOptions extends UiThemeOptions {
|
|
54
|
+
/** Directory for default output file names. Default: `.` (cwd) */
|
|
55
|
+
outputDir?: string;
|
|
56
|
+
/** Override output path per variant (relative to cwd unless absolute) */
|
|
57
|
+
outputPaths?: Partial<Record<ThemeCssVariant, string>>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Write theme CSS to a file using the selected core generator variant.
|
|
61
|
+
*/
|
|
62
|
+
declare function generateThemeFile(options?: GenerateThemeFileOptions): Promise<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Write all three theme CSS variants (layer-base, theme-block, full) to files.
|
|
65
|
+
*/
|
|
66
|
+
declare function generateThemeFiles(options?: GenerateThemeFilesOptions): Promise<Record<ThemeCssVariant, string>>;
|
|
67
|
+
|
|
68
|
+
export { type GenerateThemeFileOptions, type GenerateThemeFilesOptions, type ThemeCssVariant, generateThemeFile, generateThemeFiles };
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
/**
|
|
37
|
+
* When set, only these theme names are emitted (after merging builtins).
|
|
38
|
+
* Use to keep app CSS small when the package ships extra demo themes.
|
|
39
|
+
*/
|
|
40
|
+
includeThemes?: string[];
|
|
41
|
+
tokenMapping?: TokenMapping;
|
|
42
|
+
cssSelector?: (themeName: string, root: boolean) => string;
|
|
43
|
+
outputPath?: string;
|
|
44
|
+
overwrite?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** CSS variant aligned with {@link core.ts} generators */
|
|
48
|
+
type ThemeCssVariant = 'layer-base' | 'theme-block' | 'full';
|
|
49
|
+
interface GenerateThemeFileOptions extends UiThemeOptions {
|
|
50
|
+
/** Which CSS generator to use. Default: `full` */
|
|
51
|
+
variant?: ThemeCssVariant;
|
|
52
|
+
}
|
|
53
|
+
interface GenerateThemeFilesOptions extends UiThemeOptions {
|
|
54
|
+
/** Directory for default output file names. Default: `.` (cwd) */
|
|
55
|
+
outputDir?: string;
|
|
56
|
+
/** Override output path per variant (relative to cwd unless absolute) */
|
|
57
|
+
outputPaths?: Partial<Record<ThemeCssVariant, string>>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Write theme CSS to a file using the selected core generator variant.
|
|
61
|
+
*/
|
|
62
|
+
declare function generateThemeFile(options?: GenerateThemeFileOptions): Promise<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Write all three theme CSS variants (layer-base, theme-block, full) to files.
|
|
65
|
+
*/
|
|
66
|
+
declare function generateThemeFiles(options?: GenerateThemeFilesOptions): Promise<Record<ThemeCssVariant, string>>;
|
|
67
|
+
|
|
68
|
+
export { type GenerateThemeFileOptions, type GenerateThemeFilesOptions, type ThemeCssVariant, generateThemeFile, generateThemeFiles };
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
// src/generater.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
// src/utils.ts
|
|
6
|
+
function resolveTokenValue(value, prefix) {
|
|
7
|
+
return value.replace(/\$\{prefix\}/g, prefix);
|
|
8
|
+
}
|
|
9
|
+
function deepMerge(target, source) {
|
|
10
|
+
const result = { ...target };
|
|
11
|
+
for (const key in source) {
|
|
12
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
13
|
+
const sourceVal = source[key];
|
|
14
|
+
const targetVal = result[key];
|
|
15
|
+
if (sourceVal && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal && typeof targetVal === "object") {
|
|
16
|
+
result[key] = deepMerge(
|
|
17
|
+
targetVal,
|
|
18
|
+
sourceVal
|
|
19
|
+
);
|
|
20
|
+
} else {
|
|
21
|
+
result[key] = sourceVal;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/config.ts
|
|
29
|
+
var themePrimaryBgOpacity = {
|
|
30
|
+
light: "0.08",
|
|
31
|
+
dark: "0.12",
|
|
32
|
+
pink: "0.12",
|
|
33
|
+
amber: "0.12",
|
|
34
|
+
forest: "0.1",
|
|
35
|
+
ocean: "0.1"
|
|
36
|
+
};
|
|
37
|
+
var builtinThemes = {
|
|
38
|
+
light: {
|
|
39
|
+
"color-primary": "246 248 250",
|
|
40
|
+
"color-secondary": "255 255 255",
|
|
41
|
+
"color-elevated": "240 242 244",
|
|
42
|
+
"color-primary-text": "31 35 40",
|
|
43
|
+
"color-primary-text-hover": "101 109 118",
|
|
44
|
+
"color-secondary-text": "101 109 118",
|
|
45
|
+
"color-tertiary-text": "140 149 159",
|
|
46
|
+
"color-primary-border": "208 215 222",
|
|
47
|
+
"color-brand": "124 58 237",
|
|
48
|
+
"color-brand-hover": "109 40 217",
|
|
49
|
+
"color-brand-active": "91 33 182",
|
|
50
|
+
"color-success": "#1a7f37",
|
|
51
|
+
"color-warning": "#faad14",
|
|
52
|
+
"color-error": "#cf222e",
|
|
53
|
+
"border-radius": "6px"
|
|
54
|
+
},
|
|
55
|
+
dark: {
|
|
56
|
+
"color-primary": "15 17 21",
|
|
57
|
+
"color-secondary": "22 27 34",
|
|
58
|
+
"color-elevated": "33 38 45",
|
|
59
|
+
"color-primary-text": "230 237 243",
|
|
60
|
+
"color-primary-text-hover": "139 148 158",
|
|
61
|
+
"color-secondary-text": "139 148 158",
|
|
62
|
+
"color-tertiary-text": "110 118 129",
|
|
63
|
+
"color-primary-border": "48 54 61",
|
|
64
|
+
"color-brand": "139 92 246",
|
|
65
|
+
"color-brand-hover": "124 58 237",
|
|
66
|
+
"color-brand-active": "109 40 217",
|
|
67
|
+
"color-success": "#3fb950",
|
|
68
|
+
"color-warning": "#faad14",
|
|
69
|
+
"color-error": "#f85149",
|
|
70
|
+
"border-radius": "6px"
|
|
71
|
+
},
|
|
72
|
+
pink: {
|
|
73
|
+
"color-primary": "26 13 20",
|
|
74
|
+
"color-secondary": "37 16 27",
|
|
75
|
+
"color-elevated": "48 21 34",
|
|
76
|
+
"color-primary-text": "252 232 240",
|
|
77
|
+
"color-primary-text-hover": "196 144 168",
|
|
78
|
+
"color-secondary-text": "196 144 168",
|
|
79
|
+
"color-tertiary-text": "138 88 112",
|
|
80
|
+
"color-primary-border": "92 45 66",
|
|
81
|
+
"color-brand": "244 114 182",
|
|
82
|
+
"color-brand-hover": "236 72 153",
|
|
83
|
+
"color-brand-active": "219 39 119",
|
|
84
|
+
"color-success": "#34d399",
|
|
85
|
+
"color-warning": "#faad14",
|
|
86
|
+
"color-error": "#fb7185",
|
|
87
|
+
"border-radius": "8px"
|
|
88
|
+
},
|
|
89
|
+
amber: {
|
|
90
|
+
"color-primary": "30 18 0",
|
|
91
|
+
"color-secondary": "40 26 0",
|
|
92
|
+
"color-elevated": "50 31 0",
|
|
93
|
+
"color-primary-text": "242 232 213",
|
|
94
|
+
"color-primary-text-hover": "184 166 138",
|
|
95
|
+
"color-secondary-text": "184 166 138",
|
|
96
|
+
"color-tertiary-text": "122 106 86",
|
|
97
|
+
"color-primary-border": "74 56 0",
|
|
98
|
+
"color-brand": "232 148 58",
|
|
99
|
+
"color-brand-hover": "208 120 40",
|
|
100
|
+
"color-brand-active": "180 100 30",
|
|
101
|
+
"color-success": "#5aad6e",
|
|
102
|
+
"color-warning": "#faad14",
|
|
103
|
+
"color-error": "#c85a4a",
|
|
104
|
+
"border-radius": "6px"
|
|
105
|
+
},
|
|
106
|
+
forest: {
|
|
107
|
+
"color-primary": "6 21 8",
|
|
108
|
+
"color-secondary": "12 31 14",
|
|
109
|
+
"color-elevated": "19 39 22",
|
|
110
|
+
"color-primary-text": "216 240 220",
|
|
111
|
+
"color-primary-text-hover": "136 173 142",
|
|
112
|
+
"color-secondary-text": "136 173 142",
|
|
113
|
+
"color-tertiary-text": "90 122 94",
|
|
114
|
+
"color-primary-border": "44 66 48",
|
|
115
|
+
"color-brand": "74 222 128",
|
|
116
|
+
"color-brand-hover": "34 197 94",
|
|
117
|
+
"color-brand-active": "22 163 74",
|
|
118
|
+
"color-success": "#86efac",
|
|
119
|
+
"color-warning": "#faad14",
|
|
120
|
+
"color-error": "#f87171",
|
|
121
|
+
"border-radius": "6px"
|
|
122
|
+
},
|
|
123
|
+
ocean: {
|
|
124
|
+
"color-primary": "6 14 26",
|
|
125
|
+
"color-secondary": "13 26 46",
|
|
126
|
+
"color-elevated": "18 36 62",
|
|
127
|
+
"color-primary-text": "218 238 255",
|
|
128
|
+
"color-primary-text-hover": "122 181 212",
|
|
129
|
+
"color-secondary-text": "122 181 212",
|
|
130
|
+
"color-tertiary-text": "74 126 154",
|
|
131
|
+
"color-primary-border": "30 58 92",
|
|
132
|
+
"color-brand": "56 189 248",
|
|
133
|
+
"color-brand-hover": "14 165 233",
|
|
134
|
+
"color-brand-active": "2 132 199",
|
|
135
|
+
"color-success": "#34d399",
|
|
136
|
+
"color-warning": "#faad14",
|
|
137
|
+
"color-error": "#f87171",
|
|
138
|
+
"border-radius": "6px"
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
var getDerivedTokens = (prefix, themeName) => {
|
|
142
|
+
const opacity = themeName ? themePrimaryBgOpacity[themeName] ?? "0.1" : "0.1";
|
|
143
|
+
return {
|
|
144
|
+
"color-bg-container": `rgb(var(--${prefix}-color-secondary))`,
|
|
145
|
+
"color-text": `rgb(var(--${prefix}-color-primary-text) / 0.85)`,
|
|
146
|
+
"color-text-heading": `rgb(var(--${prefix}-color-primary-text))`,
|
|
147
|
+
"color-text-disabled": `rgb(var(--${prefix}-color-primary-text) / 0.25)`,
|
|
148
|
+
"color-primary-hover": `rgb(var(--${prefix}-color-brand-hover))`,
|
|
149
|
+
"color-primary-active": `rgb(var(--${prefix}-color-brand-active))`,
|
|
150
|
+
"color-primary-bg": `rgb(var(--${prefix}-color-brand) / ${opacity})`,
|
|
151
|
+
"line-height": "1.5715"
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
var defaultTokenMapping = {
|
|
155
|
+
"color-primary": "rgb(var(--${prefix}-color-primary))",
|
|
156
|
+
"color-primary-active": "rgb(var(--${prefix}-color-primary-active))",
|
|
157
|
+
"color-primary-hover": "rgb(var(--${prefix}-color-primary-hover))",
|
|
158
|
+
"color-primary-bg": "rgb(var(--${prefix}-color-primary-bg))",
|
|
159
|
+
"color-secondary": "rgb(var(--${prefix}-color-secondary))",
|
|
160
|
+
"color-elevated": "rgb(var(--${prefix}-color-elevated))",
|
|
161
|
+
"color-primary-text": "rgb(var(--${prefix}-color-primary-text))",
|
|
162
|
+
"color-primary-text-hover": "rgb(var(--${prefix}-color-primary-text-hover))",
|
|
163
|
+
"color-secondary-text": "rgb(var(--${prefix}-color-secondary-text))",
|
|
164
|
+
"color-tertiary-text": "rgb(var(--${prefix}-color-tertiary-text))",
|
|
165
|
+
"color-primary-border": "rgb(var(--${prefix}-color-primary-border))",
|
|
166
|
+
"color-brand": "rgb(var(--${prefix}-color-brand))",
|
|
167
|
+
"color-brand-hover": "rgb(var(--${prefix}-color-brand-hover))",
|
|
168
|
+
"color-brand-active": "rgb(var(--${prefix}-color-brand-active))",
|
|
169
|
+
/** Text/icons on brand-colored surfaces (buttons, badges) */
|
|
170
|
+
"color-on-brand": "#ffffff",
|
|
171
|
+
"color-progress-track": "rgb(var(--${prefix}-color-primary-border) / 0.5)",
|
|
172
|
+
"color-bg-container": "rgb(var(--${prefix}-color-bg-container))",
|
|
173
|
+
"font-sans": 'var(--font-inter), ui-sans-serif, system-ui, "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei", "Noto Sans SC", sans-serif',
|
|
174
|
+
"animate-dashboard-skeleton-shimmer": "dashboard-skeleton-shimmer 1.6s ease-in-out infinite"
|
|
175
|
+
};
|
|
176
|
+
function getDefaultSelector(themeName, root) {
|
|
177
|
+
if (root) {
|
|
178
|
+
return `:root, html[data-theme="${themeName}"], [data-theme="${themeName}"]`;
|
|
179
|
+
}
|
|
180
|
+
return `html[data-theme="${themeName}"], [data-theme="${themeName}"]`;
|
|
181
|
+
}
|
|
182
|
+
var defaultConfig = {
|
|
183
|
+
prefix: "fe",
|
|
184
|
+
themes: {},
|
|
185
|
+
tokenMapping: defaultTokenMapping,
|
|
186
|
+
cssSelector: getDefaultSelector
|
|
187
|
+
};
|
|
188
|
+
function getConfig(options) {
|
|
189
|
+
let allThemes = deepMerge(builtinThemes, options?.themes || {});
|
|
190
|
+
const includeThemes = options?.includeThemes;
|
|
191
|
+
if (includeThemes?.length) {
|
|
192
|
+
const filtered = {};
|
|
193
|
+
for (const name of includeThemes) {
|
|
194
|
+
if (allThemes[name]) {
|
|
195
|
+
filtered[name] = allThemes[name];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
allThemes = filtered;
|
|
199
|
+
}
|
|
200
|
+
const allMappings = deepMerge(
|
|
201
|
+
defaultTokenMapping,
|
|
202
|
+
options?.tokenMapping || {}
|
|
203
|
+
);
|
|
204
|
+
const config = Object.assign(
|
|
205
|
+
{},
|
|
206
|
+
defaultConfig,
|
|
207
|
+
options,
|
|
208
|
+
{
|
|
209
|
+
themes: allThemes,
|
|
210
|
+
tokenMapping: allMappings,
|
|
211
|
+
includeThemes: includeThemes ?? []
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
if (!config.defaultTheme || !config.themes[config.defaultTheme]) {
|
|
215
|
+
config.defaultTheme = Object.keys(config.themes)[0];
|
|
216
|
+
}
|
|
217
|
+
return config;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/core.ts
|
|
221
|
+
function generateLayerBaseCSS(options = {}) {
|
|
222
|
+
const config = getConfig(options);
|
|
223
|
+
const { prefix, themes, cssSelector, defaultTheme } = config;
|
|
224
|
+
let css = "";
|
|
225
|
+
for (const [themeName, vars] of Object.entries(themes)) {
|
|
226
|
+
const isDefault = themeName === defaultTheme;
|
|
227
|
+
const selector = cssSelector(themeName, isDefault);
|
|
228
|
+
const themeDerived = getDerivedTokens(prefix, themeName);
|
|
229
|
+
const merged = {
|
|
230
|
+
...vars,
|
|
231
|
+
...themeDerived
|
|
232
|
+
};
|
|
233
|
+
css += `${selector} {
|
|
234
|
+
`;
|
|
235
|
+
for (const [varName, value] of Object.entries(merged)) {
|
|
236
|
+
css += ` --${prefix}-${varName}: ${value};
|
|
237
|
+
`;
|
|
238
|
+
}
|
|
239
|
+
css += "}\n\n";
|
|
240
|
+
}
|
|
241
|
+
return css;
|
|
242
|
+
}
|
|
243
|
+
function generateThemeBlockCSS(options = {}) {
|
|
244
|
+
const config = getConfig(options);
|
|
245
|
+
const { prefix, tokenMapping = defaultTokenMapping } = config;
|
|
246
|
+
let css = "@theme {\n";
|
|
247
|
+
for (const [tokenName, tokenValue] of Object.entries(tokenMapping)) {
|
|
248
|
+
const finalValue = resolveTokenValue(tokenValue, prefix);
|
|
249
|
+
css += ` --${tokenName}: ${finalValue};
|
|
250
|
+
`;
|
|
251
|
+
}
|
|
252
|
+
css += "}\n";
|
|
253
|
+
return css;
|
|
254
|
+
}
|
|
255
|
+
function generateThemeCSS(options = {}) {
|
|
256
|
+
let css = "";
|
|
257
|
+
const layerBaseContent = generateLayerBaseCSS(options);
|
|
258
|
+
if (layerBaseContent) {
|
|
259
|
+
css += "@layer base {\n" + layerBaseContent + "}\n\n";
|
|
260
|
+
}
|
|
261
|
+
css += generateThemeBlockCSS(options);
|
|
262
|
+
return css;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/generater.ts
|
|
266
|
+
var DEFAULT_OUTPUT_PATHS = {
|
|
267
|
+
"layer-base": "theme-layer-base.css",
|
|
268
|
+
"theme-block": "theme-block.css",
|
|
269
|
+
full: "theme.css"
|
|
270
|
+
};
|
|
271
|
+
function resolveCssContent(variant, options) {
|
|
272
|
+
switch (variant) {
|
|
273
|
+
case "layer-base": {
|
|
274
|
+
const layerBaseContent = generateLayerBaseCSS(options);
|
|
275
|
+
return layerBaseContent ? `@layer base {
|
|
276
|
+
${layerBaseContent}}
|
|
277
|
+
` : "";
|
|
278
|
+
}
|
|
279
|
+
case "theme-block":
|
|
280
|
+
return generateThemeBlockCSS(options);
|
|
281
|
+
case "full":
|
|
282
|
+
return generateThemeCSS(options);
|
|
283
|
+
default: {
|
|
284
|
+
const _exhaustive = variant;
|
|
285
|
+
return _exhaustive;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function writeCssFile(absolutePath, css, overwrite) {
|
|
290
|
+
if (fs.existsSync(absolutePath)) {
|
|
291
|
+
if (overwrite) {
|
|
292
|
+
console.warn(
|
|
293
|
+
`\u26A0\uFE0F Warning: File already exists at ${absolutePath}. It will be overwritten.`
|
|
294
|
+
);
|
|
295
|
+
} else {
|
|
296
|
+
throw new Error(
|
|
297
|
+
`File already exists at ${absolutePath} and overwrite is set to false.`
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const dir = path.dirname(absolutePath);
|
|
302
|
+
if (!fs.existsSync(dir)) {
|
|
303
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
304
|
+
}
|
|
305
|
+
await fs.promises.writeFile(absolutePath, css, "utf-8");
|
|
306
|
+
console.log(`\u2705 Theme CSS generated at ${absolutePath}`);
|
|
307
|
+
}
|
|
308
|
+
function resolveOutputPath(variant, options) {
|
|
309
|
+
if (options.outputPath) {
|
|
310
|
+
return path.resolve(process.cwd(), options.outputPath);
|
|
311
|
+
}
|
|
312
|
+
return path.resolve(process.cwd(), DEFAULT_OUTPUT_PATHS[variant]);
|
|
313
|
+
}
|
|
314
|
+
async function generateThemeFile(options = {}) {
|
|
315
|
+
const {
|
|
316
|
+
variant = "full",
|
|
317
|
+
overwrite = true,
|
|
318
|
+
outputPath,
|
|
319
|
+
...restOptions
|
|
320
|
+
} = options;
|
|
321
|
+
const absolutePath = outputPath ? path.resolve(process.cwd(), outputPath) : resolveOutputPath(variant, options);
|
|
322
|
+
const css = resolveCssContent(variant, restOptions);
|
|
323
|
+
await writeCssFile(absolutePath, css, overwrite);
|
|
324
|
+
return absolutePath;
|
|
325
|
+
}
|
|
326
|
+
async function generateThemeFiles(options = {}) {
|
|
327
|
+
const {
|
|
328
|
+
outputDir = ".",
|
|
329
|
+
outputPaths = {},
|
|
330
|
+
overwrite = true,
|
|
331
|
+
...restOptions
|
|
332
|
+
} = options;
|
|
333
|
+
const variants = Object.keys(DEFAULT_OUTPUT_PATHS);
|
|
334
|
+
const result = {};
|
|
335
|
+
for (const variant of variants) {
|
|
336
|
+
const relativePath = outputPaths[variant] ?? path.join(outputDir, DEFAULT_OUTPUT_PATHS[variant]);
|
|
337
|
+
const absolutePath = path.resolve(process.cwd(), relativePath);
|
|
338
|
+
const css = resolveCssContent(variant, restOptions);
|
|
339
|
+
await writeCssFile(absolutePath, css, overwrite);
|
|
340
|
+
result[variant] = absolutePath;
|
|
341
|
+
}
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
344
|
+
export {
|
|
345
|
+
generateThemeFile,
|
|
346
|
+
generateThemeFiles
|
|
347
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`;for(let[
|
|
3
|
-
`;
|
|
1
|
+
"use strict";var d=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var w=(r,o)=>{for(var t in o)d(r,t,{get:o[t],enumerable:!0})},R=(r,o,t,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of C(o))!S.call(r,e)&&e!==t&&d(r,e,{get:()=>o[e],enumerable:!(a=O(o,e))||a.enumerable});return r};var U=r=>R(d({},"__esModule",{value:!0}),r);var B={};w(B,{builtinThemes:()=>f,defaultConfig:()=>b,defaultTokenMapping:()=>l,generateLayerBaseCSS:()=>x,generateThemeBlockCSS:()=>h,generateThemeCSS:()=>V,getConfig:()=>p,getDefaultSelector:()=>y,getDerivedTokens:()=>m});module.exports=U(B);function g(r,o){return r.replace(/\$\{prefix\}/g,o)}function s(r,o){let t={...r};for(let a in o)if(Object.prototype.hasOwnProperty.call(o,a)){let e=o[a],c=t[a];e&&typeof e=="object"&&!Array.isArray(e)&&c&&typeof c=="object"?t[a]=s(c,e):t[a]=e}return t}var j={light:"0.08",dark:"0.12",pink:"0.12",amber:"0.12",forest:"0.1",ocean:"0.1"},f={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"}},m=(r,o)=>{let t=o?j[o]??"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) / ${t})`,"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 y(r,o){return o?`:root, html[data-theme="${r}"], [data-theme="${r}"]`:`html[data-theme="${r}"], [data-theme="${r}"]`}var b={prefix:"fe",themes:{},tokenMapping:l,cssSelector:y};function p(r){let o=s(f,r?.themes||{}),t=r?.includeThemes;if(t?.length){let c={};for(let n of t)o[n]&&(c[n]=o[n]);o=c}let a=s(l,r?.tokenMapping||{}),e=Object.assign({},b,r,{themes:o,tokenMapping:a,includeThemes:t??[]});return(!e.defaultTheme||!e.themes[e.defaultTheme])&&(e.defaultTheme=Object.keys(e.themes)[0]),e}function x(r={}){let o=p(r),{prefix:t,themes:a,cssSelector:e,defaultTheme:c}=o,n="";for(let[i,v]of Object.entries(a)){let u=e(i,i===c),T=m(t,i),$={...v,...T};n+=`${u} {
|
|
2
|
+
`;for(let[k,M]of Object.entries($))n+=` --${t}-${k}: ${M};
|
|
3
|
+
`;n+=`}
|
|
4
4
|
|
|
5
|
-
`}return
|
|
6
|
-
`;for(let[n
|
|
7
|
-
`}return
|
|
8
|
-
`,
|
|
9
|
-
`+
|
|
5
|
+
`}return n}function h(r={}){let o=p(r),{prefix:t,tokenMapping:a=l}=o,e=`@theme {
|
|
6
|
+
`;for(let[c,n]of Object.entries(a)){let i=g(n,t);e+=` --${c}: ${i};
|
|
7
|
+
`}return e+=`}
|
|
8
|
+
`,e}function V(r={}){let o="",t=x(r);return t&&(o+=`@layer base {
|
|
9
|
+
`+t+`}
|
|
10
10
|
|
|
11
|
-
`),
|
|
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});
|
|
11
|
+
`),o+=h(r),o}0&&(module.exports={builtinThemes,defaultConfig,defaultTokenMapping,generateLayerBaseCSS,generateThemeBlockCSS,generateThemeCSS,getConfig,getDefaultSelector,getDerivedTokens});
|
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,11 @@ interface UiThemeOptions {
|
|
|
33
33
|
prefix?: string;
|
|
34
34
|
defaultTheme?: string;
|
|
35
35
|
themes?: ThemesMap;
|
|
36
|
+
/**
|
|
37
|
+
* When set, only these theme names are emitted (after merging builtins).
|
|
38
|
+
* Use to keep app CSS small when the package ships extra demo themes.
|
|
39
|
+
*/
|
|
40
|
+
includeThemes?: string[];
|
|
36
41
|
tokenMapping?: TokenMapping;
|
|
37
42
|
cssSelector?: (themeName: string, root: boolean) => string;
|
|
38
43
|
outputPath?: string;
|
|
@@ -64,25 +69,4 @@ declare function generateThemeBlockCSS(options?: UiThemeOptions): string;
|
|
|
64
69
|
*/
|
|
65
70
|
declare function generateThemeCSS(options?: UiThemeOptions): string;
|
|
66
71
|
|
|
67
|
-
|
|
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 };
|
|
72
|
+
export { type ColorValue, type RGBChannels, type ThemeTokens, type ThemesMap, type TokenMapping, type UiThemeOptions, builtinThemes, defaultConfig, defaultTokenMapping, generateLayerBaseCSS, generateThemeBlockCSS, generateThemeCSS, getConfig, getDefaultSelector, getDerivedTokens };
|
package/dist/index.js
CHANGED
|
@@ -182,7 +182,17 @@ var defaultConfig = {
|
|
|
182
182
|
cssSelector: getDefaultSelector
|
|
183
183
|
};
|
|
184
184
|
function getConfig(options) {
|
|
185
|
-
|
|
185
|
+
let allThemes = deepMerge(builtinThemes, options?.themes || {});
|
|
186
|
+
const includeThemes = options?.includeThemes;
|
|
187
|
+
if (includeThemes?.length) {
|
|
188
|
+
const filtered = {};
|
|
189
|
+
for (const name of includeThemes) {
|
|
190
|
+
if (allThemes[name]) {
|
|
191
|
+
filtered[name] = allThemes[name];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
allThemes = filtered;
|
|
195
|
+
}
|
|
186
196
|
const allMappings = deepMerge(
|
|
187
197
|
defaultTokenMapping,
|
|
188
198
|
options?.tokenMapping || {}
|
|
@@ -193,10 +203,11 @@ function getConfig(options) {
|
|
|
193
203
|
options,
|
|
194
204
|
{
|
|
195
205
|
themes: allThemes,
|
|
196
|
-
tokenMapping: allMappings
|
|
206
|
+
tokenMapping: allMappings,
|
|
207
|
+
includeThemes: includeThemes ?? []
|
|
197
208
|
}
|
|
198
209
|
);
|
|
199
|
-
if (!config.defaultTheme
|
|
210
|
+
if (!config.defaultTheme || !config.themes[config.defaultTheme]) {
|
|
200
211
|
config.defaultTheme = Object.keys(config.themes)[0];
|
|
201
212
|
}
|
|
202
213
|
return config;
|
|
@@ -246,88 +257,6 @@ function generateThemeCSS(options = {}) {
|
|
|
246
257
|
css += generateThemeBlockCSS(options);
|
|
247
258
|
return css;
|
|
248
259
|
}
|
|
249
|
-
|
|
250
|
-
// src/generater.ts
|
|
251
|
-
import fs from "fs";
|
|
252
|
-
import path from "path";
|
|
253
|
-
var DEFAULT_OUTPUT_PATHS = {
|
|
254
|
-
"layer-base": "theme-layer-base.css",
|
|
255
|
-
"theme-block": "theme-block.css",
|
|
256
|
-
full: "theme.css"
|
|
257
|
-
};
|
|
258
|
-
function resolveCssContent(variant, options) {
|
|
259
|
-
switch (variant) {
|
|
260
|
-
case "layer-base": {
|
|
261
|
-
const layerBaseContent = generateLayerBaseCSS(options);
|
|
262
|
-
return layerBaseContent ? `@layer base {
|
|
263
|
-
${layerBaseContent}}
|
|
264
|
-
` : "";
|
|
265
|
-
}
|
|
266
|
-
case "theme-block":
|
|
267
|
-
return generateThemeBlockCSS(options);
|
|
268
|
-
case "full":
|
|
269
|
-
return generateThemeCSS(options);
|
|
270
|
-
default: {
|
|
271
|
-
const _exhaustive = variant;
|
|
272
|
-
return _exhaustive;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
async function writeCssFile(absolutePath, css, overwrite) {
|
|
277
|
-
if (fs.existsSync(absolutePath)) {
|
|
278
|
-
if (overwrite) {
|
|
279
|
-
console.warn(
|
|
280
|
-
`\u26A0\uFE0F Warning: File already exists at ${absolutePath}. It will be overwritten.`
|
|
281
|
-
);
|
|
282
|
-
} else {
|
|
283
|
-
throw new Error(
|
|
284
|
-
`File already exists at ${absolutePath} and overwrite is set to false.`
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
const dir = path.dirname(absolutePath);
|
|
289
|
-
if (!fs.existsSync(dir)) {
|
|
290
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
291
|
-
}
|
|
292
|
-
await fs.promises.writeFile(absolutePath, css, "utf-8");
|
|
293
|
-
console.log(`\u2705 Theme CSS generated at ${absolutePath}`);
|
|
294
|
-
}
|
|
295
|
-
function resolveOutputPath(variant, options) {
|
|
296
|
-
if (options.outputPath) {
|
|
297
|
-
return path.resolve(process.cwd(), options.outputPath);
|
|
298
|
-
}
|
|
299
|
-
return path.resolve(process.cwd(), DEFAULT_OUTPUT_PATHS[variant]);
|
|
300
|
-
}
|
|
301
|
-
async function generateThemeFile(options = {}) {
|
|
302
|
-
const {
|
|
303
|
-
variant = "full",
|
|
304
|
-
overwrite = true,
|
|
305
|
-
outputPath,
|
|
306
|
-
...restOptions
|
|
307
|
-
} = options;
|
|
308
|
-
const absolutePath = outputPath ? path.resolve(process.cwd(), outputPath) : resolveOutputPath(variant, options);
|
|
309
|
-
const css = resolveCssContent(variant, restOptions);
|
|
310
|
-
await writeCssFile(absolutePath, css, overwrite);
|
|
311
|
-
return absolutePath;
|
|
312
|
-
}
|
|
313
|
-
async function generateThemeFiles(options = {}) {
|
|
314
|
-
const {
|
|
315
|
-
outputDir = ".",
|
|
316
|
-
outputPaths = {},
|
|
317
|
-
overwrite = true,
|
|
318
|
-
...restOptions
|
|
319
|
-
} = options;
|
|
320
|
-
const variants = Object.keys(DEFAULT_OUTPUT_PATHS);
|
|
321
|
-
const result = {};
|
|
322
|
-
for (const variant of variants) {
|
|
323
|
-
const relativePath = outputPaths[variant] ?? path.join(outputDir, DEFAULT_OUTPUT_PATHS[variant]);
|
|
324
|
-
const absolutePath = path.resolve(process.cwd(), relativePath);
|
|
325
|
-
const css = resolveCssContent(variant, restOptions);
|
|
326
|
-
await writeCssFile(absolutePath, css, overwrite);
|
|
327
|
-
result[variant] = absolutePath;
|
|
328
|
-
}
|
|
329
|
-
return result;
|
|
330
|
-
}
|
|
331
260
|
export {
|
|
332
261
|
builtinThemes,
|
|
333
262
|
defaultConfig,
|
|
@@ -335,8 +264,6 @@ export {
|
|
|
335
264
|
generateLayerBaseCSS,
|
|
336
265
|
generateThemeBlockCSS,
|
|
337
266
|
generateThemeCSS,
|
|
338
|
-
generateThemeFile,
|
|
339
|
-
generateThemeFiles,
|
|
340
267
|
getConfig,
|
|
341
268
|
getDefaultSelector,
|
|
342
269
|
getDerivedTokens
|
package/dist/plugin.cjs
CHANGED
|
@@ -208,7 +208,17 @@ var defaultConfig = {
|
|
|
208
208
|
cssSelector: getDefaultSelector
|
|
209
209
|
};
|
|
210
210
|
function getConfig(options) {
|
|
211
|
-
|
|
211
|
+
let allThemes = deepMerge(builtinThemes, options?.themes || {});
|
|
212
|
+
const includeThemes = options?.includeThemes;
|
|
213
|
+
if (includeThemes?.length) {
|
|
214
|
+
const filtered = {};
|
|
215
|
+
for (const name of includeThemes) {
|
|
216
|
+
if (allThemes[name]) {
|
|
217
|
+
filtered[name] = allThemes[name];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
allThemes = filtered;
|
|
221
|
+
}
|
|
212
222
|
const allMappings = deepMerge(
|
|
213
223
|
defaultTokenMapping,
|
|
214
224
|
options?.tokenMapping || {}
|
|
@@ -219,10 +229,11 @@ function getConfig(options) {
|
|
|
219
229
|
options,
|
|
220
230
|
{
|
|
221
231
|
themes: allThemes,
|
|
222
|
-
tokenMapping: allMappings
|
|
232
|
+
tokenMapping: allMappings,
|
|
233
|
+
includeThemes: includeThemes ?? []
|
|
223
234
|
}
|
|
224
235
|
);
|
|
225
|
-
if (!config.defaultTheme
|
|
236
|
+
if (!config.defaultTheme || !config.themes[config.defaultTheme]) {
|
|
226
237
|
config.defaultTheme = Object.keys(config.themes)[0];
|
|
227
238
|
}
|
|
228
239
|
return config;
|
package/dist/plugin.d.cts
CHANGED
|
@@ -35,6 +35,11 @@ interface UiThemeOptions {
|
|
|
35
35
|
prefix?: string;
|
|
36
36
|
defaultTheme?: string;
|
|
37
37
|
themes?: ThemesMap;
|
|
38
|
+
/**
|
|
39
|
+
* When set, only these theme names are emitted (after merging builtins).
|
|
40
|
+
* Use to keep app CSS small when the package ships extra demo themes.
|
|
41
|
+
*/
|
|
42
|
+
includeThemes?: string[];
|
|
38
43
|
tokenMapping?: TokenMapping;
|
|
39
44
|
cssSelector?: (themeName: string, root: boolean) => string;
|
|
40
45
|
outputPath?: string;
|
package/dist/plugin.d.ts
CHANGED
|
@@ -35,6 +35,11 @@ interface UiThemeOptions {
|
|
|
35
35
|
prefix?: string;
|
|
36
36
|
defaultTheme?: string;
|
|
37
37
|
themes?: ThemesMap;
|
|
38
|
+
/**
|
|
39
|
+
* When set, only these theme names are emitted (after merging builtins).
|
|
40
|
+
* Use to keep app CSS small when the package ships extra demo themes.
|
|
41
|
+
*/
|
|
42
|
+
includeThemes?: string[];
|
|
38
43
|
tokenMapping?: TokenMapping;
|
|
39
44
|
cssSelector?: (themeName: string, root: boolean) => string;
|
|
40
45
|
outputPath?: string;
|
package/dist/plugin.js
CHANGED
|
@@ -182,7 +182,17 @@ var defaultConfig = {
|
|
|
182
182
|
cssSelector: getDefaultSelector
|
|
183
183
|
};
|
|
184
184
|
function getConfig(options) {
|
|
185
|
-
|
|
185
|
+
let allThemes = deepMerge(builtinThemes, options?.themes || {});
|
|
186
|
+
const includeThemes = options?.includeThemes;
|
|
187
|
+
if (includeThemes?.length) {
|
|
188
|
+
const filtered = {};
|
|
189
|
+
for (const name of includeThemes) {
|
|
190
|
+
if (allThemes[name]) {
|
|
191
|
+
filtered[name] = allThemes[name];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
allThemes = filtered;
|
|
195
|
+
}
|
|
186
196
|
const allMappings = deepMerge(
|
|
187
197
|
defaultTokenMapping,
|
|
188
198
|
options?.tokenMapping || {}
|
|
@@ -193,10 +203,11 @@ function getConfig(options) {
|
|
|
193
203
|
options,
|
|
194
204
|
{
|
|
195
205
|
themes: allThemes,
|
|
196
|
-
tokenMapping: allMappings
|
|
206
|
+
tokenMapping: allMappings,
|
|
207
|
+
includeThemes: includeThemes ?? []
|
|
197
208
|
}
|
|
198
209
|
);
|
|
199
|
-
if (!config.defaultTheme
|
|
210
|
+
if (!config.defaultTheme || !config.themes[config.defaultTheme]) {
|
|
200
211
|
config.defaultTheme = Object.keys(config.themes)[0];
|
|
201
212
|
}
|
|
202
213
|
return config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qlover/tailwind-theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"import": "./dist/plugin.js",
|
|
19
19
|
"require": "./dist/plugin.cjs"
|
|
20
20
|
},
|
|
21
|
+
"./generater": {
|
|
22
|
+
"types": "./dist/generater.d.ts",
|
|
23
|
+
"import": "./dist/generater.js",
|
|
24
|
+
"require": "./dist/generater.cjs"
|
|
25
|
+
},
|
|
21
26
|
"./theme.css": "./dist/theme.css",
|
|
22
27
|
"./theme-layer-base.css": "./dist/theme-layer-base.css",
|
|
23
28
|
"./theme-block.css": "./dist/theme-block.css"
|