ComponentsOverlay
Context Menu
A menu that appears on right-click or long-press. Built on Radix UI with support for nested submenus, checkboxes, radio items, shortcuts, and disabled states.
Basic Context Menu
Right click anywhere here
With Keyboard Shortcuts
Right click for shortcuts
Destructive Items
Right click to see destructive items
Disabled Items
Right click to see disabled items
Checkbox Items
Right click for view options
Radio Items
Right click for layout options
Nested Submenus
Right click for nested menus
Installation
npx visor add context-menuThis copies two files into your project:
components/ui/context-menu/context-menu.tsx— the componentcomponents/ui/context-menu/context-menu.module.css— the styles
Usage
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuLabel,
} from '@/components/ui/context-menu/context-menu';
export default function Example() {
return (
<ContextMenu>
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuLabel>Actions</ContextMenuLabel>
<ContextMenuItem>Edit</ContextMenuItem>
<ContextMenuItem>Duplicate</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}API Reference
ContextMenuProps
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'destructive' | 'default' | Visual style of ContextMenuItem — use "destructive" for dangerous actions. |
inset | boolean | false | Adds left padding to ContextMenuItem, ContextMenuLabel, or ContextMenuSubTrigger to align with items that have icons. |
disabled | boolean | false | Disables the menu item, making it non-interactive and visually muted. |
checked | boolean | "indeterminate" | — | Controlled checked state for ContextMenuCheckboxItem. |
onCheckedChange | (checked: boolean) => void | — | Callback when the checked state of a ContextMenuCheckboxItem changes. |
value | string | — | Value for ContextMenuRadioItem. The selected value is managed by ContextMenuRadioGroup. |
onValueChange | (value: string) => void | — | Callback on ContextMenuRadioGroup when the selected radio value changes. |
onSelect | (event: Event) => void | — | Callback when a ContextMenuItem is selected. Call event.preventDefault() to keep the menu open. |
className | string | — | Additional CSS class names to merge onto the element. |
Sub-components
| Component | Element | Purpose |
|---|---|---|
ContextMenu | Root | Context provider (wraps Radix ContextMenu.Root) |
ContextMenuTrigger | Any element | Right-click target area |
ContextMenuContent | Floating panel | Container for menu items |
ContextMenuGroup | Group | Groups related items |
ContextMenuLabel | Label | Non-interactive section heading |
ContextMenuItem | Item | Clickable menu item |
ContextMenuCheckboxItem | Item | Toggleable checkbox item |
ContextMenuRadioGroup | Group | Container for radio items |
ContextMenuRadioItem | Item | Mutually exclusive selection item |
ContextMenuSeparator | <hr> | Visual divider between groups |
ContextMenuShortcut | <span> | Keyboard shortcut label displayed on the right |
ContextMenuSub | Root | Wrapper for a nested submenu |
ContextMenuSubTrigger | Item | Trigger that opens a submenu |
ContextMenuSubContent | Floating panel | Container for submenu items |
Accessibility
- Built on Radix UI ContextMenu — ARIA roles (
menu,menuitem,menuitemcheckbox,menuitemradio) are applied automatically. - Keyboard navigation:
ArrowUp/ArrowDownto move between items,ArrowRightto open submenus,ArrowLeftto close them,Escapeto dismiss. - Focus is trapped within the open menu and restored to the trigger on close.
- Disabled items use
aria-disabledand are not keyboard-reachable. - Shortcut text is visible to screen readers — use
aria-hiddenif the shortcut text would be redundant.