added theme detection

This commit is contained in:
Fedor Katurov 2023-04-26 22:26:04 +06:00
parent 378687df52
commit 70f6dcd495
11 changed files with 133 additions and 19 deletions

View file

@ -25,6 +25,7 @@
"@remirror/react": "^2.0.27",
"@remirror/react-editors": "^1.0.27",
"classnames": "^2.3.2",
"color": "^4.2.3",
"dockview": "^1.7.1",
"formik": "^2.2.9",
"i18next": "^22.4.15",
@ -42,6 +43,7 @@
},
"devDependencies": {
"@types/classnames": "^2.3.1",
"@types/color": "^3.0.3",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/uuid": "^9.0.1",

View file

@ -9,7 +9,6 @@ i18n
.use(LanguageDetector)
.init({
fallbackLng: "en",
debug: true,
interpolation: {
escapeValue: false,
},

View file

@ -51,13 +51,8 @@ export const useGridLayoutPersistance = () => {
persistLayout();
});
const onPanelChange = api.current.onDidActivePanelChange((event) => {
console.log(event);
});
return () => {
onLayoutChange.dispose();
onPanelChange.dispose();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [persistLayout, api.current]);

View file

@ -1,10 +1,13 @@
import { createContext, useContext } from "react";
export type SettingsValue = {
richEditorEnabled: boolean;
export interface ColorSettings {
backgroundColor: string;
textColor: string;
linkColor: string;
}
export type SettingsValue = ColorSettings & {
richEditorEnabled: boolean;
};
export const defaultSettings: SettingsValue = {

View file

@ -7,9 +7,22 @@ import {
defaultSettings,
} from "../../context/SettingsContext";
import { ModalPage } from "~/modules/modal/components/ModalPage";
import { useDetectTheme } from "~/modules/theme/hooks/useDetectTheme";
import {
Theme,
defaultDarkTheme,
defaultLightTheme,
} from "~/modules/theme/constants/theme";
const SettingsProvider: FC<PropsWithChildren> = ({ children }) => {
const [settings, setSettings] = useState(defaultSettings);
const theme = useDetectTheme();
const defaultColors =
theme === Theme.Dark ? defaultDarkTheme : defaultLightTheme;
const [settings, setSettings] = useState({
...defaultSettings,
...defaultColors,
});
const [settingsModalVisible, setSettingsModalVisible] = useState(false);
const show = useCallback(() => setSettingsModalVisible(true), []);

View file

@ -1,3 +1,18 @@
import { ColorSettings } from "~/modules/settings/context/SettingsContext";
export enum Theme {
Dark = "dark",
Light = "light",
}
export const defaultDarkTheme: ColorSettings = {
backgroundColor: "#2e2e2e",
textColor: "#eeeeee",
linkColor: "#25bfe6",
};
export const defaultLightTheme: ColorSettings = {
backgroundColor: "#eeeeee",
textColor: "#2e2e2e",
linkColor: "#25bfe6",
};

View file

@ -1,6 +1,7 @@
import { FC, PropsWithChildren, useEffect, useState } from "react";
import { ThemeContext, defaultTheme } from "../../context/ThemeContext";
import { useSettings } from "~/modules/settings/context/SettingsContext";
import { useThemeColors } from "../../hooks/useThemeColors";
type ThemeProviderProps = PropsWithChildren;
@ -18,15 +19,7 @@ const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
return () => document.body.classList.remove(`theme-${theme.theme}`);
}, [theme.theme]);
useEffect(() => {
document.body.style.setProperty(
"--color-background",
settings.backgroundColor
);
document.body.style.setProperty("--color-text", settings.textColor);
document.body.style.setProperty("--color-link", settings.linkColor);
}, [settings]);
useThemeColors(settings);
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>

View file

@ -0,0 +1,27 @@
import { useEffect, useState } from "react";
import { Theme } from "../constants/theme";
const isDark = () =>
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
export const useDetectTheme = () => {
const [theme, setTheme] = useState(isDark() ? Theme.Dark : Theme.Light);
useEffect(() => {
const listener = (event: MediaQueryListEvent) => {
setTheme(event.matches ? Theme.Dark : Theme.Light);
};
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", listener);
return () =>
window
.matchMedia("(prefers-color-scheme: dark)")
.removeEventListener("change", listener);
}, []);
return theme;
};

View file

@ -0,0 +1,19 @@
import Color from "color";
import { useEffect } from "react";
import { ColorSettings } from "~/modules/settings/context/SettingsContext";
export const useThemeColors = (settings: ColorSettings) => {
useEffect(() => {
const background = new Color(settings.backgroundColor);
const isDark = background.isDark();
const border = isDark
? background.mix(Color("white"), 0.1)
: background.mix(Color("black"), 0.1);
document.body.style.setProperty("--color-background", background.hex());
document.body.style.setProperty("--color-text", settings.textColor);
document.body.style.setProperty("--color-link", settings.linkColor);
document.body.style.setProperty("--color-border", border.hex());
}, [settings]);
};

View file

@ -12,6 +12,7 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"esModuleInterop": true,
/* Linting */
"strict": true,

View file

@ -2016,6 +2016,25 @@
dependencies:
"@types/tern" "*"
"@types/color-convert@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.0.tgz#8f5ee6b9e863dcbee5703f5a517ffb13d3ea4e22"
integrity sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==
dependencies:
"@types/color-name" "*"
"@types/color-name@*":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/color@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/color/-/color-3.0.3.tgz#e6d8d72b7aaef4bb9fe80847c26c7c786191016d"
integrity sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==
dependencies:
"@types/color-convert" "*"
"@types/debug@^4.0.0":
version "4.1.7"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
@ -2887,16 +2906,32 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4:
color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color2k@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.2.tgz#ac2b4aea11c822a6bcb70c768b5a289f4fffcebb"
integrity sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==
color@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
dependencies:
color-convert "^2.0.1"
color-string "^1.9.0"
columnify@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3"
@ -4468,6 +4503,11 @@ is-arrayish@^0.2.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
is-bigint@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@ -6854,6 +6894,13 @@ signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
dependencies:
is-arrayish "^0.3.1"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"