A dropdown menu displays a list of actions or options when triggered, supporting nested submenus, checkboxes, radio groups, and keyboard navigation.
Installation
npm install @kuzenbo/core
Usage
Basic Example
import { DropdownMenu, Button } from "@kuzenbo/core";
export default function DropdownMenuExample() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button variant="outline" />}>
Workspace: Acme Platform
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>Workspace actions</DropdownMenu.Label>
<DropdownMenu.Item>Open workspace settings</DropdownMenu.Item>
<DropdownMenu.Item>Invite teammate</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Item variant="danger">Leave workspace</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}
With Checkbox Items
import { DropdownMenu, Button } from "@kuzenbo/core";
export default function CheckboxExample() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button variant="outline" />}>
Columns
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>Table columns</DropdownMenu.Label>
<DropdownMenu.CheckboxItem defaultChecked>
Status
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem defaultChecked>
Owner
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem>
Priority
</DropdownMenu.CheckboxItem>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu>
);
}
import { DropdownMenu, Button } from "@kuzenbo/core";
export default function SubmenuExample() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button variant="outline" />}>
Options
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item>Open dashboard</DropdownMenu.Item>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger>Switch workspace</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Item>Acme Platform</DropdownMenu.Item>
<DropdownMenu.Item>Security Ops</DropdownMenu.Item>
<DropdownMenu.Item>Customer Success</DropdownMenu.Item>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Separator />
<DropdownMenu.Item>Settings</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}
With Shortcuts
import { DropdownMenu, Button } from "@kuzenbo/core";
export default function ShortcutsExample() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button variant="outline" />}>
Actions
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>Release workflow</DropdownMenu.Label>
<DropdownMenu.Item>
Start release
<DropdownMenu.Shortcut>⌘R</DropdownMenu.Shortcut>
</DropdownMenu.Item>
<DropdownMenu.Item>
Rollback
<DropdownMenu.Shortcut>⇧⌘R</DropdownMenu.Shortcut>
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu>
);
}
Composed Anatomy
import { DropdownMenu, Button } from "@kuzenbo/core";
export default function ComposedDropdown() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button variant="outline" />}>
Account
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Backdrop />
<DropdownMenu.Positioner>
<DropdownMenu.Popup>
<DropdownMenu.Arrow />
<DropdownMenu.Group>
<DropdownMenu.Label>Account</DropdownMenu.Label>
<DropdownMenu.Item>Profile</DropdownMenu.Item>
<DropdownMenu.LinkItem href="/billing">
Billing
</DropdownMenu.LinkItem>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Item variant="danger">Sign out</DropdownMenu.Item>
</DropdownMenu.Popup>
</DropdownMenu.Positioner>
</DropdownMenu.Portal>
</DropdownMenu>
);
}
API Reference
The initial open state when uncontrolled.
The controlled open state of the menu.
Callback fired when the open state changes.
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
default:"'md'"
The size variant for the menu.
side
'top' | 'right' | 'bottom' | 'left'
default:"'bottom'"
The preferred side of the trigger to render against.
The distance in pixels from the trigger.
align
'start' | 'center' | 'end'
default:"'start'"
The alignment of the menu relative to the trigger.
The offset in pixels from the alignment axis.
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
Override the root size for this content.
Additional CSS classes to apply.
variant
'default' | 'danger'
default:"'default'"
The visual variant of the item.
Whether the item is disabled.
Callback fired when the item is selected.
The controlled checked state.
The initial checked state when uncontrolled.
onCheckedChange
(checked: boolean) => void
Callback fired when the checked state changes.
The controlled value of the selected radio item.
The initial value when uncontrolled.
Callback fired when the value changes.
The value of this radio item.
Visual separator between menu items.
The keyboard shortcut text.
The element to render as the trigger.
Component Parts
DropdownMenu - Root component that manages state
DropdownMenu.Trigger - Opens the menu
DropdownMenu.Portal - Portals the menu content
DropdownMenu.Positioner - Positions the menu relative to trigger
DropdownMenu.Popup - The menu container
DropdownMenu.Content - Convenience wrapper
DropdownMenu.Item - A menu item
DropdownMenu.CheckboxItem - A checkable menu item
DropdownMenu.RadioGroup - Groups radio items
DropdownMenu.RadioItem - A radio menu item
DropdownMenu.LinkItem - A navigation menu item
DropdownMenu.Label - A non-interactive label
DropdownMenu.Separator - Visual separator
DropdownMenu.Shortcut - Keyboard shortcut indicator
DropdownMenu.Sub - Submenu root
DropdownMenu.SubTrigger - Opens a submenu
DropdownMenu.SubContent - Submenu content
DropdownMenu.Group - Groups related items
DropdownMenu.Arrow - Visual arrow indicator
DropdownMenu.Backdrop - Optional backdrop overlay
Accessibility
- Full keyboard navigation support
- Arrow keys navigate between items
- Enter or Space activates items
- Escape closes the menu
- Type-ahead to focus items
- Proper ARIA attributes
- Focus management on open/close