(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ui-refactor 75 lines 1.9 kB view raw
1import { createContext, useContext, useEffect, useState } from "react"; 2 3const ThemeContext = createContext({ 4 theme: "system", 5 setTheme: () => null, 6}); 7 8export function ThemeProvider({ children }) { 9 const [theme, setTheme] = useState(() => { 10 return localStorage.getItem("theme") || "system"; 11 }); 12 13 useEffect(() => { 14 localStorage.setItem("theme", theme); 15 16 const root = window.document.documentElement; 17 root.classList.remove("light", "dark"); 18 19 delete root.dataset.theme; 20 21 if (theme === "system") { 22 const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") 23 .matches 24 ? "dark" 25 : "light"; 26 27 if (systemTheme === "light") { 28 root.dataset.theme = "light"; 29 } else { 30 root.dataset.theme = "dark"; 31 } 32 return; 33 } 34 35 if (theme === "light") { 36 root.dataset.theme = "light"; 37 } 38 }, [theme]); 39 40 useEffect(() => { 41 if (theme !== "system") return; 42 43 const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); 44 const handleChange = () => { 45 const root = window.document.documentElement; 46 if (mediaQuery.matches) { 47 delete root.dataset.theme; 48 } else { 49 root.dataset.theme = "light"; 50 } 51 }; 52 53 mediaQuery.addEventListener("change", handleChange); 54 return () => mediaQuery.removeEventListener("change", handleChange); 55 }, [theme]); 56 57 const value = { 58 theme, 59 setTheme: (newTheme) => { 60 setTheme(newTheme); 61 }, 62 }; 63 64 return ( 65 <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider> 66 ); 67} 68 69// eslint-disable-next-line react-refresh/only-export-components 70export function useTheme() { 71 const context = useContext(ThemeContext); 72 if (context === undefined) 73 throw new Error("useTheme must be used within a ThemeProvider"); 74 return context; 75}