A set of actions in a popover.

DropdownMenu

Usage

  • Use DropdownMenu to present a list of actions or links in a floating overlay anchored to a trigger.
  • Use DropdownMenu to group actions within a specific context, such as row-level actions in a table or account settings.
  • Use Select instead for form controls where the chosen value persists as the field's value and is submitted with the form.
  • Use Popover instead for freeform content such as text, forms, or other UI too complex for a Tooltip.
  • Group items with DropdownMenuGroup once the list grows past 7–10 items.
  • Limit nesting to one sub-level. Rework the menu structure or use group labels instead of deeper nesting.

Appearance

  • Add a leading icon (icon) to items so users can identify actions quickly.
  • Apply icons consistently within a group. Never mix icon and non-icon items in the same group.
  • Add a description (description) to an item to explain what it does.
  • Mark destructive or irreversible actions with danger styling (isDanger).
  • Use DropdownMenuGroup to separate related items into visually distinct sections. Add label to categorize the section; omit it to render only a divider.
  • Use groups deliberately — for shorter lists, group only when it improves the user experience or visual hierarchy.
  • Use DropdownMenuFooter for supplemental information or hints that apply to the whole list. It renders after all items.
  • Use DropdownMenuTrigger for an inline text trigger that inherits surrounding text styles.
  • Use DropdownMenuTriggerButton for a standard Button trigger, or with isIconOnly for tight layouts such as tables and toolbars.
  • Wrap any interactive element in DropdownMenuTrigger to build a custom trigger (e.g., an Avatar).

Behaviors

  • Items support base, hover, focus, disabled (isDisabled), and danger (isDanger) states. Hover and keyboard focus apply the same background highlight.
  • Pair a disabled item with a tooltip (tooltip) explaining why the action is unavailable.
  • Add a tooltip (tooltip) to any item that needs extra context beyond its label and description.
  • Menus close when the user clicks an item, clicks outside, or presses Escape. Focus returns to the trigger.
  • Set shouldCloseOnClick={false} on an item to keep the menu open after it is clicked, for multi-select or toggle flows.
  • Use DropdownMenuCheckboxItem for toggle options such as column visibility or filters. It shows a check indicator when selected.
  • Nest a submenu with DropdownMenuSub and DropdownMenuSubTrigger. The submenu opens on mouse hover or keyboard activation and its trigger shows a trailing chevron.
  • Set placement to control where the menu opens relative to the trigger. Default is bottom-start. Placement is a preference — the menu adjusts to stay visible in the viewport, and disappears when the trigger scrolls out of view.

Content

  • Write menu item labels as short, specific verb phrases in sentence case, starting with the verb that describes what happens (e.g., "Edit details", "Export results").
  • Never use vague or generic item labels such as "Copy" or "Click here".
  • Write descriptions as a single, simple sentence explaining what the action does or when to use it. Never repeat the label or restate it vaguely.
  • Write group labels as brief, single nouns in uppercase that name the category.
  • Write tooltips on disabled items to explain why the action is unavailable and, where possible, what would make it available. Never restate the disabled state without explanation.

Implementation Notes

  • DropdownMenu is a compound component. Compose DropdownMenu with DropdownMenuTrigger or DropdownMenuTriggerButton, DropdownMenuContent, and inside the content: DropdownMenuGroup, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuSub, DropdownMenuSubTrigger, and DropdownMenuFooter.
  • DropdownMenuItem renders a non-interactive div unless it has onClick, href, or isTrigger. Provide onClick or href for any item the user is meant to activate — including disabled items, which otherwise render as static text.
  • Use href on DropdownMenuItem for navigation items; pair with isExternal for external links, which adds target="_blank" rel="noopener noreferrer".
  • DropdownMenuCheckboxItem requires both isChecked and onCheckedChange. It does not accept icon — the slot is reserved for the check indicator.
  • DropdownMenuGroup renders a header only when label is set; without it, only the divider renders.
  • DropdownMenuSubTrigger adds its own trailing chevron and keeps the menu open on click. Pass the label as children and an optional leading icon.
  • DropdownMenuTriggerButton renders a Button and accepts every Button prop (variant, icon, iconPosition, isIconOnly, aria-label).
  • Use elementAfter for trailing item content — most often a KeyboardShortcut. It is pinned to the trailing edge, so shortcuts line up down the menu without hand-tuned spacing. Never pad labels or add spacer elements to achieve that alignment.
  • Use elementBefore for leading item content that is not an icon. It renders after the icon rather than replacing it.
  • Use trailingIcon on DropdownMenuItem for a trailing indicator icon.
  • DropdownMenu accepts every PopoverPrimitive prop except withArrow — menus never render an arrow.
  • shouldRestrictSize defaults to false on DropdownMenu (the primitive defaults to true), so menu size is not viewport-constrained by default.
  • shouldNavigateList defaults to true, enabling arrow-key navigation and typeahead across items.
  • Customize the open/close animation with animationTransitionDuration in milliseconds; default is 125.
  • Control the open state externally with isOpen paired with onOpenChange; use defaultIsOpen for an uncontrolled initial state; use isDisabled to disable the whole menu.
  • React passes content via children. Ember yields via the default block, which also exposes the Floating UI context as a block param.
  • In Ember, components take the Pluma prefix (<PlumaDropdownMenu>, <PlumaDropdownMenuItem>, <PlumaDropdownMenuTriggerButton>) and all props are @ args. elementBefore and elementAfter are available as the :elementBefore and :elementAfter named blocks (with the label in :default) or as component args.

On this page