@gluonjs/molecules / packages/molecules/src / ContextMenuProps
Interface: ContextMenuProps
Extends
MenuCallbacks
Properties
attributes?
readonlyoptionalattributes?:MenuNativeAttributes
children
readonlychildren:TemplateValue
id
readonlyid:string
items
readonlyitems: readonlyMenuItem[]
label
readonlylabel:string
onCheckedChange?
readonlyoptionalonCheckedChange?: (change,event) =>void
Parameters
change
event
MenuEvent
Returns
void
Inherited from
MenuCallbacks.onCheckedChange
onOpenChange
readonlyonOpenChange: (open,event) =>void
Parameters
open
boolean
event
Event
Returns
void
onSubmenuOpenChange?
readonlyoptionalonSubmenuOpenChange?: (id,open,event) =>void
Parameters
id
string
open
boolean
event
MenuEvent
Returns
void
Inherited from
MenuCallbacks.onSubmenuOpenChange
open
readonlyopen:boolean
targetAttributes?
readonlyoptionaltargetAttributes?:MenuNativeAttributes
Example
Configure a controlled pointer and keyboard context menu around native target content:
import { Button, Input, Radio } from '@gluonjs/atoms';
import { html } from '@gluonjs/core';
import {
Accordion,
ButtonGroup,
Card,
ChoiceGroup,
ControlField,
ContextMenu,
DialogSurface,
Disclosure,
ResponsiveDisclosure,
DropdownMenu,
EmptyState,
FormField,
InlineNotice,
NavigationMenu,
NavigationStrip,
SearchField,
SearchResults,
Menubar,
OneTimePasswordField,
PasswordToggleField,
SegmentedControl,
TableRegion,
Tabs,
Toolbar,
createDialogSurfaceController,
moleculeManifest,
moleculeStyles,
passwordToggleFieldStyles,
searchFieldStyles,
searchResultsStyles,
oneTimePasswordFieldStyles,
type AccordionAccessibleName,
type AccordionAttributes,
type AccordionChangeEvent,
type AccordionHeadingLevel,
type AccordionItem,
type AccordionMultipleProps,
type AccordionProps,
type AccordionSingleProps,
type ButtonGroupAccessibleName,
type ButtonGroupAttributes,
type ButtonGroupOrientation,
type ButtonGroupPresentation,
type ButtonGroupProps,
type CardProps,
type CardTone,
type ChoiceGroupAttributes,
type ChoiceGroupOrientation,
type ChoiceGroupProps,
type ControlFieldAttributes,
type ControlFieldProps,
type ControlFieldRelationships,
type ControlFieldRenderer,
type ContextMenuProps,
type DropdownMenuProps,
type DialogSurfaceAccessibleName,
type DialogSurfaceAttributes,
type DialogSurfaceController,
type DialogSurfaceControllerOptions,
type DialogSurfacePlacement,
type DialogSurfaceProps,
type DialogSurfaceSectionAttributes,
type DisclosureAttributes,
type DisclosureAvailability,
type DisclosureProps,
type DisclosureState,
type DisclosureSummaryAttributes,
type ResponsiveDisclosureAttributes,
type ResponsiveDisclosureProps,
type EmptyStateAttributes,
type EmptyStateHeadingLevel,
type EmptyStatePresentation,
type EmptyStateProps,
type FormFieldProps,
type InlineNoticeAnnouncement,
type InlineNoticeAttributes,
type InlineNoticeProps,
type InlineNoticeTone,
type NavigationMenuAttributes,
type NavigationMenuItem,
type NavigationMenuItemAttributes,
type NavigationMenuLinkAttributes,
type NavigationMenuOpenChangeEvent,
type NavigationMenuProps,
type NavigationMenuTriggerAttributes,
type NavigationStripProps,
type SearchFieldAttributes,
type SearchFieldInputAttributes,
type SearchFieldProps,
type SearchResultGroup,
type SearchResultsAttributes,
type SearchResultsHeadingLevel,
type SearchResultsProps,
type SearchResultsState,
type MenuActionItem,
type MenuAttributes,
type MenuCheckboxItem,
type MenuCheckedChange,
type MenuItem,
type MenuItemKind,
type MenuProps,
type MenuRadioItem,
type MenuSeparatorItem,
type MenubarProps,
type OneTimePasswordFieldAttributes,
type OneTimePasswordFieldInputAttributes,
type OneTimePasswordFieldMode,
type OneTimePasswordFieldProps,
type PasswordToggleFieldAttributes,
type PasswordToggleFieldInputAttributes,
type PasswordToggleFieldProps,
type SegmentedControlAccessibleName,
type SegmentedControlAttributes,
type SegmentedControlChangeEvent,
type SegmentedControlOption,
type SegmentedControlOrientation,
type SegmentedControlProps,
type TableRegionAccessibleName,
type TableRegionAttributes,
type TableRegionContent,
type TableRegionProps,
type TabsAccessibleName,
type TabsActivation,
type TabsAttributes,
type TabsChangeEvent,
type TabsItem,
type TabsOrientation,
type TabsProps,
type ToolbarButtonItem,
type ToolbarItem,
type ToolbarLinkItem,
type ToolbarProps,
type ToolbarSeparatorItem,
} from '@gluonjs/molecules';
const email = { label: 'Email', name: 'email', type: 'email', helper: 'Order updates go here.' } satisfies FormFieldProps;
const buttonGroupName = { label: 'Order actions' } satisfies ButtonGroupAccessibleName;
const buttonGroupAttributes = { class: 'order-actions' } satisfies ButtonGroupAttributes;
const buttonGroupOrientation: ButtonGroupOrientation = 'horizontal';
const buttonGroupPresentation: ButtonGroupPresentation = 'attached';
const orderActions = { ...buttonGroupName, orientation: buttonGroupOrientation, presentation: buttonGroupPresentation, attributes: buttonGroupAttributes, children: [Button({ label: 'Save' }), Button({ label: 'Share' })] } satisfies ButtonGroupProps;
const fieldAttributes = { class: 'order-reference-field' } satisfies ControlFieldAttributes;
const renderOrderReference: ControlFieldRenderer = (relationships: ControlFieldRelationships) => Input({ attributes: { id: relationships.controlId, aria: relationships.aria } });
const orderReference = { id: 'order-reference', label: 'Order reference', helper: 'Optional internal reference.', attributes: fieldAttributes, control: renderOrderReference } satisfies ControlFieldProps;
const dialogName = { labelledBy: 'archive-title' } satisfies DialogSurfaceAccessibleName;
const dialogAttributes = { class: 'archive-dialog' } satisfies DialogSurfaceAttributes;
const dialogSectionAttributes = { class: 'archive-actions' } satisfies DialogSurfaceSectionAttributes;
const dialogPlacement: DialogSurfacePlacement = 'center';
const dialogControllerOptions = { initialFocus: '[data-dialog-initial-focus]' } satisfies DialogSurfaceControllerOptions;
const dialogController: DialogSurfaceController = createDialogSurfaceController(dialogControllerOptions);
const archiveDialog = { ...dialogName, id: 'archive-dialog', title: 'Archive order?', description: 'The order remains available.', placement: dialogPlacement, controller: dialogController, attributes: dialogAttributes, footerAttributes: dialogSectionAttributes, closeAction: Button({ label: 'Close', attributes: { data: { dialogInitialFocus: true } } }), children: 'Archive this order?', footer: Button({ label: 'Archive' }), onDismiss: () => dialogController.deactivate() } satisfies DialogSurfaceProps;
const disclosureAttributes = { class: 'delivery-details' } satisfies DisclosureAttributes;
const disclosureSummaryAttributes = { class: 'delivery-summary' } satisfies DisclosureSummaryAttributes;
const disclosureState = { defaultOpen: false } satisfies DisclosureState;
const disclosureAvailability = { unavailable: false } satisfies DisclosureAvailability;
const deliveryDisclosure = { ...disclosureState, ...disclosureAvailability, id: 'delivery-details', summary: 'Delivery details', children: 'Tracked delivery in 2–3 working days.', attributes: disclosureAttributes, summaryAttributes: disclosureSummaryAttributes } satisfies DisclosureProps;
const responsiveAttributes = { class: 'catalog-filters' } satisfies ResponsiveDisclosureAttributes;
const responsiveDisclosure = { id: 'catalog-filters', summary: 'Filters', compactBreakpoint: '(max-width: 48rem)', compactInitialOpen: false, children: 'Availability and finish filters.', attributes: responsiveAttributes } satisfies ResponsiveDisclosureProps;
const accordionName = { label: 'Shipping topics' } satisfies AccordionAccessibleName;
const accordionAttributes = { class: 'shipping-topics' } satisfies AccordionAttributes;
const accordionHeadingLevel: AccordionHeadingLevel = 3;
const accordionItems = [{ id: 'shipping-tracking', value: 'tracking', summary: 'Tracking', children: 'Sent after dispatch.' }] satisfies readonly AccordionItem[];
const handleAccordion = (value: string | undefined, event: AccordionChangeEvent) => console.log(value, event.type);
const accordionSingle = { ...accordionName, value: 'tracking', onChange: handleAccordion } satisfies AccordionSingleProps;
const accordionMultiple = { ...accordionName, mode: 'multiple', value: ['tracking'] } satisfies AccordionMultipleProps;
const accordionProps = { ...accordionSingle, items: accordionItems, headingLevel: accordionHeadingLevel, attributes: accordionAttributes } satisfies AccordionProps;
const multipleAccordionProps = { ...accordionMultiple, items: accordionItems } satisfies AccordionProps;
const noticeTone: InlineNoticeTone = 'success';
const noticeAnnouncement: InlineNoticeAnnouncement = 'polite';
const noticeAttributes = { class: 'order-notice' } satisfies InlineNoticeAttributes;
const orderNotice = { tone: noticeTone, announcement: noticeAnnouncement, title: 'Order confirmed', children: 'Delivery details were sent.', action: Button({ label: 'View order' }), attributes: noticeAttributes } satisfies InlineNoticeProps;
const emptyPresentation: EmptyStatePresentation = 'compact';
const emptyHeadingLevel: EmptyStateHeadingLevel = 3;
const emptyAttributes = { class: 'empty-bag' } satisfies EmptyStateAttributes;
const emptyBag = { presentation: emptyPresentation, heading: 'Your bag is empty', headingLevel: emptyHeadingLevel, children: 'Choose something useful.', action: Button({ label: 'Shop objects' }), attributes: emptyAttributes } satisfies EmptyStateProps;
const tableName = { label: 'Recent orders' } satisfies TableRegionAccessibleName;
const tableAttributes = { class: 'recent-orders' } satisfies TableRegionAttributes;
const tableContent = { children: html`<table><caption>Recent orders</caption><tbody><tr><th scope="row">A-101</th><td>Ready</td></tr></tbody></table>` } satisfies TableRegionContent;
const recentOrders = { ...tableName, ...tableContent, id: 'recent-orders', summary: 'One recent order.', scrollHint: 'Scroll horizontally to review every column.', attributes: tableAttributes } satisfies TableRegionProps;
const choiceAttributes = { data: { owner: 'settings' } } satisfies ChoiceGroupAttributes;
const choiceOrientation: ChoiceGroupOrientation = 'horizontal';
const visibility = { id: 'visibility', legend: 'Visibility', orientation: choiceOrientation, attributes: choiceAttributes, children: html`<label>${Radio({ name: 'visibility', checked: true })} Team</label><label>${Radio({ name: 'visibility' })} Private</label>` } satisfies ChoiceGroupProps;
const tone: CardTone = 'success';
const order = {
title: 'Order confirmed',
subtitle: '#GL-1042',
tone,
children: html`${FormField(email)}${ControlField(orderReference)}${ChoiceGroup(visibility)}` ,
actions: Button({ label: 'View order' }),
} satisfies CardProps;
const sections = {
label: 'Order sections',
children: html`<a href="#summary" aria-current="page">Summary</a><a href="#delivery">Delivery</a>`,
} satisfies NavigationStripProps;
const navigationMenu = { id: 'primary-navigation', label: 'Primary navigation', open: ['shop'], items: [{ id: 'shop', label: 'Shop', accessibleLabel: 'Open Shop navigation', href: '/shop', active: true, children: [{ id: 'new', label: 'New arrivals', href: '/shop?sort=new' }] }] } satisfies NavigationMenuProps;
const searchFieldAttributes = { class: 'catalog-search' } satisfies SearchFieldAttributes;
const searchInputAttributes = { autocomplete: 'off' } satisfies SearchFieldInputAttributes;
const searchField = { id: 'catalog-search', label: 'Search products', query: 'cable', inputAttributes: searchInputAttributes, attributes: searchFieldAttributes } satisfies SearchFieldProps;
const searchGroup = { id: 'products', heading: 'Products', count: 1, children: html`<li><a href="/products/cable">Cobalt cable</a></li>` } satisfies SearchResultGroup;
const searchResultsAttributes = { class: 'catalog-results' } satisfies SearchResultsAttributes;
const searchHeadingLevel: SearchResultsHeadingLevel = 2;
const searchState: SearchResultsState = 'ready';
const searchResults = { id: 'catalog-results', heading: 'Results', headingLevel: searchHeadingLevel, state: searchState, groups: [searchGroup], attributes: searchResultsAttributes } satisfies SearchResultsProps;
const menuAttributes = { class: 'order-menu' } satisfies MenuAttributes;
const actionItem = { id: 'view', label: 'View order', href: '/orders/GL-1042' } satisfies MenuActionItem;
const checkboxItem = { id: 'compact', kind: 'checkbox', label: 'Compact rows', checked: false } satisfies MenuCheckboxItem;
const radioItem = { id: 'comfortable', kind: 'radio', group: 'density', label: 'Comfortable', checked: true } satisfies MenuRadioItem;
const separatorItem = { id: 'view-separator', kind: 'separator' } satisfies MenuSeparatorItem;
const menuKind: MenuItemKind = 'checkbox';
const menuItems = [actionItem, checkboxItem, radioItem, separatorItem] satisfies readonly MenuItem[];
const checkedChange: MenuCheckedChange = { id: checkboxItem.id, kind: 'checkbox', checked: true };
const dropdown = { id: 'order-menu', label: 'Order actions', trigger: 'Actions', open: false, onOpenChange: () => {}, attributes: menuAttributes, items: menuItems, onCheckedChange: (change: MenuCheckedChange) => console.log(change.checked) } satisfies DropdownMenuProps;
const retainedMenuProps: MenuProps = dropdown;
const contextMenu = { id: 'order-context', label: 'Order actions', children: 'Order GL-1042', open: false, onOpenChange: () => {}, items: menuItems } satisfies ContextMenuProps;
const menubar = { id: 'order-menubar', label: 'Order menu', items: menuItems } satisfies MenubarProps;
const toolbarButton = { id: 'save', label: 'Save' } satisfies ToolbarButtonItem;
const toolbarLink = { id: 'help', kind: 'link', label: 'Help', href: '/help' } satisfies ToolbarLinkItem;
const toolbarSeparator = { id: 'actions-separator', kind: 'separator' } satisfies ToolbarSeparatorItem;
const toolbarItems = [toolbarButton, toolbarLink, toolbarSeparator] satisfies readonly ToolbarItem[];
const toolbar = { id: 'order-toolbar', label: 'Order tools', items: toolbarItems } satisfies ToolbarProps;
const otpMode: OneTimePasswordFieldMode = 'numeric';
const otpAttributes = { class: 'checkout-code' } satisfies OneTimePasswordFieldAttributes;
const otpInputAttributes = { title: 'One-time code digit' } satisfies OneTimePasswordFieldInputAttributes;
const otpChange = (value: string) => console.log('code length', value.length);
const checkoutCode = { id: 'checkout-code', label: 'One-time code', length: 6, mode: otpMode, value: '123', name: 'code', helper: 'Enter the code from the device.', inputAttributes: otpInputAttributes, attributes: otpAttributes, onValueChange: otpChange } satisfies OneTimePasswordFieldProps;
const passwordToggle = { id: 'account-password', label: 'Password', value: 'secret', visible: false, showLabel: 'Show password', hideLabel: 'Hide password', autocomplete: 'current-password' } satisfies PasswordToggleFieldProps;
const segmentName = { label: 'Order view' } satisfies SegmentedControlAccessibleName;
const segmentAttributes = { class: 'order-view' } satisfies SegmentedControlAttributes;
const segmentOptions = [{ value: 'summary', label: 'Summary' }, { value: 'details', label: 'Details' }] satisfies readonly SegmentedControlOption[];
const segmentOrientation: SegmentedControlOrientation = 'horizontal';
const handleSegment = (value: string, event: SegmentedControlChangeEvent) => console.log(value, event.type);
const orderView = { ...segmentName, value: 'summary', options: segmentOptions, orientation: segmentOrientation, attributes: segmentAttributes, onChange: handleSegment } satisfies SegmentedControlProps;
const tabsName = { label: 'Order information' } satisfies TabsAccessibleName;
const tabsActivation: TabsActivation = 'automatic';
const tabsOrientation: TabsOrientation = 'horizontal';
const tabsAttributes = { class: 'order-information' } satisfies TabsAttributes;
const tabsItems = [{ id: 'order-summary', value: 'summary', label: 'Summary', panel: 'Order summary' }, { id: 'order-delivery', value: 'delivery', label: 'Delivery', panel: 'Delivery details' }] satisfies readonly TabsItem[];
const handleTab = (value: string, event: TabsChangeEvent) => console.log(value, event.type);
const orderTabs = { ...tabsName, value: 'summary', items: tabsItems, activation: tabsActivation, orientation: tabsOrientation, attributes: tabsAttributes, onChange: handleTab } satisfies TabsProps;
console.log(html`${NavigationStrip(sections)}${NavigationMenu(navigationMenu)}${SearchField(searchField)}${SearchResults(searchResults)}${OneTimePasswordField(checkoutCode)}${PasswordToggleField(passwordToggle)}${Card(order)}${ButtonGroup(orderActions)}${DropdownMenu(dropdown)}${ContextMenu(contextMenu)}${Menubar(menubar)}${Toolbar(toolbar)}${SegmentedControl(orderView)}${Tabs(orderTabs)}${DialogSurface(archiveDialog)}${Disclosure(deliveryDisclosure)}${Accordion(accordionProps)}${Accordion(multipleAccordionProps)}${InlineNotice(orderNotice)}${EmptyState(emptyBag)}${TableRegion(recentOrders)}`, moleculeStyles, searchFieldStyles, searchResultsStyles, oneTimePasswordFieldStyles, passwordToggleFieldStyles, retainedMenuProps, menuKind, checkedChange, moleculeManifest.entries);