MenusReact
A menu that appears at the pointer on right click or long press.
Rendered by React 19.3.1
Loading React…Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<ContextMenu.Root>
<ContextMenu.Trigger />
<ContextMenu.Portal>
<ContextMenu.Positioner>
<ContextMenu.Popup>
<ContextMenu.Item />
</ContextMenu.Popup>
</ContextMenu.Positioner>
</ContextMenu.Portal>
</ContextMenu.Root>
// Not in this example: ContextMenu.Arrow, ContextMenu.Backdrop, ContextMenu.CheckboxItem, ContextMenu.CheckboxItemIndicator, ContextMenu.Group, ContextMenu.GroupLabel, ContextMenu.LinkItem, ContextMenu.RadioGroup, ContextMenu.RadioItem, ContextMenu.RadioItemIndicator, ContextMenu.Separator, ContextMenu.SubmenuRoot, ContextMenu.SubmenuTriggerExamples
Submenu
SubmenuRoot and SubmenuTrigger open a nested menu from an item.
API reference
75 props across 19 parts, in React syntax. className, style, render are listed once, under Shared props.
ArrowContextMenu.Arrow
Displays an element positioned against the menu anchor. Renders a <div>.
| Data attribute | Description |
|---|---|
data-open | Present when the menu popup is open. |
data-closed | Present when the menu popup is closed. |
data-side | Indicates which side the popup is positioned relative to the anchor. |
data-align | Indicates how the popup is aligned relative to specified side. |
data-uncentered | Present when the menu arrow is uncentered. |
BackdropContextMenu.Backdrop
An overlay displayed beneath the menu popup. Renders a <div>.
| Data attribute | Description |
|---|---|
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. |
CheckboxItemContextMenu.CheckboxItem
A menu item that toggles a setting on or off. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
labelOverrides the text used for keyboard text navigation and filtering. | string | — |
defaultCheckedWhether the checkbox item is initially ticked. | boolean | false |
checkedWhether the checkbox item is currently ticked. | boolean | — |
onCheckedChangeEvent handler called when the checkbox item is ticked or unticked. | ((checked: boolean, eventDetails: MenuRootChangeEventDetails) => void) | — |
onClickThe click handler for the menu item. | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — |
closeOnClickWhether to close the menu when the item is clicked. | boolean | false |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
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-highlighted | Present when the menu checkbox item is highlighted. |
CheckboxItemIndicatorContextMenu.CheckboxItemIndicator
Indicates whether the checkbox item is ticked. Renders a <span>.
| Prop | Type | Default |
|---|---|---|
keepMountedWhether to keep the HTML element in the DOM when the checkbox item is not checked. | boolean | false |
| Data attribute | Description |
|---|---|
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. |
GroupContextMenu.Group
Groups related menu items with the corresponding label. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
childrenThe content of the component. | React.ReactNode | — |
GroupLabelContextMenu.GroupLabel
An accessible label that is automatically associated with its parent group. Renders a <div>.
ItemContextMenu.Item
An individual interactive item in the menu. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
labelOverrides the text used for keyboard text navigation and filtering. | string | — |
onClickThe click handler for the menu item. | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — |
closeOnClickWhether to close the menu when the item is clicked. | boolean | true |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
data-highlighted | Present when the menu item is highlighted. |
data-disabled | Present when the menu item is disabled. |
LinkItemContextMenu.LinkItem
A link in the menu that can be used to navigate to a different page or section. Renders an <a>.
| Prop | Type | Default |
|---|---|---|
labelOverrides the text used for keyboard text navigation and filtering. | string | — |
closeOnClickWhether to close the menu when the item is clicked. | boolean | false |
| Data attribute | Description |
|---|---|
data-highlighted | Present when the link is highlighted. |
PopupContextMenu.Popup
A container for the menu items. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
finalFocusDetermines the element to focus when the menu is closed. | boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null) | — |
children | React.ReactNode | — |
| Data attribute | Description |
|---|---|
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. |
data-side | Indicates which side the popup is positioned relative to the anchor. |
data-align | Indicates how the popup is aligned relative to specified side. |
data-instant | Present if animations should be instant. |
PortalContextMenu.Portal
A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to <body>. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
containerA parent element to render the portal element into. | HTMLElement | ShadowRoot | React.RefObject<HTMLElement | ShadowRoot | null> | null | — |
keepMountedWhether to keep the portal mounted in the DOM while the popup is hidden. | boolean | false |
PositionerContextMenu.Positioner
Positions the context menu popup against the pointer or a custom anchor. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
disableAnchorTrackingWhether to disable the popup from tracking any layout shift of its positioning anchor. | boolean | false |
alignHow to align the popup relative to the specified side. | Align | 'start' |
alignOffsetAdditional offset along the alignment axis in pixels. | number | OffsetFunction | — |
sideWhich side of the anchor element to align the popup against. | Side | 'bottom' |
sideOffsetDistance between the anchor and the popup in pixels. | number | OffsetFunction | — |
arrowPaddingMinimum distance to maintain between the arrow and the edges of the popup. | number | — |
anchorAn element to position the popup against. | Element | VirtualElement | React.RefObject<Element | null> | (() => Element | VirtualElement | null) | null | — |
collisionAvoidanceDetermines how to handle collisions when positioning the popup. | CollisionAvoidance | — |
collisionBoundaryAn element or a rectangle that delimits the area that the popup is confined to. | Boundary | 'clipping-ancestors' |
collisionPaddingAdditional space to maintain from the edge of the collision boundary. | Padding | 5 |
stickyWhether to maintain the popup in the viewport after | boolean | false |
| Data attribute | Description |
|---|---|
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-side | Indicates which side the popup is positioned relative to the anchor. |
data-align | Indicates how the popup is aligned relative to the specified side. |
| CSS variable | Description |
|---|---|
--available-width | The available width between the anchor and the edge of the viewport. |
--available-height | The available height between the anchor and the edge of the viewport. |
--anchor-width | The anchor's width. |
--anchor-height | The anchor's height. |
--transform-origin | The coordinates that this element is anchored to. Used for animations and transitions. |
--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. |
--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. |
RadioGroupContextMenu.RadioGroup
Groups related radio items. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
defaultValueThe uncontrolled value of the radio item that should be initially selected. | any | — |
valueThe controlled value of the radio item that should be currently selected. | any | — |
onValueChangeFunction called when the selected value changes. | ((value: any, eventDetails: MenuRootChangeEventDetails) => void) | — |
disabledWhether the component should ignore user interaction. | boolean | false |
childrenThe content of the component. | React.ReactNode | — |
RadioItemContextMenu.RadioItem
A menu item that works like a radio button in a given group. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
labelOverrides the text used for keyboard text navigation and filtering. | string | — |
valuerequiredValue of the radio item. | any | — |
onClickThe click handler for the menu item. | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — |
closeOnClickWhether to close the menu when the item is clicked. | boolean | false |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
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-highlighted | Present when the menu radio item is highlighted. |
RadioItemIndicatorContextMenu.RadioItemIndicator
Indicates whether the radio item is selected. Renders a <span>.
| Prop | Type | Default |
|---|---|---|
keepMountedWhether to keep the HTML element in the DOM when the radio item is inactive. | boolean | false |
| Data attribute | Description |
|---|---|
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. |
RootContextMenu.Root
A component that creates a context menu activated by right clicking or long pressing. Doesn’t render its own element.
| Prop | Type | Default |
|---|---|---|
defaultOpenWhether the menu is initially open. | boolean | false |
openWhether the menu is currently open. | boolean | — |
onOpenChangeEvent handler called when the menu is opened or closed. | ((open: boolean, eventDetails: ContextMenuRootChangeEventDetails) => void) | — |
highlightItemOnHoverWhether moving the pointer over items should highlight them. | boolean | true |
actionsRefA ref to imperative actions. | React.RefObject<MenuRootActions | null> | — |
loopFocusWhether to loop keyboard focus back to the first item | boolean | true |
onItemHighlightedCallback fired when an item is highlighted or unhighlighted. | ((highlightedItem: HTMLElement | undefined, eventDetails: MenuRootHighlightEventDetails) => void) | — |
onOpenChangeCompleteEvent handler called after any animations complete when the menu is opened or closed. | ((open: boolean) => void) | — |
disabledWhether the component should ignore user interaction. | boolean | false |
orientationThe visual orientation of the menu. | MenuRootOrientation | 'vertical' |
children | React.ReactNode | — |
SeparatorContextMenu.Separator
A separator element accessible to screen readers. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
orientationThe orientation of the separator. | Orientation | 'horizontal' |
| Data attribute | Description |
|---|---|
data-orientation | Indicates the orientation of the separator. |
SubmenuRootContextMenu.SubmenuRoot
Groups all parts of a submenu. Doesn’t render its own element.
| Prop | Type | Default |
|---|---|---|
defaultOpenWhether the menu is initially open. | boolean | false |
openWhether the menu is currently open. | boolean | — |
onOpenChangeEvent handler called when the menu is opened or closed. | ((open: boolean, eventDetails: MenuRootChangeEventDetails) => void) | — |
highlightItemOnHoverWhether moving the pointer over items should highlight them. | boolean | true |
actionsRefA ref to imperative actions. | React.RefObject<MenuRootActions | null> | — |
closeParentOnEscWhen in a submenu, determines whether pressing the Escape key | boolean | false |
loopFocusWhether to loop keyboard focus back to the first item | boolean | true |
onItemHighlightedCallback fired when an item is highlighted or unhighlighted. | ((highlightedItem: HTMLElement | undefined, eventDetails: MenuRootHighlightEventDetails) => void) | — |
onOpenChangeCompleteEvent handler called after any animations complete when the menu is opened or closed. | ((open: boolean) => void) | — |
disabledWhether the component should ignore user interaction. | boolean | false |
orientationThe visual orientation of the menu. | MenuRootOrientation | 'vertical' |
childrenThe content of the submenu. | React.ReactNode | — |
SubmenuTriggerContextMenu.SubmenuTrigger
A menu item that opens a submenu. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
labelOverrides the text used for keyboard text navigation and filtering. | string | — |
onClick | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
openOnHoverWhether the menu should also open when the trigger is hovered. | boolean | true |
delayHow long to wait before the menu may be opened on hover. | number | 100 |
closeDelayHow long to wait before closing the menu that was opened on hover. | number | 0 |
| Data attribute | Description |
|---|---|
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. |
TriggerContextMenu.Trigger
An area that opens the menu on right click or long press. Renders a <div>.
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding context menu is open. |
data-pressed | Present when the corresponding context menu is open. |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| ShiftTab | Closes the menu and returns focus to the area it was opened on | Popup |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Popup | role="menu" | the popup is announced as a menu |
| Item | role="menuitem" | each action is read as a menu item |
| CheckboxItem | role="menuitemcheckbox", aria-checked | a setting is read with its on or off state |
| RadioItem | role="menuitemradio", aria-checked | the chosen option of a set is read |
| Group | role="group", aria-labelledby to its GroupLabel | related items are read under their label |
| SubmenuTrigger | aria-controls to the submenu | a screen reader knows the item opens another menu |
| Separator | role="separator" | groups are divided for screen readers too |
| Arrow | aria-hidden="true" | the decorative arrow is not read |
Focus order
- Opening moves focus into Popup.
- Arrow keys move between items;
TabandShift+Tabclose the menu. - Closing returns focus to where it was before the menu opened.