feat: auto dark mode (#321)
This commit is contained in:
@@ -12,7 +12,12 @@ export function useDarkMode() {
|
||||
} = useSetting();
|
||||
|
||||
const toggleDarkMode = useCallback(() => {
|
||||
updateSetting({ darkMode: !darkMode });
|
||||
const nextMode = {
|
||||
light: "dark",
|
||||
dark: "auto",
|
||||
auto: "light",
|
||||
};
|
||||
updateSetting({ darkMode: nextMode[darkMode] || "light" });
|
||||
}, [darkMode, updateSetting]);
|
||||
|
||||
return { darkMode, toggleDarkMode };
|
||||
|
||||
@@ -33,6 +33,15 @@ export function SettingProvider({ children }) {
|
||||
reload,
|
||||
} = useStorage(STOKEY_SETTING, DEFAULT_SETTING, KV_SETTING_KEY);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof setting?.darkMode === "boolean") {
|
||||
update((currentSetting) => ({
|
||||
...currentSetting,
|
||||
darkMode: currentSetting.darkMode ? "dark" : "light",
|
||||
}));
|
||||
}
|
||||
}, [setting?.darkMode, update]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { ThemeProvider, createTheme } from "@mui/material/styles";
|
||||
import { CssBaseline, GlobalStyles } from "@mui/material";
|
||||
import { useDarkMode } from "./ColorMode";
|
||||
@@ -11,6 +11,21 @@ import { THEME_DARK, THEME_LIGHT } from "../config";
|
||||
*/
|
||||
export default function Theme({ children, options, styles }) {
|
||||
const { darkMode } = useDarkMode();
|
||||
const [systemMode, setSystemMode] = useState(THEME_LIGHT);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window.matchMedia !== "function") {
|
||||
return;
|
||||
}
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
const handleChange = () => {
|
||||
setSystemMode(mediaQuery.matches ? THEME_DARK : THEME_LIGHT);
|
||||
};
|
||||
handleChange(); // Set initial value
|
||||
mediaQuery.addEventListener("change", handleChange);
|
||||
return () => mediaQuery.removeEventListener("change", handleChange);
|
||||
}, []);
|
||||
|
||||
const theme = useMemo(() => {
|
||||
let htmlFontSize = 16;
|
||||
try {
|
||||
@@ -23,16 +38,19 @@ export default function Theme({ children, options, styles }) {
|
||||
//
|
||||
}
|
||||
|
||||
const isDarkMode =
|
||||
darkMode === "dark" || (darkMode === "auto" && systemMode === THEME_DARK);
|
||||
|
||||
return createTheme({
|
||||
palette: {
|
||||
mode: darkMode ? THEME_DARK : THEME_LIGHT,
|
||||
mode: isDarkMode ? THEME_DARK : THEME_LIGHT,
|
||||
},
|
||||
typography: {
|
||||
htmlFontSize,
|
||||
},
|
||||
...options,
|
||||
});
|
||||
}, [darkMode, options]);
|
||||
}, [darkMode, options, systemMode]);
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
|
||||
Reference in New Issue
Block a user