DropdownMenu
A menu that appears below a trigger with selectable items.
import { DropdownMenu } from "@ninna-ui/overlays"pnpm add @ninna-ui/overlaysRequires @ninna-ui/core (auto-installed) + CSS setup.
Usage
Import and use the DropdownMenu component in your application.
import { DropdownMenu } from "@ninna-ui/overlays";import { Button , Code } from "@ninna-ui/primitives";
export default function Example() { return ( <DropdownMenu> <DropdownMenu.Trigger asChild> <Button variant="outline">Open Menu</Button> </DropdownMenu.Trigger> <DropdownMenu.Content> <DropdownMenu.Item>Profile</DropdownMenu.Item> <DropdownMenu.Item>Settings</DropdownMenu.Item> <DropdownMenu.Separator /> <DropdownMenu.Item>Sign out</DropdownMenu.Item> </DropdownMenu.Content> </DropdownMenu> );}Basic
A simple dropdown menu with items and a separator.
Groups & Labels
Organize menu items with groups, labels, and separators.
Checkbox Items
Menu items that can be toggled on and off.
Radio Items
Mutually exclusive selection within a radio group.
Disabled Items
Items can be disabled to prevent interaction.
API Reference
Complete list of props for the DropdownMenu component and its sub-components.
DropdownMenu (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | DropdownMenu content (Trigger, Content, etc.) |
open | boolean | - | Controlled open state |
defaultOpen | boolean | false | Default open state (uncontrolled) |
onOpenChange | (open: boolean) => void | - | Callback when open state changes |
modal | boolean | true | Whether the dropdown is modal |
dir | 'ltr' | 'rtl' | 'ltr' | Reading direction |
DropdownMenu.Content
| Prop | Type | Default | Description |
|---|---|---|---|
side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | Which side to place the menu |
sideOffset | number | 4 | Distance from trigger in pixels |
align | 'start' | 'center' | 'end' | 'start' | Alignment along the side |
loop | boolean | true | Whether to loop keyboard navigation |
avoidCollisions | boolean | true | Whether to avoid collisions with viewport boundary |
className | string | - | Additional CSS classes |
DropdownMenu.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as child element instead of wrapping button |
DropdownMenu.Item
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Whether the item is disabled |
destructive | boolean | false | Whether the item uses danger styling |
onSelect | (event: Event) => void | - | Callback when the item is selected |
textValue | string | - | Text value for typeahead search |
DropdownMenu.CheckboxItem
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | 'indeterminate' | - | Whether the item is checked |
onCheckedChange | (checked: boolean) => void | - | Callback when checked state changes |
disabled | boolean | false | Whether the item is disabled |
onSelect | (event: Event) => void | - | Callback when the item is selected |
textValue | string | - | Text value for typeahead search |
DropdownMenu.RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | Current selected value |
onValueChange | (value: string) => void | - | Callback when value changes |
DropdownMenu.RadioItem
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | - | Value of the radio item |
disabled | boolean | false | Whether the item is disabled |
onSelect | (event: Event) => void | - | Callback when the item is selected |
textValue | string | - | Text value for typeahead search |
DropdownMenu.Label
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Whether the label is inset (indented to align with items) |
Accessibility
- Uses
role="menu"with proper ARIA attributes - Arrow keys navigate between items, Enter/Space selects
- Typeahead support — type to jump to matching items
- Escape key closes the menu
- Sub menus open with Arrow Right and close with Arrow Left
- Disabled items are skipped during keyboard navigation
- Checkbox and radio items announce their state to screen readers