@boo-dreamer/theme 0.0.1
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/dist/index.cjs +420 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +374 -0
- package/dist/index.mjs +420 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const DEFAULT_RADIUS = {
|
|
5
|
+
none: "0",
|
|
6
|
+
sm: "2px",
|
|
7
|
+
base: "4px",
|
|
8
|
+
md: "6px",
|
|
9
|
+
lg: "8px",
|
|
10
|
+
xl: "12px",
|
|
11
|
+
full: "9999px"
|
|
12
|
+
};
|
|
13
|
+
const DEFAULT_SHADOW = {
|
|
14
|
+
none: "none",
|
|
15
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
16
|
+
base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
|
|
17
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
|
|
18
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
|
|
19
|
+
xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)"
|
|
20
|
+
};
|
|
21
|
+
const DARK_SHADOW = {
|
|
22
|
+
none: "none",
|
|
23
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.3)",
|
|
24
|
+
base: "0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4)",
|
|
25
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4)",
|
|
26
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4)",
|
|
27
|
+
xl: "0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)"
|
|
28
|
+
};
|
|
29
|
+
const DEFAULT_FONT_SIZE = {
|
|
30
|
+
xs: "12px",
|
|
31
|
+
sm: "13px",
|
|
32
|
+
base: "14px",
|
|
33
|
+
md: "16px",
|
|
34
|
+
lg: "18px",
|
|
35
|
+
xl: "20px",
|
|
36
|
+
"2xl": "24px",
|
|
37
|
+
"3xl": "30px"
|
|
38
|
+
};
|
|
39
|
+
const DEFAULT_LINE_HEIGHT = {
|
|
40
|
+
tight: "1.25",
|
|
41
|
+
base: "1.5",
|
|
42
|
+
relaxed: "1.75"
|
|
43
|
+
};
|
|
44
|
+
const DEFAULT_FONT_WEIGHT = {
|
|
45
|
+
normal: "400",
|
|
46
|
+
medium: "500",
|
|
47
|
+
semibold: "600",
|
|
48
|
+
bold: "700"
|
|
49
|
+
};
|
|
50
|
+
const DEFAULT_SPACING = {
|
|
51
|
+
0: "0",
|
|
52
|
+
1: "4px",
|
|
53
|
+
2: "8px",
|
|
54
|
+
3: "12px",
|
|
55
|
+
4: "16px",
|
|
56
|
+
5: "20px",
|
|
57
|
+
6: "24px",
|
|
58
|
+
8: "32px",
|
|
59
|
+
10: "40px",
|
|
60
|
+
12: "48px"
|
|
61
|
+
};
|
|
62
|
+
const DEFAULT_TRANSITION = {
|
|
63
|
+
fast: "0.1s",
|
|
64
|
+
base: "0.2s",
|
|
65
|
+
slow: "0.3s",
|
|
66
|
+
ease: "cubic-bezier(0.4, 0, 0.2, 1)"
|
|
67
|
+
};
|
|
68
|
+
const DEFAULT_Z_INDEX = {
|
|
69
|
+
dropdown: 1e3,
|
|
70
|
+
sticky: 1100,
|
|
71
|
+
fixed: 1200,
|
|
72
|
+
modalBackdrop: 1300,
|
|
73
|
+
modal: 1400,
|
|
74
|
+
popover: 1500,
|
|
75
|
+
tooltip: 1600
|
|
76
|
+
};
|
|
77
|
+
const DEFAULT_FONT_FAMILY = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"';
|
|
78
|
+
const DEFAULT_FONT_FAMILY_MONO = 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
|
|
79
|
+
const DEFAULT_STORAGE_KEY = "boo-theme-mode";
|
|
80
|
+
const DEFAULT_CSS_PREFIX = "boo";
|
|
81
|
+
const MINT_LIGHT = {
|
|
82
|
+
// 品牌色
|
|
83
|
+
primary: "#10B981",
|
|
84
|
+
primaryLight: "#34D399",
|
|
85
|
+
primaryDark: "#059669",
|
|
86
|
+
primaryBg: "#ECFDF5",
|
|
87
|
+
// 功能色
|
|
88
|
+
success: "#22C55E",
|
|
89
|
+
warning: "#F59E0B",
|
|
90
|
+
error: "#EF4444",
|
|
91
|
+
info: "#3B82F6",
|
|
92
|
+
// 文字颜色
|
|
93
|
+
textPrimary: "#1F2937",
|
|
94
|
+
textSecondary: "#6B7280",
|
|
95
|
+
textPlaceholder: "#9CA3AF",
|
|
96
|
+
textDisabled: "#D1D5DB",
|
|
97
|
+
// 边框
|
|
98
|
+
border: "#E5E7EB",
|
|
99
|
+
borderLight: "#F3F4F6",
|
|
100
|
+
divider: "#E5E7EB",
|
|
101
|
+
// 背景
|
|
102
|
+
bgPage: "#F9FAFB",
|
|
103
|
+
bgContainer: "#FFFFFF",
|
|
104
|
+
bgElevated: "#FFFFFF",
|
|
105
|
+
bgSpotlight: "#F3F4F6"
|
|
106
|
+
};
|
|
107
|
+
const MINT_DARK = {
|
|
108
|
+
// 品牌色
|
|
109
|
+
primary: "#34D399",
|
|
110
|
+
primaryLight: "#6EE7B7",
|
|
111
|
+
primaryDark: "#10B981",
|
|
112
|
+
primaryBg: "#064E3B",
|
|
113
|
+
// 功能色
|
|
114
|
+
success: "#4ADE80",
|
|
115
|
+
warning: "#FBBF24",
|
|
116
|
+
error: "#F87171",
|
|
117
|
+
info: "#60A5FA",
|
|
118
|
+
// 文字颜色
|
|
119
|
+
textPrimary: "#F9FAFB",
|
|
120
|
+
textSecondary: "#D1D5DB",
|
|
121
|
+
textPlaceholder: "#9CA3AF",
|
|
122
|
+
textDisabled: "#6B7280",
|
|
123
|
+
// 边框
|
|
124
|
+
border: "#374151",
|
|
125
|
+
borderLight: "#4B5563",
|
|
126
|
+
divider: "#374151",
|
|
127
|
+
// 背景
|
|
128
|
+
bgPage: "#111827",
|
|
129
|
+
bgContainer: "#1F2937",
|
|
130
|
+
bgElevated: "#374151",
|
|
131
|
+
bgSpotlight: "#374151"
|
|
132
|
+
};
|
|
133
|
+
const PRESET_MINT = {
|
|
134
|
+
name: "mint",
|
|
135
|
+
light: MINT_LIGHT,
|
|
136
|
+
dark: MINT_DARK
|
|
137
|
+
};
|
|
138
|
+
const PRESETS = {
|
|
139
|
+
mint: PRESET_MINT
|
|
140
|
+
};
|
|
141
|
+
const DEFAULT_PRESET = PRESET_MINT;
|
|
142
|
+
function camelToKebab(str) {
|
|
143
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
144
|
+
}
|
|
145
|
+
function cssVar(prefix, category, key) {
|
|
146
|
+
return `--${prefix}-${category}-${camelToKebab(key)}`;
|
|
147
|
+
}
|
|
148
|
+
function generateColorVars(colors, prefix) {
|
|
149
|
+
const vars = {};
|
|
150
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
151
|
+
vars[cssVar(prefix, "color", key)] = value;
|
|
152
|
+
}
|
|
153
|
+
return vars;
|
|
154
|
+
}
|
|
155
|
+
function generateCommonVars(prefix) {
|
|
156
|
+
const vars = {};
|
|
157
|
+
for (const [key, value] of Object.entries(DEFAULT_RADIUS)) {
|
|
158
|
+
vars[cssVar(prefix, "radius", key)] = value;
|
|
159
|
+
}
|
|
160
|
+
for (const [key, value] of Object.entries(DEFAULT_FONT_SIZE)) {
|
|
161
|
+
vars[cssVar(prefix, "font-size", key)] = value;
|
|
162
|
+
}
|
|
163
|
+
for (const [key, value] of Object.entries(DEFAULT_LINE_HEIGHT)) {
|
|
164
|
+
vars[cssVar(prefix, "line-height", key)] = value;
|
|
165
|
+
}
|
|
166
|
+
for (const [key, value] of Object.entries(DEFAULT_FONT_WEIGHT)) {
|
|
167
|
+
vars[cssVar(prefix, "font-weight", key)] = value;
|
|
168
|
+
}
|
|
169
|
+
for (const [key, value] of Object.entries(DEFAULT_SPACING)) {
|
|
170
|
+
vars[cssVar(prefix, "spacing", key)] = value;
|
|
171
|
+
}
|
|
172
|
+
for (const [key, value] of Object.entries(DEFAULT_TRANSITION)) {
|
|
173
|
+
vars[cssVar(prefix, "transition", key)] = value;
|
|
174
|
+
}
|
|
175
|
+
for (const [key, value] of Object.entries(DEFAULT_Z_INDEX)) {
|
|
176
|
+
vars[cssVar(prefix, "z", camelToKebab(key))] = String(value);
|
|
177
|
+
}
|
|
178
|
+
vars[`--${prefix}-font-family`] = DEFAULT_FONT_FAMILY;
|
|
179
|
+
vars[`--${prefix}-font-family-mono`] = DEFAULT_FONT_FAMILY_MONO;
|
|
180
|
+
return vars;
|
|
181
|
+
}
|
|
182
|
+
function generateShadowVars(isDark, prefix) {
|
|
183
|
+
const vars = {};
|
|
184
|
+
const shadow = isDark ? DARK_SHADOW : DEFAULT_SHADOW;
|
|
185
|
+
for (const [key, value] of Object.entries(shadow)) {
|
|
186
|
+
vars[cssVar(prefix, "shadow", key)] = value;
|
|
187
|
+
}
|
|
188
|
+
return vars;
|
|
189
|
+
}
|
|
190
|
+
function varsToCSS(vars) {
|
|
191
|
+
return Object.entries(vars).map(([key, value]) => `${key}: ${value};`).join("\n ");
|
|
192
|
+
}
|
|
193
|
+
function injectCSSVars(colors, theme, prefix = DEFAULT_CSS_PREFIX) {
|
|
194
|
+
const styleId = `${prefix}-theme-vars`;
|
|
195
|
+
let styleEl = document.getElementById(styleId);
|
|
196
|
+
if (!styleEl) {
|
|
197
|
+
styleEl = document.createElement("style");
|
|
198
|
+
styleEl.id = styleId;
|
|
199
|
+
document.head.appendChild(styleEl);
|
|
200
|
+
}
|
|
201
|
+
const colorVars = generateColorVars(colors, prefix);
|
|
202
|
+
const commonVars = generateCommonVars(prefix);
|
|
203
|
+
const shadowVars = generateShadowVars(theme === "dark", prefix);
|
|
204
|
+
const allVars = { ...colorVars, ...commonVars, ...shadowVars };
|
|
205
|
+
styleEl.textContent = `:root {
|
|
206
|
+
${varsToCSS(allVars)}
|
|
207
|
+
}`;
|
|
208
|
+
}
|
|
209
|
+
function setThemeAttribute(theme) {
|
|
210
|
+
document.documentElement.setAttribute("data-theme", theme);
|
|
211
|
+
if (theme === "dark") {
|
|
212
|
+
document.documentElement.classList.add("dark");
|
|
213
|
+
} else {
|
|
214
|
+
document.documentElement.classList.remove("dark");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function getCSSVar(name, prefix = DEFAULT_CSS_PREFIX) {
|
|
218
|
+
const varName = name.startsWith("--") ? name : `--${prefix}-${name}`;
|
|
219
|
+
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
|
|
220
|
+
}
|
|
221
|
+
function setCSSVar(name, value, prefix = DEFAULT_CSS_PREFIX) {
|
|
222
|
+
const varName = name.startsWith("--") ? name : `--${prefix}-${name}`;
|
|
223
|
+
document.documentElement.style.setProperty(varName, value);
|
|
224
|
+
}
|
|
225
|
+
function getSystemTheme() {
|
|
226
|
+
if (typeof window === "undefined") {
|
|
227
|
+
return "light";
|
|
228
|
+
}
|
|
229
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
230
|
+
return mediaQuery.matches ? "dark" : "light";
|
|
231
|
+
}
|
|
232
|
+
function watchSystemTheme(callback) {
|
|
233
|
+
if (typeof window === "undefined") {
|
|
234
|
+
return () => {
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
238
|
+
const handler = (e) => {
|
|
239
|
+
callback(e.matches ? "dark" : "light");
|
|
240
|
+
};
|
|
241
|
+
if (mediaQuery.addEventListener) {
|
|
242
|
+
mediaQuery.addEventListener("change", handler);
|
|
243
|
+
return () => mediaQuery.removeEventListener("change", handler);
|
|
244
|
+
} else {
|
|
245
|
+
mediaQuery.addListener(handler);
|
|
246
|
+
return () => {
|
|
247
|
+
mediaQuery.removeListener(handler);
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function supportsSystemTheme() {
|
|
252
|
+
if (typeof window === "undefined") {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
return window.matchMedia !== void 0;
|
|
256
|
+
}
|
|
257
|
+
function loadMode(storageKey) {
|
|
258
|
+
if (typeof localStorage === "undefined") return null;
|
|
259
|
+
const stored = localStorage.getItem(storageKey);
|
|
260
|
+
if (stored === "light" || stored === "dark" || stored === "system") {
|
|
261
|
+
return stored;
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
function saveMode(storageKey, mode) {
|
|
266
|
+
if (typeof localStorage === "undefined") return;
|
|
267
|
+
localStorage.setItem(storageKey, mode);
|
|
268
|
+
}
|
|
269
|
+
function createTheme(config = {}) {
|
|
270
|
+
const {
|
|
271
|
+
defaultMode = "system",
|
|
272
|
+
storageKey = DEFAULT_STORAGE_KEY,
|
|
273
|
+
persist = true,
|
|
274
|
+
colors: customColors,
|
|
275
|
+
darkColors: customDarkColors,
|
|
276
|
+
preset: presetName,
|
|
277
|
+
cssPrefix = DEFAULT_CSS_PREFIX
|
|
278
|
+
} = config;
|
|
279
|
+
const preset = presetName ? PRESETS[presetName] || DEFAULT_PRESET : DEFAULT_PRESET;
|
|
280
|
+
const lightColors = { ...preset.light, ...customColors };
|
|
281
|
+
const darkColors = { ...preset.dark, ...customDarkColors };
|
|
282
|
+
const mode = vue.ref(
|
|
283
|
+
(persist ? loadMode(storageKey) : null) || defaultMode
|
|
284
|
+
);
|
|
285
|
+
const appliedTheme = vue.computed(() => {
|
|
286
|
+
if (mode.value === "system") {
|
|
287
|
+
return getSystemTheme();
|
|
288
|
+
}
|
|
289
|
+
return mode.value;
|
|
290
|
+
});
|
|
291
|
+
const isDark = vue.computed(() => appliedTheme.value === "dark");
|
|
292
|
+
const colors = vue.computed(() => isDark.value ? darkColors : lightColors);
|
|
293
|
+
let unwatchSystem = null;
|
|
294
|
+
function applyTheme() {
|
|
295
|
+
const theme = appliedTheme.value;
|
|
296
|
+
const currentColors = isDark.value ? darkColors : lightColors;
|
|
297
|
+
injectCSSVars(currentColors, theme, cssPrefix);
|
|
298
|
+
setThemeAttribute(theme);
|
|
299
|
+
}
|
|
300
|
+
function setMode(newMode) {
|
|
301
|
+
mode.value = newMode;
|
|
302
|
+
if (persist) {
|
|
303
|
+
saveMode(storageKey, newMode);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function toggle() {
|
|
307
|
+
if (mode.value === "light") {
|
|
308
|
+
setMode("dark");
|
|
309
|
+
} else if (mode.value === "dark") {
|
|
310
|
+
setMode("light");
|
|
311
|
+
} else {
|
|
312
|
+
setMode(isDark.value ? "light" : "dark");
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function setColors(newColors) {
|
|
316
|
+
if (isDark.value) {
|
|
317
|
+
Object.assign(darkColors, newColors);
|
|
318
|
+
} else {
|
|
319
|
+
Object.assign(lightColors, newColors);
|
|
320
|
+
}
|
|
321
|
+
applyTheme();
|
|
322
|
+
}
|
|
323
|
+
function getCssVar(name) {
|
|
324
|
+
return getCSSVar(name, cssPrefix);
|
|
325
|
+
}
|
|
326
|
+
function init() {
|
|
327
|
+
applyTheme();
|
|
328
|
+
if (mode.value === "system") {
|
|
329
|
+
unwatchSystem = watchSystemTheme(() => {
|
|
330
|
+
applyTheme();
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function destroy() {
|
|
335
|
+
if (unwatchSystem) {
|
|
336
|
+
unwatchSystem();
|
|
337
|
+
unwatchSystem = null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
vue.watch(mode, (newMode) => {
|
|
341
|
+
if (unwatchSystem) {
|
|
342
|
+
unwatchSystem();
|
|
343
|
+
unwatchSystem = null;
|
|
344
|
+
}
|
|
345
|
+
if (newMode === "system") {
|
|
346
|
+
unwatchSystem = watchSystemTheme(() => {
|
|
347
|
+
applyTheme();
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
applyTheme();
|
|
351
|
+
});
|
|
352
|
+
return {
|
|
353
|
+
mode,
|
|
354
|
+
appliedTheme,
|
|
355
|
+
isDark,
|
|
356
|
+
colors,
|
|
357
|
+
setMode,
|
|
358
|
+
toggle,
|
|
359
|
+
setColors,
|
|
360
|
+
getCssVar,
|
|
361
|
+
init,
|
|
362
|
+
destroy
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
let globalTheme = null;
|
|
366
|
+
function setupTheme(config = {}) {
|
|
367
|
+
globalTheme = createTheme(config);
|
|
368
|
+
globalTheme.init();
|
|
369
|
+
return globalTheme;
|
|
370
|
+
}
|
|
371
|
+
function useTheme() {
|
|
372
|
+
if (!globalTheme) {
|
|
373
|
+
globalTheme = createTheme();
|
|
374
|
+
vue.onMounted(() => {
|
|
375
|
+
globalTheme.init();
|
|
376
|
+
});
|
|
377
|
+
vue.onUnmounted(() => {
|
|
378
|
+
globalTheme.destroy();
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
mode: globalTheme.mode,
|
|
383
|
+
appliedTheme: globalTheme.appliedTheme,
|
|
384
|
+
isDark: globalTheme.isDark,
|
|
385
|
+
colors: globalTheme.colors,
|
|
386
|
+
setMode: globalTheme.setMode,
|
|
387
|
+
toggle: globalTheme.toggle,
|
|
388
|
+
setColors: globalTheme.setColors,
|
|
389
|
+
getCssVar: globalTheme.getCssVar
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
exports.DARK_SHADOW = DARK_SHADOW;
|
|
393
|
+
exports.DEFAULT_CSS_PREFIX = DEFAULT_CSS_PREFIX;
|
|
394
|
+
exports.DEFAULT_FONT_FAMILY = DEFAULT_FONT_FAMILY;
|
|
395
|
+
exports.DEFAULT_FONT_FAMILY_MONO = DEFAULT_FONT_FAMILY_MONO;
|
|
396
|
+
exports.DEFAULT_FONT_SIZE = DEFAULT_FONT_SIZE;
|
|
397
|
+
exports.DEFAULT_FONT_WEIGHT = DEFAULT_FONT_WEIGHT;
|
|
398
|
+
exports.DEFAULT_LINE_HEIGHT = DEFAULT_LINE_HEIGHT;
|
|
399
|
+
exports.DEFAULT_PRESET = DEFAULT_PRESET;
|
|
400
|
+
exports.DEFAULT_RADIUS = DEFAULT_RADIUS;
|
|
401
|
+
exports.DEFAULT_SHADOW = DEFAULT_SHADOW;
|
|
402
|
+
exports.DEFAULT_SPACING = DEFAULT_SPACING;
|
|
403
|
+
exports.DEFAULT_STORAGE_KEY = DEFAULT_STORAGE_KEY;
|
|
404
|
+
exports.DEFAULT_TRANSITION = DEFAULT_TRANSITION;
|
|
405
|
+
exports.DEFAULT_Z_INDEX = DEFAULT_Z_INDEX;
|
|
406
|
+
exports.MINT_DARK = MINT_DARK;
|
|
407
|
+
exports.MINT_LIGHT = MINT_LIGHT;
|
|
408
|
+
exports.PRESETS = PRESETS;
|
|
409
|
+
exports.PRESET_MINT = PRESET_MINT;
|
|
410
|
+
exports.createTheme = createTheme;
|
|
411
|
+
exports.getCSSVar = getCSSVar;
|
|
412
|
+
exports.getSystemTheme = getSystemTheme;
|
|
413
|
+
exports.injectCSSVars = injectCSSVars;
|
|
414
|
+
exports.setCSSVar = setCSSVar;
|
|
415
|
+
exports.setThemeAttribute = setThemeAttribute;
|
|
416
|
+
exports.setupTheme = setupTheme;
|
|
417
|
+
exports.supportsSystemTheme = supportsSystemTheme;
|
|
418
|
+
exports.useTheme = useTheme;
|
|
419
|
+
exports.watchSystemTheme = watchSystemTheme;
|
|
420
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/constants.ts","../src/presets.ts","../src/css-vars.ts","../src/system.ts","../src/useTheme.ts"],"sourcesContent":["/**\n * @boo-dreamer/theme - 常量定义\n */\nimport type {\n ThemeRadius,\n ThemeShadow,\n ThemeFontSize,\n ThemeLineHeight,\n ThemeFontWeight,\n ThemeSpacing,\n ThemeTransition,\n ThemeZIndex,\n} from './types.js';\n\n/**\n * 默认圆角\n */\nexport const DEFAULT_RADIUS: ThemeRadius = {\n none: '0',\n sm: '2px',\n base: '4px',\n md: '6px',\n lg: '8px',\n xl: '12px',\n full: '9999px',\n};\n\n/**\n * 默认阴影\n */\nexport const DEFAULT_SHADOW: ThemeShadow = {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)',\n};\n\n/**\n * 暗色模式阴影\n */\nexport const DARK_SHADOW: ThemeShadow = {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)',\n};\n\n/**\n * 默认字号\n */\nexport const DEFAULT_FONT_SIZE: ThemeFontSize = {\n xs: '12px',\n sm: '13px',\n base: '14px',\n md: '16px',\n lg: '18px',\n xl: '20px',\n '2xl': '24px',\n '3xl': '30px',\n};\n\n/**\n * 默认行高\n */\nexport const DEFAULT_LINE_HEIGHT: ThemeLineHeight = {\n tight: '1.25',\n base: '1.5',\n relaxed: '1.75',\n};\n\n/**\n * 默认字重\n */\nexport const DEFAULT_FONT_WEIGHT: ThemeFontWeight = {\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n};\n\n/**\n * 默认间距\n */\nexport const DEFAULT_SPACING: ThemeSpacing = {\n 0: '0',\n 1: '4px',\n 2: '8px',\n 3: '12px',\n 4: '16px',\n 5: '20px',\n 6: '24px',\n 8: '32px',\n 10: '40px',\n 12: '48px',\n};\n\n/**\n * 默认过渡\n */\nexport const DEFAULT_TRANSITION: ThemeTransition = {\n fast: '0.1s',\n base: '0.2s',\n slow: '0.3s',\n ease: 'cubic-bezier(0.4, 0, 0.2, 1)',\n};\n\n/**\n * 默认层级\n */\nexport const DEFAULT_Z_INDEX: ThemeZIndex = {\n dropdown: 1000,\n sticky: 1100,\n fixed: 1200,\n modalBackdrop: 1300,\n modal: 1400,\n popover: 1500,\n tooltip: 1600,\n};\n\n/**\n * 默认字体\n */\nexport const DEFAULT_FONT_FAMILY =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"';\n\n/**\n * 默认代码字体\n */\nexport const DEFAULT_FONT_FAMILY_MONO =\n 'SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace';\n\n/**\n * 默认存储 key\n */\nexport const DEFAULT_STORAGE_KEY = 'boo-theme-mode';\n\n/**\n * 默认 CSS 前缀\n */\nexport const DEFAULT_CSS_PREFIX = 'boo';\n","/**\n * @boo-dreamer/theme - 主题预设(薄荷绿)\n */\nimport type { ThemeColors, ThemePreset } from './types.js';\n\n/**\n * 薄荷绿 - 浅色模式\n */\nexport const MINT_LIGHT: ThemeColors = {\n // 品牌色\n primary: '#10B981',\n primaryLight: '#34D399',\n primaryDark: '#059669',\n primaryBg: '#ECFDF5',\n\n // 功能色\n success: '#22C55E',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n\n // 文字颜色\n textPrimary: '#1F2937',\n textSecondary: '#6B7280',\n textPlaceholder: '#9CA3AF',\n textDisabled: '#D1D5DB',\n\n // 边框\n border: '#E5E7EB',\n borderLight: '#F3F4F6',\n divider: '#E5E7EB',\n\n // 背景\n bgPage: '#F9FAFB',\n bgContainer: '#FFFFFF',\n bgElevated: '#FFFFFF',\n bgSpotlight: '#F3F4F6',\n};\n\n/**\n * 薄荷绿 - 深色模式\n */\nexport const MINT_DARK: ThemeColors = {\n // 品牌色\n primary: '#34D399',\n primaryLight: '#6EE7B7',\n primaryDark: '#10B981',\n primaryBg: '#064E3B',\n\n // 功能色\n success: '#4ADE80',\n warning: '#FBBF24',\n error: '#F87171',\n info: '#60A5FA',\n\n // 文字颜色\n textPrimary: '#F9FAFB',\n textSecondary: '#D1D5DB',\n textPlaceholder: '#9CA3AF',\n textDisabled: '#6B7280',\n\n // 边框\n border: '#374151',\n borderLight: '#4B5563',\n divider: '#374151',\n\n // 背景\n bgPage: '#111827',\n bgContainer: '#1F2937',\n bgElevated: '#374151',\n bgSpotlight: '#374151',\n};\n\n/**\n * 薄荷绿预设\n */\nexport const PRESET_MINT: ThemePreset = {\n name: 'mint',\n light: MINT_LIGHT,\n dark: MINT_DARK,\n};\n\n/**\n * 所有预设\n */\nexport const PRESETS: Record<string, ThemePreset> = {\n mint: PRESET_MINT,\n};\n\n/**\n * 默认预设\n */\nexport const DEFAULT_PRESET = PRESET_MINT;\n","/**\n * @boo-dreamer/theme - CSS 变量注入\n */\nimport type { ThemeColors, AppliedTheme } from './types.js';\nimport {\n DEFAULT_RADIUS,\n DEFAULT_SHADOW,\n DARK_SHADOW,\n DEFAULT_FONT_SIZE,\n DEFAULT_LINE_HEIGHT,\n DEFAULT_FONT_WEIGHT,\n DEFAULT_SPACING,\n DEFAULT_TRANSITION,\n DEFAULT_Z_INDEX,\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_FAMILY_MONO,\n DEFAULT_CSS_PREFIX,\n} from './constants.js';\n\n/**\n * 驼峰转短横线\n */\nfunction camelToKebab(str: string): string {\n return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\n/**\n * 生成 CSS 变量名\n */\nfunction cssVar(prefix: string, category: string, key: string): string {\n return `--${prefix}-${category}-${camelToKebab(key)}`;\n}\n\n/**\n * 生成颜色 CSS 变量\n */\nfunction generateColorVars(colors: ThemeColors, prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n \n for (const [key, value] of Object.entries(colors)) {\n vars[cssVar(prefix, 'color', key)] = value;\n }\n \n return vars;\n}\n\n/**\n * 生成通用 CSS 变量(不随主题变化)\n */\nfunction generateCommonVars(prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n \n // 圆角\n for (const [key, value] of Object.entries(DEFAULT_RADIUS)) {\n vars[cssVar(prefix, 'radius', key)] = value;\n }\n \n // 字号\n for (const [key, value] of Object.entries(DEFAULT_FONT_SIZE)) {\n vars[cssVar(prefix, 'font-size', key)] = value;\n }\n \n // 行高\n for (const [key, value] of Object.entries(DEFAULT_LINE_HEIGHT)) {\n vars[cssVar(prefix, 'line-height', key)] = value;\n }\n \n // 字重\n for (const [key, value] of Object.entries(DEFAULT_FONT_WEIGHT)) {\n vars[cssVar(prefix, 'font-weight', key)] = value;\n }\n \n // 间距\n for (const [key, value] of Object.entries(DEFAULT_SPACING)) {\n vars[cssVar(prefix, 'spacing', key)] = value;\n }\n \n // 过渡\n for (const [key, value] of Object.entries(DEFAULT_TRANSITION)) {\n vars[cssVar(prefix, 'transition', key)] = value;\n }\n \n // 层级\n for (const [key, value] of Object.entries(DEFAULT_Z_INDEX)) {\n vars[cssVar(prefix, 'z', camelToKebab(key))] = String(value);\n }\n \n // 字体\n vars[`--${prefix}-font-family`] = DEFAULT_FONT_FAMILY;\n vars[`--${prefix}-font-family-mono`] = DEFAULT_FONT_FAMILY_MONO;\n \n return vars;\n}\n\n/**\n * 生成阴影 CSS 变量\n */\nfunction generateShadowVars(isDark: boolean, prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n const shadow = isDark ? DARK_SHADOW : DEFAULT_SHADOW;\n \n for (const [key, value] of Object.entries(shadow)) {\n vars[cssVar(prefix, 'shadow', key)] = value;\n }\n \n return vars;\n}\n\n/**\n * 将变量对象转换为 CSS 字符串\n */\nfunction varsToCSS(vars: Record<string, string>): string {\n return Object.entries(vars)\n .map(([key, value]) => `${key}: ${value};`)\n .join('\\n ');\n}\n\n/**\n * 注入 CSS 变量到页面\n */\nexport function injectCSSVars(\n colors: ThemeColors,\n theme: AppliedTheme,\n prefix: string = DEFAULT_CSS_PREFIX\n): void {\n const styleId = `${prefix}-theme-vars`;\n let styleEl = document.getElementById(styleId) as HTMLStyleElement | null;\n \n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.id = styleId;\n document.head.appendChild(styleEl);\n }\n \n const colorVars = generateColorVars(colors, prefix);\n const commonVars = generateCommonVars(prefix);\n const shadowVars = generateShadowVars(theme === 'dark', prefix);\n \n const allVars = { ...colorVars, ...commonVars, ...shadowVars };\n \n styleEl.textContent = `:root {\\n ${varsToCSS(allVars)}\\n}`;\n}\n\n/**\n * 设置 HTML 属性(用于 CSS 选择器)\n */\nexport function setThemeAttribute(theme: AppliedTheme): void {\n document.documentElement.setAttribute('data-theme', theme);\n \n // 同时设置 class,方便 Tailwind 等框架使用\n if (theme === 'dark') {\n document.documentElement.classList.add('dark');\n } else {\n document.documentElement.classList.remove('dark');\n }\n}\n\n/**\n * 获取 CSS 变量值\n */\nexport function getCSSVar(name: string, prefix: string = DEFAULT_CSS_PREFIX): string {\n const varName = name.startsWith('--') ? name : `--${prefix}-${name}`;\n return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();\n}\n\n/**\n * 设置单个 CSS 变量\n */\nexport function setCSSVar(\n name: string,\n value: string,\n prefix: string = DEFAULT_CSS_PREFIX\n): void {\n const varName = name.startsWith('--') ? name : `--${prefix}-${name}`;\n document.documentElement.style.setProperty(varName, value);\n}\n","/**\n * @boo-dreamer/theme - 系统主题监听\n */\nimport type { AppliedTheme } from './types.js';\n\n/**\n * 获取系统主题偏好\n */\nexport function getSystemTheme(): AppliedTheme {\n if (typeof window === 'undefined') {\n return 'light';\n }\n \n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n return mediaQuery.matches ? 'dark' : 'light';\n}\n\n/**\n * 监听系统主题变化\n */\nexport function watchSystemTheme(callback: (theme: AppliedTheme) => void): () => void {\n if (typeof window === 'undefined') {\n return () => {};\n }\n \n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n \n const handler = (e: MediaQueryListEvent) => {\n callback(e.matches ? 'dark' : 'light');\n };\n \n // 兼容旧版浏览器\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handler);\n return () => mediaQuery.removeEventListener('change', handler);\n } else {\n // 旧版 API\n (mediaQuery as unknown as { addListener: (h: typeof handler) => void }).addListener(handler);\n return () => {\n (mediaQuery as unknown as { removeListener: (h: typeof handler) => void }).removeListener(handler);\n };\n }\n}\n\n/**\n * 检查是否支持系统主题检测\n */\nexport function supportsSystemTheme(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n return window.matchMedia !== undefined;\n}\n","/**\n * @boo-dreamer/theme - useTheme 组合式函数\n */\nimport { ref, computed, watch, onMounted, onUnmounted } from 'vue';\nimport type {\n ThemeMode,\n AppliedTheme,\n ThemeColors,\n ThemeConfig,\n UseThemeReturn,\n} from './types.js';\nimport { DEFAULT_PRESET, PRESETS } from './presets.js';\nimport { DEFAULT_STORAGE_KEY, DEFAULT_CSS_PREFIX } from './constants.js';\nimport { injectCSSVars, setThemeAttribute, getCSSVar } from './css-vars.js';\nimport { getSystemTheme, watchSystemTheme } from './system.js';\n\n/**\n * 从 localStorage 读取模式\n */\nfunction loadMode(storageKey: string): ThemeMode | null {\n if (typeof localStorage === 'undefined') return null;\n const stored = localStorage.getItem(storageKey);\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n return stored;\n }\n return null;\n}\n\n/**\n * 保存模式到 localStorage\n */\nfunction saveMode(storageKey: string, mode: ThemeMode): void {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(storageKey, mode);\n}\n\n/**\n * 创建主题管理\n */\nexport function createTheme(config: ThemeConfig = {}) {\n const {\n defaultMode = 'system',\n storageKey = DEFAULT_STORAGE_KEY,\n persist = true,\n colors: customColors,\n darkColors: customDarkColors,\n preset: presetName,\n cssPrefix = DEFAULT_CSS_PREFIX,\n } = config;\n\n // 获取预设\n const preset = presetName ? PRESETS[presetName] || DEFAULT_PRESET : DEFAULT_PRESET;\n\n // 合并自定义颜色\n const lightColors: ThemeColors = { ...preset.light, ...customColors };\n const darkColors: ThemeColors = { ...preset.dark, ...customDarkColors };\n\n // 状态\n const mode = ref<ThemeMode>(\n (persist ? loadMode(storageKey) : null) || defaultMode\n );\n\n // 计算实际应用的主题\n const appliedTheme = computed<AppliedTheme>(() => {\n if (mode.value === 'system') {\n return getSystemTheme();\n }\n return mode.value;\n });\n\n // 是否暗色模式\n const isDark = computed(() => appliedTheme.value === 'dark');\n\n // 当前颜色\n const colors = computed(() => (isDark.value ? darkColors : lightColors));\n\n // 系统主题变化时触发更新\n let unwatchSystem: (() => void) | null = null;\n\n /**\n * 应用主题\n */\n function applyTheme(): void {\n const theme = appliedTheme.value;\n const currentColors = isDark.value ? darkColors : lightColors;\n \n injectCSSVars(currentColors, theme, cssPrefix);\n setThemeAttribute(theme);\n }\n\n /**\n * 设置模式\n */\n function setMode(newMode: ThemeMode): void {\n mode.value = newMode;\n if (persist) {\n saveMode(storageKey, newMode);\n }\n }\n\n /**\n * 切换主题\n */\n function toggle(): void {\n if (mode.value === 'light') {\n setMode('dark');\n } else if (mode.value === 'dark') {\n setMode('light');\n } else {\n // system 模式下,切换到当前实际主题的反面\n setMode(isDark.value ? 'light' : 'dark');\n }\n }\n\n /**\n * 设置自定义颜色(运行时)\n */\n function setColors(newColors: Partial<ThemeColors>): void {\n if (isDark.value) {\n Object.assign(darkColors, newColors);\n } else {\n Object.assign(lightColors, newColors);\n }\n applyTheme();\n }\n\n /**\n * 获取 CSS 变量值\n */\n function getCssVar(name: string): string {\n return getCSSVar(name, cssPrefix);\n }\n\n /**\n * 初始化\n */\n function init(): void {\n applyTheme();\n\n // 监听系统主题变化\n if (mode.value === 'system') {\n unwatchSystem = watchSystemTheme(() => {\n applyTheme();\n });\n }\n }\n\n /**\n * 销毁\n */\n function destroy(): void {\n if (unwatchSystem) {\n unwatchSystem();\n unwatchSystem = null;\n }\n }\n\n // 监听模式变化\n watch(mode, (newMode) => {\n // 清除旧的系统监听\n if (unwatchSystem) {\n unwatchSystem();\n unwatchSystem = null;\n }\n\n // 如果是 system 模式,重新监听\n if (newMode === 'system') {\n unwatchSystem = watchSystemTheme(() => {\n applyTheme();\n });\n }\n\n applyTheme();\n });\n\n return {\n mode,\n appliedTheme,\n isDark,\n colors,\n setMode,\n toggle,\n setColors,\n getCssVar,\n init,\n destroy,\n };\n}\n\n// 全局实例\nlet globalTheme: ReturnType<typeof createTheme> | null = null;\n\n/**\n * 初始化主题(在 app 入口调用)\n */\nexport function setupTheme(config: ThemeConfig = {}): ReturnType<typeof createTheme> {\n globalTheme = createTheme(config);\n globalTheme.init();\n return globalTheme;\n}\n\n/**\n * useTheme 组合式函数\n */\nexport function useTheme(): UseThemeReturn {\n if (!globalTheme) {\n // 如果没有初始化,创建一个默认实例\n globalTheme = createTheme();\n \n // 在组件挂载时初始化\n onMounted(() => {\n globalTheme!.init();\n });\n\n onUnmounted(() => {\n globalTheme!.destroy();\n });\n }\n\n return {\n mode: globalTheme.mode,\n appliedTheme: globalTheme.appliedTheme,\n isDark: globalTheme.isDark,\n colors: globalTheme.colors,\n setMode: globalTheme.setMode,\n toggle: globalTheme.toggle,\n setColors: globalTheme.setColors,\n getCssVar: globalTheme.getCssVar,\n };\n}\n"],"names":["ref","computed","watch","onMounted","onUnmounted"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
import { Ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 实际应用的主题(不含 system)
|
|
6
|
+
*/
|
|
7
|
+
export declare type AppliedTheme = 'light' | 'dark';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 创建主题管理
|
|
11
|
+
*/
|
|
12
|
+
export declare function createTheme(config?: ThemeConfig): {
|
|
13
|
+
mode: Ref<ThemeMode, ThemeMode>;
|
|
14
|
+
appliedTheme: ComputedRef<AppliedTheme>;
|
|
15
|
+
isDark: ComputedRef<boolean>;
|
|
16
|
+
colors: ComputedRef<ThemeColors>;
|
|
17
|
+
setMode: (newMode: ThemeMode) => void;
|
|
18
|
+
toggle: () => void;
|
|
19
|
+
setColors: (newColors: Partial<ThemeColors>) => void;
|
|
20
|
+
getCssVar: (name: string) => string;
|
|
21
|
+
init: () => void;
|
|
22
|
+
destroy: () => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 暗色模式阴影
|
|
27
|
+
*/
|
|
28
|
+
export declare const DARK_SHADOW: ThemeShadow;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 默认 CSS 前缀
|
|
32
|
+
*/
|
|
33
|
+
export declare const DEFAULT_CSS_PREFIX = "boo";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 默认字体
|
|
37
|
+
*/
|
|
38
|
+
export declare const DEFAULT_FONT_FAMILY = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 默认代码字体
|
|
42
|
+
*/
|
|
43
|
+
export declare const DEFAULT_FONT_FAMILY_MONO = "SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 默认字号
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_FONT_SIZE: ThemeFontSize;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 默认字重
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_FONT_WEIGHT: ThemeFontWeight;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 默认行高
|
|
57
|
+
*/
|
|
58
|
+
export declare const DEFAULT_LINE_HEIGHT: ThemeLineHeight;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 默认预设
|
|
62
|
+
*/
|
|
63
|
+
export declare const DEFAULT_PRESET: ThemePreset;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 默认圆角
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEFAULT_RADIUS: ThemeRadius;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 默认阴影
|
|
72
|
+
*/
|
|
73
|
+
export declare const DEFAULT_SHADOW: ThemeShadow;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 默认间距
|
|
77
|
+
*/
|
|
78
|
+
export declare const DEFAULT_SPACING: ThemeSpacing;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 默认存储 key
|
|
82
|
+
*/
|
|
83
|
+
export declare const DEFAULT_STORAGE_KEY = "boo-theme-mode";
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 默认过渡
|
|
87
|
+
*/
|
|
88
|
+
export declare const DEFAULT_TRANSITION: ThemeTransition;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 默认层级
|
|
92
|
+
*/
|
|
93
|
+
export declare const DEFAULT_Z_INDEX: ThemeZIndex;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 获取 CSS 变量值
|
|
97
|
+
*/
|
|
98
|
+
export declare function getCSSVar(name: string, prefix?: string): string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 获取系统主题偏好
|
|
102
|
+
*/
|
|
103
|
+
export declare function getSystemTheme(): AppliedTheme;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 注入 CSS 变量到页面
|
|
107
|
+
*/
|
|
108
|
+
export declare function injectCSSVars(colors: ThemeColors, theme: AppliedTheme, prefix?: string): void;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 薄荷绿 - 深色模式
|
|
112
|
+
*/
|
|
113
|
+
export declare const MINT_DARK: ThemeColors;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 薄荷绿 - 浅色模式
|
|
117
|
+
*/
|
|
118
|
+
export declare const MINT_LIGHT: ThemeColors;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 薄荷绿预设
|
|
122
|
+
*/
|
|
123
|
+
export declare const PRESET_MINT: ThemePreset;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 所有预设
|
|
127
|
+
*/
|
|
128
|
+
export declare const PRESETS: Record<string, ThemePreset>;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 设置单个 CSS 变量
|
|
132
|
+
*/
|
|
133
|
+
export declare function setCSSVar(name: string, value: string, prefix?: string): void;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 设置 HTML 属性(用于 CSS 选择器)
|
|
137
|
+
*/
|
|
138
|
+
export declare function setThemeAttribute(theme: AppliedTheme): void;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 初始化主题(在 app 入口调用)
|
|
142
|
+
*/
|
|
143
|
+
export declare function setupTheme(config?: ThemeConfig): ReturnType<typeof createTheme>;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 检查是否支持系统主题检测
|
|
147
|
+
*/
|
|
148
|
+
export declare function supportsSystemTheme(): boolean;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 颜色配置
|
|
152
|
+
*/
|
|
153
|
+
export declare interface ThemeColors {
|
|
154
|
+
/** 品牌主色 */
|
|
155
|
+
primary: string;
|
|
156
|
+
/** 主色浅色 */
|
|
157
|
+
primaryLight: string;
|
|
158
|
+
/** 主色深色 */
|
|
159
|
+
primaryDark: string;
|
|
160
|
+
/** 主色背景色 */
|
|
161
|
+
primaryBg: string;
|
|
162
|
+
/** 成功色 */
|
|
163
|
+
success: string;
|
|
164
|
+
/** 警告色 */
|
|
165
|
+
warning: string;
|
|
166
|
+
/** 错误色 */
|
|
167
|
+
error: string;
|
|
168
|
+
/** 信息色 */
|
|
169
|
+
info: string;
|
|
170
|
+
/** 主要文字颜色 */
|
|
171
|
+
textPrimary: string;
|
|
172
|
+
/** 次要文字颜色 */
|
|
173
|
+
textSecondary: string;
|
|
174
|
+
/** 占位符文字颜色 */
|
|
175
|
+
textPlaceholder: string;
|
|
176
|
+
/** 禁用文字颜色 */
|
|
177
|
+
textDisabled: string;
|
|
178
|
+
/** 边框颜色 */
|
|
179
|
+
border: string;
|
|
180
|
+
/** 浅边框颜色 */
|
|
181
|
+
borderLight: string;
|
|
182
|
+
/** 分割线颜色 */
|
|
183
|
+
divider: string;
|
|
184
|
+
/** 页面背景色 */
|
|
185
|
+
bgPage: string;
|
|
186
|
+
/** 容器背景色 */
|
|
187
|
+
bgContainer: string;
|
|
188
|
+
/** 悬浮层背景色 */
|
|
189
|
+
bgElevated: string;
|
|
190
|
+
/** 聚焦/hover 背景色 */
|
|
191
|
+
bgSpotlight: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 主题配置
|
|
196
|
+
*/
|
|
197
|
+
export declare interface ThemeConfig {
|
|
198
|
+
/** 默认模式 */
|
|
199
|
+
defaultMode?: ThemeMode;
|
|
200
|
+
/** 存储 key */
|
|
201
|
+
storageKey?: string;
|
|
202
|
+
/** 是否持久化 */
|
|
203
|
+
persist?: boolean;
|
|
204
|
+
/** 自定义颜色 */
|
|
205
|
+
colors?: Partial<ThemeColors>;
|
|
206
|
+
/** 暗色模式自定义颜色 */
|
|
207
|
+
darkColors?: Partial<ThemeColors>;
|
|
208
|
+
/** 使用预设 */
|
|
209
|
+
preset?: string;
|
|
210
|
+
/** CSS 变量前缀 */
|
|
211
|
+
cssPrefix?: string;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 字体大小配置
|
|
216
|
+
*/
|
|
217
|
+
export declare interface ThemeFontSize {
|
|
218
|
+
xs: string;
|
|
219
|
+
sm: string;
|
|
220
|
+
base: string;
|
|
221
|
+
md: string;
|
|
222
|
+
lg: string;
|
|
223
|
+
xl: string;
|
|
224
|
+
'2xl': string;
|
|
225
|
+
'3xl': string;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 字重配置
|
|
230
|
+
*/
|
|
231
|
+
export declare interface ThemeFontWeight {
|
|
232
|
+
normal: string;
|
|
233
|
+
medium: string;
|
|
234
|
+
semibold: string;
|
|
235
|
+
bold: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 行高配置
|
|
240
|
+
*/
|
|
241
|
+
export declare interface ThemeLineHeight {
|
|
242
|
+
tight: string;
|
|
243
|
+
base: string;
|
|
244
|
+
relaxed: string;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* 主题模式
|
|
249
|
+
*/
|
|
250
|
+
export declare type ThemeMode = 'light' | 'dark' | 'system';
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 主题预设
|
|
254
|
+
*/
|
|
255
|
+
export declare interface ThemePreset {
|
|
256
|
+
name: string;
|
|
257
|
+
light: ThemeColors;
|
|
258
|
+
dark: ThemeColors;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 圆角配置
|
|
263
|
+
*/
|
|
264
|
+
export declare interface ThemeRadius {
|
|
265
|
+
none: string;
|
|
266
|
+
sm: string;
|
|
267
|
+
base: string;
|
|
268
|
+
md: string;
|
|
269
|
+
lg: string;
|
|
270
|
+
xl: string;
|
|
271
|
+
full: string;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 阴影配置
|
|
276
|
+
*/
|
|
277
|
+
export declare interface ThemeShadow {
|
|
278
|
+
none: string;
|
|
279
|
+
sm: string;
|
|
280
|
+
base: string;
|
|
281
|
+
md: string;
|
|
282
|
+
lg: string;
|
|
283
|
+
xl: string;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 间距配置
|
|
288
|
+
*/
|
|
289
|
+
export declare interface ThemeSpacing {
|
|
290
|
+
0: string;
|
|
291
|
+
1: string;
|
|
292
|
+
2: string;
|
|
293
|
+
3: string;
|
|
294
|
+
4: string;
|
|
295
|
+
5: string;
|
|
296
|
+
6: string;
|
|
297
|
+
8: string;
|
|
298
|
+
10: string;
|
|
299
|
+
12: string;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* 过渡动画配置
|
|
304
|
+
*/
|
|
305
|
+
export declare interface ThemeTransition {
|
|
306
|
+
fast: string;
|
|
307
|
+
base: string;
|
|
308
|
+
slow: string;
|
|
309
|
+
ease: string;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* 主题变量配置
|
|
314
|
+
*/
|
|
315
|
+
export declare interface ThemeVariables {
|
|
316
|
+
colors: ThemeColors;
|
|
317
|
+
radius: ThemeRadius;
|
|
318
|
+
shadow: ThemeShadow;
|
|
319
|
+
fontSize: ThemeFontSize;
|
|
320
|
+
lineHeight: ThemeLineHeight;
|
|
321
|
+
fontWeight: ThemeFontWeight;
|
|
322
|
+
spacing: ThemeSpacing;
|
|
323
|
+
transition: ThemeTransition;
|
|
324
|
+
zIndex: ThemeZIndex;
|
|
325
|
+
fontFamily: string;
|
|
326
|
+
fontFamilyMono: string;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* 层级配置
|
|
331
|
+
*/
|
|
332
|
+
export declare interface ThemeZIndex {
|
|
333
|
+
dropdown: number;
|
|
334
|
+
sticky: number;
|
|
335
|
+
fixed: number;
|
|
336
|
+
modalBackdrop: number;
|
|
337
|
+
modal: number;
|
|
338
|
+
popover: number;
|
|
339
|
+
tooltip: number;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* useTheme 组合式函数
|
|
344
|
+
*/
|
|
345
|
+
export declare function useTheme(): UseThemeReturn;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* useTheme 返回值
|
|
349
|
+
*/
|
|
350
|
+
export declare interface UseThemeReturn {
|
|
351
|
+
/** 当前模式 */
|
|
352
|
+
mode: Ref<ThemeMode>;
|
|
353
|
+
/** 实际应用的主题 */
|
|
354
|
+
appliedTheme: Ref<AppliedTheme>;
|
|
355
|
+
/** 是否暗色模式 */
|
|
356
|
+
isDark: Ref<boolean>;
|
|
357
|
+
/** 当前颜色配置 */
|
|
358
|
+
colors: Ref<ThemeColors>;
|
|
359
|
+
/** 设置模式 */
|
|
360
|
+
setMode: (mode: ThemeMode) => void;
|
|
361
|
+
/** 切换主题 */
|
|
362
|
+
toggle: () => void;
|
|
363
|
+
/** 设置自定义颜色 */
|
|
364
|
+
setColors: (colors: Partial<ThemeColors>) => void;
|
|
365
|
+
/** 获取 CSS 变量值 */
|
|
366
|
+
getCssVar: (name: string) => string;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* 监听系统主题变化
|
|
371
|
+
*/
|
|
372
|
+
export declare function watchSystemTheme(callback: (theme: AppliedTheme) => void): () => void;
|
|
373
|
+
|
|
374
|
+
export { }
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { ref, computed, watch, onMounted, onUnmounted } from "vue";
|
|
2
|
+
const DEFAULT_RADIUS = {
|
|
3
|
+
none: "0",
|
|
4
|
+
sm: "2px",
|
|
5
|
+
base: "4px",
|
|
6
|
+
md: "6px",
|
|
7
|
+
lg: "8px",
|
|
8
|
+
xl: "12px",
|
|
9
|
+
full: "9999px"
|
|
10
|
+
};
|
|
11
|
+
const DEFAULT_SHADOW = {
|
|
12
|
+
none: "none",
|
|
13
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
14
|
+
base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
|
|
15
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
|
|
16
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
|
|
17
|
+
xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)"
|
|
18
|
+
};
|
|
19
|
+
const DARK_SHADOW = {
|
|
20
|
+
none: "none",
|
|
21
|
+
sm: "0 1px 2px 0 rgba(0, 0, 0, 0.3)",
|
|
22
|
+
base: "0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4)",
|
|
23
|
+
md: "0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4)",
|
|
24
|
+
lg: "0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4)",
|
|
25
|
+
xl: "0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)"
|
|
26
|
+
};
|
|
27
|
+
const DEFAULT_FONT_SIZE = {
|
|
28
|
+
xs: "12px",
|
|
29
|
+
sm: "13px",
|
|
30
|
+
base: "14px",
|
|
31
|
+
md: "16px",
|
|
32
|
+
lg: "18px",
|
|
33
|
+
xl: "20px",
|
|
34
|
+
"2xl": "24px",
|
|
35
|
+
"3xl": "30px"
|
|
36
|
+
};
|
|
37
|
+
const DEFAULT_LINE_HEIGHT = {
|
|
38
|
+
tight: "1.25",
|
|
39
|
+
base: "1.5",
|
|
40
|
+
relaxed: "1.75"
|
|
41
|
+
};
|
|
42
|
+
const DEFAULT_FONT_WEIGHT = {
|
|
43
|
+
normal: "400",
|
|
44
|
+
medium: "500",
|
|
45
|
+
semibold: "600",
|
|
46
|
+
bold: "700"
|
|
47
|
+
};
|
|
48
|
+
const DEFAULT_SPACING = {
|
|
49
|
+
0: "0",
|
|
50
|
+
1: "4px",
|
|
51
|
+
2: "8px",
|
|
52
|
+
3: "12px",
|
|
53
|
+
4: "16px",
|
|
54
|
+
5: "20px",
|
|
55
|
+
6: "24px",
|
|
56
|
+
8: "32px",
|
|
57
|
+
10: "40px",
|
|
58
|
+
12: "48px"
|
|
59
|
+
};
|
|
60
|
+
const DEFAULT_TRANSITION = {
|
|
61
|
+
fast: "0.1s",
|
|
62
|
+
base: "0.2s",
|
|
63
|
+
slow: "0.3s",
|
|
64
|
+
ease: "cubic-bezier(0.4, 0, 0.2, 1)"
|
|
65
|
+
};
|
|
66
|
+
const DEFAULT_Z_INDEX = {
|
|
67
|
+
dropdown: 1e3,
|
|
68
|
+
sticky: 1100,
|
|
69
|
+
fixed: 1200,
|
|
70
|
+
modalBackdrop: 1300,
|
|
71
|
+
modal: 1400,
|
|
72
|
+
popover: 1500,
|
|
73
|
+
tooltip: 1600
|
|
74
|
+
};
|
|
75
|
+
const DEFAULT_FONT_FAMILY = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"';
|
|
76
|
+
const DEFAULT_FONT_FAMILY_MONO = 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
|
|
77
|
+
const DEFAULT_STORAGE_KEY = "boo-theme-mode";
|
|
78
|
+
const DEFAULT_CSS_PREFIX = "boo";
|
|
79
|
+
const MINT_LIGHT = {
|
|
80
|
+
// 品牌色
|
|
81
|
+
primary: "#10B981",
|
|
82
|
+
primaryLight: "#34D399",
|
|
83
|
+
primaryDark: "#059669",
|
|
84
|
+
primaryBg: "#ECFDF5",
|
|
85
|
+
// 功能色
|
|
86
|
+
success: "#22C55E",
|
|
87
|
+
warning: "#F59E0B",
|
|
88
|
+
error: "#EF4444",
|
|
89
|
+
info: "#3B82F6",
|
|
90
|
+
// 文字颜色
|
|
91
|
+
textPrimary: "#1F2937",
|
|
92
|
+
textSecondary: "#6B7280",
|
|
93
|
+
textPlaceholder: "#9CA3AF",
|
|
94
|
+
textDisabled: "#D1D5DB",
|
|
95
|
+
// 边框
|
|
96
|
+
border: "#E5E7EB",
|
|
97
|
+
borderLight: "#F3F4F6",
|
|
98
|
+
divider: "#E5E7EB",
|
|
99
|
+
// 背景
|
|
100
|
+
bgPage: "#F9FAFB",
|
|
101
|
+
bgContainer: "#FFFFFF",
|
|
102
|
+
bgElevated: "#FFFFFF",
|
|
103
|
+
bgSpotlight: "#F3F4F6"
|
|
104
|
+
};
|
|
105
|
+
const MINT_DARK = {
|
|
106
|
+
// 品牌色
|
|
107
|
+
primary: "#34D399",
|
|
108
|
+
primaryLight: "#6EE7B7",
|
|
109
|
+
primaryDark: "#10B981",
|
|
110
|
+
primaryBg: "#064E3B",
|
|
111
|
+
// 功能色
|
|
112
|
+
success: "#4ADE80",
|
|
113
|
+
warning: "#FBBF24",
|
|
114
|
+
error: "#F87171",
|
|
115
|
+
info: "#60A5FA",
|
|
116
|
+
// 文字颜色
|
|
117
|
+
textPrimary: "#F9FAFB",
|
|
118
|
+
textSecondary: "#D1D5DB",
|
|
119
|
+
textPlaceholder: "#9CA3AF",
|
|
120
|
+
textDisabled: "#6B7280",
|
|
121
|
+
// 边框
|
|
122
|
+
border: "#374151",
|
|
123
|
+
borderLight: "#4B5563",
|
|
124
|
+
divider: "#374151",
|
|
125
|
+
// 背景
|
|
126
|
+
bgPage: "#111827",
|
|
127
|
+
bgContainer: "#1F2937",
|
|
128
|
+
bgElevated: "#374151",
|
|
129
|
+
bgSpotlight: "#374151"
|
|
130
|
+
};
|
|
131
|
+
const PRESET_MINT = {
|
|
132
|
+
name: "mint",
|
|
133
|
+
light: MINT_LIGHT,
|
|
134
|
+
dark: MINT_DARK
|
|
135
|
+
};
|
|
136
|
+
const PRESETS = {
|
|
137
|
+
mint: PRESET_MINT
|
|
138
|
+
};
|
|
139
|
+
const DEFAULT_PRESET = PRESET_MINT;
|
|
140
|
+
function camelToKebab(str) {
|
|
141
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
142
|
+
}
|
|
143
|
+
function cssVar(prefix, category, key) {
|
|
144
|
+
return `--${prefix}-${category}-${camelToKebab(key)}`;
|
|
145
|
+
}
|
|
146
|
+
function generateColorVars(colors, prefix) {
|
|
147
|
+
const vars = {};
|
|
148
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
149
|
+
vars[cssVar(prefix, "color", key)] = value;
|
|
150
|
+
}
|
|
151
|
+
return vars;
|
|
152
|
+
}
|
|
153
|
+
function generateCommonVars(prefix) {
|
|
154
|
+
const vars = {};
|
|
155
|
+
for (const [key, value] of Object.entries(DEFAULT_RADIUS)) {
|
|
156
|
+
vars[cssVar(prefix, "radius", key)] = value;
|
|
157
|
+
}
|
|
158
|
+
for (const [key, value] of Object.entries(DEFAULT_FONT_SIZE)) {
|
|
159
|
+
vars[cssVar(prefix, "font-size", key)] = value;
|
|
160
|
+
}
|
|
161
|
+
for (const [key, value] of Object.entries(DEFAULT_LINE_HEIGHT)) {
|
|
162
|
+
vars[cssVar(prefix, "line-height", key)] = value;
|
|
163
|
+
}
|
|
164
|
+
for (const [key, value] of Object.entries(DEFAULT_FONT_WEIGHT)) {
|
|
165
|
+
vars[cssVar(prefix, "font-weight", key)] = value;
|
|
166
|
+
}
|
|
167
|
+
for (const [key, value] of Object.entries(DEFAULT_SPACING)) {
|
|
168
|
+
vars[cssVar(prefix, "spacing", key)] = value;
|
|
169
|
+
}
|
|
170
|
+
for (const [key, value] of Object.entries(DEFAULT_TRANSITION)) {
|
|
171
|
+
vars[cssVar(prefix, "transition", key)] = value;
|
|
172
|
+
}
|
|
173
|
+
for (const [key, value] of Object.entries(DEFAULT_Z_INDEX)) {
|
|
174
|
+
vars[cssVar(prefix, "z", camelToKebab(key))] = String(value);
|
|
175
|
+
}
|
|
176
|
+
vars[`--${prefix}-font-family`] = DEFAULT_FONT_FAMILY;
|
|
177
|
+
vars[`--${prefix}-font-family-mono`] = DEFAULT_FONT_FAMILY_MONO;
|
|
178
|
+
return vars;
|
|
179
|
+
}
|
|
180
|
+
function generateShadowVars(isDark, prefix) {
|
|
181
|
+
const vars = {};
|
|
182
|
+
const shadow = isDark ? DARK_SHADOW : DEFAULT_SHADOW;
|
|
183
|
+
for (const [key, value] of Object.entries(shadow)) {
|
|
184
|
+
vars[cssVar(prefix, "shadow", key)] = value;
|
|
185
|
+
}
|
|
186
|
+
return vars;
|
|
187
|
+
}
|
|
188
|
+
function varsToCSS(vars) {
|
|
189
|
+
return Object.entries(vars).map(([key, value]) => `${key}: ${value};`).join("\n ");
|
|
190
|
+
}
|
|
191
|
+
function injectCSSVars(colors, theme, prefix = DEFAULT_CSS_PREFIX) {
|
|
192
|
+
const styleId = `${prefix}-theme-vars`;
|
|
193
|
+
let styleEl = document.getElementById(styleId);
|
|
194
|
+
if (!styleEl) {
|
|
195
|
+
styleEl = document.createElement("style");
|
|
196
|
+
styleEl.id = styleId;
|
|
197
|
+
document.head.appendChild(styleEl);
|
|
198
|
+
}
|
|
199
|
+
const colorVars = generateColorVars(colors, prefix);
|
|
200
|
+
const commonVars = generateCommonVars(prefix);
|
|
201
|
+
const shadowVars = generateShadowVars(theme === "dark", prefix);
|
|
202
|
+
const allVars = { ...colorVars, ...commonVars, ...shadowVars };
|
|
203
|
+
styleEl.textContent = `:root {
|
|
204
|
+
${varsToCSS(allVars)}
|
|
205
|
+
}`;
|
|
206
|
+
}
|
|
207
|
+
function setThemeAttribute(theme) {
|
|
208
|
+
document.documentElement.setAttribute("data-theme", theme);
|
|
209
|
+
if (theme === "dark") {
|
|
210
|
+
document.documentElement.classList.add("dark");
|
|
211
|
+
} else {
|
|
212
|
+
document.documentElement.classList.remove("dark");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function getCSSVar(name, prefix = DEFAULT_CSS_PREFIX) {
|
|
216
|
+
const varName = name.startsWith("--") ? name : `--${prefix}-${name}`;
|
|
217
|
+
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
|
|
218
|
+
}
|
|
219
|
+
function setCSSVar(name, value, prefix = DEFAULT_CSS_PREFIX) {
|
|
220
|
+
const varName = name.startsWith("--") ? name : `--${prefix}-${name}`;
|
|
221
|
+
document.documentElement.style.setProperty(varName, value);
|
|
222
|
+
}
|
|
223
|
+
function getSystemTheme() {
|
|
224
|
+
if (typeof window === "undefined") {
|
|
225
|
+
return "light";
|
|
226
|
+
}
|
|
227
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
228
|
+
return mediaQuery.matches ? "dark" : "light";
|
|
229
|
+
}
|
|
230
|
+
function watchSystemTheme(callback) {
|
|
231
|
+
if (typeof window === "undefined") {
|
|
232
|
+
return () => {
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
236
|
+
const handler = (e) => {
|
|
237
|
+
callback(e.matches ? "dark" : "light");
|
|
238
|
+
};
|
|
239
|
+
if (mediaQuery.addEventListener) {
|
|
240
|
+
mediaQuery.addEventListener("change", handler);
|
|
241
|
+
return () => mediaQuery.removeEventListener("change", handler);
|
|
242
|
+
} else {
|
|
243
|
+
mediaQuery.addListener(handler);
|
|
244
|
+
return () => {
|
|
245
|
+
mediaQuery.removeListener(handler);
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function supportsSystemTheme() {
|
|
250
|
+
if (typeof window === "undefined") {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
return window.matchMedia !== void 0;
|
|
254
|
+
}
|
|
255
|
+
function loadMode(storageKey) {
|
|
256
|
+
if (typeof localStorage === "undefined") return null;
|
|
257
|
+
const stored = localStorage.getItem(storageKey);
|
|
258
|
+
if (stored === "light" || stored === "dark" || stored === "system") {
|
|
259
|
+
return stored;
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
function saveMode(storageKey, mode) {
|
|
264
|
+
if (typeof localStorage === "undefined") return;
|
|
265
|
+
localStorage.setItem(storageKey, mode);
|
|
266
|
+
}
|
|
267
|
+
function createTheme(config = {}) {
|
|
268
|
+
const {
|
|
269
|
+
defaultMode = "system",
|
|
270
|
+
storageKey = DEFAULT_STORAGE_KEY,
|
|
271
|
+
persist = true,
|
|
272
|
+
colors: customColors,
|
|
273
|
+
darkColors: customDarkColors,
|
|
274
|
+
preset: presetName,
|
|
275
|
+
cssPrefix = DEFAULT_CSS_PREFIX
|
|
276
|
+
} = config;
|
|
277
|
+
const preset = presetName ? PRESETS[presetName] || DEFAULT_PRESET : DEFAULT_PRESET;
|
|
278
|
+
const lightColors = { ...preset.light, ...customColors };
|
|
279
|
+
const darkColors = { ...preset.dark, ...customDarkColors };
|
|
280
|
+
const mode = ref(
|
|
281
|
+
(persist ? loadMode(storageKey) : null) || defaultMode
|
|
282
|
+
);
|
|
283
|
+
const appliedTheme = computed(() => {
|
|
284
|
+
if (mode.value === "system") {
|
|
285
|
+
return getSystemTheme();
|
|
286
|
+
}
|
|
287
|
+
return mode.value;
|
|
288
|
+
});
|
|
289
|
+
const isDark = computed(() => appliedTheme.value === "dark");
|
|
290
|
+
const colors = computed(() => isDark.value ? darkColors : lightColors);
|
|
291
|
+
let unwatchSystem = null;
|
|
292
|
+
function applyTheme() {
|
|
293
|
+
const theme = appliedTheme.value;
|
|
294
|
+
const currentColors = isDark.value ? darkColors : lightColors;
|
|
295
|
+
injectCSSVars(currentColors, theme, cssPrefix);
|
|
296
|
+
setThemeAttribute(theme);
|
|
297
|
+
}
|
|
298
|
+
function setMode(newMode) {
|
|
299
|
+
mode.value = newMode;
|
|
300
|
+
if (persist) {
|
|
301
|
+
saveMode(storageKey, newMode);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function toggle() {
|
|
305
|
+
if (mode.value === "light") {
|
|
306
|
+
setMode("dark");
|
|
307
|
+
} else if (mode.value === "dark") {
|
|
308
|
+
setMode("light");
|
|
309
|
+
} else {
|
|
310
|
+
setMode(isDark.value ? "light" : "dark");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function setColors(newColors) {
|
|
314
|
+
if (isDark.value) {
|
|
315
|
+
Object.assign(darkColors, newColors);
|
|
316
|
+
} else {
|
|
317
|
+
Object.assign(lightColors, newColors);
|
|
318
|
+
}
|
|
319
|
+
applyTheme();
|
|
320
|
+
}
|
|
321
|
+
function getCssVar(name) {
|
|
322
|
+
return getCSSVar(name, cssPrefix);
|
|
323
|
+
}
|
|
324
|
+
function init() {
|
|
325
|
+
applyTheme();
|
|
326
|
+
if (mode.value === "system") {
|
|
327
|
+
unwatchSystem = watchSystemTheme(() => {
|
|
328
|
+
applyTheme();
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function destroy() {
|
|
333
|
+
if (unwatchSystem) {
|
|
334
|
+
unwatchSystem();
|
|
335
|
+
unwatchSystem = null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
watch(mode, (newMode) => {
|
|
339
|
+
if (unwatchSystem) {
|
|
340
|
+
unwatchSystem();
|
|
341
|
+
unwatchSystem = null;
|
|
342
|
+
}
|
|
343
|
+
if (newMode === "system") {
|
|
344
|
+
unwatchSystem = watchSystemTheme(() => {
|
|
345
|
+
applyTheme();
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
applyTheme();
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
mode,
|
|
352
|
+
appliedTheme,
|
|
353
|
+
isDark,
|
|
354
|
+
colors,
|
|
355
|
+
setMode,
|
|
356
|
+
toggle,
|
|
357
|
+
setColors,
|
|
358
|
+
getCssVar,
|
|
359
|
+
init,
|
|
360
|
+
destroy
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
let globalTheme = null;
|
|
364
|
+
function setupTheme(config = {}) {
|
|
365
|
+
globalTheme = createTheme(config);
|
|
366
|
+
globalTheme.init();
|
|
367
|
+
return globalTheme;
|
|
368
|
+
}
|
|
369
|
+
function useTheme() {
|
|
370
|
+
if (!globalTheme) {
|
|
371
|
+
globalTheme = createTheme();
|
|
372
|
+
onMounted(() => {
|
|
373
|
+
globalTheme.init();
|
|
374
|
+
});
|
|
375
|
+
onUnmounted(() => {
|
|
376
|
+
globalTheme.destroy();
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
mode: globalTheme.mode,
|
|
381
|
+
appliedTheme: globalTheme.appliedTheme,
|
|
382
|
+
isDark: globalTheme.isDark,
|
|
383
|
+
colors: globalTheme.colors,
|
|
384
|
+
setMode: globalTheme.setMode,
|
|
385
|
+
toggle: globalTheme.toggle,
|
|
386
|
+
setColors: globalTheme.setColors,
|
|
387
|
+
getCssVar: globalTheme.getCssVar
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
export {
|
|
391
|
+
DARK_SHADOW,
|
|
392
|
+
DEFAULT_CSS_PREFIX,
|
|
393
|
+
DEFAULT_FONT_FAMILY,
|
|
394
|
+
DEFAULT_FONT_FAMILY_MONO,
|
|
395
|
+
DEFAULT_FONT_SIZE,
|
|
396
|
+
DEFAULT_FONT_WEIGHT,
|
|
397
|
+
DEFAULT_LINE_HEIGHT,
|
|
398
|
+
DEFAULT_PRESET,
|
|
399
|
+
DEFAULT_RADIUS,
|
|
400
|
+
DEFAULT_SHADOW,
|
|
401
|
+
DEFAULT_SPACING,
|
|
402
|
+
DEFAULT_STORAGE_KEY,
|
|
403
|
+
DEFAULT_TRANSITION,
|
|
404
|
+
DEFAULT_Z_INDEX,
|
|
405
|
+
MINT_DARK,
|
|
406
|
+
MINT_LIGHT,
|
|
407
|
+
PRESETS,
|
|
408
|
+
PRESET_MINT,
|
|
409
|
+
createTheme,
|
|
410
|
+
getCSSVar,
|
|
411
|
+
getSystemTheme,
|
|
412
|
+
injectCSSVars,
|
|
413
|
+
setCSSVar,
|
|
414
|
+
setThemeAttribute,
|
|
415
|
+
setupTheme,
|
|
416
|
+
supportsSystemTheme,
|
|
417
|
+
useTheme,
|
|
418
|
+
watchSystemTheme
|
|
419
|
+
};
|
|
420
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/constants.ts","../src/presets.ts","../src/css-vars.ts","../src/system.ts","../src/useTheme.ts"],"sourcesContent":["/**\n * @boo-dreamer/theme - 常量定义\n */\nimport type {\n ThemeRadius,\n ThemeShadow,\n ThemeFontSize,\n ThemeLineHeight,\n ThemeFontWeight,\n ThemeSpacing,\n ThemeTransition,\n ThemeZIndex,\n} from './types.js';\n\n/**\n * 默认圆角\n */\nexport const DEFAULT_RADIUS: ThemeRadius = {\n none: '0',\n sm: '2px',\n base: '4px',\n md: '6px',\n lg: '8px',\n xl: '12px',\n full: '9999px',\n};\n\n/**\n * 默认阴影\n */\nexport const DEFAULT_SHADOW: ThemeShadow = {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)',\n};\n\n/**\n * 暗色模式阴影\n */\nexport const DARK_SHADOW: ThemeShadow = {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)',\n};\n\n/**\n * 默认字号\n */\nexport const DEFAULT_FONT_SIZE: ThemeFontSize = {\n xs: '12px',\n sm: '13px',\n base: '14px',\n md: '16px',\n lg: '18px',\n xl: '20px',\n '2xl': '24px',\n '3xl': '30px',\n};\n\n/**\n * 默认行高\n */\nexport const DEFAULT_LINE_HEIGHT: ThemeLineHeight = {\n tight: '1.25',\n base: '1.5',\n relaxed: '1.75',\n};\n\n/**\n * 默认字重\n */\nexport const DEFAULT_FONT_WEIGHT: ThemeFontWeight = {\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n};\n\n/**\n * 默认间距\n */\nexport const DEFAULT_SPACING: ThemeSpacing = {\n 0: '0',\n 1: '4px',\n 2: '8px',\n 3: '12px',\n 4: '16px',\n 5: '20px',\n 6: '24px',\n 8: '32px',\n 10: '40px',\n 12: '48px',\n};\n\n/**\n * 默认过渡\n */\nexport const DEFAULT_TRANSITION: ThemeTransition = {\n fast: '0.1s',\n base: '0.2s',\n slow: '0.3s',\n ease: 'cubic-bezier(0.4, 0, 0.2, 1)',\n};\n\n/**\n * 默认层级\n */\nexport const DEFAULT_Z_INDEX: ThemeZIndex = {\n dropdown: 1000,\n sticky: 1100,\n fixed: 1200,\n modalBackdrop: 1300,\n modal: 1400,\n popover: 1500,\n tooltip: 1600,\n};\n\n/**\n * 默认字体\n */\nexport const DEFAULT_FONT_FAMILY =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"';\n\n/**\n * 默认代码字体\n */\nexport const DEFAULT_FONT_FAMILY_MONO =\n 'SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace';\n\n/**\n * 默认存储 key\n */\nexport const DEFAULT_STORAGE_KEY = 'boo-theme-mode';\n\n/**\n * 默认 CSS 前缀\n */\nexport const DEFAULT_CSS_PREFIX = 'boo';\n","/**\n * @boo-dreamer/theme - 主题预设(薄荷绿)\n */\nimport type { ThemeColors, ThemePreset } from './types.js';\n\n/**\n * 薄荷绿 - 浅色模式\n */\nexport const MINT_LIGHT: ThemeColors = {\n // 品牌色\n primary: '#10B981',\n primaryLight: '#34D399',\n primaryDark: '#059669',\n primaryBg: '#ECFDF5',\n\n // 功能色\n success: '#22C55E',\n warning: '#F59E0B',\n error: '#EF4444',\n info: '#3B82F6',\n\n // 文字颜色\n textPrimary: '#1F2937',\n textSecondary: '#6B7280',\n textPlaceholder: '#9CA3AF',\n textDisabled: '#D1D5DB',\n\n // 边框\n border: '#E5E7EB',\n borderLight: '#F3F4F6',\n divider: '#E5E7EB',\n\n // 背景\n bgPage: '#F9FAFB',\n bgContainer: '#FFFFFF',\n bgElevated: '#FFFFFF',\n bgSpotlight: '#F3F4F6',\n};\n\n/**\n * 薄荷绿 - 深色模式\n */\nexport const MINT_DARK: ThemeColors = {\n // 品牌色\n primary: '#34D399',\n primaryLight: '#6EE7B7',\n primaryDark: '#10B981',\n primaryBg: '#064E3B',\n\n // 功能色\n success: '#4ADE80',\n warning: '#FBBF24',\n error: '#F87171',\n info: '#60A5FA',\n\n // 文字颜色\n textPrimary: '#F9FAFB',\n textSecondary: '#D1D5DB',\n textPlaceholder: '#9CA3AF',\n textDisabled: '#6B7280',\n\n // 边框\n border: '#374151',\n borderLight: '#4B5563',\n divider: '#374151',\n\n // 背景\n bgPage: '#111827',\n bgContainer: '#1F2937',\n bgElevated: '#374151',\n bgSpotlight: '#374151',\n};\n\n/**\n * 薄荷绿预设\n */\nexport const PRESET_MINT: ThemePreset = {\n name: 'mint',\n light: MINT_LIGHT,\n dark: MINT_DARK,\n};\n\n/**\n * 所有预设\n */\nexport const PRESETS: Record<string, ThemePreset> = {\n mint: PRESET_MINT,\n};\n\n/**\n * 默认预设\n */\nexport const DEFAULT_PRESET = PRESET_MINT;\n","/**\n * @boo-dreamer/theme - CSS 变量注入\n */\nimport type { ThemeColors, AppliedTheme } from './types.js';\nimport {\n DEFAULT_RADIUS,\n DEFAULT_SHADOW,\n DARK_SHADOW,\n DEFAULT_FONT_SIZE,\n DEFAULT_LINE_HEIGHT,\n DEFAULT_FONT_WEIGHT,\n DEFAULT_SPACING,\n DEFAULT_TRANSITION,\n DEFAULT_Z_INDEX,\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_FAMILY_MONO,\n DEFAULT_CSS_PREFIX,\n} from './constants.js';\n\n/**\n * 驼峰转短横线\n */\nfunction camelToKebab(str: string): string {\n return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\n/**\n * 生成 CSS 变量名\n */\nfunction cssVar(prefix: string, category: string, key: string): string {\n return `--${prefix}-${category}-${camelToKebab(key)}`;\n}\n\n/**\n * 生成颜色 CSS 变量\n */\nfunction generateColorVars(colors: ThemeColors, prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n \n for (const [key, value] of Object.entries(colors)) {\n vars[cssVar(prefix, 'color', key)] = value;\n }\n \n return vars;\n}\n\n/**\n * 生成通用 CSS 变量(不随主题变化)\n */\nfunction generateCommonVars(prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n \n // 圆角\n for (const [key, value] of Object.entries(DEFAULT_RADIUS)) {\n vars[cssVar(prefix, 'radius', key)] = value;\n }\n \n // 字号\n for (const [key, value] of Object.entries(DEFAULT_FONT_SIZE)) {\n vars[cssVar(prefix, 'font-size', key)] = value;\n }\n \n // 行高\n for (const [key, value] of Object.entries(DEFAULT_LINE_HEIGHT)) {\n vars[cssVar(prefix, 'line-height', key)] = value;\n }\n \n // 字重\n for (const [key, value] of Object.entries(DEFAULT_FONT_WEIGHT)) {\n vars[cssVar(prefix, 'font-weight', key)] = value;\n }\n \n // 间距\n for (const [key, value] of Object.entries(DEFAULT_SPACING)) {\n vars[cssVar(prefix, 'spacing', key)] = value;\n }\n \n // 过渡\n for (const [key, value] of Object.entries(DEFAULT_TRANSITION)) {\n vars[cssVar(prefix, 'transition', key)] = value;\n }\n \n // 层级\n for (const [key, value] of Object.entries(DEFAULT_Z_INDEX)) {\n vars[cssVar(prefix, 'z', camelToKebab(key))] = String(value);\n }\n \n // 字体\n vars[`--${prefix}-font-family`] = DEFAULT_FONT_FAMILY;\n vars[`--${prefix}-font-family-mono`] = DEFAULT_FONT_FAMILY_MONO;\n \n return vars;\n}\n\n/**\n * 生成阴影 CSS 变量\n */\nfunction generateShadowVars(isDark: boolean, prefix: string): Record<string, string> {\n const vars: Record<string, string> = {};\n const shadow = isDark ? DARK_SHADOW : DEFAULT_SHADOW;\n \n for (const [key, value] of Object.entries(shadow)) {\n vars[cssVar(prefix, 'shadow', key)] = value;\n }\n \n return vars;\n}\n\n/**\n * 将变量对象转换为 CSS 字符串\n */\nfunction varsToCSS(vars: Record<string, string>): string {\n return Object.entries(vars)\n .map(([key, value]) => `${key}: ${value};`)\n .join('\\n ');\n}\n\n/**\n * 注入 CSS 变量到页面\n */\nexport function injectCSSVars(\n colors: ThemeColors,\n theme: AppliedTheme,\n prefix: string = DEFAULT_CSS_PREFIX\n): void {\n const styleId = `${prefix}-theme-vars`;\n let styleEl = document.getElementById(styleId) as HTMLStyleElement | null;\n \n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.id = styleId;\n document.head.appendChild(styleEl);\n }\n \n const colorVars = generateColorVars(colors, prefix);\n const commonVars = generateCommonVars(prefix);\n const shadowVars = generateShadowVars(theme === 'dark', prefix);\n \n const allVars = { ...colorVars, ...commonVars, ...shadowVars };\n \n styleEl.textContent = `:root {\\n ${varsToCSS(allVars)}\\n}`;\n}\n\n/**\n * 设置 HTML 属性(用于 CSS 选择器)\n */\nexport function setThemeAttribute(theme: AppliedTheme): void {\n document.documentElement.setAttribute('data-theme', theme);\n \n // 同时设置 class,方便 Tailwind 等框架使用\n if (theme === 'dark') {\n document.documentElement.classList.add('dark');\n } else {\n document.documentElement.classList.remove('dark');\n }\n}\n\n/**\n * 获取 CSS 变量值\n */\nexport function getCSSVar(name: string, prefix: string = DEFAULT_CSS_PREFIX): string {\n const varName = name.startsWith('--') ? name : `--${prefix}-${name}`;\n return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();\n}\n\n/**\n * 设置单个 CSS 变量\n */\nexport function setCSSVar(\n name: string,\n value: string,\n prefix: string = DEFAULT_CSS_PREFIX\n): void {\n const varName = name.startsWith('--') ? name : `--${prefix}-${name}`;\n document.documentElement.style.setProperty(varName, value);\n}\n","/**\n * @boo-dreamer/theme - 系统主题监听\n */\nimport type { AppliedTheme } from './types.js';\n\n/**\n * 获取系统主题偏好\n */\nexport function getSystemTheme(): AppliedTheme {\n if (typeof window === 'undefined') {\n return 'light';\n }\n \n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n return mediaQuery.matches ? 'dark' : 'light';\n}\n\n/**\n * 监听系统主题变化\n */\nexport function watchSystemTheme(callback: (theme: AppliedTheme) => void): () => void {\n if (typeof window === 'undefined') {\n return () => {};\n }\n \n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n \n const handler = (e: MediaQueryListEvent) => {\n callback(e.matches ? 'dark' : 'light');\n };\n \n // 兼容旧版浏览器\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handler);\n return () => mediaQuery.removeEventListener('change', handler);\n } else {\n // 旧版 API\n (mediaQuery as unknown as { addListener: (h: typeof handler) => void }).addListener(handler);\n return () => {\n (mediaQuery as unknown as { removeListener: (h: typeof handler) => void }).removeListener(handler);\n };\n }\n}\n\n/**\n * 检查是否支持系统主题检测\n */\nexport function supportsSystemTheme(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n return window.matchMedia !== undefined;\n}\n","/**\n * @boo-dreamer/theme - useTheme 组合式函数\n */\nimport { ref, computed, watch, onMounted, onUnmounted } from 'vue';\nimport type {\n ThemeMode,\n AppliedTheme,\n ThemeColors,\n ThemeConfig,\n UseThemeReturn,\n} from './types.js';\nimport { DEFAULT_PRESET, PRESETS } from './presets.js';\nimport { DEFAULT_STORAGE_KEY, DEFAULT_CSS_PREFIX } from './constants.js';\nimport { injectCSSVars, setThemeAttribute, getCSSVar } from './css-vars.js';\nimport { getSystemTheme, watchSystemTheme } from './system.js';\n\n/**\n * 从 localStorage 读取模式\n */\nfunction loadMode(storageKey: string): ThemeMode | null {\n if (typeof localStorage === 'undefined') return null;\n const stored = localStorage.getItem(storageKey);\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n return stored;\n }\n return null;\n}\n\n/**\n * 保存模式到 localStorage\n */\nfunction saveMode(storageKey: string, mode: ThemeMode): void {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(storageKey, mode);\n}\n\n/**\n * 创建主题管理\n */\nexport function createTheme(config: ThemeConfig = {}) {\n const {\n defaultMode = 'system',\n storageKey = DEFAULT_STORAGE_KEY,\n persist = true,\n colors: customColors,\n darkColors: customDarkColors,\n preset: presetName,\n cssPrefix = DEFAULT_CSS_PREFIX,\n } = config;\n\n // 获取预设\n const preset = presetName ? PRESETS[presetName] || DEFAULT_PRESET : DEFAULT_PRESET;\n\n // 合并自定义颜色\n const lightColors: ThemeColors = { ...preset.light, ...customColors };\n const darkColors: ThemeColors = { ...preset.dark, ...customDarkColors };\n\n // 状态\n const mode = ref<ThemeMode>(\n (persist ? loadMode(storageKey) : null) || defaultMode\n );\n\n // 计算实际应用的主题\n const appliedTheme = computed<AppliedTheme>(() => {\n if (mode.value === 'system') {\n return getSystemTheme();\n }\n return mode.value;\n });\n\n // 是否暗色模式\n const isDark = computed(() => appliedTheme.value === 'dark');\n\n // 当前颜色\n const colors = computed(() => (isDark.value ? darkColors : lightColors));\n\n // 系统主题变化时触发更新\n let unwatchSystem: (() => void) | null = null;\n\n /**\n * 应用主题\n */\n function applyTheme(): void {\n const theme = appliedTheme.value;\n const currentColors = isDark.value ? darkColors : lightColors;\n \n injectCSSVars(currentColors, theme, cssPrefix);\n setThemeAttribute(theme);\n }\n\n /**\n * 设置模式\n */\n function setMode(newMode: ThemeMode): void {\n mode.value = newMode;\n if (persist) {\n saveMode(storageKey, newMode);\n }\n }\n\n /**\n * 切换主题\n */\n function toggle(): void {\n if (mode.value === 'light') {\n setMode('dark');\n } else if (mode.value === 'dark') {\n setMode('light');\n } else {\n // system 模式下,切换到当前实际主题的反面\n setMode(isDark.value ? 'light' : 'dark');\n }\n }\n\n /**\n * 设置自定义颜色(运行时)\n */\n function setColors(newColors: Partial<ThemeColors>): void {\n if (isDark.value) {\n Object.assign(darkColors, newColors);\n } else {\n Object.assign(lightColors, newColors);\n }\n applyTheme();\n }\n\n /**\n * 获取 CSS 变量值\n */\n function getCssVar(name: string): string {\n return getCSSVar(name, cssPrefix);\n }\n\n /**\n * 初始化\n */\n function init(): void {\n applyTheme();\n\n // 监听系统主题变化\n if (mode.value === 'system') {\n unwatchSystem = watchSystemTheme(() => {\n applyTheme();\n });\n }\n }\n\n /**\n * 销毁\n */\n function destroy(): void {\n if (unwatchSystem) {\n unwatchSystem();\n unwatchSystem = null;\n }\n }\n\n // 监听模式变化\n watch(mode, (newMode) => {\n // 清除旧的系统监听\n if (unwatchSystem) {\n unwatchSystem();\n unwatchSystem = null;\n }\n\n // 如果是 system 模式,重新监听\n if (newMode === 'system') {\n unwatchSystem = watchSystemTheme(() => {\n applyTheme();\n });\n }\n\n applyTheme();\n });\n\n return {\n mode,\n appliedTheme,\n isDark,\n colors,\n setMode,\n toggle,\n setColors,\n getCssVar,\n init,\n destroy,\n };\n}\n\n// 全局实例\nlet globalTheme: ReturnType<typeof createTheme> | null = null;\n\n/**\n * 初始化主题(在 app 入口调用)\n */\nexport function setupTheme(config: ThemeConfig = {}): ReturnType<typeof createTheme> {\n globalTheme = createTheme(config);\n globalTheme.init();\n return globalTheme;\n}\n\n/**\n * useTheme 组合式函数\n */\nexport function useTheme(): UseThemeReturn {\n if (!globalTheme) {\n // 如果没有初始化,创建一个默认实例\n globalTheme = createTheme();\n \n // 在组件挂载时初始化\n onMounted(() => {\n globalTheme!.init();\n });\n\n onUnmounted(() => {\n globalTheme!.destroy();\n });\n }\n\n return {\n mode: globalTheme.mode,\n appliedTheme: globalTheme.appliedTheme,\n isDark: globalTheme.isDark,\n colors: globalTheme.colors,\n setMode: globalTheme.setMode,\n toggle: globalTheme.toggle,\n setColors: globalTheme.setColors,\n getCssVar: globalTheme.getCssVar,\n };\n}\n"],"names":[],"mappings":";AAiBO,MAAM,iBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR;AAKO,MAAM,iBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAKO,MAAM,cAA2B;AAAA,EACtC,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAKO,MAAM,oBAAmC;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,OAAO;AACT;AAKO,MAAM,sBAAuC;AAAA,EAClD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AACX;AAKO,MAAM,sBAAuC;AAAA,EAClD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AACR;AAKO,MAAM,kBAAgC;AAAA,EAC3C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AACN;AAKO,MAAM,qBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAKO,MAAM,kBAA+B;AAAA,EAC1C,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,eAAe;AAAA,EACf,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AACX;AAKO,MAAM,sBACX;AAKK,MAAM,2BACX;AAKK,MAAM,sBAAsB;AAK5B,MAAM,qBAAqB;ACvI3B,MAAM,aAA0B;AAAA;AAAA,EAErC,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAGX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA;AAAA,EAGN,aAAa;AAAA,EACb,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA;AAAA,EAGd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA;AAAA,EAGT,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,aAAa;AACf;AAKO,MAAM,YAAyB;AAAA;AAAA,EAEpC,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAGX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA;AAAA,EAGN,aAAa;AAAA,EACb,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA;AAAA,EAGd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA;AAAA,EAGT,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,aAAa;AACf;AAKO,MAAM,cAA2B;AAAA,EACtC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AACR;AAKO,MAAM,UAAuC;AAAA,EAClD,MAAM;AACR;AAKO,MAAM,iBAAiB;ACtE9B,SAAS,aAAa,KAAqB;AACzC,SAAO,IAAI,QAAQ,sBAAsB,OAAO,EAAE,YAAA;AACpD;AAKA,SAAS,OAAO,QAAgB,UAAkB,KAAqB;AACrE,SAAO,KAAK,MAAM,IAAI,QAAQ,IAAI,aAAa,GAAG,CAAC;AACrD;AAKA,SAAS,kBAAkB,QAAqB,QAAwC;AACtF,QAAM,OAA+B,CAAA;AAErC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,SAAK,OAAO,QAAQ,SAAS,GAAG,CAAC,IAAI;AAAA,EACvC;AAEA,SAAO;AACT;AAKA,SAAS,mBAAmB,QAAwC;AAClE,QAAM,OAA+B,CAAA;AAGrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,SAAK,OAAO,QAAQ,UAAU,GAAG,CAAC,IAAI;AAAA,EACxC;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AAC5D,SAAK,OAAO,QAAQ,aAAa,GAAG,CAAC,IAAI;AAAA,EAC3C;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AAC9D,SAAK,OAAO,QAAQ,eAAe,GAAG,CAAC,IAAI;AAAA,EAC7C;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AAC9D,SAAK,OAAO,QAAQ,eAAe,GAAG,CAAC,IAAI;AAAA,EAC7C;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,SAAK,OAAO,QAAQ,WAAW,GAAG,CAAC,IAAI;AAAA,EACzC;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,kBAAkB,GAAG;AAC7D,SAAK,OAAO,QAAQ,cAAc,GAAG,CAAC,IAAI;AAAA,EAC5C;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,SAAK,OAAO,QAAQ,KAAK,aAAa,GAAG,CAAC,CAAC,IAAI,OAAO,KAAK;AAAA,EAC7D;AAGA,OAAK,KAAK,MAAM,cAAc,IAAI;AAClC,OAAK,KAAK,MAAM,mBAAmB,IAAI;AAEvC,SAAO;AACT;AAKA,SAAS,mBAAmB,QAAiB,QAAwC;AACnF,QAAM,OAA+B,CAAA;AACrC,QAAM,SAAS,SAAS,cAAc;AAEtC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,SAAK,OAAO,QAAQ,UAAU,GAAG,CAAC,IAAI;AAAA,EACxC;AAEA,SAAO;AACT;AAKA,SAAS,UAAU,MAAsC;AACvD,SAAO,OAAO,QAAQ,IAAI,EACvB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,GAAG,EACzC,KAAK,MAAM;AAChB;AAKO,SAAS,cACd,QACA,OACA,SAAiB,oBACX;AACN,QAAM,UAAU,GAAG,MAAM;AACzB,MAAI,UAAU,SAAS,eAAe,OAAO;AAE7C,MAAI,CAAC,SAAS;AACZ,cAAU,SAAS,cAAc,OAAO;AACxC,YAAQ,KAAK;AACb,aAAS,KAAK,YAAY,OAAO;AAAA,EACnC;AAEA,QAAM,YAAY,kBAAkB,QAAQ,MAAM;AAClD,QAAM,aAAa,mBAAmB,MAAM;AAC5C,QAAM,aAAa,mBAAmB,UAAU,QAAQ,MAAM;AAE9D,QAAM,UAAU,EAAE,GAAG,WAAW,GAAG,YAAY,GAAG,WAAA;AAElD,UAAQ,cAAc;AAAA,IAAc,UAAU,OAAO,CAAC;AAAA;AACxD;AAKO,SAAS,kBAAkB,OAA2B;AAC3D,WAAS,gBAAgB,aAAa,cAAc,KAAK;AAGzD,MAAI,UAAU,QAAQ;AACpB,aAAS,gBAAgB,UAAU,IAAI,MAAM;AAAA,EAC/C,OAAO;AACL,aAAS,gBAAgB,UAAU,OAAO,MAAM;AAAA,EAClD;AACF;AAKO,SAAS,UAAU,MAAc,SAAiB,oBAA4B;AACnF,QAAM,UAAU,KAAK,WAAW,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;AAClE,SAAO,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,OAAO,EAAE,KAAA;AAC9E;AAKO,SAAS,UACd,MACA,OACA,SAAiB,oBACX;AACN,QAAM,UAAU,KAAK,WAAW,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;AAClE,WAAS,gBAAgB,MAAM,YAAY,SAAS,KAAK;AAC3D;ACvKO,SAAS,iBAA+B;AAC7C,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,WAAW,8BAA8B;AACnE,SAAO,WAAW,UAAU,SAAS;AACvC;AAKO,SAAS,iBAAiB,UAAqD;AACpF,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,QAAM,aAAa,OAAO,WAAW,8BAA8B;AAEnE,QAAM,UAAU,CAAC,MAA2B;AAC1C,aAAS,EAAE,UAAU,SAAS,OAAO;AAAA,EACvC;AAGA,MAAI,WAAW,kBAAkB;AAC/B,eAAW,iBAAiB,UAAU,OAAO;AAC7C,WAAO,MAAM,WAAW,oBAAoB,UAAU,OAAO;AAAA,EAC/D,OAAO;AAEJ,eAAuE,YAAY,OAAO;AAC3F,WAAO,MAAM;AACV,iBAA0E,eAAe,OAAO;AAAA,IACnG;AAAA,EACF;AACF;AAKO,SAAS,sBAA+B;AAC7C,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AACA,SAAO,OAAO,eAAe;AAC/B;ACjCA,SAAS,SAAS,YAAsC;AACtD,MAAI,OAAO,iBAAiB,YAAa,QAAO;AAChD,QAAM,SAAS,aAAa,QAAQ,UAAU;AAC9C,MAAI,WAAW,WAAW,WAAW,UAAU,WAAW,UAAU;AAClE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,SAAS,SAAS,YAAoB,MAAuB;AAC3D,MAAI,OAAO,iBAAiB,YAAa;AACzC,eAAa,QAAQ,YAAY,IAAI;AACvC;AAKO,SAAS,YAAY,SAAsB,IAAI;AACpD,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,aAAa;AAAA,IACb,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,YAAY;AAAA,EAAA,IACV;AAGJ,QAAM,SAAS,aAAa,QAAQ,UAAU,KAAK,iBAAiB;AAGpE,QAAM,cAA2B,EAAE,GAAG,OAAO,OAAO,GAAG,aAAA;AACvD,QAAM,aAA0B,EAAE,GAAG,OAAO,MAAM,GAAG,iBAAA;AAGrD,QAAM,OAAO;AAAA,KACV,UAAU,SAAS,UAAU,IAAI,SAAS;AAAA,EAAA;AAI7C,QAAM,eAAe,SAAuB,MAAM;AAChD,QAAI,KAAK,UAAU,UAAU;AAC3B,aAAO,eAAA;AAAA,IACT;AACA,WAAO,KAAK;AAAA,EACd,CAAC;AAGD,QAAM,SAAS,SAAS,MAAM,aAAa,UAAU,MAAM;AAG3D,QAAM,SAAS,SAAS,MAAO,OAAO,QAAQ,aAAa,WAAY;AAGvE,MAAI,gBAAqC;AAKzC,WAAS,aAAmB;AAC1B,UAAM,QAAQ,aAAa;AAC3B,UAAM,gBAAgB,OAAO,QAAQ,aAAa;AAElD,kBAAc,eAAe,OAAO,SAAS;AAC7C,sBAAkB,KAAK;AAAA,EACzB;AAKA,WAAS,QAAQ,SAA0B;AACzC,SAAK,QAAQ;AACb,QAAI,SAAS;AACX,eAAS,YAAY,OAAO;AAAA,IAC9B;AAAA,EACF;AAKA,WAAS,SAAe;AACtB,QAAI,KAAK,UAAU,SAAS;AAC1B,cAAQ,MAAM;AAAA,IAChB,WAAW,KAAK,UAAU,QAAQ;AAChC,cAAQ,OAAO;AAAA,IACjB,OAAO;AAEL,cAAQ,OAAO,QAAQ,UAAU,MAAM;AAAA,IACzC;AAAA,EACF;AAKA,WAAS,UAAU,WAAuC;AACxD,QAAI,OAAO,OAAO;AAChB,aAAO,OAAO,YAAY,SAAS;AAAA,IACrC,OAAO;AACL,aAAO,OAAO,aAAa,SAAS;AAAA,IACtC;AACA,eAAA;AAAA,EACF;AAKA,WAAS,UAAU,MAAsB;AACvC,WAAO,UAAU,MAAM,SAAS;AAAA,EAClC;AAKA,WAAS,OAAa;AACpB,eAAA;AAGA,QAAI,KAAK,UAAU,UAAU;AAC3B,sBAAgB,iBAAiB,MAAM;AACrC,mBAAA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAKA,WAAS,UAAgB;AACvB,QAAI,eAAe;AACjB,oBAAA;AACA,sBAAgB;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,MAAM,CAAC,YAAY;AAEvB,QAAI,eAAe;AACjB,oBAAA;AACA,sBAAgB;AAAA,IAClB;AAGA,QAAI,YAAY,UAAU;AACxB,sBAAgB,iBAAiB,MAAM;AACrC,mBAAA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,eAAA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAGA,IAAI,cAAqD;AAKlD,SAAS,WAAW,SAAsB,IAAoC;AACnF,gBAAc,YAAY,MAAM;AAChC,cAAY,KAAA;AACZ,SAAO;AACT;AAKO,SAAS,WAA2B;AACzC,MAAI,CAAC,aAAa;AAEhB,kBAAc,YAAA;AAGd,cAAU,MAAM;AACd,kBAAa,KAAA;AAAA,IACf,CAAC;AAED,gBAAY,MAAM;AAChB,kBAAa,QAAA;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,YAAY;AAAA,IAClB,cAAc,YAAY;AAAA,IAC1B,QAAQ,YAAY;AAAA,IACpB,QAAQ,YAAY;AAAA,IACpB,SAAS,YAAY;AAAA,IACrB,QAAQ,YAAY;AAAA,IACpB,WAAW,YAAY;AAAA,IACvB,WAAW,YAAY;AAAA,EAAA;AAE3B;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@boo-dreamer/theme",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Vue3 主题管理工具包,支持 light/dark/system 模式切换、CSS 变量注入",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"keywords": [
|
|
21
|
+
"theme",
|
|
22
|
+
"dark-mode",
|
|
23
|
+
"css-variables",
|
|
24
|
+
"vue3"
|
|
25
|
+
],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"vue": "^3.0.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "vite build",
|
|
39
|
+
"dev": "vite build --watch",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"clean": "rm -rf dist"
|
|
42
|
+
}
|
|
43
|
+
}
|