1
0

update-css-variables.ts 3.5 KB

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