Displays a menu located at the pointer, triggered by a right click or a long press.
<ContextMenu.root id="context-primitive">
<ContextMenu.trigger
id="context-trigger"
content_id="context-content"
class="DemoContextMenuTrigger"
>
Right-click here.
</ContextMenu.trigger>
<ContextMenu.content
id="context-content"
class="DemoContextMenuContent"
>
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Back"
>
Back
<div class="DemoRightSlot">⌘+[</div>
</ContextMenu.item>
<ContextMenu.item
class="DemoContextMenuItem"
disabled
text_value="Forward"
>
Forward
<div class="DemoRightSlot">⌘+]</div>
</ContextMenu.item>
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Reload"
>
Reload
<div class="DemoRightSlot">⌘+R</div>
</ContextMenu.item>
<ContextMenu.sub>
<ContextMenu.sub_trigger
class="DemoContextMenuSubTrigger"
text_value="More Tools"
>
More Tools
<div class="DemoRightSlot">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.61514 7.15788C10.7954 7.3502 10.7954 7.64949 10.61514 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</div>
</ContextMenu.sub_trigger>
<ContextMenu.sub_content
class="DemoContextMenuSubContent"
side_offset={2}
>
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Save Page As"
>
Save Page As…
<div class="DemoRightSlot">⌘+S</div>
</ContextMenu.item>
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Create Shortcut"
>
Create Shortcut…
</ContextMenu.item>
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Name Window"
>
Name Window…
</ContextMenu.item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.item
class="DemoContextMenuItem"
text_value="Developer Tools"
>
Developer Tools
</ContextMenu.item>
</ContextMenu.sub_content>
</ContextMenu.sub>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.checkbox_item
class="DemoContextMenuCheckboxItem"
checked
text_value="Show Bookmarks"
>
<ContextMenu.item_indicator
class="DemoContextMenuItemIndicator"
force_mount
>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</ContextMenu.item_indicator>
Show Bookmarks
<div class="DemoRightSlot">⌘+B</div>
</ContextMenu.checkbox_item>
<ContextMenu.checkbox_item
class="DemoContextMenuCheckboxItem"
text_value="Show Full URLs"
>
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</ContextMenu.item_indicator>
Show Full URLs
</ContextMenu.checkbox_item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.label class="DemoContextMenuLabel">People</ContextMenu.label>
<ContextMenu.radio_group value="pedro">
<ContextMenu.radio_item
class="DemoContextMenuRadioItem"
value="pedro"
checked
>
<ContextMenu.item_indicator
class="DemoContextMenuItemIndicator"
force_mount
>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
fill="currentColor"
>
</path>
</svg>
</ContextMenu.item_indicator>
Pedro Duarte
</ContextMenu.radio_item>
<ContextMenu.radio_item
class="DemoContextMenuRadioItem"
value="colm"
>
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
fill="currentColor"
>
</path>
</svg>
</ContextMenu.item_indicator>
Colm Tuite
</ContextMenu.radio_item>
</ContextMenu.radio_group>
</ContextMenu.content>
</ContextMenu.root>
.DemoContextMenuTrigger {
display: block;
border: 2px white dashed;
color: white;
border-radius: 4px;
font-size: 15px;
user-select: none;
padding: 45px 0;
width: 300px;
text-align: center;
}
.DemoContextMenuContent,
.DemoContextMenuSubContent {
min-width: 220px;
background-color: white;
border-radius: 6px;
overflow: hidden;
padding: 5px;
box-shadow:
0px 10px 38px -10px rgba(22, 23, 24, 0.35),
0px 10px 20px -15px rgba(22, 23, 24, 0.2);
}
.DemoContextMenuItem,
.DemoContextMenuCheckboxItem,
.DemoContextMenuRadioItem,
.DemoContextMenuSubTrigger {
font-size: 13px;
line-height: 1;
color: var(--violet-11);
border-radius: 3px;
display: flex;
align-items: center;
height: 25px;
padding: 0 5px;
position: relative;
padding-left: 25px;
user-select: none;
outline: none;
}
.DemoContextMenuSubTrigger[data-state="open"] {
background-color: var(--violet-4);
color: var(--violet-11);
}
.DemoContextMenuItem[data-disabled],
.DemoContextMenuCheckboxItem[data-disabled],
.DemoContextMenuRadioItem[data-disabled],
.DemoContextMenuSubTrigger[data-disabled] {
color: var(--mauve-8);
pointer-events: "none";
}
.DemoContextMenuItem[data-highlighted],
.DemoContextMenuCheckboxItem[data-highlighted],
.DemoContextMenuRadioItem[data-highlighted],
.DemoContextMenuSubTrigger[data-highlighted] {
background-color: var(--violet-9);
color: var(--violet-1);
}
.DemoContextMenuLabel {
padding-left: 25px;
font-size: 12px;
line-height: 25px;
color: var(--mauve-11);
}
.DemoContextMenuSeparator {
height: 1px;
background-color: var(--violet-6);
margin: 5px;
}
.DemoContextMenuItemIndicator {
position: absolute;
left: 0;
width: 25px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.DemoRightSlot {
margin-left: auto;
padding-left: 20px;
color: var(--mauve-11);
}
[data-highlighted] > .DemoRightSlot {
color: white;
}
[data-disabled] .DemoRightSlot {
color: var(--mauve-8);
}
.DemoContextMenuArrow {
fill: white;
}
Anatomy
Import all parts and piece them together.
<ContextMenu.root id="…">
<ContextMenu.trigger content_id="…" />
<ContextMenu.portal>
<ContextMenu.content id="…">
<ContextMenu.label />
<ContextMenu.item />
<ContextMenu.group>
<ContextMenu.item />
</ContextMenu.group>
<ContextMenu.checkbox_item>
<ContextMenu.item_indicator />
</ContextMenu.checkbox_item>
<ContextMenu.radio_group>
<ContextMenu.radio_item>
<ContextMenu.item_indicator />
</ContextMenu.radio_item>
</ContextMenu.radio_group>
<ContextMenu.sub>
<ContextMenu.sub_trigger />
<ContextMenu.sub_content />
</ContextMenu.sub>
<ContextMenu.separator />
</ContextMenu.content>
</ContextMenu.portal>
</ContextMenu.root>
Anatomy
-
Root - Contains all the parts of a context menu.
-
Trigger - The area that opens the context menu on right-click or long press.
-
Portal - Portals the content into the document (default `body`).
-
Content - The component that pops out in an open context menu.
-
Item - An actionable menu item.
-
Checkbox Item - An item that can be checked or unchecked.
-
Radio Group - Groups mutually exclusive `radio_item` parts.
-
Radio Item - An item that can be selected among a radio group.
-
Item Indicator - Renders when a checkbox or radio item is checked.
-
Label - A non-focusable section label.
-
Separator - Visually separates groups of items.
-
Group - Groups multiple items.
-
Arrow - Optional pointer for submenu positioning.
-
Sub - Contains all the parts of a submenu.
-
Sub Trigger - An item that opens a submenu.
-
Sub Content - The submenu panel.
API Reference
Root
Contains all the parts of a context menu.
| Prop | Type | Default | Description |
|---|---|---|---|
default_open
|
boolean
|
false
|
|
dir
|
string
|
"ltr"
|
|
id
|
string
|
—
|
|
modal
|
boolean
|
true
|
|
on_open_change
|
string
|
nil
|
|
open
|
boolean
|
false
|
default_open
boolean
Default
false
dir
string
Default
"ltr"
id
string
Default
—
modal
boolean
Default
true
on_open_change
string
Default
nil
open
boolean
Default
false
Trigger
The area that opens the context menu. Wrap it around the target you want the menu to open from when right-clicking (or using the relevant keyboard shortcuts).
| Prop | Type | Default | Description |
|---|---|---|---|
content_id
|
string
|
nil
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
content_id
string
Default
nil
disabled
boolean
Default
false
id
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the menu is open. |
Portal
When used, portals the content part into the target (default body).
| Prop | Type | Default | Description |
|---|---|---|---|
class
|
any
|
nil
|
|
container
|
string
|
"div"
|
|
id
|
string
|
—
|
|
target
|
string
|
"body"
|
class
any
Default
nil
container
string
Default
"div"
id
string
Default
—
target
string
Default
"body"
Content
The component that pops out in an open context menu.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
loop
|
boolean
|
true
|
id
string
Default
nil
loop
boolean
Default
true
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the menu is open. |
[data-side]
|
left | right | bottom | top
|
The side the content rendered against. |
[data-align]
|
start | end | center
|
The alignment of the content. |
| CSS variable | Description |
| --- | --- |
| --radix-context-menu-content-transform-origin | The transform-origin computed from content and arrow positions/offsets |
| --radix-context-menu-content-available-width | Remaining width between the trigger and the boundary edge |
| --radix-context-menu-content-available-height | Remaining height between the trigger and the boundary edge |
| --radix-context-menu-trigger-width | The width of the trigger |
| --radix-context-menu-trigger-height | The height of the trigger |
Item
The component that contains the context menu items.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Checkbox Item
An item that can be controlled and rendered like a checkbox.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
checked
boolean
Default
false
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the checked state. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Radio Group
Used to group multiple ContextMenu.radio_item parts.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
value
|
string
|
nil
|
id
string
Default
nil
value
string
Default
nil
Radio Item
An item that can be controlled and rendered like a radio.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
|
value
|
string
|
—
|
checked
boolean
Default
false
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
value
string
Default
—
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the selected state. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Item Indicator
Renders when the parent checkbox_item or radio_item is checked.
| Prop | Type | Default | Description |
|---|---|---|---|
force_mount
|
boolean
|
false
|
|
id
|
string
|
nil
|
force_mount
boolean
Default
false
id
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the checked state of the parent item. |
Label
Used to render a label. It won't be focusable using arrow keys.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
id
string
Default
nil
Separator
Used to visually separate items in the context menu.
| Prop | Type | Default | Description |
|---|---|---|---|
decorative
|
boolean
|
true
|
|
id
|
string
|
nil
|
decorative
boolean
Default
true
id
string
Default
nil
Group
Used to group multiple ContextMenu.item parts.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
id
string
Default
nil
Arrow
An optional arrow element rendered alongside a submenu.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
id
string
Default
nil
Sub
Contains all the parts of a submenu.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
open
|
boolean
|
false
|
id
string
Default
nil
open
boolean
Default
false
Sub Trigger
An item that opens a submenu. Must be rendered inside ContextMenu.sub.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the submenu is open. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Sub Content
The component that pops out when a submenu is open. Must be rendered inside ContextMenu.sub.
| Prop | Type | Default | Description |
|---|---|---|---|
align
|
string
|
"start"
|
|
id
|
string
|
nil
|
|
side
|
string
|
"right"
|
|
side_offset
|
integer
|
0
|
align
string
Default
"start"
id
string
Default
nil
side
string
Default
"right"
side_offset
integer
Default
0
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the submenu is open. |
[data-side]
|
left | right | bottom | top
|
The side the submenu rendered against. |
[data-align]
|
start | end | center
|
The alignment of the submenu. |
Examples
With submenus
You can create submenus by using ContextMenu.sub in combination with its parts.
<ContextMenu.root id="context-sub">
<ContextMenu.trigger id="context-sub-trigger" content_id="context-sub-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-sub-content">
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.sub>
<ContextMenu.sub_trigger class="DemoContextMenuSubTrigger">Sub menu →</ContextMenu.sub_trigger>
<ContextMenu.sub_content class="DemoContextMenuSubContent">
<ContextMenu.item class="DemoContextMenuItem">Sub menu item</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">Sub menu item</ContextMenu.item>
<ContextMenu.arrow class="DemoContextMenuArrow" />
</ContextMenu.sub_content>
</ContextMenu.sub>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
</ContextMenu.content>
</ContextMenu.root>
With disabled items
You can add special styles to disabled items via the data-disabled attribute.
<ContextMenu.root id="context-disabled">
<ContextMenu.trigger id="context-disabled-trigger" content_id="context-disabled-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-disabled-content">
<ContextMenu.item class="DemoContextMenuItem" disabled>…</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
</ContextMenu.content>
</ContextMenu.root>
.DemoContextMenuItem[data-disabled] {
color: gainsboro;
}
With separators
Use the separator part to add a separator between items.
<ContextMenu.root id="context-separators">
<ContextMenu.trigger id="context-separators-trigger" content_id="context-separators-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-separators-content">
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
</ContextMenu.content>
</ContextMenu.root>
With labels
Use the label part to help label a section.
<ContextMenu.root id="context-labels">
<ContextMenu.trigger id="context-labels-trigger" content_id="context-labels-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-labels-content">
<ContextMenu.label class="DemoContextMenuLabel">Label</ContextMenu.label>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
</ContextMenu.content>
</ContextMenu.root>
With checkbox items
Use the checkbox_item part to add an item that can be checked. Pass checked from LiveView assigns to control state.
<ContextMenu.root id="context-checkbox">
<ContextMenu.trigger id="context-checkbox-trigger" content_id="context-checkbox-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-checkbox-content">
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">…</ContextMenu.item>
<ContextMenu.separator class="DemoContextMenuSeparator" />
<ContextMenu.checkbox_item checked={@checked} class="DemoContextMenuCheckboxItem" text_value="Checkbox item">
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">✓</ContextMenu.item_indicator>
Checkbox item
</ContextMenu.checkbox_item>
</ContextMenu.content>
</ContextMenu.root>
With radio items
Use the radio_group and radio_item parts to add an item that can be checked amongst others.
<ContextMenu.root id="context-radio">
<ContextMenu.trigger id="context-radio-trigger" content_id="context-radio-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-radio-content">
<ContextMenu.radio_group value={@color}>
<ContextMenu.radio_item value="red" checked={@color == "red"} class="DemoContextMenuRadioItem">
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">●</ContextMenu.item_indicator>
Red
</ContextMenu.radio_item>
<ContextMenu.radio_item value="blue" checked={@color == "blue"} class="DemoContextMenuRadioItem">
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">●</ContextMenu.item_indicator>
Blue
</ContextMenu.radio_item>
<ContextMenu.radio_item value="green" checked={@color == "green"} class="DemoContextMenuRadioItem">
<ContextMenu.item_indicator class="DemoContextMenuItemIndicator">●</ContextMenu.item_indicator>
Green
</ContextMenu.radio_item>
</ContextMenu.radio_group>
</ContextMenu.content>
</ContextMenu.root>
With complex items
You can add extra decorative elements in the item parts, such as images.
<ContextMenu.root id="context-complex">
<ContextMenu.trigger id="context-complex-trigger" content_id="context-complex-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-complex-content">
<ContextMenu.item class="DemoContextMenuItem">
<img src="…" alt="" />
Adolfo Hess
</ContextMenu.item>
<ContextMenu.item class="DemoContextMenuItem">
<img src="…" alt="" />
Miyah Myles
</ContextMenu.item>
</ContextMenu.content>
</ContextMenu.root>
Constrain the content/sub-content size
You may want to constrain the width of the content (or sub-content) so that it matches the trigger width, or constrain its height to not exceed the viewport.
We expose several CSS custom properties such as --radix-context-menu-trigger-width and --radix-context-menu-content-available-height to support this. Use them to constrain the content dimensions.
<ContextMenu.root id="context-constrain">
<ContextMenu.trigger id="context-constrain-trigger" content_id="context-constrain-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-constrain-content" class="DemoContextMenuContent">
…
</ContextMenu.content>
</ContextMenu.root>
.DemoContextMenuContent {
width: var(--radix-context-menu-trigger-width);
max-height: var(--radix-context-menu-content-available-height);
}
Origin-aware animations
We expose a CSS custom property --radix-context-menu-content-transform-origin. Use it to animate the content from its computed origin based on positioning and any collisions.
<ContextMenu.root id="context-origin">
<ContextMenu.trigger id="context-origin-trigger" content_id="context-origin-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-origin-content" class="DemoContextMenuContent">
…
</ContextMenu.content>
</ContextMenu.root>
.DemoContextMenuContent {
transform-origin: var(--radix-context-menu-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
Collision-aware animations
We expose data-side and data-align attributes. Their values change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
<ContextMenu.root id="context-collision">
<ContextMenu.trigger id="context-collision-trigger" content_id="context-collision-content">…</ContextMenu.trigger>
<ContextMenu.content id="context-collision-content" class="DemoContextMenuContent">
…
</ContextMenu.content>
</ContextMenu.root>
.DemoContextMenuContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.DemoContextMenuContent[data-side="top"] {
animation-name: slideUp;
}
.DemoContextMenuContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Accessibility
Adheres to the Menu WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.
Keyboard Interactions
Keyboard Interactions
| Key | Description |
|---|---|
Space
|
Activates the focused item. |
Enter
|
Activates the focused item. |
ArrowDown
|
Moves focus to the next item. |
ArrowUp
|
Moves focus to the previous item. |
ArrowRight, ArrowLeft
|
When focus is on `ContextMenu.sub_trigger`, opens or closes the submenu depending on reading direction. |
Esc
|
Closes the context menu. |