Overlays & feedback
Dropdown menu
A floating list of actions triggered from a button — row overflow menus, the create button, account menus, view options. Supports icons, shortcuts, sections, submenus, and checkable items, with full keyboard control.
npx shadcn@latest add @orbit/menuOverview
Four common trigger styles, each opening its own action list. Click to open — every menu here is live.
Item types
One menu composes from a handful of row types: section headers, action items with an icon and optional shortcut, dividers, submenus that fly out on hover, checkable items that keep the menu open, and a destructive action set apart at the bottom.
last action: —
Checkable items
MenuCheckboxItem toggles a boolean; MenuRadioGroup + MenuRadioItem hold a single choice. Both keep the menu open on click so several settings can be changed in one visit.
sort: manual · sub-tasks: true
Alignment
The panel aligns to the trigger's start edge by default; use end for right-anchored triggers like an overflow “…” button at the edge of a row.
States
Disabled rows fade to the faint text color and ignore pointer and keyboard activation. Destructive rows use the danger tokens with a danger-soft highlight.
Props
Menu wraps Base UI Menu — the root also accepts open, defaultOpen, and onOpenChange, and every part forwards ...rest (and ref) to its underlying element. Raw parts are re-exported as MenuPrimitive.
<MenuContent>
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "center" | "end" | "start" | Horizontal alignment against the trigger. |
| side | "top" | "bottom" | "left" | "right" | … | "bottom" | Which side of the trigger the panel opens on. |
| sideOffset | number | 6 | Gap between trigger and panel in px. |
| width | string | — | Fixed panel width (e.g. "220px"). Defaults to a 220px minimum that can grow. |
<MenuItem>
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | ReactNode | — | 16px leading icon, rendered ink-soft (danger items render it in danger). |
| shortcut | string | — | Keyboard hint like "⌘+D" — renders one keycap chip per "+"-separated key. |
| danger | boolean | false | Destructive styling: danger text and a danger-soft highlight. |
| disabled | boolean | false | Fades the row and blocks activation. |
| onClick | (event) => void | — | Fired when the item is activated; the menu closes afterwards. |
<MenuCheckboxItem> · <MenuRadioGroup> · <MenuRadioItem>
| Prop | Type | Default | Description |
|---|---|---|---|
| checked / onCheckedChange | boolean / (checked) => void | — | Checkbox item state. Toggling keeps the menu open (override with closeOnClick). |
| value / onValueChange | any / (value) => void | — | On MenuRadioGroup: the selected MenuRadioItem value. |
| value | any | — | On MenuRadioItem: this row's value within its group. |
| icon | ReactNode | — | Radio rows: lead element (icon, color dot, avatar) after the check slot. |
| checkSide | "start" | "end" | "start" | Radio rows: leading check slot, or a trailing check for submenu pickers. |
<MenuSub> · <MenuSubTrigger> · <MenuSubContent>
| Prop | Type | Default | Description |
|---|---|---|---|
| MenuSub | component | — | Submenu root — nest inside MenuContent, opens on hover or →. |
| MenuSubTrigger icon | ReactNode | — | 16px leading icon; a trailing chevron is added automatically. |
| MenuSubContent sideOffset | number | 2 | Gap between the parent panel edge and the flyout. |
| MenuSubContent alignOffset | number | -5 | Vertical shift so the first sub-row lines up with its trigger. |
Other parts
| Prop | Type | Default | Description |
|---|---|---|---|
| MenuTrigger | component | — | Unstyled trigger — compose any control via children or the render prop. |
| MenuTriggerButton | component | — | The spec's default 34px bordered trigger with a rotating chevron. |
| MenuLabel | component | — | Mono uppercase section header; skipped by keyboard navigation. |
| MenuSeparator | component | — | Hairline divider bleeding to the panel edges. |
| MenuShortcut | component | — | Standalone keycap chips — keys="⌘+K" splits on "+". |
Usage
Group with headers and dividers
Cluster related actions and separate destructive ones so the menu scans fast.
Bury primary actions in a menu
The most common action belongs on the surface as a button, not hidden behind “…”.
Put the dangerous action last
Delete sits alone at the bottom in red so it's never clicked by reflex.
Nest more than one level
A single submenu is fine; deeper trees are hard to navigate with a mouse.
Keyboard & accessibility
Built on Base UI Menu: role=menu/menuitem, roving focus, typeahead, and focus returned to the trigger on close. Checkable rows expose menuitemcheckbox / menuitemradio semantics.