Usage
import { DropdownMenu } from "@voila.dev/ui/dropdown-menu";<DropdownMenu.Root>
<DropdownMenu.Trigger render={<Button variant="outline" />}>Actions</DropdownMenu.Trigger>
<DropdownMenu.Content className="w-56">
<DropdownMenu.Label>Launch review</DropdownMenu.Label>
<DropdownMenu.Group>
<DropdownMenu.Item>
Edit project
<DropdownMenu.Shortcut>⌘E</DropdownMenu.Shortcut>
</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Item variant="destructive">Cancel project</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>A menu of actions hanging off a button. Use it when the items do things; when they set a value that stays set, a Select is the honest control, because a menu that closes gives no sense of current state. For the same menu opened by right-click, ContextMenu is the same parts with a different trigger.
Recipes
Items compose: Group and Separator for structure, Sub and SubTrigger
for nesting, CheckboxItem and RadioItem for state, Shortcut for the key
hint. variant="destructive" tints the one item that deletes something — one
per menu, at the bottom, behind a separator.
inset indents an item so it lines up with siblings that have an icon or a
checkmark; without it a mixed menu's labels sit at two different left edges.
Shortcut takes either children (⌘K) or a keys array, which renders each
key as its own Kbd chip.
API
DropdownMenu.Root
| Prop | Type | Default | |
|---|---|---|---|
actionsRef | RefObject<MenuRootActions | null> | — | A ref to imperative actions. |
children | PayloadChildRenderFunction<unknown> | ReactNode | — | The content of the popover.
This can be a regular React node or a render function that receives the payload of the active trigger. |
closeParentOnEsc | boolean | — | When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. |
defaultOpen | boolean | — | Whether the menu is initially open. To render a controlled menu, use the open prop instead. |
defaultTriggerId | string | null | — | ID of the trigger that the popover is associated with.
This is useful in conjunction with the defaultOpen prop to create an initially open popover. |
disabled | boolean | — | Whether the component should ignore user interaction. |
handle | MenuHandle<unknown> | — | A handle to associate the menu with a trigger. If specified, allows external triggers to control the menu's open state. |
highlightItemOnHover | boolean | — | Whether moving the pointer over items should highlight them.
Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state. |
loopFocus | boolean | — | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
modal | boolean | — | Determines if the menu enters a modal state when open. |
onOpenChange | ((open: boolean, eventDetails: MenuRootChangeEventDetails) => void) | — | Event handler called when the menu is opened or closed. |
onOpenChangeComplete | ((open: boolean) => void) | — | Event handler called after any animations complete when the menu is closed. |
open | boolean | — | Whether the menu is currently open. |
orientation | MenuRootOrientation | — | The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. |
triggerId | string | null | — | ID of the trigger that the popover is associated with.
This is useful in conjunction with the open prop to create a controlled popover.
There's no need to specify this prop when the popover is uncontrolled (that is, when the open prop is not set). |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-root.tsx.
DropdownMenu.CheckboxItem
| Prop | Type | Default | |
|---|---|---|---|
inset | boolean | — | Indents the item to line up with siblings that have an icon or a checkmark. |
checked | boolean | — | Whether the checkbox item is currently ticked. To render an uncontrolled checkbox item, use the defaultChecked prop instead. |
className | string | ((state: MenuCheckboxItemState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
closeOnClick | boolean | — | Whether to close the menu when the item is clicked. |
defaultChecked | boolean | — | Whether the checkbox item is initially ticked. To render a controlled checkbox item, use the checked prop instead. |
disabled | boolean | — | Whether the component should ignore user interaction. |
id | string | — | |
label | string | — | Overrides the text label to use when the item is matched during keyboard text navigation. |
nativeButton | boolean | — | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to true if the rendered element is a native button. |
onCheckedChange | ((checked: boolean, eventDetails: MenuRootChangeEventDetails) => void) | — | Event handler called when the checkbox item is ticked or unticked. |
onClick | ((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — | The click handler for the menu item. |
render | ComponentRenderFn<HTMLProps, MenuCheckboxItemState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuCheckboxItemState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-checkbox-item.tsx.
DropdownMenu.Content
| Prop | Type | Default | |
|---|---|---|---|
align | Align | "start" | How to align the popup relative to the specified side. |
alignOffset | number | OffsetFunction | 0 | Additional offset along the alignment axis in pixels.
Also accepts a function that returns the offset to read the dimensions of the anchor
and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: |
children | ReactNode | — | |
className | string | ((state: MenuPopupState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
finalFocus | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => void | boolean | HTMLElement | null) | — | Determines the element to focus when the menu is closed. |
id | string | — | |
render | ComponentRenderFn<HTMLProps, MenuPopupState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
side | Side | "bottom" | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
sideOffset | number | OffsetFunction | 4 | Distance between the anchor and the popup in pixels.
Also accepts a function that returns the distance to read the dimensions of the anchor
and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: |
style | CSSProperties | ((state: MenuPopupState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-content.tsx.
DropdownMenu.Group
| Prop | Type | Default | |
|---|---|---|---|
children | ReactNode | — | The content of the component. |
className | string | ((state: MenuGroupState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
render | ComponentRenderFn<HTMLProps, MenuGroupState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuGroupState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-group.tsx.
DropdownMenu.Item
| Prop | Type | Default | |
|---|---|---|---|
inset | boolean | — | Indents the item to line up with siblings that have an icon or a checkmark. |
variant | "default" | "destructive" | "default" | destructive tints the item red, for the one action that deletes something. |
className | string | ((state: MenuItemState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
closeOnClick | boolean | — | Whether to close the menu when the item is clicked. |
disabled | boolean | — | Whether the component should ignore user interaction. |
id | string | — | |
label | string | — | Overrides the text label to use when the item is matched during keyboard text navigation. |
nativeButton | boolean | — | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to true if the rendered element is a native button. |
onClick | ((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — | The click handler for the menu item. |
render | ComponentRenderFn<HTMLProps, MenuItemState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuItemState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-item.tsx.
DropdownMenu.Label
| Prop | Type | Default | |
|---|---|---|---|
inset | boolean | — | Indents the item to line up with siblings that have an icon or a checkmark. |
Plus every <div> prop. Source: dropdown-menu/components/dropdown-menu-label.tsx.
DropdownMenu.Portal
| Prop | Type | Default | |
|---|---|---|---|
className | string | ((state: MenuPortalState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
container | HTMLElement | RefObject<HTMLElement | ShadowRoot | null> | ShadowRoot | null | — | A parent element to render the portal element into. |
keepMounted | boolean | — | Whether to keep the portal mounted in the DOM while the popup is hidden. |
render | ComponentRenderFn<HTMLProps, MenuPortalState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuPortalState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-portal.tsx.
DropdownMenu.RadioGroup
| Prop | Type | Default | |
|---|---|---|---|
children | ReactNode | — | The content of the component. |
className | string | ((state: MenuRadioGroupState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
defaultValue | any | — | The uncontrolled value of the radio item that should be initially selected. To render a controlled radio group, use the value prop instead. |
disabled | boolean | — | Whether the component should ignore user interaction. |
onValueChange | ((value: any, eventDetails: MenuRootChangeEventDetails) => void) | — | Function called when the selected value changes. |
render | ComponentRenderFn<HTMLProps, MenuRadioGroupState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuRadioGroupState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
value | any | — | The controlled value of the radio item that should be currently selected. To render an uncontrolled radio group, use the defaultValue prop instead. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-radio-group.tsx.
DropdownMenu.RadioItem
| Prop | Type | Default | |
|---|---|---|---|
inset | boolean | — | Indents the item to line up with siblings that have an icon or a checkmark. |
value | any | required | Value of the radio item. This is the value that will be set in the MenuRadioGroup when the item is selected. |
className | string | ((state: MenuRadioItemState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
closeOnClick | boolean | — | Whether to close the menu when the item is clicked. |
disabled | boolean | — | Whether the component should ignore user interaction. |
id | string | — | |
label | string | — | Overrides the text label to use when the item is matched during keyboard text navigation. |
nativeButton | boolean | — | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to true if the rendered element is a native button. |
onClick | ((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — | The click handler for the menu item. |
render | ComponentRenderFn<HTMLProps, MenuRadioItemState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuRadioItemState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-radio-item.tsx.
DropdownMenu.Separator
| Prop | Type | Default | |
|---|---|---|---|
className | string | ((state: SeparatorState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
orientation | Orientation | — | The orientation of the separator. |
render | ComponentRenderFn<HTMLProps, SeparatorState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: SeparatorState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-separator.tsx.
DropdownMenu.Shortcut
| Prop | Type | Default | |
|---|---|---|---|
keys | readonly string[] | — | Render each key as a small Kbd chip. Omit it and children are shown as plain text. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-shortcut.tsx.
DropdownMenu.Sub
| Prop | Type | Default | |
|---|---|---|---|
actionsRef | RefObject<MenuRootActions | null> | — | A ref to imperative actions. |
children | ReactNode | — | The content of the submenu. |
closeParentOnEsc | boolean | — | When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. |
defaultOpen | boolean | — | Whether the menu is initially open. To render a controlled menu, use the open prop instead. |
disabled | boolean | — | Whether the component should ignore user interaction. |
highlightItemOnHover | boolean | — | Whether moving the pointer over items should highlight them.
Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state. |
loopFocus | boolean | — | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
onOpenChange | ((open: boolean, eventDetails: MenuRootChangeEventDetails) => void) | — | Event handler called when the menu is opened or closed. |
onOpenChangeComplete | ((open: boolean) => void) | — | Event handler called after any animations complete when the menu is closed. |
open | boolean | — | Whether the menu is currently open. |
orientation | MenuRootOrientation | — | The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-sub.tsx.
DropdownMenu.SubContent
| Prop | Type | Default | |
|---|---|---|---|
align | Align | — | How to align the popup relative to the specified side. |
alignOffset | number | OffsetFunction | -3 | Additional offset along the alignment axis in pixels.
Also accepts a function that returns the offset to read the dimensions of the anchor
and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: |
children | ReactNode | — | |
className | string | ((state: MenuPopupState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
finalFocus | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => void | boolean | HTMLElement | null) | — | Determines the element to focus when the menu is closed. |
id | string | — | |
render | ComponentRenderFn<HTMLProps, MenuPopupState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
side | Side | "inline-end" | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
sideOffset | number | OffsetFunction | 0 | Distance between the anchor and the popup in pixels.
Also accepts a function that returns the distance to read the dimensions of the anchor
and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: |
style | CSSProperties | ((state: MenuPopupState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-sub-content.tsx.
DropdownMenu.SubTrigger
| Prop | Type | Default | |
|---|---|---|---|
inset | boolean | — | Indents the item to line up with siblings that have an icon or a checkmark. |
className | string | ((state: MenuSubmenuTriggerState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
closeDelay | number | — | How long to wait before closing the menu that was opened on hover.
Specified in milliseconds. Requires the openOnHover prop. |
delay | number | — | How long to wait before the menu may be opened on hover. Specified in milliseconds. Requires the openOnHover prop. |
disabled | boolean | — | Whether the component should ignore user interaction. |
id | string | — | |
label | string | — | Overrides the text label to use when the item is matched during keyboard text navigation. |
nativeButton | boolean | — | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to true if the rendered element is a native button. |
onClick | ((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — | |
openOnHover | boolean | — | Whether the menu should also open when the trigger is hovered. |
render | ComponentRenderFn<HTMLProps, MenuSubmenuTriggerState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuSubmenuTriggerState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-sub-trigger.tsx.
DropdownMenu.Trigger
| Prop | Type | Default | |
|---|---|---|---|
children | ReactNode | — | |
className | string | ((state: MenuTriggerState) => string | undefined) | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
closeDelay | number | — | How long to wait before closing the menu that was opened on hover.
Specified in milliseconds. Requires the openOnHover prop. |
delay | number | — | How long to wait before the menu may be opened on hover. Specified in milliseconds. Requires the openOnHover prop. |
disabled | boolean | — | Whether the component should ignore user interaction. |
handle | MenuHandle<unknown> | — | A handle to associate the trigger with a menu. |
nativeButton | boolean | — | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>). |
openOnHover | boolean | — | Whether the menu should also open when the trigger is hovered. |
payload | unknown | — | A payload to pass to the menu when it is opened. |
render | ComponentRenderFn<HTMLProps, MenuTriggerState> | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
style | CSSProperties | ((state: MenuTriggerState) => CSSProperties | undefined) | — | Style applied to the element, or a function that returns a style object based on the component's state. |
Plus the DOM props of the element it renders. Source: dropdown-menu/components/dropdown-menu-trigger.tsx.
Related
ContextMenu · Menubar · Select · Popover