Skip to main content
cngx-src documentation

CngxContextMenu

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/ui/context-menu/context-menu.component.ts

Import#

import { CngxContextMenu } from '@cngx/ui/context-menu'

Description#

Declarative context-menu panel. Stacks CngxPopover (the top-layer popup surface) and CngxMenu (the role="menu" keyboard + ARIA brain) as host directives on its own element, so projected items and the lazy content template resolve CngxActiveDescendant / CNGX_MENU_HOST against the panel host's injector chain. Pair it with [cngxContextMenuFor] on a target.

The brains live on the host - not inside an inner [cngxMenu] element - because Angular resolves DI for projected and template content at the declaration site, not the projection site; an inner menu directive would be invisible to items rendered through <ng-content> or the content slot. Construction mirrors CngxPopoverPanel.

context() is derived, never synced: it reads the trigger's per-open datum while the popover is visible and null once it closes - no manual reset on dismiss (Pillar 1).

Static menu

<div [cngxContextMenuFor]="menu">Right-click me</div>
<cngx-context-menu #menu ariaLabel="Actions">
  <cngx-context-menu-item (select)="copy()">Copy</cngx-context-menu-item>
  <cngx-context-menu-item (select)="paste()">Paste</cngx-context-menu-item>
</cngx-context-menu>

Per-row content

<cngx-context-menu #menu ariaLabel="Row actions">
  <ng-template cngxContextMenuContent let-row>
    <cngx-context-menu-item (select)="edit(row)">Edit {{ row.name }}</cngx-context-menu-item>
  </ng-template>
</cngx-context-menu>

https://cngxjs.github.io/cngx/examples/#/ui/context-menu/basic/static-items https://cngxjs.github.io/cngx/examples/#/ui/context-menu/grid/delegated-resolver https://cngxjs.github.io/cngx/examples/#/ui/context-menu/submenu/nested-export-menu https://cngxjs.github.io/cngx/examples/#/ui/context-menu/selection/checkbox-radio-items

Metadata#

Host#

Providers#

CNGX_CONTEXT_MENU_PANEL
useExisting CngxContextMenu

Dependencies#

CngxMenuinject()selfmenuHost

The menu brain (role="menu", active-descendant registry).

CngxPopoverinject()selfpopover

The popover surface this panel drives. Consumed by the trigger core.

Relationships

Index#

Derived State

HostListeners

Instance Properties#

contentTemplate#unknown
contentChild()ProtectedReadonly
contentChild(CngxContextMenuContent)

Methods#

handleKeydown#void
Protected
handleKeydown(event: KeyboardEvent)
@parameventKeyboardEvent

HostListeners#

EventHandler
(keydown)keydown()

Default visuals for CngxContextMenu. The organism stacks CngxPopover and CngxMenu as host directives, so the base menu-family skin's container rules ([cngxMenu], cngx-menu.css) never reach this host - a host directive applies behaviour, not its selector attribute. The container therefore paints its own popup surface here (the chrome a CngxPopoverPanel would otherwise supply), while the item slot and state painting (.cngx-menu-item__label, .cngx-menu-item--highlighted, ...) is adopted from the base skin via the classes the brains stamp programmatically. The --cngx-context-menu-* family carries the surface chrome; spacing derives from --cngx-space-* so a root [data-density] compacts the menu.

Slots

  • projected cngx-context-menu-item / -divider rows, or a lazy ng-template[cngxContextMenuContent] outlet
  • cngx-context-menu-divider - hairline separator painted here (the base [cngxMenuSeparator] attribute rule does not reach the shell)

Inheritance

Surface tokens delegate to the foundation so a brand or dark-mode swap cascades through one :root pass - no per-component dark 4-block needed:

  • --cngx-context-menu-surface -> --cngx-color-surface
  • --cngx-context-menu-color -> --cngx-color-text
  • --cngx-context-menu-border -> --cngx-color-border
  • --cngx-context-menu-shadow -> --cngx-shadow-md
  • --cngx-context-menu-separator-color -> --cngx-color-border

Forced colors

The separator is a 1px background hairline that flattens to Canvas under WHCM; an unlayered forced-colors rule re-draws it with CanvasText ink.

Pair with

  • @cngx/themes/material/context-menu-theme - Material 3 surface

Index#

Surface

--cngx-context-menu-surface#<color>
Default value oklch(1 0 0)

Popup surface background. Falls back through --cngx-color-surface.

See: [[--cngx-color-surface]]

--cngx-context-menu-color#<color>
Default value oklch(0.2 0.01 250)

Menu text color. Falls back through --cngx-color-text.

See: [[--cngx-color-text]]

--cngx-context-menu-border#*
Default value 1px solid oklch(0.88 0.005 250)

Border shorthand around the popup surface. Falls back through --cngx-color-border.

See: [[--cngx-color-border]]

--cngx-context-menu-shadow#*
Default value 0 4px 16px oklch(0 0 0 / 0.12)

Drop-shadow shorthand for the popup. inherits: true so a :root override reaches the open surface. Falls back through --cngx-shadow-md.

--cngx-context-menu-separator-color#<color>
Default value oklch(0.88 0.005 250)

Color of the separator hairline. Falls back through --cngx-color-border.

See: [[--cngx-color-border]]

Layout

--cngx-context-menu-radius#<length>
Default value 8px

Corner radius of the popup surface.

--cngx-context-menu-padding#<length>
Default value 4px

Padding inside the popup surface (around the item stack). Derived from --cngx-space-xs at the host so density tracks; the registered pixel initial defeats the use-site fallback, so the :scope SET is the only mechanism that re-scales it.

--cngx-context-menu-separator-inset#<length>
Default value 4px

Block margin above and below the separator hairline. Derived from --cngx-space-xs at the host.