DEV Community

Cover image for Create Modal Component with React Hooks
Nabilla Trisnani
Nabilla Trisnani

Posted on • Edited on

Create Modal Component with React Hooks

For this tutorial we're going to make Modal with React Hooks.

1. Create a button

First, let's create a button inside our Modal.js file

{/* Modal.js */}

import React from 'react';

export default function Modal() {
  return (
    <div>
      <button className="btn btn-toggle btn-primary">
        Click Me!
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* style.css */

/* base */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');

* {
  font-family: 'Poppins', sans-serif;
}
body {
  padding: 0;
  margin: 0;
}

/* button */
.btn {
  border: none;
  padding: 9px 18px;
  border-radius: 8px;
}
.btn-toggle {
  font-weight: 600;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%);
}
.btn-primary {
  background-color: #0085ff;
  color: #ffffff;
}
Enter fullscreen mode Exit fullscreen mode

2. Create Modal

Then, add our modal code just below the button

{/* Modal.js */}

import React from 'react';

export default function Modal() {
  return (
    <div>
      <button className="btn btn-toggle btn-primary">
        Click Me!
      </button>

      <div className="modal-container"></div>

      <div className="modal-dialog">
          <div className="modal-content">
            <div className="modal-header">
              <h3>Modal Header</h3>
              <button className="modal-close">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="25"
                  height="25"
                  preserveAspectRatio="xMidYMid meet"
                  viewBox="0 0 24 24"
                >
                  <path
                    fill="currentColor"
                    d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6Z"
                  />
                </svg>
              </button>
            </div>
            <div className="modal-body">
              <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae
                culpa, inventore alias ab atque similique quod ea reprehenderit.
              </p>
            </div>
            <div className="modal-footer">
              <button className="btn">
                Close
              </button>
              <button className="btn btn-primary">Okay</button>
            </div>
          </div>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* style.css */

/* modal */
.modal-container {
  width: 100%;
  min-height: 100vh;
  position: absolute;
  top: 0;
  background-color: #0000007d;
}
.modal-dialog {
  max-width: 500px;
  margin-right: auto;
  margin-left: auto;
  display: flex;
  align-items: center;
  min-height: calc(100vh - 2.1rem * 2);
  max-height: calc(100vh - 2.1rem * 2);
}
.modal-content {
  border: 1px solid #e0dcda;
  border-radius: 12px;
  background-color: #ffffff;
  position: relative;
}
.modal-header {
  border-bottom: 1px solid #e0dcda;
  padding: 14px 16px;
  border-radius: 12px 12px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.modal-header .modal-close {
  background: transparent;
  border: none;
  display: flex;
  justify-content: center;
  align-items: center;
}
.modal-header h3 {
  margin-bottom: 0;
  margin-top: 0;
  font-size: 16px;
  font-weight: 600;
}
.modal-body {
  padding: 16px;
  overflow-y: auto;
  max-height: calc(100vh - 7rem * 2);
}
.modal-footer {
  border-top: 1px solid #e0dcda;
  padding: 14px 16px;
  border-radius: 0 0 12px 12px;
  display: flex;
}
.modal-footer .btn:first-child {
  margin-right: 8px;
  margin-left: auto;
}
Enter fullscreen mode Exit fullscreen mode

3. Add onClick handler

So the logic is when the btn-toggle is clicked, it will set state show to true and then add class show to modal-dialog and when the modal-container or modal-close button is clicked, it will set state show to false and then add class hide to modal-dialog.

{/* Modal.js */}

import React, { useState } from 'react';

export default function Modal() {
  const [show, setShow] = useState(false);

  const handleShow = () => {
    setShow((current) => !current);
  };

  return (
    <div>
      <button className="btn btn-toggle btn-primary" onClick={handleShow}>
        Default Modal
      </button>
      <div
        className={`modal-container ${show === true ? 'show' : 'hide'}`}
        onClick={handleShow}
      ></div>
      <div className={`modal-dialog ${show === true ? 'show' : 'hide'}`}>
        <div className="modal-content">
          <div className="modal-header">
            <h3>Default Modal</h3>
            <button className="modal-close" onClick={handleShow}>
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="25"
                height="25"
                preserveAspectRatio="xMidYMid meet"
                viewBox="0 0 24 24"
              >
                <path
                  fill="currentColor"
                  d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6Z"
                />
              </svg>
            </button>
          </div>
          <div className="modal-body">
            <p>
              Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae
              culpa, inventore alias ab atque similique quod ea reprehenderit.
            </p>
          </div>
          <div className="modal-footer">
            <button className="btn" onClick={handleShow}>
              Close
            </button>
            <button className="btn btn-primary">Okay</button>
          </div>
        </div>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* style.css */

/* important part */
.hide {
  display: none;
}
.show {
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

Static Modal

For static modal, simply remove the function handleShow in modal-container

{/* Modal.js */}

{/* ... */}

{/* remove the onClick in modal-container */}
<div className={`modal-container ${show === true ? 'show' : 'hide'}`}></div>

{/* ... */}
Enter fullscreen mode Exit fullscreen mode

Scrollable Modal

You can also make a scrollable modal.
Simply add overflow-y: auto; and max-height to our modal-body in our CSS file.

/* style.css */

.modal-body {
  padding: 16px;
  overflow-y: auto;
  max-height: calc(100vh - 7rem * 2);
}
Enter fullscreen mode Exit fullscreen mode

With Image Inside Modal

Image can also be included inside our modal.
Just don't forget to set our image's width to 100% so it will fit inside our modal-body

{/* Modal.js */}

{/* ... */}

{/* remove the onClick in modal-container */}
<div className="modal-body">
  <img
    className="modal-img"
    src="https://asset.kompas.com/crops/NsA-H96AvvPUMjunfBGSqylkSUI=/0x0:1000x667/750x500/data/photo/2022/07/29/62e36ad288459.jpg"
    alt="Dobberman"
  />
  <br />
  <br />
  <p>This is an image of a black dobberman</p>
</div>

{/* ... */}
Enter fullscreen mode Exit fullscreen mode
/* style.css */

.modal-img {
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

And just like that, you have created your own react hooks modal without any additional library. You can check the repo here.

Thanks for coming by and Peace ✌


Author

Top comments (0)