feat(web): useTheme hook with live system tracking (#59)
This commit is contained in:
@@ -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<Theme>(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 };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user