HyContextMenu
Usage examples on this page are written for Lit / plain HTML (
<hy-context-menu>). The same component ships asHyContextMenuin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A right-click (context) menu. Listens for contextmenu on a target element — either slotted via the target slot or selected via the target CSS selector — and opens an hy-menu anchored to the pointer coordinates.
The anchor is a 1×1 invisible element positioned with position: fixed at the click point; hy-popover then lays the panel out relative to it using standard placement rules.
Slots vs. selector
The slotted target wins when both are set. Pointer-events on the slotted content are untouched — the host uses display: contents so the target stays in its natural layout position.
Rendering open
open shows the menu without a right-click — in markup, for a menu that renders open at rest, or set later. The menu is anchored at the target's start edge (its top-left corner, top-right in right-to-left text); with no target it opens at the viewport origin. show(x, y) opens at explicit coordinates. Every close — Escape, an outside click, a selection, hide() — sets open back to false.
Name
The menu is named by label, "Context menu" by default — it opens at the pointer, so there is no trigger to name it.
Disabled
When disabled, listeners stay attached but suppress opening. This lets consumers gate on app state (e.g. "no row selected") without juggling listener lifecycles.
When to use
- Shortcuts to the actions of an item people work on often: a file, a row, a canvas object.
Do
- List the same actions, in the same order, as the item's visible menu.
When not to use
- The only way to reach an action: put it in a visible
hy-menu-buttonorhy-toolbartoo. Right-click is a shortcut nobody sees, and touch screens barely have it. - A main action, or one people must find on their own: a visible
hy-button. - Picking a value for a form:
hy-selectorhy-combobox. - Moving between pages:
hy-sidebarorhy-tab-nav.
Accessibility: your part
- Open the menu from the keyboard too: on the Menu key or Shift+F10, call
show(x, y)with the focused element's position.
Examples
Right-click menu on slotted content
<hy-context-menu>
<div slot="target">Right-click anywhere in this box</div>
<hy-menu-item value="cut" label="Cut" shortcut="⌘X"></hy-menu-item>
<hy-menu-item value="copy" label="Copy" shortcut="⌘C"></hy-menu-item>
<hy-menu-item value="paste" label="Paste" shortcut="⌘V"></hy-menu-item>
<hy-divider></hy-divider>
<hy-menu-item value="delete" label="Delete" variant="danger"></hy-menu-item>
</hy-context-menu>
<script>
document.querySelector('hy-context-menu').addEventListener('select', (e) => {
console.log(e.detail.value, e.detail.x, e.detail.y);
});
</script>Rendered open at rest
<hy-context-menu open>
<div slot="target">File row</div>
<hy-menu-item value="rename" label="Rename"></hy-menu-item>
<hy-menu-item value="delete" label="Delete" variant="danger"></hy-menu-item>
</hy-context-menu>Selector-based target (listens on every match)
<ul id="results">
<li class="row">Row one</li>
<li class="row">Row two</li>
</ul>
<hy-context-menu target="#results .row">
<hy-menu-item value="open" label="Open"></hy-menu-item>
<hy-menu-item value="rename" label="Rename"></hy-menu-item>
</hy-context-menu>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
target | target | string | '' | CSS selector for the target element (fallback when the target slot is empty). |
open | open | boolean | false | Whether the menu is open. Set it to show the menu anchored at the target's start edge (see "Rendering open"); a right-click, show(x, y) and every close keep it in sync. |
disabled | disabled | boolean | false | Suppresses opening without removing listeners. |
label | label | string | 'Context menu' | The menu's accessible name. A context menu has no trigger to be named by (it opens at the pointer), so it carries its own; name what it acts on ("File actions") when the page has several. |
actions | — | MenuAction[] | [] | Data-driven items; rendered only when the default slot is empty. |
Events
| Event | Detail | Description |
|---|---|---|
select | — | { value, item, x, y, target } — adds pointer origin and the triggering element to the standard menu select detail. target is null for programmatic show(x, y) calls. |
show | — | Relayed from the underlying menu (does NOT bubble). Detail: { source: 'programmatic' }. |
hide | — | Relayed from the underlying menu (does NOT bubble). Detail: { source } — escape-key when Escape dismissed the menu, backdrop-click for an outside click, programmatic otherwise. Mirrors the React onHide derivation. |
Slots
| Slot | Description |
|---|---|
target | The element to listen on. |
default | hy-menu-item / checkable variants / groups / dividers. |
Methods
show()
Programmatically open the menu at the given viewport coordinates.
When contextTarget is provided it becomes the target field of the next select event detail — useful when opening the menu from custom pointer handlers that already know the row/node the user acted on.