Skip to content

Dropdown menu

Opens a menu of actions or options from a button, like a record's row actions.

Library
What’s this?

Installation

pnpm dlx shadcn@latest add @wisty/dropdown-menu

The CLI installs the Radix or Base UI file to match your project.

If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.

When to use

Use it

  • A button opens a list of actions, like a record's Edit, Clone and Delete.
  • Row actions in a table, behind a small icon button.
  • A few settings that change a view, like visible columns (checkbox items) or a sort order (radio items).

Don't use it

  • People pick a value for a form field. Use Select.
  • People search a long list. Use Combobox.
  • There are only one or two actions with room for them. Show buttons.
  • The list is navigation between pages. Use links or Tabs.
  • People right-click an object to act on it. Use Context menu.

Usage

DropdownMenu
├── DropdownMenuTrigger
└── DropdownMenuContent
    ├── DropdownMenuGroup
    │   ├── DropdownMenuLabel
    │   └── DropdownMenuItem
    │       └── DropdownMenuShortcut
    ├── DropdownMenuSeparator
    └── DropdownMenuSub
        ├── DropdownMenuSubTrigger
        └── DropdownMenuSubContent
            └── DropdownMenuItem
import { buttonVariants } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
<DropdownMenu>
  <DropdownMenuTrigger className={buttonVariants({ variant: "outline" })}>
    New
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem onClick={newOpportunity}>Opportunity</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>
  • Run an action with onClick, which works in Radix and Base UI projects; onSelect is Radix only.
  • For settings, use DropdownMenuCheckboxItem, or DropdownMenuRadioItem inside a DropdownMenuRadioGroup, in an item's place. inset on an item, label or submenu trigger indents its text to line up with theirs.
  • In Radix projects, checking a checkbox or radio item closes the menu; call event.preventDefault() in its onSelect to keep it open. In Base UI projects the menu stays open; pass closeOnClick to close it.

Examples

Row actions

An opportunity row's actions behind a small icon button named for the row, the menu lined up with its end by `align="end"`.

Acme - 200 Widgets
Prospecting · $120,000

Checkbox and radio items

Checkbox items (`DropdownMenuCheckboxItem`) for visible columns and radio items (`DropdownMenuRadioItem`) for the sort order, one checked in each.

API reference

PartBuilt on
DropdownMenuRadix DropdownMenu.Root (opens in a new tab)
DropdownMenuPortalRadix DropdownMenu.Portal (opens in a new tab)
DropdownMenuTriggerRadix DropdownMenu.Trigger (opens in a new tab)
DropdownMenuContentRadix DropdownMenu.Content (opens in a new tab)
DropdownMenuGroupRadix DropdownMenu.Group (opens in a new tab)
DropdownMenuItemRadix DropdownMenu.Item (opens in a new tab)
DropdownMenuCheckboxItemRadix DropdownMenu.CheckboxItem (opens in a new tab)
DropdownMenuRadioGroupRadix DropdownMenu.RadioGroup (opens in a new tab)
DropdownMenuRadioItemRadix DropdownMenu.RadioItem (opens in a new tab)
DropdownMenuLabelRadix DropdownMenu.Label (opens in a new tab)
DropdownMenuSeparatorRadix DropdownMenu.Separator (opens in a new tab)
DropdownMenuShortcut<span> (opens in a new tab)
DropdownMenuSubRadix DropdownMenu.Sub (opens in a new tab)
DropdownMenuSubTriggerRadix DropdownMenu.SubTrigger (opens in a new tab)
DropdownMenuSubContentRadix DropdownMenu.SubContent (opens in a new tab)

DropdownMenu

PropTypeDefault
modalbooleanfalse

DropdownMenuContent

PropTypeDefault
align"center" | "end" | "start""start"
sideOffsetnumber2

DropdownMenuItem

PropTypeDefault
insetboolean
variant"default" | "destructive""default"

DropdownMenuCheckboxItem

PropTypeDefault
insetboolean

DropdownMenuRadioItem

PropTypeDefault
insetboolean

DropdownMenuLabel

PropTypeDefault
insetboolean

DropdownMenuSubTrigger

PropTypeDefault
insetboolean

DropdownMenuSubContent

PropTypeDefault
sideOffsetnumber4

SLDS mapping

  • DropdownMenuContent and DropdownMenuSubContent are slds-dropdown.
  • DropdownMenuItem, DropdownMenuCheckboxItem and DropdownMenuRadioItem are slds-dropdown__item. Checked items show SLDS's selected check (slds-icon_selected) before the text.
  • DropdownMenuLabel is slds-dropdown__header.
  • DropdownMenuSeparator is slds-has-divider_top-space.
  • DropdownMenuSubTrigger is an item with slds-has-submenu.
  • DropdownMenuShortcut has no SLDS counterpart. The trigger is whatever you style it as, usually Button's neutral or icon button.

Known gaps:

  • No nubbin, and no slds-dropdown_length-* heights. The menu scrolls only when it runs out of room on screen.
  • Icons are lucide's, not SLDS's utility icons.
  • SLDS truncates a long item on one line. Here it wraps, unless you wrap the label in <span className="truncate">.
  • A submenu trigger keeps its highlight while its submenu is open. SLDS drops it once focus moves into the submenu.
PropValueSLDSNotes
DropdownMenuItem variantdefaultslds-dropdown__item
DropdownMenuItem variantdestructivenoneSLDS has no destructive item. The text and icon take the error color; the highlight stays.
DropdownMenuItem insettruenoneStarts the text where a checked item's text starts.

Keyboard interactions

Keys Action
Enter, Space or Down Arrow On the trigger, opens the menu and focuses the first item.
Down Arrow, Up Arrow Moves focus to the next or previous item.
Home, End Moves focus to the first or last item.
Letters Moves focus to the next item that starts with them.
Enter or Space Runs the focused item, or checks it.
Right Arrow On a submenu trigger, opens the submenu and focuses its first item.
Left Arrow In a submenu, closes it and returns focus to its trigger.
Escape Closes the menu and returns focus to the trigger.

In Radix projects the arrow keys skip disabled items. In Base UI projects focus lands on them, but Enter and Space don't run them.

Accessibility

  • Name an icon-only trigger with aria-label. In a list, name it for its row ("Show actions for Acme"), as the Row actions example does, so screen readers can tell the buttons apart.
  • A disabled item still reads out. Say why it's unavailable in nearby text if it matters.

Responsive behavior

  • The menu is as wide as its longest item, between 6rem and 20rem.
  • For a menu at the end of a row, pass align="end" to line it up with the trigger's end edge, as the Row actions example does.

Rules

  • Put each DropdownMenuLabel inside a DropdownMenuGroup, or the menu can throw.
  • Pass modal only when the page must be blocked. A modal menu stops the page scrolling and takes the next click outside just to close itself.
  • Never nest a Button inside the trigger. That's a button in a button; style the trigger with buttonVariants() instead.
  • Put an icon first in an item, then the text, then an optional DropdownMenuShortcut. The shortcut only shows the keys; it doesn't make them work.
  • Use variant="destructive" only for actions that delete or can't be undone, and put them last, after a separator.
  • Don't restyle highlight, focus or check colors. They come from the theme tokens.