Overlays
Context Menu A menu that appears at the cursor position on right-click, offering context-specific actions.
npm pnpm yarn bun
npm install @morphos/overlays pnpm add @morphos/overlays yarn add @morphos/overlays bun add @morphos/overlays
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
} from '@morphos/overlays'
@ Component ()
class MyComponent extends StatefulComponent {
@ State () contextMenu = new ContextMenu ()
render () {
return (
<>
< ContextMenuTrigger contextMenu = { this .contextMenu}>
Right-click anywhere in this area
</ ContextMenuTrigger >
< ContextMenuContent contextMenu = { this .contextMenu}>
< ContextMenuItem contextMenu = { this .contextMenu} label = "Copy" value = "copy" onSelect = {() => console. log ( 'copy' )} />
< ContextMenuItem contextMenu = { this .contextMenu} label = "Paste" value = "paste" onSelect = {() => console. log ( 'paste' )} />
< ContextMenuItem contextMenu = { this .contextMenu} label = "Delete" value = "delete" disabled />
</ ContextMenuContent >
</>
)
}
}
Component Description ContextMenuRoot state manager. Tracks open state and the cursor coordinates captured on contextmenu. ContextMenuTrigger<div> that listens for the native contextmenu event, prevents the default browser menu, and opens the menu at the cursor. Sets data-open.ContextMenuContent<ul role="menu"> rendered into a Portal, positioned with position: fixed at the captured coordinates. Closes on outside click or Escape.ContextMenuItem<li role="menuitem">. Selectable via click or Enter/Space.
Prop Type Default Description onOpenChange(open: boolean) => void— Called when the menu opens or closes. childrenChildren— Content — typically ContextMenuTrigger and ContextMenuContent.
Method Description open()Opens the context menu. Emits onOpenChange(true). close()Closes the context menu. Emits onOpenChange(false). setPosition(x, y)Sets the cursor coordinates used to position the menu. Called internally by ContextMenuTrigger's contextmenu handler.
Unlike the other overlays in this package, ContextMenu has no open / defaultOpen props —
it is always uncontrolled, since it is driven entirely by the browser's native contextmenu
event rather than a click on a fixed trigger element.
Prop Type Default Description contextMenuContextMenu— The ContextMenu instance this trigger controls. childrenChildren— The trigger area content. classstring— CSS class. idstring— HTML id.
Prop Type Default Description contextMenuContextMenu— The ContextMenu instance this content belongs to. childrenChildren— ContextMenuItem elements.classstring— CSS class. idstring— HTML id. aria-labelstring— Accessible label for the menu.
Prop Type Default Description contextMenuContextMenu— The ContextMenu instance this item belongs to. valuestring— Unique value identifier. labelstring— Display text, used when no children are passed. disabledbooleanfalseDisables the item. onSelect() => void— Called when the item is selected. childrenChildren— Item content. Falls back to label if omitted. classstring— CSS class. idstring— HTML id.
ContextMenuContent is rendered with position: fixed at the coordinates captured on the most
recent contextmenu event, read from the internal _x / _y state on the ContextMenu
instance. Unlike Dropdown, Popover, Tooltip, and PreviewCard, ContextMenu does not use
computeAnchorPosition() from @morphos/core — there is no anchor element to measure, only a
cursor position.
Attribute Element When present data-openContextMenuTriggerMenu is open data-openContextMenuContent rootMenu is open data-disabledContextMenuItemdisabled is true
ContextMenuContent renders with role="menu" and each ContextMenuItem renders with
role="menuitem". The menu closes automatically when the user clicks outside, presses
Escape, or selects an item.
.morphos-context-menu-content {
z-index : 100 ;
min-width : 10 rem ;
padding : var ( --morphos-space-1 );
list-style : none ;
border : 1 px solid var ( --morphos-color-border );
border-radius : var ( --morphos-radius-md );
}
.morphos-context-menu-item [ data-disabled ] {
opacity : 0.5 ;
cursor : not-allowed ;
}