Skip to main content
cngx-src documentation

CngxMenuItemSubmenu

DirectivePrimaryv0.1.0WCAG AA

projects/common/interactive/menu/menu-item-submenu.directive.ts

Import#

import { CngxMenuItemSubmenu } from '@cngx/common/interactive'

Description#

Companion directive applied to a [cngxMenuItem] that opens a nested submenu. The directive itself does NOT render role="menuitem" - that stays on CngxMenuItem. Adds aria-haspopup="menu" and reactive aria-expanded, registers itself with the surrounding menu as a submenu source so the menu trigger can drive arrow-right / arrow-left focus-stack semantics.

Wiring, two ways (Bridge-Input-Regel):

  • cngxMenuItemSubmenu + submenuMenu inputs bind the popover and the inner CngxMenu directly, or
  • a component shell provides CNGX_MENU_SUBMENU_WIRING and omits both inputs, so the brain resolves them from DI.

Until one source is present the brain stays inert: it renders neither aria-haspopup nor aria-expanded and opens nothing.

The submenu popover needs no [exclusive] binding: a popover nested inside another never evicts its ancestor, so opening the submenu leaves the parent popover open by default. An explicit [exclusive]="false" remains valid (it additionally opts the submenu out of evicting unrelated sibling popovers) but is no longer required for nesting.

https://cngxjs.github.io/cngx/examples/#/common/interactive/menu/submenu/two-level-submenu

Metadata#

Host#

Providers#

CNGX_MENU_SUBMENU_ITEM
useExisting CngxMenuItemSubmenu

Relationships

Index#

Inputs#

input()

Popover wrapping the submenu. Optional - a component shell can instead provide CNGX_MENU_SUBMENU_WIRING (Bridge-Input-Regel: an optional DI fallback forbids input.required; the empty-string transform keeps a bare cngxMenuItemSubmenu attribute from binding '').

default
undefined, {    alias: 'cngxMenuItemSubmenu',    transform: (v) => (typeof v === 'string' ? undefined : v),  }

Instance Properties#

hoverIntent#unknown
Readonly

CngxMenuSubmenuLike.hoverIntent - the debounced combined-surface hover state. Derivation only: the brain never opens or closes anything off it. The surrounding trigger routes the edges through its focus stack (connectSubmenuHoverToFocusStack), so a hover-opened submenu is stack-tracked and keyboard-visible exactly like a keyboard-opened one.

this.intent.active

Methods#

close#void
open#void

Accessors#

get

Effective id used by CngxMenuHost.submenuItems().find(s => s.id === activeId). When applied alongside [cngxMenuItem] the directive mirrors the sibling's id so the trigger's lookup matches the AD's activeId. When applied alone (no sibling), falls back to a fresh nextUid.

HostBindings#

BindingExpression
[id]id
[attr.aria-haspopup]ariaHaspopup()
[attr.aria-expanded]ariaExpanded()
[style.anchor-name]cssAnchorName()