Skip to main content

Overview

A dropdown menu displays a list of actions or options triggered by a button.

Features

  • Can be controlled or uncontrolled
  • Supports submenus with configurable reading direction
  • Supports items, labels, groups of items
  • Supports checkable items (single or multiple)
  • Customize side, alignment, offsets, collision handling
  • Focus is fully managed
  • Full keyboard navigation
  • Typeahead support
  • Optional modal or non-modal mode

Installation

npm install @radix-ui/react-dropdown-menu

Anatomy

Import all parts and piece them together.
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';

export default () => (
  <DropdownMenu.Root>
    <DropdownMenu.Trigger />
    <DropdownMenu.Portal>
      <DropdownMenu.Content>
        <DropdownMenu.Label />
        <DropdownMenu.Item />

        <DropdownMenu.Group>
          <DropdownMenu.Item />
        </DropdownMenu.Group>

        <DropdownMenu.CheckboxItem>
          <DropdownMenu.ItemIndicator />
        </DropdownMenu.CheckboxItem>

        <DropdownMenu.RadioGroup>
          <DropdownMenu.RadioItem>
            <DropdownMenu.ItemIndicator />
          </DropdownMenu.RadioItem>
        </DropdownMenu.RadioGroup>

        <DropdownMenu.Sub>
          <DropdownMenu.SubTrigger />
          <DropdownMenu.Portal>
            <DropdownMenu.SubContent />
          </DropdownMenu.Portal>
        </DropdownMenu.Sub>

        <DropdownMenu.Separator />
        <DropdownMenu.Arrow />
      </DropdownMenu.Content>
    </DropdownMenu.Portal>
  </DropdownMenu.Root>
);

API Reference

Root

Contains all the parts of a dropdown menu.
open
boolean
The controlled open state of the dropdown menu. Must be used in conjunction with onOpenChange.
defaultOpen
boolean
The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state.
onOpenChange
(open: boolean) => void
Event handler called when the open state of the dropdown menu changes.
dir
'ltr' | 'rtl'
The reading direction of submenus when applicable. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode.
modal
boolean
default:"true"
The modality of the dropdown menu. When set to true, interaction with outside elements will be disabled and only menu content will be visible to screen readers.

Trigger

The button that toggles the dropdown menu.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
Supports all standard HTML button attributes.

Portal

When used, portals the content part into the body.
container
HTMLElement
default:"document.body"
Specify a container element to portal the content into.
forceMount
boolean
Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

Content

The component that pops out when the dropdown menu is open.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
loop
boolean
default:"false"
When true, keyboard navigation will loop from last item to first, and vice versa.
side
'top' | 'right' | 'bottom' | 'left'
default:"'bottom'"
The preferred side of the trigger to render against when open.
sideOffset
number
default:"0"
The distance in pixels from the trigger.
align
'start' | 'center' | 'end'
default:"'center'"
The preferred alignment against the trigger. May change when collisions occur.
alignOffset
number
default:"0"
An offset in pixels from the “start” or “end” alignment options.
avoidCollisions
boolean
default:"true"
When true, overrides the side and align preferences to prevent collisions with boundary edges.
collisionBoundary
Element | Element[]
default:"[]"
The element used as the collision boundary. By default this is the viewport.
collisionPadding
number | Padding
default:"0"
The distance in pixels from the boundary edges where collision detection should occur.
sticky
'partial' | 'always'
default:"'partial'"
The sticky behavior on the align axis.
hideWhenDetached
boolean
default:"false"
Whether to hide the content when the trigger becomes fully occluded.
onCloseAutoFocus
(event: Event) => void
Event handler called when focus moves to the trigger after closing. It can be prevented by calling event.preventDefault.
onEscapeKeyDown
(event: KeyboardEvent) => void
Event handler called when the escape key is down. It can be prevented by calling event.preventDefault.
onPointerDownOutside
(event: PointerDownOutsideEvent) => void
Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling event.preventDefault.
onInteractOutside
(event: PointerDownOutsideEvent | FocusOutsideEvent) => void
Event handler called when an interaction happens outside the bounds of the component. It can be prevented by calling event.preventDefault.

Item

The component that contains the dropdown menu items.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
disabled
boolean
default:"false"
When true, prevents the user from interacting with the item.
onSelect
(event: Event) => void
Event handler called when the user selects an item (via mouse or keyboard). Calling event.preventDefault in this handler will prevent the dropdown menu from closing when selecting that item.
textValue
string
Optional text used for typeahead purposes. By default, the typeahead behavior will use the .textContent of the item. Use this when the content is complex, or you have non-textual content inside.

Group

Used to group multiple items. Use in conjunction with DropdownMenu.Label to ensure good accessibility via automatic labelling.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.

Label

Used to render a label. It won’t be focusable using arrow keys.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.

CheckboxItem

An item that can be controlled and rendered like a checkbox.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
checked
boolean | 'indeterminate'
The controlled checked state of the item. Must be used in conjunction with onCheckedChange.
onCheckedChange
(checked: boolean) => void
Event handler called when the checked state changes.
disabled
boolean
default:"false"
When true, prevents the user from interacting with the item.
onSelect
(event: Event) => void
Event handler called when the user selects an item (via mouse or keyboard). Calling event.preventDefault in this handler will prevent the dropdown menu from closing when selecting that item.
textValue
string
Optional text used for typeahead purposes.

RadioGroup

Used to group multiple DropdownMenu.RadioItems.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
value
string
The value of the selected item in the group.
onValueChange
(value: string) => void
Event handler called when the value changes.

RadioItem

An item that can be controlled and rendered like a radio.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
value
string
required
The unique value of the item.
disabled
boolean
default:"false"
When true, prevents the user from interacting with the item.
onSelect
(event: Event) => void
Event handler called when the user selects an item (via mouse or keyboard).
textValue
string
Optional text used for typeahead purposes.

ItemIndicator

Renders when the parent DropdownMenu.CheckboxItem or DropdownMenu.RadioItem is checked. You can style this element directly, or you can use it as a wrapper to put an icon into, or both.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
forceMount
boolean
Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

Separator

Used to visually separate items in the dropdown menu.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.

Sub

Contains all the parts of a submenu.
open
boolean
The controlled open state of the submenu. Must be used in conjunction with onOpenChange.
defaultOpen
boolean
The open state of the submenu when it is initially rendered. Use when you do not need to control its open state.
onOpenChange
(open: boolean) => void
Event handler called when the open state of the submenu changes.

SubTrigger

An item that opens a submenu. Must be rendered inside DropdownMenu.Sub.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
disabled
boolean
default:"false"
When true, prevents the user from interacting with the item.
textValue
string
Optional text used for typeahead purposes.

SubContent

The component that pops out when a submenu is open. Must be rendered inside DropdownMenu.Sub.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
loop
boolean
default:"false"
When true, keyboard navigation will loop from last item to first, and vice versa.
onEscapeKeyDown
(event: KeyboardEvent) => void
Event handler called when the escape key is down.
onPointerDownOutside
(event: PointerDownOutsideEvent) => void
Event handler called when a pointer event occurs outside the bounds of the component.

Arrow

An optional arrow element to render alongside the dropdown menu.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child, merging their props and behavior.
width
number
default:"10"
The width of the arrow in pixels.
height
number
default:"5"
The height of the arrow in pixels.

Example

import * as DropdownMenu from '@radix-ui/react-dropdown-menu';

function DropdownMenuDemo() {
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger className="button">
        Options
      </DropdownMenu.Trigger>
      <DropdownMenu.Portal>
        <DropdownMenu.Content className="dropdown-menu-content">
          <DropdownMenu.Item className="dropdown-menu-item">
            New Tab
          </DropdownMenu.Item>
          <DropdownMenu.Item className="dropdown-menu-item">
            New Window
          </DropdownMenu.Item>
          <DropdownMenu.Separator className="dropdown-menu-separator" />
          <DropdownMenu.Item className="dropdown-menu-item">
            Settings
          </DropdownMenu.Item>
        </DropdownMenu.Content>
      </DropdownMenu.Portal>
    </DropdownMenu.Root>
  );
}

Accessibility

Adheres to the Menu Button WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.

Keyboard Interactions

  • Space - Opens the dropdown menu and activates items
  • Enter - Opens the dropdown menu and activates items
  • ArrowDown - When focus is on trigger, opens the dropdown menu. When open, moves focus to the next item
  • ArrowUp - Moves focus to the previous item
  • ArrowRight - Opens a submenu or moves focus to the next item in a submenu
  • ArrowLeft - Closes a submenu or moves to the parent menu
  • Esc - Closes the dropdown menu and moves focus to trigger

Build docs developers (and LLMs) love