added simple modal dialog

This commit is contained in:
Fedor Katurov 2023-04-26 15:06:26 +06:00
parent 2d11fef559
commit 3f81f6d3b3
12 changed files with 157 additions and 7 deletions

View file

@ -4,11 +4,14 @@ import { Editor } from "~/pages/editor";
import "./styles/main.scss";
import { ThemeProvider } from "./modules/theme/containers/ThemeProvider";
import { SettingsProvider } from "./modules/settings/providers/SettingsProvider";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<ThemeProvider>
<Editor />
</ThemeProvider>
<SettingsProvider>
<ThemeProvider>
<Editor />
</ThemeProvider>
</SettingsProvider>
</React.StrictMode>
);

View file

@ -6,6 +6,7 @@ import { GridLayoutItemWrapper } from "../GridLayoutItemWrapper";
import { splitLayoutVertical } from "./utils/splitLayoutVertical";
import { splitLayoutHorizontal } from "./utils/splitLayoutHorizontal";
import styles from "./styles.module.scss";
import { useSettings } from "~/modules/settings/context/SettingsContext";
export interface GridLayoutProps {
component: FC<GridLayoutComponentProps>;
@ -22,6 +23,8 @@ const DefaultLayout = ({
panelProps,
persistLayout,
}: DefaultLayoutProps) => {
const { show: showSettings } = useSettings();
const splitVertical = useCallback(() => {
splitLayoutVertical(panelProps.api.id, panelProps.containerApi);
}, [panelProps.api.id, panelProps.containerApi]);
@ -54,6 +57,7 @@ const DefaultLayout = ({
remove={remove}
locked={locked}
lock={lock}
showSettings={showSettings}
>
{createElement(component, {
id: panelProps.api.id,

View file

@ -14,12 +14,14 @@ type GridLayoutItemWrapperProps = PropsWithChildren & {
remove: () => void;
locked: boolean;
lock: () => void;
showSettings: () => void;
};
const GridLayoutItemWrapper: FC<GridLayoutItemWrapperProps> = ({
children,
splitVertical,
splitHorizontal,
showSettings,
remove,
locked,
lock,
@ -33,6 +35,7 @@ const GridLayoutItemWrapper: FC<GridLayoutItemWrapperProps> = ({
>
<SplitVertical />
</IconButton>
<IconButton
onClick={splitHorizontal}
role="button"
@ -41,6 +44,14 @@ const GridLayoutItemWrapper: FC<GridLayoutItemWrapperProps> = ({
<SplitHorizontal />
</IconButton>
<IconButton
onClick={showSettings}
role="button"
className={styles.button}
>
S
</IconButton>
{!locked && (
<IconButton onClick={remove} role="button" className={styles.button}>
<DeleteIcon />

View file

@ -0,0 +1,16 @@
import { FC, PropsWithChildren } from "react";
import styles from "./styles.module.scss";
type ModalProps = PropsWithChildren & {
onClose: () => void;
};
const Modal: FC<ModalProps> = ({ children }) => (
<div className={styles.modal}>
<div className={styles.overlay} />
<div className={styles.content}>
<div className={styles.page}>{children}</div>
</div>
</div>
);
export { Modal };

View file

@ -0,0 +1,31 @@
.modal {
position: fixed;
inset: 0;
z-index: 100;
}
.content {
position: absolute;
inset: 0;
z-index: 2;
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
box-sizing: border-box;
}
.page {
background: var(--color-background);
padding: 16px;
border-radius: 10px;
margin: auto;
}
.overlay {
position: absolute;
inset: 0;
z-index: 1;
background: rgba(0, 0, 0, 0.1);
}

View file

@ -0,0 +1,12 @@
import { FC } from "react";
const SettingsContainer: FC = () => (
<div>
<label htmlFor="color">
<input type="color" id="color" />
Sample color switch
</label>
</div>
);
export { SettingsContainer };

View file

@ -0,0 +1,12 @@
import { createContext, useContext } from "react";
export type SettingsValue = Record<string, never>;
export const defaultSettings: SettingsValue = {};
export const SettingsContext = createContext({
settings: defaultSettings,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setSettings: (_: SettingsValue) => {},
show: () => {},
hide: () => {},
});
export const useSettings = () => useContext(SettingsContext);

View file

@ -0,0 +1,29 @@
import { FC, PropsWithChildren, useCallback, useState } from "react";
import { Modal } from "~/modules/modal/containers/Modal";
import { SettingsContainer } from "../../containers/SettingsContainer";
import {
SettingsContext,
defaultSettings,
} from "../../context/SettingsContext";
const SettingsProvider: FC<PropsWithChildren> = ({ children }) => {
const [settings, setSettings] = useState(defaultSettings);
const [settingsModalVisible, setSettingsModalVisible] = useState(false);
const show = useCallback(() => setSettingsModalVisible(true), []);
const hide = useCallback(() => setSettingsModalVisible(false), []);
return (
<SettingsContext.Provider value={{ settings, setSettings, show, hide }}>
{settingsModalVisible && (
<Modal onClose={hide}>
<SettingsContainer />
</Modal>
)}
{children}
</SettingsContext.Provider>
);
};
export { SettingsProvider };

View file

@ -18,9 +18,16 @@ body {
a {
color: var(--color-link);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
ul {
padding-left: 1em;
li p {
margin: 0.5em 0;
}