@yh-ui/theme 1.0.51 → 1.0.53

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/theme.cjs CHANGED
@@ -420,8 +420,9 @@ const colorBlindPalettes = exports.colorBlindPalettes = {
420
420
  const THEME_TRANSITION_CLASS = "yh-theme-transitioning";
421
421
  const DEFAULT_TRANSITION_DURATION = 300;
422
422
  const DEFAULT_TRANSITION_TIMING = "cubic-bezier(0.4, 0, 0.2, 1)";
423
- function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing = DEFAULT_TRANSITION_TIMING) {
423
+ function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing = DEFAULT_TRANSITION_TIMING, el = null) {
424
424
  if (typeof document === "undefined") return;
425
+ const target = el || document.documentElement;
425
426
  const style = document.createElement("style");
426
427
  style.id = "yh-theme-transition";
427
428
  style.textContent = `
@@ -439,9 +440,9 @@ function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing =
439
440
  }
440
441
  `;
441
442
  document.head.appendChild(style);
442
- document.documentElement.classList.add(THEME_TRANSITION_CLASS);
443
+ target.classList.add(THEME_TRANSITION_CLASS);
443
444
  setTimeout(() => {
444
- document.documentElement.classList.remove(THEME_TRANSITION_CLASS);
445
+ target.classList.remove(THEME_TRANSITION_CLASS);
445
446
  style.remove();
446
447
  }, duration);
447
448
  }
@@ -556,6 +557,7 @@ class ThemeManager {
556
557
  };
557
558
  themeHistory = [];
558
559
  maxHistoryLength = 10;
560
+ responsiveVars = /* @__PURE__ */new Map();
559
561
  // 响应式状态
560
562
  state = (0, _vue.reactive)({
561
563
  theme: "default",
@@ -576,7 +578,8 @@ class ThemeManager {
576
578
  this.persistKey = options?.persistKey || "yh-ui-theme";
577
579
  this.restoreFromStorage();
578
580
  }
579
- this.apply({
581
+ this.targetEl = getTargetElement(options?.scope);
582
+ this.applyFullConfig({
580
583
  preset: "default",
581
584
  ...options
582
585
  });
@@ -667,11 +670,12 @@ class ThemeManager {
667
670
  setDarkMode(dark) {
668
671
  this.isDark = dark;
669
672
  this.state.dark = dark;
670
- if (typeof document !== "undefined") {
673
+ const el = this.targetEl || (typeof document !== "undefined" ? document.documentElement : null);
674
+ if (el) {
671
675
  if (dark) {
672
- document.documentElement.classList.add("dark");
676
+ el.classList.add("dark");
673
677
  } else {
674
- document.documentElement.classList.remove("dark");
678
+ el.classList.remove("dark");
675
679
  }
676
680
  }
677
681
  const currentColors = {
@@ -918,7 +922,7 @@ class ThemeManager {
918
922
  try {
919
923
  const snapshot = JSON.parse(json);
920
924
  if (this.transitionEnabled) {
921
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
925
+ enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing, this.targetEl);
922
926
  }
923
927
  this.setPreset(snapshot.preset);
924
928
  if (snapshot.colors && Object.keys(snapshot.colors).length > 0) {
@@ -965,8 +969,8 @@ class ThemeManager {
965
969
  this.state.colorBlindMode = "none";
966
970
  this.state.algorithm = "default";
967
971
  this.state.componentThemeVersion += 1;
968
- document.documentElement.classList.remove("dark");
969
972
  const el = this.targetEl || document.documentElement;
973
+ el.classList.remove("dark");
970
974
  const colorTypes = ["primary", "success", "warning", "danger", "info"];
971
975
  const suffixes = ["", "light-1", "light-2", "light-3", "light-4", "light-5", "light-6", "light-7", "light-8", "light-9", "dark-2", "hover", "active", "disabled", "focus", "rgb"];
972
976
  colorTypes.forEach(type => {
@@ -984,7 +988,7 @@ class ThemeManager {
984
988
  /** 设置密度 */
985
989
  setDensity(density) {
986
990
  if (this.transitionEnabled) {
987
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
991
+ enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing, this.targetEl);
988
992
  }
989
993
  this.currentDensity = density;
990
994
  this.state.density = density;
@@ -1004,7 +1008,7 @@ class ThemeManager {
1004
1008
  /** 设置色盲友好模式 */
1005
1009
  setColorBlindMode(mode) {
1006
1010
  if (this.transitionEnabled) {
1007
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
1011
+ enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing, this.targetEl);
1008
1012
  }
1009
1013
  this.colorBlindMode = mode;
1010
1014
  this.state.colorBlindMode = mode;
@@ -1109,7 +1113,7 @@ class ThemeManager {
1109
1113
  duration: DEFAULT_TRANSITION_DURATION,
1110
1114
  timing: DEFAULT_TRANSITION_TIMING
1111
1115
  };
1112
- enableThemeTransition(transitionConfig.duration, transitionConfig.timing);
1116
+ enableThemeTransition(transitionConfig.duration, transitionConfig.timing, this.targetEl);
1113
1117
  }
1114
1118
  this.pushHistory();
1115
1119
  const snapshot = this.createTheme(config);
@@ -1194,6 +1198,7 @@ class ThemeManager {
1194
1198
  /** 设置响应式变量 (根据断点自动切换) */
1195
1199
  setResponsiveVar(name, values) {
1196
1200
  if (typeof document === "undefined") return;
1201
+ this.responsiveVars.set(name, values);
1197
1202
  let style = document.getElementById("yh-responsive-vars");
1198
1203
  if (!style) {
1199
1204
  style = document.createElement("style");
@@ -1201,23 +1206,25 @@ class ThemeManager {
1201
1206
  document.head.appendChild(style);
1202
1207
  }
1203
1208
  let css = "";
1204
- const orderedBreakpoints = ["xs", "sm", "md", "lg", "xl", "xxl"];
1205
- orderedBreakpoints.forEach(bp => {
1206
- if (values[bp]) {
1207
- if (bp === "xs") {
1208
- css += `
1209
- :root { ${name}: ${values[bp]}; }
1210
- `;
1211
- } else {
1212
- css += `
1213
- @media (min-width: ${breakpoints[bp]}px) {
1214
- :root { ${name}: ${values[bp]}; }
1215
- }
1216
- `;
1209
+ this.responsiveVars.forEach((vals, varName) => {
1210
+ const orderedBreakpoints = ["xs", "sm", "md", "lg", "xl", "xxl"];
1211
+ orderedBreakpoints.forEach(bp => {
1212
+ if (vals[bp]) {
1213
+ if (bp === "xs") {
1214
+ css += `
1215
+ :root { ${varName}: ${vals[bp]}; }
1216
+ `;
1217
+ } else {
1218
+ css += `
1219
+ @media (min-width: ${breakpoints[bp]}px) {
1220
+ :root { ${varName}: ${vals[bp]}; }
1221
+ }
1222
+ `;
1223
+ }
1217
1224
  }
1218
- }
1225
+ });
1219
1226
  });
1220
- style.textContent += css;
1227
+ style.textContent = css;
1221
1228
  }
1222
1229
  /** 销毁 */
1223
1230
  destroy() {
@@ -1229,6 +1236,7 @@ class ThemeManager {
1229
1236
  if (style) {
1230
1237
  style.remove();
1231
1238
  }
1239
+ this.responsiveVars.clear();
1232
1240
  }
1233
1241
  }
1234
1242
  exports.ThemeManager = ThemeManager;
package/dist/theme.d.ts CHANGED
@@ -148,6 +148,7 @@ export declare class ThemeManager {
148
148
  private transitionConfig;
149
149
  private themeHistory;
150
150
  private maxHistoryLength;
151
+ private responsiveVars;
151
152
  readonly state: {
152
153
  theme: PresetTheme;
153
154
  dark: boolean;
@@ -164,9 +165,9 @@ export declare class ThemeManager {
164
165
  algorithm: ColorAlgorithm;
165
166
  componentThemeVersion: number;
166
167
  };
167
- constructor(options?: ThemeOptions);
168
+ constructor(options?: FullThemeConfig);
168
169
  /** 初始化主题 */
169
- initTheme(options?: ThemeOptions): void;
170
+ initTheme(options?: FullThemeConfig): void;
170
171
  /** 应用主题 */
171
172
  apply(options: ThemeOptions): void;
172
173
  /** 设置预设主题 */
@@ -278,7 +279,7 @@ export declare function useTheme(): ThemeManager;
278
279
  export declare function setThemeColor(color: string): void;
279
280
  export declare function toggleDarkMode(): boolean;
280
281
  export declare function setThemePreset(preset: PresetTheme): void;
281
- export declare function initTheme(options?: ThemeOptions): ThemeManager;
282
+ export declare function initTheme(options?: FullThemeConfig): ThemeManager;
282
283
  /** Vue Composition API Hook - 获取主题变量 */
283
284
  export declare function useThemeVars(): {
284
285
  getCssVar: (name: string) => string;
@@ -310,7 +311,7 @@ export declare function checkContrast(foreground: string, background: string, le
310
311
  export declare function getTextColorForBackground(background: string): string;
311
312
  export declare const THEME_INJECTION_KEY: InjectionKey<ThemeManager>;
312
313
  export declare const ThemePlugin: {
313
- install(app: App, options?: ThemeOptions): void;
314
+ install(app: App, options?: FullThemeConfig): void;
314
315
  };
315
316
  export default ThemePlugin;
316
317
  export { hexToRgb, rgbToHex, rgbToHsl, hslToRgb, mixColor, adjustSaturation, adjustLightness, getContrastRatio, ensureContrast, getRelativeLuminance, getComplementaryColor, getAnalogousColors, getTriadicColors, generatePaletteFromPrimary };
package/dist/theme.mjs CHANGED
@@ -391,8 +391,9 @@ const colorBlindPalettes = {
391
391
  const THEME_TRANSITION_CLASS = "yh-theme-transitioning";
392
392
  const DEFAULT_TRANSITION_DURATION = 300;
393
393
  const DEFAULT_TRANSITION_TIMING = "cubic-bezier(0.4, 0, 0.2, 1)";
394
- function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing = DEFAULT_TRANSITION_TIMING) {
394
+ function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing = DEFAULT_TRANSITION_TIMING, el = null) {
395
395
  if (typeof document === "undefined") return;
396
+ const target = el || document.documentElement;
396
397
  const style = document.createElement("style");
397
398
  style.id = "yh-theme-transition";
398
399
  style.textContent = `
@@ -410,9 +411,9 @@ function enableThemeTransition(duration = DEFAULT_TRANSITION_DURATION, timing =
410
411
  }
411
412
  `;
412
413
  document.head.appendChild(style);
413
- document.documentElement.classList.add(THEME_TRANSITION_CLASS);
414
+ target.classList.add(THEME_TRANSITION_CLASS);
414
415
  setTimeout(() => {
415
- document.documentElement.classList.remove(THEME_TRANSITION_CLASS);
416
+ target.classList.remove(THEME_TRANSITION_CLASS);
416
417
  style.remove();
417
418
  }, duration);
418
419
  }
@@ -497,6 +498,7 @@ export class ThemeManager {
497
498
  };
498
499
  themeHistory = [];
499
500
  maxHistoryLength = 10;
501
+ responsiveVars = /* @__PURE__ */ new Map();
500
502
  // 响应式状态
501
503
  state = reactive({
502
504
  theme: "default",
@@ -517,7 +519,8 @@ export class ThemeManager {
517
519
  this.persistKey = options?.persistKey || "yh-ui-theme";
518
520
  this.restoreFromStorage();
519
521
  }
520
- this.apply({
522
+ this.targetEl = getTargetElement(options?.scope);
523
+ this.applyFullConfig({
521
524
  preset: "default",
522
525
  ...options
523
526
  });
@@ -597,11 +600,12 @@ export class ThemeManager {
597
600
  setDarkMode(dark) {
598
601
  this.isDark = dark;
599
602
  this.state.dark = dark;
600
- if (typeof document !== "undefined") {
603
+ const el = this.targetEl || (typeof document !== "undefined" ? document.documentElement : null);
604
+ if (el) {
601
605
  if (dark) {
602
- document.documentElement.classList.add("dark");
606
+ el.classList.add("dark");
603
607
  } else {
604
- document.documentElement.classList.remove("dark");
608
+ el.classList.remove("dark");
605
609
  }
606
610
  }
607
611
  const currentColors = {
@@ -836,7 +840,11 @@ export class ThemeManager {
836
840
  try {
837
841
  const snapshot = JSON.parse(json);
838
842
  if (this.transitionEnabled) {
839
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
843
+ enableThemeTransition(
844
+ this.transitionConfig.duration,
845
+ this.transitionConfig.timing,
846
+ this.targetEl
847
+ );
840
848
  }
841
849
  this.setPreset(snapshot.preset);
842
850
  if (snapshot.colors && Object.keys(snapshot.colors).length > 0) {
@@ -883,8 +891,8 @@ export class ThemeManager {
883
891
  this.state.colorBlindMode = "none";
884
892
  this.state.algorithm = "default";
885
893
  this.state.componentThemeVersion += 1;
886
- document.documentElement.classList.remove("dark");
887
894
  const el = this.targetEl || document.documentElement;
895
+ el.classList.remove("dark");
888
896
  const colorTypes = ["primary", "success", "warning", "danger", "info"];
889
897
  const suffixes = [
890
898
  "",
@@ -919,7 +927,11 @@ export class ThemeManager {
919
927
  /** 设置密度 */
920
928
  setDensity(density) {
921
929
  if (this.transitionEnabled) {
922
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
930
+ enableThemeTransition(
931
+ this.transitionConfig.duration,
932
+ this.transitionConfig.timing,
933
+ this.targetEl
934
+ );
923
935
  }
924
936
  this.currentDensity = density;
925
937
  this.state.density = density;
@@ -939,7 +951,11 @@ export class ThemeManager {
939
951
  /** 设置色盲友好模式 */
940
952
  setColorBlindMode(mode) {
941
953
  if (this.transitionEnabled) {
942
- enableThemeTransition(this.transitionConfig.duration, this.transitionConfig.timing);
954
+ enableThemeTransition(
955
+ this.transitionConfig.duration,
956
+ this.transitionConfig.timing,
957
+ this.targetEl
958
+ );
943
959
  }
944
960
  this.colorBlindMode = mode;
945
961
  this.state.colorBlindMode = mode;
@@ -1034,7 +1050,7 @@ export class ThemeManager {
1034
1050
  applyFullConfig(config) {
1035
1051
  if (this.transitionEnabled || config.transition) {
1036
1052
  const transitionConfig = typeof config.transition === "object" ? config.transition : { duration: DEFAULT_TRANSITION_DURATION, timing: DEFAULT_TRANSITION_TIMING };
1037
- enableThemeTransition(transitionConfig.duration, transitionConfig.timing);
1053
+ enableThemeTransition(transitionConfig.duration, transitionConfig.timing, this.targetEl);
1038
1054
  }
1039
1055
  this.pushHistory();
1040
1056
  const snapshot = this.createTheme(config);
@@ -1117,6 +1133,7 @@ export class ThemeManager {
1117
1133
  /** 设置响应式变量 (根据断点自动切换) */
1118
1134
  setResponsiveVar(name, values) {
1119
1135
  if (typeof document === "undefined") return;
1136
+ this.responsiveVars.set(name, values);
1120
1137
  let style = document.getElementById("yh-responsive-vars");
1121
1138
  if (!style) {
1122
1139
  style = document.createElement("style");
@@ -1124,23 +1141,25 @@ export class ThemeManager {
1124
1141
  document.head.appendChild(style);
1125
1142
  }
1126
1143
  let css = "";
1127
- const orderedBreakpoints = ["xs", "sm", "md", "lg", "xl", "xxl"];
1128
- orderedBreakpoints.forEach((bp) => {
1129
- if (values[bp]) {
1130
- if (bp === "xs") {
1131
- css += `
1132
- :root { ${name}: ${values[bp]}; }
1133
- `;
1134
- } else {
1135
- css += `
1136
- @media (min-width: ${breakpoints[bp]}px) {
1137
- :root { ${name}: ${values[bp]}; }
1138
- }
1139
- `;
1144
+ this.responsiveVars.forEach((vals, varName) => {
1145
+ const orderedBreakpoints = ["xs", "sm", "md", "lg", "xl", "xxl"];
1146
+ orderedBreakpoints.forEach((bp) => {
1147
+ if (vals[bp]) {
1148
+ if (bp === "xs") {
1149
+ css += `
1150
+ :root { ${varName}: ${vals[bp]}; }
1151
+ `;
1152
+ } else {
1153
+ css += `
1154
+ @media (min-width: ${breakpoints[bp]}px) {
1155
+ :root { ${varName}: ${vals[bp]}; }
1156
+ }
1157
+ `;
1158
+ }
1140
1159
  }
1141
- }
1160
+ });
1142
1161
  });
1143
- style.textContent += css;
1162
+ style.textContent = css;
1144
1163
  }
1145
1164
  /** 销毁 */
1146
1165
  destroy() {
@@ -1152,6 +1171,7 @@ export class ThemeManager {
1152
1171
  if (style) {
1153
1172
  style.remove();
1154
1173
  }
1174
+ this.responsiveVars.clear();
1155
1175
  }
1156
1176
  }
1157
1177
  let globalThemeManager = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yh-ui/theme",
3
- "version": "1.0.51",
3
+ "version": "1.0.53",
4
4
  "description": "YH-UI theme and design tokens",
5
5
  "type": "module",
6
6
  "sideEffects": [