Overlays & feedback
Context menu
A right-click menu that opens exactly where the cursor is and offers the actions relevant to whatever was clicked. Icons, shortcuts, danger actions, toggles and nested submenus — keyboard-navigable, edge-aware, and dismissed by Escape or an outside click.
npx shadcn@latest add @orbit/context-menuOverview
Live components — right-click any panel below. Each surface offers a different set of actions; hover “Move to” or “Sort by” for a submenu.
Predictable by default
Opens at the cursor, not at a fixed corner. Near a viewport edge the panel shifts inward and submenus flip to the other side so nothing is clipped. Arrow keys move the highlight, → and ← enter and leave submenus, Enter activates, and Escape, an outside click, or picking an action closes it cleanly.
Props
ContextMenu wraps Base UI ContextMenu; rows share the dropdown menu's styling. Every part forwards ...rest (and ref) to its underlying element, and raw parts are re-exported as ContextMenuPrimitive.
<ContextMenuTrigger> · <ContextMenuContent>
| Prop | Type | Default | Description |
|---|---|---|---|
| ContextMenuTrigger | component | — | The right-clickable surface. Renders a div around your content; long-press opens it on touch. |
| width | string | "220px" | On ContextMenuContent: fixed panel width. |
<ContextMenuItem>
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | ReactNode | — | 16px leading icon, rendered ink-soft (danger items render it in danger). |
| shortcut | string | — | Trailing mono hint like "⌘D" or "F2" (quiet text, no keycap chip in this spec). |
| danger | boolean | false | Destructive styling: danger text and a danger-soft highlight. |
| disabled | boolean | false | Fades the row and blocks activation. |
| onClick | (event) => void | — | Fired when the item is activated; the menu closes afterwards. |
<ContextMenuCheckboxItem> · <ContextMenuRadioGroup> · <ContextMenuRadioItem>
| Prop | Type | Default | Description |
|---|---|---|---|
| checked / onCheckedChange | boolean / (checked) => void | — | Checkbox row state — shows a trailing ✓ and keeps the menu open on toggle. |
| value / onValueChange | any / (value) => void | — | On ContextMenuRadioGroup: the selected row's value (used for submenu pickers like Move to). |
| icon | ReactNode | — | Lead element in the 16px slot — an icon or a color/status dot. |
<ContextMenuSub> · <ContextMenuSubTrigger> · <ContextMenuSubContent>
| Prop | Type | Default | Description |
|---|---|---|---|
| ContextMenuSubTrigger icon | ReactNode | — | 16px leading icon; a trailing chevron is added automatically. |
| ContextMenuSubContent sideOffset | number | 2 | Gap between the parent panel edge and the flyout. |
| ContextMenuSubContent alignOffset | number | -5 | Vertical shift so the first sub-row lines up with its trigger. |
| ContextMenuLabel / ContextMenuSeparator | component | — | Quiet mono group caption · hairline divider bleeding to the panel edges. |
Usage
A context menu is a shortcut, never the only path. Every action it offers should also be reachable from a visible control or the command palette.
Mirror the visible actions
Offer the same operations available from toolbars and the “⋯” menu, just faster to reach.
Hide critical actions here
Right-click is a discovery dead-end on touch. Never make it the only way to do something important.
Group and separate
Cluster related actions, divide with separators, and isolate destructive items at the bottom.
Overfill the menu
Keep it to the dozen-or-so actions that fit the object. Push the long tail into submenus or settings.
Keyboard & accessibility
Built on Base UI ContextMenu: role=menu/menuitem, roving focus, typeahead, edge-aware positioning, and long-press support on touch devices.