DropdownMenu
The DropdownMenu component provides a way to create customizable dropdown menus. It can render submenus and show item various indicators.
It can be composed with several subcomponents such as DropdownMenu.Root, DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Header, DropdownMenu.Footer, DropdownMenu.Separator, DropdownMenu.Group and DropdownMenu.Item to offer a structured and customizable interface.
DropdownMenu.Item has such variations as AvatarItem, LogoItem, IconItem, IndicatorItem, CheckboxItem, and RadioItem to provide different types of items for different use cases.
Usage
import { DropdownMenu } from "@harnessio/ui/components";
//...
return ( <DropdownMenu.Root> <DropdownMenu.Trigger aria-label="options menu"> <IconV2 name="more-horizontal" /> </DropdownMenu.Trigger>
<DropdownMenu.Content> <DropdownMenu.Item onSelect={onEdit}>Edit</DropdownMenu.Item> <DropdownMenu.Item onSelect={onDelete}>Delete</DropdownMenu.Item> </DropdownMenu.Content> </DropdownMenu.Root>)Anatomy
All parts of the DropdownMenu component can be imported and composed as required.
<DropdownMenu.Root> <DropdownMenu.Trigger /> <DropdownMenu.Content> <DropdownMenu.Item /> <DropdownMenu.Group> <DropdownMenu.Item /> </DropdownMenu.Group> <DropdownMenu.Separator /> <DropdownMenu.RadioGroup> <DropdownMenu.RadioItem /> </DropdownMenu.RadioGroup> <DropdownMenu.Item> <DropdownMenu.AvatarItem /> <DropdownMenu.LogoItem /> <DropdownMenu.IconItem /> <DropdownMenu.IndicatorItem /> <DropdownMenu.CheckboxItem /> <DropdownMenu.RadioItem /> </DropdownMenu.Item> </DropdownMenu.Content></DropdownMenu.Root>Grouped items
The DropdownMenu component supports grouping items together using the DropdownMenu.Group component. This allows you to create a structured menu with labeled sections.
Submenus
The DropdownMenu component supports subitems using the DropdownMenu.Item component. This allows you to create items that can have their own nested items, effectively creating a submenu.
Header and Footer
The DropdownMenu component supports header and footer sections using the DropdownMenu.Header and DropdownMenu.Footer components. This allows you to add additional content at the top or bottom of the dropdown menu.
Checkbox items
The DropdownMenu component supports checkbox items using the DropdownMenu.CheckboxItem component. This allows you to create items with checkboxes that can be checked or unchecked.
Radio items
The DropdownMenu component supports radio items using the DropdownMenu.RadioItem component. This allows you to create items with radio buttons that can be selected.
Avatar items
The DropdownMenu component supports avatar items using the DropdownMenu.AvatarItem component. This allows you to create items with avatars that can be used to represent users or other entities.
Logo items
The DropdownMenu component supports logo items using the DropdownMenu.LogoItem component. This allows you to create items with logos that can be used to represent brands or services.
Icon items
The DropdownMenu component supports icon items using the DropdownMenu.IconItem component. This allows you to create items with icons that can be used to represent actions or statuses.
Indicator items
The DropdownMenu component supports indicator items using the DropdownMenu.IndicatorItem component. This allows you to create items with indicators that can be used to make color pickers or other visual indicators.
Spinner
The DropdownMenu component supports loading states using the DropdownMenu.Spinner component. This is useful when the dropdown content is being loaded asynchronously.
No Options
The DropdownMenu component supports empty states using the DropdownMenu.NoOptions component. This is useful when there are no items to display in the dropdown menu.
Slot
The DropdownMenu.Slot component provides a simple wrapper for custom content within the dropdown menu. This is useful for adding custom components or layouts that don’t fit the standard item patterns.
API Reference
Root
The Root component serves as the main container for all dropdown menu elements.
It requires both a Trigger and Content as children. It can be used in either
a controlled or uncontrolled manner. When used in a controlled manner, you must
pass in the open and onOpenChange props. When used in an uncontrolled manner,
the open state is stored internally.
<DropdownMenu.Root open // [OPTIONAL] controlled open state onOpenChange={onChange} // [OPTIONAL] event handler called when the open state changes defaultOpen // [OPTIONAL] default open state modal // [OPTIONAL] when set to true, interaction with outside elements // will be disabled and only menu content will be // visible to screen readers. dir // [OPTIONAL] reading direction of the dropdown> {/* Trigger and Content */}</DropdownMenu.Root>Prop | Required | Default | Type |
|---|---|---|---|
| open | false | false | boolean |
| onOpenChange | false | (open: boolean) => void | |
| defaultOpen | false | false | boolean |
| modal | false | true | boolean |
| dir | false | 'ltr' | 'rtl' | |
| children | true | ReactNode |
Trigger
The Trigger component represents the button that triggers the dropdown menu.
<DropdownMenu.Trigger className="my-class" // [OPTIONAL] custom class asChild // [OPTIONAL] render the trigger as the child disabled // [OPTIONAL] disable the trigger> {/* Trigger content */}</DropdownMenu.Trigger>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| asChild | false | false | boolean |
| disabled | false | false | boolean |
| children | true | ReactNode |
Content
The Content component represents the dropdown menu content.
<DropdownMenu.Content className="my-class" // [OPTIONAL] custom class sideOffset={4} // [OPTIONAL] offset from the trigger align="start" // [OPTIONAL] alignment relative to trigger alignOffset={0} // [OPTIONAL] offset from align side="bottom" // [OPTIONAL] preferred side of the trigger> {/* Item, Group, Separator, RadioGroup, Header, Footer */}</DropdownMenu.Content>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| sideOffset | false | 4 | number |
| align | false | 'center' | 'start' | 'center' | 'end' |
| alignOffset | false | 0 | number |
| side | false | 'bottom' | 'top' | 'right' | 'bottom' | 'left' |
| children | true | ReactNode |
Item
The Item component represents a dropdown menu item.
<DropdownMenu.Item title="Item title" // title of the item description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon prefix={<IconV2 />} // [OPTIONAL] prefix element (icon, avatar, etc.) className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item onSelect={onSelect} // [OPTIONAL] event handler called when the item is selected textValue="text" // [OPTIONAL] text value for typeahead asChild // [OPTIONAL] render the item as the child> {/* Optional nested items for submenu */}</DropdownMenu.Item>Prop | Required | Default | Type |
|---|---|---|---|
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| prefix | false | ReactNode | |
| className | false | string | |
| disabled | false | false | boolean |
| onSelect | false | (event: Event) => void | |
| textValue | false | string | |
| asChild | false | false | boolean |
| children | false | ReactNode |
Separator
The Separator component represents a visual divider between menu items.
<DropdownMenu.Separator className="my-class" // [OPTIONAL] custom class/>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string |
Group
The Group component represents a labeled group of menu items.
<DropdownMenu.Group label="Group label" // [OPTIONAL] label for the group className="my-class" // [OPTIONAL] custom class> {/* Group items */}</DropdownMenu.Group>Prop | Required | Default | Type |
|---|---|---|---|
| label | false | string | |
| className | false | string | |
| children | true | ReactNode |
Header
The Header component represents a header section with a separator.
<DropdownMenu.Header className="my-class" // [OPTIONAL] custom class> {/* Header content */}</DropdownMenu.Header>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| children | true | ReactNode |
Footer
The Footer component represents a footer section with a separator.
<DropdownMenu.Footer className="my-class" // [OPTIONAL] custom class> {/* Footer content */}</DropdownMenu.Footer>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| children | true | ReactNode |
CheckboxItem
The CheckboxItem component displays a checkbox next to the item. When the user interacts with the checkbox, the
onCheckedChange prop is called. Setting the checked prop will set whether the checkbox is checked.
<DropdownMenu.CheckboxItem title="Item title" // title of the item checked // [OPTIONAL] whether the checkbox is checked onCheckedChange={onChange} // [OPTIONAL] callback when checked state changes description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item> {/* Optional nested items for submenu */}</DropdownMenu.CheckboxItem>Prop | Required | Default | Type |
|---|---|---|---|
| title | true | ReactNode | |
| checked | false | false | boolean | 'indeterminate' |
| onCheckedChange | false | (checked: boolean) => void | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
| children | false | ReactNode |
RadioGroup
The RadioGroup component groups together RadioItem components and controls the selected radio item.
<DropdownMenu.RadioGroup value // [OPTIONAL] the selected radio item onValueChange={onChange} // [OPTIONAL] callback when selection changes label="Group label" // [OPTIONAL] label for the group className="my-class" // [OPTIONAL] custom class> {/* RadioItem components */}</DropdownMenu.RadioGroup>Prop | Required | Default | Type |
|---|---|---|---|
| value | false | string | |
| onValueChange | false | (value: string) => void | |
| label | false | string | |
| className | false | string | |
| children | true | ReactNode |
RadioItem
The RadioItem component displays a radio button next to the item. When the user interacts with the radio button, the
the onValueChange prop of the parent RadioGroup component is called with the value from the clicked RadioItem.
<DropdownMenu.RadioGroup value={currentItem} onValueChange={setCurrentItem}> <DropdownMenu.RadioItem value="item-1" // value of the item title="Item title" // title of the item description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item > {/* Item content */} </DropdownMenu.RadioItem></DropdownMenu.RadioGroup>Prop | Required | Default | Type |
|---|---|---|---|
| value | true | string | |
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
AvatarItem
The AvatarItem component is a specialized item that displays an avatar.
<DropdownMenu.AvatarItem src="/avatar.png" // avatar image source title="Item title" // title of the item rounded // [OPTIONAL] rounded avatar description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item onSelect={onSelect} // [OPTIONAL] event handler> {/* Optional nested items for submenu */}</DropdownMenu.AvatarItem>Prop | Required | Default | Type |
|---|---|---|---|
| src | false | string | |
| rounded | false | true | boolean |
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
| onSelect | false | (event: Event) => void | |
| children | false | ReactNode |
LogoItem
The LogoItem component is a specialized item that displays a logo.
<DropdownMenu.LogoItem logo="gitlab" // logo name title="Item title" // title of the item original // [OPTIONAL] use original logo colors description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item onSelect={onSelect} // [OPTIONAL] event handler> {/* Optional nested items for submenu */}</DropdownMenu.LogoItem>Prop | Required | Default | Type |
|---|---|---|---|
| logo | true | string | |
| original | false | false | boolean |
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
| onSelect | false | (event: Event) => void | |
| children | false | ReactNode |
IconItem
The IconItem component is a specialized item that displays an icon.
<DropdownMenu.IconItem icon="git-pull-request-closed" // icon name title="Item title" // title of the item description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item onSelect={onSelect} // [OPTIONAL] event handler> {/* Optional nested items for submenu */}</DropdownMenu.IconItem>Prop | Required | Default | Type |
|---|---|---|---|
| icon | true | string | |
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
| onSelect | false | (event: Event) => void | |
| children | false | ReactNode |
IndicatorItem
The IndicatorItem component is a specialized item that displays a color indicator.
<DropdownMenu.IndicatorItem color="green" // indicator color title="Item title" // title of the item pulse // [OPTIONAL] animate the indicator description="Description" // [OPTIONAL] description text label="Label" // [OPTIONAL] right-aligned label shortcut="⌘K" // [OPTIONAL] keyboard shortcut checkmark // [OPTIONAL] show checkmark icon className="my-class" // [OPTIONAL] custom class disabled // [OPTIONAL] disable the item onSelect={onSelect} // [OPTIONAL] event handler> {/* Optional nested items for submenu */}</DropdownMenu.IndicatorItem>Prop | Required | Default | Type |
|---|---|---|---|
| color | true | 'gray' | 'green' | 'red' | 'yellow' | 'blue' | 'purple' | 'brown' | 'cyan' | 'indigo' | 'lime' | 'mint' | 'orange' | 'pink' | 'violet' | |
| pulse | false | false | boolean |
| title | true | ReactNode | |
| description | false | string | |
| label | false | string | |
| shortcut | false | string | |
| checkmark | false | false | boolean |
| className | false | string | |
| disabled | false | false | boolean |
| onSelect | false | (event: Event) => void | |
| children | false | ReactNode |
Spinner
The Spinner component displays a loading indicator within the dropdown menu.
<DropdownMenu.Spinner className="my-class" // [OPTIONAL] custom class> {/* Optional children content */}</DropdownMenu.Spinner>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| children | false | ReactNode |
NoOptions
The NoOptions component displays a message when there are no menu items available.
<DropdownMenu.NoOptions className="my-class" // [OPTIONAL] custom class> {/* Custom message - defaults to "No options available" */}</DropdownMenu.NoOptions>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| children | false | "No options available" | ReactNode |
Slot
The Slot component provides a flexible container for custom content within the dropdown menu.
<DropdownMenu.Slot className="my-class" // [OPTIONAL] custom class> {/* Custom content */}</DropdownMenu.Slot>Prop | Required | Default | Type |
|---|---|---|---|
| className | false | string | |
| children | false | ReactNode |