-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththeme.ts
More file actions
32 lines (26 loc) · 1009 Bytes
/
theme.ts
File metadata and controls
32 lines (26 loc) · 1009 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { useEffect, useState } from "react";
type Theme = 'light' | 'dark' | 'system';
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
function resolveTheme(theme: Theme): 'light' | 'dark' {
if (theme !== 'system') return theme;
return mediaQuery.matches ? 'dark' : 'light'
}
export function useTheme() {
const [theme, setTheme] = useState<Theme>(
() => (localStorage.getItem('theme') as Theme) || 'system'
)
useEffect(() => {
const resolvedTheme = resolveTheme(theme)
document.documentElement.dataset.theme = resolvedTheme;
localStorage.setItem('theme', theme)
}, [theme])
useEffect(() => {
if (theme !== 'system') return
const handler = () => {
document.documentElement.dataset.theme = resolveTheme('system')
}
mediaQuery.addEventListener('change', handler)
return () => mediaQuery.removeEventListener('change', handler)
}, [theme])
return {theme, setTheme}
}