import { merge } from 'lodash-es';
|
import { AlloyConstant } from '../config/AlloyConstant';
|
import { AlloyCSS } from './AlloyCSS';
|
import { AlloyColor } from './AlloyColor';
|
import { AlloyStorage } from './AlloyStorage';
|
|
export type BrandColor = 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
export type BrandMixLevel = 'default' | 'light-3' | 'light-5' | 'light-7' | 'light-8' | 'light-9' | 'dark-2';
|
|
export type Theme = {
|
colors: {
|
primary?: string;
|
info?: string;
|
warning?: string;
|
success?: string;
|
danger?: string;
|
};
|
};
|
/**
|
* 通过 JS 方式修改主题
|
*/
|
export class AlloyTheme {
|
static isDark = useDark({
|
|
storageKey: `${AlloyStorage.PREFIX}isDark`,
|
});
|
static readonly THEME_KEY = 'theme';
|
static getBrandVarColor(brand: BrandColor, mixLevel: BrandMixLevel = 'default') {
|
const varSuffix = mixLevel === 'default' ? '' : `-${mixLevel}`;
|
return AlloyCSS.getRootPropertyValue(`--${AlloyConstant.NAMESPACE}-color-${brand}${varSuffix}`);
|
}
|
|
static setBrandVarColor(brand: BrandColor, color: string, mixLevel: BrandMixLevel = 'default') {
|
const varSuffix = mixLevel === 'default' ? '' : `-${mixLevel}`;
|
AlloyCSS.setRootPropertyValue(`--${AlloyConstant.NAMESPACE}-color-${brand}${varSuffix}`, color);
|
}
|
static updateBrandColor(name: BrandColor, color: string) {
|
|
|
// 暗黑模式 dark 混合白色,light 混合黑色
|
// 非暗黑模式 dark 混合黑色,light 混合白色
|
const { DEFAULT, dark, light } = AlloyColor.genMixColor(color, AlloyTheme.isDark.value);
|
// 每种主题色由浅到深分为五个阶梯以供开发者使用。
|
|
AlloyTheme.setBrandVarColor(name, DEFAULT);
|
AlloyTheme.setBrandVarColor(name, dark[2], 'dark-2');
|
AlloyTheme.setBrandVarColor(name, light[3], 'light-3');
|
AlloyTheme.setBrandVarColor(name, light[5], 'light-5');
|
AlloyTheme.setBrandVarColor(name, light[7], 'light-7');
|
AlloyTheme.setBrandVarColor(name, light[8], 'light-8');
|
AlloyTheme.setBrandVarColor(name, light[9], 'light-9');
|
|
// elementPlus主题色更新
|
// setStyleProperty(`--el-color-${name}`, DEFAULT);
|
// setStyleProperty(`--el-color-${name}-dark-2`, dark[2]);
|
// setStyleProperty(`--el-color-${name}-light-3`, light[3]);
|
// setStyleProperty(`--el-color-${name}-light-5`, light[5]);
|
// setStyleProperty(`--el-color-${name}-light-7`, light[7]);
|
// setStyleProperty(`--el-color-${name}-light-8`, light[8]);
|
// setStyleProperty(`--el-color-${name}-light-9`, light[9]);
|
}
|
// 更新主题色到css变量
|
static updateThemeColorVar({ colors }: Theme) {
|
// 遍历当前主题色,生成混合色,并更新到css变量(tailwind + elementPlus)
|
for (const brand in colors) {
|
AlloyTheme.updateBrandColor(brand as BrandColor, colors[brand as keyof Theme['colors']] as string);
|
}
|
}
|
|
static getTheme = (): Theme => {
|
const theme = AlloyStorage.get(AlloyTheme.THEME_KEY);
|
return theme ?? defaultThemeConfig;
|
};
|
// 设置主题
|
static setTheme(data: Theme = defaultThemeConfig) {
|
const oldTheme = AlloyTheme.getTheme();
|
|
// 将传入配置与旧的主题合并,以填补缺省的值
|
data = merge(oldTheme, data || {});
|
|
AlloyStorage.set(AlloyTheme.THEME_KEY, data);
|
// 将主题更新到css变量中,使之生效
|
AlloyTheme.updateThemeColorVar(data);
|
}
|
}
|
|
export const defaultThemeConfig: Theme = {
|
colors: {
|
primary: AlloyTheme.getBrandVarColor('primary'),
|
info: AlloyTheme.getBrandVarColor('info'),
|
warning: AlloyTheme.getBrandVarColor('warning'),
|
danger: AlloyTheme.getBrandVarColor('danger'),
|
success: AlloyTheme.getBrandVarColor('success'),
|
},
|
};
|