ContextMenu
ContextMenu provides a context-sensitive menu that appears at a specific position when opened programmatically via its openAt() API. Unlike DropdownMenu, it has no trigger button and is typically used with onContextMenu events to create right-click menus or custom context-aware action menus. The menu automatically positions itself within the viewport and closes when clicking outside or when a menu item is selected.
Key features:
- Programmatic control: Opens at specific coordinates via the
openAt()API - Context-aware data: Pass context information that's available to menu items via
$context - No trigger button: Unlike
DropdownMenu,ContextMenuhas no built-in trigger and is typically used withonContextMenuevents - Automatic positioning: Positions itself within the viewport and prevents default browser context menus
You can nest MenuItem, MenuSeparator, and SubMenuItem components into ContextMenu to define a menu hierarchy. The menu is opened programmatically using the openAt() method:
<App>
<Items data="{['Main.xmlui', 'MyComp.xmlui', 'AnotherComp.xmlui']}">
<Card
title="File: {$item}"
onContextMenu="ev => contextMenu.openAt(ev, { file: $item })"
/>
</Items>
<ContextMenu id="contextMenu" menuWidth="200px">
<MenuItem onClick="toast.success('Renamed ' + $context.file)">
Rename {$context.file}
</MenuItem>
<MenuItem onClick="toast.success('Copied ' + $context.file)">
Copy {$context.file}
</MenuItem>
<MenuSeparator />
<MenuItem onClick="toast.success('Deleted ' + $context.file)">
Delete {$context.file}
</MenuItem>
</ContextMenu>
</App>Try right-clicking the cards to see the context menu:
<App>
<Items data="{['Main.xmlui', 'MyComp.xmlui', 'AnotherComp.xmlui']}">
<Card
title="File: {$item}"
onContextMenu="ev => contextMenu.openAt(ev, { file: $item })"
/>
</Items>
<ContextMenu id="contextMenu" menuWidth="200px">
<MenuItem onClick="toast.success('Renamed ' + $context.file)">
Rename {$context.file}
</MenuItem>
<MenuItem onClick="toast.success('Copied ' + $context.file)">
Copy {$context.file}
</MenuItem>
<MenuSeparator />
<MenuItem onClick="toast.success('Deleted ' + $context.file)">
Delete {$context.file}
</MenuItem>
</ContextMenu>
</App>Try right-clicking the cards to see the context menu:
Context variables available during execution:
$context: Contains the context data passed to theopenAt()method. This allows menu items to access information about the element or data that triggered the context menu.
Behaviors
This component supports the following behaviors:
| Behavior | Properties |
|---|---|
| Animation | animation, animationOptions |
| Bookmark | bookmark, bookmarkLevel, bookmarkTitle, bookmarkOmitFromToc |
| Component Label | label, labelPosition, labelWidth, labelBreak, required, enabled, shrinkToLabel, style, readOnly |
| Publish/Subscribe | subscribeToTopic |
| Tooltip | tooltip, tooltipMarkdown, tooltipOptions |
| Styling Variant | variant |
Properties
menuWidth
Sets the width of the context menu.
Events
This component does not have any events.
Exposed Methods
close
This method closes the context menu.
Signature: close(): void
openAt
This method opens the context menu at the specified event position (e.g., mouse click coordinates). Optionally, you can pass a context object that will be available within the menu as $context. The method automatically prevents the browser's default context menu from appearing.
Signature: openAt(event: MouseEvent, context?: any): void
Parts
The component has some parts that can be styled through layout properties and theme variables separately:
content: The content area of the ContextMenu where menu items are displayed.
Styling
Theme Variables
| Variable | Default Value (Light) | Default Value (Dark) |
|---|---|---|
| backgroundColor-ContextMenu | $color-surface-raised | $color-surface-raised |
| borderColor-ContextMenu-content | none | none |
| borderRadius-ContextMenu | $borderRadius | $borderRadius |
| borderStyle-ContextMenu-content | solid | solid |
| borderWidth-ContextMenu-content | none | none |
| boxShadow-ContextMenu | $boxShadow-xl | $boxShadow-xl |
| minWidth-ContextMenu | 160px | 160px |