ContextMenu
A menu at the pointer on right-click or long-press.
Browser menu
Right-click the area, or long-press it on touch. Inset rows line up with checkbox and radio rows.
Code
<ContextMenu>
<div slot="trigger" class="area">Right click here</div>
<ContextMenuItem inset>Back <ContextMenuShortcut>⌘[</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem inset disabled>Forward <ContextMenuShortcut>⌘]</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem inset>Reload <ContextMenuShortcut>⌘R</ContextMenuShortcut></ContextMenuItem>
<ContextMenuSub inset label="More Tools">
<ContextMenuItem>Save Page As... <ContextMenuShortcut>⇧⌘S</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem>Create Shortcut...</ContextMenuItem>
<ContextMenuItem>Name Window...</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>Developer Tools</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuCheckboxItem checked={view.bookmarks}>Show Bookmarks</ContextMenuCheckboxItem>
<ContextMenuCheckboxItem checked={view.urls}>Show Full URLs</ContextMenuCheckboxItem>
<ContextMenuSeparator />
<ContextMenuRadioGroup value={view.person}>
<ContextMenuLabel inset>People</ContextMenuLabel>
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenu>Usage
import {
ContextMenu, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem,
ContextMenuLabel, ContextMenuGroup, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub,
} from "@elements/ui/context-menu";
<ContextMenu>
<div slot="trigger" class="drop-zone">Right click here</div>
<ContextMenuItem onSelect={back}>Back <ContextMenuShortcut>⌘[</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem disabled>Forward <ContextMenuShortcut>⌘]</ContextMenuShortcut></ContextMenuItem>
<ContextMenuSub label="More Tools">
<ContextMenuItem>Save Page As...</ContextMenuItem>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuCheckboxItem checked={view.bookmarks}>Show Bookmarks</ContextMenuCheckboxItem>
<ContextMenuRadioGroup value={view.person}>
<ContextMenuLabel inset>People</ContextMenuLabel>
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenu>Examples
Icons, groups and the keyboard
A focusable area opens from the keyboard too: Shift+F10 or the context menu key, at the focused element.
Code
<ContextMenu>
<button slot="trigger" class="area">Right click or Shift+F10</button>
<ContextMenuGroup>
<ContextMenuItem><Icon name="copy" /> Copy <ContextMenuShortcut>⌘C</ContextMenuShortcut></ContextMenuItem>
<ContextMenuItem><Icon name="pencil" /> Rename</ContextMenuItem>
</ContextMenuGroup>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive"><Icon name="trash" /> Delete</ContextMenuItem>
</ContextMenu>Controlled, non-modal, disabled
open is two-way. onOpenChangeComplete fires once the open or close animation has finished. modal={false} leaves the page usable. A disabled menu leaves the browser's own menu in place.
Code
<ContextMenu open={state.open}
onOpenChange={(open) => log(open)}
onOpenChangeComplete={(open) => log(open ? "open complete" : "closed complete")}
modal={false}>
<div slot="trigger" class="area">Non-modal, controlled</div>
...
</ContextMenu>
<ContextMenu disabled>
<div slot="trigger" class="area">The browser's own menu</div>
</ContextMenu>Arrow
arrow draws a pointer from the menu to the spot that was pressed.
Code
<ContextMenu arrow>
<div slot="trigger" class="area">Right click for a menu with an arrow</div>
<ContextMenuItem>Cut <ContextMenuShortcut>⌘X</ContextMenuShortcut></ContextMenuItem>
...
</ContextMenu>Sides
side places the menu around the press: top, right, bottom or left, or inline-start and inline-end that follow the direction (the default is inline-end). align and sideOffset adjust it.
Code
<ContextMenu side="top" align="center">
<div slot="trigger" class="area">Right click (top)</div>
<ContextMenuItem>Back</ContextMenuItem>
...
</ContextMenu>
<ContextMenu side="right">...</ContextMenu>
<ContextMenu side="bottom" alignOffset={-12}>...</ContextMenu>
<ContextMenu side="left" sideOffset={8}>...</ContextMenu>Filtering
An input row narrows the items as you type, with focus kept in the input. Enter chooses the highlighted row.
Code
<ContextMenu>
<div slot="trigger" class="area">Right click to insert</div>
<ContextMenuInput placeholder="Insert..." autoHighlight />
<ContextMenuList>
<ContextMenuItem>Heading</ContextMenuItem>
<ContextMenuItem>Table</ContextMenuItem>
</ContextMenuList>
<ContextMenuEmpty>Nothing to insert.</ContextMenuEmpty>
</ContextMenu>Horizontal
orientation="horizontal" lays the items in a row: ArrowLeft and ArrowRight move between them, and ArrowUp and ArrowDown do nothing.
Code
<ContextMenu orientation="horizontal">
<div slot="trigger" class="area">Right click for quick actions</div>
<ContextMenuItem>Cut</ContextMenuItem>
<ContextMenuItem>Copy</ContextMenuItem>
<ContextMenuSeparator orientation="vertical" />
<ContextMenuItem>Paste</ContextMenuItem>
</ContextMenu>Placement, backdrop and anchor
side="bottom" with sideOffset={-5} and alignOffset={2} places the menu with its top edge just above the press so the menu overlaps the pointer (the default keeps the menu's corner beside the press). backdrop dims the page under the menu. anchor opens the menu against another element instead of the press; positionMethod="absolute" and disableAnchorTracking place it once in page coordinates. A submenu with orientation="horizontal" moves with ArrowLeft and ArrowRight and closes with ArrowUp.
Code
<!-- placed with its top just above the press, overlapping it -->
<ContextMenu side="bottom" align="start" sideOffset={-5} alignOffset={2}>...</ContextMenu>
<!-- dims the page under the menu -->
<ContextMenu backdrop>...</ContextMenu>
<!-- opens against another element, placed once in page coordinates -->
<ContextMenu anchor="#preview" side="bottom" positionMethod="absolute" disableAnchorTracking>
<div slot="trigger">...</div>
<ContextMenuSub label="Align" orientation="horizontal">...</ContextMenuSub>
</ContextMenu>Right to left
Under dir=rtl the menu opens to the left of the pointer and submenus open to the left.
Code
<div dir="rtl">
<ContextMenu>
<div slot="trigger" class="area">انقر بزر الفأرة الأيمن هنا</div>
<ContextMenuItem>رجوع</ContextMenuItem>
<ContextMenuSub label="المزيد من الأدوات">...</ContextMenuSub>
</ContextMenu>
</div>