|
|
|
|
|
|
|
import React, { createContext, useState, useEffect } from 'react'; |
|
|
|
const getInitialTheme = () => { |
|
if (typeof window !== 'undefined' && window.localStorage) { |
|
const storedPrefs = window.localStorage.getItem('color-theme'); |
|
if (typeof storedPrefs === 'string') { |
|
return storedPrefs; |
|
} |
|
|
|
const userMedia = window.matchMedia('(prefers-color-scheme: dark)'); |
|
if (userMedia.matches) { |
|
return 'dark'; |
|
} |
|
} |
|
|
|
return 'light'; |
|
}; |
|
|
|
export const ThemeContext = createContext(); |
|
|
|
export const ThemeProvider = ({ initialTheme, children }) => { |
|
const [theme, setTheme] = useState(getInitialTheme); |
|
|
|
const rawSetTheme = (rawTheme) => { |
|
const root = window.document.documentElement; |
|
let isDark = rawTheme === 'dark'; |
|
|
|
if (rawTheme === 'system') { |
|
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches; |
|
} |
|
|
|
root.classList.remove(isDark ? 'light' : 'dark'); |
|
root.classList.add(isDark ? 'dark' : 'light'); |
|
|
|
localStorage.setItem('color-theme', rawTheme); |
|
}; |
|
|
|
if (initialTheme) { |
|
rawSetTheme(initialTheme); |
|
} |
|
|
|
useEffect(() => { |
|
rawSetTheme(theme); |
|
}, [theme]); |
|
|
|
return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>; |
|
}; |
|
|