diff --git a/web/src/theme/use-theme.ts b/web/src/theme/use-theme.ts new file mode 100644 index 0000000..cbd194e --- /dev/null +++ b/web/src/theme/use-theme.ts @@ -0,0 +1,25 @@ +import { useEffect, useState } from "react"; + +import { applyTheme, readTheme, THEME_KEY, type Theme } from "./theme"; + +export function useTheme(): { theme: Theme; setTheme: (theme: Theme) => void } { + const [theme, setThemeState] = useState(readTheme); + + const setTheme = (next: Theme) => { + if (typeof localStorage !== "undefined") localStorage.setItem(THEME_KEY, next); + setThemeState(next); + applyTheme(next); + }; + + useEffect(() => { + applyTheme(theme); + if (theme !== "system") return; + if (typeof window === "undefined" || typeof window.matchMedia !== "function") return; + const mql = window.matchMedia("(prefers-color-scheme: dark)"); + const onChange = () => applyTheme("system"); + mql.addEventListener("change", onChange); + return () => mql.removeEventListener("change", onChange); + }, [theme]); + + return { theme, setTheme }; +}