Skip to content

Overlays & navigation

Dropdown menu

A dropdown menu lists actions behind a button: account menus, row actions, view options. Items take icons, shortcuts, checkboxes, radio choices, section labels, separators, a danger style and nested submenus. It follows the WAI-ARIA menu button pattern, including arrow keys, Home and End, typeahead and Escape, and renders in the top layer so it is never clipped.

On this page

Usage

components/ui/dropdown-menu.tsx
import { DropdownMenu } from "@/components/ui/dropdown-menu"; <DropdownMenu  trigger={<Button>Actions</Button>}  items={[    { label: "Edit", icon: <Pencil strokeWidth={1.75} />, onSelect: edit },    { type: "separator" },    { label: "Delete", icon: <Trash2 strokeWidth={1.75} />, danger: true, onSelect: remove },  ]}/>

Examples

Account menu

Section label, icons, shortcuts, a disabled item and a submenu with radio items. Hover or press ArrowRight on “Switch workspace”.

Row actions with a danger item

An icon button trigger aligned to the end of a row. Put destructive actions last, after a separator.

INV-2041

Fernhill Studio · €4,200.00

Checkbox and radio items

Checkbox and radio items keep the menu open, so several options can be changed in one go.

Menu is the shorthand for the common “more” button: pass the icon and a label. It is built on DropdownMenu.

Props

DropdownMenu

  • triggerrequiredReactNodedefault: —Your button element (gets aria-haspopup, aria-expanded, aria-controls) or text for a default button.
  • itemsrequiredDropdownMenuItem[]default: —The entries, in order. See the item types below.
  • labelstringdefault: —Accessible name of the menu. Defaults to the trigger text when it is a string.
  • placement"top" | "bottom" | "start" | "end"default: "bottom"Preferred side of the trigger.
  • align"start" | "center" | "end"default: "start"Edge of the trigger the menu lines up with.
  • classNamestringdefault: —Extra classes for the panel, e.g. a width (default min width 208px).
  • onOpenChange(open: boolean) => voiddefault: —Called when the menu opens or closes.

DropdownMenuItem

  • item{ label, icon?, shortcut?, disabled?, danger?, href?, onSelect? }default: —An action. href renders a link. Selecting closes the menu.
  • checkbox{ type: "checkbox", label, checked, onCheckedChange }default: —Toggle. Keeps the menu open.
  • radio{ type: "radio", label, checked, onSelect }default: —One of a set. Keeps the menu open.
  • submenu{ type: "submenu", label, icon?, items }default: —Opens a nested menu to the side.
  • label{ type: "label", label }default: —Small heading for a section.
  • separator{ type: "separator" }default: —A hairline between groups.

Menu

  • triggerrequiredReactNodedefault: —The icon shown in the 32px button.
  • labelrequiredstringdefault: —Accessible name of the button and the menu.
  • itemsrequired{ label, icon?, danger?, onSelect? }[]default: —Plain actions.
  • align"start" | "end"default: "end"Edge the menu lines up with.

Accessibility

  • The trigger has aria-haspopup="menu" and aria-expanded. Enter, Space and ArrowDown open the menu on the first item, ArrowUp on the last.
  • Inside, ArrowUp and ArrowDown move between items (wrapping), Home and End jump to the ends, and typing letters jumps to the matching item.
  • Escape closes the menu and returns focus to the trigger. Tab closes it and moves on.
  • Submenus open with ArrowRight, Enter or Space and close with ArrowLeft or Escape, returning focus to their parent item.
  • Items use role menuitem, menuitemcheckbox or menuitemradio with aria-checked; disabled items are skipped and marked aria-disabled.

Suggested