Skip to contents

Menu

A list of actions in a dropdown, enhanced with keyboard navigation.

Anatomy

Import the component and assemble its parts:

Anatomy

Examples

Open on hover

To create a menu that opens on hover, add the openOnHover prop to <Menu.Trigger>. You can additionally configure how quickly the menu opens on hover using the delay prop.

Checkbox items

Use the <Menu.CheckboxItem> part to create a menu item that can toggle a setting on or off.

Radio items

Use the <Menu.RadioGroup> and <Menu.RadioItem> parts to create menu items that work like radio buttons.

Close on click

Use the closeOnClick prop to change whether the menu closes when an item is clicked.

Control whether the menu closes on click

Group labels

Use the <Menu.GroupLabel> part to add a label to a <Menu.Group> or <Menu.RadioGroup>.

Nested menu

To create a submenu, nest another menu inside the parent menu with <Menu.SubmenuRoot>. Use the <Menu.SubmenuTrigger> part for the menu item that opens the nested menu.

Adding a submenu

Use the <Menu.LinkItem> part to create a link.

A menu item that opens a link

Open a dialog

In order to open a dialog using a menu, control the dialog state and open it imperatively using the onclick handler on the menu item.

Connecting a dialog to a menu

Detached triggers

A menu can be opened by a trigger that lives either inside or outside the <Menu.Root>. Keep the trigger inside <Menu.Root> for simple, tightly coupled layouts like the hero demo at the top of this page. When the trigger and menu content need to live in different parts of the tree (for example, in a card list that controls a menu rendered near the document root), create a handle with Menu.createHandle() and pass it to both the trigger and the root.

Note that only top-level menus can have detached triggers. Submenus must have their triggers defined within the SubmenuRoot part.

The imperative methods on the handle, such as open() and close(), require a <Menu.Root> using the same handle to be mounted. Calls made while no root is attached to the handle (before one mounts, or after it unmounts) are ignored. Each time a root mounts, it starts from fresh state: a call made while no root was attached is not replayed, and no open state carries over from a previous mount.

Detached triggers

Multiple triggers

One menu can be opened by several triggers. You can either render multiple <Menu.Trigger> components inside the same <Menu.Root>, or attach several detached triggers to the same handle.

Multiple triggers within the Root part
Multiple detached triggers

Menus can render different content depending on which trigger opened them. Pass a payload prop to each <Menu.Trigger> and read it via the children snippet on <Menu.Root>. Provide a type argument to createHandle() to strongly type the payload.

Detached triggers with payload

Controlled mode with multiple triggers

Control a menu's open state externally with bind:open on <Menu.Root>. When more than one trigger can open the menu, track the active trigger with bind:triggerId on <Menu.Root> and matching id props on each <Menu.Trigger>. The onOpenChange callback receives eventDetails, which includes the DOM element that initiated the change as trigger, so you can react when the user activates a different trigger.

Arrow

Use the <Menu.Arrow> part inside the popup to visually connect the menu to its trigger.

Animating the Menu

When one menu is opened by multiple detached triggers, you can animate the menu as it moves between triggers. This includes animating position, size, and content.

Position and Size

To animate the menu's position, apply CSS transitions to the left, right, top, and bottom properties of the Positioner part. To animate its size, transition the width and height of the Popup part.

Content

The menu also supports content transitions. This is useful when different triggers display different content within the same menu.

To enable content animations, wrap the menu content in the <Menu.Viewport> part. This part renders a div with data-activation-direction, containing up to two space-separated tokens (a horizontal left or right value and a vertical up or down value), so you can make direction-aware animations.

Inside <Menu.Viewport>, content is wrapped in divs with transition data attributes:

  • data-current: The currently visible content when no transitions are present or the incoming content.
  • data-previous: The outgoing content during a transition.

Filtering

Wrap <Menu.Root> in <Menu.FilterProvider>, add <Menu.Input> to the popup, and put the items inside <Menu.List>.

Filterable menu

Label the input with aria-label, aria-labelledby, or a visible <label>. Type to narrow the actions, then use the arrow keys to move through matching items.

Matching items

Items match their text by default. Use label to override it.

Labels

Groups with no matching items get the hidden attribute and stay mounted. If your styles set display on a group, add a [hidden] rule so it still hides.

Hiding styled groups

<Menu.Empty> appears when no items match.

By default, an item matches when its text contains the query, ignoring case, accents, and punctuation. Use filter to replace the matching. It receives each item's text and the trimmed query, and keeps the item when it returns true. Menu.useFilter provides the same locale-aware comparisons.

Custom matching

For external filtering, pass filter={null} and render the results yourself, omitting empty groups.

External filtering

Controlling the query

bind:value on <Menu.FilterProvider> controls the query, and onValueChange reports each change. It resets to an empty string when the menu closes, reported with the 'popup-close' reason. Cancel that change to keep the query.

Highlighting

Use autoHighlight to highlight the first match while filtering, or autoHighlight="always" to highlight it even when the query is empty. The highlighted item has the data-highlighted attribute, and onItemHighlighted on <Menu.Root> reports each change.

Focus and keyboard

Opening the menu with a click or the keyboard focuses the input. Opening it on hover, touch, or with a pen does not, so the on-screen keyboard stays hidden. The arrow keys move the highlight while the input keeps focus. Tab closes the menu, and Shift+Tab returns focus to the trigger. The popup is a dialog that holds the searchbox input and the menu list.

Wrap each searchable <Menu.SubmenuRoot> in its own <Menu.FilterProvider>. Submenus without a provider remain unfiltered.

Filtering with detached triggers

Use the same Menu.createHandle() handle for the root and its detached trigger:

Detached trigger

API reference

FilterProvider

Enables filtering for the menu or submenu it wraps. Add Menu.Input to the popup and place its items in Menu.List. Wrap each searchable submenu in its own provider. Does not render its own HTML element.

value string ''
Name
Description

The filter query. Use bind:value to share it with the parent. A value passed without bind: is the initial query. Closing the popup clears the query.

Type
string
Default
''
Binding
bind:value
onValueChange function โ€”
Description

Called before the query changes. Call eventDetails.cancel() to veto it.

Type
(value: string, details: MenuFilterChangeEventDetails) => void
filter MenuFilterFunction | null โ€”
Name
Description

Matches items against the query. Receives each item's label (or its rendered text) and the trimmed query, and keeps the item when it returns true. By default, items match when they contain the query, ignoring case, accents and punctuation. Pass null when rendering filtered items yourself.

Type
MenuFilterFunction | null
autoHighlight boolean | 'always' false
Description

Whether filtering highlights the first matching item. true highlights it while the query is not empty, and 'always' also when it is empty. With either value the arrow keys wrap within the list instead of returning to the input.

Type
boolean | 'always'
Default
false
locale Intl.LocalesArgument โ€”
Name
Description

The locale the default filter compares with. Defaults to the runtime locale.

Type
Intl.LocalesArgument

Root

Groups all parts of the menu. Does not render its own HTML element.

open boolean false
Name
Description

Whether the menu is open. Use bind:open to share it with the parent. A value passed without bind: holds until the parent changes it.

Type
boolean
Default
false
Binding
bind:open
onOpenChange function โ€”
Description

Called before the open state changes. Call eventDetails.cancel() to veto it.

Type
(open: boolean, details: MenuChangeEventDetails) => void
onOpenChangeComplete function โ€”
Description

Called after the open or close animation finishes.

Type
(open: boolean) => void
onItemHighlighted function โ€”
Description

Called when an item is highlighted or unhighlighted. Receives the highlighted item element, or undefined when no item is highlighted, and details with the reason, the event, and the item's text label. The reason is 'keyboard', 'pointer', or 'none' for anything else, such as the list changing or the popup opening or closing.

Type
(highlightedItem: HTMLElement | undefined, details: MenuHighlightEventDetails) => void
loopFocus boolean true
Description

Whether to loop keyboard focus back to the first item at the end of the list.

Type
boolean
Default
true
highlightItemOnHover boolean true
Description

Whether moving the pointer over items highlights them. Turn it off to tell CSS :hover apart from [data-highlighted].

Type
boolean
Default
true
modal boolean true
Name
Description

Whether the menu limits interaction to itself while open: page scroll is locked and outside pointer interaction is blocked. Nested menus ignore it, and menus opened by hover are never modal.

Type
boolean
Default
true
orientation MenuOrientation 'vertical'
Description

The visual orientation of the menu. Controls whether the up/down or left/right arrow keys move the highlight.

Type
MenuOrientation
Default
'vertical'
disabled boolean false
Description

Whether the menu ignores user interaction.

Type
boolean
Default
false
closeParentOnEsc boolean false
Description

In a submenu, whether Escape closes the whole menu or only the submenu.

Type
boolean
Default
false
triggerId string | null โ€”
Description

Id of the trigger that owns the menu. A string wins over the trigger that opened it.

Type
string | null
Binding
bind:triggerId
handle MenuHandle<Payload> โ€”
Name
Description

Associates detached triggers and imperative open and close.

Type
MenuHandle<Payload>
children Snippet<[{ payload: Payload | undefined }]> โ€”
Type
Snippet<[{ payload: Payload | undefined }]>

Trigger

A button that opens the menu. Renders a <button> element.

disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean true
Description

Whether the host is a native <button>. Set false when render supplies a non-button element.

Type
boolean
Default
true
handle MenuHandle<Payload> โ€”
Name
Type
MenuHandle<Payload>
payload Payload โ€”
Name
Description

A payload passed to the menu while this trigger owns it.

Type
Payload
id string | null โ€”
Name
Type
string | null
openOnHover boolean โ€”
Description

Whether the menu also opens when the trigger is hovered.

Type
boolean
delay number 100
Name
Description

Hover open delay in milliseconds. Requires openOnHover.

Type
number
Default
100
closeDelay number 0
Description

Hover close delay in milliseconds. Requires openOnHover.

Type
number
Default
0
render Snippet<[props: HTMLButtonAttributes, state: MenuTriggerState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLButtonAttributes, state: MenuTriggerState, children: Snippet | undefined]>
open boolean
Name
open
Description

Whether the menu is open and was opened by this trigger.

Type
boolean
disabled boolean
Name
disabled
Type
boolean
data-popup-open
Present when the corresponding menu is open.
data-pressed
Present when the trigger is pressed.
data-disabled
Present when the trigger is disabled.

Portal

A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to <body>.

keepMounted boolean false
Description

Keep the portal mounted while the popup is closed.

Type
boolean
Default
false
container HTMLElement | ShadowRoot | null โ€”
Description

Element the portal is appended to. undefined uses the parent portal or document.body. null waits and does not mount until an element or shadow root is set. There is no ref object.

Type
HTMLElement | ShadowRoot | null
render Snippet<[props: HTMLAttributes<HTMLDivElement> & Record<symbol, Attachment<HTMLDivElement>>, state: MenuPortalState, children: Snippet | undefined]> โ€”
Name
Description

Replace the portal element. The snippet receives host props, an empty state, and the children. Host props include the move attachment.

Type
Snippet<[props: HTMLAttributes<HTMLDivElement> & Record<symbol, Attachment<HTMLDivElement>>, state: MenuPortalState, children: Snippet | undefined]>

Backdrop

An overlay displayed beneath the menu popup. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuBackdropState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuBackdropState, children: Snippet | undefined]>
open boolean
Name
open
Type
boolean
transitionStatus 'starting' | 'ending' | 'idle' | undefined
Name
transitionStatus
Type
'starting' | 'ending' | 'idle' | undefined
data-open
Present when the menu is open.
data-closed
Present when the menu is closed.
data-starting-style
Present when the menu begins animating in.
data-ending-style
Present when the menu is animating out.

Positioner

Positions the menu popup against the trigger. Renders a <div> element.

anchor Anchor โ€”
Name
Description

An element to position the popup against. Defaults to the trigger.

Type
Anchor
positionMethod "absolute" | "fixed" 'absolute'
Type
"absolute" | "fixed"
Default
'absolute'
side Side 'bottom'
Name
Description

Which side of the anchor to place the popup on. May change to avoid collisions. Submenus and vertical menubars default to 'inline-end'.

Type
Side
Default
'bottom'
align Align 'center'
Name
Description

How to align the popup against the side. Submenus and menubars default to 'start'.

Type
Align
Default
'center'
sideOffset number | OffsetFunction 0
Description

Distance between the anchor and the popup in pixels, or a function of the layout.

Type
number | OffsetFunction
Default
0
alignOffset number | OffsetFunction 0
Description

Offset along the alignment axis in pixels, or a function of the layout.

Type
number | OffsetFunction
Default
0
collisionBoundary Boundary 'clipping-ancestors'
Type
Boundary
Default
'clipping-ancestors'
collisionPadding Padding 5
Type
Padding
Default
5
arrowPadding number 5
Description

Minimum distance between the arrow and the popup edges.

Type
number
Default
5
sticky boolean false
Name
Description

Whether the popup stays in the viewport after the anchor scrolls out of view.

Type
boolean
Default
false
disableAnchorTracking boolean false
Description

Whether to stop tracking layout shifts of the anchor.

Type
boolean
Default
false
collisionAvoidance CollisionAvoidance โ€”
Description

How to handle collisions. Root menus default to { fallbackAxisSide: 'none' } and submenus to { fallbackAxisSide: 'end' }.

Type
CollisionAvoidance
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuPositionerState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuPositionerState, children: Snippet | undefined]>
open boolean
Name
open
Type
boolean
side Side
Name
side
Type
Side
align Align
Name
align
Type
Align
anchorHidden boolean
Name
anchorHidden
Type
boolean
nested boolean
Name
nested
Description

Whether the menu is a submenu.

Type
boolean
instant MenuInstant | undefined
Name
instant
Type
MenuInstant | undefined
data-open
Present when the menu popup is open.
data-closed
Present when the menu popup is closed.
data-anchor-hidden
Present when the anchor is hidden.
data-align
Indicates how the popup is aligned relative to the specified side.
data-side
Indicates which side the popup is positioned relative to the anchor.
--anchor-height
The anchor's height.
--anchor-width
The anchor's width.
--available-height
The available height between the anchor and the edge of the viewport.
--available-width
The available width between the anchor and the edge of the viewport.
--positioner-height
The height of the menu's positioner. It is important to set height to this value when using CSS to animate size changes.
--positioner-width
The width of the menu's positioner. It is important to set width to this value when using CSS to animate size changes.
--transform-origin
The coordinates that this element is anchored to. Used for animations and transitions.

A container for the menu items. Renders a <div> element.

finalFocus FocusTarget โ€”
Description

Element to focus when the menu closes. false leaves focus. true uses the default (the trigger). A function receives the close interaction and returns an element, true, or false.

Type
FocusTarget
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuPopupState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuPopupState, children: Snippet | undefined]>
open boolean
Name
open
Type
boolean
side Side
Name
side
Type
Side
align Align
Name
align
Type
Align
transitionStatus 'starting' | 'ending' | 'idle' | undefined
Name
transitionStatus
Type
'starting' | 'ending' | 'idle' | undefined
nested boolean
Name
nested
Description

Whether the menu is a submenu.

Type
boolean
instant MenuInstant | undefined
Name
instant
Type
MenuInstant | undefined
data-open
Present when the menu is open.
data-closed
Present when the menu is closed.
data-align
Indicates how the popup is aligned relative to specified side.
data-instant
Present if animations should be instant.
data-side
Indicates which side the popup is positioned relative to the anchor.
data-starting-style
Present when the menu begins animating in.
data-ending-style
Present when the menu is animating out.

Viewport

A viewport for displaying content transitions between triggers. Renders a <div> element. Needed only when several triggers open one menu with different content and the switch animates.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuViewportState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuViewportState, children: Snippet | undefined]>
activationDirection string | undefined
Name
activationDirection
Description

Direction from the previous trigger to the new one, such as 'right down'.

Type
string | undefined
transitioning boolean
Name
transitioning
Type
boolean
instant MenuInstant | undefined
Name
instant
Type
MenuInstant | undefined

The Viewport is optional. Reach for it only when a single popup is opened by multiple triggers, its content differs per trigger, and the switch between them is animated. When used, set width: var(--positioner-width) and height: var(--positioner-height) on the Positioner so its box is frozen to the measured size during the transition; otherwise content-driven resizing can make the popup thrash or flip to another side.

data-activation-direction
Indicates the direction from which the popup was activated. This can be used to create directional animations based on how the popup was triggered. Contains space-separated values for both horizontal and vertical axes.
data-current
Applied to the direct child of the viewport when no transitions are present or the new content when it's entering.
data-instant
Present if animations should be instant.
data-previous
Applied to the direct child of the viewport that contains the exiting content when transitions are present.
data-transitioning
Indicates that the viewport is currently transitioning between old and new content.
--popup-height
The height of the parent popup. This variable is placed on the 'previous' container and stores the height of the popup when the previous content was rendered. It can be used to freeze the dimensions of the popup when animating between different content.
--popup-width
The width of the parent popup. This variable is placed on the 'previous' container and stores the width of the popup when the previous content was rendered. It can be used to freeze the dimensions of the popup when animating between different content.

Arrow

Displays an element positioned against the menu anchor. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuArrowState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuArrowState, children: Snippet | undefined]>
open boolean
Name
open
Type
boolean
side Side
Name
side
Type
Side
align Align
Name
align
Type
Align
uncentered boolean
Name
uncentered
Type
boolean
data-open
Present when the menu popup is open.
data-closed
Present when the menu popup is closed.
data-uncentered
Present when the menu arrow is uncentered.
data-align
Indicates how the popup is aligned relative to specified side.
data-side
Indicates which side the popup is positioned relative to the anchor.

Input

A search field that filters the menu items. Requires the menu to be wrapped in Menu.FilterProvider. Renders an <input> element.

id string | null โ€”
Name
Type
string | null
disabled boolean | null false
Type
boolean | null
Default
false
render Snippet<[props: HTMLInputAttributes, state: MenuInputState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLInputAttributes, state: MenuInputState, children: Snippet | undefined]>
highlighted boolean
Name
highlighted
Description

Whether the input shows its focus ring. Cleared when keyboard navigation highlights an item.

Type
boolean
data-highlighted
Present while the input shows its focus ring. Cleared when keyboard navigation highlights an item.

Clear

A button that clears the input text. Requires the menu to be wrapped in Menu.FilterProvider. Renders a <button> element while the input has text.

disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean true
Description

Whether the host is a native <button>. Set false when render supplies a non-button element.

Type
boolean
Default
true
render Snippet<[props: HTMLButtonAttributes, state: MenuClearState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLButtonAttributes, state: MenuClearState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean
data-disabled
Present when the button is disabled.

Empty

A message shown when the menu has no matching items. Requires the menu to be wrapped in Menu.FilterProvider. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuEmptyState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuEmptyState, children: Snippet | undefined]>

List

Groups menu items so other content, such as a filter input, can share the popup. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuListState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuListState, children: Snippet | undefined]>

Item

An individual interactive item in the menu. Renders a <div> element.

disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean false
Description

Whether the host is a native <button>. Set true when render supplies a button.

Type
boolean
Default
false
closeOnClick boolean true
Description

Whether clicking the item closes the menu.

Type
boolean
Default
true
label string โ€”
Name
Description

Text used by keyboard typeahead. Defaults to the item's text content.

Type
string
id string | null โ€”
Name
Type
string | null
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuItemState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuItemState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
data-highlighted
Present when the menu item is highlighted.
data-disabled
Present when the menu item is disabled.

LinkItem

A link in the menu that navigates to another page or section. Renders an <a> element.

closeOnClick boolean false
Description

Whether clicking the link closes the menu.

Type
boolean
Default
false
label string โ€”
Name
Description

Text used by keyboard typeahead. Defaults to the item's text content.

Type
string
id string | null โ€”
Name
Type
string | null
render Snippet<[props: HTMLAnchorAttributes, state: MenuLinkItemState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAnchorAttributes, state: MenuLinkItemState, children: Snippet | undefined]>
highlighted boolean
Name
highlighted
Type
boolean
data-highlighted
Present when the link is highlighted.

Groups all parts of a submenu. Does not render its own HTML element.

disabled boolean false
Description

Whether the menu ignores user interaction.

Type
boolean
Default
false
onOpenChange function โ€”
Description

Called before the open state changes. Call eventDetails.cancel() to veto it.

Type
(open: boolean, details: MenuChangeEventDetails) => void
open boolean false
Name
Description

Whether the menu is open. Use bind:open to share it with the parent. A value passed without bind: holds until the parent changes it.

Type
boolean
Default
false
Binding
bind:open
onOpenChangeComplete function โ€”
Description

Called after the open or close animation finishes.

Type
(open: boolean) => void
onItemHighlighted function โ€”
Description

Called when an item is highlighted or unhighlighted. Receives the highlighted item element, or undefined when no item is highlighted, and details with the reason, the event, and the item's text label. The reason is 'keyboard', 'pointer', or 'none' for anything else, such as the list changing or the popup opening or closing.

Type
(highlightedItem: HTMLElement | undefined, details: MenuHighlightEventDetails) => void
highlightItemOnHover boolean true
Description

Whether moving the pointer over items highlights them. Turn it off to tell CSS :hover apart from [data-highlighted].

Type
boolean
Default
true
loopFocus boolean true
Description

Whether to loop keyboard focus back to the first item at the end of the list.

Type
boolean
Default
true
orientation MenuOrientation 'vertical'
Description

The visual orientation of the menu. Controls whether the up/down or left/right arrow keys move the highlight.

Type
MenuOrientation
Default
'vertical'
closeParentOnEsc boolean false
Description

In a submenu, whether Escape closes the whole menu or only the submenu.

Type
boolean
Default
false

A menu item that opens a submenu. Renders a <div> element.

disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean false
Type
boolean
Default
false
openOnHover boolean true
Description

Whether the submenu opens when the trigger is hovered.

Type
boolean
Default
true
delay number 100
Name
Description

Hover open delay in milliseconds.

Type
number
Default
100
closeDelay number 0
Description

Hover close delay in milliseconds.

Type
number
Default
0
label string โ€”
Name
Description

Text used by keyboard typeahead. Defaults to the item's text content.

Type
string
id string | null โ€”
Name
Type
string | null
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuSubmenuTriggerState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuSubmenuTriggerState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
open boolean
Name
open
Description

Whether the submenu is open.

Type
boolean
data-popup-open
Present when the corresponding submenu is open.
data-highlighted
Present when the submenu trigger is highlighted.
data-disabled
Present when the submenu trigger is disabled.

Group

Groups related menu items with the corresponding label. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuGroupState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuGroupState, children: Snippet | undefined]>

GroupLabel

An accessible label that is associated with its parent group. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuGroupLabelState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuGroupLabelState, children: Snippet | undefined]>

RadioGroup

Groups related radio items. Renders a <div> element.

value unknown โ€”
Name
Description

The value of the selected radio item. Use bind:value to share it with the parent.

Type
unknown
Binding
bind:value
onValueChange function โ€”
Description

Called before the value changes. Call eventDetails.cancel() to veto it.

Type
(value: unknown, details: MenuChangeEventDetails) => void
disabled boolean | null false
Type
boolean | null
Default
false
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuRadioGroupState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuRadioGroupState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean

RadioItem

A menu item that works like a radio button in a given group. Renders a <div> element.

value* unknown โ€”
Name
Description

The value the radio group takes when this item is selected.

Type
unknown
disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean false
Type
boolean
Default
false
closeOnClick boolean false
Description

Whether clicking the item closes the menu.

Type
boolean
Default
false
label string โ€”
Name
Description

Text used by keyboard typeahead. Defaults to the item's text content.

Type
string
id string | null โ€”
Name
Type
string | null
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuRadioItemState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuRadioItemState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
checked boolean
Name
checked
Type
boolean
data-checked
Present when the menu radio item is selected.
data-unchecked
Present when the menu radio item is not selected.
data-highlighted
Present when the menu radio item is highlighted.
data-disabled
Present when the menu radio item is disabled.

RadioItemIndicator

Indicates whether the radio item is ticked. Renders a <span> element.

keepMounted boolean false
Description

Whether to keep the element in the DOM while the item is not checked.

Type
boolean
Default
false
render Snippet<[props: HTMLAttributes<HTMLSpanElement>, state: MenuItemIndicatorState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLSpanElement>, state: MenuItemIndicatorState, children: Snippet | undefined]>
checked boolean
Name
checked
Type
boolean
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
transitionStatus 'starting' | 'ending' | 'idle' | undefined
Name
transitionStatus
Type
'starting' | 'ending' | 'idle' | undefined
data-checked
Present when the menu radio item is selected.
data-unchecked
Present when the menu radio item is not selected.
data-disabled
Present when the menu radio item is disabled.
data-starting-style
Present when the radio indicator begins animating in.
data-ending-style
Present when the radio indicator is animating out.

CheckboxItem

A menu item that toggles a setting on or off. Renders a <div> element.

checked boolean false
Name
Description

Whether the item is ticked. Use bind:checked to share it with the parent.

Type
boolean
Default
false
Binding
bind:checked
onCheckedChange function โ€”
Description

Called before the checked state changes. Call eventDetails.cancel() to veto it.

Type
(checked: boolean, details: MenuChangeEventDetails) => void
disabled boolean | null false
Type
boolean | null
Default
false
nativeButton boolean false
Type
boolean
Default
false
closeOnClick boolean false
Description

Whether clicking the item closes the menu.

Type
boolean
Default
false
label string โ€”
Name
Description

Text used by keyboard typeahead. Defaults to the item's text content.

Type
string
id string | null โ€”
Name
Type
string | null
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuCheckboxItemState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: MenuCheckboxItemState, children: Snippet | undefined]>
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
checked boolean
Name
checked
Type
boolean
data-checked
Present when the menu checkbox item is checked.
data-unchecked
Present when the menu checkbox item is not checked.
data-highlighted
Present when the menu checkbox item is highlighted.
data-disabled
Present when the menu checkbox item is disabled.

CheckboxItemIndicator

Indicates whether the checkbox item is ticked. Renders a <span> element.

keepMounted boolean false
Description

Whether to keep the element in the DOM while the item is not checked.

Type
boolean
Default
false
render Snippet<[props: HTMLAttributes<HTMLSpanElement>, state: MenuItemIndicatorState, children: Snippet | undefined]> โ€”
Name
Type
Snippet<[props: HTMLAttributes<HTMLSpanElement>, state: MenuItemIndicatorState, children: Snippet | undefined]>
checked boolean
Name
checked
Type
boolean
disabled boolean
Name
disabled
Type
boolean
highlighted boolean
Name
highlighted
Type
boolean
transitionStatus 'starting' | 'ending' | 'idle' | undefined
Name
transitionStatus
Type
'starting' | 'ending' | 'idle' | undefined
data-checked
Present when the menu checkbox item is checked.
data-unchecked
Present when the menu checkbox item is not checked.
data-disabled
Present when the menu checkbox item is disabled.
data-starting-style
Present when the indicator begins animating in.
data-ending-style
Present when the indicator is animating out.

Separator

A separator element accessible to screen readers. Renders a <div>.

orientation "horizontal" | "vertical" 'horizontal'
Description

The orientation of the separator.

Type
"horizontal" | "vertical"
Default
'horizontal'
render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: SeparatorState, children: Snippet | undefined]> โ€”
Name
Description

Replace the default <div>. Spread props onto the host element.

Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: SeparatorState, children: Snippet | undefined]>
orientation 'horizontal' | 'vertical'
Name
orientation
Description

The orientation of the separator.

Type
'horizontal' | 'vertical'
data-orientation
Indicates the orientation of the separator.

useFilter

When filtering items yourself, Menu.useFilter matches text according to the user's locale.

Parameters:

ParameterTypeDefaultDescription
options?GetFilterParameters{}-

Return Value:

GetFilterParameters takes a locale and any Intl.CollatorOptions. Filter has three functions, each of the form (item, query, itemToString?) => boolean.

createHandle

Creates a new handle to connect a Menu.Root with detached Menu.Trigger components.

Return Value:

Handle

Controls a Menu imperatively and associates detached Menu.Trigger components with a Menu.Root. Create one with Menu.createHandle() and pass it to the handle prop of the root and of any triggers rendered outside of it.

The imperative methods take effect only while a root using this handle is mounted. Calls made before a root attaches (or after it unmounts) are ignored.

Properties:

PropertyTypeModifiersDescription
isOpenbooleanreadonlyWhether the menu is currently open. Returns false while no root is attached to the handle.
payloadPayload \| undefinedreadonlyThe payload of the trigger that owns the menu.

Methods:

Opens the menu and associates it with the trigger with the given id.

This method should only be called in an event handler or an effect (not during rendering).

Closes the menu.

This method should only be called in an event handler or an effect (not during rendering).

Ends the closing phase of the menu after an externally controlled closing animation finishes.