mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: add system mode to the theme selector (#7853)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
92bc08207c
commit
cd50aa719f
21 changed files with 301 additions and 56 deletions
70
excalidraw-app/useHandleAppTheme.ts
Normal file
70
excalidraw-app/useHandleAppTheme.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { atom, useAtom } from "jotai";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { THEME } from "../packages/excalidraw";
|
||||
import { EVENT } from "../packages/excalidraw/constants";
|
||||
import { Theme } from "../packages/excalidraw/element/types";
|
||||
import { KEYS } from "../packages/excalidraw/keys";
|
||||
import { STORAGE_KEYS } from "./app_constants";
|
||||
|
||||
export const appThemeAtom = atom<Theme | "system">(
|
||||
(localStorage.getItem(STORAGE_KEYS.LOCAL_STORAGE_THEME) as
|
||||
| Theme
|
||||
| "system"
|
||||
| null) || THEME.LIGHT,
|
||||
);
|
||||
|
||||
const getDarkThemeMediaQuery = (): MediaQueryList | undefined =>
|
||||
window.matchMedia?.("(prefers-color-scheme: dark)");
|
||||
|
||||
export const useHandleAppTheme = () => {
|
||||
const [appTheme, setAppTheme] = useAtom(appThemeAtom);
|
||||
const [editorTheme, setEditorTheme] = useState<Theme>(THEME.LIGHT);
|
||||
|
||||
useEffect(() => {
|
||||
const mediaQuery = getDarkThemeMediaQuery();
|
||||
|
||||
const handleChange = (e: MediaQueryListEvent) => {
|
||||
setEditorTheme(e.matches ? THEME.DARK : THEME.LIGHT);
|
||||
};
|
||||
|
||||
if (appTheme === "system") {
|
||||
mediaQuery?.addEventListener("change", handleChange);
|
||||
}
|
||||
|
||||
const handleKeydown = (event: KeyboardEvent) => {
|
||||
if (
|
||||
!event[KEYS.CTRL_OR_CMD] &&
|
||||
event.altKey &&
|
||||
event.shiftKey &&
|
||||
event.code === KEYS.D
|
||||
) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
setAppTheme(editorTheme === THEME.DARK ? THEME.LIGHT : THEME.DARK);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener(EVENT.KEYDOWN, handleKeydown, { capture: true });
|
||||
|
||||
return () => {
|
||||
mediaQuery?.removeEventListener("change", handleChange);
|
||||
document.removeEventListener(EVENT.KEYDOWN, handleKeydown, {
|
||||
capture: true,
|
||||
});
|
||||
};
|
||||
}, [appTheme, editorTheme, setAppTheme]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
localStorage.setItem(STORAGE_KEYS.LOCAL_STORAGE_THEME, appTheme);
|
||||
|
||||
if (appTheme === "system") {
|
||||
setEditorTheme(
|
||||
getDarkThemeMediaQuery()?.matches ? THEME.DARK : THEME.LIGHT,
|
||||
);
|
||||
} else {
|
||||
setEditorTheme(appTheme);
|
||||
}
|
||||
}, [appTheme]);
|
||||
|
||||
return { editorTheme };
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue