feat: add dark theme support with CSS custom properties and Naive UI integration
Implement runtime theme switching using CSS custom properties delegated through SCSS variables, with light/dark/system modes, FOUC prevention, sidebar toggle, and settings selector. Add theme-aware video assets for sidebar and chat thinking indicator. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
export type ThemeMode = 'light' | 'dark' | 'system'
|
||||
|
||||
const STORAGE_KEY = 'hermes_theme'
|
||||
|
||||
const mode = ref<ThemeMode>(
|
||||
(localStorage.getItem(STORAGE_KEY) as ThemeMode) || 'system',
|
||||
)
|
||||
|
||||
const isDark = ref(false)
|
||||
|
||||
function applyTheme(dark: boolean) {
|
||||
isDark.value = dark
|
||||
document.documentElement.classList.toggle('dark', dark)
|
||||
}
|
||||
|
||||
function resolveDark(m: ThemeMode): boolean {
|
||||
if (m === 'system') {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
}
|
||||
return m === 'dark'
|
||||
}
|
||||
|
||||
// Initial resolve
|
||||
applyTheme(resolveDark(mode.value))
|
||||
|
||||
// Listen for system preference changes
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
mediaQuery.addEventListener('change', () => {
|
||||
if (mode.value === 'system') {
|
||||
applyTheme(true)
|
||||
}
|
||||
})
|
||||
|
||||
// Watch mode changes
|
||||
watch(mode, (newMode) => {
|
||||
localStorage.setItem(STORAGE_KEY, newMode)
|
||||
applyTheme(resolveDark(newMode))
|
||||
})
|
||||
|
||||
export function useTheme() {
|
||||
function setMode(m: ThemeMode) {
|
||||
mode.value = m
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
mode.value = isDark.value ? 'light' : 'dark'
|
||||
}
|
||||
|
||||
return {
|
||||
mode,
|
||||
isDark,
|
||||
setMode,
|
||||
toggleTheme,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user