提交新版本
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`defaultPreferences immutability test > should not modify the config object 1`] = `
|
||||
{
|
||||
"app": {
|
||||
"accessMode": "frontend",
|
||||
"authPageLayout": "panel-right",
|
||||
"checkUpdatesInterval": 1,
|
||||
"colorGrayMode": false,
|
||||
"colorWeakMode": false,
|
||||
"compact": false,
|
||||
"contentCompact": "wide",
|
||||
"contentCompactWidth": 1200,
|
||||
"contentPadding": 0,
|
||||
"contentPaddingBottom": 0,
|
||||
"contentPaddingLeft": 0,
|
||||
"contentPaddingRight": 0,
|
||||
"contentPaddingTop": 0,
|
||||
"defaultAvatar": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp",
|
||||
"defaultHomePath": "/analytics",
|
||||
"dynamicTitle": true,
|
||||
"enableCheckUpdates": true,
|
||||
"enablePreferences": true,
|
||||
"enableRefreshToken": false,
|
||||
"enableStickyPreferencesNavigationBar": true,
|
||||
"isMobile": false,
|
||||
"layout": "sidebar-nav",
|
||||
"locale": "zh-CN",
|
||||
"loginExpiredMode": "page",
|
||||
"name": "Vben Admin",
|
||||
"preferencesButtonPosition": "auto",
|
||||
"watermark": false,
|
||||
"watermarkContent": "",
|
||||
"zIndex": 200,
|
||||
},
|
||||
"breadcrumb": {
|
||||
"enable": true,
|
||||
"hideOnlyOne": false,
|
||||
"showHome": false,
|
||||
"showIcon": true,
|
||||
"styleType": "normal",
|
||||
},
|
||||
"copyright": {
|
||||
"companyName": "Vben",
|
||||
"companySiteLink": "https://www.vben.pro",
|
||||
"date": "2024",
|
||||
"enable": true,
|
||||
"icp": "",
|
||||
"icpLink": "",
|
||||
"settingShow": true,
|
||||
},
|
||||
"footer": {
|
||||
"enable": false,
|
||||
"fixed": false,
|
||||
"height": 32,
|
||||
},
|
||||
"header": {
|
||||
"enable": true,
|
||||
"height": 50,
|
||||
"hidden": false,
|
||||
"menuAlign": "start",
|
||||
"mode": "fixed",
|
||||
},
|
||||
"logo": {
|
||||
"enable": true,
|
||||
"fit": "contain",
|
||||
"source": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp",
|
||||
},
|
||||
"navigation": {
|
||||
"accordion": true,
|
||||
"split": true,
|
||||
"styleType": "rounded",
|
||||
},
|
||||
"shortcutKeys": {
|
||||
"enable": true,
|
||||
"globalLockScreen": true,
|
||||
"globalLogout": true,
|
||||
"globalPreferences": true,
|
||||
"globalSearch": true,
|
||||
},
|
||||
"sidebar": {
|
||||
"autoActivateChild": false,
|
||||
"collapseWidth": 60,
|
||||
"collapsed": false,
|
||||
"collapsedButton": true,
|
||||
"collapsedShowTitle": false,
|
||||
"enable": true,
|
||||
"expandOnHover": true,
|
||||
"extraCollapse": false,
|
||||
"extraCollapsedWidth": 60,
|
||||
"fixedButton": true,
|
||||
"hidden": false,
|
||||
"mixedWidth": 80,
|
||||
"width": 224,
|
||||
},
|
||||
"tabbar": {
|
||||
"draggable": true,
|
||||
"enable": true,
|
||||
"height": 38,
|
||||
"keepAlive": true,
|
||||
"maxCount": 0,
|
||||
"middleClickToClose": false,
|
||||
"persist": true,
|
||||
"showIcon": true,
|
||||
"showMaximize": true,
|
||||
"showMore": true,
|
||||
"styleType": "chrome",
|
||||
"wheelable": true,
|
||||
},
|
||||
"theme": {
|
||||
"builtinType": "default",
|
||||
"colorDestructive": "hsl(348 100% 61%)",
|
||||
"colorPrimary": "hsl(212 100% 45%)",
|
||||
"colorSuccess": "hsl(144 57% 58%)",
|
||||
"colorWarning": "hsl(42 84% 61%)",
|
||||
"mode": "dark",
|
||||
"radius": "0.5",
|
||||
"semiDarkHeader": false,
|
||||
"semiDarkSidebar": false,
|
||||
},
|
||||
"transition": {
|
||||
"enable": true,
|
||||
"loading": true,
|
||||
"name": "fade-slide",
|
||||
"progress": true,
|
||||
},
|
||||
"widget": {
|
||||
"fullscreen": true,
|
||||
"globalSearch": true,
|
||||
"languageToggle": true,
|
||||
"lockScreen": true,
|
||||
"notification": true,
|
||||
"refresh": true,
|
||||
"sidebarToggle": true,
|
||||
"themeToggle": true,
|
||||
"timezone": true,
|
||||
},
|
||||
}
|
||||
`;
|
||||
37
packages/@core/preferences/package.json
Normal file
37
packages/@core/preferences/package.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@vben-core/preferences",
|
||||
"version": "5.5.9",
|
||||
"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/@core/preferences"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"#build": "pnpm unbuild"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
],
|
||||
"sideEffects": [
|
||||
"**/*.css"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"development": "./src/index.ts",
|
||||
"default": "./src/index.ts",
|
||||
"#default": "./dist/index.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "catalog:",
|
||||
"vue": "catalog:"
|
||||
}
|
||||
}
|
||||
141
packages/@core/preferences/src/config.ts
Normal file
141
packages/@core/preferences/src/config.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import type { Preferences } from './types';
|
||||
|
||||
const defaultPreferences: Preferences = {
|
||||
app: {
|
||||
accessMode: 'frontend',
|
||||
authPageLayout: 'panel-right',
|
||||
checkUpdatesInterval: 1,
|
||||
colorGrayMode: false,
|
||||
colorWeakMode: false,
|
||||
compact: false,
|
||||
contentCompact: 'wide',
|
||||
contentCompactWidth: 1200,
|
||||
contentPadding: 0,
|
||||
contentPaddingBottom: 0,
|
||||
contentPaddingLeft: 0,
|
||||
contentPaddingRight: 0,
|
||||
contentPaddingTop: 0,
|
||||
defaultAvatar:
|
||||
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/avatar-v1.webp',
|
||||
defaultHomePath: '/analytics',
|
||||
dynamicTitle: true,
|
||||
enableCheckUpdates: true,
|
||||
enablePreferences: true,
|
||||
enableRefreshToken: false,
|
||||
enableStickyPreferencesNavigationBar: true,
|
||||
isMobile: false,
|
||||
layout: 'sidebar-nav',
|
||||
locale: 'zh-CN',
|
||||
loginExpiredMode: 'page',
|
||||
name: 'Vben Admin',
|
||||
preferencesButtonPosition: 'auto',
|
||||
watermark: false,
|
||||
watermarkContent: '',
|
||||
zIndex: 200,
|
||||
},
|
||||
breadcrumb: {
|
||||
enable: true,
|
||||
hideOnlyOne: false,
|
||||
showHome: false,
|
||||
showIcon: true,
|
||||
styleType: 'normal',
|
||||
},
|
||||
copyright: {
|
||||
companyName: 'Vben',
|
||||
companySiteLink: 'https://www.vben.pro',
|
||||
date: '2024',
|
||||
enable: true,
|
||||
icp: '',
|
||||
icpLink: '',
|
||||
settingShow: true,
|
||||
},
|
||||
footer: {
|
||||
enable: false,
|
||||
fixed: false,
|
||||
height: 32,
|
||||
},
|
||||
header: {
|
||||
enable: true,
|
||||
height: 50,
|
||||
hidden: false,
|
||||
menuAlign: 'start',
|
||||
mode: 'fixed',
|
||||
},
|
||||
|
||||
logo: {
|
||||
enable: true,
|
||||
fit: 'contain',
|
||||
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
|
||||
},
|
||||
navigation: {
|
||||
accordion: true,
|
||||
split: true,
|
||||
styleType: 'rounded',
|
||||
},
|
||||
shortcutKeys: {
|
||||
enable: true,
|
||||
globalLockScreen: true,
|
||||
globalLogout: true,
|
||||
globalPreferences: true,
|
||||
globalSearch: true,
|
||||
},
|
||||
sidebar: {
|
||||
autoActivateChild: false,
|
||||
collapsed: false,
|
||||
collapsedButton: true,
|
||||
collapsedShowTitle: false,
|
||||
collapseWidth: 60,
|
||||
enable: true,
|
||||
expandOnHover: true,
|
||||
extraCollapse: false,
|
||||
extraCollapsedWidth: 60,
|
||||
fixedButton: true,
|
||||
hidden: false,
|
||||
mixedWidth: 80,
|
||||
width: 224,
|
||||
},
|
||||
tabbar: {
|
||||
draggable: true,
|
||||
enable: true,
|
||||
height: 38,
|
||||
keepAlive: true,
|
||||
maxCount: 0,
|
||||
middleClickToClose: false,
|
||||
persist: true,
|
||||
showIcon: true,
|
||||
showMaximize: true,
|
||||
showMore: true,
|
||||
styleType: 'chrome',
|
||||
wheelable: true,
|
||||
},
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
colorWarning: 'hsl(42 84% 61%)',
|
||||
mode: 'dark',
|
||||
radius: '0.5',
|
||||
semiDarkHeader: false,
|
||||
semiDarkSidebar: false,
|
||||
},
|
||||
transition: {
|
||||
enable: true,
|
||||
loading: true,
|
||||
name: 'fade-slide',
|
||||
progress: true,
|
||||
},
|
||||
widget: {
|
||||
fullscreen: true,
|
||||
globalSearch: true,
|
||||
languageToggle: true,
|
||||
lockScreen: true,
|
||||
notification: true,
|
||||
refresh: true,
|
||||
sidebarToggle: true,
|
||||
themeToggle: true,
|
||||
timezone: true,
|
||||
},
|
||||
};
|
||||
|
||||
export { defaultPreferences };
|
||||
119
packages/@core/preferences/src/constants.ts
Normal file
119
packages/@core/preferences/src/constants.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import type { BuiltinThemeType, TimezoneOption } from '@vben-core/typings';
|
||||
|
||||
interface BuiltinThemePreset {
|
||||
color: string;
|
||||
darkPrimaryColor?: string;
|
||||
primaryColor?: string;
|
||||
type: BuiltinThemeType;
|
||||
}
|
||||
|
||||
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
||||
{
|
||||
color: 'hsl(212 100% 45%)',
|
||||
type: 'default',
|
||||
},
|
||||
{
|
||||
color: 'hsl(245 82% 67%)',
|
||||
type: 'violet',
|
||||
},
|
||||
{
|
||||
color: 'hsl(347 77% 60%)',
|
||||
type: 'pink',
|
||||
},
|
||||
{
|
||||
color: 'hsl(42 84% 61%)',
|
||||
type: 'yellow',
|
||||
},
|
||||
{
|
||||
color: 'hsl(231 98% 65%)',
|
||||
type: 'sky-blue',
|
||||
},
|
||||
{
|
||||
color: 'hsl(161 90% 43%)',
|
||||
type: 'green',
|
||||
},
|
||||
{
|
||||
color: 'hsl(240 5% 26%)',
|
||||
darkPrimaryColor: 'hsl(0 0% 98%)',
|
||||
primaryColor: 'hsl(240 5.9% 10%)',
|
||||
type: 'zinc',
|
||||
},
|
||||
|
||||
{
|
||||
color: 'hsl(181 84% 32%)',
|
||||
type: 'deep-green',
|
||||
},
|
||||
|
||||
{
|
||||
color: 'hsl(211 91% 39%)',
|
||||
type: 'deep-blue',
|
||||
},
|
||||
{
|
||||
color: 'hsl(18 89% 40%)',
|
||||
type: 'orange',
|
||||
},
|
||||
{
|
||||
color: 'hsl(0 75% 42%)',
|
||||
type: 'rose',
|
||||
},
|
||||
|
||||
{
|
||||
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',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 时区选项
|
||||
*/
|
||||
const DEFAULT_TIME_ZONE_OPTIONS: TimezoneOption[] = [
|
||||
{
|
||||
offset: -5,
|
||||
timezone: 'America/New_York',
|
||||
label: 'America/New_York(GMT-5)',
|
||||
},
|
||||
{
|
||||
offset: 0,
|
||||
timezone: 'Europe/London',
|
||||
label: 'Europe/London(GMT0)',
|
||||
},
|
||||
{
|
||||
offset: 8,
|
||||
timezone: 'Asia/Shanghai',
|
||||
label: 'Asia/Shanghai(GMT+8)',
|
||||
},
|
||||
{
|
||||
offset: 9,
|
||||
timezone: 'Asia/Tokyo',
|
||||
label: 'Asia/Tokyo(GMT+9)',
|
||||
},
|
||||
{
|
||||
offset: 9,
|
||||
timezone: 'Asia/Seoul',
|
||||
label: 'Asia/Seoul(GMT+9)',
|
||||
},
|
||||
];
|
||||
|
||||
export const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 7);
|
||||
|
||||
export { BUILT_IN_THEME_PRESETS, DEFAULT_TIME_ZONE_OPTIONS };
|
||||
|
||||
export type { BuiltinThemePreset };
|
||||
231
packages/@core/preferences/src/preferences.ts
Normal file
231
packages/@core/preferences/src/preferences.ts
Normal file
@@ -0,0 +1,231 @@
|
||||
import type { DeepPartial } from '@vben-core/typings';
|
||||
|
||||
import type { InitialOptions, Preferences } from './types';
|
||||
|
||||
import { markRaw, reactive, readonly, watch } from 'vue';
|
||||
|
||||
import { StorageManager } from '@vben-core/shared/cache';
|
||||
import { isMacOs, merge } from '@vben-core/shared/utils';
|
||||
|
||||
import {
|
||||
breakpointsTailwind,
|
||||
useBreakpoints,
|
||||
useDebounceFn,
|
||||
} from '@vueuse/core';
|
||||
|
||||
import { defaultPreferences } from './config';
|
||||
import { updateCSSVariables } from './update-css-variables';
|
||||
|
||||
const STORAGE_KEY = 'preferences';
|
||||
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
|
||||
const STORAGE_KEY_THEME = `${STORAGE_KEY}-theme`;
|
||||
|
||||
class PreferenceManager {
|
||||
private cache: null | StorageManager = null;
|
||||
// private flattenedState: Flatten<Preferences>;
|
||||
private initialPreferences: Preferences = defaultPreferences;
|
||||
private isInitialized: boolean = false;
|
||||
private savePreferences: (preference: Preferences) => void;
|
||||
private state: Preferences = reactive<Preferences>({
|
||||
...this.loadPreferences(),
|
||||
});
|
||||
constructor() {
|
||||
this.cache = new StorageManager();
|
||||
|
||||
// 避免频繁的操作缓存
|
||||
this.savePreferences = useDebounceFn(
|
||||
(preference: Preferences) => this._savePreferences(preference),
|
||||
150,
|
||||
);
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
|
||||
this.cache?.removeItem(key);
|
||||
});
|
||||
}
|
||||
|
||||
public getInitialPreferences() {
|
||||
return this.initialPreferences;
|
||||
}
|
||||
|
||||
public getPreferences() {
|
||||
return readonly(this.state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖偏好设置
|
||||
* overrides 要覆盖的偏好设置
|
||||
* namespace 命名空间
|
||||
*/
|
||||
public async initPreferences({ namespace, overrides }: InitialOptions) {
|
||||
// 是否初始化过
|
||||
if (this.isInitialized) {
|
||||
return;
|
||||
}
|
||||
// 初始化存储管理器
|
||||
this.cache = new StorageManager({ prefix: namespace });
|
||||
// 合并初始偏好设置
|
||||
this.initialPreferences = merge({}, overrides, defaultPreferences);
|
||||
|
||||
// 加载并合并当前存储的偏好设置
|
||||
const mergedPreference = merge(
|
||||
{},
|
||||
// overrides,
|
||||
this.loadCachedPreferences() || {},
|
||||
this.initialPreferences,
|
||||
);
|
||||
|
||||
// 更新偏好设置
|
||||
this.updatePreferences(mergedPreference);
|
||||
|
||||
this.setupWatcher();
|
||||
|
||||
this.initPlatform();
|
||||
// 标记为已初始化
|
||||
this.isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置偏好设置
|
||||
* 偏好设置将被重置为初始值,并从 localStorage 中移除。
|
||||
*
|
||||
* @example
|
||||
* 假设 initialPreferences 为 { theme: 'light', language: 'en' }
|
||||
* 当前 state 为 { theme: 'dark', language: 'fr' }
|
||||
* this.resetPreferences();
|
||||
* 调用后,state 将被重置为 { theme: 'light', language: 'en' }
|
||||
* 并且 localStorage 中的对应项将被移除
|
||||
*/
|
||||
resetPreferences() {
|
||||
// 将状态重置为初始偏好设置
|
||||
Object.assign(this.state, this.initialPreferences);
|
||||
// 保存重置后的偏好设置
|
||||
this.savePreferences(this.state);
|
||||
// 从存储中移除偏好设置项
|
||||
[STORAGE_KEY, STORAGE_KEY_THEME, STORAGE_KEY_LOCALE].forEach((key) => {
|
||||
this.cache?.removeItem(key);
|
||||
});
|
||||
this.updatePreferences(this.state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新偏好设置
|
||||
* @param updates - 要更新的偏好设置
|
||||
*/
|
||||
public updatePreferences(updates: DeepPartial<Preferences>) {
|
||||
const mergedState = merge({}, updates, markRaw(this.state));
|
||||
|
||||
Object.assign(this.state, mergedState);
|
||||
|
||||
// 根据更新的键值执行相应的操作
|
||||
this.handleUpdates(updates);
|
||||
this.savePreferences(this.state);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存偏好设置
|
||||
* @param {Preferences} preference - 需要保存的偏好设置
|
||||
*/
|
||||
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.theme.mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理更新的键值
|
||||
* 根据更新的键值执行相应的操作。
|
||||
* @param {DeepPartial<Preferences>} updates - 部分更新的偏好设置
|
||||
*/
|
||||
private handleUpdates(updates: DeepPartial<Preferences>) {
|
||||
const themeUpdates = updates.theme || {};
|
||||
const appUpdates = updates.app || {};
|
||||
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
|
||||
updateCSSVariables(this.state);
|
||||
}
|
||||
|
||||
if (
|
||||
Reflect.has(appUpdates, 'colorGrayMode') ||
|
||||
Reflect.has(appUpdates, 'colorWeakMode')
|
||||
) {
|
||||
this.updateColorMode(this.state);
|
||||
}
|
||||
}
|
||||
|
||||
private initPlatform() {
|
||||
const dom = document.documentElement;
|
||||
dom.dataset.platform = isMacOs() ? 'macOs' : 'window';
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中加载偏好设置。如果缓存中没有找到对应的偏好设置,则返回默认偏好设置。
|
||||
*/
|
||||
private loadCachedPreferences() {
|
||||
return this.cache?.getItem<Preferences>(STORAGE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载偏好设置
|
||||
* @returns {Preferences} 加载的偏好设置
|
||||
*/
|
||||
private loadPreferences(): Preferences {
|
||||
return this.loadCachedPreferences() || { ...defaultPreferences };
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听状态和系统偏好设置的变化。
|
||||
*/
|
||||
private setupWatcher() {
|
||||
if (this.isInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 监听断点,判断是否移动端
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||
const isMobile = breakpoints.smaller('md');
|
||||
watch(
|
||||
() => isMobile.value,
|
||||
(val) => {
|
||||
this.updatePreferences({
|
||||
app: { isMobile: val },
|
||||
});
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// 监听系统主题偏好设置变化
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', ({ matches: isDark }) => {
|
||||
// 如果偏好设置中主题模式为auto,则跟随系统更新
|
||||
if (this.state.theme.mode === 'auto') {
|
||||
this.updatePreferences({
|
||||
theme: { mode: isDark ? 'dark' : 'light' },
|
||||
});
|
||||
// 恢复为auto模式
|
||||
this.updatePreferences({
|
||||
theme: { mode: 'auto' },
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新页面颜色模式(灰色、色弱)
|
||||
* @param preference
|
||||
*/
|
||||
private updateColorMode(preference: Preferences) {
|
||||
if (preference.app) {
|
||||
const { colorGrayMode, colorWeakMode } = preference.app;
|
||||
const dom = document.documentElement;
|
||||
const COLOR_WEAK = 'invert-mode';
|
||||
const COLOR_GRAY = 'grayscale-mode';
|
||||
dom.classList.toggle(COLOR_WEAK, colorWeakMode);
|
||||
dom.classList.toggle(COLOR_GRAY, colorGrayMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const preferencesManager = new PreferenceManager();
|
||||
export { PreferenceManager, preferencesManager };
|
||||
336
packages/@core/preferences/src/types.ts
Normal file
336
packages/@core/preferences/src/types.ts
Normal file
@@ -0,0 +1,336 @@
|
||||
import type {
|
||||
AccessModeType,
|
||||
AuthPageLayoutType,
|
||||
BreadcrumbStyleType,
|
||||
BuiltinThemeType,
|
||||
ContentCompactType,
|
||||
DeepPartial,
|
||||
LayoutHeaderMenuAlignType,
|
||||
LayoutHeaderModeType,
|
||||
LayoutType,
|
||||
LoginExpiredModeType,
|
||||
NavigationStyleType,
|
||||
PageTransitionType,
|
||||
PreferencesButtonPositionType,
|
||||
TabsStyleType,
|
||||
ThemeModeType,
|
||||
} from '@vben-core/typings';
|
||||
|
||||
type SupportedLanguagesType = 'en-US' | 'zh-CN';
|
||||
|
||||
interface AppPreferences {
|
||||
/** 权限模式 */
|
||||
accessMode: AccessModeType;
|
||||
/** 登录注册页面布局 */
|
||||
authPageLayout: AuthPageLayoutType;
|
||||
/** 检查更新轮询时间 */
|
||||
checkUpdatesInterval: number;
|
||||
/** 是否开启灰色模式 */
|
||||
colorGrayMode: boolean;
|
||||
/** 是否开启色弱模式 */
|
||||
colorWeakMode: boolean;
|
||||
/** 是否开启紧凑模式 */
|
||||
compact: boolean;
|
||||
/** 是否开启内容紧凑模式 */
|
||||
contentCompact: ContentCompactType;
|
||||
/** 内容紧凑宽度 */
|
||||
contentCompactWidth: number;
|
||||
/** 内容内边距 */
|
||||
contentPadding: number;
|
||||
/** 内容底部内边距 */
|
||||
contentPaddingBottom: number;
|
||||
/** 内容左侧内边距 */
|
||||
contentPaddingLeft: number;
|
||||
/** 内容右侧内边距 */
|
||||
contentPaddingRight: number;
|
||||
/** 内容顶部内边距 */
|
||||
contentPaddingTop: number;
|
||||
// /** 应用默认头像 */
|
||||
defaultAvatar: string;
|
||||
/** 默认首页地址 */
|
||||
defaultHomePath: string;
|
||||
// /** 开启动态标题 */
|
||||
dynamicTitle: boolean;
|
||||
/** 是否开启检查更新 */
|
||||
enableCheckUpdates: boolean;
|
||||
/** 是否显示偏好设置 */
|
||||
enablePreferences: boolean;
|
||||
/**
|
||||
* @zh_CN 是否开启refreshToken
|
||||
*/
|
||||
enableRefreshToken: boolean;
|
||||
/**
|
||||
* @zh_CN 是否开启首选项导航栏吸顶效果
|
||||
*/
|
||||
enableStickyPreferencesNavigationBar: boolean;
|
||||
/** 是否移动端 */
|
||||
isMobile: boolean;
|
||||
/** 布局方式 */
|
||||
layout: LayoutType;
|
||||
/** 支持的语言 */
|
||||
locale: SupportedLanguagesType;
|
||||
/** 登录过期模式 */
|
||||
loginExpiredMode: LoginExpiredModeType;
|
||||
/** 应用名 */
|
||||
name: string;
|
||||
/** 偏好设置按钮位置 */
|
||||
preferencesButtonPosition: PreferencesButtonPositionType;
|
||||
/**
|
||||
* @zh_CN 是否开启水印
|
||||
*/
|
||||
watermark: boolean;
|
||||
/**
|
||||
* @zh_CN 水印文案
|
||||
*/
|
||||
watermarkContent: string;
|
||||
/** z-index */
|
||||
zIndex: number;
|
||||
}
|
||||
|
||||
interface BreadcrumbPreferences {
|
||||
/** 面包屑是否启用 */
|
||||
enable: boolean;
|
||||
/** 面包屑是否只有一个时隐藏 */
|
||||
hideOnlyOne: boolean;
|
||||
/** 面包屑首页图标是否可见 */
|
||||
showHome: boolean;
|
||||
/** 面包屑图标是否可见 */
|
||||
showIcon: boolean;
|
||||
/** 面包屑风格 */
|
||||
styleType: BreadcrumbStyleType;
|
||||
}
|
||||
|
||||
interface CopyrightPreferences {
|
||||
/** 版权公司名 */
|
||||
companyName: string;
|
||||
/** 版权公司名链接 */
|
||||
companySiteLink: string;
|
||||
/** 版权日期 */
|
||||
date: string;
|
||||
/** 版权是否可见 */
|
||||
enable: boolean;
|
||||
/** 备案号 */
|
||||
icp: string;
|
||||
/** 备案号链接 */
|
||||
icpLink: string;
|
||||
/** 设置面板是否显示*/
|
||||
settingShow?: boolean;
|
||||
}
|
||||
|
||||
interface FooterPreferences {
|
||||
/** 底栏是否可见 */
|
||||
enable: boolean;
|
||||
/** 底栏是否固定 */
|
||||
fixed: boolean;
|
||||
/** 底栏高度 */
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface HeaderPreferences {
|
||||
/** 顶栏是否启用 */
|
||||
enable: boolean;
|
||||
/** 顶栏高度 */
|
||||
height: number;
|
||||
/** 顶栏是否隐藏,css-隐藏 */
|
||||
hidden: boolean;
|
||||
/** 顶栏菜单位置 */
|
||||
menuAlign: LayoutHeaderMenuAlignType;
|
||||
/** header显示模式 */
|
||||
mode: LayoutHeaderModeType;
|
||||
}
|
||||
|
||||
interface LogoPreferences {
|
||||
/** logo是否可见 */
|
||||
enable: boolean;
|
||||
/** logo图片适应方式 */
|
||||
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
||||
/** logo地址 */
|
||||
source: string;
|
||||
/** 暗色主题logo地址 (可选,若不设置则使用 source) */
|
||||
sourceDark?: string;
|
||||
}
|
||||
|
||||
interface NavigationPreferences {
|
||||
/** 导航菜单手风琴模式 */
|
||||
accordion: boolean;
|
||||
/** 导航菜单是否切割,只在 layout=mixed-nav 生效 */
|
||||
split: boolean;
|
||||
/** 导航菜单风格 */
|
||||
styleType: NavigationStyleType;
|
||||
}
|
||||
|
||||
interface SidebarPreferences {
|
||||
/** 点击目录时自动激活子菜单 */
|
||||
autoActivateChild: boolean;
|
||||
/** 侧边栏是否折叠 */
|
||||
collapsed: boolean;
|
||||
/** 侧边栏折叠按钮是否可见 */
|
||||
collapsedButton: boolean;
|
||||
/** 侧边栏折叠时,是否显示title */
|
||||
collapsedShowTitle: boolean;
|
||||
/** 侧边栏折叠宽度 */
|
||||
collapseWidth: number;
|
||||
/** 侧边栏是否可见 */
|
||||
enable: boolean;
|
||||
/** 菜单自动展开状态 */
|
||||
expandOnHover: boolean;
|
||||
/** 侧边栏扩展区域是否折叠 */
|
||||
extraCollapse: boolean;
|
||||
/** 侧边栏扩展区域折叠宽度 */
|
||||
extraCollapsedWidth: number;
|
||||
/** 侧边栏固定按钮是否可见 */
|
||||
fixedButton: boolean;
|
||||
/** 侧边栏是否隐藏 - css */
|
||||
hidden: boolean;
|
||||
/** 混合侧边栏宽度 */
|
||||
mixedWidth: number;
|
||||
/** 侧边栏宽度 */
|
||||
width: number;
|
||||
}
|
||||
|
||||
interface ShortcutKeyPreferences {
|
||||
/** 是否启用快捷键-全局 */
|
||||
enable: boolean;
|
||||
/** 是否启用全局锁屏快捷键 */
|
||||
globalLockScreen: boolean;
|
||||
/** 是否启用全局注销快捷键 */
|
||||
globalLogout: boolean;
|
||||
/** 是否启用全局偏好设置快捷键 */
|
||||
globalPreferences: boolean;
|
||||
/** 是否启用全局搜索快捷键 */
|
||||
globalSearch: boolean;
|
||||
}
|
||||
|
||||
interface TabbarPreferences {
|
||||
/** 是否开启多标签页拖拽 */
|
||||
draggable: boolean;
|
||||
/** 是否开启多标签页 */
|
||||
enable: boolean;
|
||||
/** 标签页高度 */
|
||||
height: number;
|
||||
/** 开启标签页缓存功能 */
|
||||
keepAlive: boolean;
|
||||
/** 限制最大数量 */
|
||||
maxCount: number;
|
||||
/** 是否点击中键时关闭标签 */
|
||||
middleClickToClose: boolean;
|
||||
/** 是否持久化标签 */
|
||||
persist: boolean;
|
||||
/** 是否开启多标签页图标 */
|
||||
showIcon: boolean;
|
||||
/** 显示最大化按钮 */
|
||||
showMaximize: boolean;
|
||||
/** 显示更多按钮 */
|
||||
showMore: boolean;
|
||||
/** 标签页风格 */
|
||||
styleType: TabsStyleType;
|
||||
/** 是否开启鼠标滚轮响应 */
|
||||
wheelable: boolean;
|
||||
}
|
||||
|
||||
interface ThemePreferences {
|
||||
/** 内置主题名 */
|
||||
builtinType: BuiltinThemeType;
|
||||
/** 错误色 */
|
||||
colorDestructive: string;
|
||||
/** 主题色 */
|
||||
colorPrimary: string;
|
||||
/** 成功色 */
|
||||
colorSuccess: string;
|
||||
/** 警告色 */
|
||||
colorWarning: string;
|
||||
/** 当前主题 */
|
||||
mode: ThemeModeType;
|
||||
/** 圆角 */
|
||||
radius: string;
|
||||
/** 是否开启半深色header(只在theme='light'时生效) */
|
||||
semiDarkHeader: boolean;
|
||||
/** 是否开启半深色菜单(只在theme='light'时生效) */
|
||||
semiDarkSidebar: boolean;
|
||||
}
|
||||
|
||||
interface TransitionPreferences {
|
||||
/** 页面切换动画是否启用 */
|
||||
enable: boolean;
|
||||
// /** 是否开启页面加载loading */
|
||||
loading: boolean;
|
||||
/** 页面切换动画 */
|
||||
name: PageTransitionType | string;
|
||||
/** 是否开启页面加载进度动画 */
|
||||
progress: boolean;
|
||||
}
|
||||
|
||||
interface WidgetPreferences {
|
||||
/** 是否启用全屏部件 */
|
||||
fullscreen: boolean;
|
||||
/** 是否启用全局搜索部件 */
|
||||
globalSearch: boolean;
|
||||
/** 是否启用语言切换部件 */
|
||||
languageToggle: boolean;
|
||||
/** 是否开启锁屏功能 */
|
||||
lockScreen: boolean;
|
||||
/** 是否显示通知部件 */
|
||||
notification: boolean;
|
||||
/** 显示刷新按钮 */
|
||||
refresh: boolean;
|
||||
/** 是否显示侧边栏显示/隐藏部件 */
|
||||
sidebarToggle: boolean;
|
||||
/** 是否显示主题切换部件 */
|
||||
themeToggle: boolean;
|
||||
/** 是否显示时区部件 */
|
||||
timezone: boolean;
|
||||
}
|
||||
|
||||
interface Preferences {
|
||||
/** 全局配置 */
|
||||
app: AppPreferences;
|
||||
/** 顶栏配置 */
|
||||
breadcrumb: BreadcrumbPreferences;
|
||||
/** 版权配置 */
|
||||
copyright: CopyrightPreferences;
|
||||
/** 底栏配置 */
|
||||
footer: FooterPreferences;
|
||||
/** 面包屑配置 */
|
||||
header: HeaderPreferences;
|
||||
/** logo配置 */
|
||||
logo: LogoPreferences;
|
||||
/** 导航配置 */
|
||||
navigation: NavigationPreferences;
|
||||
/** 快捷键配置 */
|
||||
shortcutKeys: ShortcutKeyPreferences;
|
||||
/** 侧边栏配置 */
|
||||
sidebar: SidebarPreferences;
|
||||
/** 标签页配置 */
|
||||
tabbar: TabbarPreferences;
|
||||
/** 主题配置 */
|
||||
theme: ThemePreferences;
|
||||
/** 动画配置 */
|
||||
transition: TransitionPreferences;
|
||||
/** 功能配置 */
|
||||
widget: WidgetPreferences;
|
||||
}
|
||||
|
||||
type PreferencesKeys = keyof Preferences;
|
||||
|
||||
interface InitialOptions {
|
||||
namespace: string;
|
||||
overrides?: DeepPartial<Preferences>;
|
||||
}
|
||||
export type {
|
||||
AppPreferences,
|
||||
BreadcrumbPreferences,
|
||||
FooterPreferences,
|
||||
HeaderPreferences,
|
||||
InitialOptions,
|
||||
LogoPreferences,
|
||||
NavigationPreferences,
|
||||
Preferences,
|
||||
PreferencesKeys,
|
||||
ShortcutKeyPreferences,
|
||||
SidebarPreferences,
|
||||
SupportedLanguagesType,
|
||||
TabbarPreferences,
|
||||
ThemePreferences,
|
||||
TransitionPreferences,
|
||||
WidgetPreferences,
|
||||
};
|
||||
Reference in New Issue
Block a user