Skip to contents

Context Menu

A menu that appears at the pointer on right click or long press.

Right click here

Usage guidelines

  • Use context menus as an enhancement: Don't make a context menu the only way to perform actions. Users may not discover or be able to open a context menu, especially on touch devices or with assistive technology. Always provide visible controls for the actions that are available in the context menu.

Anatomy

Import the components and place them together:

Examples

Menu displays additional demos, many of which apply to the context menu as well.

Using with Menu

A context menu should supplement a primary way to perform the same actions. This image card exposes actions through a visible menu button and reuses them in the context menu for right-click and long-press users.

Station Hofplein

JPG, 2.4 MB

Nested menu

To create a submenu, create a <ContextMenu.SubmenuRoot> inside the parent context menu. Use the <ContextMenu.SubmenuTrigger> part for the menu item that opens the nested menu.

Right click here

API reference

Root

A component that creates a context menu activated by right clicking or long pressing. 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'

Trigger

An area that opens the menu on right click or long press. Renders a <div> element.

render Snippet<[props: HTMLAttributes<HTMLDivElement>, state: ContextMenuTriggerState, children: Snippet | undefined]> —
Name
Description

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

Type
Snippet<[props: HTMLAttributes<HTMLDivElement>, state: ContextMenuTriggerState, children: Snippet | undefined]>
open boolean
Name
open
Description

Whether the context menu is currently open.

Type
boolean
data-popup-open
Present when the corresponding context menu is open.
data-pressed
Present when the corresponding context menu is open.

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.

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.

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.