Skip to content

Commit

Permalink
Merge pull request #509 from sparcs-kaist/dev
Browse files Browse the repository at this point in the history
Main branch update from Dev branch
  • Loading branch information
14KGun authored Apr 6, 2023
2 parents c456953 + 5adc089 commit 3f627b5
Show file tree
Hide file tree
Showing 22 changed files with 237 additions and 161 deletions.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CookiesProvider } from "react-cookie";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";

import ModalProvider from "components/Modal/ModalProvider";
import Skeleton from "components/Skeleton";
import AlertProvider from "components/Skeleton/AlertProvider";
import CSSVariablesProvider from "components/Skeleton/CSSVariablesProvider";
Expand Down Expand Up @@ -38,6 +39,7 @@ const App = () => {
<FirebaseMessagingProvider />
<I18nextProvider />
<AlertProvider />
<ModalProvider />
<CSSVariablesProvider />
<Skeleton>
<Switch>
Expand Down
15 changes: 15 additions & 0 deletions src/atoms/modals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ModalElemProps } from "components/Modal/ModalElem";

import { atom } from "recoil";

export type ModalType = {
id: string;
props: ModalElemProps;
};

const modalsAtom = atom<Array<ModalType>>({
key: "modalsAtom",
default: [],
});

export default modalsAtom;
109 changes: 0 additions & 109 deletions src/components/Modal.jsx

This file was deleted.

126 changes: 126 additions & 0 deletions src/components/Modal/ModalElem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {
MouseEvent,
ReactNode,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";

import { useDelayBoolean } from "hooks/useDelay";
import useDisableScrollEffect from "hooks/useDisableScrollEffect";
import useKeyboardOperationEffect from "hooks/useKeyboardOperationEffect";

import RLayout from "components/RLayout";

import theme from "tools/theme";

import CloseRoundedIcon from "@mui/icons-material/CloseRounded";

export type ModalElemProps = {
isOpen: boolean;
onChangeIsOpen?: (isOpen: boolean) => void;
onEnter?: () => void;
displayCloseBtn?: boolean;
width?: PixelValue;
padding?: Padding;
children: ReactNode;
isAlert?: boolean;
};

const ModalElem = ({
isOpen,
onChangeIsOpen,
onEnter,
displayCloseBtn = true,
width = theme.modal_width,
padding = "0px",
children,
isAlert = false,
}: ModalElemProps) => {
const [display, setDisplay] = useState(false);
const shouldMount = useDelayBoolean(isOpen, theme.duration_num);
const modalRef = useRef<HTMLDivElement>(null);
const clickRef = useRef(false);

const closeHandler = useCallback(
onChangeIsOpen ? () => onChangeIsOpen(false) : () => {},
[onChangeIsOpen]
);
const onMouseDown = useCallback(({ target }: MouseEvent) => {
if (!modalRef.current?.contains(target as Node)) {
clickRef.current = true;
}
}, []);
const onMouseUp = useCallback(
({ target }: MouseEvent) => {
if (clickRef.current && !modalRef.current?.contains(target as Node)) {
closeHandler();
}
clickRef.current = false;
},
[closeHandler]
);

useDisableScrollEffect(isOpen);
useKeyboardOperationEffect({
onEnter: isOpen ? onEnter : undefined,
onEscape: isOpen ? closeHandler : undefined,
});
useEffect(() => {
setDisplay(shouldMount && isOpen);
}, [shouldMount, isOpen]);

const styleBgd = {
position: "fixed" as any,
display: "flex",
top: "0px",
left: "0px",
width: "100%",
height: "calc(100% + 1px)", // useDisableScrollEffect 로 감소된 1px을 보정
zIndex: isAlert ? theme.zIndex_alert : theme.zIndex_modal,
background: isAlert ? theme.black_40 : theme.black_60,
opacity: display ? 1 : 0,
transition: `opacity ${theme.duration} ease-in-out`,
pointerEvents: (isOpen ? "auto" : "none") as any,
};
const styleBody = {
position: "relative" as any,
background: theme.white,
borderRadius: "15px",
padding: padding,
minHeight: "148px",
maxHeight: "720px",
display: "flex",
flexDirection: "column" as any,
boxSizing: "border-box" as any,
};
const styleBtn: CSS = useMemo(
() => ({
color: theme.gray_text,
position: "absolute",
top: "10px",
right: "10px",
fontSize: "24px",
cursor: "pointer",
}),
[]
);

if (!shouldMount) return null;
return (
<div css={styleBgd} onMouseDown={onMouseDown} onMouseUp={onMouseUp}>
<RLayout.Popup width={parseFloat(width.replace("px", ""))}>
<div ref={modalRef} css={styleBody}>
{children}
{displayCloseBtn && (
<CloseRoundedIcon style={styleBtn} onClick={closeHandler} />
)}
</div>
</RLayout.Popup>
</div>
);
};

export default ModalElem;
11 changes: 11 additions & 0 deletions src/components/Modal/ModalProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ModalElem from "./ModalElem";

import modalsAtom from "atoms/modals";
import { useRecoilValue } from "recoil";

const ModalProvider = () => {
const modals = useRecoilValue(modalsAtom);
return modals.map(({ id, props }) => <ModalElem key={id} {...props} />);
};

export default ModalProvider;
28 changes: 28 additions & 0 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffect } from "react";

import useDateToken from "hooks/useDateToken";

import { ModalElemProps } from "./ModalElem";

import modalsAtom from "atoms/modals";
import { useSetRecoilState } from "recoil";

const Modal = (props: ModalElemProps) => {
const [id] = useDateToken();
const setModals = useSetRecoilState(modalsAtom);

useEffect(() => {
setModals((prev) => [...prev, { id, props }]);
return () => setModals((prev) => prev.filter((modal) => modal.id !== id));
}, []);

useEffect(() => {
setModals((prev) =>
prev.map((modal) => (modal.id === id ? { id, props } : modal))
);
}, Object.values(props));

return null;
};

export default Modal;
7 changes: 3 additions & 4 deletions src/components/RoomOptions/Place.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ const PopupInput = (props) => {

return (
<Modal
display={props.isOpen}
onClickClose={props.onClose}
isOpen={props.isOpen}
onChangeIsOpen={props.onClose}
onEnter={onClick}
width={335}
closeBtn={false}
displayCloseBtn={false}
>
<div style={{ height: "266px" }}>
<div style={{ width: "calc(100% - 20px)", marginLeft: "10px" }}>
Expand Down
7 changes: 3 additions & 4 deletions src/components/RoomOptions/Time.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,10 @@ const PopupInput = (props: PopupInputProps) => {

return (
<Modal
display={props.isOpen}
onClickClose={props.onClose}
isOpen={props.isOpen}
onChangeIsOpen={props.onClose}
onEnter={onClick}
width={335}
closeBtn={false}
displayCloseBtn={false}
>
<div style={style}>
<div style={styleContainer}>
Expand Down
22 changes: 11 additions & 11 deletions src/components/Skeleton/AlertProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ReactNode, useRef } from "react";
import { ReactNode, useCallback, useRef } from "react";

import Button from "components/Button";
import DottedLine from "components/DottedLine";
import Modal from "components/Modal";
import ModalElem from "components/Modal/ModalElem";

import alertAtom from "atoms/alert";
import { useRecoilState } from "recoil";
Expand All @@ -15,17 +15,17 @@ const AlertProvider = () => {
const messageCache = useRef<ReactNode>("");
const [message, setMessage] = useRecoilState(alertAtom);

const onClickClose = () => setMessage(null);
const closeHandler = useCallback(() => setMessage(null), [setMessage]);
if (message) messageCache.current = message;

return (
<Modal
display={!!message}
onClickClose={onClickClose}
width={315}
<ModalElem
isOpen={!!message}
onChangeIsOpen={closeHandler}
width={theme.modal_width_alert}
padding="10px"
closeBtn={false}
alert
displayCloseBtn={false}
isAlert
>
<div
style={{
Expand Down Expand Up @@ -56,11 +56,11 @@ const AlertProvider = () => {
padding="9px 10px"
radius={8}
font={theme.font14_bold}
onClick={onClickClose}
onClick={closeHandler}
>
확인
</Button>
</Modal>
</ModalElem>
);
};

Expand Down
Loading

0 comments on commit 3f627b5

Please sign in to comment.