Dropdown Menu

Dropdown menus display a list of actions or options that a user can choose from, triggered by a button.

Overview

The DropdownMenu component provides a floating menu of actions triggered by a button click. Built on Base UI Menu, it supports keyboard navigation, submenus, checkbox items, radio items, and accessible labelling.

tsx
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@rogo-technologies/ui/dropdown-menu"

<DropdownMenu>
  <DropdownMenuTrigger>
    <button>Open</button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Action One</DropdownMenuItem>
    <DropdownMenuItem>Action Two</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Basic

A standard dropdown with labeled groups, items, keyboard shortcuts, and a separator.

tsx
<DropdownMenu>
  <DropdownMenuTrigger>
    <button>Open Menu</button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>
      Profile
      <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
    </DropdownMenuItem>
    <DropdownMenuItem>
      Settings
      <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
    </DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Log out</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Checkbox Items

Use DropdownMenuCheckboxItem for toggling boolean options. Each item manages its own checked / onCheckedChange state.

tsx
const [showStatusBar, setShowStatusBar] = useState(true)
const [showPanel, setShowPanel] = useState(false)

<DropdownMenu>
  <DropdownMenuTrigger>
    <button>View Options</button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>Appearance</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuCheckboxItem
      checked={showStatusBar}
      onCheckedChange={setShowStatusBar}
    >
      Status Bar
    </DropdownMenuCheckboxItem>
    <DropdownMenuCheckboxItem
      checked={showPanel}
      onCheckedChange={setShowPanel}
    >
      Panel
    </DropdownMenuCheckboxItem>
  </DropdownMenuContent>
</DropdownMenu>

Radio Items

Use DropdownMenuRadioGroup and DropdownMenuRadioItem for single-select options within a menu. The selected item shows a checkmark indicator.

tsx
const [sort, setSort] = useState("relevance")

<DropdownMenu>
  <DropdownMenuTrigger>
    <button>Sort By: {sort}</button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>Sort order</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuRadioGroup value={sort} onValueChange={setSort}>
      <DropdownMenuRadioItem value="relevance">Relevance</DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="date">Date</DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="name">Name</DropdownMenuRadioItem>
    </DropdownMenuRadioGroup>
  </DropdownMenuContent>
</DropdownMenu>

Submenus

Use DropdownMenuSub, DropdownMenuSubTrigger, and DropdownMenuSubContent to nest menus. A chevron icon is automatically appended to the sub-trigger.

tsx
<DropdownMenu>
  <DropdownMenuTrigger>
    <button>Actions</button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>New File</DropdownMenuItem>
    <DropdownMenuSub>
      <DropdownMenuSubTrigger>Share</DropdownMenuSubTrigger>
      <DropdownMenuSubContent>
        <DropdownMenuItem>Email</DropdownMenuItem>
        <DropdownMenuItem>Slack</DropdownMenuItem>
        <DropdownMenuItem>Copy Link</DropdownMenuItem>
      </DropdownMenuSubContent>
    </DropdownMenuSub>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Download</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Destructive Items

Use actionType="destructive" on a DropdownMenuItem to indicate a destructive action. The item text turns red on hover.

tsx
<DropdownMenuItem actionType="destructive">Delete</DropdownMenuItem>

Groups and Labels

Use DropdownMenuGroup and DropdownMenuLabel to organize related items into sections.

tsx
<DropdownMenuContent>
  <DropdownMenuGroup>
    <DropdownMenuLabel>Navigation</DropdownMenuLabel>
    <DropdownMenuItem>Dashboard</DropdownMenuItem>
    <DropdownMenuItem>Analytics</DropdownMenuItem>
  </DropdownMenuGroup>
  <DropdownMenuSeparator />
  <DropdownMenuGroup>
    <DropdownMenuLabel>Settings</DropdownMenuLabel>
    <DropdownMenuItem>Account</DropdownMenuItem>
    <DropdownMenuItem disabled>Billing (coming soon)</DropdownMenuItem>
  </DropdownMenuGroup>
</DropdownMenuContent>

Trigger with asChild

Use asChild on DropdownMenuTrigger to render the trigger as a custom element instead of the default button.

tsx
import { Button } from "@rogo-technologies/ui/button"

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="ghost">Options</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Edit</DropdownMenuItem>
    <DropdownMenuItem>Delete</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Positioning

Use side, align, sideOffset, and alignOffset on DropdownMenuContent to control the popup placement relative to the trigger.

tsx
// Opens to the right, aligned to the top
<DropdownMenuContent side="right" align="start" sideOffset={8}>
  ...
</DropdownMenuContent>

// Opens above, centered
<DropdownMenuContent side="top" align="center">
  ...
</DropdownMenuContent>

Props

DropdownMenu

The root component that manages open state.

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state for uncontrolled usage.
onOpenChange(open: boolean) => voidCallback when open state changes.

DropdownMenuTrigger

The button that toggles the menu open/closed.

PropTypeDefaultDescription
asChildbooleanfalseRender as the child element instead of a button.

DropdownMenuContent

Convenience wrapper that renders Portal → Positioner → Popup.

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""bottom"Side of the trigger to anchor.
sideOffsetnumber4Offset from the trigger edge in px.
align"start" | "center" | "end""start"Alignment along the side axis.
alignOffsetnumberOffset from the alignment edge.
collisionPaddingnumber | PaddingPadding from viewport edges for collision detection.
positionerClassNamestringAdditional class for the positioner wrapper.

DropdownMenuItem

A menu item that triggers an action.

PropTypeDefaultDescription
insetbooleanfalseAdds left padding to align with items that have icons.
actionType"default" | "destructive""default"Visual style — destructive shows red text.
onSelect(event: MouseEvent) => voidCallback when selected (mapped to onClick).
disabledbooleanfalseDisables the item.

DropdownMenuCheckboxItem

A menu item with a checkbox indicator.

PropTypeDefaultDescription
checkedbooleanControlled checked state.
onCheckedChange(checked: boolean) => voidCallback when checked state changes.

DropdownMenuRadioGroup

Wraps radio items for single selection.

PropTypeDefaultDescription
valuestringControlled selected value.
onValueChange(value: string) => voidCallback when selection changes.

DropdownMenuRadioItem

A radio item within a radio group. Shows a checkmark when selected.

PropTypeDefaultDescription
valuestringUnique value identifying this item.

DropdownMenuSubTrigger

The item that opens a submenu. Automatically includes a chevron icon.

PropTypeDefaultDescription
insetbooleanfalseAdds left padding for alignment.

DropdownMenuSubContent

The popup content for a submenu.

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""right"Side relative to the sub-trigger.
sideOffsetnumber-4Offset from the sub-trigger edge.
align"start" | "center" | "end""start"Alignment along the side axis.

DropdownMenuLabel

A non-interactive label for a group of items.

PropTypeDefaultDescription
insetbooleanfalseAdds left padding for alignment.

DropdownMenuSeparator

A visual divider between groups of items.

DropdownMenuShortcut

Displays a keyboard shortcut hint, right-aligned within a menu item.

Accessibility

  • Menu uses role="menu" with role="menuitem" children
  • Full keyboard navigation: / to move, Enter/Space to select, Esc to close
  • Submenus open with and close with
  • Focus is trapped within the menu while open
  • Menu closes when clicking outside or pressing Escape
  • Checkbox items use role="menuitemcheckbox"
  • Radio items use role="menuitemradio" within a role="group"
tsx
// Accessible labelling
<DropdownMenu>
  <DropdownMenuTrigger aria-label="More actions">
    <button></button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Edit</DropdownMenuItem>
    <DropdownMenuItem>Delete</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Usage Guidelines

Do

  • Use dropdown menus for contextual actions related to a specific element
  • Group related items with labels and separators
  • Place destructive actions last, separated visually
  • Keep menu items concise — use short, action-oriented labels
  • Use radio items for single-select options (e.g. sort order, view mode)
  • Use checkbox items for toggling independent boolean settings

Don't

  • Don't use dropdown menus for navigation — use a navigation component instead
  • Don't nest submenus more than one level deep — it becomes difficult to use
  • Don't place too many items in a single menu — consider grouping or using a dialog
  • Don't use dropdown menus for form inputs — use select, combobox, or radio groups instead
  • Don't forget to add keyboard shortcuts for frequently used actions
PreviousCheckbox
NextInput
© 2026 Rogo Technologies Inc.