Context menu
Right-click (or long-press) menu attached to any element. Same compound API as DropdownMenu — items, shortcuts, checkbox / radio items, submenus, labels, separators — triggered by the contextmenu event instead of a button click.
Anatomy
- 1Trigger
The element that opens the menu on right-click / long-press (ContextMenuTrigger).
- 2Content
The floating panel (min-w-32, rounded-md, shadow-md, p-1). Portals above everything.
- 3Item
A row: pl-8 aligns text past the indicator column, with an optional leading icon + a right-aligned ContextMenuShortcut. Hover = bg-muted.
- 4Checkbox / Radio item
CheckboxItem shows a Check; RadioItem shows a filled dot in the left indicator slot.
- 5Label + separator
ContextMenuLabel is a semibold title; ContextMenuSeparator is a 1px divider. Submenus via ContextMenuSub + SubTrigger (CaretRight).
Variants
<ContextMenu>
<ContextMenuTrigger>…</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuLabel>Row</ContextMenuLabel>
<ContextMenuItem>
<PencilSimple weight="light" /> Edit
<ContextMenuShortcut>⌘E</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuCheckboxItem checked={starred} onCheckedChange={setStarred}>
Starred
</ContextMenuCheckboxItem>
<ContextMenuSub>
<ContextMenuSubTrigger inset>Move to</ContextMenuSubTrigger>
<ContextMenuSubContent>…</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuItem>Delete <ContextMenuShortcut>⌫</ContextMenuShortcut></ContextMenuItem>
</ContextMenuContent>
</ContextMenu>Import
Copy this import line at the top of the file where you compose this atom.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuCheckboxItem,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubTrigger,
ContextMenuSubContent,
} from "@/components/ui/context-menu";Props
Everything else from the underlying HTML or Radix primitive is forwarded via ...props.
| Prop | Type | Default | Description |
|---|---|---|---|
| ContextMenuTrigger | Radix Trigger | — | The element right-clicking opens the menu on. Style it however you like. |
| ContextMenuContent | Radix Content | — | The floating panel (min-w-32, rounded-md, shadow-md). Portals above everything. |
| ContextMenuItem | Radix Item | — | A selectable row. inset prop adds pl-8 to align with checkbox/radio rows. onSelect handler; disabled. |
| ContextMenuCheckboxItem | Radix CheckboxItem | — | Toggle row with a Check indicator. checked + onCheckedChange. |
| ContextMenuRadioGroup / RadioItem | Radix Radio | — | Single-choice group. value + onValueChange on the group; value on each item. |
| ContextMenuLabel | Radix Label | — | A non-interactive semibold title. inset aligns it with the items. |
| ContextMenuShortcut | span | — | Muted keyboard hint pinned to the right of an item (ml-auto). |
| ContextMenuSeparator | Radix Separator | — | A 1px divider between groups. |
| ContextMenuSub / SubTrigger / SubContent | Radix Sub | — | A nested submenu. SubTrigger shows a CaretRight; keep nesting to one level. |
When to use
- Row actions in tables (right-click a row to reveal edit/delete).
- Secondary actions on cards or list items.
- A canvas/editor where right-click is expected.
When not to use
- As the primary way to reveal actions — most users don't right-click.
- On touch-only prototypes — no right-click there.
- For a searchable action palette — use Command.
Usage
- Mirror the same options as the row's kebab dropdown so both entry points behave the same.
- Give high-frequency items a keyboard shortcut.
- Don't hide critical actions only in the context menu.
- Don't nest more than one submenu.
- Don't use uppercase labels — ContextMenuLabel is a sentence-case semibold title.
Related
Cross-links to atoms and patterns you may reach for next.
- Dropdown menuSame compound, opened by a button click instead of right-click.
- MenubarA horizontal bar of menus sharing this item vocabulary.
- CommandFor a searchable palette of actions.