Skip to content

Dropdown Menu

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

View 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

View Code
<DropdownMenuContent variant="default">...</DropdownMenuContent>
<DropdownMenuContent variant="outline">...</DropdownMenuContent>

Checkbox Items

Use DropdownMenuCheckboxItem for togglable options within the menu.

Checkbox Items

View 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

View 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

View 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

Name Type Default Description
open boolean - Controlled open state
defaultOpen boolean false Initial open state for uncontrolled usage
onOpenChange (open: boolean) => void - Callback when the open state changes
dir 'ltr' | 'rtl' - Text direction
modal boolean true When true, traps focus and makes background inert
Name Type Default Description
variant 'default' | 'outline' 'default' Visual style variant
side 'top' | 'bottom' | 'left' | 'right' 'bottom' Preferred side to display the menu
sideOffset number 4 Distance in px between the menu and the trigger
className string - Additional CSS classes
Name Type Default Description
inset boolean false Add left padding to align with labels
disabled boolean false Disable the item
onSelect (event: Event) => void - Callback when the item is selected
Name Type Default Description
checked boolean - Controlled checked state
onCheckedChange (checked: boolean) => void - Callback when checked state changes
disabled boolean false Disable the item
Name Type Default Description
value string - Currently selected value
onValueChange (value: string) => void - Callback when selected value changes

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