Home

Dropdown menu

A button that opens a list of actions, with shortcuts, submenus, checks and a destructive end.

ui.menucomponents/ui/menu.tsx

Use case

For the AI

Use it for the actions on a record or a page that do not each deserve a button: the ⋯ at the end of an invoice row (Edit, Duplicate, Send Reminder, Delete), the Actions button on an order's page, the account menu behind the avatar (Your Profile, Settings, Sign Out). Each item runs something; the menu holds no value of its own.

Use it when

  • Secondary actions on a record: a row's ⋯ or an Actions button
  • The account menu behind an avatar
  • View options that toggle (Compact Rows) with `MenuCheckboxItem`
  • Related actions under a submenu (Share › Copy the Link, Email It)

Use something else when

  • Picking a value a form or a filter holds (a status, a province): Select
  • The same actions on a right click over a row or a file: Context menu
  • Finding any page, record or action by typing: Command bar
  • Switching between teams or companies: Team selector

Examples

Actions on a record, with shortcuts, a submenu and a destructive end

Code

Import

import { CopyIcon, MoreHorizontalIcon, PencilIcon, TrashIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { Menu, MenuItem, MenuPopup, MenuSeparator, MenuShortcut, MenuTrigger } from "@/components/ui/menu"

Usage

<Menu>
  <MenuTrigger render={<Button size="icon" variant="ghost" aria-label="Invoice actions" />}>
    <MoreHorizontalIcon />
  </MenuTrigger>
  <MenuPopup align="end" className="w-52">
    <MenuItem onClick={onEdit}>
      <PencilIcon />
      Edit
      <MenuShortcut>⌘E</MenuShortcut>
    </MenuItem>
    <MenuItem onClick={onDuplicate}>
      <CopyIcon />
      Duplicate
    </MenuItem>
    <MenuSeparator />
    <MenuItem variant="destructive" onClick={onDelete}>
      <TrashIcon />
      Delete
    </MenuItem>
  </MenuPopup>
</Menu>

Rules

  • Items are Title Case ("Send Reminder", "Copy the Link"); a `MenuGroupLabel` is sentence case or an address.
  • A destructive item uses `variant="destructive"` and sits last, after a `MenuSeparator`.
  • The trigger is a real button: `MenuTrigger render={<Button variant="secondary" />}`, or `size="icon"` with an `aria-label` for an icon alone (⋯, the avatar).
  • An icon goes before the words and a shortcut in `MenuShortcut` at the end.