diff --git a/public/2D_material/modal.webp b/public/2D_material/modal.webp new file mode 100644 index 0000000..6eabff7 Binary files /dev/null and b/public/2D_material/modal.webp differ diff --git a/src/components/ui/Modal/index.module.css b/src/components/ui/Modal/index.module.css new file mode 100644 index 0000000..15e77bc --- /dev/null +++ b/src/components/ui/Modal/index.module.css @@ -0,0 +1,21 @@ +.modal-background{ + background-color:#08000080; + width:100%; + height:100%; + position:fixed; + left:0; + top:0; + z-index:0; + +} + +.modal-content-wrapper{ + position:absolute; + left:50%; + top:30%; + translate: -50% -50%; + z-index:10; + border: none; + border-radius: 8px; + overflow: hidden; +} \ No newline at end of file diff --git a/src/components/ui/Modal/index.tsx b/src/components/ui/Modal/index.tsx new file mode 100644 index 0000000..f492711 --- /dev/null +++ b/src/components/ui/Modal/index.tsx @@ -0,0 +1,81 @@ +import { useCallback, useEffect, useRef } from "react"; +import type { FC, ReactNode } from "react"; +import { createPortal } from "react-dom"; +import styles from "./index.module.css"; + +type Props = { + open: boolean; + children: ReactNode; + onClose?: () => void; + onOpen?: () => void; +}; + +export const Modal: FC = ({ + children, + open, + onClose = () => {}, + onOpen = () => {}, +}) => { + const dialogRef = useRef(null); + + const handleShowModal = useCallback(() => { + onOpen(); + dialogRef.current?.showModal(); + }, [onOpen]); + + const handleCloseModal = useCallback(() => { + onClose(); + dialogRef.current?.close(); + }, [onClose]); + + useEffect(() => { + if (open) { + handleShowModal(); + } else { + handleCloseModal(); + } + }, [open, handleShowModal, handleCloseModal]); + + const handleKeyUp = useCallback( + (event: KeyboardEvent) => { + if (event.key === "Escape") { + handleCloseModal(); + } + }, + [handleCloseModal], + ); + + useEffect(() => { + if (open) { + document.addEventListener("keyup", handleKeyUp); + } else { + document.removeEventListener("keyup", handleKeyUp); + } + return () => { + document.removeEventListener("keyup", handleKeyUp); + }; + }, [open, handleKeyUp]); + + return createPortal( + <> + e.key === "Enter" && handleShowModal()} + tabIndex={-1} + > + {children} + + {open && ( +