import {
useEffect,
useRef,
useState,
type ReactNode,
} from "react";
import { cn } from "../../lib/cn";
import { Button, type ButtonTone } from "../button";
export type MenuItem = {
disabled?: boolean;
label: string;
leadingIcon?: ReactNode;
onSelect?: () => void;
tone?: "default" | "destructive";
};
export function Menu({
className,
items,
}: {
className?: string;
items: MenuItem[];
}) {
return (
{items.map((item) => (
))}
);
}
export function DropdownMenu({
align = "left",
className,
items,
label,
tone = "secondary",
}: {
align?: "center" | "left" | "right";
className?: string;
items: MenuItem[];
label: string;
tone?: Exclude;
}) {
const containerRef = useRef(null);
const [open, setOpen] = useState(false);
const menuPlacement = align === "center" ? "left-1/2 -translate-x-1/2" : align === "right" ? "right-0" : "left-0";
useEffect(() => {
function handlePointerDown(event: PointerEvent) {
if (!containerRef.current?.contains(event.target as Node)) {
setOpen(false);
}
}
function handleEscape(event: KeyboardEvent) {
if (event.key === "Escape") {
setOpen(false);
}
}
window.addEventListener("pointerdown", handlePointerDown);
window.addEventListener("keydown", handleEscape);
return () => {
window.removeEventListener("pointerdown", handlePointerDown);
window.removeEventListener("keydown", handleEscape);
};
}, []);
return (
);
}