API and Development
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.
Name | Type | Default | Description |
|---|---|---|---|
|
| — | The element that activates the context menu on right-click. |
|
| — | Additional CSS class applied to the context menu content container. |
|
| — | Props forwarded to the Radix context-menu content (e.g. |
|
| — | — |
|
|
| When true, disables the context menu trigger and prevents opening. |
|
|
| When true, the menu width fits its content instead of using a fixed width. |
|
| — | Callback fired when a radio item is selected. |
|
| — | Called with the new item id order after a successful reorder.
Reports every id in the reordered list, so a caller can replace its list outright. Reordering
is therefore only offered when the whole list is on screen — see |
|
| — | Currently selected value when the menu contains |
|
|
| When true, menu items can be reordered via drag or keyboard. |
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.
| Name | Default | Description |
|---|---|---|
label | required | Checkbox label text, and the row's accessible name. |
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.
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. |
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 searchable NavigableContextMenu, 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.
On this page