import * as _floating_ui_dom from '@floating-ui/dom'; import { ReferenceElement } from '@floating-ui/dom'; import * as forty_cdk_core_overlay from 'forty-cdk/core-overlay'; import { MenuOverlayHost, ForMenuContext, AnchoredPositioningSeedDefaults, FloatingFallbackAxisSideDirection, AnchoredPositioningOverride, ForMenuCloseReason, Point, FloatingSide, FloatingAlign } from 'forty-cdk/core-overlay'; import * as _angular_core from '@angular/core'; import { Signal, InjectionToken, Provider } from '@angular/core'; import { WritingDirection, VetoableNativeEvent, VetoableEvent } from 'forty-cdk/core'; import * as forty_cdk_menu from 'forty-cdk/menu'; /** * Opener-agnostic menu root: one `[forMenuContent]` definition that any number * of heterogeneous openers can drive. Implements the same * [WAI-ARIA Menu Button / Menu semantics](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/) * as `[forDropdownMenu]` and `[forContextMenu]`, which stay as its single-opener * presets. * * Reach for it when the same actions must be reachable two ways — the canonical * case being a table row with a kebab button *and* a right-click region, where * the two presets would each need their own root and therefore their own copy of * every item: * * ```html * * …cells… * * * @if (open()) { *
* * *
* } * * ``` * * Exactly one instance is open at a time, and everything the mounted surface * resolves follows the **active opener** — the one that fired: return-focus lands * on it, and the floating-ui anchor is its element for a button opener or its * recorded pointer / rect position for a right-click opener. Each opener carries * its own `id`, so two of them never emit the same one. * * `[forDropdownMenuTrigger]` resolves this root through DI like any menu piece. * `[forContextMenuTrigger]` resolves `FOR_CONTEXT_MENU_CONTEXT`, which this root * does not provide, so bind it explicitly — `[forContextMenuTrigger]="row"` with * `#row="forMenu"`. * * Accessible name: the labelling policy follows the active opener too. A button * opener is a discrete labelling control, so the surface falls back to * `aria-labelledby=""` for it; a right-click region is not — pointing * the menu's name at a whole row would announce the entire row — so nothing is * emitted for that one. `[ariaLabel]` wins over both, and a shared menu with a * region opener needs it. * * Positioning is seeded from `provideForMenuDefaults` — `sideOffset` defaults to * `0`, flush against the anchor, which is what a pointer-anchored open wants — * and every opener may override the four placement values for the opens it * drives through its trigger's `[menuPositioning]`, falling back to the root's * inputs for whatever it leaves out: * * ```html * …cells… * * ``` */ declare class ForMenu extends MenuOverlayHost implements ForMenuContext { #private; /** * Two-way bindable. Whether the menu is currently shown. The `model()` * change emitter (`(openChange)`) fires only on internal transitions * (an opener activating, Escape, outside dismissal, item selection), never on * consumer writes via `[(open)]`. */ readonly open: _angular_core.ModelSignal; /** * `ForMenuDefaults.side` is shared with `[forMenuSub]`, whose own fallback is * the writing-direction side, so `null` is what "each root keeps its own" * looks like in the scope. Here that resolves to `'bottom'`. */ protected readonly positioningDefaults: AnchoredPositioningSeedDefaults; /** * Direction `flip` falls back to on the perpendicular axis when both sides of * the preferred axis overflow. `'none'` (default) keeps only the opposite * same-axis placement; `'start'` / `'end'` let the menu drop to a * perpendicular side on a narrow viewport. Only consulted when * `avoidCollisions` is on. The default is read from `provideForMenuDefaults` * for the surrounding scope, since dropping to a perpendicular side is a * design-system-wide viewport-degradation policy rather than a per-menu one. */ readonly fallbackAxisSideDirection: _angular_core.InputSignal; /** * When `true` (default), arrow-key navigation wraps from the last enabled * item back to the first (and vice versa). When `false`, navigation stops * at the ends. */ readonly loop: _angular_core.InputSignalWithTransform; /** * Writing direction. Drives ArrowLeft / ArrowRight semantics on submenu * triggers and items underneath this menu (in RTL, ArrowLeft opens a submenu * and ArrowRight closes it back). When unset (default `null`), the inherited * ambient direction is resolved from the nearest ancestor carrying a `dir` * attribute (or ``), defaulting to `'ltr'`. An explicit `[dir]` * always wins, the resolved value is reflected to the host `dir` attribute, * and it is inherited by descendant submenus. */ readonly _dirInput: _angular_core.InputSignal; readonly dir: _angular_core.Signal; /** * When true, every opener is ignored and any open menu stays open until the * consumer flips `open` themselves. Each opener reflects `data-disabled`; the * items keep their per-item disabled semantics. */ readonly disabled: _angular_core.InputSignalWithTransform; /** When true (default), Escape, pointer-down outside, and focus outside close the menu. */ readonly dismissible: _angular_core.InputSignalWithTransform; /** When true (default), focus returns to the opener that opened the menu on close. */ readonly returnFocus: _angular_core.InputSignalWithTransform; /** * Accessible name reflected as `aria-label` on `[forMenuContent]`. It wins over * the per-opener `aria-labelledby=""` fallback for every opener, so * set it when the menu needs one name regardless of how it was opened. * * Without it the surface names itself after the **active** opener when that * opener is a labelling control (a `[forDropdownMenuTrigger]` button) and * exposes no accessible name when it is not (a `[forContextMenuTrigger]` * region, whose whole text would otherwise be announced as the menu's name) — * so a shared menu with any region opener still wants an `ariaLabel`. */ readonly ariaLabel: _angular_core.InputSignal; /** * Fires when Escape is pressed while the menu is open, just before it * closes. Call `preventDefault()` on the emitted veto to keep the menu * open and suppress the Escape-driven close. */ readonly escapeKeyDown: _angular_core.OutputEmitterRef>; /** * Fires on a pointer-down outside the menu (and outside any exempt opener), * just before it closes. Call `preventDefault()` on the veto to keep the menu * open. */ readonly pointerDownOutside: _angular_core.OutputEmitterRef>; /** * Fires when focus moves outside the menu, just before it closes. Call * `preventDefault()` on the veto to keep the menu open. */ readonly focusOutside: _angular_core.OutputEmitterRef>; /** * Composite outside-interaction channel: fires for either a * pointer-down-outside or a focus-outside, just before the menu closes. * Call `preventDefault()` on the veto to keep the menu open regardless of * which interaction triggered it. */ readonly interactOutside: _angular_core.OutputEmitterRef>; /** * Fires just before the menu sends focus to its first / last enabled * item on mount. Call `preventDefault()` on the emitted veto to skip * the imperative focus move. */ readonly autoFocusOnOpen: _angular_core.OutputEmitterRef; /** * Fires just before focus returns to the active opener on unmount. Call * `preventDefault()` on the veto to suppress the return-focus. */ readonly autoFocusOnClose: _angular_core.OutputEmitterRef; protected readonly _overlay: forty_cdk_core_overlay.MenuOverlay; /** * The active opener's anchor: its recorded pointer / rect position when it set * one, otherwise its own element. */ readonly anchor: _angular_core.Signal<_floating_ui_dom.ReferenceElement | null>; /** * The active opener's own placement override, resolved by the base ahead of * this root's `[side]` / `[align]` / `[sideOffset]` / `[alignOffset]`. The * four placement values resolve per opener because a shared menu's openers * are heterogeneous — a button opener wants the clearance * `[forDropdownMenu]` seeds, a pointer-anchored region wants to sit flush at * the cursor. */ protected positioningOverride(): AnchoredPositioningOverride | null; /** * Only the openers that asked to count as "inside" — a toggle-style button * opener, whose own click already toggles and would otherwise double-close. A * right-click region opts out, so a left-click on it closes the menu. */ readonly dismissibleExemptions: _angular_core.Signal; /** * Resolved against the **active** opener, because a shared menu's openers are * heterogeneous: a `[forDropdownMenuTrigger]` button is a discrete labelling * control, a `[forContextMenuTrigger]` region is not. So `[forMenuContent]` * falls back to `aria-labelledby=""` for a button-opened instance and * emits nothing for a region-opened one — and flips as the menu is reopened * from the other opener. `false` while no single opener is resolvable. */ readonly triggerLabelsMenu: _angular_core.Signal; /** Top-level: no parent menu. */ readonly parentMenu: null; /** * Anchors the active opener's next open at a 0×0 rect at (`x`, `y`) in viewport * coordinates. Widens the shared base's protected pass-through so a * pointer-driven opener can reach it through this root's exported reference. */ setVirtualAnchor(x: number, y: number): void; /** * Anchors the active opener's next open at a by-value snapshot of `rect`, so * later layout changes don't shift it. Used by the keyboard activators of a * pointer-driven opener (`Shift+F10`, the `ContextMenu` key). */ setVirtualAnchorFromRect(rect: DOMRect): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * The menu surface. Carries `role="menu"`, is portaled to `document.body`, * and is positioned by `@floating-ui/dom` against the registered anchor — * the trigger button for `[forDropdownMenu]`, or a virtual pointer element * for `[forContextMenu]`. * * The directive does not manage DOM presence — wrap with * `@if (open())` so `animate.enter` / `animate.leave` fire on the natural * mount cycle. While mounted, it dismisses on Escape, pointer-down outside or * focus outside, and initial focus is sent to the first or last menu item per * the trigger's hint. * * The trigger element is exempt from the layer's outside-pointer checks, * so clicking the trigger again routes through its own toggle handler * without spuriously closing. * * Accessible name: a consumer-set **static** `aria-labelledby` on the surface * always wins and is preserved. Otherwise an explicit `ariaLabel` on the root * is reflected as `aria-label`, and with neither the surface falls back to * `aria-labelledby=""` — but only when the trigger that opened it is * a labelling control (`[forDropdownMenu]`, `[forMenubar]`, `[forMenuSub]`). * `[forContextMenu]` opts out of that fallback (its trigger is the whole * right-click region), so name a context menu with `[ariaLabel]`. `[forMenu]` * answers per **active opener**, so a shared menu names itself after the button * that opened it and emits nothing when a right-click region did. * * Both `id` and `aria-labelledby` are emitted truthy-only: a surface the * context has not associated with a trigger yet — only reachable under * `[forMenubar]`, where one surface may be mounted unconditionally while no * menu is open — carries neither attribute rather than an invalid `id=""` and * an `aria-labelledby` pointing at nothing. That same menubar shape is why the * dev-mode mounted-while-closed warning is gated on * `ForMenuContext.allowsUnconditionalMount`: under every other root mount * equals open, so a surface still mounted while closed is a missing `@if`. * * Navigation is vertical-only (Up / Down between items, per the APG Menu * pattern), so the surface reflects `aria-orientation="vertical"` explicitly. * Horizontal menus are out of scope; a horizontal *bar* of menus is modelled * by `[forMenubar]` instead. */ declare class ForMenuContent { #private; protected readonly ctx: forty_cdk_core_overlay.ForMenuContext; protected readonly resolvedAriaLabel: _angular_core.Signal; protected readonly labelledBy: _angular_core.Signal; constructor(); /** * Hover-follows-pointer: the pointer left the menu surface, so drop the * highlight from whichever item the pointer was over. Focus is left where it * is (anchored on the item for keyboard navigation); only `data-highlighted` * clears. Gated to mouse — touch / pen never hover. */ protected onPointerLeave(event: PointerEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * The highlight / focus / navigation mechanics every menu item role shares. * `[forMenuItem]`, `[forMenuCheckboxItem]`, and `[forMenuRadioItem]` each own * their role, activation (click / Enter / Space), and toggle-vs-select * semantics, but the surrounding interaction is identical: the * `data-highlighted` state machine, registration with the parent menu, and the * ArrowLeft/Right → Arrow/Home/End → Tab keyboard prefix. Consolidating them * here keeps the three item directives from drifting apart. */ interface MenuItemInteraction { /** * True while this item is the active keyboard candidate or hovered by the * pointer. Set on keyboard-driven focus and on `pointermove` (hover follows * the pointer), cleared on `blur` and when the pointer leaves the surface. * The programmatic initial focus of a pointer-driven open lands without a * highlight until the pointer moves onto the item or keyboard navigation * begins. Reflected as `data-highlighted`. */ readonly highlighted: Signal; /** `(focus)` handler — highlights unless a pointer-open suppression is pending. */ onFocus(): void; /** `(blur)` handler — drops the highlight and clears any pending suppression. */ onBlur(): void; /** `(pointermove)` handler — mouse hover moves focus onto the item and highlights it. */ onPointerMove(event: PointerEvent): void; /** * Handle the navigation prefix shared by every item — horizontal-arrow * routing (submenu close / menubar sibling switch), ArrowUp/Down/Home/End * list navigation, and Tab-out. Returns `true` when the key was consumed, so * the caller stops before its own activation / typeahead handling. */ handleNavigation(event: KeyboardEvent): boolean; } /** * A single action inside `[forMenuContent]`. Apply on a `` * for an item rendered as `New file ⌘N`. */ readonly textValue: _angular_core.InputSignal; readonly effectiveDisabled: _angular_core.Signal; protected readonly interaction: MenuItemInteraction; /** * True while this item is the active keyboard candidate or hovered by the * pointer. Reflected as `data-highlighted`. */ readonly highlighted: _angular_core.Signal; /** * Fires on click / Enter / Space activation. Call `preventDefault()` * on the emitted veto to keep the menu open after activation. */ readonly activate: _angular_core.OutputEmitterRef; protected onClick(): void; protected onKeyDown(event: KeyboardEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Injection key the `[forMenuItemIndicator]` uses to resolve a parent * checkbox item, decoupled from the concrete `ForMenuCheckboxItem` class. * `ForMenuCheckboxItem` provides itself under this token, so a design system * wrapping the item by subclassing re-points it at the subclass with a single * provider (`{ provide: FOR_MENU_CHECKBOX_ITEM, useExisting: MtxMenuCheckboxItem }`) * and the indicator keeps resolving — see `docs/wrapping-form-primitives.md`. */ declare const FOR_MENU_CHECKBOX_ITEM: InjectionToken; /** * Tri-state-free checkbox item. Click and Enter toggle `checked`, emit * `(activate)`, and close the menu — `event.preventDefault()` on the emitted * event keeps the menu open. Per APG, **Space** toggles `checked` and * emits `(activate)` without closing the menu, so users can flip several * options in one open without consumer glue. * * Disabled items are skipped by arrow-key navigation, typeahead, and * Home/End, and ignore pointer hover, but stay in the DOM carrying * `aria-disabled="true"` (never the native `disabled` attribute) so assistive * tech can still perceive and announce them. */ declare class ForMenuCheckboxItem { protected readonly buttonType: _angular_core.Signal; protected readonly ctx: forty_cdk_core_overlay.ForMenuContext; /** Two-way bindable. */ readonly checked: _angular_core.ModelSignal; /** Per-item disabled, in addition to the menu's `disabled`. */ readonly disabled: _angular_core.InputSignalWithTransform; /** * Override the string used for typeahead matching. Defaults to `''`, * which falls back to the item's `textContent`. See `[forMenuItem]` * for the rationale. */ readonly textValue: _angular_core.InputSignal; readonly effectiveDisabled: _angular_core.Signal; protected readonly interaction: MenuItemInteraction; /** * True while this item is the active keyboard candidate or hovered by the * pointer. Reflected as `data-highlighted`. */ readonly highlighted: _angular_core.Signal; /** * Fires on click / Enter / Space activation. Call `preventDefault()` * on the emitted veto to keep the menu open after activation. */ readonly activate: _angular_core.OutputEmitterRef; protected onClick(): void; protected onKeyDown(event: KeyboardEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Coordination contract owned by `[forMenuGroup]` and `[forMenuRadioGroup]`. * `[forMenuGroupLabel]` registers its generated id so the group wires * `aria-labelledby`. */ interface ForMenuGroupContext { registerLabel(id: string): void; unregisterLabel(id: string): void; } declare const FOR_MENU_GROUP_CONTEXT: InjectionToken; /** * Coordination contract owned by `[forMenuRadioGroup]`. Radio items inject * it to read selection state and request a value change. Independent from * the parent menu's context so radio items can compose without the radio * group needing to know about menu internals (and vice versa). */ interface ForMenuRadioGroupContext { /** * The selected value, or `null` when nothing is selected, as a read-only * signal. Mutate it through `select` or the root's `[(value)]` binding * rather than writing it directly. */ readonly value: Signal; isSelected(value: string): boolean; select(value: string): void; } declare const FOR_MENU_RADIO_GROUP_CONTEXT: InjectionToken; /** * Container for a set of `[forMenuRadioItem]` elements. Acts as a * `role="group"` plus a coordination point for the shared `value`. * * Give the group an accessible name with a projected `[forMenuGroupLabel]` * (rendered as a section header in most designs) — the group references it * via `aria-labelledby`, the same labelling mechanism as `[forMenuGroup]`. */ declare class ForMenuRadioGroup implements ForMenuRadioGroupContext, ForMenuGroupContext { #private; /** * Two-way bindable. The selected radio item's `value`, or `null` when * nothing is selected. `null` is the canonical unset state — distinct from * an item whose `value` is the empty string `''`, which is a legal, * selectable value. The `model()` change emitter (`(valueChange)`) fires * only on internal selection. */ readonly value: _angular_core.ModelSignal; /** * `aria-labelledby` target: a consumer-set static `aria-labelledby` when * present, else the space-joined ids of every projected * `[forMenuGroupLabel]`, or `null` when none are present. */ readonly labelledBy: _angular_core.Signal; isSelected(v: string): boolean; select(v: string): void; /** Registers a `[forMenuGroupLabel]` id for `aria-labelledby`. */ registerLabel(id: string): void; /** Unregisters a previously registered `[forMenuGroupLabel]` id. */ unregisterLabel(id: string): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Injection key the `[forMenuItemIndicator]` uses to resolve a parent radio * item, decoupled from the concrete `ForMenuRadioItem` class. * `ForMenuRadioItem` provides itself under this token, so a design system * wrapping the item by subclassing re-points it at the subclass with a single * provider (`{ provide: FOR_MENU_RADIO_ITEM, useExisting: MtxMenuRadioItem }`) * and the indicator keeps resolving — see `docs/wrapping-form-primitives.md`. */ declare const FOR_MENU_RADIO_ITEM: InjectionToken; /** * One radio option inside `[forMenuRadioGroup]`. Click and Enter set the * group's `value` to this item's `value`, emit `(activate)`, and close the * menu — call `event.preventDefault()` on the emitted event to keep the * menu open. Per APG, **Space** sets the value and emits `(activate)` * without closing the menu. * * Disabled items are skipped by arrow-key navigation, typeahead, and * Home/End, and ignore pointer hover, but stay in the DOM carrying * `aria-disabled="true"` (never the native `disabled` attribute) so assistive * tech can still perceive and announce them. */ declare class ForMenuRadioItem { protected readonly buttonType: _angular_core.Signal; protected readonly menu: forty_cdk_core_overlay.ForMenuContext; protected readonly group: forty_cdk_menu.ForMenuRadioGroupContext; /** Identifier added to / read from the radio group's `value`. Required. */ readonly value: _angular_core.InputSignal; /** Per-item disabled, in addition to the menu's `disabled`. */ readonly disabled: _angular_core.InputSignalWithTransform; /** * Override the string used for typeahead matching. Defaults to `''`, * which falls back to the item's `textContent`. See `[forMenuItem]` * for the rationale. */ readonly textValue: _angular_core.InputSignal; readonly checked: _angular_core.Signal; readonly effectiveDisabled: _angular_core.Signal; protected readonly interaction: MenuItemInteraction; /** * True while this item is the active keyboard candidate or hovered by the * pointer. Reflected as `data-highlighted`. */ readonly highlighted: _angular_core.Signal; /** * Fires on click / Enter / Space activation. Call `preventDefault()` * on the emitted veto to keep the menu open after activation. */ readonly activate: _angular_core.OutputEmitterRef; protected onClick(): void; protected onKeyDown(event: KeyboardEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Visibility helper inside `[forMenuCheckboxItem]` or `[forMenuRadioItem]`. * The directive flips a `[hidden]` host binding so the consumer can keep * the checkmark / dot inline without extra `@if` glue: * * ```html * * *
* *
* ``` * * Reflects the parent item's `data-state` (`"checked" | "unchecked"`) so * the consumer can also style it from CSS. Set `[forceMount]` to keep the * indicator in the DOM regardless of state — useful when wrapping * `animate.leave` for an exit animation, or when the consumer styles the * indicator via `data-state` instead of presence. * * Visibility while unchecked is enforced with an inline `display: none` * (which beats any author `display` rule a consumer applies via a class) in * addition to the `hidden` attribute that removes it from the a11y tree. */ declare class ForMenuItemIndicator { #private; protected readonly checked: _angular_core.Signal; /** Keep the indicator mounted even when the parent item is unchecked. */ readonly forceMount: _angular_core.InputSignalWithTransform; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Visual + semantic separator between menu items. Never focused, never * registers with the menu's item collection, so keyboard navigation and * typeahead skip it automatically. Set `decorative` when the surrounding items * already convey the split and the line should be skipped by assistive tech. */ declare class ForMenuSeparator { /** * Axis the separator divides along, always reflected to `data-orientation` * and reflected to `aria-orientation` only for `vertical` (`horizontal` is * the ARIA default and is omitted). `horizontal` (default) splits items * stacked vertically — the common case in a vertical menu; `vertical` splits * items laid out horizontally. */ readonly orientation: _angular_core.InputSignal<"vertical" | "horizontal">; /** * When true, the separator is purely visual: it gets `role="none"` and no * `aria-orientation`, so assistive tech treats the surrounding items as a * single flow. `data-orientation` is still reflected for styling. */ readonly decorative: _angular_core.InputSignalWithTransform; protected roleAttr(): 'separator' | 'none'; protected ariaOrientationAttr(): 'vertical' | null; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Logical grouping of menu items, exposed to assistive tech as * `role="group"`. Use with `[forMenuGroupLabel]` for an accessible name * (rendered as a section header in most designs). */ declare class ForMenuGroup implements ForMenuGroupContext { #private; readonly labelledBy: _angular_core.Signal; registerLabel(id: string): void; unregisterLabel(id: string): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Accessible name for `[forMenuGroup]` or `[forMenuRadioGroup]`. Generates an * id on the host and registers it with the parent group so `aria-labelledby` * resolves to this element. */ declare class ForMenuGroupLabel { readonly id: string; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Root for a nested submenu inside a parent `[forDropdownMenu]` / * `[forContextMenu]` (or another `[forMenuSub]`). Owns its own open * state, ids, and item collection — items inside the submenu register * here, not in the parent. * * The shared item-collection / typeahead / navigate / focus / id / * outside-veto logic is owned by the `_internal/menu-overlay` helper (the * same one `[forDropdownMenu]` / `[forContextMenu]` compose). The submenu * contributes only its genuine differences on top: pointer-driven (hover) * open/close scheduling, the autofocus vetoes that keep hover from stealing / * returning focus, and the reason-dependent upward `closeMenu` propagation. * The pointer paths run through the overlay's own `openMenu` / `closeMenu` * (with `{ suppressFocusMoves: true }`, closing with reason `'hover'`), so all * three concerns are wired through the `onOpen` / `onClose` lifecycle hooks and * `lastCloseReason` / the initial-focus state stay correct on every transition. * * The parent menu's content is added to this submenu's dismissible * exemptions so a click on a parent menu item doesn't fire the * submenu's outside-handler (the parent item's own click flow closes * everything via propagated `closeMenu`). * * Closing this submenu propagates `closeMenu` upward for every reason * except `'escape'`, `'hover'` and `'programmatic'` — Escape inside a submenu * and a hover-leave close only that level, while activating an item or * clicking outside everything tears down the entire chain. * * ```html *
* * @if (open()) { *
* *
* * @if (moreOpen()) { *
* *
* } *
*
* } *
* ``` */ declare class ForMenuSub extends MenuOverlayHost implements ForMenuContext { #private; protected get positioningDefaults(): AnchoredPositioningSeedDefaults; /** The enclosing menu — required (orphan throws). */ readonly parentMenu: ForMenuContext; /** * Two-way bindable. Whether the submenu is currently shown. The `model()` change emitter fires * only when the primitive itself opens or closes the submenu, never on consumer writes through * `[(open)]`. */ readonly open: _angular_core.ModelSignal; /** * Writing direction. When unset, inherits from the enclosing menu — set * `[dir]` once on the top-level `[forDropdownMenu]` / `[forContextMenu]` * and every nested submenu picks it up. Override per-submenu only when * a specific submenu needs to render against the opposite direction. * * The input is aliased to `dir`; consumers bind `[dir]="..."` and read * the effective value via the public `dir` computed below. */ readonly _dirInput: _angular_core.InputSignal; readonly dir: _angular_core.Signal; /** * Direction `flip` falls back to on the perpendicular axis when both sides of * the preferred axis overflow. `'none'` (default) keeps only the opposite * same-axis placement; `'start'` / `'end'` let the submenu drop to a vertical * side (`top` / `bottom`) when both horizontal sides are blocked — the * graceful-degradation lever for a submenu clipped on a narrow viewport. Only * consulted when `avoidCollisions` is on. * * The default is read from `provideForMenuDefaults` for the surrounding scope, * since dropping to a vertical side is a design-system-wide * viewport-degradation policy rather than a per-submenu one. */ readonly fallbackAxisSideDirection: _angular_core.InputSignal; /** * When `true` (default), arrow-key navigation wraps from the last enabled * item back to the first (and vice versa). When `false`, navigation stops * at the ends. */ readonly loop: _angular_core.InputSignalWithTransform; /** * When true, the sub-trigger interaction is ignored and any open submenu * stays open until the consumer flips `open`. Layered on top of the parent * menu's own `disabled`. */ readonly disabled: _angular_core.InputSignalWithTransform; /** When true (default), Escape, pointer-down outside, and focus outside close the submenu. */ readonly dismissible: _angular_core.InputSignalWithTransform; /** When true (default), focus returns to the sub-trigger on close. */ readonly returnFocus: _angular_core.InputSignalWithTransform; /** Manual `aria-label` on `[forMenuSubContent]`. Use when the sub-trigger isn't a meaningful name. */ readonly ariaLabel: _angular_core.InputSignal; /** * Fires when Escape is pressed while the submenu is open, just before it * closes. Call `preventDefault()` on the emitted veto to keep the submenu * open and suppress the Escape-driven close. */ readonly escapeKeyDown: _angular_core.OutputEmitterRef>; /** * Fires on a pointer-down outside the submenu (and outside its exempt * parent content), just before it closes. Call `preventDefault()` on the * veto to keep the submenu open. */ readonly pointerDownOutside: _angular_core.OutputEmitterRef>; /** * Fires when focus moves outside the submenu, just before it closes. Call * `preventDefault()` on the veto to keep the submenu open. */ readonly focusOutside: _angular_core.OutputEmitterRef>; /** * Composite outside-interaction channel: fires for either a * pointer-down-outside or a focus-outside, just before the submenu closes. * Call `preventDefault()` on the veto to keep the submenu open regardless of * which interaction triggered it. */ readonly interactOutside: _angular_core.OutputEmitterRef>; /** * Fires just before the submenu sends focus to its first / last * enabled item on mount. Call `preventDefault()` on the emitted veto * to skip the imperative focus move. */ readonly autoFocusOnOpen: _angular_core.OutputEmitterRef; /** * Fires just before focus returns to the parent item on unmount. Call * `preventDefault()` on the veto to suppress the return-focus. */ readonly autoFocusOnClose: _angular_core.OutputEmitterRef; protected readonly _overlay: forty_cdk_core_overlay.MenuOverlay; readonly anchor: _angular_core.Signal; /** * Submenus exempt the parent menu's content. Clicks on parent menu items * activate via the item's own click handler (which propagates `closeMenu` * upward through the whole chain) instead of firing the submenu's * outside-close. */ readonly dismissibleExemptions: _angular_core.Signal; constructor(); registerContent(el: HTMLElement): void; unregisterContent(el: HTMLElement): void; closeMenu(reason: ForMenuCloseReason): void; /** * Schedule a hover-open of the submenu after `subMenuOpenDelay`. Re-entering * the trigger also keeps every ancestor menu alive and aborts a pending * close. No-op when disabled or already open / scheduled. */ scheduleOpenByPointer(): void; /** * The pointer left the sub-trigger. Cancels a not-yet-fired hover-open; if * the submenu is already open, arms the pointer-grace "safe triangle" toward * the content so travelling into the submenu doesn't close it. */ onTriggerPointerLeave(cursor: Point): void; /** Schedule a hover-close of the submenu after `subMenuCloseDelay`. */ scheduleCloseByPointer(): void; /** Cancel a pending hover-close and disarm the pointer-grace tracker. */ cancelPendingClose(): void; emitAutoFocusOnOpen(): boolean; emitAutoFocusOnClose(): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * The `menuitem` inside the parent menu that opens its `[forMenuSub]`. * Apply on a `