fix: center header logo and fix theme color variants in dark mode

- Logo 区内容居中
- 主题色改为注入 <style> 生成明/暗两套派生变量:暗黑下 light-N 混黑、dark-2 混白,避免侧栏/按钮高亮在暗黑模式下变近白

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
liuyun 2026-10-11 00:43:31 +08:00
parent 99650949c0
commit 82aa944d48
3 changed files with 54 additions and 29 deletions

View File

@ -1,11 +1,7 @@
<template> <template>
<header class="ty-header" :class="{ 'is-fixed': fixed }"> <header class="ty-header" :class="{ 'is-fixed': fixed }">
<div class="ty-header__left"> <div class="ty-header__left">
<div <div class="ty-header__logo" :style="logoWidth != null ? { width: `${logoWidth}px` } : undefined">
class="ty-header__logo"
:class="{ 'is-icon': !showTitle }"
:style="logoWidth != null ? { width: `${logoWidth}px` } : undefined"
>
<img v-if="logo" class="ty-header__logo-img" :src="logo" alt="logo" /> <img v-if="logo" class="ty-header__logo-img" :src="logo" alt="logo" />
<span v-if="showTitle" class="ty-header__title">{{ title }}</span> <span v-if="showTitle" class="ty-header__title">{{ title }}</span>
</div> </div>
@ -172,18 +168,14 @@ function onUserCommand(command: string): void {
&__logo { &__logo {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
gap: 8px; gap: 8px;
flex-shrink: 0; flex-shrink: 0;
overflow: hidden; overflow: hidden;
height: var(--ty-header-height, 56px); height: var(--ty-header-height, 56px);
padding: 0 12px; padding: 0 8px;
background: var(--wm-bg-color-base); background: var(--wm-bg-color-base);
border-right: 1px solid var(--wm-border-color-light); border-right: 1px solid var(--wm-border-color-light);
&.is-icon {
justify-content: center;
gap: 0;
}
} }
&__logo-img { &__logo-img {

View File

@ -1,3 +1,5 @@
const THEME_STYLE_ID = 'sysmgr-theme'
/** 十六进制颜色 → RGB 三元组。 */ /** 十六进制颜色 → RGB 三元组。 */
function hexToRgb(hex: string): [number, number, number] { function hexToRgb(hex: string): [number, number, number] {
let h = hex.replace('#', '') let h = hex.replace('#', '')
@ -18,26 +20,57 @@ function mix(base: string, target: string, weight: number): string {
return rgbToHex(r1 + (r2 - r1) * weight, g1 + (g2 - g1) * weight, b1 + (b2 - b1) * weight) return rgbToHex(r1 + (r2 - r1) * weight, g1 + (g2 - g1) * weight, b1 + (b2 - b1) * weight)
} }
/** 应用主题色:写入 Element Plus 主色派生变量与 --wm-color-* 令牌(内联样式优先级最高,明暗皆生效)。 */ /** 生成一组 CSS 变量声明。 */
function cssVars(vars: [string, string][]): string {
return vars.map(([k, v]) => `${k}: ${v};`).join('')
}
/**
* 由主色生成明/暗两套 Element Plus 主色派生变量与 --wm-color-* 令牌,
* 注入 <style id="sysmgr-theme">。暗黑模式把 light-N 改为混黑(作深色高亮底)、
* dark-2 改为混白(作深色对比色),保证暗黑下侧栏/按钮高亮不刺眼。
*/
export function applyThemeColor(primary: string): void { export function applyThemeColor(primary: string): void {
const root = document.documentElement const mixWhite = (w: number) => mix(primary, '#ffffff', w)
const set = (name: string, value: string) => root.style.setProperty(name, value) const mixBlack = (w: number) => mix(primary, '#000000', w)
set('--el-color-primary', primary) // 明亮模式
set('--el-color-primary-light-3', mix(primary, '#ffffff', 0.3)) const light: [string, string][] = [
set('--el-color-primary-light-5', mix(primary, '#ffffff', 0.5)) ['--el-color-primary', primary],
set('--el-color-primary-light-7', mix(primary, '#ffffff', 0.7)) ['--el-color-primary-light-3', mixWhite(0.3)],
set('--el-color-primary-light-8', mix(primary, '#ffffff', 0.8)) ['--el-color-primary-light-5', mixWhite(0.5)],
set('--el-color-primary-light-9', mix(primary, '#ffffff', 0.9)) ['--el-color-primary-light-7', mixWhite(0.7)],
set('--el-color-primary-dark-2', mix(primary, '#000000', 0.2)) ['--el-color-primary-light-8', mixWhite(0.8)],
['--el-color-primary-light-9', mixWhite(0.9)],
['--el-color-primary-dark-2', mixBlack(0.2)],
['--wm-color-primary', primary],
...([1, 2, 3, 5, 7, 8, 9].map((i) => [`--wm-color-primary-light-${i}`, mixWhite(i / 10)] as [string, string])),
['--wm-color-primary-dark-1', mixBlack(0.1)],
['--wm-color-primary-dark-2', mixBlack(0.2)],
]
// 同步 --wm-color-primary 及色阶,保证 UnoCSS(text-primary 等)一致 // 暗黑模式:light-N 混黑、dark-2 混白
set('--wm-color-primary', primary) const dark: [string, string][] = [
;[1, 2, 3, 5, 7, 8, 9].forEach((i) => { ['--el-color-primary', primary],
set(`--wm-color-primary-light-${i}`, mix(primary, '#ffffff', i / 10)) ['--el-color-primary-light-3', mixBlack(0.2)],
}) ['--el-color-primary-light-5', mixBlack(0.4)],
set('--wm-color-primary-dark-1', mix(primary, '#000000', 0.1)) ['--el-color-primary-light-7', mixBlack(0.6)],
set('--wm-color-primary-dark-2', mix(primary, '#000000', 0.2)) ['--el-color-primary-light-8', mixBlack(0.7)],
['--el-color-primary-light-9', mixBlack(0.8)],
['--el-color-primary-dark-2', mixWhite(0.3)],
['--wm-color-primary', primary],
...([1, 2, 3, 5, 7, 8, 9].map((i) => [`--wm-color-primary-light-${i}`, mixBlack(i / 10)] as [string, string])),
['--wm-color-primary-dark-1', mixWhite(0.1)],
['--wm-color-primary-dark-2', mixWhite(0.2)],
]
let el = document.getElementById(THEME_STYLE_ID) as HTMLStyleElement | null
if (!el) {
el = document.createElement('style')
el.id = THEME_STYLE_ID
document.head.appendChild(el)
}
el.textContent = `:root{${cssVars(light)}}html.dark{${cssVars(dark)}}`
} }
/** 应用暗黑模式:同时切换 Element Plus 的 html.dark 与现有 data-theme 令牌。 */ /** 应用暗黑模式:同时切换 Element Plus 的 html.dark 与现有 data-theme 令牌。 */

File diff suppressed because one or more lines are too long