Context Menu
A menu that appears when right-clicking on an element, providing contextual actions and options.
Overview
The Context Menu component displays a menu triggered by right-clicking on an element, providing contextual actions and options. It supports keyboard shortcuts, checkboxes, radio groups, submenus, and separators. Built on Base UI primitives, it offers full keyboard navigation and accessibility features.
Usage
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuCheckboxItem,
ContextMenuRadioItem,
ContextMenuRadioGroup,
ContextMenuGroupLabel,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
} from "@tilt-legal/cubitt-components/primitives";<ContextMenu>
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem>Item 1</ContextMenuItem>
<ContextMenuItem>Item 2</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>Item 3</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>Examples
With Shortcuts
Display keyboard shortcuts alongside menu items for quick reference.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuShortcut,
} from "@tilt-legal/cubitt-components/primitives";
export default function Component() {
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-64">
<ContextMenuItem>
Back
<ContextMenuShortcut>⌘[</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Forward
<ContextMenuShortcut>⌘]</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Reload
<ContextMenuShortcut>⌘R</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>
View Source
<ContextMenuShortcut>⌘U</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Inspect
<ContextMenuShortcut>⌘⇧I</ContextMenuShortcut>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}With Checkboxes
Use checkboxes for toggleable options in the context menu.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuCheckboxItem,
ContextMenuSeparator,
} from "@tilt-legal/cubitt-components/primitives";
export default function Component() {
const [showBookmarks, setShowBookmarks] = React.useState(true);
const [showReadingList, setShowReadingList] = React.useState(false);
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-64">
<ContextMenuItem>Reload</ContextMenuItem>
<ContextMenuItem>Force Reload</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuCheckboxItem
checked={showBookmarks}
onCheckedChange={setShowBookmarks}
>
Show Bookmarks Bar
</ContextMenuCheckboxItem>
<ContextMenuCheckboxItem
checked={showReadingList}
onCheckedChange={setShowReadingList}
>
Show Reading List
</ContextMenuCheckboxItem>
</ContextMenuContent>
</ContextMenu>
);
}With Radio Group
Use radio groups for mutually exclusive options.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuGroup,
ContextMenuGroupLabel,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuSeparator,
} from "@tilt-legal/cubitt-components/primitives";
export default function Component() {
const [position, setPosition] = React.useState("top");
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-64">
<ContextMenuItem>Preferences</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuGroup>
<ContextMenuGroupLabel>Panel Position</ContextMenuGroupLabel>
<ContextMenuRadioGroup value={position} onValueChange={setPosition}>
<ContextMenuRadioItem value="top">Top</ContextMenuRadioItem>
<ContextMenuRadioItem value="bottom">Bottom</ContextMenuRadioItem>
<ContextMenuRadioItem value="right">Right</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenuGroup>
</ContextMenuContent>
</ContextMenu>
);
}With Submenu
Create nested menus for organizing related actions.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
} from "@tilt-legal/cubitt-components/primitives";
export default function Component() {
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-64">
<ContextMenuItem>New File</ContextMenuItem>
<ContextMenuItem>New Folder</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuSub>
<ContextMenuSubTrigger>Share</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Email</ContextMenuItem>
<ContextMenuItem>Messages</ContextMenuItem>
<ContextMenuItem>Copy Link</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuItem>Rename</ContextMenuItem>
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}With Inset
Use the inset prop to add left padding for consistent alignment with checkboxes and radio items.
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuGroup,
ContextMenuGroupLabel,
ContextMenuSeparator,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
} from "@tilt-legal/cubitt-components/primitives";
export default function Component() {
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-64">
<ContextMenuItem inset>View</ContextMenuItem>
<ContextMenuItem inset>Edit</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuSub>
<ContextMenuSubTrigger inset>More Tools</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Developer Tools</ContextMenuItem>
<ContextMenuItem>Task Manager</ContextMenuItem>
<ContextMenuItem>Extensions</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuGroup>
<ContextMenuGroupLabel inset>Advanced</ContextMenuGroupLabel>
<ContextMenuItem inset>Settings</ContextMenuItem>
</ContextMenuGroup>
</ContextMenuContent>
</ContextMenu>
);
}API Reference
ContextMenu
The root component that manages context menu state.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Controlled open state |
defaultOpen | boolean | false | Initial open state |
onOpenChange | (open: boolean) => void | - | Callback when open state changes |
ContextMenuTrigger
The element that triggers the context menu on right-click.
| Prop | Type | Default | Description |
|---|---|---|---|
render | React.ReactElement | - | Custom element to render as trigger |
ContextMenuContent
The container for menu items.
| Prop | Type | Default | Description |
|---|---|---|---|
align | "start" | "center" | "end" | "start" | Alignment relative to trigger |
side | "top" | "right" | "bottom" | "left" | "bottom" | Side to render on |
sideOffset | number | 4 | Distance from trigger |
alignOffset | number | 0 | Offset from alignment axis |
ContextMenuItem
A menu item that can be clicked.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Disable the item |
inset | boolean | false | Add left padding |
variant | "default" | "destructive" | "default" | Visual variant |
ContextMenuCheckboxItem
A menu item with a checkbox.
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | - | Controlled checked state |
defaultChecked | boolean | false | Initial checked state |
onCheckedChange | (checked: boolean) => void | - | Callback when checked changes |
ContextMenuRadioGroup
A container for radio items.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | Controlled value |
defaultValue | string | - | Initial value |
onValueChange | (value: string) => void | - | Callback when value changes |
ContextMenuRadioItem
A menu item with a radio button.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | The value of the item |
disabled | boolean | false | Disable the item |
ContextMenuSub
Container for submenu.
ContextMenuSubTrigger
Trigger for opening a submenu.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Disable the trigger |
inset | boolean | false | Add left padding |
ContextMenuSubContent
Content for a submenu.
| Prop | Type | Default | Description |
|---|---|---|---|
align | "start" | "center" | "end" | - | Alignment relative to trigger |
side | "top" | "right" | "bottom" | "left" | - | Side to render on |
sideOffset | number | 4 | Distance from trigger |
alignOffset | number | 0 | Offset from alignment axis |
ContextMenuGroup
Container for grouping related menu items with a label.
ContextMenuGroupLabel
Label for a group of items.
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Add left padding |
ContextMenuSeparator
Visual separator between items.
ContextMenuShortcut
Display keyboard shortcuts.