forked from craigary/nobelium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
theme.js
33 lines (27 loc) · 1.1 KB
/
theme.js
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
import { createContext, useContext, useEffect } from 'react'
import { useMedia } from 'react-use'
import { useConfig } from '@/lib/config'
const ThemeContext = createContext({ dark: true })
export function ThemeProvider ({ children }) {
const { appearance } = useConfig()
// `defaultState` should normally be a boolean. But it causes initial loading flashes in slow
// rendering. Setting it to `null` so that we can differentiate the initial loading phase
const prefersDark = useMedia('(prefers-color-scheme: dark)', null)
const dark = appearance === 'dark' || (appearance === 'auto' && prefersDark)
useEffect(() => {
// Only decide color scheme after initial loading, i.e. when `dark` is really representing a
// media query result
if (typeof dark === 'boolean') {
document.documentElement.classList.toggle('dark', dark)
document.documentElement.classList.remove('color-scheme-unset')
}
}, [dark])
return (
<ThemeContext.Provider value={{ dark }}>
{children}
</ThemeContext.Provider>
)
}
export default function useTheme () {
return useContext(ThemeContext)
}