Headless Core — Context Menu
Powers Context Menu internally. Like
Dropdown, it’s built on
createMenuSelection for its
selectItem action — the difference is where the panel opens: at the pointer
position from a right-click, not anchored to a trigger element.
import { createContextMenu } from '@andersseen/headless-components/context-menu';
const ctx = createContextMenu({ closeOnSelect: true, onOpenChange: open => console.log('Open:', open), onPosition: pos => console.log('Position:', pos),});
el.addEventListener('contextmenu', e => ctx.handleContextMenu(e));document.addEventListener('keydown', e => ctx.handleKeyDown(e));Config
Section titled “Config”| Option | Type | Default | Notes |
|---|---|---|---|
onOpenChange | (isOpen: boolean) => void | — | |
onPosition | (position: { x: number; y: number }) => void | — | Fires every time open() runs (initial open or reposition). |
closeOnSelect | boolean | true | Forwarded to createMenuSelection. |
onSelect | (e: { itemId?: string }) => void | — | Forwarded to createMenuSelection. |
isOpen, position: { x, y }.
Actions
Section titled “Actions”open(position?) (re-uses the last position if you omit one), close(),
selectItem(itemId?) — no queries bucket; read ctx.state.isOpen directly.
Prop-getters & handlers
Section titled “Prop-getters & handlers”| Getter | Returns |
|---|---|
getTriggerProps() | data-state |
getPanelProps(label?) | role: 'menu', aria-label (defaults to 'Context menu'), data-state, hidden |
handleContextMenu(event, triggerRect?) — call this from your element’s native
contextmenu listener. It always calls event.preventDefault() (so the
browser’s own right-click menu never shows), then computes the open position:
event.clientX/clientY directly, or relative to triggerRect if you pass the
trigger’s getBoundingClientRect() (useful for a panel positioned with
position: absolute inside the trigger rather than position: fixed at the
viewport level). handleKeyDown(event) closes on Escape — attach it at the
document level, since a right-click doesn’t necessarily move focus onto the
panel.
Live example
Section titled “Live example”Right-click anywhere in the box below:
Next steps
Section titled “Next steps”Dropdown — the trigger-anchored counterpart to this pointer-anchored menu.