// Generated by scripts/generate-showcase.mjs. Do not edit directly.
page ContextMenuDetail {
layout = "showcase"
state playground_items = JSON.parse(ctx.url.searchParams.get("pg_items") ?? "[{\"label\":\"Open dashboard\",\"description\":\"View the operational workspace\",\"value\":\"dashboard\",\"icon\":\"icon-[lucide--layout-dashboard]\"},{\"label\":\"Share record\",\"value\":\"share\",\"icon\":\"icon-[lucide--share-2]\",\"shortcut\":\"Ctrl S\"},{\"type\":\"divider\"},{\"label\":\"Delete record\",\"value\":\"delete\",\"icon\":\"icon-[lucide--trash-2]\",\"danger\":true}]")
state playground_open = (ctx.url.searchParams.get("pg_open") ?? "false") === "true"
state playground_defaultOpen = (ctx.url.searchParams.get("pg_defaultOpen") ?? "false") === "true"
state playground_trigger = ctx.url.searchParams.get("pg_trigger") ?? "click"
state playground_placement = ctx.url.searchParams.get("pg_placement") ?? "pointer"
state playground_align = ctx.url.searchParams.get("pg_align") ?? "start"
state playground_size = ctx.url.searchParams.get("pg_size") ?? "default"
state playground_color = ctx.url.searchParams.get("pg_color") ?? "primary"
state playground_variant = ctx.url.searchParams.get("pg_variant") ?? "raised"
state playground_title = ctx.url.searchParams.get("pg_title") ?? "Context Menu example"
state playground_description = ctx.url.searchParams.get("pg_description") ?? "A polished default context menu for a modern application."
state playground_label = ctx.url.searchParams.get("pg_label") ?? "Context Menu"
state playground_closeOnSelect = (ctx.url.searchParams.get("pg_closeOnSelect") ?? "true") === "true"
state playground_closeOnOutside = (ctx.url.searchParams.get("pg_closeOnOutside") ?? "true") === "true"
state playground_disabled = (ctx.url.searchParams.get("pg_disabled") ?? "false") === "true"
state playground_minWidth = ctx.url.searchParams.get("pg_minWidth") ?? "14rem"
state playground_maxWidth = ctx.url.searchParams.get("pg_maxWidth") ?? "20rem"
state playground_class = ctx.url.searchParams.get("pg_class") ?? "showcase-instance showcase-instance--1"
seo {
title = "Context Menu"
description = "Open an accessible keyboard-aware action menu from pointer or keyboard context interactions."
}
view {
Interactive playgroundConfigure Context Menu
Change any prop and inspect the server-rendered component immediately.
Live preview
Right-click for contextual actions
<ContextMenu
items='[
{
"id": "context-menu-0-1",
"key": "context-menu-0-1",
"value": "primary",
"label": "Primary workflow",
"title": "Primary workflow",
"description": "A clean default configuration for everyday product interfaces.",
"text": "A configurable sample message.",
"href": "#context-menu-demo",
"actionHref": "#context-menu-demo",
"actionLabel": "View details",
"icon": "icon-[lucide--sparkles]",
"iconClass": "icon-[lucide--sparkles]",
"variant": "primary",
"status": "Active",
"time": "09:30",
"current": true,
"selected": true,
"checked": true,
"disabled": false,
"outgoing": false,
"open": true,
"number": 1,
"count": 16,
"percentage": 72,
"color": "#7c3aed",
"target": "_self",
"ariaLabel": "Open primary workflow 1",
"items": [
{
"label": "Nested option A",
"value": "nested-a"
},
{
"label": "Nested option B",
"value": "nested-b"
}
],
"links": [
{
"label": "Documentation",
"href": "#documentation"
},
{
"label": "API reference",
"href": "#api-reference"
}
],
"values": [
"Included",
"Standard"
]
},
{
"id": "context-menu-0-2",
"key": "context-menu-0-2",
"value": "secondary",
"label": "Additional option",
"title": "Supporting example",
"description": "A clean default configuration for everyday product interfaces.",
"text": "Another configurable message.",
"href": "#context-menu-demo",
"actionHref": "#context-menu-demo",
"actionLabel": "View details",
"icon": "icon-[lucide--sparkles]",
"iconClass": "icon-[lucide--sparkles]",
"variant": "primary",
"status": "Active",
"time": "09:30",
"current": false,
"selected": false,
"checked": false,
"disabled": false,
"outgoing": true,
"open": true,
"number": 2,
"count": 32,
"percentage": 72,
"color": "#7c3aed",
"target": "_self",
"ariaLabel": "Open primary workflow 2",
"items": [
{
"label": "Nested option A",
"value": "nested-a"
},
{
"label": "Nested option B",
"value": "nested-b"
}
],
"links": [
{
"label": "Documentation",
"href": "#documentation"
},
{
"label": "API reference",
"href": "#api-reference"
}
],
"values": [
"Included",
"Standard"
]
}
]'
title="Context Menu example"
description="A polished default context menu for a modern application."
label="Context Menu">
<div data-slot="trigger">
<div class="showcase-slot">trigger slot</div>
</div>
<div data-slot="header">
<div class="showcase-slot">header slot</div>
</div>
<div data-slot="footer">
<div class="showcase-slot">footer slot</div>
</div>
</ContextMenu>
Event outputInteract with the preview to inspect event.detail.
Live examplesDesigned for real product surfaces
Compare configurations and resize the browser to check responsive behavior.
<ContextMenu
items='[
{
"label": "Open dashboard",
"description": "View the operational workspace",
"value": "dashboard",
"icon": "icon-[lucide--layout-dashboard]"
},
{
"label": "Share record",
"value": "share",
"icon": "icon-[lucide--share-2]",
"shortcut": "Ctrl S"
},
{
"type": "divider"
},
{
"label": "Delete record",
"value": "delete",
"icon": "icon-[lucide--trash-2]",
"danger": true
}
]'
title="Record actions"
description="Right-click the target surface"
label="Context Menu">
<div data-slot="trigger">
<div class="showcase-context-target">Right-click for contextual actions</div>
</div>
<div data-slot="header">
<div class="showcase-slot">header slot</div>
</div>
<div data-slot="footer">
<div class="showcase-slot">footer slot</div>
</div>
</ContextMenu>
<ContextMenu
items='[
{
"label": "Open dashboard",
"description": "View the operational workspace",
"value": "dashboard",
"icon": "icon-[lucide--layout-dashboard]"
},
{
"label": "Share record",
"value": "share",
"icon": "icon-[lucide--share-2]",
"shortcut": "Ctrl S"
},
{
"type": "divider"
},
{
"label": "Delete record",
"value": "delete",
"icon": "icon-[lucide--trash-2]",
"danger": true
}
]'
trigger="click"
align="center"
size="sm"
variant="secondary"
title="Quick actions"
description="A compact configuration for dashboards and dense product surfaces."
label="Compact example"
minWidth="12rem">
<div data-slot="trigger">
<button type="button" class="showcase-action">Open quick actions</button>
</div>
<div data-slot="header">
<div class="showcase-slot">header slot</div>
</div>
<div data-slot="footer">
<div class="showcase-slot">footer slot</div>
</div>
</ContextMenu>
<ContextMenu
items='[
{
"label": "Open dashboard",
"description": "View the operational workspace",
"value": "dashboard",
"icon": "icon-[lucide--layout-dashboard]"
},
{
"label": "Share record",
"value": "share",
"icon": "icon-[lucide--share-2]",
"shortcut": "Ctrl S"
},
{
"type": "divider"
},
{
"label": "Delete record",
"value": "delete",
"icon": "icon-[lucide--trash-2]",
"danger": true
}
]'
trigger="both"
placement="bottom-start"
align="end"
size="lg"
variant="soft"
title="Accessible actions"
description="A richer configuration demonstrating additional content and hierarchy."
label="Advanced example">
<div data-slot="trigger">
<button type="button" class="showcase-action">Click, press Enter, or right-click</button>
</div>
<div data-slot="header">
<div class="showcase-slot">header slot</div>
</div>
<div data-slot="footer">
<div class="showcase-slot">footer slot</div>
</div>
</ContextMenu>
Component eventsRespond to every public interaction
Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.
@openFires after the component opens.
@closeFires after the component closes.
@selectFires when an item, option, card, or result is selected.
@actionFires when the component's primary or item action is activated.
<ContextMenu
@open='console.log(event.detail)'
@close='console.log(event.detail)'
@select='console.log(event.detail)'
@action='console.log(event.detail)'
/>
const component = document.querySelector("[data-ui-component=\"ContextMenu\"], [data-component=\"ContextMenu\"]")
component?.addEventListener("open", (event) => {
console.log("open", event.detail)
})
component?.addEventListener("close", (event) => {
console.log("close", event.detail)
})
component?.addEventListener("select", (event) => {
console.log("select", event.detail)
})
component?.addEventListener("action", (event) => {
console.log("action", event.detail)
})
Component APIProps and configuration
All content and behavior shown above is supplied through these props and slots.
| Prop | Type | Default | Required |
|---|
items | string | [] | No |
open | boolean | false | No |
defaultOpen | boolean | false | No |
trigger | string | "contextmenu" | No |
placement | string | "pointer" | No |
align | string | "start" | No |
size | string | "default" | No |
color | string | "primary" | No |
variant | string | "raised" | No |
title | string | "" | No |
description | string | "" | No |
label | string | "Context menu" | No |
closeOnSelect | boolean | true | No |
closeOnOutside | boolean | true | No |
disabled | boolean | false | No |
minWidth | string | "14rem" | No |
maxWidth | string | "20rem" | No |
class | string | "" | No |
}
}