perf: reorganize the icons and reduce the volume
This commit is contained in:
@@ -4,12 +4,7 @@ import type { Preferences } from './types';
|
||||
|
||||
import { markRaw, reactive, readonly, watch } from 'vue';
|
||||
|
||||
import {
|
||||
StorageManager,
|
||||
generatorColorVariables,
|
||||
merge,
|
||||
updateCSSVariables,
|
||||
} from '@vben-core/toolkit';
|
||||
import { StorageManager, merge } from '@vben-core/toolkit';
|
||||
|
||||
import {
|
||||
breakpointsTailwind,
|
||||
@@ -18,7 +13,7 @@ import {
|
||||
} from '@vueuse/core';
|
||||
|
||||
import { defaultPreferences } from './config';
|
||||
import { BUILT_IN_THEME_PRESETS } from './constants';
|
||||
import { updateCSSVariables } from './update-css-variables';
|
||||
|
||||
const STORAGE_KEY = 'preferences';
|
||||
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
|
||||
@@ -48,11 +43,10 @@ class PreferenceManager {
|
||||
});
|
||||
constructor() {
|
||||
this.cache = new StorageManager();
|
||||
// this.flattenedState = reactive(flattenObject(this.state));
|
||||
|
||||
this.savePreferences = useDebounceFn(
|
||||
(preference: Preferences) => this._savePreferences(preference),
|
||||
100,
|
||||
200,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,7 +70,7 @@ class PreferenceManager {
|
||||
const themeUpdates = updates.theme || {};
|
||||
const appUpdates = updates.app || {};
|
||||
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
|
||||
this.updateTheme(this.state);
|
||||
updateCSSVariables(this.state);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -130,7 +124,7 @@ class PreferenceManager {
|
||||
this.updatePreferences({
|
||||
theme: { mode: isDark ? 'dark' : 'light' },
|
||||
});
|
||||
this.updateTheme(this.state);
|
||||
updateCSSVariables(this.state);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -153,101 +147,6 @@ class PreferenceManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 CSS 变量
|
||||
* @param preference - 当前偏好设置对象,它的颜色值将被转换成 HSL 格式并设置为 CSS 变量。
|
||||
*/
|
||||
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-500'],
|
||||
);
|
||||
}
|
||||
|
||||
if (colorVariables['--green-500']) {
|
||||
colorVariables['--success'] = colorVariables['--green-500'];
|
||||
}
|
||||
if (colorVariables['--yellow-500']) {
|
||||
colorVariables['--warning'] = colorVariables['--yellow-500'];
|
||||
}
|
||||
if (colorVariables['--red-500']) {
|
||||
colorVariables['--destructive'] = colorVariables['--red-500'];
|
||||
}
|
||||
updateCSSVariables(colorVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主题
|
||||
* @param preferences - 当前偏好设置对象,它的主题值将被用来设置文档的主题。
|
||||
*/
|
||||
private updateTheme(preferences: Preferences) {
|
||||
// 当修改到颜色变量时,更新 css 变量
|
||||
const root = document.documentElement;
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
const theme = preferences?.theme ?? {};
|
||||
|
||||
const { builtinType, colorPrimary, mode, radius } = theme;
|
||||
|
||||
if (Reflect.has(theme, 'mode')) {
|
||||
const dark = isDarkTheme(mode);
|
||||
root.classList.toggle('dark', dark);
|
||||
}
|
||||
|
||||
if (Reflect.has(theme, '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 ||
|
||||
Reflect.has(theme, 'colorPrimary') ||
|
||||
Reflect.has(theme, 'colorDestructive') ||
|
||||
Reflect.has(theme, 'colorSuccess') ||
|
||||
Reflect.has(theme, 'colorWarning')
|
||||
) {
|
||||
preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
|
||||
this.updateMainColors(preferences);
|
||||
}
|
||||
|
||||
if (Reflect.has(theme, 'radius')) {
|
||||
document.documentElement.style.setProperty('--radius', `${radius}rem`);
|
||||
}
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
|
||||
this.cache?.removeItem(key);
|
||||
|
118
packages/@core/forward/preferences/src/update-css-variables.ts
Normal file
118
packages/@core/forward/preferences/src/update-css-variables.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import type { Preferences } from './types';
|
||||
|
||||
import {
|
||||
updateCSSVariables as executeUpdateCSSVariables,
|
||||
generatorColorVariables,
|
||||
} from '@vben-core/toolkit';
|
||||
|
||||
import { BUILT_IN_THEME_PRESETS } from './constants';
|
||||
|
||||
/**
|
||||
* 更新主题的 CSS 变量以及其他 CSS 变量
|
||||
* @param preferences - 当前偏好设置对象,它的主题值将被用来设置文档的主题。
|
||||
*/
|
||||
function updateCSSVariables(preferences: Preferences) {
|
||||
// 当修改到颜色变量时,更新 css 变量
|
||||
const root = document.documentElement;
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
const theme = preferences?.theme ?? {};
|
||||
|
||||
const { builtinType, colorPrimary, mode, radius } = theme;
|
||||
|
||||
// html 设置 dark 类
|
||||
if (Reflect.has(theme, 'mode')) {
|
||||
const dark = isDarkTheme(mode);
|
||||
root.classList.toggle('dark', dark);
|
||||
}
|
||||
|
||||
// html 设置 data-theme=[builtinType]
|
||||
if (Reflect.has(theme, '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(preferences.theme.mode);
|
||||
// 设置不同主题的主要颜色
|
||||
const color = isDark
|
||||
? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor
|
||||
: currentBuiltType.primaryColor;
|
||||
builtinTypeColorPrimary = color || currentBuiltType.color;
|
||||
}
|
||||
|
||||
// 如果内置主题颜色和自定义颜色都不存在,则不更新主题颜色
|
||||
if (
|
||||
builtinTypeColorPrimary ||
|
||||
Reflect.has(theme, 'colorPrimary') ||
|
||||
Reflect.has(theme, 'colorDestructive') ||
|
||||
Reflect.has(theme, 'colorSuccess') ||
|
||||
Reflect.has(theme, 'colorWarning')
|
||||
) {
|
||||
preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
|
||||
updateMainColorVariables(preferences);
|
||||
}
|
||||
|
||||
// 更新圆角
|
||||
if (Reflect.has(theme, 'radius')) {
|
||||
document.documentElement.style.setProperty('--radius', `${radius}rem`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主要的 CSS 变量
|
||||
* @param preference - 当前偏好设置对象,它的颜色值将被转换成 HSL 格式并设置为 CSS 变量。
|
||||
*/
|
||||
function updateMainColorVariables(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-500'],
|
||||
);
|
||||
}
|
||||
|
||||
if (colorVariables['--green-500']) {
|
||||
colorVariables['--success'] = colorVariables['--green-500'];
|
||||
}
|
||||
if (colorVariables['--yellow-500']) {
|
||||
colorVariables['--warning'] = colorVariables['--yellow-500'];
|
||||
}
|
||||
if (colorVariables['--red-500']) {
|
||||
colorVariables['--destructive'] = colorVariables['--red-500'];
|
||||
}
|
||||
executeUpdateCSSVariables(colorVariables);
|
||||
}
|
||||
|
||||
function isDarkTheme(theme: string) {
|
||||
let dark = theme === 'dark';
|
||||
if (theme === 'auto') {
|
||||
dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
return dark;
|
||||
}
|
||||
|
||||
export { updateCSSVariables };
|
@@ -27,6 +27,10 @@ function usePreferences() {
|
||||
return isDarkTheme(preferences.theme.mode);
|
||||
});
|
||||
|
||||
const isMobile = computed(() => {
|
||||
return appPreferences.value.isMobile;
|
||||
});
|
||||
|
||||
const theme = computed(() => {
|
||||
return isDark.value ? 'dark' : 'light';
|
||||
});
|
||||
@@ -35,7 +39,7 @@ function usePreferences() {
|
||||
* @zh_CN 布局方式
|
||||
*/
|
||||
const layout = computed(() =>
|
||||
appPreferences.value.isMobile ? 'sidebar-nav' : appPreferences.value.layout,
|
||||
isMobile.value ? 'sidebar-nav' : appPreferences.value.layout,
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -109,6 +113,16 @@ function usePreferences() {
|
||||
return appPreferences.value.authPageLayout === 'panel-center';
|
||||
});
|
||||
|
||||
/**
|
||||
* @zh_CN 内容是否已经最大化
|
||||
* 排除 full-content模式
|
||||
*/
|
||||
const contentIsMaximize = computed(() => {
|
||||
const headerIsHidden = preferences.header.hidden;
|
||||
const sidebarIsHidden = preferences.sidebar.hidden;
|
||||
return headerIsHidden && sidebarIsHidden && !isFullContent.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* @zh_CN 是否启用全局搜索快捷键
|
||||
*/
|
||||
@@ -138,17 +152,6 @@ function usePreferences() {
|
||||
return enable && globalPreferences;
|
||||
});
|
||||
|
||||
/**
|
||||
* @zh_CN 内容是否已经最大化
|
||||
* 排除 full-content模式
|
||||
*/
|
||||
const contentIsMaximize = computed(() => {
|
||||
const headerIsHidden = preferences.header.hidden;
|
||||
const sidebarIsHidden = preferences.sidebar.hidden;
|
||||
|
||||
return headerIsHidden && sidebarIsHidden && !isFullContent.value;
|
||||
});
|
||||
|
||||
return {
|
||||
authPanelCenter,
|
||||
authPanelLeft,
|
||||
@@ -163,6 +166,7 @@ function usePreferences() {
|
||||
isFullContent,
|
||||
isHeaderNav,
|
||||
isMixedNav,
|
||||
isMobile,
|
||||
isSideMixedNav,
|
||||
isSideMode,
|
||||
isSideNav,
|
||||
|
Reference in New Issue
Block a user