Components
Dropdown menu
Command list attached to a trigger. Reserve for secondary actions — surface the primary one as a button.
When to useto collect several secondary actions behind one visible trigger — the button-with-a-menu at the end of a card or row.
Import
import {
DropdownMenu, DropdownMenuTrigger, DropdownMenuContent,
DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator,
DropdownMenuItem, DropdownMenuShortcut,
} from "@ravnhq/efni/dropdown-menu"Default
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Actions</Button>} />
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Mission MB-4472</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem><Icon icon={Pencil} />Rename</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive"><Icon icon={Trash2} />Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Accessibility
| Key | Action |
|---|---|
| Enter / Space | Open the menu, or activate the focused item. |
| ArrowDown / ArrowUp | Move between items, skipping separators and labels. |
| Home / End | Jump to first / last item. |
| Escape | Close the menu and return focus to the trigger. |
DropdownMenuLabelMUST live inside aDropdownMenuGroup— Base UI throwsMenuGroupContext is missingotherwise.- Never wrap the trigger's inner content in a Button — the trigger IS a button. Apply buttonVariants() to className instead if you need custom styling.
Guidelines
Do
- Group by object with a label at the top; the label describes what the actions target.
- Assign shortcuts to the most-used items and display them on the right.
- Reserve the destructive variant for the last item, separated from others.
Don't
- Don't nest more than one submenu level.
- Don't put more than ~7 items in one group without a separator.
- Don't use a dropdown menu for the primary action — that belongs on a button.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the menu is currently open. |
onOpenChange | ((open: boolean, eventDetails: MenuRoot.ChangeEventDetails) => void) | — | Event handler called when the menu is opened or closed. |
DropdownMenuTrigger.render | React.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
DropdownMenuContent.side | "top" | "bottom" | "left" | "right" | "inline-end" | "inline-start" | "bottom" | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
DropdownMenuContent.align | "center" | "start" | "end" | "start" | How to align the popup relative to the specified side. |
DropdownMenuItem.variant | "default" | "destructive" | "default" | Destructive tone for delete-style actions. |
DropdownMenuItem.disabled | boolean | false | Whether the component should ignore user interaction. |
DropdownMenuItem.onClick | BaseUIComponentProps<'div', MenuItemState>['onClick'] | — | The click handler for the menu item. |
DropdownMenuItem.inset | boolean | — | Indent to line up with items that have an icon or a checkmark. |
…props | MenuPrimitive.Root.Props | — | Everything DropdownMenu passes to the element it renders. |