diff --git a/web/src/hooks/useApperance.ts b/web/src/hooks/useApperance.ts index c020b388..14cb9154 100644 --- a/web/src/hooks/useApperance.ts +++ b/web/src/hooks/useApperance.ts @@ -3,24 +3,26 @@ import { useColorScheme } from "@mui/joy/styles"; import { APPERANCE_OPTIONS, APPERANCE_OPTIONS_STORAGE_KEY } from "../helpers/consts"; import useLocalStorage from "./useLocalStorage"; +import useMediaQuery from "./useMediaQuery"; export type Apperance = typeof APPERANCE_OPTIONS[number]; const useApperance = () => { const [apperance, setApperance] = useLocalStorage(APPERANCE_OPTIONS_STORAGE_KEY, APPERANCE_OPTIONS[0]); + const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)"); const { setMode } = useColorScheme(); useEffect(() => { const root = document.documentElement; - if (apperance === "dark" || (apperance === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches)) { + if (apperance === "dark" || (apperance === "auto" && prefersDarkMode)) { root.classList.add("dark"); setMode("dark"); } else { root.classList.remove("dark"); setMode("light"); } - }, [apperance]); + }, [apperance, prefersDarkMode]); return [apperance, setApperance] as const; }; diff --git a/web/src/hooks/useMediaQuery.ts b/web/src/hooks/useMediaQuery.ts new file mode 100644 index 00000000..ecc22f2b --- /dev/null +++ b/web/src/hooks/useMediaQuery.ts @@ -0,0 +1,21 @@ +import { useState, useEffect } from "react"; + +const useMediaQuery = (query: string) => { + const [matches, setMatches] = useState(false); + + useEffect(() => { + const media = window.matchMedia(query); + if (media.matches !== matches) { + setMatches(media.matches); + } + const listener = () => { + setMatches(media.matches); + }; + media.addEventListener("change", listener); + return () => media.removeEventListener("change", listener); + }, [query, matches]); + + return matches; +}; + +export default useMediaQuery;