ContextMenu wraps trigger content and renders actions in ContextMenu.Content. Compose with ContextMenuItem, ContextMenuItemCheckbox, ContextMenuItemSwitch, ContextMenuItemRadio, ContextMenuItemSubmenu, ContextMenuLabel, ContextMenuSeparator, and ContextMenuGroup. For radio groups, pass radioValue and onRadioValueChange. NavigableContextMenu adds advanced navigation patterns for large menus.
Pass contentProps to forward attributes onto the portaled Radix content — for example data-* markers so overlay systems (annotation capture) treat the open menu as exempt. This mirrors Menu's contentProps API.
ContextMenu
Name
Type
Default
Description
children
ReactNode
—
One {@link ContextMenuTrigger }, one {@link ContextMenuContent }, and any other parts.
defaultOpen
boolean
false
Initial open state when uncontrolled.
disabled
boolean
false
Leaves the platform's own context menu alone. The region opens nothing, and its contextmenu event is not
canceled. An open menu closes when this becomes true.
onOpenChange
MenuOpenChangeHandler
—
Called when the menu opens or closes. Every opening gesture (right click, two-finger tap, Shift+F10, the context
menu key, a long press) reports "trigger-press" with the platform event in details.event; a close reports
"item-press", "focus-out" (Tab), or "light-dismiss" (Escape, an outside press, or a scroll of the region).
open
boolean
—
Controlled open state. Pair with onOpenChange.
replaceTextFieldMenu
boolean
false
Opens over native text fields too. By default a right click, Shift+F10, or long press on a text input, a
textarea, or editable content leaves the platform's text menu (cut, copy, paste, spelling) alone and this region
takes nothing, so a form inside a region keeps its editing menu. Set true on a region that must replace it.
Storybook
Interactive examples and edge cases for this component are in Storybook.
ContextMenu and NavigableContextMenu accept the same reorder props as Menu:
Name
Default
Description
sortable
false
Enables drag handles, drop indicators, and keyboard reorder for items with a sortableId.
onReorder
Called with the new ordered list of sortableId values: (orderedIds: string[]) => void.
ContextMenuItem and ContextMenuItemCheckbox accept sortableId (defaults to label or value when omitted). Checkbox rows drag from the handle only; activating the row still toggles its checked state.
onReorder reports every id in the reordered list, so handlers can replace their list outright. In
a NavigableContextMenu, reorder affordances are therefore hidden whenever the visible list is only
part of the list: while a search filter is active, and while a submenu pane is open.
Reorderable context menu
Basic
Separators and labels
With icons
With badges
Checkboxes and radio group
ContextMenuItemCheckbox Props
Name
Default
Description
label
required
Checkbox label text, and the row's accessible name. LocalizedMessage | DisplayValue—copy from formatMessage, or data from toDisplayValue.
checked
false
boolean | "indeterminate". "indeterminate" shows the partial-selection dash and announces aria-checked="mixed".
value
Stable identifier. Read by ContextMenuCollapsibleGroup select-all to scope a toggle to filtered children.
disabled
false
Disables the row.
onCheckedChange
(checked: boolean) => void. Never receives "indeterminate" — activation always resolves to a definite state.
The row is itself the menuitemcheckbox; the checkbox is painted with the non-interactive
CheckboxVisual, so there is no nested focusable to break Radix's roving tabindex.
ContextMenuCollapsibleGroup Props
A group heading that expands in place and carries a tri-state select-all for its children. Use this
when options should stay in one pane; use ContextMenuItemSubmenu when they belong on their own
pane behind a breadcrumb. The ContextMenu counterpart of
MenuCollapsibleGroup, with the same
semantics.
Name
Default
Description
label
required
Group heading, and the accessible name of the select-all row. LocalizedMessage—copy from formatMessage.
groupId
Stable identifier for search indexing and the fallback React key. An explicit consumer key is preserved while filtering. Use groupId when two groups share a label or when a label contains >.
checked
required
Tri-state select-all: boolean | "indeterminate". "indeterminate" announces aria-checked="mixed". Compute it from the whole group; under an active search the group narrows it to the visible children.
onCheckedChange
required
(checked: boolean, visibleValues?: string[]) => void. visibleValues lists the children surviving an active search filter, or is undefined when the toggle applies to the whole group.
caption
Trailing count rendered next to the label, e.g. 13 for "Fire (13)".
disabled
false
Disables the row and its select-all.
defaultOpen
false
Initial expanded state when open is not supplied.
open
Controlled expanded state.
onOpenChange
Fired when the expanded state should change: (open: boolean) => void.
children
required
ContextMenuItemCheckbox rows for the group. Unmounted while collapsed.
The row is a single menuitemcheckbox carrying both aria-checked and aria-expanded. Clicking
anywhere on the row expands or collapses it; clicking the checkbox toggles select-all. Keyboard
and AT activation on a collapsed row expands first; when expanded, Space and Enter toggle
select-all. ArrowRight expands and ArrowLeft collapses.
Inside a searchableNavigableContextMenu, a group with matching children keeps its own header,
auto-expands, and scopes select-all to the surviving matches rather than the whole group. Give each
child a value so the group can identify them: the row's own tri-state is then read from the
visible children, so a fully selected subset of a partially selected group still announces
checked and toggles off rather than appearing stuck at mixed.