|
import { useState, useEffect, createContext, useContext } from "react"; |
|
|
|
|
|
const ThemeModeContext = createContext(); |
|
|
|
|
|
export const ThemeModeProvider = ({ children }) => { |
|
|
|
const getSystemPreference = () => { |
|
return window.matchMedia("(prefers-color-scheme: dark)").matches |
|
? "dark" |
|
: "light"; |
|
}; |
|
|
|
|
|
const getSavedTheme = () => { |
|
const savedTheme = localStorage.getItem("theme-mode"); |
|
return savedTheme || getSystemPreference(); |
|
}; |
|
|
|
|
|
const [mode, setMode] = useState(getSavedTheme); |
|
|
|
|
|
useEffect(() => { |
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); |
|
const handleChange = (e) => { |
|
|
|
if (!localStorage.getItem("theme-mode")) { |
|
setMode(e.matches ? "dark" : "light"); |
|
} |
|
}; |
|
|
|
mediaQuery.addEventListener("change", handleChange); |
|
return () => mediaQuery.removeEventListener("change", handleChange); |
|
}, []); |
|
|
|
|
|
useEffect(() => { |
|
localStorage.setItem("theme-mode", mode); |
|
}, [mode]); |
|
|
|
const toggleTheme = () => { |
|
setMode((prevMode) => (prevMode === "light" ? "dark" : "light")); |
|
}; |
|
|
|
return ( |
|
<ThemeModeContext.Provider value={{ mode, toggleTheme }}> |
|
{children} |
|
</ThemeModeContext.Provider> |
|
); |
|
}; |
|
|
|
|
|
export const useThemeMode = () => { |
|
const context = useContext(ThemeModeContext); |
|
if (context === undefined) { |
|
throw new Error("useThemeMode must be used within a ThemeModeProvider"); |
|
} |
|
return context; |
|
}; |
|
|