ngwr 13.0.0 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/fesm2022/ngwr-border-glow.mjs +12 -3
  2. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  3. package/fesm2022/ngwr-breadcrumbs.mjs +14 -3
  4. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  5. package/fesm2022/ngwr-context-menu.mjs +6 -2
  6. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  7. package/fesm2022/ngwr-dialog.mjs +22 -16
  8. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  9. package/fesm2022/ngwr-directives.mjs +5 -2
  10. package/fesm2022/ngwr-directives.mjs.map +1 -1
  11. package/fesm2022/ngwr-drawer.mjs +24 -18
  12. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  13. package/fesm2022/ngwr-dropdown.mjs +6 -2
  14. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  15. package/fesm2022/ngwr-fuzzy-text.mjs +21 -4
  16. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  17. package/fesm2022/ngwr-gradient-text.mjs +9 -2
  18. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  19. package/fesm2022/ngwr-icon-adapters-feather.mjs +11 -0
  20. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  21. package/fesm2022/ngwr-icon-adapters-lucide.mjs +22 -2
  22. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  23. package/fesm2022/ngwr-icon.mjs +474 -37
  24. package/fesm2022/ngwr-icon.mjs.map +1 -1
  25. package/fesm2022/ngwr-markdown.mjs +63 -11
  26. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  27. package/fesm2022/ngwr-overlay.mjs +36 -7
  28. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  29. package/fesm2022/ngwr-qr.mjs +38 -1
  30. package/fesm2022/ngwr-qr.mjs.map +1 -1
  31. package/fesm2022/ngwr-shiny-text.mjs +10 -3
  32. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  33. package/fesm2022/ngwr-tabs.mjs +6 -2
  34. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  35. package/fesm2022/ngwr-utils.mjs +107 -1
  36. package/fesm2022/ngwr-utils.mjs.map +1 -1
  37. package/fesm2022/ngwr-version.mjs +1 -1
  38. package/fesm2022/ngwr-version.mjs.map +1 -1
  39. package/llms-full.txt +1 -1
  40. package/package.json +3 -3
  41. package/types/ngwr-breadcrumbs.d.ts +1 -0
  42. package/types/ngwr-fuzzy-text.d.ts +5 -0
  43. package/types/ngwr-icon-adapters-feather.d.ts +11 -0
  44. package/types/ngwr-icon.d.ts +42 -1
  45. package/types/ngwr-shiny-text.d.ts +1 -0
  46. package/types/ngwr-utils.d.ts +47 -1
  47. package/types/ngwr-version.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-context-menu.mjs","sources":["../../../projects/lib/context-menu/menu-focus.ts","../../../projects/lib/context-menu/context-menu-item.ts","../../../projects/lib/context-menu/context-menu-item.html","../../../projects/lib/context-menu/context-menu.ts","../../../projects/lib/context-menu/context-menu-panel.ts","../../../projects/lib/context-menu/context-menu-divider.ts","../../../projects/lib/context-menu/ngwr-context-menu.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * Roving focus inside ONE context-menu pane.\n *\n * The APG menu pattern makes a menu a single tab stop and moves a focus cursor\n * between its rows with the arrows — which is why every `<wr-context-menu-item>`\n * carries `tabindex=\"-1\"`. Shared by the root directive and by\n * `WrContextMenuItem`'s submenu because a submenu is a SEPARATE overlay pane\n * rather than nested DOM: each pane roves over its own rows, and CDK's keyboard\n * dispatcher hands the key to the topmost one, which is the pane the user is in.\n *\n * @internal\n */\n\n/**\n * The rows of one pane the cursor may land on. Disabled rows are not stops —\n * the same rule `WrDropdown` follows.\n */\nexport function wrMenuItems(pane: HTMLElement): readonly HTMLElement[] {\n return Array.from(pane.querySelectorAll<HTMLElement>('.wr-context-menu-item:not(.wr-context-menu-item--disabled)'));\n}\n\n/** Focus the row at `index`, wrapping at both ends. A pane with no rows is left alone. */\nexport function wrFocusMenuItemAt(pane: HTMLElement, index: number): void {\n const items = wrMenuItems(pane);\n if (items.length === 0) return;\n const clamped = ((index % items.length) + items.length) % items.length;\n items[clamped]?.focus();\n}\n\n/**\n * ArrowDown / ArrowUp / Home / End over one pane's rows. Returns `true` when the\n * key was consumed, so a caller can leave every other key alone.\n */\nexport function wrHandleMenuNavigation(pane: HTMLElement, event: KeyboardEvent): boolean {\n const items = wrMenuItems(pane);\n if (items.length === 0) return false;\n const active = document.activeElement;\n // -1 when the keyboard is not on a row yet, which makes ArrowDown open at the\n // first row and ArrowUp at the last.\n const index = active instanceof HTMLElement ? items.indexOf(active) : -1;\n switch (event.key) {\n case 'ArrowDown':\n wrFocusMenuItemAt(pane, index + 1);\n break;\n case 'ArrowUp':\n wrFocusMenuItemAt(pane, index <= 0 ? items.length - 1 : index - 1);\n break;\n case 'Home':\n wrFocusMenuItemAt(pane, 0);\n break;\n case 'End':\n wrFocusMenuItemAt(pane, items.length - 1);\n break;\n default:\n return false;\n }\n event.preventDefault();\n return true;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type ConnectedPosition, type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n ViewContainerRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport type { Subscription } from 'rxjs';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { WR_OVERLAY, wrMirrorOffsets } from 'ngwr/overlay';\nimport { randomId } from 'ngwr/utils';\n\nimport { WrContextMenu } from './context-menu';\nimport type { WrContextMenuPanel } from './context-menu-panel';\nimport { wrFocusMenuItemAt, wrHandleMenuNavigation } from './menu-focus';\n\n/** Hover delay (ms) before a submenu opens. */\nconst SUBMENU_OPEN_DELAY = 120;\n/** Grace window (ms) before a submenu closes when the cursor leaves it. */\nconst SUBMENU_CLOSE_DELAY = 240;\n/** Animation duration of the submenu — mirrors the root menu CSS. */\nconst SUBMENU_TRANSITION_MS = 220;\n\n/**\n * Single row inside a `<wr-context-menu>`. Mirrors `<wr-dropdown-item>` —\n * rendered as a menu item with an optional leading icon and an optional\n * nested `[submenu]` that opens to the right on hover.\n *\n * @example\n * ```html\n * <wr-context-menu #menu>\n * <wr-context-menu-item icon=\"copy\" (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item icon=\"more\" [submenu]=\"extras\">More…</wr-context-menu-item>\n * </wr-context-menu>\n *\n * <wr-context-menu #extras>\n * <wr-context-menu-item (click)=\"duplicate()\">Duplicate</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"archive()\">Archive</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu-item',\n templateUrl: './context-menu-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'menuitem',\n '[class]': 'classes()',\n '[attr.tabindex]': '-1',\n '[attr.aria-disabled]': 'disabled() ? true : null',\n '[attr.aria-haspopup]': 'submenu() ? \"menu\" : null',\n '[attr.aria-expanded]': 'submenu() ? (submenuOpen ? \"true\" : \"false\") : null',\n '[attr.aria-controls]': 'submenuId()',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave($event)',\n '(click)': 'onClick()',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n '(keydown.arrowRight)': 'onArrowRight($event)',\n '(keydown.arrowLeft)': 'onArrowLeft($event)',\n },\n imports: [WrIcon],\n})\nexport class WrContextMenuItem {\n /** Optional leading icon name. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n /** Disable interaction (suppresses pointer + keyboard). @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Optional nested `<wr-context-menu>`. When set, hovering the item\n * (or pressing →) opens it to the right with a chevron indicator.\n */\n readonly submenu = input<WrContextMenuPanel | null>(null);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-context-menu-item'];\n if (this.disabled()) parts.push('wr-context-menu-item--disabled');\n if (this.submenu()) parts.push('wr-context-menu-item--has-submenu');\n return parts.join(' ');\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n private submenuRef: OverlayRef | null = null;\n private submenuKeys: Subscription | null = null;\n private openTimer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n protected submenuOpen = false;\n /**\n * Whether the pending open was asked for by the keyboard (→ / Enter / Space)\n * rather than by hover — only then does the submenu take focus, the same rule\n * `wr-dropdown` applies to its own open. Sweeping the cursor across a row must\n * show its submenu without yanking the caret out of it.\n */\n private openedByKeyboard = false;\n\n /**\n * Id of the submenu's menu element while it is open, published on the item as\n * `aria-controls` — the same contract the root trigger keeps (see\n * {@link WrContextMenu}). Each submenu pane is its own overlay in the shared\n * container, so `aria-haspopup` / `aria-expanded` say that a submenu EXISTS\n * and is showing, and this says WHICH one.\n *\n * A signal, not a plain field like `submenuOpen`: host bindings re-run only\n * when something they read has changed, and this flips outside change\n * detection. Writing it is also what now refreshes `aria-expanded` next to\n * it, which used to depend on some unrelated work dirtying the view.\n *\n * @internal\n */\n protected readonly submenuId = signal<string | null>(null);\n\n /**\n * Global registry of open submenus keyed by the host element of the\n * item that owns them. Used to cascade-close descendants when a\n * parent submenu is disposed — Angular's onDestroy on detached\n * portals doesn't always tear down the deepest grand-children's\n * overlays in the right order, leaving orphaned floating panes.\n */\n private static readonly openSubmenus = new Map<HTMLElement, WrContextMenuItem>();\n\n /**\n * Dispose every open submenu pane on the page. Called by the root\n * `WrContextMenu` when its own overlay closes — destroyRef cascade\n * isn't reliable across separate overlay panes (each pane lives in\n * the CDK overlay container, not inside the parent pane's view).\n */\n static disposeAll(immediate: boolean): void {\n for (const [, owner] of [...WrContextMenuItem.openSubmenus]) {\n owner.disposeSubmenu(immediate);\n }\n }\n\n constructor() {\n this.destroyRef.onDestroy(() => this.disposeSubmenu(true));\n }\n\n /**\n * @internal Pointer activation — selecting a leaf item dismisses the\n * whole menu chain. The consumer's own `(click)` binding on the host\n * runs in the same event; we defer the close to a microtask so that\n * handler (the actual \"select\") always completes before the overlay\n * tears down, regardless of listener registration order. Items that\n * own a submenu (or are disabled) don't dismiss — clicking them just\n * drills into / ignores the row.\n */\n protected onClick(): void {\n if (this.disabled() || this.submenu()) return;\n queueMicrotask(() => WrContextMenu.closeActive());\n }\n\n /** @internal Keyboard activation — Enter / Space. */\n protected activate(event: Event): void {\n if (this.disabled()) return;\n if (this.submenu()) {\n event.preventDefault();\n this.openedByKeyboard = true;\n this.scheduleOpen(0);\n return;\n }\n event.preventDefault();\n this.host.nativeElement.click();\n }\n\n /**\n * @internal The arrow that walks INTO a submenu, which is the one pointing the\n * way the menu cascades: right in LTR, left in RTL. The panes mirror with the\n * reading direction (the CDK flips their placement), so a fixed ArrowRight\n * would ask an RTL user to press toward the parent to open the child.\n */\n protected onArrowRight(event: Event): void {\n if (this.isRtl()) return this.closeFromKey(event);\n this.openFromKey(event);\n }\n\n /** @internal The arrow that walks back OUT — the mirror of {@link onArrowRight}. */\n protected onArrowLeft(event: Event): void {\n if (this.isRtl()) return this.openFromKey(event);\n this.closeFromKey(event);\n }\n\n private openFromKey(event: Event): void {\n if (this.disabled() || !this.submenu()) return;\n event.preventDefault();\n this.openedByKeyboard = true;\n this.scheduleOpen(0);\n }\n\n private closeFromKey(event: Event): void {\n if (!this.submenu() || !this.submenuOpen) return;\n event.preventDefault();\n this.scheduleClose(0);\n }\n\n /** @internal Hover schedules a submenu open after a small delay. */\n protected onMouseEnter(): void {\n if (this.disabled() || !this.submenu()) return;\n this.cancelClose();\n this.openedByKeyboard = false;\n this.scheduleOpen(SUBMENU_OPEN_DELAY);\n }\n\n /** @internal Hover-out schedules a close with a grace window. */\n protected onMouseLeave(event: MouseEvent): void {\n if (!this.submenu()) return;\n this.cancelOpen();\n // Only skip the close when the cursor is moving into MY OWN submenu\n // (the user is drilling further down). Moving elsewhere — sibling\n // item, ancestor menu, or completely off the chain — should close\n // this item's submenu and let the cascade-on-dispose tear down any\n // descendants.\n if (this.relatedTargetIsInsideOwnSubmenu(event)) return;\n this.scheduleClose(SUBMENU_CLOSE_DELAY);\n }\n\n // Submenu lifecycle\n\n private scheduleOpen(delay: number): void {\n if (this.submenuRef) return;\n this.cancelOpen();\n if (delay === 0) {\n this.openSubmenu();\n return;\n }\n this.openTimer = setTimeout(() => {\n this.openTimer = null;\n this.openSubmenu();\n }, delay);\n }\n\n private scheduleClose(delay: number): void {\n this.cancelClose();\n if (delay === 0) {\n this.disposeSubmenu(false);\n return;\n }\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n this.disposeSubmenu(false);\n }, delay);\n }\n\n private cancelOpen(): void {\n if (this.openTimer !== null) {\n clearTimeout(this.openTimer);\n this.openTimer = null;\n }\n }\n\n private cancelClose(): void {\n if (this.closeTimer !== null) {\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private openSubmenu(): void {\n const panel = this.submenu();\n if (!panel || this.submenuRef) return;\n\n // Position to the right of the item, vertically aligned with the\n // item's top. Falls back to opening to the LEFT if there's no room.\n const positions: ConnectedPosition[] = [\n { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', offsetX: 4 },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', offsetX: -4 },\n ];\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(wrMirrorOffsets(positions, this.isRtl()))\n .withPush(true);\n\n this.submenuRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: ['wr-context-menu-overlay', 'wr-context-menu-overlay--submenu'],\n });\n\n const portal = new TemplatePortal(panel.contentTpl(), this.vcr);\n this.submenuRef.attach(portal);\n\n // Mirror the open animation pattern from the root menu directive.\n const pane = this.submenuRef.overlayElement;\n requestAnimationFrame(() => pane.classList.add('wr-context-menu-overlay--open'));\n\n // Name the pane's menu so the item can point at it — minted per open for\n // the same reason the root does it (a closing pane outlives its close).\n const menuEl = pane.querySelector<HTMLElement>('.wr-context-menu');\n if (menuEl) {\n menuEl.id = randomId('wr-context-menu');\n this.submenuId.set(menuEl.id);\n }\n\n // Track mouse entering / leaving the submenu so we don't auto-close\n // when the cursor crosses the gap between item and submenu pane.\n pane.addEventListener('mouseenter', this.onSubmenuEnter);\n pane.addEventListener('mouseleave', this.onSubmenuLeave);\n\n // While this pane is open it is the newest overlay that listens, so CDK's\n // keyboard dispatcher hands it every keydown and the root menu's own handler\n // stops seeing them. Which pane the keys then act on is decided in\n // `onSubmenuKeydown`, not here: a hover open leaves the caret where it was.\n this.submenuKeys = this.submenuRef.keydownEvents().subscribe(event => this.onSubmenuKeydown(event));\n\n // A keyboard open walks INTO the submenu; a hover open only shows it.\n if (this.openedByKeyboard) wrFocusMenuItemAt(pane, 0);\n\n this.submenuOpen = true;\n WrContextMenuItem.openSubmenus.set(this.host.nativeElement, this);\n }\n\n /**\n * @internal Keys routed here while this submenu is the topmost overlay: the\n * arrows walk the rows of the pane the caret is in, and Escape or the arrow\n * pointing BACK the way the menu cascades steps out one level, returning the\n * cursor to the row that owns the pane when the cursor was inside it.\n *\n * Escape closes this level only, not the whole chain — the APG's rule for a\n * submenu. It reaches this handler rather than the root's because the\n * dispatcher stops at the topmost overlay that listens, which is now this one.\n *\n * Which is also why the arrows are aimed at the pane holding the caret rather\n * than at this one. The dispatcher routes by stacking order, not by focus, and\n * a HOVER-opened submenu is topmost while focus is deliberately still on the\n * root row the pointer swept off (see `openedByKeyboard`) — so ArrowDown used\n * to jump into this pane's first row instead of moving down the menu the user\n * is in. Same reason `wr-dropdown`'s menu handler checks ownership.\n */\n private onSubmenuKeydown(event: KeyboardEvent): void {\n const pane = this.submenuRef?.overlayElement;\n if (!pane) return;\n // A row inside the pane already acted on this key — its own → into a deeper\n // submenu, or Enter on a leaf. Re-handling it here would close the pane out\n // from under the level it just opened.\n if (event.defaultPrevented) return;\n const active = document.activeElement;\n const focusedPane = active instanceof Element ? active.closest<HTMLElement>('.wr-context-menu-overlay') : null;\n const back = this.isRtl() ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === 'Escape' || event.key === back) {\n event.preventDefault();\n this.disposeSubmenu(false);\n // Onto the owning row only when the caret was in the pane just closed:\n // dismissing a submenu the pointer opened must not drag it off the row the\n // keyboard user is on.\n if (focusedPane === pane) this.host.nativeElement.focus();\n return;\n }\n // Falls back to this pane when the caret is outside every menu — nothing\n // else can answer, and the navigation opens at the first row from there.\n wrHandleMenuNavigation(focusedPane ?? pane, event);\n }\n\n /** Bound handlers (= preserves identity for removeEventListener). */\n private readonly onSubmenuEnter = (): void => {\n this.cancelClose();\n // Cursor is inside our pane — keep the whole chain (root + every\n // ancestor submenu) alive.\n WrContextMenu.keepChainAlive();\n };\n private readonly onSubmenuLeave = (event: MouseEvent): void => {\n // Only stay open if the cursor is moving into a DESCENDANT submenu\n // of ours (an item inside our pane opening its own submenu). Moving\n // back up to an ancestor menu, sideways to a sibling, or completely\n // off-chain should dismiss this submenu (cascade-on-dispose then\n // tears down any deeper levels we own).\n if (this.relatedTargetIsInsideDescendantSubmenu(event)) return;\n this.scheduleClose(SUBMENU_CLOSE_DELAY);\n // If the cursor left ALL menu panes (root + every submenu), tear\n // down the whole chain. Otherwise just close this pane and let the\n // user continue navigating ancestors.\n if (!this.relatedTargetIsInsideAnyMenu(event)) {\n WrContextMenu.scheduleChainClose();\n }\n };\n\n private relatedTargetIsInsideAnyMenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element)) return false;\n return !!related.closest('.wr-context-menu-overlay');\n }\n\n /**\n * `true` when the cursor moved from this item directly into the pane\n * of its own (just-opening) submenu — drilling down. Sibling items\n * and ancestor menus do NOT count.\n */\n private relatedTargetIsInsideOwnSubmenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element) || !this.submenuRef) return false;\n return this.submenuRef.overlayElement.contains(related);\n }\n\n /**\n * `true` when the cursor moved from our submenu pane into another\n * submenu pane whose owner-item lives INSIDE ours — the user is\n * drilling further down the chain (e.g., from the Share submenu into\n * the Export-as submenu). Moving back up the chain returns false so\n * we close.\n */\n private relatedTargetIsInsideDescendantSubmenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element) || !this.submenuRef) return false;\n const targetPane = related.closest('.wr-context-menu-overlay');\n if (!targetPane) return false;\n const myPane = this.submenuRef.overlayElement;\n if (targetPane === myPane) return true;\n // Find the owner-item of the pane the cursor is heading into. If\n // that owner-item is inside our own pane, the destination is a\n // descendant submenu.\n for (const [ownerEl, owner] of WrContextMenuItem.openSubmenus) {\n if (owner.submenuRef?.overlayElement === targetPane) {\n return myPane.contains(ownerEl);\n }\n }\n return false;\n }\n\n private disposeSubmenu(immediate: boolean): void {\n this.cancelOpen();\n this.cancelClose();\n const ref = this.submenuRef;\n if (!ref) return;\n this.submenuRef = null;\n this.submenuOpen = false;\n this.submenuId.set(null);\n // Now, not when the ref is finally disposed 220ms later: an overlay with a\n // keydown subscriber is where CDK's dispatcher STOPS looking, so a pane\n // still listening on its way out would swallow the arrows for the whole\n // exit animation and the root menu would go dead for a quarter of a second.\n this.submenuKeys?.unsubscribe();\n this.submenuKeys = null;\n WrContextMenuItem.openSubmenus.delete(this.host.nativeElement);\n\n const pane = ref.overlayElement;\n pane.removeEventListener('mouseenter', this.onSubmenuEnter);\n pane.removeEventListener('mouseleave', this.onSubmenuLeave);\n\n // Cascade-close any descendant submenus whose owner-item lives inside\n // the pane we're about to dispose. Without this, when a parent submenu\n // closes (via hover-out grace timer), a grandchild submenu whose owner\n // is rendered inside the parent's portal is orphaned — its OverlayRef\n // stays alive in the DOM with no parent to reach it from.\n for (const [ownerEl, owner] of WrContextMenuItem.openSubmenus) {\n if (pane.contains(ownerEl)) owner.disposeSubmenu(immediate);\n }\n\n if (immediate) {\n ref.dispose();\n return;\n }\n pane.classList.remove('wr-context-menu-overlay--open');\n setTimeout(() => ref.dispose(), SUBMENU_TRANSITION_MS);\n }\n\n /**\n * Whether the app reads right-to-left.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a\n * component that works, and defaulting to LTR is the honest fallback.\n */\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\n }\n}\n","@if (icon(); as name) {\n <wr-icon class=\"wr-context-menu-item__icon\" [name]=\"name\" size=\"14\" />\n}\n<span class=\"wr-context-menu-item__label\"><ng-content /></span>\n@if (submenu()) {\n <svg\n class=\"wr-icon__svg wr-context-menu-item__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport {\n type ConnectedPosition,\n type FlexibleConnectedPositionStrategyOrigin,\n type OverlayRef,\n ScrollStrategyOptions,\n} from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { DestroyRef, Directive, ElementRef, ViewContainerRef, inject, input, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport type { Subscription } from 'rxjs';\n\nimport { WR_OVERLAY, WrOutsideClick } from 'ngwr/overlay';\nimport { randomId } from 'ngwr/utils';\n\nimport { WrContextMenuItem } from './context-menu-item';\nimport type { WrContextMenuPanel } from './context-menu-panel';\nimport { wrFocusMenuItemAt, wrHandleMenuNavigation } from './menu-focus';\n\n/**\n * Where the menu may hang off the pointer, best first: down-and-inline-start of\n * the cursor (what a native context menu does), then flipped up, then across,\n * then both.\n *\n * The origin is a zero-size POINT, so every `originX` / `originY` resolves to\n * the same coordinate and only the overlay's own corner varies. `overlayX:\n * 'start'` is the logical corner: CDK resolves it against the ambient reading\n * direction, so an RTL page opens the menu to the LEFT of the cursor without a\n * second table.\n */\nconst POINTER_POSITIONS: ConnectedPosition[] = [\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'bottom' },\n];\n\n/**\n * The pointer as a CDK origin: a zero-size rect at the click, in VIEWPORT\n * coordinates.\n *\n * Live getters rather than a snapshot, and that is the whole trick. The menu is\n * anchored to the DOCUMENT — as the page scrolls it travels with the content it\n * was opened over (native + PrimeNG behaviour) — while CDK positions against\n * the viewport. Reading the scroll offset at `apply()` time is what converts one\n * into the other, so a re-anchor is nothing but a request to re-apply.\n */\nfunction pointerOrigin(pageX: number, pageY: number): FlexibleConnectedPositionStrategyOrigin {\n return {\n width: 0,\n height: 0,\n get x(): number {\n return pageX - window.scrollX;\n },\n get y(): number {\n return pageY - window.scrollY;\n },\n };\n}\n\n/**\n * Attach to any element to show a `<wr-context-menu>` at the pointer\n * position when the user right-clicks or otherwise sends a `contextmenu`\n * event (Shift+F10, etc.). The native browser menu is suppressed for the\n * host element.\n *\n * @example\n * ```html\n * <div [wrContextMenu]=\"menu\">Right-click me</div>\n * <wr-context-menu #menu>\n * <wr-context-menu-item (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n *\n * @see https://ngwr.dev/reference/components/context-menu\n */\n@Directive({\n selector: '[wrContextMenu]',\n host: {\n class: 'wr-context-menu-host',\n '[attr.aria-controls]': 'openMenuId()',\n '(contextmenu)': 'onContextMenu($event)',\n '(pointerdown)': 'onPointerDown($event)',\n '(pointermove)': 'onPointerMove($event)',\n '(pointerup)': 'onPointerUp()',\n '(pointercancel)': 'onPointerUp()',\n },\n})\nexport class WrContextMenu {\n /** Menu to open. Pass a `<wr-context-menu>` template reference. */\n readonly menu = input.required<WrContextMenuPanel>({ alias: 'wrContextMenu' });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n /**\n * Id of the menu element while this trigger's menu is open, published on the\n * host as `aria-controls`. The pane is portalled into the overlay container, a\n * sibling of the whole app, so this reference is the ONLY link between a\n * trigger and the menu it opened — for a screen reader, and for anything else\n * that has to find it. Cleared on close, which is also what tells an open\n * trigger from a closing one: the pane itself lingers for the exit animation.\n *\n * A signal, not a plain field: host bindings re-run only when something they\n * READ has changed, and this one flips outside change detection (from a\n * pointer handler, and from `onDestroy`). Held as a plain string it published\n * the id on open — the overlay attach happens to dirty the host view — and\n * then kept it forever, so the trigger still pointed at a menu that was gone.\n *\n * @internal\n */\n protected readonly openMenuId = signal<string | null>(null);\n\n private overlayRef: OverlayRef | null = null;\n /**\n * The open menu's subscription to CDK's keyboard dispatcher, held so that\n * `closeOverlay()` can drop it — see the unsubscribe there for why the pane's\n * own disposal is 220 ms too late.\n */\n private rootKeys: Subscription | null = null;\n /**\n * Where the keyboard was at the moment this menu took it, so a close can put\n * it back there. Null when it was nowhere in particular (`<body>`) or already\n * inside a menu pane, neither of which is a place to return to.\n */\n private restoreFocusTo: HTMLElement | null = null;\n /**\n * Panes waiting out their exit animation, keyed by the timer that disposes\n * them.\n *\n * A SET, because one handle cannot hold two closings. It used to be a single\n * `closingTimer`, and the second close inside the 220ms window cleared the\n * first one's timer instead of its own — so the previous pane's `dispose()`\n * never ran. `onContextMenu` closes and immediately re-opens, so right-clicking\n * one target faster than the animation orphaned a pane per click: an\n * `opacity: 0` box with `pointer-events: auto` eating clicks, a never-destroyed\n * embedded view, a capture-phase document scroll listener still moving it, and\n * an undetached ref still registered with CDK's keyboard dispatcher — which\n * swallowed Escape for the whole page.\n */\n private readonly closingPanes = new Map<ReturnType<typeof setTimeout>, OverlayRef>();\n private leaveTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Touch long-press → open. Right-click keeps using `(contextmenu)`.\n private pressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressX = 0;\n private pressY = 0;\n private pressPageX = 0;\n private pressPageY = 0;\n private lastLongPressAt = 0;\n private cancelPressScroll: (() => void) | null = null;\n\n /**\n * Single open root menu at a time. Submenu items use this to signal\n * chain-level hover state: when the cursor enters ANY pane in the\n * chain (root or submenu) `keepChainAlive()` cancels the close timer;\n * when the cursor leaves ALL panes `scheduleChainClose()` starts it.\n * The whole chain (root → submenus) tears down through the root's\n * close (submenus react to their owner-item destroyRef + the static\n * registry in `WrContextMenuItem`).\n */\n private static activeRoot: WrContextMenu | null = null;\n\n /** Called from a submenu pane's mouseenter — keep the whole chain alive. */\n static keepChainAlive(): void {\n WrContextMenu.activeRoot?.cancelLeaveTimer();\n }\n\n /** Called from a submenu pane's mouseleave when the cursor left ALL menus. */\n static scheduleChainClose(): void {\n WrContextMenu.activeRoot?.scheduleLeave();\n }\n\n /**\n * Called from a `<wr-context-menu-item>` click — selecting an item\n * dismisses the whole chain (root + any open submenus). Items live in\n * a detached overlay portal, so they reach their owning root through\n * this static handle rather than DI.\n */\n static closeActive(): void {\n WrContextMenu.activeRoot?.closeOverlay();\n }\n\n /**\n * Open/close animation duration in ms. Matches the longest SCSS\n * transition on `.wr-context-menu-overlay` (the spring-scale curve).\n * The directive holds the overlay alive for this long during close\n * so the exit animation can play before the pane is removed from\n * the DOM.\n */\n private static readonly TRANSITION_MS = 220;\n /**\n * Grace window after the cursor leaves the root pane. Long enough\n * for the user to dip momentarily into the gap between the root and\n * a submenu (or back from a submenu), short enough to feel snappy\n * on a deliberate hover-out.\n */\n private static readonly LEAVE_DELAY = 240;\n\n /** Hold duration before a touch long-press opens the menu. */\n private static readonly LONG_PRESS_MS = 500;\n /** Finger travel (px) that turns a pending long-press into a scroll/drag. */\n private static readonly PRESS_MOVE_TOLERANCE = 10;\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.cancelPress();\n this.closeOverlay();\n // Whatever is still fading out goes now: the timers that would have\n // disposed those panes belong to a directive that no longer exists.\n for (const [timer, ref] of this.closingPanes) {\n clearTimeout(timer);\n ref.dispose();\n }\n this.closingPanes.clear();\n });\n }\n\n /** @internal Right-click handler — opens at the pointer (or re-positions if already open). */\n protected onContextMenu(event: MouseEvent): void {\n event.preventDefault();\n // Some touch browsers (Android Chrome) fire a synthetic `contextmenu`\n // right after a long-press has already opened the menu — swallow it so it\n // doesn't re-open / restart the animation.\n if (Date.now() - this.lastLongPressAt < 700) return;\n event.stopPropagation();\n // Re-open at the new position even if it was already open.\n // Use page coords (document-relative) so the menu anchors to the\n // zone it was opened over — scrolling the page carries the menu\n // along with the content, matching native + PrimeNG behavior.\n this.closeOverlay();\n this.openOverlay(event.pageX, event.pageY);\n }\n\n /**\n * @internal Touch/pen long-press → open the menu at the press point. Desktop\n * right-click stays on `(contextmenu)`; this path is filtered to non-mouse\n * pointers. Deliberately does NOT `preventDefault`/`setPointerCapture` or set\n * `touch-action` — a press that turns into a scroll must still scroll, so the\n * open is cancelled on movement (> tolerance), on scroll, and on early lift.\n */\n protected onPointerDown(event: PointerEvent): void {\n if (event.pointerType === 'mouse' || !event.isPrimary || this.pressTimer !== null) return;\n this.pressX = event.clientX;\n this.pressY = event.clientY;\n this.pressPageX = event.pageX;\n this.pressPageY = event.pageY;\n this.pressTimer = setTimeout(() => {\n this.pressTimer = null;\n this.cancelPress();\n this.lastLongPressAt = Date.now();\n this.closeOverlay();\n this.openOverlay(this.pressPageX, this.pressPageY);\n }, WrContextMenu.LONG_PRESS_MS);\n const onScroll = (): void => this.cancelPress();\n document.addEventListener('scroll', onScroll, { capture: true, passive: true });\n this.cancelPressScroll = (): void => document.removeEventListener('scroll', onScroll, { capture: true });\n }\n\n /** @internal Finger moved too far before the hold fired — it's a scroll/drag. */\n protected onPointerMove(event: PointerEvent): void {\n if (this.pressTimer === null) return;\n if (Math.hypot(event.clientX - this.pressX, event.clientY - this.pressY) > WrContextMenu.PRESS_MOVE_TOLERANCE) {\n this.cancelPress();\n }\n }\n\n /** @internal Lifted (or the browser claimed the gesture) before the hold fired. */\n protected onPointerUp(): void {\n this.cancelPress();\n }\n\n private cancelPress(): void {\n if (this.pressTimer !== null) {\n clearTimeout(this.pressTimer);\n this.pressTimer = null;\n }\n this.cancelPressScroll?.();\n this.cancelPressScroll = null;\n }\n\n /** Close the menu. */\n close(): void {\n this.closeOverlay();\n }\n\n // Overlay\n\n private openOverlay(x: number, y: number): void {\n // Read before `wrFocusMenuItemAt` below takes the keyboard: this is the\n // element the close hands it back to. A pane row is not a candidate — a\n // previous menu may still be fading out — and neither is `<body>`, which is\n // where focus already is when nobody has it.\n const active = document.activeElement;\n this.restoreFocusTo =\n active instanceof HTMLElement && active !== document.body && !active.closest('.wr-context-menu-overlay')\n ? active\n : null;\n\n // Anchored to the POINTER, which is not an element — CDK takes a virtual\n // origin for exactly that, and a FLEXIBLE strategy is what makes the menu\n // flip up (or across) instead of hanging off the edge of the screen. It used\n // to be a bare `GlobalPositionStrategy` with the raw coordinates written\n // onto the pane, which never measured the menu against the viewport: a\n // right-click 6px above the bottom of the window put two of the three rows\n // below the fold and clipped the third, since the pane is `position: fixed`\n // and cannot be scrolled to. Submenus have used the flexible strategy from\n // the start (`context-menu-item.ts`); only the root skipped it.\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(pointerOrigin(x, y))\n // The menu sizes itself; the fallbacks below are the whole answer to a\n // cramped viewport, and `withPush` clamps whatever is left over.\n .withFlexibleDimensions(false)\n .withPush(true)\n .withPositions(POINTER_POSITIONS);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n // `noop` so scroll doesn't dismiss the menu — `sync()` below re-anchors it\n // instead.\n scrollStrategy: this.scrollStrategies.noop(),\n panelClass: ['wr-context-menu-overlay'],\n });\n\n const portal = new TemplatePortal(this.menu().contentTpl(), this.vcr);\n this.overlayRef.attach(portal);\n // `attach()` defers CDK's first placement into `afterNextRender`. Place it\n // now: until then the pane sits at the container's top-left corner, and the\n // rows are already in the DOM (see `wrFocusMenuItemAt` below), so the\n // measurement the flip depends on is available.\n this.overlayRef.updatePosition();\n\n const pane = this.overlayRef.overlayElement;\n\n // Name the menu we just opened so the host can point at it. The id is\n // minted per OPEN rather than living on the panel: `closeOverlay()` keeps\n // the previous pane in the DOM for its exit animation, so a re-open would\n // otherwise leave two elements answering to the same id — with the dying\n // one first in document order.\n const menuEl = pane.querySelector<HTMLElement>('.wr-context-menu');\n if (menuEl) {\n menuEl.id = randomId('wr-context-menu');\n this.openMenuId.set(menuEl.id);\n }\n\n // Re-anchor. `pointerOrigin` reads the scroll offset afresh, so this is all\n // it takes for the menu to travel with the content it was opened over.\n //\n // `reapplyLastPosition()` rather than `updatePosition()`: the flip is\n // decided once, when the menu opens. Re-running the fallback list on every\n // scroll event would let the menu hop from above the cursor to below it and\n // back while the page moves under it, which is a worse reading of \"the menu\n // stays where you put it\" than a menu that simply slides with the page.\n const sync = (): void => positionStrategy.reapplyLastPosition();\n\n // Move the keyboard INTO the menu. Without this the pane painted a\n // `role=\"menu\"` that could be seen and never entered: rows are\n // `tabindex=\"-1\"` (the roving-focus contract) and the pane is not a tab\n // stop, so ArrowDown / Enter / ArrowRight all went to whatever still held\n // focus behind the menu and only Escape worked — the dispatcher routes that\n // one regardless of focus.\n //\n // Unconditional, unlike `wr-dropdown`'s `openedByPointer` gate: there is no\n // hover open here. Every path into this method is a deliberate request for\n // the menu (right-click, Shift+F10, the Menu key, a long-press), which is\n // also when a native context menu takes the keyboard.\n //\n // Synchronous, and it can be: `attach()` above runs the embedded view's\n // first change detection itself (CDK's `attachTemplatePortal`), so the rows\n // and their `[class]` host binding are already in the DOM.\n wrFocusMenuItemAt(pane, 0);\n\n // Trigger the open transition on the next frame — adding the class\n // synchronously with attach would skip the initial 0→1 frame and\n // the menu would just appear without animating.\n requestAnimationFrame(() => pane.classList.add('wr-context-menu-overlay--open'));\n\n // Hover-out closes the menu after a grace window, unless the\n // cursor moved INTO a descendant submenu (any other\n // `.wr-context-menu-overlay`). Re-entering the root cancels the\n // scheduled close so the user can dip out and back without losing\n // the menu.\n const onPaneLeave = (event: MouseEvent): void => {\n const related = event.relatedTarget;\n // Moving into ANY other menu pane (a submenu) keeps the chain\n // alive — the submenu's own mouseenter will cancel any pending\n // chain-close. Only schedule when the cursor genuinely left the\n // chain.\n if (related instanceof Element && related.closest('.wr-context-menu-overlay')) return;\n this.scheduleLeave();\n };\n const onPaneEnter = (): void => this.cancelLeaveTimer();\n pane.addEventListener('mouseleave', onPaneLeave);\n pane.addEventListener('mouseenter', onPaneEnter);\n WrContextMenu.activeRoot = this;\n this.overlayRef.detachments().subscribe(() => {\n pane.removeEventListener('mouseleave', onPaneLeave);\n pane.removeEventListener('mouseenter', onPaneEnter);\n });\n // Capture-phase listener on document catches scroll events from ANY\n // ancestor (window, html, body, custom scroll containers), so the\n // menu stays anchored to the click position even inside scrollable\n // layouts.\n document.addEventListener('scroll', sync, { capture: true, passive: true });\n // On resize the page layout reflows — the original pageX/pageY no\n // longer points at whatever the user right-clicked. Dismiss the menu\n // rather than dragging it across a now-stale coordinate (matches\n // PrimeNG / native behavior).\n const onResize = (): void => this.closeOverlay();\n window.addEventListener('resize', onResize, { passive: true });\n this.overlayRef.detachments().subscribe(() => {\n document.removeEventListener('scroll', sync, { capture: true });\n window.removeEventListener('resize', onResize);\n });\n\n // The right-click that opens the menu still has `mouseup` + `auxclick`\n // events pending, and the outside-click source fires on `auxclick` — which\n // would close the menu the instant the user lifts their finger. Two-part\n // guard:\n // 1. Track the open timestamp.\n // 2. Ignore any outside events that arrive within a short window\n // after the open (long enough to cover the original mouseup +\n // auxclick, short enough that a deliberate second click is\n // still respected).\n const openedAt = performance.now();\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (performance.now() - openedAt < 200) return;\n this.closeOverlay();\n });\n\n this.rootKeys = this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.closeOverlay();\n return;\n }\n if (event.key === 'Tab') {\n // Let focus leave naturally — `closeOverlay()` hands it back to the\n // trigger first, so Tab continues from there instead of from a pane\n // that is about to be removed.\n this.closeOverlay();\n return;\n }\n // A row's own handler already acted on this key (ArrowRight into a\n // submenu, Enter on an item): `preventDefault()` is how it says so, and\n // moving the cursor on top of that would undo it.\n if (event.defaultPrevented) return;\n wrHandleMenuNavigation(pane, event);\n });\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n // Read up front, before the teardown below starts on the panes: the answer\n // wanted is where the keyboard was at the moment of dismissal.\n const active = document.activeElement;\n const focusWasInside = active instanceof Element && active.closest('.wr-context-menu-overlay') !== null;\n const restoreTo = this.restoreFocusTo;\n this.restoreFocusTo = null;\n this.cancelLeaveTimer();\n // Drop the reference immediately: the pane below stays in the DOM until the\n // exit animation has played, and a trigger still pointing at a menu on its\n // way out reads as open.\n this.openMenuId.set(null);\n if (WrContextMenu.activeRoot === this) WrContextMenu.activeRoot = null;\n // Submenu panes live in the CDK overlay container, not inside the\n // root pane's view — destroyRef cascade through portal detach\n // doesn't reach them. Close them all explicitly first so they\n // don't float when the root is dismissed (outside-click, Esc, etc).\n WrContextMenuItem.disposeAll(false);\n const ref = this.overlayRef;\n const pane = ref.overlayElement;\n // Detach immediately would skip the exit animation. Remove the open\n // class first so the SCSS transition runs back to the default\n // (faded + scaled-down) state, then dispose after the transition.\n pane.classList.remove('wr-context-menu-overlay--open');\n // …and stop it hit-testing on the way out. Fading to `opacity: 0` does not\n // stop a pane receiving pointer events — `.cdk-overlay-pane` sets\n // `pointer-events: auto` — so for the whole 220 ms an invisible menu kept\n // swallowing clicks meant for the page underneath, and a second click on\n // the item just picked (a double-click, or Escape then click) re-ran the\n // consumer's action. Written inline rather than in `styles/_index.scss`\n // because the closing state has no class of its own, and inline beats the\n // CDK's own sheet without an `!important`.\n pane.style.pointerEvents = 'none';\n // …and stop it taking the page's KEYS on the way out, for the same reason\n // and with the same timing. An overlay with a keydown subscriber is where\n // CDK's dispatcher stops looking, and it is removed from the dispatcher only\n // by `detach()` / `dispose()` — which is 220 ms away — so a dismissed menu\n // went on swallowing every keydown on the page: ArrowDown pulled real focus\n // back onto a row of the invisible pane, and a second Escape meant for the\n // dialog underneath was `preventDefault`ed and did nothing.\n // `WrContextMenuItem.disposeSubmenu()` does exactly this; the root had not.\n this.rootKeys?.unsubscribe();\n this.rootKeys = null;\n const timer = setTimeout(() => {\n this.closingPanes.delete(timer);\n ref.dispose();\n }, WrContextMenu.TRANSITION_MS);\n this.closingPanes.set(timer, ref);\n // Mark immediately so a subsequent right-click opens a fresh menu\n // rather than landing on the disposing one.\n this.overlayRef = null;\n // Hand the keyboard back. The menu takes focus on open, so a dismissal that\n // left it in the pane would strand it on `<body>` once the pane is disposed\n // and the next Tab would restart at the top of the document. Only when the\n // caret was actually in the chain: Escape reaches this overlay from anywhere\n // on the page (CDK's dispatcher routes it by stacking order, not by focus),\n // and a menu nobody was in must not steal the caret from a field they are.\n if (focusWasInside) this.handBackFocus(restoreTo);\n }\n\n /**\n * Put the keyboard back where it came from.\n *\n * The element that had it when the menu opened comes first: a context menu\n * hangs on a REGION — a card, a table row — and Shift+F10 / the Menu key fires\n * `contextmenu` at whatever control inside it the user was actually on, which\n * is their place in the page.\n *\n * The trigger is the fallback, and it needs help to be one. `[wrContextMenu]`\n * adds no `tabindex` and every shape the docs ship is a plain `<div>`, so\n * `focus()` on it does nothing at all — the handback silently missed, leaving\n * the caret in the disposing pane and then on `<body>`, which is the outcome\n * the call is there to prevent. Lending it `tabindex=\"-1\"` for the call and\n * taking that back on blur keeps the consumer's DOM as they wrote it; a\n * permanent `tabindex=\"0\"` would make every right-clickable region a tab stop,\n * which is their decision and not the library's.\n */\n private handBackFocus(previous: HTMLElement | null): void {\n const target =\n previous?.isConnected && !previous.closest('.wr-context-menu-overlay') ? previous : this.host.nativeElement;\n target.focus();\n // Asking whether it took, rather than deciding up front whether it can: the\n // focusability rules are wide (an `<a>` needs an href, a `<div>` needs a\n // tabindex, `inert`/`disabled` opt out) and `document.activeElement` answers\n // all of them at once.\n if (document.activeElement === target) return;\n target.setAttribute('tabindex', '-1');\n target.focus();\n target.addEventListener('blur', () => target.removeAttribute('tabindex'), { once: true });\n }\n\n private cancelLeaveTimer(): void {\n if (this.leaveTimer !== null) {\n clearTimeout(this.leaveTimer);\n this.leaveTimer = null;\n }\n }\n\n private scheduleLeave(): void {\n this.cancelLeaveTimer();\n this.leaveTimer = setTimeout(() => {\n this.leaveTimer = null;\n this.closeOverlay();\n }, WrContextMenu.LEAVE_DELAY);\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, TemplateRef, ViewEncapsulation, viewChild } from '@angular/core';\n\n/**\n * Container for the rows shown when a {@link WrContextMenu} opens.\n * The component itself doesn't render; the directive portals the inner\n * template into an overlay positioned at the pointer.\n *\n * @example\n * ```html\n * <div [wrContextMenu]=\"menu\">Right-click me</div>\n * <wr-context-menu #menu>\n * <wr-context-menu-item icon=\"copy\" (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item icon=\"trash\" (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu',\n template: '<ng-template><div class=\"wr-context-menu\" role=\"menu\"><ng-content /></div></ng-template>',\n exportAs: 'wrContextMenu',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrContextMenuPanel {\n /** The internal template the directive portals into the overlay. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation } from '@angular/core';\n\n/**\n * Thin horizontal separator inside a `<wr-context-menu>`. Use it to\n * group related items (e.g., a destructive action below a divider, or\n * a \"More\" section below the primary items).\n *\n * @example\n * ```html\n * <wr-context-menu #menu>\n * <wr-context-menu-item (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"paste()\">Paste</wr-context-menu-item>\n * <wr-context-menu-divider />\n * <wr-context-menu-item (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu-divider',\n template: '',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-context-menu-divider',\n role: 'separator',\n 'aria-orientation': 'horizontal',\n },\n})\nexport class WrContextMenuDivider {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-context-menu.mjs","sources":["../../../projects/lib/context-menu/menu-focus.ts","../../../projects/lib/context-menu/context-menu-item.ts","../../../projects/lib/context-menu/context-menu-item.html","../../../projects/lib/context-menu/context-menu.ts","../../../projects/lib/context-menu/context-menu-panel.ts","../../../projects/lib/context-menu/context-menu-divider.ts","../../../projects/lib/context-menu/ngwr-context-menu.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * Roving focus inside ONE context-menu pane.\n *\n * The APG menu pattern makes a menu a single tab stop and moves a focus cursor\n * between its rows with the arrows — which is why every `<wr-context-menu-item>`\n * carries `tabindex=\"-1\"`. Shared by the root directive and by\n * `WrContextMenuItem`'s submenu because a submenu is a SEPARATE overlay pane\n * rather than nested DOM: each pane roves over its own rows, and CDK's keyboard\n * dispatcher hands the key to the topmost one, which is the pane the user is in.\n *\n * @internal\n */\n\n/**\n * The rows of one pane the cursor may land on. Disabled rows are not stops —\n * the same rule `WrDropdown` follows.\n */\nexport function wrMenuItems(pane: HTMLElement): readonly HTMLElement[] {\n return Array.from(pane.querySelectorAll<HTMLElement>('.wr-context-menu-item:not(.wr-context-menu-item--disabled)'));\n}\n\n/** Focus the row at `index`, wrapping at both ends. A pane with no rows is left alone. */\nexport function wrFocusMenuItemAt(pane: HTMLElement, index: number): void {\n const items = wrMenuItems(pane);\n if (items.length === 0) return;\n const clamped = ((index % items.length) + items.length) % items.length;\n items[clamped]?.focus();\n}\n\n/**\n * ArrowDown / ArrowUp / Home / End over one pane's rows. Returns `true` when the\n * key was consumed, so a caller can leave every other key alone.\n */\nexport function wrHandleMenuNavigation(pane: HTMLElement, event: KeyboardEvent): boolean {\n const items = wrMenuItems(pane);\n if (items.length === 0) return false;\n const active = document.activeElement;\n // -1 when the keyboard is not on a row yet, which makes ArrowDown open at the\n // first row and ArrowUp at the last.\n const index = active instanceof HTMLElement ? items.indexOf(active) : -1;\n switch (event.key) {\n case 'ArrowDown':\n wrFocusMenuItemAt(pane, index + 1);\n break;\n case 'ArrowUp':\n wrFocusMenuItemAt(pane, index <= 0 ? items.length - 1 : index - 1);\n break;\n case 'Home':\n wrFocusMenuItemAt(pane, 0);\n break;\n case 'End':\n wrFocusMenuItemAt(pane, items.length - 1);\n break;\n default:\n return false;\n }\n event.preventDefault();\n return true;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type ConnectedPosition, type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n ViewContainerRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport type { Subscription } from 'rxjs';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { WR_OVERLAY, wrMirrorOffsets } from 'ngwr/overlay';\nimport { randomId } from 'ngwr/utils';\n\nimport { WrContextMenu } from './context-menu';\nimport type { WrContextMenuPanel } from './context-menu-panel';\nimport { wrFocusMenuItemAt, wrHandleMenuNavigation } from './menu-focus';\n\n/** Hover delay (ms) before a submenu opens. */\nconst SUBMENU_OPEN_DELAY = 120;\n/** Grace window (ms) before a submenu closes when the cursor leaves it. */\nconst SUBMENU_CLOSE_DELAY = 240;\n/** Animation duration of the submenu — mirrors the root menu CSS. */\nconst SUBMENU_TRANSITION_MS = 220;\n\n/**\n * Single row inside a `<wr-context-menu>`. Mirrors `<wr-dropdown-item>` —\n * rendered as a menu item with an optional leading icon and an optional\n * nested `[submenu]` that opens to the right on hover.\n *\n * @example\n * ```html\n * <wr-context-menu #menu>\n * <wr-context-menu-item icon=\"copy\" (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item icon=\"more\" [submenu]=\"extras\">More…</wr-context-menu-item>\n * </wr-context-menu>\n *\n * <wr-context-menu #extras>\n * <wr-context-menu-item (click)=\"duplicate()\">Duplicate</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"archive()\">Archive</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu-item',\n templateUrl: './context-menu-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'menuitem',\n '[class]': 'classes()',\n '[attr.tabindex]': '-1',\n '[attr.aria-disabled]': 'disabled() ? true : null',\n '[attr.aria-haspopup]': 'submenu() ? \"menu\" : null',\n '[attr.aria-expanded]': 'submenu() ? (submenuOpen ? \"true\" : \"false\") : null',\n '[attr.aria-controls]': 'submenuId()',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave($event)',\n '(click)': 'onClick()',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n '(keydown.arrowRight)': 'onArrowRight($event)',\n '(keydown.arrowLeft)': 'onArrowLeft($event)',\n },\n imports: [WrIcon],\n})\nexport class WrContextMenuItem {\n /** Optional leading icon name. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n /** Disable interaction (suppresses pointer + keyboard). @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Optional nested `<wr-context-menu>`. When set, hovering the item\n * (or pressing →) opens it to the right with a chevron indicator.\n */\n readonly submenu = input<WrContextMenuPanel | null>(null);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-context-menu-item'];\n if (this.disabled()) parts.push('wr-context-menu-item--disabled');\n if (this.submenu()) parts.push('wr-context-menu-item--has-submenu');\n return parts.join(' ');\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n private submenuRef: OverlayRef | null = null;\n private submenuKeys: Subscription | null = null;\n private openTimer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n protected submenuOpen = false;\n /**\n * Whether the pending open was asked for by the keyboard (→ / Enter / Space)\n * rather than by hover — only then does the submenu take focus, the same rule\n * `wr-dropdown` applies to its own open. Sweeping the cursor across a row must\n * show its submenu without yanking the caret out of it.\n */\n private openedByKeyboard = false;\n\n /**\n * Id of the submenu's menu element while it is open, published on the item as\n * `aria-controls` — the same contract the root trigger keeps (see\n * {@link WrContextMenu}). Each submenu pane is its own overlay in the shared\n * container, so `aria-haspopup` / `aria-expanded` say that a submenu EXISTS\n * and is showing, and this says WHICH one.\n *\n * A signal, not a plain field like `submenuOpen`: host bindings re-run only\n * when something they read has changed, and this flips outside change\n * detection. Writing it is also what now refreshes `aria-expanded` next to\n * it, which used to depend on some unrelated work dirtying the view.\n *\n * @internal\n */\n protected readonly submenuId = signal<string | null>(null);\n\n /**\n * Global registry of open submenus keyed by the host element of the\n * item that owns them. Used to cascade-close descendants when a\n * parent submenu is disposed — Angular's onDestroy on detached\n * portals doesn't always tear down the deepest grand-children's\n * overlays in the right order, leaving orphaned floating panes.\n */\n private static readonly openSubmenus = new Map<HTMLElement, WrContextMenuItem>();\n\n /**\n * Dispose every open submenu pane on the page. Called by the root\n * `WrContextMenu` when its own overlay closes — destroyRef cascade\n * isn't reliable across separate overlay panes (each pane lives in\n * the CDK overlay container, not inside the parent pane's view).\n */\n static disposeAll(immediate: boolean): void {\n for (const [, owner] of [...WrContextMenuItem.openSubmenus]) {\n owner.disposeSubmenu(immediate);\n }\n }\n\n constructor() {\n this.destroyRef.onDestroy(() => this.disposeSubmenu(true));\n }\n\n /**\n * @internal Pointer activation — selecting a leaf item dismisses the\n * whole menu chain. The consumer's own `(click)` binding on the host\n * runs in the same event; we defer the close to a microtask so that\n * handler (the actual \"select\") always completes before the overlay\n * tears down, regardless of listener registration order. Items that\n * own a submenu (or are disabled) don't dismiss — clicking them just\n * drills into / ignores the row.\n */\n protected onClick(): void {\n if (this.disabled() || this.submenu()) return;\n queueMicrotask(() => WrContextMenu.closeActive());\n }\n\n /** @internal Keyboard activation — Enter / Space. */\n protected activate(event: Event): void {\n if (this.disabled()) return;\n if (this.submenu()) {\n event.preventDefault();\n this.openedByKeyboard = true;\n this.scheduleOpen(0);\n return;\n }\n event.preventDefault();\n this.host.nativeElement.click();\n }\n\n /**\n * @internal The arrow that walks INTO a submenu, which is the one pointing the\n * way the menu cascades: right in LTR, left in RTL. The panes mirror with the\n * reading direction (the CDK flips their placement), so a fixed ArrowRight\n * would ask an RTL user to press toward the parent to open the child.\n */\n protected onArrowRight(event: Event): void {\n if (this.isRtl()) return this.closeFromKey(event);\n this.openFromKey(event);\n }\n\n /** @internal The arrow that walks back OUT — the mirror of {@link onArrowRight}. */\n protected onArrowLeft(event: Event): void {\n if (this.isRtl()) return this.openFromKey(event);\n this.closeFromKey(event);\n }\n\n private openFromKey(event: Event): void {\n if (this.disabled() || !this.submenu()) return;\n event.preventDefault();\n this.openedByKeyboard = true;\n this.scheduleOpen(0);\n }\n\n private closeFromKey(event: Event): void {\n if (!this.submenu() || !this.submenuOpen) return;\n event.preventDefault();\n this.scheduleClose(0);\n }\n\n /** @internal Hover schedules a submenu open after a small delay. */\n protected onMouseEnter(): void {\n if (this.disabled() || !this.submenu()) return;\n this.cancelClose();\n this.openedByKeyboard = false;\n this.scheduleOpen(SUBMENU_OPEN_DELAY);\n }\n\n /** @internal Hover-out schedules a close with a grace window. */\n protected onMouseLeave(event: MouseEvent): void {\n if (!this.submenu()) return;\n this.cancelOpen();\n // Only skip the close when the cursor is moving into MY OWN submenu\n // (the user is drilling further down). Moving elsewhere — sibling\n // item, ancestor menu, or completely off the chain — should close\n // this item's submenu and let the cascade-on-dispose tear down any\n // descendants.\n if (this.relatedTargetIsInsideOwnSubmenu(event)) return;\n this.scheduleClose(SUBMENU_CLOSE_DELAY);\n }\n\n // Submenu lifecycle\n\n private scheduleOpen(delay: number): void {\n if (this.submenuRef) return;\n this.cancelOpen();\n if (delay === 0) {\n this.openSubmenu();\n return;\n }\n this.openTimer = setTimeout(() => {\n this.openTimer = null;\n this.openSubmenu();\n }, delay);\n }\n\n private scheduleClose(delay: number): void {\n this.cancelClose();\n if (delay === 0) {\n this.disposeSubmenu(false);\n return;\n }\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n this.disposeSubmenu(false);\n }, delay);\n }\n\n private cancelOpen(): void {\n if (this.openTimer !== null) {\n clearTimeout(this.openTimer);\n this.openTimer = null;\n }\n }\n\n private cancelClose(): void {\n if (this.closeTimer !== null) {\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private openSubmenu(): void {\n const panel = this.submenu();\n if (!panel || this.submenuRef) return;\n\n // Position to the right of the item, vertically aligned with the\n // item's top. Falls back to opening to the LEFT if there's no room.\n const positions: ConnectedPosition[] = [\n { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', offsetX: 4 },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', offsetX: -4 },\n ];\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(wrMirrorOffsets(positions, this.isRtl()))\n .withPush(true);\n\n this.submenuRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: ['wr-context-menu-overlay', 'wr-context-menu-overlay--submenu'],\n });\n\n const portal = new TemplatePortal(panel.contentTpl(), this.vcr);\n this.submenuRef.attach(portal);\n\n // Mirror the open animation pattern from the root menu directive.\n const pane = this.submenuRef.overlayElement;\n requestAnimationFrame(() => pane.classList.add('wr-context-menu-overlay--open'));\n\n // Name the pane's menu so the item can point at it — minted per open for\n // the same reason the root does it (a closing pane outlives its close).\n const menuEl = pane.querySelector<HTMLElement>('.wr-context-menu');\n if (menuEl) {\n menuEl.id = randomId('wr-context-menu');\n this.submenuId.set(menuEl.id);\n }\n\n // Track mouse entering / leaving the submenu so we don't auto-close\n // when the cursor crosses the gap between item and submenu pane.\n pane.addEventListener('mouseenter', this.onSubmenuEnter);\n pane.addEventListener('mouseleave', this.onSubmenuLeave);\n\n // While this pane is open it is the newest overlay that listens, so CDK's\n // keyboard dispatcher hands it every keydown and the root menu's own handler\n // stops seeing them. Which pane the keys then act on is decided in\n // `onSubmenuKeydown`, not here: a hover open leaves the caret where it was.\n this.submenuKeys = this.submenuRef.keydownEvents().subscribe(event => this.onSubmenuKeydown(event));\n\n // A keyboard open walks INTO the submenu; a hover open only shows it.\n if (this.openedByKeyboard) wrFocusMenuItemAt(pane, 0);\n\n this.submenuOpen = true;\n WrContextMenuItem.openSubmenus.set(this.host.nativeElement, this);\n }\n\n /**\n * @internal Keys routed here while this submenu is the topmost overlay: the\n * arrows walk the rows of the pane the caret is in, and Escape or the arrow\n * pointing BACK the way the menu cascades steps out one level, returning the\n * cursor to the row that owns the pane when the cursor was inside it.\n *\n * Escape closes this level only, not the whole chain — the APG's rule for a\n * submenu. It reaches this handler rather than the root's because the\n * dispatcher stops at the topmost overlay that listens, which is now this one.\n *\n * Which is also why the arrows are aimed at the pane holding the caret rather\n * than at this one. The dispatcher routes by stacking order, not by focus, and\n * a HOVER-opened submenu is topmost while focus is deliberately still on the\n * root row the pointer swept off (see `openedByKeyboard`) — so ArrowDown used\n * to jump into this pane's first row instead of moving down the menu the user\n * is in. Same reason `wr-dropdown`'s menu handler checks ownership.\n */\n private onSubmenuKeydown(event: KeyboardEvent): void {\n const pane = this.submenuRef?.overlayElement;\n if (!pane) return;\n // A row inside the pane already acted on this key — its own → into a deeper\n // submenu, or Enter on a leaf. Re-handling it here would close the pane out\n // from under the level it just opened.\n if (event.defaultPrevented) return;\n const active = document.activeElement;\n const focusedPane = active instanceof Element ? active.closest<HTMLElement>('.wr-context-menu-overlay') : null;\n const back = this.isRtl() ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === 'Escape' || event.key === back) {\n event.preventDefault();\n this.disposeSubmenu(false);\n // Onto the owning row only when the caret was in the pane just closed:\n // dismissing a submenu the pointer opened must not drag it off the row the\n // keyboard user is on.\n if (focusedPane === pane) this.host.nativeElement.focus();\n return;\n }\n // Falls back to this pane when the caret is outside every menu — nothing\n // else can answer, and the navigation opens at the first row from there.\n wrHandleMenuNavigation(focusedPane ?? pane, event);\n }\n\n /** Bound handlers (= preserves identity for removeEventListener). */\n private readonly onSubmenuEnter = (): void => {\n this.cancelClose();\n // Cursor is inside our pane — keep the whole chain (root + every\n // ancestor submenu) alive.\n WrContextMenu.keepChainAlive();\n };\n private readonly onSubmenuLeave = (event: MouseEvent): void => {\n // Only stay open if the cursor is moving into a DESCENDANT submenu\n // of ours (an item inside our pane opening its own submenu). Moving\n // back up to an ancestor menu, sideways to a sibling, or completely\n // off-chain should dismiss this submenu (cascade-on-dispose then\n // tears down any deeper levels we own).\n if (this.relatedTargetIsInsideDescendantSubmenu(event)) return;\n this.scheduleClose(SUBMENU_CLOSE_DELAY);\n // If the cursor left ALL menu panes (root + every submenu), tear\n // down the whole chain. Otherwise just close this pane and let the\n // user continue navigating ancestors.\n if (!this.relatedTargetIsInsideAnyMenu(event)) {\n WrContextMenu.scheduleChainClose();\n }\n };\n\n private relatedTargetIsInsideAnyMenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element)) return false;\n return !!related.closest('.wr-context-menu-overlay');\n }\n\n /**\n * `true` when the cursor moved from this item directly into the pane\n * of its own (just-opening) submenu — drilling down. Sibling items\n * and ancestor menus do NOT count.\n */\n private relatedTargetIsInsideOwnSubmenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element) || !this.submenuRef) return false;\n return this.submenuRef.overlayElement.contains(related);\n }\n\n /**\n * `true` when the cursor moved from our submenu pane into another\n * submenu pane whose owner-item lives INSIDE ours — the user is\n * drilling further down the chain (e.g., from the Share submenu into\n * the Export-as submenu). Moving back up the chain returns false so\n * we close.\n */\n private relatedTargetIsInsideDescendantSubmenu(event: MouseEvent): boolean {\n const related = event.relatedTarget;\n if (!(related instanceof Element) || !this.submenuRef) return false;\n const targetPane = related.closest('.wr-context-menu-overlay');\n if (!targetPane) return false;\n const myPane = this.submenuRef.overlayElement;\n if (targetPane === myPane) return true;\n // Find the owner-item of the pane the cursor is heading into. If\n // that owner-item is inside our own pane, the destination is a\n // descendant submenu.\n for (const [ownerEl, owner] of WrContextMenuItem.openSubmenus) {\n if (owner.submenuRef?.overlayElement === targetPane) {\n return myPane.contains(ownerEl);\n }\n }\n return false;\n }\n\n private disposeSubmenu(immediate: boolean): void {\n this.cancelOpen();\n this.cancelClose();\n const ref = this.submenuRef;\n if (!ref) return;\n this.submenuRef = null;\n this.submenuOpen = false;\n this.submenuId.set(null);\n // Now, not when the ref is finally disposed 220ms later: an overlay with a\n // keydown subscriber is where CDK's dispatcher STOPS looking, so a pane\n // still listening on its way out would swallow the arrows for the whole\n // exit animation and the root menu would go dead for a quarter of a second.\n this.submenuKeys?.unsubscribe();\n this.submenuKeys = null;\n WrContextMenuItem.openSubmenus.delete(this.host.nativeElement);\n\n const pane = ref.overlayElement;\n pane.removeEventListener('mouseenter', this.onSubmenuEnter);\n pane.removeEventListener('mouseleave', this.onSubmenuLeave);\n\n // Cascade-close any descendant submenus whose owner-item lives inside\n // the pane we're about to dispose. Without this, when a parent submenu\n // closes (via hover-out grace timer), a grandchild submenu whose owner\n // is rendered inside the parent's portal is orphaned — its OverlayRef\n // stays alive in the DOM with no parent to reach it from.\n for (const [ownerEl, owner] of WrContextMenuItem.openSubmenus) {\n if (pane.contains(ownerEl)) owner.disposeSubmenu(immediate);\n }\n\n if (immediate) {\n ref.dispose();\n return;\n }\n pane.classList.remove('wr-context-menu-overlay--open');\n setTimeout(() => ref.dispose(), SUBMENU_TRANSITION_MS);\n }\n\n /**\n * Whether the app reads right-to-left.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a\n * component that works, and defaulting to LTR is the honest fallback.\n */\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\n }\n}\n","@if (icon(); as name) {\n <wr-icon class=\"wr-context-menu-item__icon\" [name]=\"name\" size=\"14\" />\n}\n<span class=\"wr-context-menu-item__label\"><ng-content /></span>\n@if (submenu()) {\n <svg\n class=\"wr-icon__svg wr-context-menu-item__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport {\n type ConnectedPosition,\n type FlexibleConnectedPositionStrategyOrigin,\n type OverlayRef,\n ScrollStrategyOptions,\n} from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { DestroyRef, Directive, ElementRef, ViewContainerRef, inject, input, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport type { Subscription } from 'rxjs';\n\nimport { WR_OVERLAY, WrOutsideClick } from 'ngwr/overlay';\nimport { randomId } from 'ngwr/utils';\n\nimport { WrContextMenuItem } from './context-menu-item';\nimport type { WrContextMenuPanel } from './context-menu-panel';\nimport { wrFocusMenuItemAt, wrHandleMenuNavigation } from './menu-focus';\n\n/**\n * Where the menu may hang off the pointer, best first: down-and-inline-start of\n * the cursor (what a native context menu does), then flipped up, then across,\n * then both.\n *\n * The origin is a zero-size POINT, so every `originX` / `originY` resolves to\n * the same coordinate and only the overlay's own corner varies. `overlayX:\n * 'start'` is the logical corner: CDK resolves it against the ambient reading\n * direction, so an RTL page opens the menu to the LEFT of the cursor without a\n * second table.\n */\nconst POINTER_POSITIONS: ConnectedPosition[] = [\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top' },\n { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'bottom' },\n];\n\n/**\n * The pointer as a CDK origin: a zero-size rect at the click, in VIEWPORT\n * coordinates.\n *\n * Live getters rather than a snapshot, and that is the whole trick. The menu is\n * anchored to the DOCUMENT — as the page scrolls it travels with the content it\n * was opened over (native + PrimeNG behaviour) — while CDK positions against\n * the viewport. Reading the scroll offset at `apply()` time is what converts one\n * into the other, so a re-anchor is nothing but a request to re-apply.\n */\nfunction pointerOrigin(pageX: number, pageY: number): FlexibleConnectedPositionStrategyOrigin {\n return {\n width: 0,\n height: 0,\n get x(): number {\n return pageX - window.scrollX;\n },\n get y(): number {\n return pageY - window.scrollY;\n },\n };\n}\n\n/**\n * Attach to any element to show a `<wr-context-menu>` at the pointer\n * position when the user right-clicks or otherwise sends a `contextmenu`\n * event (Shift+F10, etc.). The native browser menu is suppressed for the\n * host element.\n *\n * @example\n * ```html\n * <div [wrContextMenu]=\"menu\">Right-click me</div>\n * <wr-context-menu #menu>\n * <wr-context-menu-item (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n *\n * @see https://ngwr.dev/reference/components/context-menu\n */\n@Directive({\n selector: '[wrContextMenu]',\n host: {\n class: 'wr-context-menu-host',\n '[attr.aria-controls]': 'openMenuId()',\n '(contextmenu)': 'onContextMenu($event)',\n '(pointerdown)': 'onPointerDown($event)',\n '(pointermove)': 'onPointerMove($event)',\n '(pointerup)': 'onPointerUp()',\n '(pointercancel)': 'onPointerUp()',\n },\n})\nexport class WrContextMenu {\n /** Menu to open. Pass a `<wr-context-menu>` template reference. */\n readonly menu = input.required<WrContextMenuPanel>({ alias: 'wrContextMenu' });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n /**\n * Id of the menu element while this trigger's menu is open, published on the\n * host as `aria-controls`. The pane is portalled into the overlay container, a\n * sibling of the whole app, so this reference is the ONLY link between a\n * trigger and the menu it opened — for a screen reader, and for anything else\n * that has to find it. Cleared on close, which is also what tells an open\n * trigger from a closing one: the pane itself lingers for the exit animation.\n *\n * A signal, not a plain field: host bindings re-run only when something they\n * READ has changed, and this one flips outside change detection (from a\n * pointer handler, and from `onDestroy`). Held as a plain string it published\n * the id on open — the overlay attach happens to dirty the host view — and\n * then kept it forever, so the trigger still pointed at a menu that was gone.\n *\n * @internal\n */\n protected readonly openMenuId = signal<string | null>(null);\n\n private overlayRef: OverlayRef | null = null;\n /**\n * The open menu's subscription to CDK's keyboard dispatcher, held so that\n * `closeOverlay()` can drop it — see the unsubscribe there for why the pane's\n * own disposal is 220 ms too late.\n */\n private rootKeys: Subscription | null = null;\n /**\n * Where the keyboard was at the moment this menu took it, so a close can put\n * it back there. Null when it was nowhere in particular (`<body>`) or already\n * inside a menu pane, neither of which is a place to return to.\n */\n private restoreFocusTo: HTMLElement | null = null;\n /**\n * Panes waiting out their exit animation, keyed by the timer that disposes\n * them.\n *\n * A SET, because one handle cannot hold two closings. It used to be a single\n * `closingTimer`, and the second close inside the 220ms window cleared the\n * first one's timer instead of its own — so the previous pane's `dispose()`\n * never ran. `onContextMenu` closes and immediately re-opens, so right-clicking\n * one target faster than the animation orphaned a pane per click: an\n * `opacity: 0` box with `pointer-events: auto` eating clicks, a never-destroyed\n * embedded view, a capture-phase document scroll listener still moving it, and\n * an undetached ref still registered with CDK's keyboard dispatcher — which\n * swallowed Escape for the whole page.\n */\n private readonly closingPanes = new Map<ReturnType<typeof setTimeout>, OverlayRef>();\n private leaveTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Touch long-press → open. Right-click keeps using `(contextmenu)`.\n private pressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressX = 0;\n private pressY = 0;\n private pressPageX = 0;\n private pressPageY = 0;\n private lastLongPressAt = 0;\n private cancelPressScroll: (() => void) | null = null;\n\n /**\n * Single open root menu at a time. Submenu items use this to signal\n * chain-level hover state: when the cursor enters ANY pane in the\n * chain (root or submenu) `keepChainAlive()` cancels the close timer;\n * when the cursor leaves ALL panes `scheduleChainClose()` starts it.\n * The whole chain (root → submenus) tears down through the root's\n * close (submenus react to their owner-item destroyRef + the static\n * registry in `WrContextMenuItem`).\n */\n private static activeRoot: WrContextMenu | null = null;\n\n /** Called from a submenu pane's mouseenter — keep the whole chain alive. */\n static keepChainAlive(): void {\n WrContextMenu.activeRoot?.cancelLeaveTimer();\n }\n\n /** Called from a submenu pane's mouseleave when the cursor left ALL menus. */\n static scheduleChainClose(): void {\n WrContextMenu.activeRoot?.scheduleLeave();\n }\n\n /**\n * Called from a `<wr-context-menu-item>` click — selecting an item\n * dismisses the whole chain (root + any open submenus). Items live in\n * a detached overlay portal, so they reach their owning root through\n * this static handle rather than DI.\n */\n static closeActive(): void {\n WrContextMenu.activeRoot?.closeOverlay();\n }\n\n /**\n * Open/close animation duration in ms. Matches the longest SCSS\n * transition on `.wr-context-menu-overlay` (the spring-scale curve).\n * The directive holds the overlay alive for this long during close\n * so the exit animation can play before the pane is removed from\n * the DOM.\n */\n private static readonly TRANSITION_MS = 220;\n /**\n * Grace window after the cursor leaves the root pane. Long enough\n * for the user to dip momentarily into the gap between the root and\n * a submenu (or back from a submenu), short enough to feel snappy\n * on a deliberate hover-out.\n */\n private static readonly LEAVE_DELAY = 240;\n\n /** Hold duration before a touch long-press opens the menu. */\n private static readonly LONG_PRESS_MS = 500;\n /** Finger travel (px) that turns a pending long-press into a scroll/drag. */\n private static readonly PRESS_MOVE_TOLERANCE = 10;\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.cancelPress();\n this.closeOverlay();\n // Whatever is still fading out goes now: the timers that would have\n // disposed those panes belong to a directive that no longer exists.\n for (const [timer, ref] of this.closingPanes) {\n clearTimeout(timer);\n ref.dispose();\n }\n this.closingPanes.clear();\n });\n }\n\n /** @internal Right-click handler — opens at the pointer (or re-positions if already open). */\n protected onContextMenu(event: MouseEvent): void {\n event.preventDefault();\n // Some touch browsers (Android Chrome) fire a synthetic `contextmenu`\n // right after a long-press has already opened the menu — swallow it so it\n // doesn't re-open / restart the animation.\n if (Date.now() - this.lastLongPressAt < 700) return;\n event.stopPropagation();\n // Re-open at the new position even if it was already open.\n // Use page coords (document-relative) so the menu anchors to the\n // zone it was opened over — scrolling the page carries the menu\n // along with the content, matching native + PrimeNG behavior.\n this.closeOverlay();\n this.openOverlay(event.pageX, event.pageY);\n }\n\n /**\n * @internal Touch/pen long-press → open the menu at the press point. Desktop\n * right-click stays on `(contextmenu)`; this path is filtered to non-mouse\n * pointers. Deliberately does NOT `preventDefault`/`setPointerCapture` or set\n * `touch-action` — a press that turns into a scroll must still scroll, so the\n * open is cancelled on movement (> tolerance), on scroll, and on early lift.\n */\n protected onPointerDown(event: PointerEvent): void {\n if (event.pointerType === 'mouse' || !event.isPrimary || this.pressTimer !== null) return;\n this.pressX = event.clientX;\n this.pressY = event.clientY;\n this.pressPageX = event.pageX;\n this.pressPageY = event.pageY;\n this.pressTimer = setTimeout(() => {\n this.pressTimer = null;\n this.cancelPress();\n this.lastLongPressAt = Date.now();\n this.closeOverlay();\n this.openOverlay(this.pressPageX, this.pressPageY);\n }, WrContextMenu.LONG_PRESS_MS);\n const onScroll = (): void => this.cancelPress();\n document.addEventListener('scroll', onScroll, { capture: true, passive: true });\n this.cancelPressScroll = (): void => document.removeEventListener('scroll', onScroll, { capture: true });\n }\n\n /** @internal Finger moved too far before the hold fired — it's a scroll/drag. */\n protected onPointerMove(event: PointerEvent): void {\n if (this.pressTimer === null) return;\n if (Math.hypot(event.clientX - this.pressX, event.clientY - this.pressY) > WrContextMenu.PRESS_MOVE_TOLERANCE) {\n this.cancelPress();\n }\n }\n\n /** @internal Lifted (or the browser claimed the gesture) before the hold fired. */\n protected onPointerUp(): void {\n this.cancelPress();\n }\n\n private cancelPress(): void {\n if (this.pressTimer !== null) {\n clearTimeout(this.pressTimer);\n this.pressTimer = null;\n }\n this.cancelPressScroll?.();\n this.cancelPressScroll = null;\n }\n\n /** Close the menu. */\n close(): void {\n this.closeOverlay();\n }\n\n // Overlay\n\n private openOverlay(x: number, y: number): void {\n // Read before `wrFocusMenuItemAt` below takes the keyboard: this is the\n // element the close hands it back to. A pane row is not a candidate — a\n // previous menu may still be fading out — and neither is `<body>`, which is\n // where focus already is when nobody has it.\n const active = document.activeElement;\n this.restoreFocusTo =\n active instanceof HTMLElement && active !== document.body && !active.closest('.wr-context-menu-overlay')\n ? active\n : null;\n\n // Anchored to the POINTER, which is not an element — CDK takes a virtual\n // origin for exactly that, and a FLEXIBLE strategy is what makes the menu\n // flip up (or across) instead of hanging off the edge of the screen. It used\n // to be a bare `GlobalPositionStrategy` with the raw coordinates written\n // onto the pane, which never measured the menu against the viewport: a\n // right-click 6px above the bottom of the window put two of the three rows\n // below the fold and clipped the third, since the pane is `position: fixed`\n // and cannot be scrolled to. Submenus have used the flexible strategy from\n // the start (`context-menu-item.ts`); only the root skipped it.\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(pointerOrigin(x, y))\n // The menu sizes itself; the fallbacks below are the whole answer to a\n // cramped viewport, and `withPush` clamps whatever is left over.\n .withFlexibleDimensions(false)\n .withPush(true)\n .withPositions(POINTER_POSITIONS);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n // `noop` so scroll doesn't dismiss the menu — `sync()` below re-anchors it\n // instead.\n scrollStrategy: this.scrollStrategies.noop(),\n panelClass: ['wr-context-menu-overlay'],\n });\n\n const portal = new TemplatePortal(this.menu().contentTpl(), this.vcr);\n this.overlayRef.attach(portal);\n // `attach()` defers CDK's first placement into `afterNextRender`. Place it\n // now: until then the pane sits at the container's top-left corner, and the\n // rows are already in the DOM (see `wrFocusMenuItemAt` below), so the\n // measurement the flip depends on is available.\n this.overlayRef.updatePosition();\n\n const pane = this.overlayRef.overlayElement;\n\n // Name the menu we just opened so the host can point at it. The id is\n // minted per OPEN rather than living on the panel: `closeOverlay()` keeps\n // the previous pane in the DOM for its exit animation, so a re-open would\n // otherwise leave two elements answering to the same id — with the dying\n // one first in document order.\n const menuEl = pane.querySelector<HTMLElement>('.wr-context-menu');\n if (menuEl) {\n menuEl.id = randomId('wr-context-menu');\n this.openMenuId.set(menuEl.id);\n }\n\n // Re-anchor. `pointerOrigin` reads the scroll offset afresh, so this is all\n // it takes for the menu to travel with the content it was opened over.\n //\n // `reapplyLastPosition()` rather than `updatePosition()`: the flip is\n // decided once, when the menu opens. Re-running the fallback list on every\n // scroll event would let the menu hop from above the cursor to below it and\n // back while the page moves under it, which is a worse reading of \"the menu\n // stays where you put it\" than a menu that simply slides with the page.\n const sync = (): void => positionStrategy.reapplyLastPosition();\n\n // Move the keyboard INTO the menu. Without this the pane painted a\n // `role=\"menu\"` that could be seen and never entered: rows are\n // `tabindex=\"-1\"` (the roving-focus contract) and the pane is not a tab\n // stop, so ArrowDown / Enter / ArrowRight all went to whatever still held\n // focus behind the menu and only Escape worked — the dispatcher routes that\n // one regardless of focus.\n //\n // Unconditional, unlike `wr-dropdown`'s `openedByPointer` gate: there is no\n // hover open here. Every path into this method is a deliberate request for\n // the menu (right-click, Shift+F10, the Menu key, a long-press), which is\n // also when a native context menu takes the keyboard.\n //\n // Synchronous, and it can be: `attach()` above runs the embedded view's\n // first change detection itself (CDK's `attachTemplatePortal`), so the rows\n // and their `[class]` host binding are already in the DOM.\n wrFocusMenuItemAt(pane, 0);\n\n // Trigger the open transition on the next frame — adding the class\n // synchronously with attach would skip the initial 0→1 frame and\n // the menu would just appear without animating.\n requestAnimationFrame(() => pane.classList.add('wr-context-menu-overlay--open'));\n\n // Hover-out closes the menu after a grace window, unless the\n // cursor moved INTO a descendant submenu (any other\n // `.wr-context-menu-overlay`). Re-entering the root cancels the\n // scheduled close so the user can dip out and back without losing\n // the menu.\n const onPaneLeave = (event: MouseEvent): void => {\n const related = event.relatedTarget;\n // Moving into ANY other menu pane (a submenu) keeps the chain\n // alive — the submenu's own mouseenter will cancel any pending\n // chain-close. Only schedule when the cursor genuinely left the\n // chain.\n if (related instanceof Element && related.closest('.wr-context-menu-overlay')) return;\n this.scheduleLeave();\n };\n const onPaneEnter = (): void => this.cancelLeaveTimer();\n pane.addEventListener('mouseleave', onPaneLeave);\n pane.addEventListener('mouseenter', onPaneEnter);\n WrContextMenu.activeRoot = this;\n this.overlayRef.detachments().subscribe(() => {\n pane.removeEventListener('mouseleave', onPaneLeave);\n pane.removeEventListener('mouseenter', onPaneEnter);\n });\n // Capture-phase listener on document catches scroll events from ANY\n // ancestor (window, html, body, custom scroll containers), so the\n // menu stays anchored to the click position even inside scrollable\n // layouts.\n document.addEventListener('scroll', sync, { capture: true, passive: true });\n // On resize the page layout reflows — the original pageX/pageY no\n // longer points at whatever the user right-clicked. Dismiss the menu\n // rather than dragging it across a now-stale coordinate (matches\n // PrimeNG / native behavior).\n const onResize = (): void => this.closeOverlay();\n window.addEventListener('resize', onResize, { passive: true });\n this.overlayRef.detachments().subscribe(() => {\n document.removeEventListener('scroll', sync, { capture: true });\n window.removeEventListener('resize', onResize);\n });\n\n // The right-click that opens the menu still has `mouseup` + `auxclick`\n // events pending, and the outside-click source fires on `auxclick` — which\n // would close the menu the instant the user lifts their finger. Two-part\n // guard:\n // 1. Track the open timestamp.\n // 2. Ignore any outside events that arrive within a short window\n // after the open (long enough to cover the original mouseup +\n // auxclick, short enough that a deliberate second click is\n // still respected).\n const openedAt = performance.now();\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (performance.now() - openedAt < 200) return;\n this.closeOverlay();\n });\n\n this.rootKeys = this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.closeOverlay();\n return;\n }\n if (event.key === 'Tab') {\n // Let focus leave naturally — `closeOverlay()` hands it back to the\n // trigger first, so Tab continues from there instead of from a pane\n // that is about to be removed.\n this.closeOverlay();\n return;\n }\n // A row's own handler already acted on this key (ArrowRight into a\n // submenu, Enter on an item): `preventDefault()` is how it says so, and\n // moving the cursor on top of that would undo it.\n if (event.defaultPrevented) return;\n wrHandleMenuNavigation(pane, event);\n });\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n // Read up front, before the teardown below starts on the panes: the answer\n // wanted is where the keyboard was at the moment of dismissal.\n const active = document.activeElement;\n const focusWasInside = active instanceof Element && active.closest('.wr-context-menu-overlay') !== null;\n const restoreTo = this.restoreFocusTo;\n this.restoreFocusTo = null;\n this.cancelLeaveTimer();\n // Drop the reference immediately: the pane below stays in the DOM until the\n // exit animation has played, and a trigger still pointing at a menu on its\n // way out reads as open.\n this.openMenuId.set(null);\n if (WrContextMenu.activeRoot === this) WrContextMenu.activeRoot = null;\n // Submenu panes live in the CDK overlay container, not inside the\n // root pane's view — destroyRef cascade through portal detach\n // doesn't reach them. Close them all explicitly first so they\n // don't float when the root is dismissed (outside-click, Esc, etc).\n WrContextMenuItem.disposeAll(false);\n const ref = this.overlayRef;\n const pane = ref.overlayElement;\n // Detach immediately would skip the exit animation. Remove the open\n // class first so the SCSS transition runs back to the default\n // (faded + scaled-down) state, then dispose after the transition.\n pane.classList.remove('wr-context-menu-overlay--open');\n // …and stop it hit-testing on the way out. Fading to `opacity: 0` does not\n // stop a pane receiving pointer events — `.cdk-overlay-pane` sets\n // `pointer-events: auto` — so for the whole 220 ms an invisible menu kept\n // swallowing clicks meant for the page underneath, and a second click on\n // the item just picked (a double-click, or Escape then click) re-ran the\n // consumer's action. Written inline rather than in `styles/_index.scss`\n // because the closing state has no class of its own, and inline beats the\n // CDK's own sheet without an `!important`.\n pane.style.pointerEvents = 'none';\n // …and stop it taking the page's KEYS on the way out, for the same reason\n // and with the same timing. An overlay with a keydown subscriber is where\n // CDK's dispatcher stops looking, and it is removed from the dispatcher only\n // by `detach()` / `dispose()` — which is 220 ms away — so a dismissed menu\n // went on swallowing every keydown on the page: ArrowDown pulled real focus\n // back onto a row of the invisible pane, and a second Escape meant for the\n // dialog underneath was `preventDefault`ed and did nothing.\n // `WrContextMenuItem.disposeSubmenu()` does exactly this; the root had not.\n this.rootKeys?.unsubscribe();\n this.rootKeys = null;\n const timer = setTimeout(() => {\n this.closingPanes.delete(timer);\n ref.dispose();\n }, WrContextMenu.TRANSITION_MS);\n this.closingPanes.set(timer, ref);\n // Mark immediately so a subsequent right-click opens a fresh menu\n // rather than landing on the disposing one.\n this.overlayRef = null;\n // Hand the keyboard back. The menu takes focus on open, so a dismissal that\n // left it in the pane would strand it on `<body>` once the pane is disposed\n // and the next Tab would restart at the top of the document. Only when the\n // caret was actually in the chain: Escape reaches this overlay from anywhere\n // on the page (CDK's dispatcher routes it by stacking order, not by focus),\n // and a menu nobody was in must not steal the caret from a field they are.\n if (focusWasInside) this.handBackFocus(restoreTo);\n }\n\n /**\n * Put the keyboard back where it came from.\n *\n * The element that had it when the menu opened comes first: a context menu\n * hangs on a REGION — a card, a table row — and Shift+F10 / the Menu key fires\n * `contextmenu` at whatever control inside it the user was actually on, which\n * is their place in the page.\n *\n * The trigger is the fallback, and it needs help to be one. `[wrContextMenu]`\n * adds no `tabindex` and every shape the docs ship is a plain `<div>`, so\n * `focus()` on it does nothing at all — the handback silently missed, leaving\n * the caret in the disposing pane and then on `<body>`, which is the outcome\n * the call is there to prevent. Lending it `tabindex=\"-1\"` for the call and\n * taking that back on blur keeps the consumer's DOM as they wrote it; a\n * permanent `tabindex=\"0\"` would make every right-clickable region a tab stop,\n * which is their decision and not the library's.\n */\n private handBackFocus(previous: HTMLElement | null): void {\n const target =\n previous?.isConnected && !previous.closest('.wr-context-menu-overlay') ? previous : this.host.nativeElement;\n target.focus();\n // Asking whether it took, rather than deciding up front whether it can: the\n // focusability rules are wide (an `<a>` needs an href, a `<div>` needs a\n // tabindex, `inert`/`disabled` opt out) and `document.activeElement` answers\n // all of them at once.\n if (document.activeElement === target) return;\n target.setAttribute('tabindex', '-1');\n target.focus();\n target.addEventListener('blur', () => target.removeAttribute('tabindex'), { once: true });\n }\n\n private cancelLeaveTimer(): void {\n if (this.leaveTimer !== null) {\n clearTimeout(this.leaveTimer);\n this.leaveTimer = null;\n }\n }\n\n private scheduleLeave(): void {\n this.cancelLeaveTimer();\n this.leaveTimer = setTimeout(() => {\n this.leaveTimer = null;\n this.closeOverlay();\n }, WrContextMenu.LEAVE_DELAY);\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, TemplateRef, ViewEncapsulation, viewChild } from '@angular/core';\n\n/**\n * Container for the rows shown when a {@link WrContextMenu} opens.\n * The component itself doesn't render; the directive portals the inner\n * template into an overlay positioned at the pointer.\n *\n * @example\n * ```html\n * <div [wrContextMenu]=\"menu\">Right-click me</div>\n * <wr-context-menu #menu>\n * <wr-context-menu-item icon=\"copy\" (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item icon=\"trash\" (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu',\n template: '<ng-template><div class=\"wr-context-menu\" role=\"menu\"><ng-content /></div></ng-template>',\n exportAs: 'wrContextMenu',\n encapsulation: ViewEncapsulation.None,\n // A BOUND display rather than a static `style` attribute: Angular writes a\n // binding through `style.setProperty`, which no CSP governs, while a real\n // `style=\"…\"` attribute is refused under `style-src 'self'` — and this host\n // would then lay out an empty box in the middle of the content.\n host: { '[style.display]': \"'none'\" },\n})\nexport class WrContextMenuPanel {\n /** The internal template the directive portals into the overlay. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation } from '@angular/core';\n\n/**\n * Thin horizontal separator inside a `<wr-context-menu>`. Use it to\n * group related items (e.g., a destructive action below a divider, or\n * a \"More\" section below the primary items).\n *\n * @example\n * ```html\n * <wr-context-menu #menu>\n * <wr-context-menu-item (click)=\"copy()\">Copy</wr-context-menu-item>\n * <wr-context-menu-item (click)=\"paste()\">Paste</wr-context-menu-item>\n * <wr-context-menu-divider />\n * <wr-context-menu-item (click)=\"remove()\">Delete</wr-context-menu-item>\n * </wr-context-menu>\n * ```\n */\n@Component({\n selector: 'wr-context-menu-divider',\n template: '',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-context-menu-divider',\n role: 'separator',\n 'aria-orientation': 'horizontal',\n },\n})\nexport class WrContextMenuDivider {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -256,6 +256,28 @@ class WrDialog {
256
256
  });
257
257
  const portal = new ComponentPortal(component, null, injector);
258
258
  dialogRef.componentRef = overlayRef.attach(portal);
259
+ // Wired BEFORE the panel is decorated, and the order is the fix: everything
260
+ // below attaches attributes, a ✕ and a focus trap to an overlay that is
261
+ // already on screen, so anything that throws in there used to leave an
262
+ // `aria-modal` panel with no dismissal path at all — no ✕, no backdrop
263
+ // handler, no Escape — over the whole application, and no ref for the caller
264
+ // to close it with. A dialog that fails to finish opening must still be one
265
+ // the user can get rid of. Overlay subscriptions complete when the overlay is
266
+ // disposed, so no explicit teardown is required.
267
+ if (options.closeOnBackdropClick !== false) {
268
+ overlayRef.backdropClick().subscribe(() => dialogRef.close());
269
+ }
270
+ if (options.closeOnEscape !== false) {
271
+ overlayRef.keydownEvents().subscribe(event => {
272
+ if (event.key === 'Escape') {
273
+ event.preventDefault();
274
+ dialogRef.close();
275
+ }
276
+ });
277
+ }
278
+ if (options.closeOnNavigation !== false) {
279
+ this.watchNavigation(overlayRef, dialogRef);
280
+ }
259
281
  if (this.isBrowser) {
260
282
  const host = overlayRef.overlayElement;
261
283
  host.setAttribute('role', 'dialog');
@@ -293,22 +315,6 @@ class WrDialog {
293
315
  dialogRef.focusTrap = trap;
294
316
  void trap.focusInitialElementWhenReady();
295
317
  }
296
- // Overlay subscriptions complete when the overlay is disposed, so no
297
- // explicit teardown is required.
298
- if (options.closeOnBackdropClick !== false) {
299
- overlayRef.backdropClick().subscribe(() => dialogRef.close());
300
- }
301
- if (options.closeOnEscape !== false) {
302
- overlayRef.keydownEvents().subscribe(event => {
303
- if (event.key === 'Escape') {
304
- event.preventDefault();
305
- dialogRef.close();
306
- }
307
- });
308
- }
309
- if (options.closeOnNavigation !== false) {
310
- this.watchNavigation(overlayRef, dialogRef);
311
- }
312
318
  return dialogRef;
313
319
  }
314
320
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-dialog.mjs","sources":["../../../projects/lib/dialog/dialog-ref.ts","../../../projects/lib/dialog/tokens/dialog-data.token.ts","../../../projects/lib/dialog/tokens/dialog-ref.token.ts","../../../projects/lib/dialog/dialog.ts","../../../projects/lib/dialog/directives/dialog-title.ts","../../../projects/lib/dialog/directives/dialog-content.ts","../../../projects/lib/dialog/directives/dialog-footer.ts","../../../projects/lib/dialog/directives/dialog-close.ts","../../../projects/lib/dialog/ngwr-dialog.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDialog.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the dialog's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDialogClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = dialog.open<ConfirmComponent, boolean>(ConfirmComponent);\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the dialog closes itself.\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject(WrDialogRef);\n *\n * save(): void {\n * this.store.save();\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDialogRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated dialog component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDialogRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the dialog, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the dialog is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDialog.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * readonly data = inject<ConfirmData>(WR_DIALOG_DATA);\n * }\n * ```\n */\nexport const WR_DIALOG_DATA = new InjectionToken<unknown>('WR_DIALOG_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\n\n/**\n * Token exposing the open dialog's `WrDialogRef` to components and\n * directives rendered inside it (e.g. `[wrDialogClose]`).\n *\n * **Prefer `inject(WrDialogRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDialogRef, { optional: true })`\n * works for content that also renders outside a dialog, and\n * `inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef)` types the\n * generics without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDialogClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef);\n *\n * confirm(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DIALOG_REF = new InjectionToken<WrDialogRef<unknown, unknown>>('WR_DIALOG_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { Location, isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Service, Injector, PLATFORM_ID, afterEveryRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrAppendOverlayClose, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport { WrDialogRef } from './dialog-ref';\nimport type { WrDialogOptions } from './interfaces';\nimport { WR_DIALOG_DATA, WR_DIALOG_REF } from './tokens';\n\nconst DEFAULT_PANEL_CLASS = 'wr-dialog-panel';\nconst DEFAULT_BACKDROP_CLASS = 'wr-dialog-backdrop';\n\n/**\n * Opens dialog components in an isolated NGWR overlay.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — dialogs render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * @example\n * ```ts\n * const dialog = inject(WrDialog);\n *\n * const ref = dialog.open(ConfirmComponent, {\n * data: { message: 'Delete this item?' },\n * width: '24rem',\n * });\n *\n * const ok = await ref.awaitClose();\n * if (ok) remove();\n * ```\n *\n * @see https://ngwr.dev/reference/components/dialog\n */\n@Service()\nexport class WrDialog {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly i18n = inject(WrI18n, { optional: true });\n // Resolvable wherever the CDK's own `Overlay` is — it injects the same thing\n // to implement `disposeOnNavigation`.\n private readonly location = inject(Location);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDialogOptions<D> = {}): WrDialogRef<C, R> {\n const panelClasses: string[] = [DEFAULT_PANEL_CLASS];\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n // On small viewports (when opted in) present as a slide-up sheet pinned\n // to the bottom edge, full-width, instead of a centred modal.\n const asSheet = wrPresentAsSheet(options.responsive, this.responsiveConfig);\n if (asSheet) panelClasses.push('wr-overlay-sheet');\n\n const position = this.overlay.position().global().centerHorizontally();\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy: asSheet ? position.bottom('0') : position.centerVertically(),\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: true,\n backdropClass: DEFAULT_BACKDROP_CLASS,\n panelClass: panelClasses,\n width: asSheet ? '100%' : options.width,\n maxWidth: asSheet ? '100%' : options.maxWidth,\n });\n\n const dialogRef = new WrDialogRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n dialogRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DIALOG_DATA, useValue: options.data },\n { provide: WR_DIALOG_REF, useValue: dialogRef },\n // Provided as its own token as well, so dialog content can reach for\n // the familiar `inject(WrDialogRef)` and close itself.\n { provide: WrDialogRef, useValue: dialogRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n dialogRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss. Appended after the content portal so it paints above\n // it, and marked on the panel so the title reserves the corner gutter.\n if (options.closable !== false) {\n host.classList.add('wr-dialog-panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-dialog__close', label, () => dialogRef.close());\n }\n // Wire aria-labelledby to wrDialogTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n //\n // And after EVERY render, not just the next one: the title belongs to the\n // caller's component, so an `@if` or a late-arriving heading can replace\n // or remove the element the attribute names. A reference to a node that is\n // no longer there is not a name — the dialog announces as unnamed — so a\n // missing title clears the attribute rather than leaving it dangling.\n const labelSync = afterEveryRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDialogTitle], [wr-dialog-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n },\n { injector: this.parentInjector }\n );\n // The hook is bound to the root injector, so it outlives the dialog unless\n // it is torn down with it. `detachments()` fires on dispose, which is the\n // one path every dismissal goes through.\n overlayRef.detachments().subscribe(() => labelSync.destroy());\n // Trap focus inside the dialog and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n dialogRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => dialogRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n dialogRef.close();\n }\n });\n }\n if (options.closeOnNavigation !== false) {\n this.watchNavigation(overlayRef, dialogRef);\n }\n\n return dialogRef;\n }\n\n /**\n * Tie the dialog's lifetime to the URL it was opened on.\n *\n * Nothing else does. The overlay belongs to a root service and is dismissed\n * only by the backdrop, Escape or an explicit `close()`, so pressing Back\n * swapped the routed view underneath and left the modal pane, its backdrop and\n * its focus trap sitting over a page the user never opened them on.\n *\n * `onUrlChange`, not `Location.subscribe()` — which is what CDK's own\n * `disposeOnNavigation` uses: `subscribe` fires on popstate alone, so an\n * in-app `router.navigate()` left the dialog standing. And `dialogRef.close()`\n * rather than disposing the overlay behind the ref's back, which would never\n * emit `closed`, never destroy the focus trap, and leave `awaitClose()`\n * pending forever.\n */\n private watchNavigation<C, R>(overlayRef: OverlayRef, dialogRef: WrDialogRef<C, R>): void {\n const stopWatching = this.location.onUrlChange(() => dialogRef.close());\n // Unhooked a microtask late, because `Location` notifies its listeners with\n // a `forEach` and unregistering splices the array it is iterating: removing\n // ours synchronously from inside the notification would shift the next entry\n // into the slot forEach has already passed, and a SECOND stacked dialog\n // would be skipped and left behind.\n overlayRef.detachments().subscribe(() => queueMicrotask(stopWatching));\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Two failure modes, and resolving PER OPEN is what covers both. `t()` hands\n * back the KEY on a miss, and `WrI18n` is root-provided with an empty catalog\n * by default, so an app that never configured i18n named its dismiss button\n * \"dialog.close\" — a name axe cannot fault, because a name is present, and a\n * screen reader reads out verbatim. Resolving once at injection time fixed\n * that but froze the answer: this is a root service, constructed before an\n * async catalog has loaded, so a localized app got the English fallback on\n * every dialog it ever opened.\n */\n private closeLabel(): string {\n const resolved = this.i18n?.t('dialog.close');\n return !resolved || resolved === 'dialog.close' ? 'Close dialog' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, ElementRef, inject } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Styles a dialog title row. Use on a heading inside an opened dialog.\n * Auto-assigns an `id` so the dialog panel can reference it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <h2 wrDialogTitle>Confirm delete</h2>\n * ```\n */\n@Directive({\n selector: '[wrDialogTitle]',\n host: { class: 'wr-dialog__title', '[attr.id]': 'id' },\n})\nexport class WrDialogTitle {\n /** Generated id used for `aria-labelledby` wiring. */\n readonly id = `wr-dialog-title-${++uid}`;\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { CdkScrollable } from '@angular/cdk/scrolling';\nimport { Directive } from '@angular/core';\n\n/**\n * Styles the scrollable body section of a dialog.\n *\n * `CdkScrollable` is a host directive because this element is a real scroll\n * container (`overflow: auto`) and an anchored overlay opened from inside it has\n * to follow its trigger. CDK's `reposition()` strategy listens to\n * `ScrollDispatcher`, which is fed by registered scrollables plus ONE\n * non-capturing `document` listener — and element `scroll` does not bubble, so\n * without the registration a `<wr-select>` halfway down a long dialog form kept\n * its panel pinned to the viewport while the trigger scrolled away. Angular\n * Material carries the same host directive on `MatDialogContent` for the same\n * reason.\n *\n * @example\n * ```html\n * <div wrDialogContent>…body…</div>\n * ```\n */\n@Directive({\n selector: '[wrDialogContent]',\n host: { class: 'wr-dialog__content' },\n hostDirectives: [CdkScrollable],\n})\nexport class WrDialogContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Footer row, typically holding action buttons.\n *\n * @example\n * ```html\n * <div wrDialogFooter align=\"end\">\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"danger\" (click)=\"confirm()\">Delete</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDialogFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDialogFooter {\n /**\n * Horizontal alignment of the children.\n *\n * @default 'end'\n */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-dialog__footer wr-dialog__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\nimport { WR_DIALOG_REF } from '../tokens';\n\n/**\n * Closes the dialog when the host element is clicked.\n *\n * Optionally passes a `[wrDialogClose]` value as the close result.\n *\n * @example\n * ```html\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" [wrDialogClose]=\"true\">Confirm</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDialogClose]',\n host: { '(click)': 'onClick()' },\n})\nexport class WrDialogClose<R = unknown> {\n /**\n * Value to pass to `close()`. When unset — or used as a bare attribute — the\n * dialog closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDialogClose',\n // A bare `wrDialogClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`. Matches `wrDrawerClose`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly ref = inject<WrDialogRef<unknown, R>>(WR_DIALOG_REF, { optional: true });\n\n protected onClick(): void {\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-dialog.mjs","sources":["../../../projects/lib/dialog/dialog-ref.ts","../../../projects/lib/dialog/tokens/dialog-data.token.ts","../../../projects/lib/dialog/tokens/dialog-ref.token.ts","../../../projects/lib/dialog/dialog.ts","../../../projects/lib/dialog/directives/dialog-title.ts","../../../projects/lib/dialog/directives/dialog-content.ts","../../../projects/lib/dialog/directives/dialog-footer.ts","../../../projects/lib/dialog/directives/dialog-close.ts","../../../projects/lib/dialog/ngwr-dialog.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDialog.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the dialog's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDialogClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = dialog.open<ConfirmComponent, boolean>(ConfirmComponent);\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the dialog closes itself.\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject(WrDialogRef);\n *\n * save(): void {\n * this.store.save();\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDialogRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated dialog component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDialogRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the dialog, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the dialog is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDialog.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * readonly data = inject<ConfirmData>(WR_DIALOG_DATA);\n * }\n * ```\n */\nexport const WR_DIALOG_DATA = new InjectionToken<unknown>('WR_DIALOG_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\n\n/**\n * Token exposing the open dialog's `WrDialogRef` to components and\n * directives rendered inside it (e.g. `[wrDialogClose]`).\n *\n * **Prefer `inject(WrDialogRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDialogRef, { optional: true })`\n * works for content that also renders outside a dialog, and\n * `inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef)` types the\n * generics without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDialogClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef);\n *\n * confirm(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DIALOG_REF = new InjectionToken<WrDialogRef<unknown, unknown>>('WR_DIALOG_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { Location, isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Service, Injector, PLATFORM_ID, afterEveryRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrAppendOverlayClose, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport { WrDialogRef } from './dialog-ref';\nimport type { WrDialogOptions } from './interfaces';\nimport { WR_DIALOG_DATA, WR_DIALOG_REF } from './tokens';\n\nconst DEFAULT_PANEL_CLASS = 'wr-dialog-panel';\nconst DEFAULT_BACKDROP_CLASS = 'wr-dialog-backdrop';\n\n/**\n * Opens dialog components in an isolated NGWR overlay.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — dialogs render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * @example\n * ```ts\n * const dialog = inject(WrDialog);\n *\n * const ref = dialog.open(ConfirmComponent, {\n * data: { message: 'Delete this item?' },\n * width: '24rem',\n * });\n *\n * const ok = await ref.awaitClose();\n * if (ok) remove();\n * ```\n *\n * @see https://ngwr.dev/reference/components/dialog\n */\n@Service()\nexport class WrDialog {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly i18n = inject(WrI18n, { optional: true });\n // Resolvable wherever the CDK's own `Overlay` is — it injects the same thing\n // to implement `disposeOnNavigation`.\n private readonly location = inject(Location);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDialogOptions<D> = {}): WrDialogRef<C, R> {\n const panelClasses: string[] = [DEFAULT_PANEL_CLASS];\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n // On small viewports (when opted in) present as a slide-up sheet pinned\n // to the bottom edge, full-width, instead of a centred modal.\n const asSheet = wrPresentAsSheet(options.responsive, this.responsiveConfig);\n if (asSheet) panelClasses.push('wr-overlay-sheet');\n\n const position = this.overlay.position().global().centerHorizontally();\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy: asSheet ? position.bottom('0') : position.centerVertically(),\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: true,\n backdropClass: DEFAULT_BACKDROP_CLASS,\n panelClass: panelClasses,\n width: asSheet ? '100%' : options.width,\n maxWidth: asSheet ? '100%' : options.maxWidth,\n });\n\n const dialogRef = new WrDialogRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n dialogRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DIALOG_DATA, useValue: options.data },\n { provide: WR_DIALOG_REF, useValue: dialogRef },\n // Provided as its own token as well, so dialog content can reach for\n // the familiar `inject(WrDialogRef)` and close itself.\n { provide: WrDialogRef, useValue: dialogRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n dialogRef.componentRef = overlayRef.attach(portal);\n\n // Wired BEFORE the panel is decorated, and the order is the fix: everything\n // below attaches attributes, a ✕ and a focus trap to an overlay that is\n // already on screen, so anything that throws in there used to leave an\n // `aria-modal` panel with no dismissal path at all — no ✕, no backdrop\n // handler, no Escape — over the whole application, and no ref for the caller\n // to close it with. A dialog that fails to finish opening must still be one\n // the user can get rid of. Overlay subscriptions complete when the overlay is\n // disposed, so no explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => dialogRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n dialogRef.close();\n }\n });\n }\n if (options.closeOnNavigation !== false) {\n this.watchNavigation(overlayRef, dialogRef);\n }\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss. Appended after the content portal so it paints above\n // it, and marked on the panel so the title reserves the corner gutter.\n if (options.closable !== false) {\n host.classList.add('wr-dialog-panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-dialog__close', label, () => dialogRef.close());\n }\n // Wire aria-labelledby to wrDialogTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n //\n // And after EVERY render, not just the next one: the title belongs to the\n // caller's component, so an `@if` or a late-arriving heading can replace\n // or remove the element the attribute names. A reference to a node that is\n // no longer there is not a name — the dialog announces as unnamed — so a\n // missing title clears the attribute rather than leaving it dangling.\n const labelSync = afterEveryRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDialogTitle], [wr-dialog-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n },\n { injector: this.parentInjector }\n );\n // The hook is bound to the root injector, so it outlives the dialog unless\n // it is torn down with it. `detachments()` fires on dispose, which is the\n // one path every dismissal goes through.\n overlayRef.detachments().subscribe(() => labelSync.destroy());\n // Trap focus inside the dialog and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n dialogRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n return dialogRef;\n }\n\n /**\n * Tie the dialog's lifetime to the URL it was opened on.\n *\n * Nothing else does. The overlay belongs to a root service and is dismissed\n * only by the backdrop, Escape or an explicit `close()`, so pressing Back\n * swapped the routed view underneath and left the modal pane, its backdrop and\n * its focus trap sitting over a page the user never opened them on.\n *\n * `onUrlChange`, not `Location.subscribe()` — which is what CDK's own\n * `disposeOnNavigation` uses: `subscribe` fires on popstate alone, so an\n * in-app `router.navigate()` left the dialog standing. And `dialogRef.close()`\n * rather than disposing the overlay behind the ref's back, which would never\n * emit `closed`, never destroy the focus trap, and leave `awaitClose()`\n * pending forever.\n */\n private watchNavigation<C, R>(overlayRef: OverlayRef, dialogRef: WrDialogRef<C, R>): void {\n const stopWatching = this.location.onUrlChange(() => dialogRef.close());\n // Unhooked a microtask late, because `Location` notifies its listeners with\n // a `forEach` and unregistering splices the array it is iterating: removing\n // ours synchronously from inside the notification would shift the next entry\n // into the slot forEach has already passed, and a SECOND stacked dialog\n // would be skipped and left behind.\n overlayRef.detachments().subscribe(() => queueMicrotask(stopWatching));\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Two failure modes, and resolving PER OPEN is what covers both. `t()` hands\n * back the KEY on a miss, and `WrI18n` is root-provided with an empty catalog\n * by default, so an app that never configured i18n named its dismiss button\n * \"dialog.close\" — a name axe cannot fault, because a name is present, and a\n * screen reader reads out verbatim. Resolving once at injection time fixed\n * that but froze the answer: this is a root service, constructed before an\n * async catalog has loaded, so a localized app got the English fallback on\n * every dialog it ever opened.\n */\n private closeLabel(): string {\n const resolved = this.i18n?.t('dialog.close');\n return !resolved || resolved === 'dialog.close' ? 'Close dialog' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, ElementRef, inject } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Styles a dialog title row. Use on a heading inside an opened dialog.\n * Auto-assigns an `id` so the dialog panel can reference it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <h2 wrDialogTitle>Confirm delete</h2>\n * ```\n */\n@Directive({\n selector: '[wrDialogTitle]',\n host: { class: 'wr-dialog__title', '[attr.id]': 'id' },\n})\nexport class WrDialogTitle {\n /** Generated id used for `aria-labelledby` wiring. */\n readonly id = `wr-dialog-title-${++uid}`;\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { CdkScrollable } from '@angular/cdk/scrolling';\nimport { Directive } from '@angular/core';\n\n/**\n * Styles the scrollable body section of a dialog.\n *\n * `CdkScrollable` is a host directive because this element is a real scroll\n * container (`overflow: auto`) and an anchored overlay opened from inside it has\n * to follow its trigger. CDK's `reposition()` strategy listens to\n * `ScrollDispatcher`, which is fed by registered scrollables plus ONE\n * non-capturing `document` listener — and element `scroll` does not bubble, so\n * without the registration a `<wr-select>` halfway down a long dialog form kept\n * its panel pinned to the viewport while the trigger scrolled away. Angular\n * Material carries the same host directive on `MatDialogContent` for the same\n * reason.\n *\n * @example\n * ```html\n * <div wrDialogContent>…body…</div>\n * ```\n */\n@Directive({\n selector: '[wrDialogContent]',\n host: { class: 'wr-dialog__content' },\n hostDirectives: [CdkScrollable],\n})\nexport class WrDialogContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Footer row, typically holding action buttons.\n *\n * @example\n * ```html\n * <div wrDialogFooter align=\"end\">\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"danger\" (click)=\"confirm()\">Delete</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDialogFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDialogFooter {\n /**\n * Horizontal alignment of the children.\n *\n * @default 'end'\n */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-dialog__footer wr-dialog__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\nimport { WR_DIALOG_REF } from '../tokens';\n\n/**\n * Closes the dialog when the host element is clicked.\n *\n * Optionally passes a `[wrDialogClose]` value as the close result.\n *\n * @example\n * ```html\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" [wrDialogClose]=\"true\">Confirm</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDialogClose]',\n host: { '(click)': 'onClick()' },\n})\nexport class WrDialogClose<R = unknown> {\n /**\n * Value to pass to `close()`. When unset — or used as a bare attribute — the\n * dialog closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDialogClose',\n // A bare `wrDialogClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`. Matches `wrDrawerClose`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly ref = inject<WrDialogRef<unknown, R>>(WR_DIALOG_REF, { optional: true });\n\n protected onClick(): void {\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}