<div id="root"></div><div id="root"></div><div id="root"></div>
.voces-regular {
  font-family: "Voces", sans-serif;
  font-weight: 400;
  font-style: normal;
}
const { useState, useRef, useCallback, useEffect, forwardRef, memo } = React;
const { createGlobalStyle } = styled;

const useModal = (initialShow: boolean): [boolean, () => void] => {
  const [show, setShow] = useState(initialShow);

  const closeModal = () => setShow(false);

  useEffect(() => {
    setShow(initialShow);
  }, [initialShow]);

  return [show, closeModal];
};

type ButtonComponentProps = {
  disabled?: boolean;
  color?: {
    background?: string;
    text?: string;
  };
  callback?: () => void;
  children: React.ReactNode;
  fontSize?: string
};

const StyledButton = styled.button<ButtonComponentProps>`
  background-color: ${({ color }) => (color && color.background) || "lightgray"};
  border: none;
  border-radius: 0.3em;
  color: ${({ color }) => (color && color.text) || "#333333"};
  cursor: pointer;
  font-size: ${({ fontSize }) => (fontSize && fontSize) || "1em"};
  outline: none;
  opacity: ${({ disabled }) => disabled && .3 || 1};;
  padding: ${({ fontSize }) => fontSize && fontSize || "1em"};
  width: 100%;
`;

const Button = ({ className, onClick, color, fontSize, disabled, children }: ButtonComponentProps) => {
  return (
    <StyledButton
      className={className}
      onClick={onClick}
      color={color}
      fontSize={fontSize}
      disabled={disabled}
    >{children}</StyledButton>
  );
};

type ModalComponentProps = {
  className?: string;
  initialShow?: boolean;
  showCloseButton?: boolean;
  closableOverlay?: boolean;
  //closeable?: boolean;
};

const StyledModal = styled.div`
  background-color: #fff;
  border-radius: .4em;
  box-shadow: 0 .5em .6em 0 rgba(0,0,0,0.2),0 .6em 2em 0 rgba(0,0,0,0.17);
  color: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1em;
  position: relative;
  min-height: 14em;
  min-width: 20em;

  & .modal-close-button {
    background: transparent;//#6486ed;
    color: #aaa;
    border-radius: 100%;
    display: block;
    font-size: 1.4em;
    height: 2.4em;
    padding: 0;
    position: absolute;
    top: 0;//-1.2em;
    right: 0;//-1.2em;
    width: 2.4em;
  }
`;

const Overlay = styled.div`
  background-color: rgba(0, 0, 0, .5);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 2000;
`;

const ModalContent = styled.p`
  text-align: center;
`;

const Modal = ({ className, initialShow=true, showCloseButton=true, closableOverlay=true, children }: ModalComponentProps) => {
  const [show, closeModal] = useModal(initialShow);

  return show ? (
    <Overlay className="modal-overlay" {...(closableOverlay && {onClick: closeModal})}>
      <StyledModal className={className} onClick={e => e.stopPropagation()}>
        <ModalContent className="modal-content">{children}</ModalContent>
        {showCloseButton && <Button
          className="modal-close-button"
          onClick={closeModal}
        >×</Button>}
      </StyledModal>
    </Overlay>
  ) : null;
};

const GlobalStyle = createGlobalStyle`
  html {
    
  }
    body {
    background-color: #C7E5E6;
    text-align: center;
    }
`;

const App = () => {
  return (
    <div>
    <GlobalStyle />
    <h1>Hello world!</h1>
      <Modal className="voces-regular">
          <div>
            <h1>Modal</h1>
            <p>something</p>
          </div>
        </Modal>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/styled-components/6.1.8/styled-components.min.js