update-css-variables.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import type { Preferences } from './types';
  2. import { generatorColorVariables } from '@vben-core/shared/color';
  3. import { updateCSSVariables as executeUpdateCSSVariables } from '@vben-core/shared/utils';
  4. import { BUILT_IN_THEME_PRESETS } from './constants';
  5. /**
  6. * 更新主题的 CSS 变量以及其他 CSS 变量
  7. * @param preferences - 当前偏好设置对象,它的主题值将被用来设置文档的主题。
  8. */
  9. function updateCSSVariables(preferences: Preferences) {
  10. // 当修改到颜色变量时,更新 css 变量
  11. const root = document.documentElement;
  12. if (!root) {
  13. return;
  14. }
  15. const theme = preferences?.theme ?? {};
  16. const { builtinType, mode, radius } = theme;
  17. // html 设置 dark 类
  18. if (Reflect.has(theme, 'mode')) {
  19. const dark = isDarkTheme(mode);
  20. root.classList.toggle('dark', dark);
  21. }
  22. // html 设置 data-theme=[builtinType]
  23. if (Reflect.has(theme, 'builtinType')) {
  24. const rootTheme = root.dataset.theme;
  25. if (rootTheme !== builtinType) {
  26. root.dataset.theme = builtinType;
  27. }
  28. }
  29. // 获取当前的内置主题
  30. const currentBuiltType = [...BUILT_IN_THEME_PRESETS].find(
  31. (item) => item.type === builtinType,
  32. );
  33. let builtinTypeColorPrimary: string | undefined = '';
  34. if (currentBuiltType) {
  35. const isDark = isDarkTheme(preferences.theme.mode);
  36. // 设置不同主题的主要颜色
  37. const color = isDark
  38. ? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor
  39. : currentBuiltType.primaryColor;
  40. builtinTypeColorPrimary = color || currentBuiltType.color;
  41. }
  42. // 如果内置主题颜色和自定义颜色都不存在,则不更新主题颜色
  43. if (
  44. builtinTypeColorPrimary ||
  45. Reflect.has(theme, 'colorPrimary') ||
  46. Reflect.has(theme, 'colorDestructive') ||
  47. Reflect.has(theme, 'colorSuccess') ||
  48. Reflect.has(theme, 'colorWarning')
  49. ) {
  50. // preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
  51. updateMainColorVariables(preferences);
  52. }
  53. // 更新圆角
  54. if (Reflect.has(theme, 'radius')) {
  55. document.documentElement.style.setProperty('--radius', `${radius}rem`);
  56. }
  57. }
  58. /**
  59. * 更新主要的 CSS 变量
  60. * @param preference - 当前偏好设置对象,它的颜色值将被转换成 HSL 格式并设置为 CSS 变量。
  61. */
  62. function updateMainColorVariables(preference: Preferences) {
  63. if (!preference.theme) {
  64. return;
  65. }
  66. const { colorDestructive, colorPrimary, colorSuccess, colorWarning } =
  67. preference.theme;
  68. const colorVariables = generatorColorVariables([
  69. { color: colorPrimary, name: 'primary' },
  70. { alias: 'warning', color: colorWarning, name: 'yellow' },
  71. { alias: 'success', color: colorSuccess, name: 'green' },
  72. { alias: 'destructive', color: colorDestructive, name: 'red' },
  73. ]);
  74. // 要设置的 CSS 变量映射
  75. const colorMappings = {
  76. '--green-500': '--success',
  77. '--primary-500': '--primary',
  78. '--red-500': '--destructive',
  79. '--yellow-500': '--warning',
  80. };
  81. // 统一处理颜色变量的更新
  82. Object.entries(colorMappings).forEach(([sourceVar, targetVar]) => {
  83. const colorValue = colorVariables[sourceVar];
  84. if (colorValue) {
  85. document.documentElement.style.setProperty(targetVar, colorValue);
  86. }
  87. });
  88. executeUpdateCSSVariables(colorVariables);
  89. }
  90. function isDarkTheme(theme: string) {
  91. let dark = theme === 'dark';
  92. if (theme === 'auto') {
  93. dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
  94. }
  95. return dark;
  96. }
  97. export { isDarkTheme, updateCSSVariables };