A customizable dropdown menu with grouped options and callbacks for selection.
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 };