theme.tsx (1798B)
1 import * as React from "react"; 2 import GlobalData from "../../content/global/index.json"; 3 4 const ThemeContext = React.createContext(GlobalData.theme); 5 6 export const useTheme = () => React.useContext(ThemeContext); 7 8 const updateRenderColorMode = (themeMode: "dark" | "light") => { 9 if (typeof window !== "undefined") { 10 const root = window.document.documentElement; 11 root.classList.remove("dark"); 12 root.classList.remove("light"); 13 root.classList.add(themeMode); 14 } 15 }; 16 17 const getUserSystemDarkMode = () => { 18 if (typeof window !== "undefined") { 19 const userMedia = window.matchMedia("(prefers-color-scheme: dark)"); 20 21 if (userMedia.matches) { 22 return "dark"; 23 } 24 } 25 26 return "light"; 27 }; 28 29 export const Theme = ({ data, children }) => { 30 const [systemDarkMode, setSystemDarkMode] = React.useState( 31 getUserSystemDarkMode() 32 ); 33 34 React.useEffect(() => { 35 if (typeof window !== "undefined") { 36 const userMedia = window.matchMedia("(prefers-color-scheme: dark)"); 37 38 const updateSystemMediaPreference = (event) => { 39 setSystemDarkMode(event.matches ? "dark" : "light"); 40 }; 41 42 userMedia.addEventListener("change", updateSystemMediaPreference); 43 44 return () => 45 userMedia.removeEventListener("change", updateSystemMediaPreference); 46 } 47 return; 48 }, [setSystemDarkMode]); 49 50 const { color = "blue", font = "sans", darkMode = "system" } = data; 51 52 React.useEffect(() => { 53 updateRenderColorMode( 54 darkMode === "system" 55 ? systemDarkMode 56 : darkMode !== "" 57 ? darkMode 58 : "light" 59 ); 60 }, [systemDarkMode, darkMode]); 61 62 return ( 63 <ThemeContext.Provider 64 value={{ 65 color, 66 font, 67 darkMode, 68 }} 69 > 70 {children} 71 </ThemeContext.Provider> 72 ); 73 };