Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Components

Free

Dropdown Menu for React

Open a list of commands from a button, for an account menu or the actions on a table row. For React with Base UI, when those commands should stay hidden until asked.

Framework
UI library

A button opens a list of commands. One row can open a nested list when the first list would get too long.

Use it when the entries are actions, not a value the form stores. A menu that opens on right-click is a Context Menu and stays on the pointer. In React, Base UI takes focus, typeahead, and Escape.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Anatomy

Dropdown Menu anatomy: trigger, label, item, shortcut, separator, sub trigger, content
DropdownMenu
└── DropdownMenuTrigger
└── DropdownMenuContent
    └── DropdownMenuGroup
        └── DropdownMenuLabel
        └── DropdownMenuItem
        └── DropdownMenuSeparator
        └── DropdownMenuShortcut
        └── DropdownMenuSub
            └── DropdownMenuSubTrigger
            └── DropdownMenuSubContent

Usage

import { Button } from "@/components/ui/button";
import {
  DropdownMenu, DropdownMenuContent, DropdownMenuGroup,
  DropdownMenuGroupLabel, DropdownMenuItem, DropdownMenuPortal,
  DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub,
  DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
const DropdownMenuDemo = () => (
  <DropdownMenu>
    <DropdownMenuTrigger
      render={<Button className="mt-8 self-start" variant="outline" />}
    >
      Open
    </DropdownMenuTrigger>
    <DropdownMenuContent align="start" className="w-40 max-w-full">
      <DropdownMenuGroup>
        <DropdownMenuGroupLabel>My Account</DropdownMenuGroupLabel>
        <DropdownMenuItem>
          Profile
          <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuItem>
          Billing
          <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuItem>
          Settings
          <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
        </DropdownMenuItem>
      </DropdownMenuGroup>
      <DropdownMenuSeparator />
      <DropdownMenuGroup>
        <DropdownMenuItem>Team</DropdownMenuItem>
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
          <DropdownMenuPortal>
            <DropdownMenuSubContent>
              <DropdownMenuItem>Email</DropdownMenuItem>
              <DropdownMenuItem>Message</DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem>More...</DropdownMenuItem>
            </DropdownMenuSubContent>
          </DropdownMenuPortal>
        </DropdownMenuSub>
        <DropdownMenuItem>
          New Team
          <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
        </DropdownMenuItem>
      </DropdownMenuGroup>
      <DropdownMenuSeparator />
      <DropdownMenuGroup>
        <DropdownMenuItem>GitHub</DropdownMenuItem>
        <DropdownMenuItem>Support</DropdownMenuItem>
        <DropdownMenuItem disabled>API</DropdownMenuItem>
      </DropdownMenuGroup>
      <DropdownMenuSeparator />
      <DropdownMenuGroup>
        <DropdownMenuItem>
          Log out
          <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
        </DropdownMenuItem>
      </DropdownMenuGroup>
    </DropdownMenuContent>
  </DropdownMenu>
);

Accessibility

Space
Activates/Selects the highlighted item.
Enter
Activates/Selects the highlighted item.
Arrow Down
Highlights the next item in the menu.
Arrow Up
Highlights the previous item in the menu.
Arrow Right
When focus is on trigger, opens or closes the submenu depending on reading direction.
Arrow Left
When focus is on trigger, opens or closes the submenu depending on reading direction.
Escape
Closes the menu and moves focus to the trigger.
Home
Go to the start.
End
Go to the end.

Demos

Basic

Profile, billing, and settings sit under a My Account label, then a separator, then GitHub, Support, and a disabled API row. Copy this when the menu is a short list of places plus one item that exists but cannot be used yet. The label is not a choice, so it stays out of the arrow-key sequence. Every other row should be a real destination or a real action.

Preview width

Invite users opens a second list, and that list opens a third for Calendly, Slack, and a webhook. Use a submenu when several actions share a parent and would make the first menu a scroll. Two levels is usually the limit. A third panel hides the item people just chose, and they have to find their way back with the arrow keys.

Preview width

Shortcuts

Profile, billing, settings, and log out each end with a key hint, such as shift-command-P. DropdownMenuShortcut only prints that hint. It does not listen for the keys, so the binding has to live somewhere that still works while the menu is closed. Keep the hint short, and do not invent a shortcut you have not actually wired up.

Preview width

Icons

A person, a card, and a gear sit in front of Profile, Billing, and Settings, and log out is marked destructive. The icon is a scanning aid, so hide it from assistive tech when the label already names the action. Skip the pictures if they do not add a second cue. Four familiar rows is about as many as this treatment can carry before it turns into decoration.

Preview width

Checkboxes

Status bar starts checked, activity bar is disabled, and panel starts off, under an Appearance label. These are independent toggles, the sort of view preference you flip and then flip another without leaving the menu. Keep the checked values in state so the ticks survive the next open. If only one of the rows may be on, this is the wrong control and the radio group is the right one.

Preview width

Checkboxes Icons

Email, SMS, and push, each with an icon, and more than one can be on at the same time. The pictures are doing real work here, because the three channels would otherwise be easy to mix up in a narrow menu. Email and push start on, SMS starts off. Same rule as the plain checkboxes: store the booleans yourself, and do not use this pattern for a single choice.

Preview width

Radio Group

Panel position is top, bottom, or right, and only one of those can be selected. The tick remains the next time the menu opens, which is what you want for a setting and what a normal item will not remember. Hold the chosen string in state and pass it back in. Bottom starts selected so the menu is never a row of empty radios.

Preview width

Radio Icons

Credit card, PayPal, and bank transfer, with one of them current. The icons are decorative and the words are the name, so do not rely on the picture alone. Start from a default, card here, because an empty radio group looks unfinished. A payment method is a setting the menu should remember, not an action that runs the moment it is clicked.

Preview width

Destructive

Edit and share are ordinary rows. Delete sits after a separator with variant set to destructive, so the color warns before the click. That variant does not confirm anything. If the action cannot be undone, open an alert dialog and run the delete only from its confirm button, with the dangerous row last.

Preview width

Avatar

The trigger is a round avatar, not a button that says Open. Account, billing, and notifications sit above a separator, then sign out. Use this when the menu belongs to a person and the photo is already how people find their account. The image alt is the name a screen reader gets from inside the button, so a meaningful alt matters more here than on a decorative avatar.

Preview width

Complex

File, view, and account share one menu: shortcuts, nested recent projects, sidebar checkboxes, a theme choice, and a destructive sign out. Treat it as a stress test for groups and nested triggers, not a menu to ship. A list this long hides the item people came for. Split it, or move a stable set of menus into a Menubar when it is the app's main command surface.

Preview width

Actions

An ellipsis on the Project Alpha row. Edit and Duplicate write the last action under the card, and Delete does not. It opens an alert dialog, and only the confirm button performs the delete. The line under the row is a live region, so the result is announced after the menu has closed and focus has moved on.

Preview width

Rtl

Arabic labels run from the account submenu through view checkboxes, a position radio group, and logout. dir is rtl on the menu and on each nested panel, with the menu anchored to the end of the trigger. A page wrapper is not enough, because a submenu can still open the wrong way. Shortcuts stay at the end of the row, which here is the left side.

Preview width

FAQ

How do I control whether a Dropdown Menu is open in React?

Keep the open flag in state and pass it back when it changes. Leave it uncontrolled when the menu should open and close on its own. Choosing an item closes it unless you opt out in the select handler. Pass open. onOpenChange receives the next boolean.

How do I run code when a Dropdown Menu item is chosen?

The menu closes after a choice. Read which item it was in that handler, as the Actions demo does. A destructive action uses variant set to destructive and is still an ordinary menu item. Set onClick on the item. closeOnClick defaults to true. Set it to false to keep the menu open.

How do I add a checkbox or radio choice to a Dropdown Menu?

Use a checkbox item when several options can be on together, and a radio group when only one can. Keep the checked value in state. The Checkboxes and Radio Group demos show both. DropdownMenuCheckboxItem takes checked and onCheckedChange with a boolean. DropdownMenuRadioGroup takes value and onValueChange with the next string.

How do I place a Dropdown Menu with Base UI?

The menu moves to stay on screen, and it flips when there is not enough room. Set the preferred side, and set the width with a class on the popup. Nest a submenu with DropdownMenuSub, DropdownMenuSubTrigger, and DropdownMenuSubContent. Set side and align on DropdownMenuContent. align defaults to start and sideOffset defaults to 4.

Can I use a Dropdown Menu from the keyboard?

Yes. The Accessibility section lists the keys. Arrow Up and Arrow Down move the highlight, Enter and Space activate it, and Escape closes the menu and returns focus to the trigger. Arrow Left and Arrow Right open or close a submenu, following the reading direction. Disabled items are skipped. Typeahead jumps to a matching label.

Why is my Dropdown Menu clipped or behind a dialog?

The popup is portaled and uses z-50, so a parent with hidden overflow does not clip it. A dialog that also portals can still paint over the menu. Open the menu from inside that dialog rather than from the page behind it. Give an icon-only trigger an aria-label, as the Actions demo does.

Should I use a Dropdown Menu or a Context Menu?

Use a Dropdown Menu when a button or an avatar opens a list of actions. Use a Context Menu when the list opens from a right-click or a long press on a region. Use a Select when the choice is a form value that should stay visible in the closed control. A menu item is an action, not a submitted field.

How do I install Dropdown Menu in React?

Run the command in the Installation section above. It adds the menu, trigger, content, items, groups, and submenu parts to your ui folder. Buttons and icons are separate. The demos on this page use the same parts. The command uses the shadcn CLI.

API Reference

data-slot="dropdown-menu"

PropType
open?boolean

Whether the menu is currently open.

defaultOpen?boolean

Whether the menu is initially open. To render a controlled menu, use the open prop instead.

Default
false
onOpenChange?(open: boolean, eventDetails: MenuRoot.ChangeEventDetails) → void

Event handler called when the menu is opened or closed.

Type
(open: boolean, eventDetails: MenuRoot.ChangeEventDetails) → void
Parameters

open – boolean

eventDetails – MenuRoot.ChangeEventDetails

Returns
void
actionsRef?React.RefObject<MenuRoot.Actions | null>

A ref to imperative actions. - unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes. Call preventUnmountOnClose() in onOpenChange first, otherwise the menu completes closing on its own. Whether it leaves the DOM is decided by keepMounted on the portal. - close: Closes the menu imperatively when called.

Type
React.RefObject<MenuRoot.Actions | null>
children?React.ReactNode | PayloadChildRenderFunction<Payload>

The content of the menu. This can be a regular React node or a render function that receives the payload of the active trigger.

Type
React.ReactNode | PayloadChildRenderFunction<Payload>
closeParentOnEsc?boolean

When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu.

Default
false
defaultTriggerId?string | null

ID of the trigger that the menu is associated with. This is useful in conjunction with the defaultOpen prop to create an initially open menu.

Type
string | null
disabled?boolean

Whether the component should ignore user interaction.

Default
false
handle?MenuHandle<Payload>

A handle to associate the menu with a trigger. If specified, allows external triggers to control the menu's open state.

Type
MenuHandle<Payload>
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.

Default
true
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.

Default
true
modal?boolean

Determines if the menu enters a modal state when open. - true: user interaction is limited to the menu: document page scroll is locked and pointer interactions on outside elements are disabled. - false: user interaction with the rest of the document is allowed. On touch devices, a true modal blocks outside taps but leaves the page scrollable unless the popup spans nearly the full viewport width, matching native iOS behavior. Nested menus ignore this prop, and menus opened by hover are never modal.

Default
true
onItemHighlighted?(highlightedItem: HTMLElement, eventDetails: MenuRoot.HighlightEventDetails) → void

Callback fired when an item is highlighted or unhighlighted. Receives the highlighted item element (or undefined if no item is highlighted) and details containing the reason for the change, the event, and the item's text label. The reason can be: - keyboard: the highlight changed due to keyboard navigation. - pointer: the highlight changed due to pointer hovering. The event may be a MouseEvent rather than a PointerEvent. - none: the highlight changed for another reason, such as automatic highlighting while filtering, the item list changing, or the popup opening or closing.

Type
(highlightedItem: HTMLElement, eventDetails: MenuRoot.HighlightEventDetails) → void
Parameters

highlightedItem – HTMLElement

eventDetails – MenuRoot.HighlightEventDetails

Returns
void
onOpenChangeComplete?(open: boolean) → void

Event handler called after any animations complete when the menu is opened or closed.

Parameters

open – boolean

Returns
void
orientation?MenuRoot.Orientation

The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.

Default
"vertical"
triggerId?string | null

ID of the trigger that the menu is associated with. This is useful in conjunction with the open prop to create a controlled menu. There's no need to specify this prop when the menu is uncontrolled (that is, when the open prop is not set).

Type
string | null
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-item"

PropType
closeOnClick?boolean

Whether to close the menu when the item is clicked.

Default
true
disabled?boolean

Whether the component should ignore user interaction.

Default
false
id?string

The element's id.

inset?boolean

Indents it to line up with items that have an icon or indicator.

label?string

Overrides the text used for keyboard text navigation and filtering. Falls back to the rendered text when not provided.

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.

Default
false
onClick?React.MouseEventHandler

The click handler for the menu item.

variant?"default" | "destructive"

The visual style.

Type
"default" | "destructive"
Default
"default"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-disabled?string

Present when disabled is true.

data-highlighted?string

Present when highlighted is true.

data-inset?string

Mirrors inset.

data-ownedbystring

Id of the content part.

data-valuestring

The item's value.

data-valuetextstring

Mirrors valueText.

data-variant?string

Mirrors variant.

<div>

PropType
align?Align

How to align the popup relative to the specified side. Submenus and menubars default to start.

Default
"center"
alignOffset?number | OffsetFunction

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: - data.anchor: the dimensions of the anchor element with properties width and height. - data.positioner: the dimensions of the positioner element with properties width and height. - data.side: which side of the anchor element the positioner is aligned against. - data.align: how the positioner is aligned relative to the specified side. ``jsx <Positioner alignOffset={({ side, align, anchor, positioner }) => { return side === top || side === bottom ? anchor.width : anchor.height; }} /> ``

Type
number | OffsetFunction
Default
0
anchor?Element | null | VirtualElement | React.RefObject<Element | null> | (() → Element | VirtualElement | null)

An element to position the popup against. By default, the popup will be positioned against the trigger.

Type
Element | null | VirtualElement | React.RefObject<Element | null> | (() → Element | VirtualElement | null)
arrowPadding?number

Minimum distance to maintain between the arrow and the edges of the popup. Use it to prevent the arrow element from hanging out of the rounded corners of a popup.

Default
5
collisionAvoidance?SideFlipMode | SideShiftMode

Determines how to handle collisions when positioning the popup. side controls overflow on the preferred placement axis (top/bottom or left/right): - flip: keep the requested side when it fits; otherwise try the opposite side (top and bottom, or left and right). - shift: never change side; keep the requested side and move the popup within the clipping boundary so it stays visible. - none: do not correct side-axis overflow. align controls overflow on the alignment axis (start/center/end): - flip: keep side, but swap start and end when the requested alignment overflows. - shift: keep side and requested alignment, then nudge the popup along the alignment axis to fit. - none: do not correct alignment-axis overflow. fallbackAxisSide controls fallback behavior on the perpendicular axis when the preferred axis cannot fit: - start: allow perpendicular fallback and try the logical start side first (top before bottom, or left before right in LTR). - end: allow perpendicular fallback and try the logical end side first (bottom before top, or right before left in LTR). - none: do not fallback to the perpendicular axis. When side is shift, explicitly setting align only supports shift or none. If align is omitted, it defaults to flip. ``jsx <Positioner collisionAvoidance={{ side: shift, align: shift, fallbackAxisSide: none, }} /> ``

Type
SideFlipMode | SideShiftMode
collisionBoundary?"clipping-ancestors" | Element | Element[] | Rect

An element or a rectangle that delimits the area that the popup is confined to.

Type
"clipping-ancestors" | Element | Element[] | Rect
Default
"clipping-ancestors"
collisionPadding?Padding

Additional space to maintain from the edge of the collision boundary.

Default
5
disableAnchorTracking?boolean

Whether to disable the popup from tracking any layout shift of its positioning anchor.

Default
false
positionMethod?"absolute" | "fixed"

Determines which CSS position property to use.

Type
"absolute" | "fixed"
Default
"absolute"
side?Side

Which side of the anchor element to align the popup against. May automatically change to avoid collisions. Submenus and vertical menubars default to inline-end.

Default
"bottom"
sideOffset?number | OffsetFunction

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: - data.anchor: the dimensions of the anchor element with properties width and height. - data.positioner: the dimensions of the positioner element with properties width and height. - data.side: which side of the anchor element the positioner is aligned against. - data.align: how the positioner is aligned relative to the specified side. ``jsx <Positioner sideOffset={({ side, align, anchor, positioner }) => { return side === top || side === bottom ? anchor.height : anchor.width; }} /> ``

Type
number | OffsetFunction
Default
0
sticky?boolean

Whether to maintain the popup in the viewport after the anchor element was scrolled out of view.

Default
false
CSS variableType
--anchor-widthstring

The anchor's width.

--available-heightstring

The height left between the anchor and the viewport's edge.

--transform-originstring

Where the content scales from, on its trigger's side.

<hr> data-slot="dropdown-menu-separator"

PropType
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

<button> data-slot="dropdown-menu-trigger"

PropType
closeDelay?number

How long to wait before closing the menu that was opened on hover. Specified in milliseconds. Requires the openOnHover prop.

Default
0
delay?number

How long to wait before the menu may be opened on hover. Specified in milliseconds. Requires the openOnHover prop.

Default
100
disabled?boolean

Whether the component should ignore user interaction.

Default
false
handle?MenuHandle<Payload>

A handle to associate the trigger with a menu.

Type
MenuHandle<Payload>
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>).

Default
true
openOnHover?boolean

Whether the menu should also open when the trigger is hovered.

payload?Payload

A payload to pass to the menu when it is opened.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-portal"

PropType
container?HTMLElement | ShadowRoot | React.RefObject<HTMLElement | ShadowRoot | null> | null

A parent element to render the portal element into.

Type
HTMLElement | ShadowRoot | React.RefObject<HTMLElement | ShadowRoot | null> | null
keepMounted?boolean

Whether to keep the portal mounted in the DOM while the popup is hidden.

Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-content"

PropType
finalFocus?boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) → boolean | HTMLElement | null | void)

Determines the element to focus when the menu is closed. - false: Do not move focus. - true: Move focus based on the default behavior (trigger or previously focused element). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.

Type
boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) → boolean | HTMLElement | null | void)
id?string

The element's id.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

CSS variableType
--anchor-widthstring

The anchor's width.

--available-heightstring

The height left between the anchor and the viewport's edge.

--transform-originstring

Where the content scales from, on its trigger's side.

<div> data-slot="dropdown-menu-group"

PropType
children?React.ReactNode

The content of the component.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-group-label"

PropType
inset?boolean

Indents it to line up with items that have an icon or indicator.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-inset?string

Mirrors inset.

data-slot="dropdown-menu-sub"

PropType
open?boolean

Whether the menu is currently open.

defaultOpen?boolean

Whether the menu is initially open. To render a controlled menu, use the open prop instead.

Default
false
onOpenChange?(open: boolean, eventDetails: MenuSubmenuRoot.ChangeEventDetails) → void

Event handler called when the menu is opened or closed.

Type
(open: boolean, eventDetails: MenuSubmenuRoot.ChangeEventDetails) → void
Parameters

open – boolean

eventDetails – MenuSubmenuRoot.ChangeEventDetails

Returns
void
actionsRef?React.RefObject<MenuRoot.Actions | null>

A ref to imperative actions. - unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes. Call preventUnmountOnClose() in onOpenChange first, otherwise the menu completes closing on its own. Whether it leaves the DOM is decided by keepMounted on the portal. - close: Closes the menu imperatively when called.

Type
React.RefObject<MenuRoot.Actions | null>
children?React.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.

Default
false
disabled?boolean

Whether the component should ignore user interaction.

Default
false
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.

Default
true
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.

Default
true
onItemHighlighted?(highlightedItem: HTMLElement, eventDetails: MenuRoot.HighlightEventDetails) → void

Callback fired when an item is highlighted or unhighlighted. Receives the highlighted item element (or undefined if no item is highlighted) and details containing the reason for the change, the event, and the item's text label. The reason can be: - keyboard: the highlight changed due to keyboard navigation. - pointer: the highlight changed due to pointer hovering. The event may be a MouseEvent rather than a PointerEvent. - none: the highlight changed for another reason, such as automatic highlighting while filtering, the item list changing, or the popup opening or closing.

Type
(highlightedItem: HTMLElement, eventDetails: MenuRoot.HighlightEventDetails) → void
Parameters

highlightedItem – HTMLElement

eventDetails – MenuRoot.HighlightEventDetails

Returns
void
onOpenChangeComplete?(open: boolean) → void

Event handler called after any animations complete when the menu is opened or closed.

Parameters

open – boolean

Returns
void
orientation?MenuRoot.Orientation

The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.

Default
"vertical"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-sub-trigger"

PropType
closeDelay?number

How long to wait before closing the menu that was opened on hover. Specified in milliseconds. Requires the openOnHover prop.

Default
0
delay?number

How long to wait before the menu may be opened on hover. Specified in milliseconds. Requires the openOnHover prop.

Default
100
disabled?boolean

Whether the component should ignore user interaction.

Default
false
id?string

The element's id.

inset?boolean

Indents it to line up with items that have an icon or indicator.

label?string

Overrides the text used for keyboard text navigation and filtering. Falls back to the rendered text when not provided.

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.

Default
false
onClick?React.MouseEventHandler

Called when it's clicked.

openOnHover?boolean

Whether the menu should also open when the trigger is hovered.

Default
true
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-inset?string

Mirrors inset.

data-slot="dropdown-menu-sub-content"

PropType
finalFocus?boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) → boolean | HTMLElement | null | void)

Determines the element to focus when the menu is closed. - false: Do not move focus. - true: Move focus based on the default behavior (trigger or previously focused element). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.

Type
boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) → boolean | HTMLElement | null | void)
id?string

The element's id.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

<div> data-slot="dropdown-menu-checkbox-item"

PropType
checked?boolean

Whether the checkbox item is currently ticked. To render an uncontrolled checkbox item, use the defaultChecked prop instead.

defaultChecked?boolean

Whether the checkbox item is initially ticked. To render a controlled checkbox item, use the checked prop instead.

Default
false
onCheckedChange?(checked: boolean, eventDetails: MenuCheckboxItem.ChangeEventDetails) → void

Event handler called when the checkbox item is ticked or unticked.

Type
(checked: boolean, eventDetails: MenuCheckboxItem.ChangeEventDetails) → void
Parameters

checked – boolean

eventDetails – MenuCheckboxItem.ChangeEventDetails

Returns
void
closeOnClick?boolean

Whether to close the menu when the item is clicked.

Default
false
disabled?boolean

Whether the component should ignore user interaction.

Default
false
id?string

The element's id.

inset?boolean

Indents it to line up with items that have an icon or indicator.

label?string

Overrides the text used for keyboard text navigation and filtering. Falls back to the rendered text when not provided.

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.

Default
false
onClick?React.MouseEventHandler

The click handler for the menu item.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-inset?string

Mirrors inset.

<div> data-slot="dropdown-menu-radio-group"

PropType
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.

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.

onValueChange?(value: any, eventDetails: MenuRadioGroup.ChangeEventDetails) → void

Function called when the selected value changes.

Type
(value: any, eventDetails: MenuRadioGroup.ChangeEventDetails) → void
Parameters

value – any

eventDetails – MenuRadioGroup.ChangeEventDetails

Returns
void
children?React.ReactNode

The content of the component.

disabled?boolean

Whether the component should ignore user interaction.

Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

<div> data-slot="dropdown-menu-radio-item"

PropType
valueany

Value of the radio item. This is the value that will be set in the MenuRadioGroup when the item is selected.

closeOnClick?boolean

Whether to close the menu when the item is clicked.

Default
false
disabled?boolean

Whether the component should ignore user interaction.

Default
false
id?string

The element's id.

inset?boolean

Indents it to line up with items that have an icon or indicator.

label?string

Overrides the text used for keyboard text navigation and filtering. Falls back to the rendered text when not provided.

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.

Default
false
onClick?React.MouseEventHandler

The click handler for the menu item.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-inset?string

Mirrors inset.

<span> data-slot="dropdown-menu-shortcut"

PropType
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

PropType
inset?boolean

Indents it to line up with items that have an icon or indicator.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

With other components

  • Free

    Button

    Buttons

    Trigger for the menu

  • Free

    Avatar

    Media

    Account switcher trigger

  • Free

    Kbd

    Typography

    Shortcut next to the label

  • Free

    Dialog

    Overlays

    Confirm a destructive pick

  • Free

    Separator

    Layout

    Split groups in the list

  • Free

    Alert Dialog

    Overlays

    Gate a delete item