ContextMenu
Wrap a region in children and pass Menu-style items. ContextMenu uses the
same Zag.js machine and styling scope as Menu.
import { ContextMenu } from '@manti-ui/react'; import type { MenuItem } from '@manti-ui/react'; const items: MenuItem[] = [ { value: 'back', label: 'Back', shortcut: '⌘[' }, { value: 'forward', label: 'Forward', shortcut: '⌘]', disabled: true }, { value: 'reload', label: 'Reload', shortcut: '⌘R' }, { type: 'separator' }, { type: 'group', label: 'Edit', items: [ { value: 'cut', label: 'Cut', shortcut: '⌘X' }, { value: 'copy', label: 'Copy', shortcut: '⌘C' }, { value: 'paste', label: 'Paste', shortcut: '⌘V' }, ], }, ]; export default function ContextMenuBasic() { return ( <ContextMenu items={items}> <div className="grid place-items-center w-[calc(var(--manti-space-16)*5)] h-[calc(var(--manti-space-16)*2.75)] rounded-lg border border-border border-dashed border-border-strong text-text-muted text-sm select-none"> Right-click anywhere here </div> </ContextMenu> ); }
Nested items use the same recursive { type: 'submenu', value, label, items }
shape as Menu. No separate nested context-menu component is required.
Sizes
size sets the panel's row rhythm, matching the scale every other control uses.
Submenus inherit it.
API
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required region that opens the menu on right-click or long-press. |
items | MenuItem[] | — | Required recursive menu contents, including groups, options, and nested submenus. |
size | 'sm' | 'md' | 'lg' | 'md' | Row rhythm of the panel: type, padding, and icon size. Submenus inherit it. |
onSelect | (value: string) => void | — | Called with the value of the selected command. |
open | boolean | — | Controlled open state. |
defaultOpen | boolean | — | Initial open state for uncontrolled usage. |
onOpenChange | (open: boolean) => void | — | Called whenever the open state changes. |
Styling
Anatomy
| Part | Selector | Description |
|---|---|---|
positioner | [data-scope="menu"][data-part="positioner"] | Positions the floating panel at the pointer. |
content | [data-scope="menu"][data-part="content"] | The translucent menu panel. |
item | [data-scope="menu"][data-part="item"] | A selectable command. |
trigger-item | [data-scope="menu"][data-part="trigger-item"] | A nested-menu trigger. |
item-icon | [data-scope="menu"][data-part="item-icon"] | A leading icon on a command. |
item-text | [data-scope="menu"][data-part="item-text"] | The command label. |
submenu-indicator | [data-scope="menu"][data-part="submenu-indicator"] | Directional affordance on a nested-menu trigger. |
item-shortcut | [data-scope="menu"][data-part="item-shortcut"] | The trailing keyboard-shortcut hint. |
item-group-label | [data-scope="menu"][data-part="item-group-label"] | The title of a command group. |
separator | [data-scope="menu"][data-part="separator"] | A horizontal divider between groups. |
Tokens
| Token | Controls |
|---|---|
--manti-menu-min-width | min width |
--manti-menu-max-width | max width |
--manti-menu-padding | padding |
--manti-menu-gap | gap |
--manti-menu-item-padding-y | item padding y |
--manti-menu-item-padding-x | item padding x |
--manti-menu-item-gap | item gap |
--manti-menu-item-radius | item radius |
--manti-menu-item-font-size | item font size |
--manti-menu-submenu-min-width | submenu min width |
--manti-menu-submenu-indicator-size | submenu indicator size |
--manti-menu-submenu-offset | submenu offset |
--manti-menu-motion-offset | motion offset |
--manti-menu-z-index | z index |
Last updated