Popover

A popover component that displays content when clicked or hovered. The position of the popover can be customized.

Copy this code and create a new component at @/components/Popover

Popover component is useful for showing extra information, tooltips, or actions when the user clicks or hovers over an element.


//@/components/Popover/Popover.tsx

"use client";

import React, { useState } from "react";

interface PopoverProps {
  trigger: React.ReactNode;
  content: React.ReactNode;
  position?: "top" | "bottom" | "left" | "right";
  triggerType?: "click" | "hover";
}

const popoverStyles = {
  base: "relative inline-block",
  popoverContent: "absolute w-[10rem] z-10 p-4 bg-gray-800 text-white rounded-md shadow-lg transition-opacity duration-300",
  top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2",
  bottom: "top-full left-1/2 transform -translate-x-1/2 mt-2",
  left: "top-1/2 right-full transform -translate-y-1/2 mr-2",
  right: "top-1/2 left-full transform -translate-y-1/2 ml-2",
};

const Popover: React.FC<PopoverProps> = ({
  trigger,
  content,
  position = "top",
  triggerType = "click", // Default to 'click'
}) => {
  const [isOpen, setIsOpen] = useState(false);

  // Toggle popover for click trigger type
  const togglePopover = () => {
    setIsOpen(!isOpen);
  };

  // Show popover on mouse enter for hover trigger type
  const handleMouseEnter = () => {
    if (triggerType === "hover") {
      setIsOpen(true);
    }
  };

  // Hide popover on mouse leave for hover trigger type
  const handleMouseLeave = () => {
    if (triggerType === "hover") {
      setIsOpen(false);
    }
  };

  return (
    <div
      className={popoverStyles.base}
      onClick={triggerType === "click" ? togglePopover : undefined}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      aria-haspopup="true"
      aria-expanded={isOpen ? "true" : "false"}
    >
      <div>{trigger}</div>
      {isOpen && (
        <div
          className={`${popoverStyles.popoverContent} ${
            position === "top"
              ? popoverStyles.top
              : position === "bottom"
              ? popoverStyles.bottom
              : position === "left"
              ? popoverStyles.left
              : popoverStyles.right
          }`}
        >
          {content}
        </div>
      )}
    </div>
  );
};
export {Popover}