fix(theme): 深色模式下主色衍生色阶改用暗底混合
applyPrimaryColor 恒定用白色混出 --el-color-primary-light-N,而这些值写的是 documentElement 内联变量,优先级高于 Element Plus 的 html.dark 样式表,导致深色下 light-9 仍是近白(#ecf5ff),plain 按钮(底色=light-9)在深色界面里是一块近白补丁。改为按当前明暗选择混合基色:深色 light-N 混 #141414、dark-2 反向混白 0.2,取值与 EP 暗色主题逐值一致(light-9 #18222b / dark-2 #66b1ff);浅色逻辑不变。
This commit is contained in:
1 parent
5e277eb167
commit
1cdc44c1d0
1 file changed
+26
-13
+26
-13
@@ -4,7 +4,7 @@ import { ref } from 'vue'
|
||||
/** 主题类型:default / light / dark / green / purple / red */
|
||||
export type ThemeMode = 'default' | 'light' | 'dark' | 'green' | 'purple' | 'red'
|
||||
|
||||
/** 主题色板:主色 + Element Plus 衍生色(light-N 为主色混白,dark-2 为主色混黑) */
|
||||
/** 主题色板:主色 + Element Plus 衍生色(浅色 light-N=混白、深色 light-N=混暗底) */
|
||||
interface ThemePalette {
|
||||
/** 是否深色模式(驱动 html.dark) */
|
||||
dark: boolean
|
||||
@@ -94,7 +94,8 @@ const PRIMARY_KEY = 'gerp-primary'
|
||||
|
||||
/**
|
||||
* 十六进制颜色与白/黑按比例混合(对齐 Element Plus light-N/dark-2 派生规则)
|
||||
* light-N:主色混白 N*10%;dark-2:主色混黑 20%
|
||||
* 浅色主题:light-N = 主色混白 N*10%;深色主题:light-N = 主色混暗底 N*10%
|
||||
* dark-2:浅色主题混黑 20%;深色主题反向提亮(混白 20%)
|
||||
*/
|
||||
function mixColor(hex: string, mix: string, weight: number): string {
|
||||
const parse = (c: string): [number, number, number] => {
|
||||
@@ -114,17 +115,29 @@ function mixColor(hex: string, mix: string, weight: number): string {
|
||||
return `#${[r, g, b].map((v) => v.toString(16).padStart(2, '0')).join('')}`
|
||||
}
|
||||
|
||||
/** 把主色应用到 Element Plus CSS 变量(含全部衍生色阶) */
|
||||
function applyPrimaryColor(color: string): void {
|
||||
/** Element Plus 暗色主题 light-N 的混合基色(取 EP dark 变量 --el-bg-color: #141414) */
|
||||
const DARK_MIX_BASE = '#141414'
|
||||
|
||||
/**
|
||||
* 把主色应用到 Element Plus CSS 变量(含全部衍生色阶)。
|
||||
*
|
||||
* 必须以「当前是否深色」区分混合基色:这里写入的是 documentElement 的内联变量,
|
||||
* 优先级高于 Element Plus 的 html.dark 样式表;若两种模式都混白,深色下
|
||||
* light-9 仍是近白色(如 #ecf5ff),plain 按钮底色(= light-9)会变成深色界面里的
|
||||
* 一块近白补丁。深色取值与 EP 暗色主题逐值一致(light-9 #18222b / dark-2 #66b1ff)。
|
||||
*/
|
||||
function applyPrimaryColor(color: string, isDark: boolean): void {
|
||||
const root = document.documentElement
|
||||
const lightMix = isDark ? DARK_MIX_BASE : '#ffffff'
|
||||
const darkMix = isDark ? '#ffffff' : '#000000'
|
||||
const vars: Record<string, string> = {
|
||||
'--el-color-primary': color,
|
||||
'--el-color-primary-light-3': mixColor(color, '#ffffff', 0.3),
|
||||
'--el-color-primary-light-5': mixColor(color, '#ffffff', 0.5),
|
||||
'--el-color-primary-light-7': mixColor(color, '#ffffff', 0.7),
|
||||
'--el-color-primary-light-8': mixColor(color, '#ffffff', 0.8),
|
||||
'--el-color-primary-light-9': mixColor(color, '#ffffff', 0.9),
|
||||
'--el-color-primary-dark-2': mixColor(color, '#000000', 0.2),
|
||||
'--el-color-primary-light-3': mixColor(color, lightMix, 0.3),
|
||||
'--el-color-primary-light-5': mixColor(color, lightMix, 0.5),
|
||||
'--el-color-primary-light-7': mixColor(color, lightMix, 0.7),
|
||||
'--el-color-primary-light-8': mixColor(color, lightMix, 0.8),
|
||||
'--el-color-primary-light-9': mixColor(color, lightMix, 0.9),
|
||||
'--el-color-primary-dark-2': mixColor(color, darkMix, 0.2),
|
||||
}
|
||||
for (const [k, v] of Object.entries(vars)) {
|
||||
root.style.setProperty(k, v)
|
||||
@@ -153,7 +166,7 @@ export const useAppStore = defineStore('app', () => {
|
||||
root.classList.toggle('dark', cfg.dark)
|
||||
// vxe-table 暗色主题([data-vxe-ui-theme="dark"] 触发其内置暗色变量)
|
||||
root.setAttribute('data-vxe-ui-theme', cfg.dark ? 'dark' : 'light')
|
||||
applyPrimaryColor(customPrimary.value ?? cfg.primary)
|
||||
applyPrimaryColor(customPrimary.value ?? cfg.primary, cfg.dark)
|
||||
localStorage.setItem(THEME_KEY, value)
|
||||
}
|
||||
|
||||
@@ -164,7 +177,7 @@ export const useAppStore = defineStore('app', () => {
|
||||
function setCustomColor(color: string | null): void {
|
||||
customPrimary.value = color
|
||||
const cfg = THEME_CONFIGS[theme.value] ?? THEME_CONFIGS.default
|
||||
applyPrimaryColor(color ?? cfg.primary)
|
||||
applyPrimaryColor(color ?? cfg.primary, cfg.dark)
|
||||
if (color) localStorage.setItem(PRIMARY_KEY, color)
|
||||
else localStorage.removeItem(PRIMARY_KEY)
|
||||
}
|
||||
@@ -179,7 +192,7 @@ export const useAppStore = defineStore('app', () => {
|
||||
const root = document.documentElement
|
||||
root.classList.toggle('dark', cfg.dark)
|
||||
root.setAttribute('data-vxe-ui-theme', cfg.dark ? 'dark' : 'light')
|
||||
applyPrimaryColor(customPrimary.value ?? cfg.primary)
|
||||
applyPrimaryColor(customPrimary.value ?? cfg.primary, cfg.dark)
|
||||
}
|
||||
|
||||
/** 顶栏快捷切换:浅色主题 ↔ 深色主题(保持当前配色) */
|
||||
|
||||
Reference in new issue
Block a user