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.
<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.
labelnames 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
| Prop | Type | Default | Description |
|---|---|---|---|
items | HabMenuItem[] | [] | The same items as HabMenu: commands, dividers, choices, submenus, panels. |
label | string | undefined | Accessible name for the menu — what it acts on ("Build greeting"). |
open | boolean | false | Whether the menu is showing, for v-model:open. The consumer opens it; choosing an item or dismissing it closes it. |
x | number | 0 | Where it opens, in viewport pixels — the pointer's clientX. Its top-left corner sits there. |
y | number | 0 | The pointer's clientY. See x. |
Events
| Event | Payload | Description |
|---|---|---|
update:open | open: boolean | — |