CngxMenuItemSubmenu
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+submenuMenuinputs bind the popover and the innerCngxMenudirectly, or- a component shell provides
CNGX_MENU_SUBMENU_WIRINGand 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.
Metadata#
Host#
Providers#
CNGX_MENU_SUBMENU_ITEM- useExisting
CngxMenuItemSubmenu CNGX_HOVER_INTENT_DEFAULTS- useFactory
() => { const cfg = injectMenuConfig(); return { enterDelay: cfg.submenuOpenDelay, leaveDelay: cfg.submenuCloseDelay }; }
Relationships
Index#
Properties
Inputs
Derived State
Inputs#
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 '').
undefined, { alias: 'cngxMenuItemSubmenu', transform: (v) => (typeof v === 'string' ? undefined : v), }Instance Properties#
unknownCngxMenuSubmenuLike.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.activeMethods#
Accessors#
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.
CngxMenuHost | nullHostBindings#
| Binding | Expression |
|---|---|
[id] | id |
[attr.aria-haspopup] | ariaHaspopup() |
[attr.aria-expanded] | ariaExpanded() |
[style.anchor-name] | cssAnchorName() |