context-menu
Right-click context menu with keyboard navigation and viewport-aware positioning.
Description
The <context-menu> component provides a custom right-click menu that opens at the cursor position. It supports keyboard navigation, separators, danger items, and disabled states. Shares menu styling patterns with <drop-down>.
Basic Usage
<context-menu> <p data-trigger>Right-click anywhere here</p> <menu> <li><button>Cut</button></li> <li><button>Copy</button></li> <li><button>Paste</button></li> <li role="separator"></li> <li><button class="danger">Delete</button></li> </menu></context-menu>
Structure
| Element | Required | Description |
|---|---|---|
any element with data-trigger | yes | Element defining the right-click target area |
<menu> | yes | Context menu with <li> items holding <button> actions |
Child Attributes
| Attribute | On | Values | Description |
|---|---|---|---|
data-trigger | * | boolean | Element defining the right-click target area |
data-shortcut | button | string | Keyboard shortcut to bind, e.g. 'meta+c'. Displayed as formatted hint. |
Disabled Items
<menu> <li><button>Open</button></li> <li><button data-disabled>Share (disabled)</button></li> <li role="separator"></li> <li><button class="danger">Delete</button></li></menu>
With Icons
Add <icon-wc> or inline <svg> inside buttons. The existing flex layout handles alignment automatically.
<context-menu> <p data-trigger>Right-click here</p> <menu> <li><button><icon-wc name="scissors"></icon-wc> Cut</button></li> <li><button><icon-wc name="copy"></icon-wc> Copy</button></li> <li><button><icon-wc name="clipboard"></icon-wc> Paste</button></li> </menu></context-menu>
Keyboard Shortcuts
Add data-shortcut to any button to display a keyboard shortcut badge and bind a real global keyboard shortcut. Pressing the shortcut anywhere on the page triggers the button's click. The format is platform-aware — it shows ⌘ symbols on Mac and Ctrl text on other platforms. Shortcuts are automatically cleaned up when the component disconnects.
<menu> <li><button data-shortcut="meta+x"><icon-wc name="scissors"></icon-wc> Cut</button></li> <li><button data-shortcut="meta+c"><icon-wc name="copy"></icon-wc> Copy</button></li> <li><button data-shortcut="meta+v"><icon-wc name="clipboard"></icon-wc> Paste</button></li> <li role="separator"></li> <li><button data-shortcut="meta+a">Select All</button></li></menu>
Group Labels
Use <li data-group> to create labeled sections within the menu. Group labels are non-interactive and visually separated from items. Non-first groups automatically get a top border.
<menu> <li data-group>Edit</li> <li><button><icon-wc name="scissors"></icon-wc> Cut</button></li> <li><button><icon-wc name="copy"></icon-wc> Copy</button></li> <li data-group>View</li> <li><button><icon-wc name="zoom-in"></icon-wc> Zoom In</button></li> <li><button><icon-wc name="zoom-out"></icon-wc> Zoom Out</button></li></menu>
Keyboard Navigation
| Key | Action |
|---|---|
| Arrow Down | Move to next item |
| Arrow Up | Move to previous item |
| Home | Move to first item |
| End | Move to last item |
| Enter / Space | Activate focused item |
| Escape | Close menu |
JavaScript API
Methods
| Method | Description |
|---|---|
close() |
Close the context menu |
Events
| Event | Description |
|---|---|
context-menu:open |
Fired when the menu opens |
context-menu:close |
Fired when the menu closes |
context-menu:select |
Fired when an item is selected (detail.item) |
const menu = document.querySelector('context-menu'); menu.addEventListener('context-menu:select', (e) => { console.log('Selected:', e.detail.item);}); menu.addEventListener('context-menu:open', () => { console.log('Menu opened');});
Accessibility
- Full keyboard navigation (Arrow keys, Home/End, Enter, Escape)
- Menu items have
role="menuitem" - Separators have
role="separator" - Closes on click outside, Escape, or scroll
- Menu is positioned within viewport bounds