Skip to content

HabContextMenu ​

A menu that opens at a point — where something was right-clicked — instead of under a button. Its rows are HabMenu's, so the two read and behave as one menu.

Build greeting
Locked card
Right-click a card: the menu opens where you clicked. Its colour entry is a panel — a sheet holding a colour grid, and picking a colour closes the menu.
vue
<HabContextMenu v-model:open="menu.open" :x="menu.x" :y="menu.y" :items="items" :label="nodeName">
	<template #panel-colour="{ close }">
		<HabColorGrid v-model="colour" label="Node colour" @update:model-value="close" />
	</template>
</HabContextMenu>

Opening it ​

The consumer opens it, from its own contextmenu handler: set x and y from the event's clientX/clientY, then open. Choosing an item, Escape or a click outside closes it and emits update:open. It does not open with an empty items.

It is controlled on purpose. A canvas suppresses the browser's own menu everywhere and offers this one only on a node, with items that depend on which node — so the decision of when and where belongs to the consumer, not to a wrapper around a region.

Items ​

The same items as HabMenu: icons, meta, dividers, single choices, submenus, disabled with a description saying why, and an error tone for destructive commands — last, after a divider.

Panels ​

An item with panel: "<name>" opens a submenu whose sheet is the panel-<name> slot instead of rows — for a choice that is not a list, like a colour grid. HabMenu takes the same slots.

A panel's content is not a menu item, so choosing something in it does not close the menu by itself. The slot receives close, which closes the whole menu — call it from whatever in the panel commits the choice, as the colour grid above does on a pick. Here, where the menu is controlled, close emits update:open with false, exactly as choosing an item does; your v-model:open does the rest.

The panel's keys belong to its content, as on HabMenu: Left and Right Arrow reach what is in it, Tab cycles through its own stops, Escape closes.

An item is a submenu of rows (items) or a panel (panel), never both — the item type refuses the pair, and one that arrives anyway from untyped code shows its panel and warns.

Accessibility ​

  • It is reka's DropdownMenu: focus moves into the menu, arrows move between rows, typing jumps to a row, Escape closes, submenus open on Right Arrow.
  • label names the menu — say what it acts on.
  • Focus is not returned to the anchor, which is an invisible point. Move it back to what was right-clicked, if that is focusable.
  • Right-click is not the only way in: offer the same commands somewhere reachable by keyboard (a ⋯ button, a shortcut).

API ​

Props ​

PropTypeDefaultDescription
itemsHabMenuItem[][]The same items as HabMenu: commands, dividers, choices, submenus, panels.
labelstringundefinedAccessible name for the menu — what it acts on ("Build greeting").
openbooleanfalseWhether the menu is showing, for v-model:open. The consumer opens it; choosing an item or dismissing it closes it.
xnumber0Where it opens, in viewport pixels — the pointer's clientX. Its top-left corner sits there.
ynumber0The pointer's clientY. See x.

Events ​

EventPayloadDescription
update:openopen: boolean—

Proprietary — internal use only.