Create Custom Modal in React with Tailwind CSS

Aug 27 20233 minutes
Video Tutorial

Modals are beneficial components for showing special messages to the visitor of your website, Although there are ready-made components for react on NPM, building our own custom modal gives us the flexibility to customize it however we want and it’s straightforward, let’s see in this tutorial.

#Prerequisites

Before starting to build Modal make sure that

  1. You have created a react project
  2. Tailwind CSS configured in that

We are going to use Tailwind CSS in this tutorial to build Modal.

#Step 1: Creating a new Modal component

We’ll create a new component for the modal and later import and use it in different parts of our app.

I am going to name this component NewsModal You can name it anything you want or your application needs.

Below is the code for the NewsModal component.

import React, { useEffect, useRef, useState } from "react";

function NewsModal() {
  const [showModal, setShowModal] = useState(true);

  // Reference to the modal's outer div element
  const divRef = useRef(null);

  const closeModal = () => {
    setShowModal(false);
  };

  // Function to handle clicks outside the modal
  const handleClickOutside = (e) => {
    if (divRef.current && !divRef.current.contains(e.target)) {
      setShowModal(false);
    }
  };

  // Adding and removing event listener when the component mounts and unmounts
  useEffect(() => {
    document.addEventListener("click", handleClickOutside);

    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  }, []);

  // Rendering the modal based on the showModal state
  if (showModal) {
    return (
      <div> Hellow from News Modal </div>
    );
  } else {
    return "";
  }
}

export default NewsModal;

In the above code, we have showModal a state that will keep track of whether should we show the modal to visitors or not.

A reference variable divRef is created using the useRef hook. This reference is used to store a reference to the outer div element of the modal. This reference will be used later to check if a click event occurs outside the modal.

CloseModal function is used to just close the Modal by toggling the state showModal to false

handleClickOutside is the function that will decide whether the click was inside the modal or outside.

Now below is the full code for the component

import React, { useEffect, useRef, useState } from "react";

function NewsModal() {
  const [showModal, setShowModal] = useState(true);

  // Reference to the modal's outer div element
  const divRef = useRef(null);

  const closeModal = () => {
    setShowModal(false);
  };

  // Function to handle clicks outside the modal
  const handleClickOutside = (e) => {
    if (divRef.current && !divRef.current.contains(e.target)) {
      setShowModal(false);
    }
  };

  // Adding and removing event listener when the component mounts and unmounts
  useEffect(() => {
    document.addEventListener("click", handleClickOutside);

    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  }, []);

  // Rendering the modal based on the showModal state
  if (showModal) {
    return (
      <>
        <div
          ref={divRef}
          className="news-modal-overlay fixed top-16 left-0 right-0 bottom-10 w-8/12 mx-auto bg-gray-900/80 rounded-xl backdrop-blur-md"
        >
          <div className="news-modal-body flex flex-col gap-4 m-4">
            <h1 className="text-4xl font-bold">Breaking News!</h1>
            <p className="text-2xl">
              We are going to launch the Nextjs course soon!
            </p>
            <img
              src="https://images.unsplash.com/photo-1499951360447-b19be8fe80f5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80"
              alt="good image"
              width={600}
              height={400}
              className="mx-auto"
            />
            <button
              onClick={closeModal}
              className="text-3xl bg-red-500 p-2 w-1/5 mx-auto rounded-xl"
            >
              Close
            </button>
          </div>
        </div>
      </>
    );
  } else {
    return "";
  }
}

export default NewsModal;

Now we can import this code and use it in any main component like app.js or main.js