Right-click / long-press / Shift+F10 menu. Same visual recipe as
DropdownMenu — the only differences are the trigger surface
(contextmenu event on a wrapped region rather than a button)
and the anchoring (cursor position rather than trigger box). 14 parts,
3 semantic events, full Items / CheckboxItem / RadioGroup / Sub-menu
parity with the dropdown family.
trace
{#if trace.length === 0}
right-click the area to summon the menu
{:else}
{#each trace.slice(0, 3) as entry}
{entry.event} · {entry.family}{entry.intent ? ' · ' + entry.intent : ''}{fmtTime(entry.at)}
{/each}
{/if}
open {String(open)}
{#if lastSelected}
last {lastSelected}
{/if}
{#if tab === 'live'}
Controls
ContextMenu is a pure pass-through over soma;
the eidos layer adds no evaluative props. Knobs are grouped by the
layer that owns the prop, plus a composition group for parts
toggled in / out of the markup (per the composition-over-visibility
norm). Semantic events live in the { e.preventDefault(); tab = 'sema'; }}>Sema tab.
soma Provider props
soma Content props
· floating layer · cursor-anchored so side/align act as a bias hint
soma Item props
· applied to the Delete item below
Composition
· toggle parts in / out of the markup (no visibility props)
Bound state
· mirrors of `bind:checked` / `bind:value` from the live menu items
Demo content
· literal labels rendered into the menu
eidosvisual · pure pass-through (no extra props at the visual layer)svelte
{eidosSnippet}
{/if}
{#if tab === 'api'}
API reference
14 parts, all forwarded verbatim from soma — eidos adds no
evaluative props. Item-family parts (Item / CheckboxItem /
RadioItem / SubTrigger) share id, disabled,
textValue, closeOnSelect; the other props
are listed per part below.
ContextMenu (Provider)
Prop
Type
Default
Description
id
string
auto
Stable identifier. Used to wire aria-labelledby / aria-controls.
open bindable
boolean
false
Whether the menu is open.
onOpenChange
(open: boolean) => void
—
Callback on open state change.
onOpenChangeComplete
(open: boolean) => void
—
Fires after the open/close animation settles.
dir
'ltr' | 'rtl'
'ltr'
Direction used by keyboard navigation in horizontal sub-menus.
Trigger
Prop
Type
Default
Description
id
string
auto
—
disabled
boolean
false
Disable opening. contextmenu bubbles to default browser menu.
Content
Prop
Type
Default
Description
forceMount
boolean
false
Keep in DOM when closed (CSS transitions).
side
'top' | 'right' | 'bottom' | 'left'
'bottom'
Preferred side relative to the anchor (cursor on open).
sideOffset
number
0
Pixels between content and anchor on the main axis.
align
'start' | 'center' | 'end'
'start'
Cross-axis alignment.
alignOffset
number
0
Pixels along the cross axis.
arrowPadding
number
0
Distance from the panel corner allowed for the Arrow.
avoidCollisions
boolean
true
Flip / shift when the preferred placement clips the viewport.
collisionBoundary
Element | Element[]
viewport
Boundary the floating math respects.
collisionPadding
number | Partial<Record<Side, number>>
0
Inner inset from the boundary edges.
sticky
'partial' | 'always'
'partial'
How the panel sticks while the anchor scrolls.
hideWhenDetached
boolean
true
Hide if anchor scrolls fully out of view.
updatePositionStrategy
'optimized' | 'always'
'optimized'
How often the floating math recomputes.
strategy
'fixed' | 'absolute'
'fixed'
CSS positioning strategy.
loop
boolean
false
ArrowDown / ArrowUp wrap at boundaries.
trapFocus
boolean
true
Tab cycles inside Content.
preventScroll
boolean
false
Body scroll lock. Context menus do NOT lock by default.
Wraps a logical block. aria-labelledby wires to GroupHeading.
GroupHeading
id
Non-interactive caption above grouped items.
Separator
id
role='separator', aria-orientation='horizontal'.
Arrow
width, height
Optional SVG pointer rendered inside Content.
Reference parity
Feature
Radix
bits-ui
ark-ui
Eidos (this)
Right-click + long-press
✓
✓
✓
✓
Shift+F10 keyboard summon
✓
✓
✓
✓
Cursor-anchored positioning
✓
✓
✓
✓
CheckboxItem / RadioGroup / RadioItem
✓
✓
✓
✓
Nested Sub menus
✓
✓
✓
✓
Group / GroupHeading
✓
✓
✓
✓
Arrow part
✓
✓
—
✓
closeOnSelect per item
✓
✓
—
✓
Typeahead search
✓
✓
✓
✓
commit-select semantic event
—
—
—
✓
{/if}
{#if tab === 'morfo'}
morfo
· declarative contract
14 parts + 3 events. open / close emit on
Content (family emerge); commit-select
emits on Item with intent affirm (semantic sound from
the `commit` family base). Source: src/uix/morfo/components/context-menu.ts.
open / close fire pre the state
flip (so sema's perceptual signal precedes the DOM mutation),
commit-select fires post activation with
static intent='affirm'. Play any signal from the { e.preventDefault(); tab = 'sema'; }}>Sema tab.
name
family
verb
sequence
intent
target
prewrite
commit
{#each events as action (action.name)}
{@const sem = action.semantic}
{@const intentDecl = 'intent' in sem ? sem.intent : undefined}
{@const intentStr = typeof intentDecl === 'string' ? intentDecl : intentDecl ? `fromProp:${(intentDecl as { fromProp?: string }).fromProp ?? '?'}` : '—'}
Three events. emerge·open and emerge·close
share the floating-overlay perceptual signature with DropdownMenu /
Popover / Tooltip; commit·select with intent='affirm'
inherits the affirmative-commit signature. Press play
to fire the signal on the live menu — open the menu first so the
Content / Item targets exist in the DOM.
Source: src/uix/eidos/components/context-menu/context-menu.css.
Visually identical to DropdownMenu — panel chrome, item rows,
indicator slots and submenu chevrons share the same vocabulary. The
only diverging rule is the Trigger: it renders inert by default and
gets a subtle dashed outline when data-state='open'
(courtesy affordance — "the menu came from this region"). All
selectors target morfo-emitted markers — eidos owns no extra
data-attrs.
Follows the APG menu pattern.
No native ARIA pattern exists for cursor-summoned menus; the
keyboard-summoned path uses Shift+F10
per WCAG 2.1 (keyboard parity for pointer-only triggers).
Summon
Input
Effect
Right-click
Open the menu at cursor position.
Ctrl+Click (macOS)
Same as right-click.
Long-press (touch)
Same after the platform's long-press delay.
Shift+F10
Open the menu via keyboard, anchored at the focused trigger.
ContextMenu key
Same (Windows / Linux keyboards).
Inside the menu
Key
Action
ArrowDown / ArrowUp
Move focus to next / previous item.
Home / End
First / last item.
Enter / Space
Activate the focused item.
Escape
Close the menu; return focus to the trigger.
ArrowRight on SubTrigger
Open the sub-menu (or ArrowLeft in RTL).
ArrowLeft inside SubContent
Close sub-menu, return to parent (or ArrowRight in RTL).
Typeahead
Letters jump to the first item starting with that prefix (uses textValue when set).