Skip to content

DropdownMenu

Button-triggered menu for grouped actions.

<DropdownMenu
button={{label: 'Actions'}}
items={[ {icon: Edit, label: 'Edit'}, {icon: Archive, label: 'Archive'}, {type: 'divider'}, {icon: Trash2, label: 'Delete'}, ]}
/>
<DropdownMenu {...args}>
<DropdownMenuItem icon={Edit} label="Edit" />
<DropdownMenuItem icon={Archive} label="Archive" />
<DropdownMenuItem icon={Trash2} label="Delete" />
</DropdownMenu>
function KeepOpenOnSelectStory(
args: React.ComponentProps<typeof DropdownMenu>,
): React.JSX.Element {
const [visible, setVisible] = useState<ReadonlySet<string>>(
() => new Set(['Name', 'Email']),
);
const toggle = (column: string): void => {
setVisible(current => {
const next = new Set(current);
if (next.has(column)) {
next.delete(column);
} else {
next.add(column);
}
return next;
});
};
return (
<DropdownMenu {...args} button={{label: 'Columns'}}>
{columns.map(column => (
<DropdownMenuItem
endContent={
visible.has(column) ? (
<Icon color="secondary" icon={Check} size="sm" />
) : null
}
hasCloseOnSelect={false}
key={column}
label={column}
onClick={() => toggle(column)}
/>
))}
<DropdownMenuItem
label="Show all"
onClick={() => setVisible(new Set(columns))}
/>
</DropdownMenu>
);
}
<KeepOpenOnSelectStory {...args} />
<DropdownMenu
button={{label: 'Actions'}}
alignment="end"
items={[ {icon: Edit, label: 'Edit'}, {icon: Archive, label: 'Archive'}, {type: 'divider'}, {icon: Trash2, label: 'Delete'}, ]}
isMenuOpen
menuWidth={240}
offsetY={8}
placement="below"
/>
<DropdownMenu
button={{label: 'Actions'}}
items={[ {description: 'Modify this item', icon: Edit, label: 'Edit'}, {description: 'Move to archive', icon: Archive, label: 'Archive'}, {type: 'divider'}, {description: 'Permanently remove', icon: Trash2, label: 'Delete'}, ]}
/>
<DropdownMenu
button={{label: 'Actions'}}
items={[ { icon: Edit, label: 'Edit', tooltip: 'Change the item title and details.', }, { icon: Archive, label: 'Archive', tooltip: 'Move the item out of active lists without deleting it.', }, {type: 'divider'}, { icon: Trash2, label: 'Delete', tooltip: 'Permanently remove the item.', }, ]}
/>
<DropdownMenu {...args}>
<DropdownMenuItem
endContent={<Kbd keys="mod+e" />}
icon={Edit}
label="Edit"
/>
<DropdownMenuItem
endContent={<Kbd keys="mod+shift+a" />}
icon={Archive}
label="Archive"
/>
<DropdownMenuItem
endContent={<Kbd keys="backspace" />}
icon={Trash2}
label="Delete"
/>
</DropdownMenu>
<DropdownMenu
button={{label: 'Actions'}}
items={[ {icon: Edit, label: 'Edit'}, {icon: Archive, isDisabled: true, label: 'Archive'}, {type: 'divider'}, {icon: Trash2, isDisabled: true, label: 'Delete'}, ]}
/>
<DropdownMenu
button={{label: 'Actions'}}
items={[ { items: [ {icon: Edit, label: 'Edit'}, {icon: Archive, label: 'Archive'}, ], title: 'Actions', type: 'section', }, { items: [{icon: Trash2, label: 'Delete'}], title: 'Danger', type: 'section', }, ]}
/>
<DropdownMenu
button={{icon: MoreVertical, isIconOnly: true, label: 'More actions'}}
items={[ {icon: Edit, label: 'Edit'}, {icon: Archive, label: 'Archive'}, {type: 'divider'}, {icon: Trash2, label: 'Delete'}, ]}
/>
<div style={{display: 'flex', gap: '1rem'}}>
<DropdownMenu
button={{label: 'Small', size: 'sm'}}
items={[
{icon: Edit, label: 'Edit'},
{icon: Archive, label: 'Archive'},
{type: 'divider'},
{icon: Trash2, label: 'Delete'},
]}
/>
<DropdownMenu
button={{label: 'Medium'}}
items={[
{icon: Edit, label: 'Edit'},
{icon: Archive, label: 'Archive'},
{type: 'divider'},
{icon: Trash2, label: 'Delete'},
]}
/>
<DropdownMenu
button={{label: 'Large', size: 'lg'}}
items={[
{icon: Edit, label: 'Edit'},
{icon: Archive, label: 'Archive'},
{type: 'divider'},
{icon: Trash2, label: 'Delete'},
]}
/>
</div>
<DropdownMenu
button={{label: 'Actions', variant: 'ghost'}}
items={[ {icon: Edit, label: 'Edit'}, {icon: Archive, label: 'Archive'}, ]}
/>

Button-triggered menu for grouped actions.

PropTypeDefaultDescription
alignment"center" | "start" | "end"'start'Alignment along the placement axis.
buttonDropdownMenuButtonProps—Trigger button props.
childrenReactNode—Compound menu content (alternative to items).
classNamestring—Additional CSS class names applied to the menu surface.
data-testidstring—Test ID applied to the trigger button.
hasAutoFocusbooleantrueWhether to auto-focus the first menu item on open.
hasChevronbooleantrueWhether to show a chevron on the trigger button.
isMenuOpenboolean—Controlled open state.
itemsReadonlyArray<DropdownMenuOption>—Data-driven menu items.
menuWidthnumber | string—Width of the menu surface.
offsetXnumber—Gap in pixels between the menu and its trigger along the inline axis.
offsetYnumber—Gap in pixels between the menu and its trigger along the block axis.
onClick() => void—Click handler for the trigger button.
onOpenChange(isOpen: boolean) => void—Called when the menu open state changes.
placement"start" | "end" | "above" | "below"'below'Position relative to the trigger.
refRef<HTMLButtonElement>—Ref forwarded to the trigger button.
styleCSSProperties—Inline styles applied to the menu surface.

Action item inside a `DropdownMenu`.

PropTypeDefaultDescription
aria-keyshortcutsAriaAttributes['aria-keyshortcuts']—Keyboard shortcuts that activate the menu item.
classNamestring—Additional CSS class names applied to the item.
data-testidstring—Test ID applied to the item.
descriptionReactNode—Supporting text shown below the label.
endContentReactNode—Trailing content.
hasCloseOnSelectbooleantrueWhether activating the item closes the menu. Set to false for items users flip repeatedly, such as toggles, so the menu stays open with focus on the item.
iconIconComponent—Icon rendered before the label.
isDisabledbooleanfalseWhether the item is disabled.
label*string—Item label.
onClick() => void—Called when the item is selected.
refRef<HTMLButtonElement>—Ref forwarded to the item button.
styleCSSProperties—Inline styles applied to the item.
tooltipReactNode—Tooltip content shown when the item is hovered or focused.