Portfolio/app/composables/useTheme.ts
2026-09-08 19:54:06 +02:00

31 lines
911 B
TypeScript

type Theme = 'light' | 'dark'
/**
* The theme is applied by an inline script in `nuxt.config.ts` before first
* paint, so there is no flash. This composable only mirrors and flips it.
*/
export function useTheme() {
const theme = useState<Theme>('theme', () => 'light')
const mounted = useState<boolean>('theme:mounted', () => false)
onMounted(() => {
const current = document.documentElement.getAttribute('data-theme')
theme.value = current === 'dark' ? 'dark' : 'light'
mounted.value = true
})
function set(next: Theme) {
theme.value = next
document.documentElement.setAttribute('data-theme', next)
try {
localStorage.setItem('theme', next)
} catch {
// private mode, blocked storage — the toggle still works for this session
}
}
const toggle = () => set(theme.value === 'dark' ? 'light' : 'dark')
return { theme, mounted, set, toggle }
}