forked from Prompt-Hash-Stellar/prompt-hash
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseTheme.ts
More file actions
76 lines (60 loc) · 2.08 KB
/
Copy pathuseTheme.ts
File metadata and controls
76 lines (60 loc) · 2.08 KB
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { useEffect, useState } from 'react'
type Theme = 'light' | 'dark' | 'system'
/**
* Apply the saved theme synchronously before first render
* to prevent a light-theme flash on dark-mode preference.
*/
export function applyThemeBeforeRender(): void {
if (typeof window === 'undefined') return
const stored = localStorage.getItem('theme-preference') as Theme | null
const theme = stored || 'system'
let isDarkMode = theme === 'dark'
if (theme === 'system') {
isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
}
const html = document.documentElement
if (isDarkMode) {
html.classList.add('dark')
html.style.colorScheme = 'dark'
} else {
html.classList.remove('dark')
html.style.colorScheme = 'light'
}
}
export function useTheme() {
const [theme, setTheme] = useState<Theme>(() => {
if (typeof window === 'undefined') return 'system'
const stored = localStorage.getItem('theme-preference') as Theme | null
return stored || 'system'
})
const [isDark, setIsDark] = useState(false)
useEffect(() => {
const updateTheme = () => {
let isDarkMode = theme === 'dark'
if (theme === 'system') {
isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
}
setIsDark(isDarkMode)
const html = document.documentElement
if (isDarkMode) {
html.classList.add('dark')
document.documentElement.style.colorScheme = 'dark'
} else {
html.classList.remove('dark')
document.documentElement.style.colorScheme = 'light'
}
}
updateTheme()
if (theme === 'system') {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
const handleChange = () => updateTheme()
mediaQuery.addEventListener('change', handleChange)
return () => mediaQuery.removeEventListener('change', handleChange)
}
}, [theme])
const toggleTheme = (newTheme: Theme) => {
setTheme(newTheme)
localStorage.setItem('theme-preference', newTheme)
}
return { theme, isDark, toggleTheme }
}