Components/ContextMenu

ContextMenu

A command menu that opens at the pointer or at given coordinates.

VerifiedSince 0.3.4

Usage

Basic

Right-clicking the trigger area opens the menu; trigger="manual" with v-model, x, and y opens it at given coordinates.

Loading demo...

Anchor Mode

anchorMode="pointer" (the default) follows the pointer or the given coordinates; reference attaches to the trigger area, like a dropdown.

<TxContextMenu anchor-mode="pointer" />
<TxContextMenu anchor-mode="reference" />

TxContextMenuSubmenu nests child panels to any depth; hovering the trigger row expands one.

Loading demo...

Best Practices

  • For editor shortcuts, command palettes, canvas nodes, and other non-right-click triggers, use trigger="manual" with explicit x / y.
  • Keep anchorMode="pointer" for real context menus; use reference only to align with the whole trigger element.
  • Nest menus with TxContextMenuSubmenu. If you teleport a TxContextMenuPanel yourself, set outsideGuard on the child panel.
  • Reserve closeOnSelect=false for submenu trigger rows and multi-step actions; ordinary commands close on selection.
  • Mark destructive actions with danger; use color only for semantic colors already in the design system.

API Reference

TxContextMenu

Props

PropTypeDefaultDescription
modelValueboolean | undefinedundefinedOpen state (v-model); undefined leaves it uncontrolled.
xnumber0X coordinate for controlled or manual opening.
ynumber0Y coordinate for controlled or manual opening.
widthnumber220Menu width; 0 sizes automatically.
minWidthnumber0Minimum width.
maxWidthnumber360Maximum width; 0 means unlimited.
maxHeightnumber420Maximum height; also shrinks to the available viewport.
unlimitedHeightbooleanfalseRemoves the height limit.
disabledbooleanfalseBlocks triggering and opening.
eagerbooleanfalseMounts menu content before the first open.
trigger'contextmenu' | 'click' | 'both' | 'manual''contextmenu'Trigger mode; manual opens only through external state and coordinates.
anchorMode'pointer' | 'reference''pointer'pointer follows the pointer or given coordinates; reference follows the trigger area.
preventDefaultbooleantrueSuppresses the browser's native context menu on right-click.
placementBaseAnchorPlacement'bottom-start'Initial placement relative to the anchor point.
offsetnumber2Distance from the anchor point.
closeOnEscbooleantrueCloses on Escape.
closeOnClickOutsidebooleantrueCloses on a click outside the menu.
closeOnTriggerPointerDownbooleantrueCloses on a click in the trigger area while open; ignored for click / both.
closeOnAnyPointerDownbooleanfalseCloses on any press outside the menu, including the trigger area.
closeOnSelectbooleantrueCloses after an item is selected.
activationFeedbackbooleantrueClears, then confirms the highlight for 90 ms each before closing; skipped under reduced motion.
showArrowbooleanfalseShows an arrow pointing at the anchor point.
arrowSizenumber10Arrow size.
animationBaseAnchorAnimationOptions{}Open and close animation: transfer, boom, opacity, or none.
keepAliveContentbooleantrueKeeps content state after closing.
panelVariant'solid' | 'dashed' | 'plain''solid'Panel border style.
panelBackground'pure' | 'mask' | 'blur' | 'glass' | 'refraction''refraction'Panel background effect.
panelShadow'none' | 'soft' | 'medium''medium'Panel shadow.
panelRadiusnumber14Panel corner radius.
panelPaddingnumber6Panel padding.
panelCardBaseAnchorPanelCardProps-Visual props forwarded to the internal TxCard.

Events

EventParamsDescription
update:modelValuebooleanFires when the open state changes.
open{ x: number; y: number }Fires on open with the final coordinates.
close-Fires on close.

Slots

SlotPropsDescription
trigger-Trigger element; falls back to the default slot.
default-Trigger content when no trigger slot is given.
menu-Menu content, rendered inside the internal TxContextMenuPanel.

Exposed Methods

NameTypeDescription
openAt(target?: { x: number; y: number } | MouseEvent | PointerEvent) => voidOpens at a point or at an event's position.
openFromEvent(event: MouseEvent | PointerEvent) => voidOpens from a mouse or pointer event.
close() => voidCloses the menu.
updatePosition() => voidRecomputes the Floating UI placement.

TxContextMenuPanel

Props

PropTypeDefaultDescription
widthnumber | string-Panel width.
minWidthnumber | string-Minimum width.
maxWidthnumber | string-Maximum width.
maxHeightnumber | string-Maximum height.
closeOnSelectbooleantrueWhether child items close the panel on selection.
activationFeedbackbooleantruePre-close confirmation for child items; each item may override it.
close() => void-Close callback injected into child items.
densebooleanfalseTightens item spacing.
outsideGuardbooleanfalseMarks the panel as a menu layer, so clicks inside it aren't outside clicks.
role'menu' | 'listbox' | 'none''menu'ARIA role; menu / listbox enable keyboard navigation, none turns it off.
ariaLabelstring-Accessible name of the panel.

Slots

SlotPropsDescription
default-Items, dividers, or nested overlays.

Exposed Methods

NameTypeDescription
focusFirstItem() => voidFocuses the first enabled item; call it after opening a standalone panel.

TxContextMenuItem

Props

PropTypeDefaultDescription
disabledbooleanfalsePrevents selection.
dangerbooleanfalseDanger styling.
colorstring-Label color; CSS variables work.
shortcutstring-Shortcut hint on the right.
submenubooleanfalseShows a submenu arrow.
closeOnSelectboolean-Overrides the parent's closeOnSelect.
activationFeedbackboolean-Overrides inherited feedback; unset follows the nearest TxContextMenuPanel.

Events

EventParamsDescription
select-Fires on selection; a closing item with feedback fires after the 180 ms confirmation.

Slots

SlotPropsDescription
default-Main label.
avatar-Leading icon or avatar.
description-Secondary text.
right-Replaces the shortcut and submenu-arrow area.

TxContextMenuSubmenu

Props

PropTypeDefaultDescription
disabledbooleanfalseDisables the trigger row; the child panel no longer opens.
placementBaseAnchorPlacement'right-start'Child panel position relative to the trigger row.
offsetnumber4Distance between the trigger row and the child panel.
widthnumber0Fixed child panel width; 0 sizes to content, bounded by minWidth.
minWidthnumber160Minimum child panel width.
maxHeightnumber420Maximum child panel height.
unlimitedHeightbooleanfalseRemoves the child panel's height limit.
animationBaseAnchorAnimationOptions{}Child panel animation.
panelCardBaseAnchorPanelCardProps-Card props forwarded to the child panel.
panelVariant'solid' | 'dashed' | 'plain''solid'Child panel border style.
panelBackground'pure' | 'mask' | 'blur' | 'glass' | 'refraction''refraction'Child panel background effect.
panelShadow'none' | 'soft' | 'medium''medium'Child panel shadow.
panelRadiusnumber14Child panel corner radius.
panelPaddingnumber6Child panel padding.

Slots

SlotPropsDescription
default-Trigger row label.
right-Trailing info on the trigger row, before the arrow.
menu-Child panel content; may nest another TxContextMenuSubmenu.

TxContextMenuDivider

Props

PropTypeDefaultDescription
dashedbooleanfalseDashed separator.
insetbooleanfalseLeft inset that aligns with items that have icons.

Overview

  • Placement runs through TxBaseAnchor (Floating UI flip + shift + size), flipping, shifting, and shrinking near viewport edges.
  • In pointer mode, a repeated right-click on the same trigger moves the anchor to the latest position.
  • Escape, an outside click, and selection close by default. A closing selection first clears the highlight, confirms with the TxCardItem active state, then emits select; non-closing items emit at once.
  • Submenus inherit the root's closeOnSelect and activationFeedback, and selecting a child closes the whole chain; clicks inside a child panel aren't outside clicks.
  • A hover bridge covers the gap between parent and child panels. Sibling rows crossed on a diagonal don't expand; resting on one for about 100 ms switches to it.
  • Keyboard: arrow keys and Home / End move within a panel, counting only role="menuitem" (menu) or role="option" (listbox) children; submenus open and close from the keyboard.

Technologies

  • Activation feedback runs on packages/tuffex/packages/utils/menu-activation-feedback.ts, shared with DropdownMenu.
  • Source: packages/tuffex/packages/components/src/context-menu/.
查看源码
packages/tuffex/packages/components/src/context-menu/index.ts