From 6afed3443754e3216a621160b9b633f5dc0f6577 Mon Sep 17 00:00:00 2001 From: vben Date: Sun, 23 Jun 2024 19:17:31 +0800 Subject: [PATCH] chore: Optimize multi-theme switching --- apps/web-antd/package.json | 1 - apps/web-antd/src/app.vue | 47 + apps/web-antd/src/views/dashboard/index.vue | 484 ++-- .../lint-configs/eslint-config/package.json | 4 +- internal/tailwind-config/src/index.ts | 56 +- internal/vite-config/package.json | 2 +- package.json | 4 +- .../@core/forward/preferences/package.json | 1 + .../@core/forward/preferences/src/config.ts | 9 +- .../forward/preferences/src/constants.ts | 99 +- .../preferences/src/preferences.test.ts | 26 +- .../forward/preferences/src/preferences.ts | 112 +- .../@core/forward/preferences/src/types.ts | 15 +- .../preferences/src/use-preferences.ts | 2 +- .../@core/shared/colorful/build.config.ts | 7 + packages/@core/shared/colorful/package.json | 42 + .../@core/shared/colorful/src/generator.ts | 45 + packages/@core/shared/colorful/src/index.ts | 2 + .../src/utils.test.ts} | 2 +- .../src/color.ts => colorful/src/utils.ts} | 0 packages/@core/shared/colorful/tsconfig.json | 6 + .../shared/design-tokens/src/dark/index.css | 290 ++- .../design-tokens/src/default/index.css | 281 +++ packages/@core/shared/toolkit/package.json | 1 - packages/@core/shared/toolkit/src/index.ts | 2 +- .../toolkit/src/update-css-variables.test.ts | 30 + .../toolkit/src/update-css-variables.ts | 35 + packages/@core/shared/typings/src/app.d.ts | 21 + packages/@core/uikit/shadcn-ui/package.json | 1 + .../src/components/menu-badge/menu-badge.vue | 2 +- .../src/components/ui/badge/badge.ts | 2 +- .../src/components/ui/button/button.ts | 2 +- .../src/authentication/authentication.vue | 13 +- .../layouts/src/authentication/toolbar.vue | 2 +- packages/business/universal-ui/package.json | 2 +- .../universal-ui/src/authentication/login.vue | 5 +- .../src/authentication/register.vue | 6 +- .../authentication/widgets/color-toggle.vue | 40 +- packages/business/universal-ui/src/index.ts | 2 +- .../src/preferences/blocks/index.ts | 3 +- .../src/preferences/blocks/theme/builtin.vue | 137 ++ .../src/preferences/blocks/theme/color.vue | 90 - .../src/preferences/blocks/theme/radius.vue | 38 + .../src/preferences/blocks/theme/theme.vue | 6 +- .../src/preferences/icons/setting.vue | 1 - .../src/preferences/preferences-widget.vue | 21 +- .../src/preferences/preferences.vue | 73 +- .../universal-ui/src/preferences/trigger.vue | 4 +- .../src/theme-toggle/theme-toggle.vue | 7 +- packages/locales/src/langs/en-US.yaml | 20 +- packages/locales/src/langs/zh-CN.yaml | 20 +- packages/styles/src/tokens/dark.scss | 4 - packages/styles/src/tokens/light.scss | 1 - pnpm-lock.yaml | 2174 ++++++++++++++--- vben-admin.code-workspace | 4 + 55 files changed, 3534 insertions(+), 772 deletions(-) create mode 100644 packages/@core/shared/colorful/build.config.ts create mode 100644 packages/@core/shared/colorful/package.json create mode 100644 packages/@core/shared/colorful/src/generator.ts create mode 100644 packages/@core/shared/colorful/src/index.ts rename packages/@core/shared/{toolkit/src/color.test.ts => colorful/src/utils.test.ts} (99%) rename packages/@core/shared/{toolkit/src/color.ts => colorful/src/utils.ts} (100%) create mode 100644 packages/@core/shared/colorful/tsconfig.json create mode 100644 packages/@core/shared/toolkit/src/update-css-variables.test.ts create mode 100644 packages/@core/shared/toolkit/src/update-css-variables.ts create mode 100644 packages/business/universal-ui/src/preferences/blocks/theme/builtin.vue delete mode 100644 packages/business/universal-ui/src/preferences/blocks/theme/color.vue create mode 100644 packages/business/universal-ui/src/preferences/blocks/theme/radius.vue diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index 6a9a799f..5b29eb71 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -38,7 +38,6 @@ "@vben/styles": "workspace:*", "@vben/types": "workspace:*", "@vben/universal-ui": "workspace:*", - "@vben/chart-ui": "workspace:*", "@vben/utils": "workspace:*", "@vueuse/core": "^10.11.0", "ant-design-vue": "^4.2.3", diff --git a/apps/web-antd/src/app.vue b/apps/web-antd/src/app.vue index 4ab49aa8..7930e112 100644 --- a/apps/web-antd/src/app.vue +++ b/apps/web-antd/src/app.vue @@ -42,3 +42,50 @@ const tokenTheme = computed(() => { + + diff --git a/apps/web-antd/src/views/dashboard/index.vue b/apps/web-antd/src/views/dashboard/index.vue index 617fb86f..e1008047 100644 --- a/apps/web-antd/src/views/dashboard/index.vue +++ b/apps/web-antd/src/views/dashboard/index.vue @@ -1,249 +1,251 @@ diff --git a/internal/lint-configs/eslint-config/package.json b/internal/lint-configs/eslint-config/package.json index e1e06943..dee0e928 100644 --- a/internal/lint-configs/eslint-config/package.json +++ b/internal/lint-configs/eslint-config/package.json @@ -32,8 +32,8 @@ "devDependencies": { "@eslint/js": "^9.5.0", "@types/eslint": "^8.56.10", - "@typescript-eslint/eslint-plugin": "^7.13.1", - "@typescript-eslint/parser": "^7.13.1", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.14.1", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", diff --git a/internal/tailwind-config/src/index.ts b/internal/tailwind-config/src/index.ts index 9e58310e..2b2f09c5 100644 --- a/internal/tailwind-config/src/index.ts +++ b/internal/tailwind-config/src/index.ts @@ -24,6 +24,31 @@ packages.forEach((pkg) => { } }); +function createColorsPattern(name: string) { + return { + 100: `hsl(var(--${name}-100))`, + 200: `hsl(var(--${name}-200))`, + 300: `hsl(var(--${name}-300))`, + 400: `hsl(var(--${name}-400))`, + 500: `hsl(var(--${name}-500))`, + 600: `hsl(var(--${name}-600))`, + 700: `hsl(var(--${name}-700))`, + 800: `hsl(var(--${name}-800))`, + 900: `hsl(var(--${name}-900))`, + 1000: `hsl(var(--${name}-1000))`, + active: `hsl(var(--${name}-700))`, + background: `hsl(var(--${name}-100))`, + 'background-hover': `hsl(var(--${name}-200))`, + border: `hsl(var(--${name}-300))`, + 'border-hover': `hsl(var(--${name}-400))`, + foreground: `hsl(var(--${name}-foreground))`, + hover: `hsl(var(--${name}-500))`, + text: `hsl(var(--${name}-900))`, + 'text-active': `hsl(var(--${name}-1000))`, + 'text-hover': `hsl(var(--${name}-800))`, + }; +} + export default { content: [ './index.html', @@ -73,17 +98,23 @@ export default { foreground: 'hsl(var(--accent-foreground))', hover: 'hsl(var(--accent-hover))', }, + authentication: 'hsl(var(--authentication))', background: 'hsl(var(--background))', border: 'hsl(var(--border))', card: { DEFAULT: 'hsl(var(--card))', foreground: 'hsl(var(--card-foreground))', }, + destructive: { + ...createColorsPattern('destructive'), DEFAULT: 'hsl(var(--destructive))', - foreground: 'hsl(var(--destructive-foreground))', }, - foreground: 'hsl(var(--foreground) / )', + foreground: 'hsl(var(--foreground))', + green: { + ...createColorsPattern('green'), + foreground: 'hsl(var(--success-foreground))', + }, heavy: { DEFAULT: 'hsl(var(--heavy))', foreground: 'hsl(var(--heavy-foreground))', @@ -102,21 +133,30 @@ export default { foreground: 'hsl(var(--popover-foreground))', }, primary: { - DEFAULT: 'hsl(var(--primary) / )', - foreground: 'hsl(var(--primary-foreground) / )', + ...createColorsPattern('primary'), + DEFAULT: 'hsl(var(--primary))', + }, + red: { + ...createColorsPattern('red'), + foreground: 'hsl(var(--destructive-foreground))', }, ring: 'hsl(var(--ring))', secondary: { - DEFAULT: 'hsl(var(--secondary) / )', - desc: 'hsl(var(--secondary-desc) / )', - foreground: 'hsl(var(--secondary-foreground) / )', + DEFAULT: 'hsl(var(--secondary))', + desc: 'hsl(var(--secondary-desc))', + foreground: 'hsl(var(--secondary-foreground))', }, + success: { + ...createColorsPattern('success'), DEFAULT: 'hsl(var(--success))', - foreground: 'hsl(var(--success-foreground))', }, warning: { + ...createColorsPattern('warning'), DEFAULT: 'hsl(var(--warning))', + }, + yellow: { + ...createColorsPattern('yellow'), foreground: 'hsl(var(--warning-foreground))', }, }, diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json index be8318ca..d5c99c99 100644 --- a/internal/vite-config/package.json +++ b/internal/vite-config/package.json @@ -46,7 +46,7 @@ "rollup": "^4.18.0", "rollup-plugin-visualizer": "^5.12.0", "sass": "^1.77.6", - "unplugin-turbo-console": "^1.8.6", + "unplugin-turbo-console": "^1.8.7", "vite": "^5.3.1", "vite-plugin-compression": "^0.5.1", "vite-plugin-dts": "^3.9.1", diff --git a/package.json b/package.json index 7bd4cd9d..b663d02a 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@changesets/cli": "^2.27.6", "@ls-lint/ls-lint": "^2.2.3", "@types/jsdom": "^21.1.7", - "@types/node": "^20.14.8", + "@types/node": "^20.14.9", "@vben/commitlint-config": "workspace:*", "@vben/eslint-config": "workspace:*", "@vben/lint-staged-config": "workspace:*", @@ -69,7 +69,7 @@ "jsdom": "^24.1.0", "rimraf": "^5.0.7", "taze": "^0.13.8", - "turbo": "^2.0.4", + "turbo": "^2.0.5", "typescript": "^5.5.2", "unbuild": "^2.0.0", "vite": "^5.3.1", diff --git a/packages/@core/forward/preferences/package.json b/packages/@core/forward/preferences/package.json index 830c2c36..729a074d 100644 --- a/packages/@core/forward/preferences/package.json +++ b/packages/@core/forward/preferences/package.json @@ -30,6 +30,7 @@ }, "dependencies": { "@vben-core/cache": "workspace:*", + "@vben-core/colorful": "workspace:*", "@vben-core/toolkit": "workspace:*", "@vben-core/typings": "workspace:*", "@vueuse/core": "^10.11.0", diff --git a/packages/@core/forward/preferences/src/config.ts b/packages/@core/forward/preferences/src/config.ts index 388c1cce..792fa59e 100644 --- a/packages/@core/forward/preferences/src/config.ts +++ b/packages/@core/forward/preferences/src/config.ts @@ -18,7 +18,6 @@ const defaultPreferences: Preferences = { name: 'Vben Admin Pro', semiDarkMenu: true, showPreference: true, - themeMode: 'dark', }, breadcrumb: { enable: true, @@ -67,7 +66,13 @@ const defaultPreferences: Preferences = { showIcon: true, }, theme: { - colorPrimary: 'hsl(211 91% 39%)', + builtinType: 'default', + colorDestructive: 'hsl(348 100% 61%)', + colorPrimary: 'hsl(245 82% 67%)', + colorSuccess: 'hsl(144 57% 58%)', + colorWarning: 'hsl(42 84% 61%)', + mode: 'dark', + radius: '0.5', }, transition: { enable: true, diff --git a/packages/@core/forward/preferences/src/constants.ts b/packages/@core/forward/preferences/src/constants.ts index 11021988..9c2753fa 100644 --- a/packages/@core/forward/preferences/src/constants.ts +++ b/packages/@core/forward/preferences/src/constants.ts @@ -1,3 +1,5 @@ +import type { BuiltinThemeType } from '@vben-core/typings'; + import type { SupportedLanguagesType } from './types'; interface Language { @@ -5,17 +7,17 @@ interface Language { text: string; } -export const COLOR_PRIMARY_RESETS = [ - 'hsl(211 91% 39%)', - 'hsl(212 100% 45%)', - 'hsl(181 84% 32%)', - 'hsl(161 90% 43%)', - 'hsl(231 98% 65%)', - 'hsl(245 82% 67%)', - 'hsl(347 77% 60%)', -]; +interface BuiltinThemePreset { + color: string; + darkPrimaryColor?: string; + primaryColor?: string; + type: BuiltinThemeType; +} -export const SUPPORT_LANGUAGES: Language[] = [ +/** + * Supported languages + */ +const SUPPORT_LANGUAGES: Language[] = [ { key: 'zh-CN', text: '简体中文', @@ -25,3 +27,80 @@ export const SUPPORT_LANGUAGES: Language[] = [ text: 'English', }, ]; + +const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [ + { + color: 'hsl(245 82% 67%)', + type: 'default', + }, + { + color: 'hsl(231 98% 65%)', + type: 'violet', + }, + { + color: 'hsl(347 77% 60%)', + type: 'pink', + }, + { + color: 'hsl(0 75% 42%)', + type: 'rose', + }, + { + color: 'hsl(212 100% 45%)', + type: 'sky-blue', + }, + { + color: 'hsl(211 91% 39%)', + type: 'deep-blue', + }, + { + color: 'hsl(161 90% 43%)', + type: 'green', + }, + { + color: 'hsl(181 84% 32%)', + type: 'deep-green', + }, + { + color: 'hsl(18 89% 40%)', + type: 'orange', + }, + { + color: 'hsl(42 84% 61%)', + type: 'yellow', + }, + { + color: 'hsl(240 5% 26%)', + darkPrimaryColor: 'hsl(0 0 98%)', + primaryColor: 'hsl(240 5.9% 10%)', + type: 'zinc', + }, + { + color: 'hsl(0 0% 25%)', + darkPrimaryColor: 'hsl(0 0 98%)', + primaryColor: 'hsl(240 5.9% 10%)', + type: 'neutral', + }, + { + color: 'hsl(215 25% 27%)', + darkPrimaryColor: 'hsl(0 0 98%)', + primaryColor: 'hsl(240 5.9% 10%)', + type: 'slate', + }, + { + color: 'hsl(217 19% 27%)', + darkPrimaryColor: 'hsl(0 0 98%)', + primaryColor: 'hsl(240 5.9% 10%)', + type: 'gray', + }, + { + color: '', + type: 'custom', + }, +]; + +export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 7); + +export { BUILT_IN_THEME_PRESETS, SUPPORT_LANGUAGES }; + +export type { BuiltinThemePreset }; diff --git a/packages/@core/forward/preferences/src/preferences.test.ts b/packages/@core/forward/preferences/src/preferences.test.ts index 2c8c2a4a..885840f3 100644 --- a/packages/@core/forward/preferences/src/preferences.test.ts +++ b/packages/@core/forward/preferences/src/preferences.test.ts @@ -55,7 +55,6 @@ describe('preferences', () => { const overrides: any = { app: { locale: 'en-US', - themeMode: 'light', }, }; await preferenceManager.initPreferences({ @@ -79,10 +78,12 @@ describe('preferences', () => { it('updates theme mode correctly', () => { preferenceManager.updatePreferences({ - app: { themeMode: 'light' }, + theme: { + mode: 'light', + }, }); - expect(preferenceManager.getPreferences().app.themeMode).toBe('light'); + expect(preferenceManager.getPreferences().theme.mode).toBe('light'); }); it('updates color modes correctly', () => { @@ -97,7 +98,9 @@ describe('preferences', () => { it('resets preferences to default', () => { // 先更新一些偏好设置 preferenceManager.updatePreferences({ - app: { themeMode: 'light' }, + theme: { + mode: 'light', + }, }); // 然后重置偏好设置 @@ -146,10 +149,10 @@ describe('preferences', () => { }); it('updates the sidebar collapse state correctly', () => { preferenceManager.updatePreferences({ - sidebar: { collapse: true }, + sidebar: { collapsed: true }, }); - expect(preferenceManager.getPreferences().sidebar.collapse).toBe(true); + expect(preferenceManager.getPreferences().sidebar.collapsed).toBe(true); }); it('updates the navigation style type correctly', () => { preferenceManager.updatePreferences({ @@ -164,8 +167,11 @@ describe('preferences', () => { it('resets preferences to default correctly', () => { // 先更新一些偏好设置 preferenceManager.updatePreferences({ - app: { locale: 'en-US', themeMode: 'light' }, - sidebar: { collapse: true, width: 200 }, + app: { locale: 'en-US' }, + sidebar: { collapsed: true, width: 200 }, + theme: { + mode: 'light', + }, }); // 然后重置偏好设置 @@ -232,10 +238,10 @@ describe('preferences', () => { await preferenceManager.initPreferences(overrides); preferenceManager.updatePreferences({ - app: { themeMode: 'light' }, + theme: { mode: 'light' }, }); - expect(preferenceManager.getPreferences().app.themeMode).toBe('light'); + expect(preferenceManager.getPreferences().theme.mode).toBe('light'); }); }); diff --git a/packages/@core/forward/preferences/src/preferences.ts b/packages/@core/forward/preferences/src/preferences.ts index 0e63aa70..7e89b51e 100644 --- a/packages/@core/forward/preferences/src/preferences.ts +++ b/packages/@core/forward/preferences/src/preferences.ts @@ -5,16 +5,17 @@ import type { Preferences } from './types'; import { markRaw, reactive, readonly, watch } from 'vue'; import { StorageManager } from '@vben-core/cache'; -import { convertToHslCssVar, merge } from '@vben-core/toolkit'; +import { generatorColorVariables } from '@vben-core/colorful'; +import { merge, updateCSSVariables } from '@vben-core/toolkit'; import { breakpointsTailwind, useBreakpoints, - useCssVar, useDebounceFn, } from '@vueuse/core'; import { defaultPreferences } from './config'; +import { BUILT_IN_THEME_PRESETS } from './constants'; const STORAGE_KEY = 'preferences'; const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`; @@ -59,7 +60,7 @@ class PreferenceManager { private _savePreferences(preference: Preferences) { this.cache?.setItem(STORAGE_KEY, preference); this.cache?.setItem(STORAGE_KEY_LOCALE, preference.app.locale); - this.cache?.setItem(STORAGE_KEY_THEME, preference.app.themeMode); + this.cache?.setItem(STORAGE_KEY_THEME, preference.theme.mode); } /** @@ -72,11 +73,7 @@ class PreferenceManager { const themeUpdates = updates.theme || {}; const appUpdates = updates.app || {}; - if (themeUpdates.colorPrimary) { - this.updateCssVar(this.state); - } - - if (appUpdates.themeMode) { + if (themeUpdates && Object.keys(themeUpdates).length > 0) { this.updateTheme(this.state); } @@ -149,7 +146,7 @@ class PreferenceManager { .matchMedia('(prefers-color-scheme: dark)') .addEventListener('change', ({ matches: isDark }) => { this.updatePreferences({ - app: { themeMode: isDark ? 'dark' : 'light' }, + theme: { mode: isDark ? 'dark' : 'light' }, }); this.updateTheme(this.state); }); @@ -178,15 +175,37 @@ class PreferenceManager { * 更新 CSS 变量 * @param preference - 当前偏好设置对象,它的颜色值将被转换成 HSL 格式并设置为 CSS 变量。 */ - private updateCssVar(preference: Preferences) { - if (preference.theme) { - for (const [key, value] of Object.entries(preference.theme)) { - if (['colorPrimary'].includes(key)) { - const cssVarValue = useCssVar(`--primary`); - cssVarValue.value = convertToHslCssVar(value); - } - } + private updateMainColors(preference: Preferences) { + if (!preference.theme) { + return; } + const { colorDestructive, colorPrimary, colorSuccess, colorWarning } = + preference.theme; + + const colorVariables = generatorColorVariables([ + { color: colorPrimary, name: 'primary' }, + { alias: 'warning', color: colorWarning, name: 'yellow' }, + { alias: 'success', color: colorSuccess, name: 'green' }, + { alias: 'destructive', color: colorDestructive, name: 'red' }, + ]); + + if (colorPrimary) { + document.documentElement.style.setProperty( + '--primary', + colorVariables['--primary-600'], + ); + } + + if (colorVariables['--green-600']) { + colorVariables['--success'] = colorVariables['--green-600']; + } + if (colorVariables['--yellow-600']) { + colorVariables['--warning'] = colorVariables['--yellow-600']; + } + if (colorVariables['--red-600']) { + colorVariables['--destructive'] = colorVariables['--red-600']; + } + updateCSSVariables(colorVariables); } /** @@ -206,14 +225,61 @@ class PreferenceManager { private updateTheme(preferences: Preferences) { // 当修改到颜色变量时,更新 css 变量 const root = document.documentElement; - if (root) { - const themeMode = preferences?.app?.themeMode; - if (!themeMode) { - return; - } - const dark = isDarkTheme(themeMode); + if (!root) { + return; + } + + const { + builtinType, + colorDestructive, + colorPrimary, + colorSuccess, + colorWarning, + mode, + radius, + } = preferences?.theme ?? {}; + + if (mode) { + const dark = isDarkTheme(mode); root.classList.toggle('dark', dark); } + + if (builtinType) { + const rootTheme = root.dataset.theme; + if (rootTheme !== builtinType) { + root.dataset.theme = builtinType; + } + } + + const currentBuiltType = BUILT_IN_THEME_PRESETS.find( + (item) => item.type === builtinType, + ); + + let builtinTypeColorPrimary: string | undefined = ''; + + if (currentBuiltType) { + const isDark = isDarkTheme(this.state.theme.mode); + + const color = isDark + ? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor + : currentBuiltType.primaryColor; + builtinTypeColorPrimary = color || currentBuiltType.color; + } + + if ( + builtinTypeColorPrimary || + colorPrimary || + colorDestructive || + colorSuccess || + colorWarning + ) { + preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary; + this.updateMainColors(preferences); + } + + if (radius) { + document.documentElement.style.setProperty('--radius', `${radius}rem`); + } } // public getFlatPreferences() { diff --git a/packages/@core/forward/preferences/src/types.ts b/packages/@core/forward/preferences/src/types.ts index eb139805..55d911d8 100644 --- a/packages/@core/forward/preferences/src/types.ts +++ b/packages/@core/forward/preferences/src/types.ts @@ -1,4 +1,5 @@ import type { + BuiltinThemeType, ContentCompactType, LayoutHeaderModeType, LayoutType, @@ -45,8 +46,6 @@ interface AppPreferences { semiDarkMenu: boolean; /** 是否显示偏好设置 */ showPreference: boolean; - /** 当前主题 */ - themeMode: ThemeModeType; } interface BreadcrumbPreferences { @@ -132,8 +131,20 @@ interface TabbarPreferences { } interface ThemePreferences { + /** 内置主题名 */ + builtinType: BuiltinThemeType; + /** 错误色 */ + colorDestructive: string; /** 主题色 */ colorPrimary: string; + /** 成功色 */ + colorSuccess: string; + /** 警告色 */ + colorWarning: string; + /** 当前主题 */ + mode: ThemeModeType; + /** 圆角 */ + radius: string; } interface TransitionPreferences { diff --git a/packages/@core/forward/preferences/src/use-preferences.ts b/packages/@core/forward/preferences/src/use-preferences.ts index d1f5b8ec..c43606a7 100644 --- a/packages/@core/forward/preferences/src/use-preferences.ts +++ b/packages/@core/forward/preferences/src/use-preferences.ts @@ -24,7 +24,7 @@ function usePreferences() { * @returns 如果主题为暗黑模式,返回 true,否则返回 false。 */ const isDark = computed(() => { - return isDarkTheme(appPreferences.value.themeMode); + return isDarkTheme(preferences.theme.mode); }); const theme = computed(() => { diff --git a/packages/@core/shared/colorful/build.config.ts b/packages/@core/shared/colorful/build.config.ts new file mode 100644 index 00000000..97e572c5 --- /dev/null +++ b/packages/@core/shared/colorful/build.config.ts @@ -0,0 +1,7 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + declaration: true, + entries: ['src/index'], +}); diff --git a/packages/@core/shared/colorful/package.json b/packages/@core/shared/colorful/package.json new file mode 100644 index 00000000..f7c429d6 --- /dev/null +++ b/packages/@core/shared/colorful/package.json @@ -0,0 +1,42 @@ +{ + "name": "@vben-core/colorful", + "version": "5.0.0", + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "packages/@vben-core/shared/colorful" + }, + "license": "MIT", + "type": "module", + "scripts": { + "build": "pnpm unbuild", + "stub": "pnpm unbuild --stub" + }, + "files": [ + "dist" + ], + "sideEffects": false, + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "exports": { + ".": { + "types": "./src/index.ts", + "development": "./src/index.ts", + "default": "./dist/index.mjs" + } + }, + "publishConfig": { + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + } + }, + "dependencies": { + "@ant-design/colors": "^7.0.2", + "@ctrl/tinycolor": "4.1.0" + } +} diff --git a/packages/@core/shared/colorful/src/generator.ts b/packages/@core/shared/colorful/src/generator.ts new file mode 100644 index 00000000..d4ca892f --- /dev/null +++ b/packages/@core/shared/colorful/src/generator.ts @@ -0,0 +1,45 @@ +import { generate } from '@ant-design/colors'; + +import { convertToHslCssVar } from './utils'; + +export * from '@ant-design/colors'; + +interface Opts { + backgroundColor?: string; + theme?: 'dark' | 'default'; +} + +interface ColorItem { + alias?: string; + color: string; + name: string; +} + +function generatorColorVariables(colorItems: ColorItem[], opts?: Opts) { + const colorVariables: Record = {}; + + colorItems.forEach(({ alias, color, name }) => { + if (color) { + const colors = generate(color, opts); + let mainColor = colors[5]; + colors.forEach((colorValue, colorIndex) => { + const hslColor = convertToHslCssVar(colorValue); + colorVariables[`--${name}-${colorIndex + 1}00`] = hslColor; + if (alias) { + colorVariables[`--${alias}-${colorIndex + 1}00`] = hslColor; + } + + if (colorIndex === 5) { + mainColor = hslColor; + } + }); + if (alias) { + colorVariables[`--${alias}`] = mainColor; + } + } + }); + + return colorVariables; +} + +export { generatorColorVariables }; diff --git a/packages/@core/shared/colorful/src/index.ts b/packages/@core/shared/colorful/src/index.ts new file mode 100644 index 00000000..8cb44f95 --- /dev/null +++ b/packages/@core/shared/colorful/src/index.ts @@ -0,0 +1,2 @@ +export * from './generator'; +export * from './utils'; diff --git a/packages/@core/shared/toolkit/src/color.test.ts b/packages/@core/shared/colorful/src/utils.test.ts similarity index 99% rename from packages/@core/shared/toolkit/src/color.test.ts rename to packages/@core/shared/colorful/src/utils.test.ts index 35bf43de..ccdc8039 100644 --- a/packages/@core/shared/toolkit/src/color.test.ts +++ b/packages/@core/shared/colorful/src/utils.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { convertToHsl, convertToHslCssVar, isValidColor } from './color'; +import { convertToHsl, convertToHslCssVar, isValidColor } from './utils'; describe('color conversion functions', () => { it('should correctly convert color to HSL format', () => { diff --git a/packages/@core/shared/toolkit/src/color.ts b/packages/@core/shared/colorful/src/utils.ts similarity index 100% rename from packages/@core/shared/toolkit/src/color.ts rename to packages/@core/shared/colorful/src/utils.ts diff --git a/packages/@core/shared/colorful/tsconfig.json b/packages/@core/shared/colorful/tsconfig.json new file mode 100644 index 00000000..f6860a32 --- /dev/null +++ b/packages/@core/shared/colorful/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/library.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/packages/@core/shared/design-tokens/src/dark/index.css b/packages/@core/shared/design-tokens/src/dark/index.css index 679b4755..4997f01c 100644 --- a/packages/@core/shared/design-tokens/src/dark/index.css +++ b/packages/@core/shared/design-tokens/src/dark/index.css @@ -1,4 +1,6 @@ -:root.dark { +:root.dark, +:root.dark[data-theme='custom'], +:root.dark[data-theme='default'] { /* Default background color of ...etc */ --background: 220deg 13.04% 8%; --foreground: 220 13% 91%; @@ -16,18 +18,22 @@ --muted-foreground: 215 20.2% 65.1%; /* 主题颜色 */ - --primary: 211 91% 39%; + + /* --primary: 245 82% 67%; */ --primary-foreground: 0 0 98%; /* Used for destructive actions such as