Dropdown Menu
Compact action menu for contextual operations.
01 Live Demo
Last action: None
02 Code Snippet
src/ui/DropdownMenu.tsx
import { DropdownMenu } from "@/ui/DropdownMenu"; <DropdownMenu.Root> <DropdownMenu.Trigger>Actions</DropdownMenu.Trigger> <DropdownMenu.Content> <DropdownMenu.Label>Profile</DropdownMenu.Label> <DropdownMenu.Item onSelect={() => console.log("Edit")}>Edit profile</DropdownMenu.Item> <DropdownMenu.Item onSelect={() => console.log("Invite")}>Invite member</DropdownMenu.Item> <DropdownMenu.Separator /> <DropdownMenu.Item onSelect={() => console.log("Delete")}>Delete project</DropdownMenu.Item> </DropdownMenu.Content> </DropdownMenu.Root>
03 Copy-Paste (Single File)
DropdownMenu.tsx
import { useState, type ReactNode } from "react"; function DropdownMenuRoot({ children }: { children: ReactNode }) { return <div className="relative inline-block">{children}</div>; } function DropdownMenuContent({ open, children }: { open: boolean; children: ReactNode }) { if (!open) return null; return <div className="absolute right-0 top-[calc(100%+8px)] min-w-56 rounded-xl border border-slate-200 bg-white p-1 shadow-xl">{children}</div>; } function DropdownMenuItem({ onClick, children }: { onClick?: () => void; children: ReactNode }) { return <button type="button" onClick={onClick} className="flex w-full rounded-lg px-2.5 py-2 text-left text-sm hover:bg-slate-50">{children}</button>; } type DropdownMenuCompound = typeof DropdownMenuRoot & { Root: typeof DropdownMenuRoot; Content: typeof DropdownMenuContent; Item: typeof DropdownMenuItem; }; export const DropdownMenu = Object.assign(DropdownMenuRoot, { Root: DropdownMenuRoot, Content: DropdownMenuContent, Item: DropdownMenuItem }) as DropdownMenuCompound; function Example() { const [open, setOpen] = useState(false); return ( <DropdownMenu.Root> <button onClick={() => setOpen((v) => !v)}>Open</button> <DropdownMenu.Content open={open}> <DropdownMenu.Item onClick={() => setOpen(false)}>Edit</DropdownMenu.Item> </DropdownMenu.Content> </DropdownMenu.Root> ); }