@lytjs/plugin-theme 5.0.1 → 6.0.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/dist/index.cjs CHANGED
@@ -1 +1,179 @@
1
- "use strict";var p=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var Q=Object.prototype.hasOwnProperty;var z=(r,n)=>{for(var g in n)p(r,g,{get:n[g],enumerable:!0})},B=(r,n,g,d)=>{if(n&&typeof n=="object"||typeof n=="function")for(let l of K(n))!Q.call(r,l)&&l!==g&&p(r,l,{get:()=>n[l],enumerable:!(d=H(n,l))||d.enumerable});return r};var R=r=>B(p({},"__esModule",{value:!0}),r);var G={};z(G,{BUILT_IN_THEMES:()=>w,createTheme:()=>q});module.exports=R(G);var w={light:{"--bg":"#ffffff","--bg-secondary":"#f5f5f5","--text":"#333333","--text-secondary":"#666666","--text-muted":"#999999","--primary":"#42b883","--primary-hover":"#3aa876","--secondary":"#35495e","--success":"#10b981","--warning":"#f59e0b","--error":"#ef4444","--info":"#3b82f6","--border":"#e5e7eb","--shadow":"rgba(0, 0, 0, 0.1)"},dark:{"--bg":"#1a1a1a","--bg-secondary":"#2d2d2d","--text":"#e5e5e5","--text-secondary":"#a3a3a3","--text-muted":"#737373","--primary":"#42b883","--primary-hover":"#3aa876","--secondary":"#94a3b8","--success":"#10b981","--warning":"#f59e0b","--error":"#ef4444","--info":"#3b82f6","--border":"#404040","--shadow":"rgba(0, 0, 0, 0.3)"}};function y(){if(typeof document=="undefined")return null;let r=document.documentElement;return!r||!r.style||typeof r.style.setProperty!="function"?null:r}function U(r){return(...n)=>{}}function q(r={}){let{default:n="light",storageKey:g="lyt_theme",themes:d={},onChange:l,autoDetect:$=!0,useDataAttribute:k=!0,cssPrefix:u="--lyt-",debug:C=!1}=r,s=U(C),a={...w,...d},c=n,f={};function x(){try{let e=localStorage.getItem(g);if(e&&a[e])return e}catch(e){}return null}function E(e){try{localStorage.setItem(g,e)}catch(t){}}function P(){var e;return typeof window=="undefined"?"light":(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function O(e){if(typeof window=="undefined"||!window.matchMedia)return()=>{};let t=window.matchMedia("(prefers-color-scheme: dark)");function i(o){e(o.matches?"dark":"light")}return t.addEventListener("change",i),()=>t.removeEventListener("change",i)}function h(e){let t=y();if(!t)return;let i=a[e];if(!i){s(`theme '${e}' not found`);return}s(`applying theme '${e}'`,i),Object.entries(i).forEach(([o,v])=>{let T=o.startsWith("--")?o:`${u}${o}`;t.style.setProperty(T,v)}),Object.entries(f).forEach(([o,v])=>{let T=o.startsWith("--")?o:`${u}${o}`;t.style.setProperty(T,v)}),k&&t.setAttribute("data-theme",e),t.style.setProperty("color-scheme",e==="dark"?"dark":"light")}function m(e){if(!a[e]){s(`theme '${e}' not found, available:`,Object.keys(a));return}let t=c;t!==e&&(c=e,h(e),E(e),l&&l(e,t),s(`theme changed from '${t}' to '${e}'`))}function V(){let e=Object.keys(a),i=(e.indexOf(c)+1)%e.length;m(e[i])}function S(){m(n)}function j(){return Object.keys(a)}function I(e,t){a[e]=t,s(`added/updated theme '${e}'`,t),c===e&&h(e)}function L(e){if(e===n){s("cannot remove default theme");return}delete a[e],c===e&&m(n),s(`removed theme '${e}'`)}function M(){return a[c]||null}function A(e){return a[e]||null}function D(e,t){let i=e.startsWith("--")?e:`${u}${e}`;f[i]=t;let o=y();o&&o.style.setProperty(i,t),s(`set variable '${i}' = '${t}'`)}function W(e){let t=e.startsWith("--")?e:`${u}${e}`;delete f[t];let i=y();i&&i.style.removeProperty(t),s(`cleared variable '${t}'`)}function _(){let e=y();Object.keys(f).forEach(t=>{e&&e.style.removeProperty(t)}),Object.keys(f).forEach(t=>delete f[t]),h(c),s("cleared all dynamic variables")}function F(){let e=x();if(!e&&$){let t=P();e=a[t]?t:n}e||(e=n),s(`initializing with theme '${e}'`),c=e,h(e)}F();let b={install(e,t){e.config=e.config||{},e.config.globalProperties=e.config.globalProperties||{},e.config.globalProperties.$theme=b,typeof e.provide=="function"&&e.provide("theme",b)},get current(){return c},set:m,toggle:V,reset:S,list:j,addTheme:I,removeTheme:L,getConfig:M,getConfigFor:A,setVariable:D,clearVariable:W,clearVariables:_,getSystemPreference:P,watchSystemPreference:O};return b}
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('@lytjs/core');
6
+ var reactivity = require('@lytjs/reactivity');
7
+
8
+ // src/index.ts
9
+ var defaultThemes = [
10
+ {
11
+ name: "light",
12
+ isDark: false,
13
+ variables: {
14
+ "--lyt-bg-primary": "#ffffff",
15
+ "--lyt-bg-secondary": "#f5f5f5",
16
+ "--lyt-text-primary": "#333333",
17
+ "--lyt-text-secondary": "#666666",
18
+ "--lyt-primary": "#1890ff",
19
+ "--lyt-success": "#52c41a",
20
+ "--lyt-warning": "#faad14",
21
+ "--lyt-error": "#ff4d4f",
22
+ "--lyt-border": "#d9d9d9"
23
+ }
24
+ },
25
+ {
26
+ name: "dark",
27
+ isDark: true,
28
+ variables: {
29
+ "--lyt-bg-primary": "#141414",
30
+ "--lyt-bg-secondary": "#1f1f1f",
31
+ "--lyt-text-primary": "#ffffff",
32
+ "--lyt-text-secondary": "#a6a6a6",
33
+ "--lyt-primary": "#177ddc",
34
+ "--lyt-success": "#49aa19",
35
+ "--lyt-warning": "#d89614",
36
+ "--lyt-error": "#d32029",
37
+ "--lyt-border": "#434343"
38
+ }
39
+ }
40
+ ];
41
+ function getSystemTheme() {
42
+ if (typeof window !== "undefined" && window.matchMedia) {
43
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
44
+ }
45
+ return "light";
46
+ }
47
+ function createThemeManager(options = {}) {
48
+ const {
49
+ defaultTheme = "light",
50
+ themes = defaultThemes,
51
+ enableSystemTheme = true,
52
+ storageKey = "lyt-theme"
53
+ } = options;
54
+ const themeMap = new Map(themes.map((t) => [t.name, t]));
55
+ const currentThemeSignal = reactivity.signal(defaultTheme);
56
+ const availableThemesSignal = reactivity.signal(themes.map((t) => t.name));
57
+ let styleElement = null;
58
+ let systemThemeMediaQuery = null;
59
+ function applyThemeVariables(variables) {
60
+ if (typeof document === "undefined") return;
61
+ if (!styleElement) {
62
+ styleElement = document.createElement("style");
63
+ styleElement.setAttribute("data-lyt-theme", "true");
64
+ document.head.appendChild(styleElement);
65
+ }
66
+ const cssVars = Object.entries(variables).map(([key, value]) => `${key}: ${value};`).join("\n");
67
+ styleElement.textContent = `:root {
68
+ ${cssVars}
69
+ }`;
70
+ }
71
+ function getStoredTheme() {
72
+ if (typeof localStorage === "undefined") return null;
73
+ try {
74
+ return localStorage.getItem(storageKey);
75
+ } catch {
76
+ return null;
77
+ }
78
+ }
79
+ function setStoredTheme(name) {
80
+ if (typeof localStorage === "undefined") return;
81
+ try {
82
+ localStorage.setItem(storageKey, name);
83
+ } catch {
84
+ }
85
+ }
86
+ function setTheme(name) {
87
+ if (!themeMap.has(name)) {
88
+ console.warn(`[Theme] Theme "${name}" not found, falling back to default`);
89
+ name = defaultTheme;
90
+ }
91
+ const theme = themeMap.get(name);
92
+ currentThemeSignal.set(name);
93
+ setStoredTheme(name);
94
+ applyThemeVariables(theme.variables);
95
+ if (typeof document !== "undefined") {
96
+ document.documentElement.setAttribute("data-lyt-theme", name);
97
+ document.documentElement.classList.toggle("lyt-theme-dark", !!theme.isDark);
98
+ }
99
+ }
100
+ function toggleTheme() {
101
+ const available = availableThemesSignal();
102
+ const currentIndex = available.indexOf(currentThemeSignal());
103
+ const nextIndex = (currentIndex + 1) % available.length;
104
+ const nextTheme = available[nextIndex];
105
+ if (nextTheme) {
106
+ setTheme(nextTheme);
107
+ }
108
+ }
109
+ function registerTheme(theme) {
110
+ themeMap.set(theme.name, theme);
111
+ availableThemesSignal.set([...availableThemesSignal(), theme.name]);
112
+ }
113
+ function getThemeVariables(name) {
114
+ const themeName = name || currentThemeSignal();
115
+ const theme = themeMap.get(themeName);
116
+ return theme ? theme.variables : {};
117
+ }
118
+ function init() {
119
+ let initialTheme = defaultTheme;
120
+ const storedTheme = getStoredTheme();
121
+ if (storedTheme && themeMap.has(storedTheme)) {
122
+ initialTheme = storedTheme;
123
+ } else if (enableSystemTheme) {
124
+ initialTheme = getSystemTheme();
125
+ }
126
+ setTheme(initialTheme);
127
+ if (enableSystemTheme && typeof window !== "undefined" && window.matchMedia) {
128
+ systemThemeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
129
+ systemThemeMediaQuery.addEventListener("change", (e) => {
130
+ const storedTheme2 = getStoredTheme();
131
+ if (!storedTheme2) {
132
+ setTheme(e.matches ? "dark" : "light");
133
+ }
134
+ });
135
+ }
136
+ }
137
+ init();
138
+ return {
139
+ get currentTheme() {
140
+ return currentThemeSignal();
141
+ },
142
+ get availableThemes() {
143
+ return availableThemesSignal();
144
+ },
145
+ setTheme,
146
+ toggleTheme,
147
+ registerTheme,
148
+ getThemeVariables
149
+ };
150
+ }
151
+ var pluginTheme = core.definePlugin({
152
+ name: "theme",
153
+ version: "6.0.0",
154
+ description: "LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support",
155
+ author: "LytJS Team",
156
+ keywords: ["lytjs", "theme", "dark-mode", "css-variables"],
157
+ schema: {
158
+ type: "object",
159
+ object: {
160
+ properties: {
161
+ defaultTheme: { type: "string", default: "light" },
162
+ themes: { type: "array", default: defaultThemes },
163
+ enableSystemTheme: { type: "boolean", default: true },
164
+ storageKey: { type: "string", default: "lyt-theme" }
165
+ }
166
+ }
167
+ },
168
+ install(app, options) {
169
+ const themeManager = createThemeManager(options);
170
+ app.config.globalProperties.$theme = themeManager;
171
+ app.provide("lyt-theme", themeManager);
172
+ }
173
+ });
174
+ var index_default = pluginTheme;
175
+
176
+ exports.createThemeManager = createThemeManager;
177
+ exports.default = index_default;
178
+ //# sourceMappingURL=index.cjs.map
179
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["signal","storedTheme","definePlugin"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * @lytjs/plugin-theme\r\n *\r\n * LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { definePlugin } from '@lytjs/core';\r\nimport { signal } from '@lytjs/reactivity';\r\nimport type { Theme, ThemeOptions, ThemeInstance } from './types';\r\n\r\nconst defaultThemes: Theme[] = [\r\n {\r\n name: 'light',\r\n isDark: false,\r\n variables: {\r\n '--lyt-bg-primary': '#ffffff',\r\n '--lyt-bg-secondary': '#f5f5f5',\r\n '--lyt-text-primary': '#333333',\r\n '--lyt-text-secondary': '#666666',\r\n '--lyt-primary': '#1890ff',\r\n '--lyt-success': '#52c41a',\r\n '--lyt-warning': '#faad14',\r\n '--lyt-error': '#ff4d4f',\r\n '--lyt-border': '#d9d9d9',\r\n },\r\n },\r\n {\r\n name: 'dark',\r\n isDark: true,\r\n variables: {\r\n '--lyt-bg-primary': '#141414',\r\n '--lyt-bg-secondary': '#1f1f1f',\r\n '--lyt-text-primary': '#ffffff',\r\n '--lyt-text-secondary': '#a6a6a6',\r\n '--lyt-primary': '#177ddc',\r\n '--lyt-success': '#49aa19',\r\n '--lyt-warning': '#d89614',\r\n '--lyt-error': '#d32029',\r\n '--lyt-border': '#434343',\r\n },\r\n },\r\n];\r\n\r\nfunction getSystemTheme(): string {\r\n if (typeof window !== 'undefined' && window.matchMedia) {\r\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\r\n }\r\n return 'light';\r\n}\r\n\r\nfunction createThemeManager(options: ThemeOptions = {}): ThemeInstance {\r\n const {\r\n defaultTheme = 'light',\r\n themes = defaultThemes,\r\n enableSystemTheme = true,\r\n storageKey = 'lyt-theme',\r\n } = options;\r\n\r\n const themeMap = new Map<string, Theme>(themes.map((t) => [t.name, t]));\r\n const currentThemeSignal = signal<string>(defaultTheme);\r\n const availableThemesSignal = signal<string[]>(themes.map((t) => t.name));\r\n\r\n let styleElement: HTMLStyleElement | null = null;\r\n let systemThemeMediaQuery: MediaQueryList | null = null;\r\n\r\n function applyThemeVariables(variables: Record<string, string>) {\r\n if (typeof document === 'undefined') return;\r\n\r\n if (!styleElement) {\r\n styleElement = document.createElement('style');\r\n styleElement.setAttribute('data-lyt-theme', 'true');\r\n document.head.appendChild(styleElement);\r\n }\r\n\r\n const cssVars = Object.entries(variables)\r\n .map(([key, value]) => `${key}: ${value};`)\r\n .join('\\n');\r\n\r\n styleElement.textContent = `:root {\\n${cssVars}\\n}`;\r\n }\r\n\r\n function getStoredTheme(): string | null {\r\n if (typeof localStorage === 'undefined') return null;\r\n try {\r\n return localStorage.getItem(storageKey);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n function setStoredTheme(name: string) {\r\n if (typeof localStorage === 'undefined') return;\r\n try {\r\n localStorage.setItem(storageKey, name);\r\n } catch {\r\n }\r\n }\r\n\r\n function setTheme(name: string) {\r\n if (!themeMap.has(name)) {\r\n console.warn(`[Theme] Theme \"${name}\" not found, falling back to default`);\r\n name = defaultTheme;\r\n }\r\n\r\n const theme = themeMap.get(name)!;\r\n currentThemeSignal.set(name);\r\n setStoredTheme(name);\r\n applyThemeVariables(theme.variables);\r\n\r\n if (typeof document !== 'undefined') {\r\n document.documentElement.setAttribute('data-lyt-theme', name);\r\n document.documentElement.classList.toggle('lyt-theme-dark', !!theme.isDark);\r\n }\r\n }\r\n\r\n function toggleTheme() {\r\n const available = availableThemesSignal();\r\n const currentIndex = available.indexOf(currentThemeSignal());\r\n const nextIndex = (currentIndex + 1) % available.length;\r\n const nextTheme = available[nextIndex];\r\n if (nextTheme) {\r\n setTheme(nextTheme);\r\n }\r\n }\r\n\r\n function registerTheme(theme: Theme) {\r\n themeMap.set(theme.name, theme);\r\n availableThemesSignal.set([...availableThemesSignal(), theme.name]);\r\n }\r\n\r\n function getThemeVariables(name?: string): Record<string, string> {\r\n const themeName = name || currentThemeSignal();\r\n const theme = themeMap.get(themeName);\r\n return theme ? theme.variables : {};\r\n }\r\n\r\n function init() {\r\n let initialTheme = defaultTheme;\r\n\r\n const storedTheme = getStoredTheme();\r\n if (storedTheme && themeMap.has(storedTheme)) {\r\n initialTheme = storedTheme;\r\n } else if (enableSystemTheme) {\r\n initialTheme = getSystemTheme();\r\n }\r\n\r\n setTheme(initialTheme);\r\n\r\n if (enableSystemTheme && typeof window !== 'undefined' && window.matchMedia) {\r\n systemThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\r\n systemThemeMediaQuery.addEventListener('change', (e) => {\r\n const storedTheme = getStoredTheme();\r\n if (!storedTheme) {\r\n setTheme(e.matches ? 'dark' : 'light');\r\n }\r\n });\r\n }\r\n }\r\n\r\n init();\r\n\r\n return {\r\n get currentTheme() {\r\n return currentThemeSignal();\r\n },\r\n get availableThemes() {\r\n return availableThemesSignal();\r\n },\r\n setTheme,\r\n toggleTheme,\r\n registerTheme,\r\n getThemeVariables,\r\n };\r\n}\r\n\r\nconst pluginTheme = definePlugin({\r\n name: 'theme',\r\n version: '6.0.0',\r\n description: 'LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support',\r\n author: 'LytJS Team',\r\n keywords: ['lytjs', 'theme', 'dark-mode', 'css-variables'],\r\n schema: {\r\n type: 'object',\r\n object: {\r\n properties: {\r\n defaultTheme: { type: 'string', default: 'light' },\r\n themes: { type: 'array', default: defaultThemes },\r\n enableSystemTheme: { type: 'boolean', default: true },\r\n storageKey: { type: 'string', default: 'lyt-theme' },\r\n },\r\n },\r\n },\r\n install(app, options) {\r\n const themeManager = createThemeManager(options as ThemeOptions);\r\n\r\n app.config.globalProperties.$theme = themeManager;\r\n\r\n app.provide('lyt-theme', themeManager);\r\n },\r\n});\r\n\r\nexport default pluginTheme;\r\nexport type { Theme, ThemeOptions, ThemeInstance };\r\nexport { createThemeManager };\r\n"]}
@@ -0,0 +1,44 @@
1
+ import * as _lytjs_core from '@lytjs/core';
2
+
3
+ /**
4
+ * @lytjs/plugin-theme - 类型定义
5
+ */
6
+ interface Theme {
7
+ /** 主题名称 */
8
+ name: string;
9
+ /** 主题变量 */
10
+ variables: Record<string, string>;
11
+ /** 是否为深色主题 */
12
+ isDark?: boolean;
13
+ }
14
+ interface ThemeOptions {
15
+ /** 默认主题 */
16
+ defaultTheme?: string;
17
+ /** 主题列表 */
18
+ themes?: Theme[];
19
+ /** 是否启用系统主题检测 */
20
+ enableSystemTheme?: boolean;
21
+ /** 本地存储 key */
22
+ storageKey?: string;
23
+ /** CSS 变量前缀 */
24
+ variablePrefix?: string;
25
+ }
26
+ interface ThemeInstance {
27
+ /** 当前主题 */
28
+ currentTheme: string;
29
+ /** 可用主题列表 */
30
+ availableThemes: string[];
31
+ /** 设置主题 */
32
+ setTheme: (name: string) => void;
33
+ /** 切换到下一个主题 */
34
+ toggleTheme: () => void;
35
+ /** 注册新主题 */
36
+ registerTheme: (theme: Theme) => void;
37
+ /** 获取主题变量 */
38
+ getThemeVariables: (name?: string) => Record<string, string>;
39
+ }
40
+
41
+ declare function createThemeManager(options?: ThemeOptions): ThemeInstance;
42
+ declare const pluginTheme: _lytjs_core.PluginDefinition<unknown>;
43
+
44
+ export { type Theme, type ThemeInstance, type ThemeOptions, createThemeManager, pluginTheme as default };
@@ -0,0 +1,44 @@
1
+ import * as _lytjs_core from '@lytjs/core';
2
+
3
+ /**
4
+ * @lytjs/plugin-theme - 类型定义
5
+ */
6
+ interface Theme {
7
+ /** 主题名称 */
8
+ name: string;
9
+ /** 主题变量 */
10
+ variables: Record<string, string>;
11
+ /** 是否为深色主题 */
12
+ isDark?: boolean;
13
+ }
14
+ interface ThemeOptions {
15
+ /** 默认主题 */
16
+ defaultTheme?: string;
17
+ /** 主题列表 */
18
+ themes?: Theme[];
19
+ /** 是否启用系统主题检测 */
20
+ enableSystemTheme?: boolean;
21
+ /** 本地存储 key */
22
+ storageKey?: string;
23
+ /** CSS 变量前缀 */
24
+ variablePrefix?: string;
25
+ }
26
+ interface ThemeInstance {
27
+ /** 当前主题 */
28
+ currentTheme: string;
29
+ /** 可用主题列表 */
30
+ availableThemes: string[];
31
+ /** 设置主题 */
32
+ setTheme: (name: string) => void;
33
+ /** 切换到下一个主题 */
34
+ toggleTheme: () => void;
35
+ /** 注册新主题 */
36
+ registerTheme: (theme: Theme) => void;
37
+ /** 获取主题变量 */
38
+ getThemeVariables: (name?: string) => Record<string, string>;
39
+ }
40
+
41
+ declare function createThemeManager(options?: ThemeOptions): ThemeInstance;
42
+ declare const pluginTheme: _lytjs_core.PluginDefinition<unknown>;
43
+
44
+ export { type Theme, type ThemeInstance, type ThemeOptions, createThemeManager, pluginTheme as default };
package/dist/index.mjs CHANGED
@@ -1 +1,174 @@
1
- var _={light:{"--bg":"#ffffff","--bg-secondary":"#f5f5f5","--text":"#333333","--text-secondary":"#666666","--text-muted":"#999999","--primary":"#42b883","--primary-hover":"#3aa876","--secondary":"#35495e","--success":"#10b981","--warning":"#f59e0b","--error":"#ef4444","--info":"#3b82f6","--border":"#e5e7eb","--shadow":"rgba(0, 0, 0, 0.1)"},dark:{"--bg":"#1a1a1a","--bg-secondary":"#2d2d2d","--text":"#e5e5e5","--text-secondary":"#a3a3a3","--text-muted":"#737373","--primary":"#42b883","--primary-hover":"#3aa876","--secondary":"#94a3b8","--success":"#10b981","--warning":"#f59e0b","--error":"#ef4444","--info":"#3b82f6","--border":"#404040","--shadow":"rgba(0, 0, 0, 0.3)"}};function u(){if(typeof document=="undefined")return null;let a=document.documentElement;return!a||!a.style||typeof a.style.setProperty!="function"?null:a}function F(a){return(...c)=>{}}function H(a={}){let{default:c="light",storageKey:b="lyt_theme",themes:p={},onChange:v,autoDetect:P=!0,useDataAttribute:w=!0,cssPrefix:g="--lyt-",debug:$=!1}=a,i=F($),o={..._,...p},s=c,l={};function k(){try{let e=localStorage.getItem(b);if(e&&o[e])return e}catch(e){}return null}function C(e){try{localStorage.setItem(b,e)}catch(t){}}function T(){var e;return typeof window=="undefined"?"light":(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function x(e){if(typeof window=="undefined"||!window.matchMedia)return()=>{};let t=window.matchMedia("(prefers-color-scheme: dark)");function n(r){e(r.matches?"dark":"light")}return t.addEventListener("change",n),()=>t.removeEventListener("change",n)}function f(e){let t=u();if(!t)return;let n=o[e];if(!n){i(`theme '${e}' not found`);return}i(`applying theme '${e}'`,n),Object.entries(n).forEach(([r,m])=>{let y=r.startsWith("--")?r:`${g}${r}`;t.style.setProperty(y,m)}),Object.entries(l).forEach(([r,m])=>{let y=r.startsWith("--")?r:`${g}${r}`;t.style.setProperty(y,m)}),w&&t.setAttribute("data-theme",e),t.style.setProperty("color-scheme",e==="dark"?"dark":"light")}function d(e){if(!o[e]){i(`theme '${e}' not found, available:`,Object.keys(o));return}let t=s;t!==e&&(s=e,f(e),C(e),v&&v(e,t),i(`theme changed from '${t}' to '${e}'`))}function E(){let e=Object.keys(o),n=(e.indexOf(s)+1)%e.length;d(e[n])}function O(){d(c)}function V(){return Object.keys(o)}function S(e,t){o[e]=t,i(`added/updated theme '${e}'`,t),s===e&&f(e)}function j(e){if(e===c){i("cannot remove default theme");return}delete o[e],s===e&&d(c),i(`removed theme '${e}'`)}function I(){return o[s]||null}function L(e){return o[e]||null}function M(e,t){let n=e.startsWith("--")?e:`${g}${e}`;l[n]=t;let r=u();r&&r.style.setProperty(n,t),i(`set variable '${n}' = '${t}'`)}function A(e){let t=e.startsWith("--")?e:`${g}${e}`;delete l[t];let n=u();n&&n.style.removeProperty(t),i(`cleared variable '${t}'`)}function D(){let e=u();Object.keys(l).forEach(t=>{e&&e.style.removeProperty(t)}),Object.keys(l).forEach(t=>delete l[t]),f(s),i("cleared all dynamic variables")}function W(){let e=k();if(!e&&P){let t=T();e=o[t]?t:c}e||(e=c),i(`initializing with theme '${e}'`),s=e,f(e)}W();let h={install(e,t){e.config=e.config||{},e.config.globalProperties=e.config.globalProperties||{},e.config.globalProperties.$theme=h,typeof e.provide=="function"&&e.provide("theme",h)},get current(){return s},set:d,toggle:E,reset:O,list:V,addTheme:S,removeTheme:j,getConfig:I,getConfigFor:L,setVariable:M,clearVariable:A,clearVariables:D,getSystemPreference:T,watchSystemPreference:x};return h}export{_ as BUILT_IN_THEMES,H as createTheme};
1
+ import { definePlugin } from '@lytjs/core';
2
+ import { signal } from '@lytjs/reactivity';
3
+
4
+ // src/index.ts
5
+ var defaultThemes = [
6
+ {
7
+ name: "light",
8
+ isDark: false,
9
+ variables: {
10
+ "--lyt-bg-primary": "#ffffff",
11
+ "--lyt-bg-secondary": "#f5f5f5",
12
+ "--lyt-text-primary": "#333333",
13
+ "--lyt-text-secondary": "#666666",
14
+ "--lyt-primary": "#1890ff",
15
+ "--lyt-success": "#52c41a",
16
+ "--lyt-warning": "#faad14",
17
+ "--lyt-error": "#ff4d4f",
18
+ "--lyt-border": "#d9d9d9"
19
+ }
20
+ },
21
+ {
22
+ name: "dark",
23
+ isDark: true,
24
+ variables: {
25
+ "--lyt-bg-primary": "#141414",
26
+ "--lyt-bg-secondary": "#1f1f1f",
27
+ "--lyt-text-primary": "#ffffff",
28
+ "--lyt-text-secondary": "#a6a6a6",
29
+ "--lyt-primary": "#177ddc",
30
+ "--lyt-success": "#49aa19",
31
+ "--lyt-warning": "#d89614",
32
+ "--lyt-error": "#d32029",
33
+ "--lyt-border": "#434343"
34
+ }
35
+ }
36
+ ];
37
+ function getSystemTheme() {
38
+ if (typeof window !== "undefined" && window.matchMedia) {
39
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
40
+ }
41
+ return "light";
42
+ }
43
+ function createThemeManager(options = {}) {
44
+ const {
45
+ defaultTheme = "light",
46
+ themes = defaultThemes,
47
+ enableSystemTheme = true,
48
+ storageKey = "lyt-theme"
49
+ } = options;
50
+ const themeMap = new Map(themes.map((t) => [t.name, t]));
51
+ const currentThemeSignal = signal(defaultTheme);
52
+ const availableThemesSignal = signal(themes.map((t) => t.name));
53
+ let styleElement = null;
54
+ let systemThemeMediaQuery = null;
55
+ function applyThemeVariables(variables) {
56
+ if (typeof document === "undefined") return;
57
+ if (!styleElement) {
58
+ styleElement = document.createElement("style");
59
+ styleElement.setAttribute("data-lyt-theme", "true");
60
+ document.head.appendChild(styleElement);
61
+ }
62
+ const cssVars = Object.entries(variables).map(([key, value]) => `${key}: ${value};`).join("\n");
63
+ styleElement.textContent = `:root {
64
+ ${cssVars}
65
+ }`;
66
+ }
67
+ function getStoredTheme() {
68
+ if (typeof localStorage === "undefined") return null;
69
+ try {
70
+ return localStorage.getItem(storageKey);
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ function setStoredTheme(name) {
76
+ if (typeof localStorage === "undefined") return;
77
+ try {
78
+ localStorage.setItem(storageKey, name);
79
+ } catch {
80
+ }
81
+ }
82
+ function setTheme(name) {
83
+ if (!themeMap.has(name)) {
84
+ console.warn(`[Theme] Theme "${name}" not found, falling back to default`);
85
+ name = defaultTheme;
86
+ }
87
+ const theme = themeMap.get(name);
88
+ currentThemeSignal.set(name);
89
+ setStoredTheme(name);
90
+ applyThemeVariables(theme.variables);
91
+ if (typeof document !== "undefined") {
92
+ document.documentElement.setAttribute("data-lyt-theme", name);
93
+ document.documentElement.classList.toggle("lyt-theme-dark", !!theme.isDark);
94
+ }
95
+ }
96
+ function toggleTheme() {
97
+ const available = availableThemesSignal();
98
+ const currentIndex = available.indexOf(currentThemeSignal());
99
+ const nextIndex = (currentIndex + 1) % available.length;
100
+ const nextTheme = available[nextIndex];
101
+ if (nextTheme) {
102
+ setTheme(nextTheme);
103
+ }
104
+ }
105
+ function registerTheme(theme) {
106
+ themeMap.set(theme.name, theme);
107
+ availableThemesSignal.set([...availableThemesSignal(), theme.name]);
108
+ }
109
+ function getThemeVariables(name) {
110
+ const themeName = name || currentThemeSignal();
111
+ const theme = themeMap.get(themeName);
112
+ return theme ? theme.variables : {};
113
+ }
114
+ function init() {
115
+ let initialTheme = defaultTheme;
116
+ const storedTheme = getStoredTheme();
117
+ if (storedTheme && themeMap.has(storedTheme)) {
118
+ initialTheme = storedTheme;
119
+ } else if (enableSystemTheme) {
120
+ initialTheme = getSystemTheme();
121
+ }
122
+ setTheme(initialTheme);
123
+ if (enableSystemTheme && typeof window !== "undefined" && window.matchMedia) {
124
+ systemThemeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
125
+ systemThemeMediaQuery.addEventListener("change", (e) => {
126
+ const storedTheme2 = getStoredTheme();
127
+ if (!storedTheme2) {
128
+ setTheme(e.matches ? "dark" : "light");
129
+ }
130
+ });
131
+ }
132
+ }
133
+ init();
134
+ return {
135
+ get currentTheme() {
136
+ return currentThemeSignal();
137
+ },
138
+ get availableThemes() {
139
+ return availableThemesSignal();
140
+ },
141
+ setTheme,
142
+ toggleTheme,
143
+ registerTheme,
144
+ getThemeVariables
145
+ };
146
+ }
147
+ var pluginTheme = definePlugin({
148
+ name: "theme",
149
+ version: "6.0.0",
150
+ description: "LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support",
151
+ author: "LytJS Team",
152
+ keywords: ["lytjs", "theme", "dark-mode", "css-variables"],
153
+ schema: {
154
+ type: "object",
155
+ object: {
156
+ properties: {
157
+ defaultTheme: { type: "string", default: "light" },
158
+ themes: { type: "array", default: defaultThemes },
159
+ enableSystemTheme: { type: "boolean", default: true },
160
+ storageKey: { type: "string", default: "lyt-theme" }
161
+ }
162
+ }
163
+ },
164
+ install(app, options) {
165
+ const themeManager = createThemeManager(options);
166
+ app.config.globalProperties.$theme = themeManager;
167
+ app.provide("lyt-theme", themeManager);
168
+ }
169
+ });
170
+ var index_default = pluginTheme;
171
+
172
+ export { createThemeManager, index_default as default };
173
+ //# sourceMappingURL=index.mjs.map
174
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["storedTheme"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * @lytjs/plugin-theme\r\n *\r\n * LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { definePlugin } from '@lytjs/core';\r\nimport { signal } from '@lytjs/reactivity';\r\nimport type { Theme, ThemeOptions, ThemeInstance } from './types';\r\n\r\nconst defaultThemes: Theme[] = [\r\n {\r\n name: 'light',\r\n isDark: false,\r\n variables: {\r\n '--lyt-bg-primary': '#ffffff',\r\n '--lyt-bg-secondary': '#f5f5f5',\r\n '--lyt-text-primary': '#333333',\r\n '--lyt-text-secondary': '#666666',\r\n '--lyt-primary': '#1890ff',\r\n '--lyt-success': '#52c41a',\r\n '--lyt-warning': '#faad14',\r\n '--lyt-error': '#ff4d4f',\r\n '--lyt-border': '#d9d9d9',\r\n },\r\n },\r\n {\r\n name: 'dark',\r\n isDark: true,\r\n variables: {\r\n '--lyt-bg-primary': '#141414',\r\n '--lyt-bg-secondary': '#1f1f1f',\r\n '--lyt-text-primary': '#ffffff',\r\n '--lyt-text-secondary': '#a6a6a6',\r\n '--lyt-primary': '#177ddc',\r\n '--lyt-success': '#49aa19',\r\n '--lyt-warning': '#d89614',\r\n '--lyt-error': '#d32029',\r\n '--lyt-border': '#434343',\r\n },\r\n },\r\n];\r\n\r\nfunction getSystemTheme(): string {\r\n if (typeof window !== 'undefined' && window.matchMedia) {\r\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\r\n }\r\n return 'light';\r\n}\r\n\r\nfunction createThemeManager(options: ThemeOptions = {}): ThemeInstance {\r\n const {\r\n defaultTheme = 'light',\r\n themes = defaultThemes,\r\n enableSystemTheme = true,\r\n storageKey = 'lyt-theme',\r\n } = options;\r\n\r\n const themeMap = new Map<string, Theme>(themes.map((t) => [t.name, t]));\r\n const currentThemeSignal = signal<string>(defaultTheme);\r\n const availableThemesSignal = signal<string[]>(themes.map((t) => t.name));\r\n\r\n let styleElement: HTMLStyleElement | null = null;\r\n let systemThemeMediaQuery: MediaQueryList | null = null;\r\n\r\n function applyThemeVariables(variables: Record<string, string>) {\r\n if (typeof document === 'undefined') return;\r\n\r\n if (!styleElement) {\r\n styleElement = document.createElement('style');\r\n styleElement.setAttribute('data-lyt-theme', 'true');\r\n document.head.appendChild(styleElement);\r\n }\r\n\r\n const cssVars = Object.entries(variables)\r\n .map(([key, value]) => `${key}: ${value};`)\r\n .join('\\n');\r\n\r\n styleElement.textContent = `:root {\\n${cssVars}\\n}`;\r\n }\r\n\r\n function getStoredTheme(): string | null {\r\n if (typeof localStorage === 'undefined') return null;\r\n try {\r\n return localStorage.getItem(storageKey);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n function setStoredTheme(name: string) {\r\n if (typeof localStorage === 'undefined') return;\r\n try {\r\n localStorage.setItem(storageKey, name);\r\n } catch {\r\n }\r\n }\r\n\r\n function setTheme(name: string) {\r\n if (!themeMap.has(name)) {\r\n console.warn(`[Theme] Theme \"${name}\" not found, falling back to default`);\r\n name = defaultTheme;\r\n }\r\n\r\n const theme = themeMap.get(name)!;\r\n currentThemeSignal.set(name);\r\n setStoredTheme(name);\r\n applyThemeVariables(theme.variables);\r\n\r\n if (typeof document !== 'undefined') {\r\n document.documentElement.setAttribute('data-lyt-theme', name);\r\n document.documentElement.classList.toggle('lyt-theme-dark', !!theme.isDark);\r\n }\r\n }\r\n\r\n function toggleTheme() {\r\n const available = availableThemesSignal();\r\n const currentIndex = available.indexOf(currentThemeSignal());\r\n const nextIndex = (currentIndex + 1) % available.length;\r\n const nextTheme = available[nextIndex];\r\n if (nextTheme) {\r\n setTheme(nextTheme);\r\n }\r\n }\r\n\r\n function registerTheme(theme: Theme) {\r\n themeMap.set(theme.name, theme);\r\n availableThemesSignal.set([...availableThemesSignal(), theme.name]);\r\n }\r\n\r\n function getThemeVariables(name?: string): Record<string, string> {\r\n const themeName = name || currentThemeSignal();\r\n const theme = themeMap.get(themeName);\r\n return theme ? theme.variables : {};\r\n }\r\n\r\n function init() {\r\n let initialTheme = defaultTheme;\r\n\r\n const storedTheme = getStoredTheme();\r\n if (storedTheme && themeMap.has(storedTheme)) {\r\n initialTheme = storedTheme;\r\n } else if (enableSystemTheme) {\r\n initialTheme = getSystemTheme();\r\n }\r\n\r\n setTheme(initialTheme);\r\n\r\n if (enableSystemTheme && typeof window !== 'undefined' && window.matchMedia) {\r\n systemThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\r\n systemThemeMediaQuery.addEventListener('change', (e) => {\r\n const storedTheme = getStoredTheme();\r\n if (!storedTheme) {\r\n setTheme(e.matches ? 'dark' : 'light');\r\n }\r\n });\r\n }\r\n }\r\n\r\n init();\r\n\r\n return {\r\n get currentTheme() {\r\n return currentThemeSignal();\r\n },\r\n get availableThemes() {\r\n return availableThemesSignal();\r\n },\r\n setTheme,\r\n toggleTheme,\r\n registerTheme,\r\n getThemeVariables,\r\n };\r\n}\r\n\r\nconst pluginTheme = definePlugin({\r\n name: 'theme',\r\n version: '6.0.0',\r\n description: 'LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support',\r\n author: 'LytJS Team',\r\n keywords: ['lytjs', 'theme', 'dark-mode', 'css-variables'],\r\n schema: {\r\n type: 'object',\r\n object: {\r\n properties: {\r\n defaultTheme: { type: 'string', default: 'light' },\r\n themes: { type: 'array', default: defaultThemes },\r\n enableSystemTheme: { type: 'boolean', default: true },\r\n storageKey: { type: 'string', default: 'lyt-theme' },\r\n },\r\n },\r\n },\r\n install(app, options) {\r\n const themeManager = createThemeManager(options as ThemeOptions);\r\n\r\n app.config.globalProperties.$theme = themeManager;\r\n\r\n app.provide('lyt-theme', themeManager);\r\n },\r\n});\r\n\r\nexport default pluginTheme;\r\nexport type { Theme, ThemeOptions, ThemeInstance };\r\nexport { createThemeManager };\r\n"]}
package/package.json CHANGED
@@ -1,46 +1,53 @@
1
1
  {
2
2
  "name": "@lytjs/plugin-theme",
3
- "version": "5.0.1",
4
- "description": "Lyt.js 主题切换插件 - 支持亮色/暗色主题和自定义主题",
3
+ "version": "6.0.0",
4
+ "description": "LytJS official theme plugin for CSS variable management, dark/light mode, and custom theme support",
5
+ "type": "module",
5
6
  "main": "./dist/index.cjs",
6
7
  "module": "./dist/index.mjs",
7
- "types": "./dist/types/index.d.ts",
8
+ "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "types": "./dist/types/index.d.ts",
11
+ "types": "./dist/index.d.ts",
11
12
  "import": "./dist/index.mjs",
12
- "require": "./dist/index.cjs",
13
- "default": "./dist/index.mjs"
14
- }
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./package.json": "./package.json"
15
16
  },
16
- "sideEffects": false,
17
17
  "files": [
18
18
  "dist"
19
19
  ],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "test:coverage": "vitest run --coverage",
27
+ "type-check": "tsc --noEmit",
28
+ "lint": "eslint \"src/**/*.ts\"",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@lytjs/core": "^6.0.0",
33
+ "@lytjs/reactivity": "^6.0.0",
34
+ "@lytjs/common-is": "^6.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "tsup": "^8.0.0",
38
+ "typescript": "^5.4.0",
39
+ "vitest": "^3.0.0"
40
+ },
20
41
  "license": "MIT",
21
- "author": "lytjs",
22
42
  "repository": {
23
43
  "type": "git",
24
- "url": "https://gitee.com/lytjs/lytjs"
44
+ "url": "https://gitee.com/lytjs/lytjs.git",
45
+ "directory": "packages/plugins/packages/plugin-theme"
25
46
  },
26
- "homepage": "https://gitee.com/lytjs/lytjs",
27
47
  "keywords": [
28
- "lyt",
29
48
  "lytjs",
30
- "javascript",
31
- "framework",
32
- "frontend",
33
- "vue-like",
34
- "lightweight",
35
- "zero-dependency",
36
49
  "theme",
37
50
  "dark-mode",
38
- "color-scheme"
39
- ],
40
- "engines": {
41
- "node": ">=18.0.0"
42
- },
43
- "publishConfig": {
44
- "access": "public"
45
- }
51
+ "css-variables"
52
+ ]
46
53
  }
package/README.md DELETED
@@ -1,163 +0,0 @@
1
- # @lytjs/plugin-theme
2
-
3
- > Lyt.js 主题切换插件 - 支持亮色/暗色主题和自定义主题
4
-
5
- **版本:** 4.2.0
6
-
7
- ## 安装
8
-
9
- ```bash
10
- npm install @lytjs/plugin-theme
11
- ```
12
-
13
- ## 使用
14
-
15
- ### 注册插件
16
-
17
- ```typescript
18
- import { createApp } from '@lytjs/core'
19
- import { createTheme } from '@lytjs/plugin-theme'
20
-
21
- const theme = createTheme({
22
- default: 'light',
23
- storageKey: 'lyt_theme',
24
- themes: {
25
- light: { '--bg': '#fff', '--text': '#333' },
26
- dark: { '--bg': '#333', '--text': '#fff' },
27
- },
28
- })
29
-
30
- const app = createApp({})
31
- app.use(theme)
32
- ```
33
-
34
- ### 切换主题
35
-
36
- ```typescript
37
- // 切换到指定主题
38
- theme.set('dark')
39
-
40
- // 在预设主题间循环切换
41
- theme.toggle()
42
-
43
- // 重置为默认主题
44
- theme.reset()
45
-
46
- // 获取当前主题名称
47
- theme.current // 'dark'
48
- ```
49
-
50
- ### 使用内置主题
51
-
52
- 插件内置了 `light` 和 `dark` 两套主题,开箱即用:
53
-
54
- ```typescript
55
- const theme = createTheme({
56
- default: 'light',
57
- autoDetect: true, // 自动检测系统主题偏好
58
- })
59
- ```
60
-
61
- 内置主题包含以下 CSS 变量:
62
-
63
- | 变量 | 说明 |
64
- |------|------|
65
- | `--bg` | 背景色 |
66
- | `--bg-secondary` | 次要背景色 |
67
- | `--text` | 文字颜色 |
68
- | `--text-secondary` | 次要文字颜色 |
69
- | `--text-muted` | 弱化文字颜色 |
70
- | `--primary` | 主色调 |
71
- | `--primary-hover` | 主色调悬停 |
72
- | `--secondary` | 次要色调 |
73
- | `--success` | 成功色 |
74
- | `--warning` | 警告色 |
75
- | `--error` | 错误色 |
76
- | `--info` | 信息色 |
77
- | `--border` | 边框色 |
78
- | `--shadow` | 阴影色 |
79
-
80
- ### 动态添加主题
81
-
82
- ```typescript
83
- // 添加新主题
84
- theme.addTheme('blue', {
85
- '--bg': '#f0f8ff',
86
- '--text': '#1a365d',
87
- '--primary': '#3182ce',
88
- })
89
-
90
- // 移除主题
91
- theme.removeTheme('blue')
92
- ```
93
-
94
- ### 动态 CSS 变量
95
-
96
- ```typescript
97
- // 设置动态 CSS 变量(不保存到持久化)
98
- theme.setVariable('--custom-color', '#ff6600')
99
-
100
- // 清除动态变量
101
- theme.clearVariable('--custom-color')
102
-
103
- // 清除所有动态变量
104
- theme.clearVariables()
105
- ```
106
-
107
- ### 系统主题检测
108
-
109
- ```typescript
110
- // 获取系统偏好主题
111
- theme.getSystemPreference() // 'light' | 'dark'
112
-
113
- // 监听系统主题变化
114
- const unsubscribe = theme.watchSystemPreference((pref) => {
115
- console.log('系统主题已切换为:', pref)
116
- })
117
-
118
- // 取消监听
119
- unsubscribe()
120
- ```
121
-
122
- ## API
123
-
124
- ### Options
125
-
126
- | 选项 | 类型 | 默认值 | 描述 |
127
- |------|------|--------|------|
128
- | `default` | `string` | `'light'` | 默认主题 |
129
- | `storageKey` | `string` | `'lyt_theme'` | localStorage 中存储主题的 key |
130
- | `themes` | `Record<string, ThemeConfig>` | 内置 light/dark | 主题配置对象 |
131
- | `onChange` | `(newTheme: string, oldTheme: string) => void` | - | 主题切换时的回调 |
132
- | `autoDetect` | `boolean` | `true` | 是否自动检测系统主题偏好 |
133
- | `useDataAttribute` | `boolean` | `true` | 是否添加 `data-theme` 属性到 html 标签 |
134
- | `cssPrefix` | `string` | `'--lyt-'` | 自定义 CSS 变量前缀 |
135
- | `debug` | `boolean` | `false` | 是否开启调试模式 |
136
-
137
- ### 属性
138
-
139
- | 属性 | 类型 | 描述 |
140
- |------|------|------|
141
- | `current` | `string` | 当前主题名称(只读) |
142
-
143
- ### 方法
144
-
145
- | 方法 | 签名 | 描述 |
146
- |------|------|------|
147
- | `set` | `(themeName: string) => void` | 切换到指定主题 |
148
- | `toggle` | `() => void` | 在预设主题间循环切换 |
149
- | `reset` | `() => void` | 重置为默认主题 |
150
- | `list` | `() => string[]` | 获取所有可用主题列表 |
151
- | `addTheme` | `(name: string, config: ThemeConfig) => void` | 动态添加/更新主题 |
152
- | `removeTheme` | `(name: string) => void` | 移除主题(不能移除默认主题) |
153
- | `getConfig` | `() => ThemeConfig \| null` | 获取当前主题的 CSS 变量配置 |
154
- | `getConfigFor` | `(themeName: string) => ThemeConfig \| null` | 获取指定主题的 CSS 变量配置 |
155
- | `setVariable` | `(key: string, value: string) => void` | 动态设置 CSS 变量(不持久化) |
156
- | `clearVariable` | `(key: string) => void` | 清除动态设置的 CSS 变量 |
157
- | `clearVariables` | `() => void` | 清除所有动态变量 |
158
- | `getSystemPreference` | `() => 'light' \| 'dark'` | 获取系统偏好主题 |
159
- | `watchSystemPreference` | `(callback: (theme: 'light' \| 'dark') => void) => () => void` | 监听系统主题变化 |
160
-
161
- ## License
162
-
163
- MIT
@@ -1,76 +0,0 @@
1
- /** 主题配置 */
2
- interface ThemeConfig {
3
- /** CSS 变量键值对 */
4
- [key: string]: string;
5
- }
6
- /** 主题插件配置选项 */
7
- interface ThemeOptions {
8
- /** 默认主题,默认 'light' */
9
- default?: string;
10
- /** localStorage 中存储主题的 key,默认 'lyt_theme' */
11
- storageKey?: string;
12
- /** 主题配置对象 */
13
- themes?: {
14
- [themeName: string]: ThemeConfig;
15
- };
16
- /** 主题切换时的回调 */
17
- onChange?: (newTheme: string, oldTheme: string) => void;
18
- /** 是否自动检测系统主题偏好 */
19
- autoDetect?: boolean;
20
- /** 是否添加 data-theme 属性到 html 标签 */
21
- useDataAttribute?: boolean;
22
- /** 自定义 CSS 变量前缀,默认 '--lyt-' */
23
- cssPrefix?: string;
24
- /** 是否开启调试模式 */
25
- debug?: boolean;
26
- }
27
- /** 主题插件应用接口(最小化) */
28
- interface ThemePluginApp {
29
- use(plugin: unknown, options?: unknown): void;
30
- [key: string]: unknown;
31
- }
32
- /** 主题插件实例 */
33
- interface ThemePlugin {
34
- /** 安装到 Lyt 应用 */
35
- install: (app: ThemePluginApp, options?: ThemeOptions) => void;
36
- /** 当前主题名称 */
37
- readonly current: string;
38
- /** 切换到指定主题 */
39
- set(themeName: string): void;
40
- /** 切换主题(在预设主题间循环) */
41
- toggle(): void;
42
- /** 重置为默认主题 */
43
- reset(): void;
44
- /** 获取所有可用主题列表 */
45
- list(): string[];
46
- /** 动态添加/更新主题 */
47
- addTheme(name: string, config: ThemeConfig): void;
48
- /** 移除主题 */
49
- removeTheme(name: string): void;
50
- /** 获取当前主题的 CSS 变量配置 */
51
- getConfig(): ThemeConfig | null;
52
- /** 获取指定主题的 CSS 变量配置 */
53
- getConfigFor(themeName: string): ThemeConfig | null;
54
- /** 动态设置 CSS 变量(不保存到持久化) */
55
- setVariable(key: string, value: string): void;
56
- /** 清除动态设置的 CSS 变量 */
57
- clearVariable(key: string): void;
58
- /** 清除所有动态变量 */
59
- clearVariables(): void;
60
- /** 获取系统偏好主题('light' 或 'dark') */
61
- getSystemPreference(): 'light' | 'dark';
62
- /** 监听系统主题变化 */
63
- watchSystemPreference(callback: (theme: 'light' | 'dark') => void): () => void;
64
- }
65
- declare const BUILT_IN_THEMES: {
66
- [key: string]: ThemeConfig;
67
- };
68
- /**
69
- * 创建主题切换插件实例
70
- * @param options 主题配置
71
- * @returns ThemePlugin 插件实例
72
- */
73
- declare function createTheme(options?: ThemeOptions): ThemePlugin;
74
- export { createTheme, BUILT_IN_THEMES };
75
- export type { ThemeOptions, ThemePlugin, ThemeConfig };
76
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAmBA,WAAW;AACX,UAAU,WAAW;IACnB,gBAAgB;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB;AAED,eAAe;AACf,UAAU,YAAY;IACpB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa;IACb,MAAM,CAAC,EAAE;QACP,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAA;KACjC,CAAA;IACD,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACvD,mBAAmB;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,oBAAoB;AACpB,UAAU,cAAc;IACtB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,aAAa;AACb,UAAU,WAAW;IACnB,iBAAiB;IACjB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAA;IAC9D,aAAa;IACb,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,cAAc;IACd,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,qBAAqB;IACrB,MAAM,IAAI,IAAI,CAAA;IACd,cAAc;IACd,KAAK,IAAI,IAAI,CAAA;IACb,iBAAiB;IACjB,IAAI,IAAI,MAAM,EAAE,CAAA;IAChB,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IACjD,WAAW;IACX,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,uBAAuB;IACvB,SAAS,IAAI,WAAW,GAAG,IAAI,CAAA;IAC/B,uBAAuB;IACvB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;IACnD,2BAA2B;IAC3B,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,qBAAqB;IACrB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,eAAe;IACf,cAAc,IAAI,IAAI,CAAA;IACtB,iCAAiC;IACjC,mBAAmB,IAAI,OAAO,GAAG,MAAM,CAAA;IACvC,eAAe;IACf,qBAAqB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;CAC/E;AAID,QAAA,MAAM,eAAe,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAiClD,CAAA;AA4BD;;;;GAIG;AACH,iBAAS,WAAW,CAAC,OAAO,GAAE,YAAiB,GAAG,WAAW,CA2S5D;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA;AACvC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAA"}