Components
DropdownMenu
A menu that appears on trigger click, providing a list of actions or options.
DropdownMenu
The DropdownMenu component displays a menu of options that appears when triggered. It supports regular items, checkbox items, radio groups, nested submenus, and keyboard shortcuts.
Use DropdownMenuShortcut to display keyboard shortcuts alongside menu items.
Features
- Trigger-based menu display
- Standard clickable items
- Checkbox items for multi-select options
- Radio groups for single-select options
- Nested submenus for hierarchical navigation
- Keyboard shortcut display
- Labels and separators for organization
- Full keyboard navigation
- Controlled and uncontrolled modes
Usage
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
} from '@loke/design-system/dropdown-menu';
export default function Example() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open Menu</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Tips:
- Use
DropdownMenuLabelto add section headings. - Use
DropdownMenuSeparatorto visually group related items. - Add icons before item text for visual clarity.
Props
DropdownMenu
Prop
Type
DropdownMenuContent
Prop
Type
DropdownMenuItem
Prop
Type
DropdownMenuCheckboxItem
Prop
Type
DropdownMenuRadioGroup
Prop
Type
DropdownMenuRadioItem
Prop
Type
Examples
Basic dropdown menu
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<User className="mr-2 h-4 w-4" />
<span>Profile</span>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard className="mr-2 h-4 w-4" />
<span>Billing</span>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings className="mr-2 h-4 w-4" />
<span>Settings</span>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut className="mr-2 h-4 w-4" />
<span>Log out</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>With checkboxes
Status Bar: On | Activity Bar: Off | Panel: Off
const [showStatusBar, setShowStatusBar] = useState(true);
const [showActivityBar, setShowActivityBar] = useState(false);
const [showPanel, setShowPanel] = useState(false);
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">View Options</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem
checked={showStatusBar}
onCheckedChange={setShowStatusBar}
>
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={showActivityBar}
onCheckedChange={setShowActivityBar}
>
Activity Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={showPanel}
onCheckedChange={setShowPanel}
>
Panel
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>With radio group
Current position: bottom
const [position, setPosition] = useState("bottom");
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Panel Position</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>With submenu
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">More Options</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuItem>New Tab</DropdownMenuItem>
<DropdownMenuItem>New Window</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<UserPlus className="mr-2 h-4 w-4" />
<span>Invite users</span>
</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>
<Mail className="mr-2 h-4 w-4" />
<span>Email</span>
</DropdownMenuItem>
<DropdownMenuItem>
<MessageSquare className="mr-2 h-4 w-4" />
<span>Message</span>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem>Settings</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>With keyboard shortcuts
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Edit</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuItem>
<span>Undo</span>
<DropdownMenuShortcut>⌘Z</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Redo</span>
<DropdownMenuShortcut>⇧⌘Z</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<span>Cut</span>
<DropdownMenuShortcut>⌘X</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Copy</span>
<DropdownMenuShortcut>⌘C</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Paste</span>
<DropdownMenuShortcut>⌘V</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Accessibility
- Uses
role="menu"with proper ARIA attributes. - Arrow key navigation between items.
- Home/End keys jump to first/last item.
- Typeahead to jump to items by typing.
- Enter/Space selects the focused item.
- Escape closes the menu.
- Focus returns to trigger when closed.
- Disabled items are skipped in navigation.
Best practices
- Keep menu items concise and action-oriented.
- Use icons to improve scannability.
- Group related items with labels and separators.
- Show keyboard shortcuts for power users.
- Limit menu depth — avoid more than one level of submenus.
- Consider using checkbox/radio items for settings that don't require navigation.
- Use
disabledfor unavailable actions rather than hiding them.