Dropdown Menu

A customizable dropdown menu with grouped options and callbacks for selection.

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

Custom dropdown menus for navigation or settings.


// @/components/DropdownMenu/DropdownMenu.tsx

import React, { useState } from "react";

interface DropdownMenuProps {
  buttonText: string;
  buttonStyles?: string;
  children?: React.ReactNode; // Explicitly type 'children'
}

interface DropdownMenuOptionGroupProps {
  options: string[];
  onSelect: (option: string) => void;
  menuLabel?: string;
}

// DropdownMenuOptionGroup Component
const DropdownMenuOptionGroup: React.FC<DropdownMenuOptionGroupProps> = ({
  options,
  onSelect,
  menuLabel,
}) => {
  const handleSelect = (option: string) => {
    onSelect(option);
  };

  return (
    <ul className="text-gray-700">
      {menuLabel && (
        <p className="px-4 py-2 border-b-[1px] border-t-[1px] border-zinc-700 text-white font-bold">
          {menuLabel}
        </p>
      )}
      {options.map((option) => (
        <li
          key={option}
          className="px-4 py-2 text-white rounded-md hover:bg-zinc-800 cursor-pointer"
          onClick={() => handleSelect(option)}
        >
          {option}
        </li>
      ))}
    </ul>
  );
};

// DropdownMenu Component
const DropdownMenu: React.FC<DropdownMenuProps> = ({ buttonText, children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const toggleMenu = () => setIsOpen(!isOpen);

  return (
    <div className="relative">
      <button
        onClick={toggleMenu}
        className="px-4 py-2 bg-zinc-600 overflow-hidden text-white rounded-md hover:bg-zinc-700"
      >
        {buttonText}
      </button>
      {isOpen && (
        <div className="absolute mt-2 w-48 bg-zinc-950 border border-zinc-700 rounded-md shadow-lg z-10">
          {children}
        </div>
      )}
    </div>
  );
};

export { DropdownMenu, DropdownMenuOptionGroup };