Context Menu
Right-click context menu overlay with nested submenus, optional horizontal icon groups, shortcuts, boolean toggles, and danger actions.
import { useContextMenuAPI, contextMenu } from 'phoundry-ui'; Programmatic Open
Show code
const api = useContextMenuAPI();
const items: MenuItem[] = [
{ type: 'action', label: 'Copy', icon: 'carbon:copy', id: 'copy', action: () => {} },
{ type: 'separator' },
{ type: 'action', label: 'Delete', danger: true, id: 'del', action: () => {} },
];
api.open(() => items, e.clientX, e.clientY, { ariaLabel: 'Edit actions' });Right-Click Area (Attachment)
Show code
<div {@attach contextMenu({ api, items: menuItems })}>
Right-click here
</div>OpenMenuOptions (4th argument to api.open)
| Prop | Type | Default | Description |
|---|---|---|---|
| ariaLabel | string | — | Accessible name for the menu panel. Defaults to `"Context menu"`. |
| anchor | 'start' | 'end' | — | Horizontal alignment relative to the open point. |
| side | PopoverSide | — | Which edge of the trigger the menu opens from. Defaults to `'bottom'`. |
| onClose | () => void | — | Called when the menu closes (Escape, backdrop, or after an action). |
| trigger | unknown | — | Optional trigger reference for callers that track menu origin. |
ActionMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'action' | — | Menu item that triggers a callback. |
| id required | string | — | Stable key for shortcuts / analytics. |
| label required | string | — | Display text. |
| icon | string | — | Iconify icon string. |
| shortcut | string | — | Display-only shortcut hint. |
| pluginId | string | — | Optional plugin scope for shortcut manager lookups (`pluginId.id`). |
| danger | boolean | false | Red danger styling. |
| disabled | boolean | false | Non-interactive row. |
| selected | boolean | — | Decorates the row as checked/active where supported. |
| preventClose | boolean | false | Keep the overlay open after invoking the action. |
| action required | () => void | Promise<void> | — | Handler run when the row is activated. |
BooleanMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'boolean' | — | Toggle row with checkbox on the right. |
| label required | string | — | Display text. |
| icon | string | — | Iconify icon string. |
| pluginId | string | — | Plugin ID (same role as on action items). |
| preventClose | boolean | false | Keep the menu open after toggling. |
| value required | boolean | — | Checked state. |
| onchange required | (nextValue: boolean) => void | Promise<void> | — | Called with the new value after the user toggles the row. |
SubmenuMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'submenu' | — | Nested submenu container. |
| label required | string | — | Submenu trigger label. |
| items required | MenuItem[] | — | Child menu items. |
GroupMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'group' | — | Horizontal row of icon-only controls. |
| id required | string | — | Stable key (see MenuItemBase). |
| items required | GroupMenuChildItem[] | — | Toolbar row: **`action`** and **`boolean`** as icon-only `Button`s (labels via tooltip / `aria-label`); **`separator`** as a vertical rule. |
| disabled | boolean | false | Disables all controls in the group. |
SeparatorMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'separator' | — | Horizontal rule between groups. |
LabelMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'label' | — | Non-interactive heading row. |
| label required | string | — | Muted caption text. |
CustomMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| type required | 'custom' | — | Fully custom row body via snippet. |
| id required | string | — | Stable key. |
| render required | Snippet | — | Snippet rendered inside the menu row. |
| disabled | boolean | false | Skip pointer interaction. |
Usage tips
provideContextMenu()must be called in the root layout, andContextMenuOverlaymust be rendered there — or callsetupOverlays()once to initialize all overlay managers together.- The menu auto-positions to stay within the viewport.
- Arrow keys, Home, and End move the highlighted row; Enter and Space activate it. Escape closes the menu. The active row uses the same background as hover; focus returns to the element that opened the menu.
api.openaccepts either a static array or() => MenuItem[]so menus can read live state (as with the attachment demo). PassariaLabelin the fourth argument when the default"Context menu"label is too generic.- For click-based dropdowns from a button, use
ButtonDropdowninstead.