2021-09-22 18:36:13 +00:00
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
|
|
|
const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
|
|
|
|
|
|
interface UseDarkModeOutput {
|
|
|
|
isDarkMode: boolean;
|
|
|
|
toggle: () => void;
|
|
|
|
enable: () => void;
|
|
|
|
disable: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
function useDarkMode(defaultValue?: boolean): UseDarkModeOutput {
|
|
|
|
const getPrefersScheme = (): boolean => {
|
|
|
|
// Prevents SSR issues
|
2021-09-24 12:52:00 +00:00
|
|
|
if (process.browser) {
|
2021-09-22 18:36:13 +00:00
|
|
|
return window.matchMedia(COLOR_SCHEME_QUERY).matches;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !!defaultValue;
|
|
|
|
};
|
|
|
|
|
|
|
|
const [isDarkMode, setDarkMode] = useState<boolean>(getPrefersScheme());
|
|
|
|
|
|
|
|
// Update darkMode if os prefers changes
|
|
|
|
useEffect(() => {
|
|
|
|
const handler = () => setDarkMode(getPrefersScheme);
|
|
|
|
const matchMedia = window.matchMedia(COLOR_SCHEME_QUERY);
|
|
|
|
|
|
|
|
matchMedia.addEventListener("change", handler);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
matchMedia.removeEventListener("change", handler);
|
|
|
|
};
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return {
|
|
|
|
isDarkMode,
|
|
|
|
toggle: () => setDarkMode((prev) => !prev),
|
|
|
|
enable: () => setDarkMode(true),
|
|
|
|
disable: () => setDarkMode(false),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default useDarkMode;
|