(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol.
Something went wrong. Try again.
JSX
at ui-refactor
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576import { createContext, useContext, useEffect, useState } from "react";
const ThemeContext = createContext({ theme: "system", setTheme: () => null,});
export function ThemeProvider({ children }) { const [theme, setTheme] = useState(() => { return localStorage.getItem("theme") || "system"; });
useEffect(() => { localStorage.setItem("theme", theme);
const root = window.document.documentElement; root.classList.remove("light", "dark");
delete root.dataset.theme;
if (theme === "system") { const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") .matches ? "dark" : "light";
if (systemTheme === "light") { root.dataset.theme = "light"; } else { root.dataset.theme = "dark"; } return; }
if (theme === "light") { root.dataset.theme = "light"; } }, [theme]);
useEffect(() => { if (theme !== "system") return;
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleChange = () => { const root = window.document.documentElement; if (mediaQuery.matches) { delete root.dataset.theme; } else { root.dataset.theme = "light"; } };
mediaQuery.addEventListener("change", handleChange); return () => mediaQuery.removeEventListener("change", handleChange); }, [theme]);
const value = { theme, setTheme: (newTheme) => { setTheme(newTheme); }, };
return ( <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider> );}
// eslint-disable-next-line react-refresh/only-export-componentsexport function useTheme() { const context = useContext(ThemeContext); if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider"); return context;}