export type ColorScheme = 'dark' | 'light' | 'system' export type ThemePreset = | 'default' | 'darkmatter' | 'cyberpunk' | 'claymorphism' | 'cleanslate' | 'modern' | 'nature' | 'mocha' | 'graphite' | 'eleganyluxury' | 'kodama' | 'midnight' | 'mono' | 'catpuccin' | 'claude' | 'cosmicnight' | 'doom64' | 'amber' | 'amethyst' | 'bold-tech' | 'bubblegum' | 'caffeine' | 'candyland' | 'neo' | 'northern' | 'notebook' | 'ocean' | 'pastel' | 'perpetuity' | 'quantum' | 'retro' | 'sage' | 'softpop' | 'solardusk' | 'starry' | 'sunset' | 'supabase' | 't3chat' | 'tangerine' | 'twitter' | 'vercel' | 'vintage' | 'violet' const DEFAULT_THEME_PRESET: ThemePreset = 'default' const THEME_PRESET_KEY = 'vite-ui-theme-preset' export const useTheme = () => { const themePreset = ref(DEFAULT_THEME_PRESET) const initFromStorage = () => { if (import.meta.client) { themePreset.value = (localStorage.getItem(THEME_PRESET_KEY) as ThemePreset) || DEFAULT_THEME_PRESET applyTheme() } } const applyTheme = () => { if (!import.meta.client) return const link = document.createElement('link') link.rel = 'stylesheet' link.href = `/themes/${themePreset.value}.css` link.title = 'theme-preset' link.id = 'theme-preset-stylesheet' link.onload = () => { document.querySelectorAll('link[title="theme-preset"]').forEach(oldLink => { if (oldLink.id !== 'theme-preset-stylesheet') { document.head.removeChild(oldLink) } }) } const existingLink = document.getElementById('theme-preset-stylesheet') if (existingLink) { existingLink.remove() } document.head.appendChild(link) } const watchSystemTheme = () => { if (!import.meta.client) return const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') const handleChange = () => { applyTheme() } mediaQuery.addEventListener('change', handleChange) return () => mediaQuery.removeEventListener('change', handleChange) } const setThemePreset = (preset: ThemePreset) => { themePreset.value = preset if (import.meta.client) { localStorage.setItem(THEME_PRESET_KEY, preset) applyTheme() } } onMounted(() => { initFromStorage() watchSystemTheme() }) return { themePreset: readonly(themePreset), setThemePreset } }