Dropdown Menu

Displays a menu to the user, typically triggered by a button.

Installation

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@gradeui/ui"

Usage

Examples

Project Actions

With Checkboxes

With Radio Items

With Submenus

Props

PropTypeDefaultDescription
openboolean-The controlled open state of the dropdown menu.
defaultOpenbooleanfalseThe default open state when uncontrolled.
onOpenChange(open: boolean) => void-Callback when the open state changes.
modalbooleantrueWhether the dropdown menu should be modal.

Accessibility

  • Built on Radix UI DropdownMenu for full accessibility
  • Keyboard navigation (Arrow keys, Enter, Escape)
  • WAI-ARIA menu pattern
  • Focus management and trapping
  • Typeahead support for quick navigation

Sidecar

The Markdown sidecar Studio (and the Grade MCP server, when it ships) reads to understand this component — frontmatter, when- to-use guidance, and canonical examples. Authored once at packages/ui/components/ui/dropdown-menu.md and shipped inside the published @gradeui/ui tarball.

---
name: DropdownMenu
import: "@gradeui/ui"
subcomponents: [DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent]
props:
  - DropdownMenu: open?, defaultOpen?, onOpenChange?, modal? (default true)
  - DropdownMenuTrigger: asChild?: boolean — usually wraps a Button
  - DropdownMenuContent: align? "start" | "center" | "end"; side? "top" | "right" | "bottom" | "left"; sideOffset? number
  - DropdownMenuItem: onSelect?, disabled?, asChild?, inset?
  - DropdownMenuCheckboxItem / DropdownMenuRadioItem: checked? / value, onCheckedChange? / onValueChange? (radio is on the group)
  - DropdownMenuSub / DropdownMenuSubTrigger / DropdownMenuSubContent: nested menu — sub-trigger shows children, sub-content holds the deeper items
  - DropdownMenuShortcut: children — right-aligned kbd hint
when_to_use: A small action menu attached to a trigger — overflow "…" buttons on cards, user-avatar menus in headers, "Insert" menus in editors. For a full searchable list, use Command. For ONE primary action plus a secondary, use a Button next to a smaller ghost Button instead of a dropdown.
composes_with: [Button (as trigger asChild), Avatar (user menu), Card (overflow on a tile), Tooltip (on the trigger)]
aliases: [dropdown, dropdown menu, overflow menu, kebab menu, more menu, action menu, context-style menu, menu, pull-down menu, pulldown menu, context menu, popup menu, actions menu]
---

```jsx
// Overflow menu on a card/row — trigger an icon-only Button.
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="ghost" size="icon" aria-label="Open menu">
      <MoreHorizontal />
    </Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent align="end">
    <DropdownMenuItem onSelect={onDuplicate}>
      <Copy /> Duplicate
    </DropdownMenuItem>
    <DropdownMenuItem onSelect={onShare}>
      <Share2 /> Share
    </DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem onSelect={onDelete} className="text-destructive">
      <Trash /> Delete
    </DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>
```