made simple settings page

This commit is contained in:
Fedor Katurov 2023-04-26 17:47:11 +06:00
parent ece7395b26
commit 00a11d05e0
9 changed files with 116 additions and 19 deletions

View file

@ -13,5 +13,5 @@ export const createDefaultLayout = (api: DockviewApi) => {
}); });
// panel.group.locked = true; // panel.group.locked = true;
panel.group.header.hidden = true; panel.group.header.hidden = false;
}; };

View file

@ -0,0 +1,12 @@
import { FC, PropsWithChildren } from "react";
import styles from "./styles.module.scss";
interface ModalPageProps extends PropsWithChildren {
onClose: () => void;
}
const ModalPage: FC<ModalPageProps> = ({ children }) => (
<div className={styles.page}>{children}</div>
);
export { ModalPage };

View file

@ -0,0 +1,5 @@
.page {
background: var(--color-background);
padding: 16px;
border-radius: 10px;
}

View file

@ -5,9 +5,9 @@ type ModalProps = PropsWithChildren & {
onClose: () => void; onClose: () => void;
}; };
const Modal: FC<ModalProps> = ({ children }) => ( const Modal: FC<ModalProps> = ({ children, onClose }) => (
<div className={styles.modal}> <div className={styles.modal}>
<div className={styles.overlay} /> <div className={styles.overlay} onClick={onClose} />
<div className={styles.content}> <div className={styles.content}>
<div className={styles.page}>{children}</div> <div className={styles.page}>{children}</div>
</div> </div>

View file

@ -14,13 +14,14 @@
justify-content: center; justify-content: center;
padding: 16px; padding: 16px;
box-sizing: border-box; box-sizing: border-box;
pointer-events: none;
touch-action: none;
} }
.page { .page {
background: var(--color-background);
padding: 16px;
border-radius: 10px;
margin: auto; margin: auto;
pointer-events: all;
touch-action: all;
} }
.overlay { .overlay {
@ -28,4 +29,5 @@
inset: 0; inset: 0;
z-index: 1; z-index: 1;
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
} }

View file

@ -1,12 +1,62 @@
import { FC } from "react"; import { ChangeEvent, FC, useCallback } from "react";
import { useSettings } from "../../context/SettingsContext";
const SettingsContainer: FC = () => ( const SettingsContainer: FC = () => {
const { update, settings } = useSettings();
const updateBackgroundColor = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
update({ backgroundColor: event.target.value });
},
[update]
);
const updateTextColor = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
update({ textColor: event.target.value });
},
[update]
);
const updateLinkColor = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
update({ linkColor: event.target.value });
},
[update]
);
return (
<div> <div>
<label htmlFor="color"> <label htmlFor="color">
<input type="color" id="color" /> Background
Sample color switch <input
type="color"
id="color"
onChange={updateBackgroundColor}
value={settings.backgroundColor}
/>
</label>
<label htmlFor="color">
Text
<input
type="color"
id="color"
onChange={updateTextColor}
value={settings.textColor}
/>
</label>
<label htmlFor="color">
Link
<input
type="color"
id="color"
onChange={updateLinkColor}
value={settings.linkColor}
/>
</label> </label>
</div> </div>
); );
};
export { SettingsContainer }; export { SettingsContainer };

View file

@ -2,14 +2,22 @@ import { createContext, useContext } from "react";
export type SettingsValue = { export type SettingsValue = {
richEditorEnabled: boolean; richEditorEnabled: boolean;
backgroundColor: string;
textColor: string;
linkColor: string;
}; };
export const defaultSettings: SettingsValue = { richEditorEnabled: false }; export const defaultSettings: SettingsValue = {
richEditorEnabled: false,
backgroundColor: "",
textColor: "",
linkColor: "",
};
export const SettingsContext = createContext({ export const SettingsContext = createContext({
settings: defaultSettings, settings: defaultSettings,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
setSettings: (_: SettingsValue) => {}, update: (_: Partial<SettingsValue>) => {},
show: () => {}, show: () => {},
hide: () => {}, hide: () => {},
}); });

View file

@ -3,8 +3,10 @@ import { Modal } from "~/modules/modal/containers/Modal";
import { SettingsContainer } from "../../containers/SettingsContainer"; import { SettingsContainer } from "../../containers/SettingsContainer";
import { import {
SettingsContext, SettingsContext,
SettingsValue,
defaultSettings, defaultSettings,
} from "../../context/SettingsContext"; } from "../../context/SettingsContext";
import { ModalPage } from "~/modules/modal/components/ModalPage";
const SettingsProvider: FC<PropsWithChildren> = ({ children }) => { const SettingsProvider: FC<PropsWithChildren> = ({ children }) => {
const [settings, setSettings] = useState(defaultSettings); const [settings, setSettings] = useState(defaultSettings);
@ -12,12 +14,18 @@ const SettingsProvider: FC<PropsWithChildren> = ({ children }) => {
const show = useCallback(() => setSettingsModalVisible(true), []); const show = useCallback(() => setSettingsModalVisible(true), []);
const hide = useCallback(() => setSettingsModalVisible(false), []); const hide = useCallback(() => setSettingsModalVisible(false), []);
const update = useCallback(
(val: Partial<SettingsValue>) => setSettings((v) => ({ ...v, ...val })),
[]
);
return ( return (
<SettingsContext.Provider value={{ settings, setSettings, show, hide }}> <SettingsContext.Provider value={{ settings, update, show, hide }}>
{settingsModalVisible && ( {settingsModalVisible && (
<Modal onClose={hide}> <Modal onClose={hide}>
<ModalPage onClose={hide}>
<SettingsContainer /> <SettingsContainer />
</ModalPage>
</Modal> </Modal>
)} )}

View file

@ -1,9 +1,11 @@
import { FC, PropsWithChildren, useEffect, useState } from "react"; import { FC, PropsWithChildren, useEffect, useState } from "react";
import { ThemeContext, defaultTheme } from "../../context/ThemeContext"; import { ThemeContext, defaultTheme } from "../../context/ThemeContext";
import { useSettings } from "~/modules/settings/context/SettingsContext";
type ThemeProviderProps = PropsWithChildren; type ThemeProviderProps = PropsWithChildren;
const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => { const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
const { settings } = useSettings();
const [theme] = useState(defaultTheme); const [theme] = useState(defaultTheme);
useEffect(() => { useEffect(() => {
@ -16,6 +18,16 @@ const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
return () => document.body.classList.remove(`theme-${theme.theme}`); return () => document.body.classList.remove(`theme-${theme.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]);
return ( return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider> <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
); );