NimUI
ComponentsFeedback

Dropdown Menu

Displays a menu of actions or options triggered by a button click

The DropdownMenu component displays a list of actions or options when users click a trigger element. Built on Radix UI DropdownMenu, it handles positioning, keyboard navigation, focus management, checkbox/radio items, and sub-menus automatically.

Import

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuLabel,
  DropdownMenuCheckboxItem,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSub,
  DropdownMenuSubTrigger,
  DropdownMenuSubContent,
} from '@nim-ui/components';

Basic Usage

Basic Dropdown Menu
Code
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">Open Menu</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Settings</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Log out</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Variants

Two visual styles: default (subtle border) and outline (thicker border).

Dropdown Menu Variants
Code
<DropdownMenuContent variant="default">...</DropdownMenuContent>
<DropdownMenuContent variant="outline">...</DropdownMenuContent>

Checkbox Items

Use DropdownMenuCheckboxItem for togglable options within the menu.

Checkbox Items
Code
const [showToolbar, setShowToolbar] = useState(true);
const [showSidebar, setShowSidebar] = useState(false);

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">View Options</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuCheckboxItem checked={showToolbar} onCheckedChange={setShowToolbar}>
      Show Toolbar
    </DropdownMenuCheckboxItem>
    <DropdownMenuCheckboxItem checked={showSidebar} onCheckedChange={setShowSidebar}>
      Show Sidebar
    </DropdownMenuCheckboxItem>
  </DropdownMenuContent>
</DropdownMenu>

Radio Items

Use DropdownMenuRadioGroup and DropdownMenuRadioItem for exclusive selection.

Radio Items
Code
const [theme, setTheme] = useState('system');

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">Theme: {theme}</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
      <DropdownMenuRadioItem value="light">Light</DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="dark">Dark</DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="system">System</DropdownMenuRadioItem>
    </DropdownMenuRadioGroup>
  </DropdownMenuContent>
</DropdownMenu>

Nest DropdownMenuSub for hierarchical menu structures.

Sub-menu
Code
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">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>Delete</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Controlled Mode

function ControlledMenu() {
  const [open, setOpen] = useState(false);

  return (
    <DropdownMenu open={open} onOpenChange={setOpen}>
      <DropdownMenuTrigger asChild>
        <Button>Controlled</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem>Action</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

Component Architecture

ComponentDescription
DropdownMenuRoot component managing open/close state
DropdownMenuTriggerElement that opens the menu on click
DropdownMenuContentFloating menu panel with variant styling, rendered via Portal
DropdownMenuItemA single actionable menu item
DropdownMenuSeparatorHorizontal divider between groups
DropdownMenuLabelNon-interactive label for grouping items
DropdownMenuCheckboxItemTogglable checkbox menu item
DropdownMenuRadioGroupContainer for exclusive radio selection
DropdownMenuRadioItemRadio option within a group
DropdownMenuSubSub-menu container
DropdownMenuSubTriggerItem that opens a sub-menu
DropdownMenuSubContentFloating panel for sub-menu items

Props

NameTypeDefaultDescription
openboolean-Controlled open state
defaultOpenbooleanfalseInitial open state for uncontrolled usage
onOpenChange(open: boolean) => void-Callback when the open state changes
dir'ltr' | 'rtl'-Text direction
modalbooleantrueWhen true, traps focus and makes background inert
NameTypeDefaultDescription
variant'default' | 'outline''default'Visual style variant
side'top' | 'bottom' | 'left' | 'right''bottom'Preferred side to display the menu
sideOffsetnumber4Distance in px between the menu and the trigger
classNamestring-Additional CSS classes
NameTypeDefaultDescription
insetbooleanfalseAdd left padding to align with labels
disabledbooleanfalseDisable the item
onSelect(event: Event) => void-Callback when the item is selected
NameTypeDefaultDescription
checkedboolean-Controlled checked state
onCheckedChange(checked: boolean) => void-Callback when checked state changes
disabledbooleanfalseDisable the item
NameTypeDefaultDescription
valuestring-Currently selected value
onValueChange(value: string) => void-Callback when selected value changes
NameTypeDefaultDescription
variant'default' | 'outline''default'Visual style variant for the sub-menu panel; matches the values and default of DropdownMenuContent's own variant prop.

Accessibility

Built on Radix UI DropdownMenu with full accessibility support:

  • role="menu": Content is announced as a menu to screen readers
  • role="menuitem": Each item is properly identified
  • role="menuitemcheckbox": Checkbox items have correct role
  • role="menuitemradio": Radio items have correct role
  • Focus management: Focus moves into the menu when opened and returns to trigger on close
  • Escape key: Pressing Escape dismisses the menu
  • Click outside: Clicking outside the menu closes it
  • Portal rendering: Content renders outside the DOM hierarchy without affecting the accessibility tree

Keyboard Support

KeyAction
Enter / SpaceOpen menu (on trigger) or select item
EscapeClose the menu
Arrow DownMove focus to next item
Arrow UpMove focus to previous item
Arrow RightOpen sub-menu (on sub-trigger)
Arrow LeftClose sub-menu
  • Popover — Rich floating content panel
  • Tooltip — Lightweight text hint on hover/focus
  • Select — Form select input for value selection

On this page