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> <div data-trigger> <p>Right-click anywhere here</p> </div> <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 Description
[data-trigger] Container where right-click is captured
<menu> The context menu with list items
role="separator" Visual divider between groups
.danger Destructive action styling (red)
[data-disabled] Greyed-out non-interactive item
[data-shortcut] Display keyboard shortcut badge AND bind a real global shortcut
<li data-group> Non-interactive section label

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> <div data-trigger> <p>Right-click here</p> </div> <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 DownMove to next item
Arrow UpMove to previous item
HomeMove to first item
EndMove to last item
Enter / SpaceActivate focused item
EscapeClose 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