index.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React from "react";
  2. import { Button } from "src/components/Button";
  3. import useKeyPress from "src/hooks/useKeyPress";
  4. import * as Styled from "./styles";
  5. type ControlProps = React.PropsWithChildren<{
  6. setVisible: (status: boolean) => void;
  7. }>;
  8. export type ReactComponent = React.FC<React.PropsWithChildren<{}>>;
  9. type ModalTypes = {
  10. Header: ReactComponent;
  11. Content: ReactComponent;
  12. Controls: React.FC<ControlProps>;
  13. };
  14. export interface ModalProps {
  15. visible: boolean;
  16. setVisible: React.Dispatch<React.SetStateAction<boolean>> | ((visible: boolean) => void);
  17. size?: "sm" | "md" | "lg";
  18. }
  19. const Header: ReactComponent = ({ children }) => {
  20. return (
  21. <Styled.HeaderWrapper>
  22. <Styled.Title>{children}</Styled.Title>
  23. </Styled.HeaderWrapper>
  24. );
  25. };
  26. const Content: ReactComponent = ({ children }) => {
  27. return <Styled.ContentWrapper>{children}</Styled.ContentWrapper>;
  28. };
  29. const Controls: React.FC<ControlProps> = ({ children, setVisible }) => {
  30. const handleEspacePress = useKeyPress("Escape");
  31. React.useEffect(() => {
  32. if (handleEspacePress) setVisible(false);
  33. }, [handleEspacePress, setVisible]);
  34. return (
  35. <Styled.ControlsWrapper>
  36. <Button onClick={() => setVisible(false)}>Close</Button>
  37. {children}
  38. </Styled.ControlsWrapper>
  39. );
  40. };
  41. const Modal: React.FC<React.PropsWithChildren<ModalProps>> & ModalTypes = ({
  42. children,
  43. visible,
  44. setVisible,
  45. size = "sm",
  46. }) => {
  47. const onClick = (e: React.SyntheticEvent<HTMLDivElement>) => {
  48. if (e.currentTarget === e.target) {
  49. setVisible(false);
  50. }
  51. };
  52. if (!visible) return null;
  53. return (
  54. <Styled.ModalWrapper onClick={onClick}>
  55. <Styled.ModalInnerWrapper size={size}>{children}</Styled.ModalInnerWrapper>
  56. </Styled.ModalWrapper>
  57. );
  58. };
  59. Modal.Header = Header;
  60. Modal.Content = Content;
  61. Modal.Controls = Controls;
  62. export { Modal };