feat(theme): 专业主题系统重构 — Warp/Linear 设计参考,深色/浅色完整适配
参考设计系统: - Warp: 温暖暗色调、自然层次、克制配色 - Linear: 亮度阶梯层次、半透明边框、精确排版 核心改进: - app-theme.ts: 完整重写深色/浅色调色板 (+surface-hover/active, border-subtle/focus, feedback-bg, placeholder) - useTheme.ts: 修复硬编码 return 'dark',支持 dark/light/system 完整切换 - index.css: 消除硬编码颜色,全部使用 CSS 变量 - tailwind.config.js: 新增 txt/content/surface/border/ph/feedback 语义 token - 44 文件批量迁移: 292 处 text-gray/bg-gray/text-white/placeholder-gray → 主题感知语义 token | 44 files +611/-482 | tsc零错误 | 96/96 tests passing
This commit is contained in:
1 parent
07c4a5b14f
commit
e9a0d21758
44 files changed
+593
-464
No files matched your search
+21
-9
@@ -6,9 +6,12 @@ import { darkColors, lightColors, type AppThemeMode, type ColorMap } from '../th
|
||||
* Resolves the *effective* theme ('dark' | 'light') from the user preference,
|
||||
* including the 'system' → prefers-color-scheme mapping.
|
||||
*/
|
||||
function resolveEffectiveTheme(_preference: AppThemeMode): 'dark' | 'light' {
|
||||
// 当前版本固定使用 dark 主题,后续版本开放主题切换
|
||||
return 'dark'
|
||||
function resolveEffectiveTheme(preference: AppThemeMode): 'dark' | 'light' {
|
||||
if (preference === 'system') {
|
||||
if (typeof window === 'undefined') return 'dark'
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
return preference
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,8 +41,10 @@ export function useTheme() {
|
||||
useEffect(() => {
|
||||
const colors = effective === 'dark' ? darkColors : lightColors
|
||||
|
||||
// Set data attribute for potential direct CSS selectors
|
||||
// Set data attribute for CSS selectors
|
||||
document.documentElement.setAttribute('data-theme', effective)
|
||||
|
||||
// Toggle Tailwind dark class
|
||||
if (effective === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
@@ -49,9 +54,9 @@ export function useTheme() {
|
||||
// Apply CSS custom properties
|
||||
applyCSSVars(colors)
|
||||
|
||||
// Update body bg & colour (mirrors index.css body rules but via vars)
|
||||
document.body.style.backgroundColor = '#0f172a'
|
||||
document.body.style.color = '#e2e8f0'
|
||||
// Update body bg & colour from tokens (not hardcoded)
|
||||
document.body.style.backgroundColor = colors['surface-base'] || '#0f172a'
|
||||
document.body.style.color = colors['text-primary'] || '#e2e8f0'
|
||||
}, [effective])
|
||||
|
||||
// Listen for system colour-scheme changes when preference is 'system'
|
||||
@@ -64,9 +69,16 @@ export function useTheme() {
|
||||
const newEffective = e.matches ? 'dark' : 'light'
|
||||
const colors = e.matches ? darkColors : lightColors
|
||||
document.documentElement.setAttribute('data-theme', newEffective)
|
||||
|
||||
if (newEffective === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
|
||||
applyCSSVars(colors)
|
||||
document.body.style.backgroundColor = '#0f172a'
|
||||
document.body.style.color = '#e2e8f0'
|
||||
document.body.style.backgroundColor = colors['surface-base'] || '#0f172a'
|
||||
document.body.style.color = colors['text-primary'] || '#e2e8f0'
|
||||
}
|
||||
|
||||
mql.addEventListener('change', handler)
|
||||
|
||||
Reference in new issue
Block a user