DEV Community

Cover image for How to create a Popover using Tailwind CSS.
ABU SAID
ABU SAID

Posted on

How to create a Popover using Tailwind CSS.

Popover is a common UI element in web applications, providing a way to display additional information or options when interacting with a particular element. With React and TailwindCSS, most of the time developers use an npm library for the Popover or Popover. You know, when we use an npm library, it increases the project build sizes.
In this article, I will create a reusable Popover component using Tailwind CSS. We will use click and hover triggers for the Popover.

The Popover component:

// @flow strict
"use client"
import { useEffect, useRef, useState } from "react";

function ReactPopover({
  children,
  content,
  trigger = "click"
}) {
  const [show, setShow] = useState(false);
  const wrapperRef = useRef(null);

  const handleMouseOver = () => {
    if (trigger === "hover") {
      setShow(true);
    };
  };

  const handleMouseLeft = () => {
    if (trigger === "hover") {
      setShow(false);
    };
  };

  useEffect(() => {
    function handleClickOutside(event) {
      if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
        setShow(false);
      }
    }

    if (show) {
      // Bind the event listener
      document.addEventListener("mousedown", handleClickOutside);
      return () => {
        // Unbind the event listener on clean up
        document.removeEventListener("mousedown", handleClickOutside);
      };
    }
  }, [show, wrapperRef]);

  return (
    <div
      ref={wrapperRef}
      onMouseEnter={handleMouseOver}
      onMouseLeave={handleMouseLeft}
      className="w-fit h-fit relative flex justify-center">
      <div
        onClick={() => setShow(!show)}
      >
        {children}
      </div>
      <div
        hidden={!show}
        className="min-w-fit w-[200px] h-fit absolute bottom-[100%] z-50 transition-all">
        <div className="rounded bg-white p-3 shadow-[10px_30px_150px_rgba(46,38,92,0.25)] mb-[10px]">
          {content}
        </div>
      </div>
    </div>
  );
};

export default ReactPopover;
Enter fullscreen mode Exit fullscreen mode

In this component the trigger default value is click and you can pass hover as an attribute. When you click outside of the Popover, the Popover will be closed.

Use the Popover component:

import ReactPopover from "@/components/common/react-popover";

const Page = () => {
  return (
    <div className="w-screen h-screen flex justify-center items-center gap-4">
      <ReactPopover
        content={
          <p>This Content Will be render in Popover.</p>
        }
      >
        <button className="bg-indigo-500 px-4 py-1.5 border rounded text-white">
          Click me
        </button>
      </ReactPopover>
      <ReactPopover
        trigger="hover"
        content={
          <p>This Content Will be render in Popover.</p>
        }
      >
        <button className="bg-indigo-500 px-4 py-1.5 border rounded text-white">
          Hover me
        </button>
      </ReactPopover>
    </div>
  );
};

export default Page;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)