save theme preference to localStorage
This commit is contained in:
@@ -48,6 +48,19 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
</ContextProvider>
|
||||
|
||||
<Footer />
|
||||
|
||||
{/* not using <Script> from next/script since it executes too late */}
|
||||
<script
|
||||
defer
|
||||
id="load-theme"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `if (localStorage.theme === "dark" || (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
document.documentElement.setAttribute("data-theme", "chessuDark");
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", "chessuLight");
|
||||
}`
|
||||
}}
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -7,31 +7,32 @@ export default function ThemeToggle() {
|
||||
const [darkTheme, setDarkTheme] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const onChange = (e: MediaQueryListEvent) => changeTheme(e.matches ? "dark" : "light");
|
||||
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", onChange);
|
||||
|
||||
changeTheme(window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
|
||||
|
||||
return () => {
|
||||
window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", onChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function changeTheme(theme: "dark" | "light") {
|
||||
if (theme === "dark") {
|
||||
document.documentElement.setAttribute("data-theme", "chessuDark");
|
||||
if (document.documentElement.getAttribute("data-theme") === "chessuDark") {
|
||||
setDarkTheme(true);
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", "chessuLight");
|
||||
setDarkTheme(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function toggleTheme() {
|
||||
if (
|
||||
document.documentElement.getAttribute("data-theme") === "chessuDark" ||
|
||||
(!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
) {
|
||||
document.documentElement.setAttribute("data-theme", "chessuLight");
|
||||
localStorage.theme = "light";
|
||||
setDarkTheme(false);
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", "chessuDark");
|
||||
localStorage.theme = "dark";
|
||||
setDarkTheme(true);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Toggle theme"
|
||||
onClick={() => changeTheme(darkTheme ? "light" : "dark")}
|
||||
onClick={toggleTheme}
|
||||
className={"btn btn-ghost btn-circle swap swap-rotate" + (darkTheme ? " swap-active" : "")}
|
||||
>
|
||||
<IconSun className="swap-on m-auto block h-full" />
|
||||
|
||||
Reference in New Issue
Block a user