import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuSeparator,
DropdownMenuLabel,
DropdownMenuCheckboxItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
DropdownMenuSelectableItem,
DropdownMenuItemWithActions,
DropdownMenuAddItem,
} from "@/components/ui/dropdown-menu";
import { DesignIcon } from "@/components/ui/design-icon";Basic building blocks for dropdown menus
| Prop | Type | Default | Description |
|---|---|---|---|
DropdownMenu | Container | - | Root component, wraps everything |
DropdownMenuTrigger | Trigger | - | Element that opens the menu. Use asChild with DesignButton |
DropdownMenuContent | Content | - | The popup container. Props: align (start|center|end), sideOffset |
DropdownMenuItem | Item | - | Clickable menu item. Props: variant (default|destructive), disabled |
DropdownMenuSeparator | Divider | - | Visual separator between groups |
DropdownMenuLabel | Text | - | Non-interactive label for grouping items |
Components for building selection menus
| Prop | Type | Default | Description |
|---|---|---|---|
DropdownMenuCheckboxItem | Toggle | - | Checkbox item. Props: checked, onCheckedChange |
DropdownMenuRadioGroup | Container | - | Radio group container. Props: value, onValueChange |
DropdownMenuRadioItem | Radio | - | Radio option. Props: value |
DropdownMenuSelectableItem | Selection | - | Single selection with check. Props: selected, onSelect |
DropdownMenuItemWithActions | Selection | - | Selection with edit/delete buttons. Props: selected, onSelect, onEdit, onDelete |
DropdownMenuAddItem | Action | - | Add new item button. Props: onClick |
Components for nested menus
| Prop | Type | Default | Description |
|---|---|---|---|
DropdownMenuSub | Container | - | Submenu container |
DropdownMenuSubTrigger | Trigger | - | Item that opens submenu (shows arrow) |
DropdownMenuSubContent | Content | - | Submenu popup content |
<DropdownMenu>
<DropdownMenuTrigger asChild>
<DesignButton variant="tertiary" size="icon">
<DesignIcon name="more" />
</DesignButton>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>
<DesignIcon name="edit" />
Edit
</DropdownMenuItem>
<DropdownMenuItem>
<DesignIcon name="duplicate" />
Duplicate
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<DesignIcon name="delete" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu><DropdownMenuContent>
<DropdownMenuLabel>File Actions</DropdownMenuLabel>
<DropdownMenuItem>
<DesignIcon name="save" />
Download
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>Edit Actions</DropdownMenuLabel>
<DropdownMenuItem>
<DesignIcon name="edit" />
Edit
</DropdownMenuItem>
</DropdownMenuContent>const [checked, setChecked] = useState(true);
<DropdownMenuContent>
<DropdownMenuLabel>Settings</DropdownMenuLabel>
<DropdownMenuCheckboxItem
checked={checked}
onCheckedChange={setChecked}
>
<DesignIcon name="analytics" />
Show notifications
</DropdownMenuCheckboxItem>
</DropdownMenuContent>const [value, setValue] = useState("bottom");
<DropdownMenuContent>
<DropdownMenuLabel>Position</DropdownMenuLabel>
<DropdownMenuRadioGroup value={value} onValueChange={setValue}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="left">Left</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent><DropdownMenuContent>
<DropdownMenuLabel>Styles</DropdownMenuLabel>
<DropdownMenuSelectableItem
selected={!selectedId}
onSelect={() => setSelectedId(null)}
>
None
</DropdownMenuSelectableItem>
<DropdownMenuItemWithActions
selected={selectedId === "pro"}
onSelect={() => setSelectedId("pro")}
onEdit={() => handleEdit("pro")}
onDelete={() => handleDelete("pro")}
>
Professional
</DropdownMenuItemWithActions>
<DropdownMenuSeparator />
<DropdownMenuAddItem onClick={handleAdd}>
Add style...
</DropdownMenuAddItem>
</DropdownMenuContent><DropdownMenuContent>
<DropdownMenuItem>
<DesignIcon name="edit" />
Edit
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<DesignIcon name="favorite" />
Favorites
</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>Add to favorites</DropdownMenuItem>
<DropdownMenuItem>Remove from favorites</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>Use icon trigger with align="end"
<DropdownMenu>
<DropdownMenuTrigger asChild>
<DesignButton variant="tertiary" size="icon">
<DesignIcon name="more" />
</DesignButton>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem><DesignIcon name="open" />Open</DropdownMenuItem>
<DropdownMenuItem><DesignIcon name="duplicate" />Duplicate</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive"><DesignIcon name="delete" />Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Profile trigger with logout as destructive
<DropdownMenuContent align="end">
<DropdownMenuItem><DesignIcon name="user-center" />Profile</DropdownMenuItem>
<DropdownMenuItem><DesignIcon name="setting" />Settings</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive"><DesignIcon name="sign-out" />Log out</DropdownMenuItem>
</DropdownMenuContent>Use SelectableItem + ItemWithActions + AddItem
<DropdownMenuContent>
<DropdownMenuLabel>Labels</DropdownMenuLabel>
<DropdownMenuSelectableItem>None</DropdownMenuSelectableItem>
<DropdownMenuItemWithActions
selected
onEdit={handleEdit}
onDelete={handleDelete}
>
Important
</DropdownMenuItemWithActions>
<DropdownMenuSeparator />
<DropdownMenuAddItem onClick={handleAdd}>Create label...</DropdownMenuAddItem>
</DropdownMenuContent>Always use asChild on DropdownMenuTrigger
<DropdownMenuTrigger asChild>
<DesignButton variant="tertiary" size="icon">
<DesignIcon name="more" />
</DesignButton>
</DropdownMenuTrigger>Add icons to menu items for better scannability
<DropdownMenuItem>
<DesignIcon name="edit" />
Edit
</DropdownMenuItem>Use variant="destructive" for delete/remove actions
<DropdownMenuItem variant="destructive">
<DesignIcon name="delete" />
Delete
</DropdownMenuItem>Group related items with separators
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>Don't forget asChild - it prevents nested button issues
// β Bad
<DropdownMenuTrigger>
<DesignButton>Open</DesignButton>
</DropdownMenuTrigger>
// β
Good
<DropdownMenuTrigger asChild>
<DesignButton>Open</DesignButton>
</DropdownMenuTrigger>Don't mix CheckboxItem and RadioItem in the same group
// β Bad - confusing UX
<DropdownMenuCheckboxItem />
<DropdownMenuRadioItem />
// β
Good - use one type per section
<DropdownMenuRadioGroup>
<DropdownMenuRadioItem />
<DropdownMenuRadioItem />
</DropdownMenuRadioGroup>Don't put destructive actions at the top
// β Bad - dangerous
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
<DropdownMenuItem>Edit</DropdownMenuItem>
// β
Good - destructive at bottom
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>Interactive examples showing all variants
Edit, duplicate, delete pattern
<DropdownMenuItem><DesignIcon name="edit" />Edit</DropdownMenuItem>
<DropdownMenuItem variant="destructive"><DesignIcon name="delete" />Delete</DropdownMenuItem>Grouped with section headers
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem>...</DropdownMenuItem>Toggle settings
<DropdownMenuCheckboxItem checked={checked} onCheckedChange={setChecked}>
Option
</DropdownMenuCheckboxItem>Single selection
<DropdownMenuRadioGroup value={value} onValueChange={setValue}>
<DropdownMenuRadioItem value="opt">Option</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>Nested menu with arrow
<DropdownMenuSub>
<DropdownMenuSubTrigger>Submenu</DropdownMenuSubTrigger>
<DropdownMenuSubContent>...</DropdownMenuSubContent>
</DropdownMenuSub>Edit/delete on hover
<DropdownMenuItemWithActions
selected={selected}
onSelect={handleSelect}
onEdit={handleEdit}
onDelete={handleDelete}
>
Item
</DropdownMenuItemWithActions>