<div id="root">
    <!-- This element's contents will be replaced with your component. -->
</div>
.App {
  font-family: sans-serif;
  text-align: center;
}

.modal-container {
  z-index: 999;
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.7);
  font-size: 15px;
  font-weight: bold;
  color: #62626e;
}

.modal-content {
  width: 80%;
  height: 90%;
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid #d8dce3;
  border-radius: 3px;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.5);
  background-color: #f7f8fa;
}

.modal-header {
  padding: 9px 10px;
  padding-left: 20px;
  height: 38px;
  font-size: 15px;
  position: relative;
}

.cross-btn {
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  position: absolute;
  right: 10px;
  font-weight: bold;
  cursor: pointer;
}

.modal-body {
  flex-grow: 1;
  border-top: solid 1px #d8dce3;
  padding: 14px 29px 14px 19px;
}

.modal-footer {
  border-top: solid 1px #d8dce3;
  padding: 10px 20px;
  display: flex;
  justify-content: flex-end;
}

.close-btn {
  font-weight: 600;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 2px 2px 0px;
  background-color: rgb(77, 144, 255);
  color: rgb(247, 248, 250);
  height: 35px;
  width: 117px;
  font-size: 14px;
  border-radius: 3px;
  border-width: 1px;
  border-style: solid;
  border-color: rgb(43, 123, 255);
  cursor: pointer;
}
function App() {
  const [isModalVisible, setIsModalVisible] = React.useState(false);

  return (
    <div className="App">
      <h1>Parent container</h1>
      <h3>This is just a demo container</h3>
      <button onClick={() => setIsModalVisible(true)}>open modal</button>
      {isModalVisible && (
        <Modal onModalClose={() => setIsModalVisible(false)}>
          <Modal.Header>Header</Modal.Header>
          <Modal.Body>Body</Modal.Body>
          <Modal.Footer>
            <Modal.Footer.CloseBtn>Close</Modal.Footer.CloseBtn>
          </Modal.Footer>
        </Modal>
      )}
    </div>
  );
}


const modalContext = React.createContext();

function Modal({ children, onModalClose }) {
  React.useEffect(() => {
    function keyListener(e) {
      const listener = keyListenersMap.get(e.keyCode);
      return listener && listener(e);
    }
    document.addEventListener("keydown", keyListener);

    return () => document.removeEventListener("keydown", keyListener);
  });

  const modalRef = React.createRef();
  const handleTabKey = e => {
    const focusableModalElements = modalRef.current.querySelectorAll(
      'a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select'
    );
    const firstElement = focusableModalElements[0];
    const lastElement =
      focusableModalElements[focusableModalElements.length - 1];

    if (!e.shiftKey && document.activeElement !== firstElement) {
      firstElement.focus();
      return e.preventDefault();
    }

    if (e.shiftKey && document.activeElement !== lastElement) {
      lastElement.focus();
      e.preventDefault();
    }
  };

  const keyListenersMap = new Map([[27, onModalClose], [9, handleTabKey]]);

  return ReactDOM.createPortal(
    <div className="modal-container" role="dialog" aria-modal="true">
      <div className="modal-content" ref={modalRef}>
        <modalContext.Provider value={{ onModalClose }}>
          {children}
        </modalContext.Provider>
      </div>
    </div>,
    document.body
  );
}

Modal.Header = function ModalHeader(props) {
  const { onModalClose } = React.useContext(modalContext);

  return (
    <div className="modal-header">
      {props.children}
      <button className="cross-btn" title="close modal" onClick={onModalClose}></button>
    </div>
  );
};

Modal.Body = function ModalBody(props) {
  return <div className="modal-body">{props.children}</div>;
};

Modal.Footer = function ModalFooter(props) {
  return <div className="modal-footer">{props.children}</div>;
};

Modal.Footer.CloseBtn = function CloseBtn(props) {
  const { onModalClose } = React.useContext(modalContext);
  return (
    <button
      {...props}
      className="close-btn"
      title="close modal"
      onClick={onModalClose}
    />
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/react/umd/react.development.js
  2. https://unpkg.com/react-dom/umd/react-dom.development.js