ngwr 13.0.1 → 14.0.0
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.
- package/README.md +13 -6
- package/color-picker/styles/_index.scss +43 -5
- package/fesm2022/ngwr-alert.mjs +5 -5
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +11 -1
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +13 -2
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +4 -4
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs +15 -0
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +51 -5
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +20 -1
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +89 -10
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +27 -3
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +7 -1
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +103 -13
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date.mjs +480 -79
- package/fesm2022/ngwr-date.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +30 -2
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +2 -1
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +1 -1
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +52 -12
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +63 -1
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +28 -1
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +150 -22
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +21 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +14 -7
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +20 -2
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
- package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
- package/fesm2022/ngwr-loading-bar.mjs +21 -32
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +104 -14
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs +11 -10
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +65 -30
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +3 -2
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +2 -1
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +93 -34
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +2 -1
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +35 -4
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +35 -12
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-router.mjs +158 -0
- package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
- package/fesm2022/ngwr-tabs-testing.mjs +13 -11
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +98 -10
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +20 -1
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +1 -1
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +2 -2
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +18 -2
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-utils.mjs +37 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs +10 -2
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +4 -4
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/i18n/en.json +33 -6
- package/i18n/ru.json +33 -6
- package/llms-full.txt +20 -11
- package/llms.txt +47 -16
- package/mcp/catalog.js +3 -3
- package/mcp/providers.js +11 -0
- package/package.json +9 -1
- package/schematics/migrations/v13/index.js +101 -0
- package/schematics/migrations/v14/index.js +422 -0
- package/schematics/migrations.json +10 -0
- package/schematics/page/templates.js +1 -1
- package/schematics/use/symbol-map.json +1 -0
- package/skills/ngwr/SKILL.md +4 -1
- package/skills/ngwr/references/catalog.md +2 -0
- package/skills/ngwr/references/setup.md +4 -0
- package/stepper/styles/_index.scss +19 -1
- package/textarea/styles/_index.scss +14 -6
- package/toast/styles/_index.scss +12 -4
- package/types/ngwr-alert.d.ts +3 -3
- package/types/ngwr-blur-text.d.ts +8 -0
- package/types/ngwr-button.d.ts +2 -2
- package/types/ngwr-calendar-testing.d.ts +21 -4
- package/types/ngwr-calendar.d.ts +37 -0
- package/types/ngwr-circular-text.d.ts +9 -0
- package/types/ngwr-collapse.d.ts +19 -15
- package/types/ngwr-color-picker-testing.d.ts +10 -4
- package/types/ngwr-color-picker.d.ts +70 -2
- package/types/ngwr-command-palette.d.ts +14 -0
- package/types/ngwr-context-menu.d.ts +1 -1
- package/types/ngwr-date-adapters-fns.d.ts +71 -29
- package/types/ngwr-date-picker-testing.d.ts +206 -185
- package/types/ngwr-date-picker.d.ts +7 -0
- package/types/ngwr-date.d.ts +143 -13
- package/types/ngwr-drag-drop.d.ts +19 -0
- package/types/ngwr-dropdown.d.ts +1 -1
- package/types/ngwr-event-calendar-testing.d.ts +12 -9
- package/types/ngwr-file-upload.d.ts +31 -3
- package/types/ngwr-i18n.d.ts +89 -7
- package/types/ngwr-input-number.d.ts +1 -1
- package/types/ngwr-input-otp.d.ts +3 -0
- package/types/ngwr-input.d.ts +11 -4
- package/types/ngwr-knob-testing.d.ts +8 -4
- package/types/ngwr-knob.d.ts +18 -0
- package/types/ngwr-loading-bar-router.d.ts +35 -0
- package/types/ngwr-loading-bar.d.ts +19 -9
- package/types/ngwr-mention.d.ts +13 -0
- package/types/ngwr-pagination-testing.d.ts +11 -10
- package/types/ngwr-pagination.d.ts +39 -10
- package/types/ngwr-popconfirm.d.ts +1 -1
- package/types/ngwr-popover.d.ts +1 -1
- package/types/ngwr-select.d.ts +65 -10
- package/types/ngwr-splitter-testing.d.ts +9 -4
- package/types/ngwr-squircle.d.ts +1 -1
- package/types/ngwr-statistic.d.ts +22 -2
- package/types/ngwr-table.d.ts +24 -5
- package/types/ngwr-tabs-router.d.ts +67 -0
- package/types/ngwr-tabs-testing.d.ts +12 -10
- package/types/ngwr-tabs.d.ts +103 -6
- package/types/ngwr-textarea.d.ts +9 -0
- package/types/ngwr-tree.d.ts +7 -0
- package/types/ngwr-utils.d.ts +33 -1
- package/types/ngwr-version.d.ts +1 -1
- package/types/ngwr-window-testing.d.ts +11 -3
- package/types/ngwr-window.d.ts +11 -4
- package/window/styles/_index.scss +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-command-palette.mjs","sources":["../../../projects/lib/command-palette/command-palette.ts","../../../projects/lib/command-palette/command-palette.html","../../../projects/lib/command-palette/ngwr-command-palette.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, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n type ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\n\nimport { WrHotkey, type WrHotkeyHandle, type WrHotkeySpec } from 'ngwr/hotkey';\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon } from 'ngwr/icon';\nimport { WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport type { WrCommandItem } from './interfaces';\n\ninterface Bucket {\n readonly title: string | null;\n readonly items: readonly WrCommandItem[];\n}\n\nlet listboxUid = 0;\n\nfunction bucketize(items: readonly WrCommandItem[]): readonly Bucket[] {\n const map = new Map<string | null, WrCommandItem[]>();\n for (const item of items) {\n const key = item.group ?? null;\n const bucket = map.get(key);\n if (bucket) bucket.push(item);\n else map.set(key, [item]);\n }\n return [...map.entries()].map(([title, items]) => ({ title, items }));\n}\n\nfunction matches(item: WrCommandItem, query: string): boolean {\n if (!query) return true;\n const q = query.toLowerCase();\n if (item.label.toLowerCase().includes(q)) return true;\n if (item.description?.toLowerCase().includes(q)) return true;\n if (item.group?.toLowerCase().includes(q)) return true;\n if (item.keywords?.some(k => k.toLowerCase().includes(q))) return true;\n return false;\n}\n\n/**\n * `⌘K`-style command palette — a centred modal with a search input and\n * filtered list of actions. Items can be grouped, have icons, descriptions,\n * and visual shortcut hints.\n *\n * Drop one at the root of the app, pass it the list of commands, and bind\n * a global hotkey (default `'mod+k'`). Use `[(open)]` for controlled\n * visibility, or let it manage itself.\n *\n * @example\n * ```html\n * <wr-command-palette [items]=\"commands\" trigger=\"mod+k\" (picked)=\"onPicked($event)\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/command-palette\n */\n@Component({\n selector: 'wr-command-palette',\n templateUrl: './command-palette.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrIcon],\n})\nexport class WrCommandPalette {\n /** Accessible name. Falls back to `commandPalette.label`, then `'Command palette'`. */\n readonly paletteLabel = input<string | null>(null);\n\n protected readonly resolvedPaletteLabel = useI18nText(this.paletteLabel, 'commandPalette.label', 'Command palette');\n\n /** Items shown in the palette. */\n readonly items = input<readonly WrCommandItem[]>([]);\n\n /** Controlled open state (two-way bindable). @default false */\n readonly open = model(false);\n\n /** Global hotkey that opens the palette. `null` disables auto-binding. @default 'mod+k' */\n readonly trigger = input<WrHotkeySpec | null>('mod+k');\n\n /** Search input placeholder. Falls back to `commandPalette.placeholder`. */\n readonly placeholder = input<string | null>(null);\n\n /** Text shown when no items match. Falls back to `commandPalette.noResults`. */\n readonly emptyText = input<string | null>(null);\n\n protected readonly resolvedPlaceholder = useI18nText(\n this.placeholder,\n 'commandPalette.placeholder',\n 'Type a command or search…'\n );\n protected readonly resolvedEmpty = useI18nText(this.emptyText, 'commandPalette.noResults', 'No results');\n\n /** Auto-close on `(picked)`. Set false to keep open. @default true */\n readonly closeOnPick = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Present the palette full-screen on small viewports instead of a centred\n * modal. `undefined` follows the app-wide `provideWrResponsiveOverlays()`\n * setting; `true`/`false` overrides it. The palette docks to the top (it\n * auto-focuses its input, so the on-screen keyboard stays clear).\n * @default undefined\n */\n readonly responsive = input<boolean | undefined, BooleanInput>(undefined, {\n transform: (v: BooleanInput): boolean | undefined => (v == null ? undefined : coerceBooleanProperty(v)),\n });\n\n /** Fires when the user commits an item (Enter / click). */\n readonly picked = output<WrCommandItem>();\n\n protected readonly query = signal('');\n protected readonly activeIndex = signal(0);\n\n /** Whether the current opening is presented full-screen. Decided on open. */\n protected readonly presentAsSheet = signal(false);\n protected readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('input');\n protected readonly panelEl = viewChild<ElementRef<HTMLElement>>('panel');\n\n /** Listbox id (referenced by the input's `aria-controls`). */\n protected readonly listboxId = `wr-command-palette-listbox-${++listboxUid}`;\n\n /** @internal Build a stable option id for a given flat index. */\n protected optionId(i: number): string {\n return `${this.listboxId}-opt-${i}`;\n }\n\n /**\n * A `role=\"listbox\"` may only own `option` and `group` children, so a titled\n * bucket becomes a labelled group and an untitled one drops out of the tree\n * entirely — leaving its options as the listbox's own children rather than as\n * role-less wrappers ARIA has no rule for.\n */\n protected groupTitleId(index: number): string {\n return `${this.listboxId}-group-${index}`;\n }\n\n /** Id of the active option for `aria-activedescendant`. */\n protected readonly activeOptionId = computed<string | null>(() => {\n const i = this.activeIndex();\n return i >= 0 && i < this.filtered().length ? this.optionId(i) : null;\n });\n\n private readonly hotkeys = inject(WrHotkey);\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private bindingHandle: WrHotkeyHandle | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n /** Grouped view — what the template renders. */\n protected readonly buckets = computed<readonly Bucket[]>(() =>\n bucketize(this.items().filter(item => matches(item, this.query())))\n );\n\n /**\n * Flat list in RENDER order — what keyboard navigation walks, and what every\n * index in this component means. Derived FROM the buckets rather than from the\n * filter: `bucketize` collects each group as it first appears, so a flat\n * source-order list disagrees with the screen the moment two groups interleave.\n * It did, and one ArrowDown moved the highlight two rows while Enter fired the\n * command below the one that looked selected.\n */\n protected readonly filtered = computed<readonly WrCommandItem[]>(() =>\n this.buckets().flatMap(bucket => bucket.items)\n );\n\n constructor() {\n // Bind / re-bind the global trigger whenever the spec changes.\n effect(() => {\n this.bindingHandle?.unbind();\n const spec = this.trigger();\n if (!spec) return;\n this.bindingHandle = this.hotkeys.bind(\n spec,\n event => {\n // CLAIM the chord, and the distinction is the whole point: the\n // `preventDefault` OPTION suppresses the browser, while a handler\n // calling `preventDefault()` is how `WrHotkey` is documented to learn\n // that a binding took the chord and the lower-priority ones should be\n // skipped. A palette that only toggled left the chord unclaimed, so\n // two palettes on one page would both open on `mod+k`.\n event.preventDefault();\n this.open.update(v => !v);\n },\n { allowInInput: true }\n );\n });\n\n // Reset query + active index whenever we open.\n effect(() => {\n if (!this.open()) return;\n this.query.set('');\n this.activeIndex.set(0);\n });\n\n // Sheet presentation, kept OUT of the reset above: reading `responsive()` there\n // made the reset depend on it, so a `[responsive]` bound to a signal that\n // flipped while the palette was open wiped whatever the user had typed.\n effect(() => {\n this.presentAsSheet.set(wrPresentAsSheet(this.responsive(), this.responsiveConfig));\n });\n\n // Focus trap + restore.\n effect(() => {\n if (!this.isBrowser) return;\n if (this.open()) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n queueMicrotask(() => {\n const host = this.panelEl()?.nativeElement;\n if (!host) return;\n this.focusTrap?.destroy();\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n });\n } else {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n if (restore && typeof restore.focus === 'function') restore.focus();\n }\n });\n\n afterNextRender(() => {\n if (this.open()) this.inputEl()?.nativeElement.focus();\n });\n\n // Auto-focus the input when opened.\n effect(() => {\n if (!this.open()) return;\n queueMicrotask(() => this.inputEl()?.nativeElement.focus());\n });\n\n // Clamp the active index when the filtered list shrinks.\n effect(() => {\n const max = Math.max(0, this.filtered().length - 1);\n if (this.activeIndex() > max) this.activeIndex.set(max);\n });\n\n this.destroyRef.onDestroy(() => {\n this.bindingHandle?.unbind();\n // The trap is torn down in the close branch of the effect above, which never\n // runs when the component itself goes away while still open — leaving a live\n // trap holding the removed panel and its document listeners.\n this.focusTrap?.destroy();\n this.focusTrap = null;\n });\n }\n\n // Template handlers\n\n protected onQueryInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n this.activeIndex.set(0);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const list = this.filtered();\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (list.length > 0) this.activeIndex.set((this.activeIndex() + 1) % list.length);\n this.revealActive();\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (list.length > 0) this.activeIndex.set((this.activeIndex() - 1 + list.length) % list.length);\n this.revealActive();\n break;\n case 'Home':\n event.preventDefault();\n this.activeIndex.set(0);\n this.revealActive();\n break;\n case 'End':\n event.preventDefault();\n this.activeIndex.set(Math.max(0, list.length - 1));\n this.revealActive();\n break;\n case 'Enter': {\n event.preventDefault();\n const item = list[this.activeIndex()];\n if (item) this.commit(item);\n break;\n }\n case 'Escape':\n event.preventDefault();\n this.close();\n break;\n default:\n break;\n }\n }\n\n protected onBackdropClick(): void {\n this.close();\n }\n\n protected onItemClick(item: WrCommandItem, event: MouseEvent): void {\n event.preventDefault();\n this.commit(item);\n }\n\n protected onItemHover(item: WrCommandItem): void {\n const i = this.filtered().indexOf(item);\n if (i >= 0) this.activeIndex.set(i);\n }\n\n /** Flat index of an item within the filtered list — for highlight checks. */\n protected indexOf(item: WrCommandItem): number {\n return this.filtered().indexOf(item);\n }\n\n // Public API\n\n /** Open the palette. */\n show(): void {\n this.open.set(true);\n }\n\n /** Close the palette. */\n close(): void {\n this.open.set(false);\n }\n\n // Internals\n\n /**\n * Keep the highlighted option on screen. The body is a fixed-height scroller and\n * the options are not focusable, so nothing moves it on the browser's behalf —\n * arrow keys walked the highlight straight off the bottom and out of sight.\n * Keyboard only: doing it on hover would fight the pointer that caused it.\n * `wr-select` and `wr-tree` keep the same promise through their own\n * `ensureVisible`; theirs is index maths because they are virtualized.\n */\n private revealActive(): void {\n if (!this.isBrowser) return;\n const id = this.activeOptionId();\n if (!id) return;\n // Ids are position-based and stable, so the element is findable straight away —\n // no need to wait for change detection to re-mark the active row.\n this.panelEl()?.nativeElement.querySelector<HTMLElement>(`#${id}`)?.scrollIntoView({ block: 'nearest' });\n }\n\n private commit(item: WrCommandItem): void {\n item.action?.();\n this.picked.emit(item);\n if (this.closeOnPick()) this.close();\n }\n}\n","@if (open()) {\n <div\n class=\"wr-command-palette\"\n [class.wr-command-palette--sheet]=\"presentAsSheet()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"resolvedPaletteLabel()\"\n >\n <!-- Backdrop captures clicks to close. Not focusable — keyboard users use\n Esc on the panel below. -->\n\n <div class=\"wr-command-palette__backdrop\" aria-hidden=\"true\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Keydown is delegated from the search input; tabindex enables Esc when\n the input is unfocused. -->\n <div #panel class=\"wr-command-palette__panel\" tabindex=\"-1\" (keydown)=\"onKeydown($event)\">\n <div class=\"wr-command-palette__search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M11 11 L14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n <input\n #input\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-autocomplete=\"list\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeOptionId() || null\"\n [placeholder]=\"resolvedPlaceholder()\"\n [value]=\"query()\"\n (input)=\"onQueryInput($event)\"\n />\n <kbd class=\"wr-command-palette__hint\">esc</kbd>\n </div>\n\n <!-- The empty row sits OUTSIDE the listbox below, and is a live region.\n A listbox may only own `option` and `group` children — the same rule\n the buckets already follow — so this row inside it was an\n `aria-required-children` critical for every query that matched\n nothing, and an empty listbox on its own is not. `role=\"status\"` also\n gets the message spoken while focus stays in the search input. -->\n @if (filtered().length === 0) {\n <div class=\"wr-command-palette__empty\" role=\"status\">{{ resolvedEmpty() }}</div>\n }\n\n <div class=\"wr-command-palette__body\" role=\"listbox\" [attr.id]=\"listboxId\">\n @for (bucket of buckets(); track bucket.title; let groupIndex = $index) {\n <!-- A listbox may only own `option` and `group` children, so a titled\n bucket is a labelled group and an untitled one leaves the tree with\n `role=\"none\"`, promoting its options to the listbox's own. -->\n <div\n class=\"wr-command-palette__group\"\n [attr.role]=\"bucket.title ? 'group' : 'none'\"\n [attr.aria-labelledby]=\"bucket.title ? groupTitleId(groupIndex) : null\"\n >\n @if (bucket.title) {\n <div class=\"wr-command-palette__group-title\" [attr.id]=\"groupTitleId(groupIndex)\">\n {{ bucket.title }}\n </div>\n }\n @for (item of bucket.items; track item.id) {\n <div\n class=\"wr-command-palette__option\"\n role=\"option\"\n [attr.id]=\"optionId(indexOf(item))\"\n [class.wr-command-palette__option--active]=\"indexOf(item) === activeIndex()\"\n [attr.aria-selected]=\"indexOf(item) === activeIndex()\"\n (mouseenter)=\"onItemHover(item)\"\n (mousedown)=\"onItemClick(item, $event)\"\n >\n @if (item.icon) {\n <wr-icon class=\"wr-command-palette__option-icon\" [name]=\"item.icon\" size=\"16\" />\n } @else {\n <span class=\"wr-command-palette__option-icon\" aria-hidden=\"true\"></span>\n }\n <div class=\"wr-command-palette__option-body\">\n <div class=\"wr-command-palette__option-label\">{{ item.label }}</div>\n @if (item.description) {\n <div class=\"wr-command-palette__option-description\">{{ item.description }}</div>\n }\n </div>\n @if (item.shortcut) {\n <kbd class=\"wr-command-palette__option-shortcut\">{{ item.shortcut }}</kbd>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;AAAA;;;;;AAKG;AAkCH,IAAI,UAAU,GAAG,CAAC;AAElB,SAAS,SAAS,CAAC,KAA+B,EAAA;AAChD,IAAA,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkC;AACrD,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI;QAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;AAC3B,QAAA,IAAI,MAAM;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3B;IACA,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACvE;AAEA,SAAS,OAAO,CAAC,IAAmB,EAAE,KAAa,EAAA;AACjD,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AACvB,IAAA,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE;IAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;IACrD,IAAI,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;IAC5D,IAAI,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;AACtD,IAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,OAAO,KAAK;AACd;AAEA;;;;;;;;;;;;;;;AAeG;MAOU,gBAAgB,CAAA;;IAElB,YAAY,GAAG,KAAK,CAAgB,IAAI;qFAAC;IAE/B,oBAAoB,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,CAAC;;IAG1G,KAAK,GAAG,KAAK,CAA2B,EAAE;8EAAC;;IAG3C,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;;IAGnB,OAAO,GAAG,KAAK,CAAsB,OAAO;gFAAC;;IAG7C,WAAW,GAAG,KAAK,CAAgB,IAAI;oFAAC;;IAGxC,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;IAE5B,mBAAmB,GAAG,WAAW,CAClD,IAAI,CAAC,WAAW,EAChB,4BAA4B,EAC5B,2BAA2B,CAC5B;IACkB,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,0BAA0B,EAAE,YAAY,CAAC;;IAG/F,WAAW,GAAG,KAAK,CAAC,IAAI,mFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAExE;;;;;;AAMG;AACM,IAAA,UAAU,GAAG,KAAK,CAAoC,SAAS,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,YAAA,EAAA,8BAAA,EAAA,CAAA,EACtE,SAAS,EAAE,CAAC,CAAe,MAA2B,CAAC,IAAI,IAAI,GAAG,SAAS,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,GACvG;;IAGO,MAAM,GAAG,MAAM,EAAiB;IAEtB,KAAK,GAAG,MAAM,CAAC,EAAE;8EAAC;IAClB,WAAW,GAAG,MAAM,CAAC,CAAC;oFAAC;;IAGvB,cAAc,GAAG,MAAM,CAAC,KAAK;uFAAC;IAC9B,OAAO,GAAG,SAAS,CAA+B,OAAO;gFAAC;IAC1D,OAAO,GAAG,SAAS,CAA0B,OAAO;gFAAC;;AAGrD,IAAA,SAAS,GAAG,CAAA,2BAAA,EAA8B,EAAE,UAAU,EAAE;;AAGjE,IAAA,QAAQ,CAAC,CAAS,EAAA;AAC1B,QAAA,OAAO,GAAG,IAAI,CAAC,SAAS,CAAA,KAAA,EAAQ,CAAC,EAAE;IACrC;AAEA;;;;;AAKG;AACO,IAAA,YAAY,CAAC,KAAa,EAAA;AAClC,QAAA,OAAO,GAAG,IAAI,CAAC,SAAS,CAAA,OAAA,EAAU,KAAK,EAAE;IAC3C;;AAGmB,IAAA,cAAc,GAAG,QAAQ,CAAgB,MAAK;AAC/D,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE;QAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IACvE,CAAC;uFAAC;AAEe,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC1B,IAAA,gBAAgB,GAAG,MAAM,CAAC,sBAAsB,CAAC;AACjD,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,gBAAgB,GAAG,MAAM,CAAC,4BAA4B,CAAC;IACvD,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3D,aAAa,GAA0B,IAAI;IAC3C,SAAS,GAAiC,IAAI;IAC9C,iBAAiB,GAAuB,IAAI;;AAGjC,IAAA,OAAO,GAAG,QAAQ,CAAoB,MACvD,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gFACpE;AAED;;;;;;;AAOG;IACgB,QAAQ,GAAG,QAAQ,CAA2B,MAC/D,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC;iFAC/C;AAED,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE;AAC5B,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;AAC3B,YAAA,IAAI,CAAC,IAAI;gBAAE;AACX,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CACpC,IAAI,EACJ,KAAK,IAAG;;;;;;;gBAON,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,YAAA,CAAC,EACD,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB;AACH,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE;AAClB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAClB,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;AACzB,QAAA,CAAC,CAAC;;;;QAKF,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACrF,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE;AACrB,YAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;AACf,gBAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,gBAAA,IAAI,CAAC,iBAAiB,GAAG,MAAM,YAAY,WAAW,GAAG,MAAM,GAAG,IAAI;gBACtE,cAAc,CAAC,MAAK;oBAClB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa;AAC1C,oBAAA,IAAI,CAAC,IAAI;wBAAE;AACX,oBAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;oBACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC;AACnD,oBAAA,KAAK,IAAI,CAAC,SAAS,CAAC,4BAA4B,EAAE;AACpD,gBAAA,CAAC,CAAC;YACJ;iBAAO;AACL,gBAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;AACzB,gBAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB;AACtC,gBAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC7B,gBAAA,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU;oBAAE,OAAO,CAAC,KAAK,EAAE;YACrE;AACF,QAAA,CAAC,CAAC;QAEF,eAAe,CAAC,MAAK;YACnB,IAAI,IAAI,CAAC,IAAI,EAAE;gBAAE,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,KAAK,EAAE;AACxD,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE;AAClB,YAAA,cAAc,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC;AAC7D,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACnD,YAAA,IAAI,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG;AAAE,gBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;AACzD,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AAC7B,YAAA,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE;;;;AAI5B,YAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;AACzB,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACvB,QAAA,CAAC,CAAC;IACJ;;AAIU,IAAA,YAAY,CAAC,KAAY,EAAA;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;AACxD,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB;AAEU,IAAA,SAAS,CAAC,KAAoB,EAAA;AACtC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,WAAW;gBACd,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;AAAE,oBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;gBACjF,IAAI,CAAC,YAAY,EAAE;gBACnB;AACF,YAAA,KAAK,SAAS;gBACZ,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;gBAC/F,IAAI,CAAC,YAAY,EAAE;gBACnB;AACF,YAAA,KAAK,MAAM;gBACT,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;gBACvB,IAAI,CAAC,YAAY,EAAE;gBACnB;AACF,YAAA,KAAK,KAAK;gBACR,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAClD,IAAI,CAAC,YAAY,EAAE;gBACnB;YACF,KAAK,OAAO,EAAE;gBACZ,KAAK,CAAC,cAAc,EAAE;gBACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AACrC,gBAAA,IAAI,IAAI;AAAE,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC3B;YACF;AACA,YAAA,KAAK,QAAQ;gBACX,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,KAAK,EAAE;gBACZ;AACF,YAAA;gBACE;;IAEN;IAEU,eAAe,GAAA;QACvB,IAAI,CAAC,KAAK,EAAE;IACd;IAEU,WAAW,CAAC,IAAmB,EAAE,KAAiB,EAAA;QAC1D,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IACnB;AAEU,IAAA,WAAW,CAAC,IAAmB,EAAA;QACvC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC;AAAE,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC;;AAGU,IAAA,OAAO,CAAC,IAAmB,EAAA;QACnC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACtC;;;IAKA,IAAI,GAAA;AACF,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IACrB;;IAGA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IACtB;;AAIA;;;;;;;AAOG;IACK,YAAY,GAAA;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AACrB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE;AAChC,QAAA,IAAI,CAAC,EAAE;YAAE;;;QAGT,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,aAAa,CAAc,CAAA,CAAA,EAAI,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC1G;AAEQ,IAAA,MAAM,CAAC,IAAmB,EAAA;AAChC,QAAA,IAAI,CAAC,MAAM,IAAI;AACf,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,KAAK,EAAE;IACtC;uGA9RW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,IAAA,EAAA,YAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,OAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,OAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECpF7B,q5IA+FA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDbY,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAEL,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAN5B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,iBAEf,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B,CAAC,MAAM,CAAC,EAAA,QAAA,EAAA,q5IAAA,EAAA;AAoDoD,SAAA,CAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,cAAA,EAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,cAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,YAAA,CAAA,EAAA,CAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,UAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,CAAA,OAAO,iEACZ,OAAO,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AEvIzE;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngwr-command-palette.mjs","sources":["../../../projects/lib/command-palette/command-palette.ts","../../../projects/lib/command-palette/command-palette.html","../../../projects/lib/command-palette/ngwr-command-palette.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, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n type ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\n\nimport { WrHotkey, type WrHotkeyHandle, type WrHotkeySpec } from 'ngwr/hotkey';\nimport { readI18nText, useI18nText } from 'ngwr/i18n';\nimport { WrIcon } from 'ngwr/icon';\nimport { WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet } from 'ngwr/overlay';\nimport { isComposing } from 'ngwr/utils';\n\nimport type { WrCommandItem } from './interfaces';\n\ninterface Bucket {\n readonly title: string | null;\n readonly items: readonly WrCommandItem[];\n}\n\nlet listboxUid = 0;\n\nfunction bucketize(items: readonly WrCommandItem[]): readonly Bucket[] {\n const map = new Map<string | null, WrCommandItem[]>();\n for (const item of items) {\n const key = item.group ?? null;\n const bucket = map.get(key);\n if (bucket) bucket.push(item);\n else map.set(key, [item]);\n }\n return [...map.entries()].map(([title, items]) => ({ title, items }));\n}\n\nfunction matches(item: WrCommandItem, query: string): boolean {\n if (!query) return true;\n const q = query.toLowerCase();\n if (item.label.toLowerCase().includes(q)) return true;\n if (item.description?.toLowerCase().includes(q)) return true;\n if (item.group?.toLowerCase().includes(q)) return true;\n if (item.keywords?.some(k => k.toLowerCase().includes(q))) return true;\n return false;\n}\n\n/**\n * `⌘K`-style command palette — a centred modal with a search input and\n * filtered list of actions. Items can be grouped, have icons, descriptions,\n * and visual shortcut hints.\n *\n * Drop one at the root of the app, pass it the list of commands, and bind\n * a global hotkey (default `'mod+k'`). Use `[(open)]` for controlled\n * visibility, or let it manage itself.\n *\n * @example\n * ```html\n * <wr-command-palette [items]=\"commands\" trigger=\"mod+k\" (picked)=\"onPicked($event)\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/command-palette\n */\n@Component({\n selector: 'wr-command-palette',\n templateUrl: './command-palette.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrIcon],\n})\nexport class WrCommandPalette {\n /** Accessible name. Falls back to `commandPalette.label`, then `'Command palette'`. */\n readonly paletteLabel = input<string | null>(null);\n\n protected readonly resolvedPaletteLabel = useI18nText(this.paletteLabel, 'commandPalette.label', 'Command palette');\n\n /** Items shown in the palette. */\n readonly items = input<readonly WrCommandItem[]>([]);\n\n /** Controlled open state (two-way bindable). @default false */\n readonly open = model(false);\n\n /** Global hotkey that opens the palette. `null` disables auto-binding. @default 'mod+k' */\n readonly trigger = input<WrHotkeySpec | null>('mod+k');\n\n /** Search input placeholder. Falls back to `commandPalette.placeholder`. */\n readonly placeholder = input<string | null>(null);\n\n /** Text shown when no items match. Falls back to `commandPalette.noResults`. */\n readonly emptyText = input<string | null>(null);\n\n protected readonly resolvedPlaceholder = useI18nText(\n this.placeholder,\n 'commandPalette.placeholder',\n 'Type a command or search…'\n );\n protected readonly resolvedEmpty = useI18nText(this.emptyText, 'commandPalette.noResults', 'No results');\n\n /**\n * The key-cap chip beside the search field. It was the literal `esc` in the\n * template — the one string on this component no catalog could reach, so a\n * fully Russian palette still hinted in English.\n */\n protected readonly resolvedEscHint = readI18nText('commandPalette.escHint', 'esc');\n\n /** Auto-close on `(picked)`. Set false to keep open. @default true */\n readonly closeOnPick = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Present the palette full-screen on small viewports instead of a centred\n * modal. `undefined` follows the app-wide `provideWrResponsiveOverlays()`\n * setting; `true`/`false` overrides it. The palette docks to the top (it\n * auto-focuses its input, so the on-screen keyboard stays clear).\n * @default undefined\n */\n readonly responsive = input<boolean | undefined, BooleanInput>(undefined, {\n transform: (v: BooleanInput): boolean | undefined => (v == null ? undefined : coerceBooleanProperty(v)),\n });\n\n /** Fires when the user commits an item (Enter / click). */\n readonly picked = output<WrCommandItem>();\n\n protected readonly query = signal('');\n protected readonly activeIndex = signal(0);\n\n /** Whether the current opening is presented full-screen. Decided on open. */\n protected readonly presentAsSheet = signal(false);\n protected readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('input');\n protected readonly panelEl = viewChild<ElementRef<HTMLElement>>('panel');\n\n /** Listbox id (referenced by the input's `aria-controls`). */\n protected readonly listboxId = `wr-command-palette-listbox-${++listboxUid}`;\n\n /** @internal Build a stable option id for a given flat index. */\n protected optionId(i: number): string {\n return `${this.listboxId}-opt-${i}`;\n }\n\n /**\n * A `role=\"listbox\"` may only own `option` and `group` children, so a titled\n * bucket becomes a labelled group and an untitled one drops out of the tree\n * entirely — leaving its options as the listbox's own children rather than as\n * role-less wrappers ARIA has no rule for.\n */\n protected groupTitleId(index: number): string {\n return `${this.listboxId}-group-${index}`;\n }\n\n /** Id of the active option for `aria-activedescendant`. */\n protected readonly activeOptionId = computed<string | null>(() => {\n const i = this.activeIndex();\n return i >= 0 && i < this.filtered().length ? this.optionId(i) : null;\n });\n\n private readonly hotkeys = inject(WrHotkey);\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private bindingHandle: WrHotkeyHandle | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n /**\n * The open branch below builds the trap inside a `queueMicrotask`, so a\n * palette destroyed while open — in the same task that opened it — runs its\n * destroy hook first and then constructs a fresh trap nothing will ever\n * destroy. A `ConfigurableFocusTrap` plants two anchor elements in the panel\n * and holds it, so that is retained DOM, not just a stray object.\n */\n private destroyed = false;\n\n /** Grouped view — what the template renders. */\n protected readonly buckets = computed<readonly Bucket[]>(() =>\n bucketize(this.items().filter(item => matches(item, this.query())))\n );\n\n /**\n * Flat list in RENDER order — what keyboard navigation walks, and what every\n * index in this component means. Derived FROM the buckets rather than from the\n * filter: `bucketize` collects each group as it first appears, so a flat\n * source-order list disagrees with the screen the moment two groups interleave.\n * It did, and one ArrowDown moved the highlight two rows while Enter fired the\n * command below the one that looked selected.\n */\n protected readonly filtered = computed<readonly WrCommandItem[]>(() =>\n this.buckets().flatMap(bucket => bucket.items)\n );\n\n constructor() {\n // Bind / re-bind the global trigger whenever the spec changes.\n effect(() => {\n this.bindingHandle?.unbind();\n const spec = this.trigger();\n if (!spec) return;\n this.bindingHandle = this.hotkeys.bind(\n spec,\n event => {\n // CLAIM the chord, and the distinction is the whole point: the\n // `preventDefault` OPTION suppresses the browser, while a handler\n // calling `preventDefault()` is how `WrHotkey` is documented to learn\n // that a binding took the chord and the lower-priority ones should be\n // skipped. A palette that only toggled left the chord unclaimed, so\n // two palettes on one page would both open on `mod+k`.\n event.preventDefault();\n this.open.update(v => !v);\n },\n { allowInInput: true }\n );\n });\n\n // Reset query + active index whenever we open.\n effect(() => {\n if (!this.open()) return;\n this.query.set('');\n this.activeIndex.set(0);\n });\n\n // Sheet presentation, kept OUT of the reset above: reading `responsive()` there\n // made the reset depend on it, so a `[responsive]` bound to a signal that\n // flipped while the palette was open wiped whatever the user had typed.\n effect(() => {\n this.presentAsSheet.set(wrPresentAsSheet(this.responsive(), this.responsiveConfig));\n });\n\n // Focus trap + restore.\n effect(() => {\n if (!this.isBrowser) return;\n if (this.open()) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n queueMicrotask(() => {\n if (this.destroyed) return;\n const host = this.panelEl()?.nativeElement;\n if (!host) return;\n this.focusTrap?.destroy();\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n });\n } else {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n if (restore && typeof restore.focus === 'function') restore.focus();\n }\n });\n\n afterNextRender(() => {\n if (this.open()) this.inputEl()?.nativeElement.focus();\n });\n\n // Auto-focus the input when opened.\n effect(() => {\n if (!this.open()) return;\n queueMicrotask(() => this.inputEl()?.nativeElement.focus());\n });\n\n // Clamp the active index when the filtered list shrinks.\n effect(() => {\n const max = Math.max(0, this.filtered().length - 1);\n if (this.activeIndex() > max) this.activeIndex.set(max);\n });\n\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.bindingHandle?.unbind();\n // The trap is torn down in the close branch of the effect above, which never\n // runs when the component itself goes away while still open — leaving a live\n // trap holding the removed panel and its document listeners.\n this.focusTrap?.destroy();\n this.focusTrap = null;\n });\n }\n\n // Template handlers\n\n protected onQueryInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n this.activeIndex.set(0);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n // Every key below belongs to the input method while it is converting: Enter\n // accepts a candidate, Escape cancels the conversion, the arrows walk the\n // candidate list. Acting on them closed the palette — and threw the query\n // away — the first time a Japanese user pressed Escape to undo a reading.\n if (isComposing(event)) return;\n\n const list = this.filtered();\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (list.length > 0) this.activeIndex.set((this.activeIndex() + 1) % list.length);\n this.revealActive();\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (list.length > 0) this.activeIndex.set((this.activeIndex() - 1 + list.length) % list.length);\n this.revealActive();\n break;\n case 'Home':\n event.preventDefault();\n this.activeIndex.set(0);\n this.revealActive();\n break;\n case 'End':\n event.preventDefault();\n this.activeIndex.set(Math.max(0, list.length - 1));\n this.revealActive();\n break;\n case 'Enter': {\n event.preventDefault();\n const item = list[this.activeIndex()];\n if (item) this.commit(item);\n break;\n }\n case 'Escape':\n event.preventDefault();\n this.close();\n break;\n default:\n break;\n }\n }\n\n protected onBackdropClick(): void {\n this.close();\n }\n\n protected onItemClick(item: WrCommandItem, event: MouseEvent): void {\n event.preventDefault();\n this.commit(item);\n }\n\n protected onItemHover(item: WrCommandItem): void {\n const i = this.filtered().indexOf(item);\n if (i >= 0) this.activeIndex.set(i);\n }\n\n /** Flat index of an item within the filtered list — for highlight checks. */\n protected indexOf(item: WrCommandItem): number {\n return this.filtered().indexOf(item);\n }\n\n // Public API\n\n /** Open the palette. */\n show(): void {\n this.open.set(true);\n }\n\n /** Close the palette. */\n close(): void {\n this.open.set(false);\n }\n\n // Internals\n\n /**\n * Keep the highlighted option on screen. The body is a fixed-height scroller and\n * the options are not focusable, so nothing moves it on the browser's behalf —\n * arrow keys walked the highlight straight off the bottom and out of sight.\n * Keyboard only: doing it on hover would fight the pointer that caused it.\n * `wr-select` and `wr-tree` keep the same promise through their own\n * `ensureVisible`; theirs is index maths because they are virtualized.\n */\n private revealActive(): void {\n if (!this.isBrowser) return;\n const id = this.activeOptionId();\n if (!id) return;\n // Ids are position-based and stable, so the element is findable straight away —\n // no need to wait for change detection to re-mark the active row.\n this.panelEl()?.nativeElement.querySelector<HTMLElement>(`#${id}`)?.scrollIntoView({ block: 'nearest' });\n }\n\n private commit(item: WrCommandItem): void {\n item.action?.();\n this.picked.emit(item);\n if (this.closeOnPick()) this.close();\n }\n}\n","@if (open()) {\n <div\n class=\"wr-command-palette\"\n [class.wr-command-palette--sheet]=\"presentAsSheet()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"resolvedPaletteLabel()\"\n >\n <!-- Backdrop captures clicks to close. Not focusable — keyboard users use\n Esc on the panel below. -->\n\n <div class=\"wr-command-palette__backdrop\" aria-hidden=\"true\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Keydown is delegated from the search input; tabindex enables Esc when\n the input is unfocused. -->\n <div #panel class=\"wr-command-palette__panel\" tabindex=\"-1\" (keydown)=\"onKeydown($event)\">\n <div class=\"wr-command-palette__search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n <path d=\"M11 11 L14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n <input\n #input\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-autocomplete=\"list\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeOptionId() || null\"\n [placeholder]=\"resolvedPlaceholder()\"\n [value]=\"query()\"\n (input)=\"onQueryInput($event)\"\n />\n <kbd class=\"wr-command-palette__hint\">{{ resolvedEscHint() }}</kbd>\n </div>\n\n <!-- The empty row sits OUTSIDE the listbox below, and is a live region.\n A listbox may only own `option` and `group` children — the same rule\n the buckets already follow — so this row inside it was an\n `aria-required-children` critical for every query that matched\n nothing, and an empty listbox on its own is not. `role=\"status\"` also\n gets the message spoken while focus stays in the search input. -->\n @if (filtered().length === 0) {\n <div class=\"wr-command-palette__empty\" role=\"status\">{{ resolvedEmpty() }}</div>\n }\n\n <div class=\"wr-command-palette__body\" role=\"listbox\" [attr.id]=\"listboxId\">\n @for (bucket of buckets(); track bucket.title; let groupIndex = $index) {\n <!-- A listbox may only own `option` and `group` children, so a titled\n bucket is a labelled group and an untitled one leaves the tree with\n `role=\"none\"`, promoting its options to the listbox's own. -->\n <div\n class=\"wr-command-palette__group\"\n [attr.role]=\"bucket.title ? 'group' : 'none'\"\n [attr.aria-labelledby]=\"bucket.title ? groupTitleId(groupIndex) : null\"\n >\n @if (bucket.title) {\n <div class=\"wr-command-palette__group-title\" [attr.id]=\"groupTitleId(groupIndex)\">\n {{ bucket.title }}\n </div>\n }\n @for (item of bucket.items; track item.id) {\n <div\n class=\"wr-command-palette__option\"\n role=\"option\"\n [attr.id]=\"optionId(indexOf(item))\"\n [class.wr-command-palette__option--active]=\"indexOf(item) === activeIndex()\"\n [attr.aria-selected]=\"indexOf(item) === activeIndex()\"\n (mouseenter)=\"onItemHover(item)\"\n (mousedown)=\"onItemClick(item, $event)\"\n >\n @if (item.icon) {\n <wr-icon class=\"wr-command-palette__option-icon\" [name]=\"item.icon\" size=\"16\" />\n } @else {\n <span class=\"wr-command-palette__option-icon\" aria-hidden=\"true\"></span>\n }\n <div class=\"wr-command-palette__option-body\">\n <div class=\"wr-command-palette__option-label\">{{ item.label }}</div>\n @if (item.description) {\n <div class=\"wr-command-palette__option-description\">{{ item.description }}</div>\n }\n </div>\n @if (item.shortcut) {\n <kbd class=\"wr-command-palette__option-shortcut\">{{ item.shortcut }}</kbd>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1041,12 +1041,18 @@ class WrContextMenu {
|
|
|
1041
1041
|
}, WrContextMenu.LEAVE_DELAY);
|
|
1042
1042
|
}
|
|
1043
1043
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrContextMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1044
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: WrContextMenu, isStandalone: true, selector: "[wrContextMenu]", inputs: { menu: { classPropertyName: "menu", publicName: "wrContextMenu", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "contextmenu": "onContextMenu($event)", "pointerdown": "onPointerDown($event)", "pointermove": "onPointerMove($event)", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()" }, properties: { "attr.aria-controls": "openMenuId()" }, classAttribute: "wr-context-menu-host" }, ngImport: i0 });
|
|
1044
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: WrContextMenu, isStandalone: true, selector: "[wrContextMenu]", inputs: { menu: { classPropertyName: "menu", publicName: "wrContextMenu", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "contextmenu": "onContextMenu($event)", "pointerdown": "onPointerDown($event)", "pointermove": "onPointerMove($event)", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()" }, properties: { "attr.aria-controls": "openMenuId()" }, classAttribute: "wr-context-menu-host" }, exportAs: ["wrContextMenuTrigger"], ngImport: i0 });
|
|
1045
1045
|
}
|
|
1046
1046
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrContextMenu, decorators: [{
|
|
1047
1047
|
type: Directive,
|
|
1048
1048
|
args: [{
|
|
1049
1049
|
selector: '[wrContextMenu]',
|
|
1050
|
+
// `wrContextMenuTrigger`, not `wrContextMenu`: the PANEL component already
|
|
1051
|
+
// exports itself under the plain name, which is what `<wr-context-menu #menu>`
|
|
1052
|
+
// hands to `[wrContextMenu]="menu"`. Two directives may share an `exportAs`
|
|
1053
|
+
// without a compile error — the reference resolves per element — so the clash
|
|
1054
|
+
// would only surface as the wrong instance on an element carrying both.
|
|
1055
|
+
exportAs: 'wrContextMenuTrigger',
|
|
1050
1056
|
host: {
|
|
1051
1057
|
class: 'wr-context-menu-host',
|
|
1052
1058
|
'[attr.aria-controls]': 'openMenuId()',
|
|
@@ -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 // 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":";;;;;;;;;;;AAAA;;;;;AAKG;AAEH;;;;;;;;;;;AAWG;AAEH;;;AAGG;AACG,SAAU,WAAW,CAAC,IAAiB,EAAA;IAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,4DAA4D,CAAC,CAAC;AACrH;AAEA;AACM,SAAU,iBAAiB,CAAC,IAAiB,EAAE,KAAa,EAAA;AAChE,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;AAC/B,IAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE;AACxB,IAAA,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;AACtE,IAAA,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE;AACzB;AAEA;;;AAGG;AACG,SAAU,sBAAsB,CAAC,IAAiB,EAAE,KAAoB,EAAA;AAC5E,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;AAC/B,IAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK;AACpC,IAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;;;AAGrC,IAAA,MAAM,KAAK,GAAG,MAAM,YAAY,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACxE,IAAA,QAAQ,KAAK,CAAC,GAAG;AACf,QAAA,KAAK,WAAW;AACd,YAAA,iBAAiB,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC;YAClC;AACF,QAAA,KAAK,SAAS;YACZ,iBAAiB,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YAClE;AACF,QAAA,KAAK,MAAM;AACT,YAAA,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1B;AACF,QAAA,KAAK,KAAK;YACR,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC;AACF,QAAA;AACE,YAAA,OAAO,KAAK;;IAEhB,KAAK,CAAC,cAAc,EAAE;AACtB,IAAA,OAAO,IAAI;AACb;;ACjEA;;;;;AAKG;AA4BH;AACA,MAAM,kBAAkB,GAAG,GAAG;AAC9B;AACA,MAAM,mBAAmB,GAAG,GAAG;AAC/B;AACA,MAAM,qBAAqB,GAAG,GAAG;AAEjC;;;;;;;;;;;;;;;;;AAiBG;MAuBU,iBAAiB,CAAA;;IAEnB,IAAI,GAAG,KAAK,CAAoB,IAAI;6EAAC;;IAGrC,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAEtE;;;AAGG;IACM,OAAO,GAAG,KAAK,CAA4B,IAAI;gFAAC;AAEtC,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,CAAC,sBAAsB,CAAC;QACtC,IAAI,IAAI,CAAC,QAAQ,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC;QACjE,IAAI,IAAI,CAAC,OAAO,EAAE;AAAE,YAAA,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC;AACnE,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;gFAAC;AAEe,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC;AAClD,IAAA,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;IAC5B,GAAG,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAChD,IAAA,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC9B,IAAA,gBAAgB,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAChD,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAExC,UAAU,GAAsB,IAAI;IACpC,WAAW,GAAwB,IAAI;IACvC,SAAS,GAAyC,IAAI;IACtD,UAAU,GAAyC,IAAI;IACrD,WAAW,GAAG,KAAK;AAC7B;;;;;AAKG;IACK,gBAAgB,GAAG,KAAK;AAEhC;;;;;;;;;;;;;AAaG;IACgB,SAAS,GAAG,MAAM,CAAgB,IAAI;kFAAC;AAE1D;;;;;;AAMG;AACK,IAAA,OAAgB,YAAY,GAAG,IAAI,GAAG,EAAkC;AAEhF;;;;;AAKG;IACH,OAAO,UAAU,CAAC,SAAkB,EAAA;AAClC,QAAA,KAAK,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,YAAY,CAAC,EAAE;AAC3D,YAAA,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC;QACjC;IACF;AAEA,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5D;AAEA;;;;;;;;AAQG;IACO,OAAO,GAAA;QACf,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE;YAAE;QACvC,cAAc,CAAC,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC;IACnD;;AAGU,IAAA,QAAQ,CAAC,KAAY,EAAA;QAC7B,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;AACrB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YAClB,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;AAC5B,YAAA,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YACpB;QACF;QACA,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;IACjC;AAEA;;;;;AAKG;AACO,IAAA,YAAY,CAAC,KAAY,EAAA;QACjC,IAAI,IAAI,CAAC,KAAK,EAAE;AAAE,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;AACjD,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IACzB;;AAGU,IAAA,WAAW,CAAC,KAAY,EAAA;QAChC,IAAI,IAAI,CAAC,KAAK,EAAE;AAAE,YAAA,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAChD,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IAC1B;AAEQ,IAAA,WAAW,CAAC,KAAY,EAAA;QAC9B,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE;QACxC,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;AAC5B,QAAA,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACtB;AAEQ,IAAA,YAAY,CAAC,KAAY,EAAA;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE;QAC1C,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACvB;;IAGU,YAAY,GAAA;QACpB,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE;QACxC,IAAI,CAAC,WAAW,EAAE;AAClB,QAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK;AAC7B,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC;IACvC;;AAGU,IAAA,YAAY,CAAC,KAAiB,EAAA;AACtC,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE;QACrB,IAAI,CAAC,UAAU,EAAE;;;;;;AAMjB,QAAA,IAAI,IAAI,CAAC,+BAA+B,CAAC,KAAK,CAAC;YAAE;AACjD,QAAA,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;IACzC;;AAIQ,IAAA,YAAY,CAAC,KAAa,EAAA;QAChC,IAAI,IAAI,CAAC,UAAU;YAAE;QACrB,IAAI,CAAC,UAAU,EAAE;AACjB,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;YACf,IAAI,CAAC,WAAW,EAAE;YAClB;QACF;AACA,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,MAAK;AAC/B,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;YACrB,IAAI,CAAC,WAAW,EAAE;QACpB,CAAC,EAAE,KAAK,CAAC;IACX;AAEQ,IAAA,aAAa,CAAC,KAAa,EAAA;QACjC,IAAI,CAAC,WAAW,EAAE;AAClB,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;AACf,YAAA,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;YAC1B;QACF;AACA,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAK;AAChC,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,YAAA,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;QAC5B,CAAC,EAAE,KAAK,CAAC;IACX;IAEQ,UAAU,GAAA;AAChB,QAAA,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE;AAC3B,YAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;AAC5B,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;QACvB;IACF;IAEQ,WAAW,GAAA;AACjB,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;AAC5B,YAAA,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAC7B,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;QACxB;IACF;IAEQ,WAAW,GAAA;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE;AAC5B,QAAA,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU;YAAE;;;AAI/B,QAAA,MAAM,SAAS,GAAwB;AACrC,YAAA,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;YAClF,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;SACpF;AAED,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC3B,aAAA,QAAQ;AACR,aAAA,mBAAmB,CAAC,IAAI,CAAC,IAAI;aAC7B,aAAa,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;aACtD,QAAQ,CAAC,IAAI,CAAC;QAEjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACpC,gBAAgB;AAChB,YAAA,cAAc,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE;AAClD,YAAA,UAAU,EAAE,CAAC,yBAAyB,EAAE,kCAAkC,CAAC;AAC5E,SAAA,CAAC;AAEF,QAAA,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC;AAC/D,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;;AAG9B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc;AAC3C,QAAA,qBAAqB,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;;;QAIhF,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAc,kBAAkB,CAAC;QAClE,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,iBAAiB,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B;;;QAIA,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC;QACxD,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC;;;;;QAMxD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;;QAGnG,IAAI,IAAI,CAAC,gBAAgB;AAAE,YAAA,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;AAErD,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,iBAAiB,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC;IACnE;AAEA;;;;;;;;;;;;;;;;AAgBG;AACK,IAAA,gBAAgB,CAAC,KAAoB,EAAA;AAC3C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc;AAC5C,QAAA,IAAI,CAAC,IAAI;YAAE;;;;QAIX,IAAI,KAAK,CAAC,gBAAgB;YAAE;AAC5B,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,QAAA,MAAM,WAAW,GAAG,MAAM,YAAY,OAAO,GAAG,MAAM,CAAC,OAAO,CAAc,0BAA0B,CAAC,GAAG,IAAI;AAC9G,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,YAAY,GAAG,WAAW;AACtD,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,EAAE;YAChD,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;;;;YAI1B,IAAI,WAAW,KAAK,IAAI;AAAE,gBAAA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;YACzD;QACF;;;AAGA,QAAA,sBAAsB,CAAC,WAAW,IAAI,IAAI,EAAE,KAAK,CAAC;IACpD;;IAGiB,cAAc,GAAG,MAAW;QAC3C,IAAI,CAAC,WAAW,EAAE;;;QAGlB,aAAa,CAAC,cAAc,EAAE;AAChC,IAAA,CAAC;AACgB,IAAA,cAAc,GAAG,CAAC,KAAiB,KAAU;;;;;;AAM5D,QAAA,IAAI,IAAI,CAAC,sCAAsC,CAAC,KAAK,CAAC;YAAE;AACxD,QAAA,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;;;;QAIvC,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;YAC7C,aAAa,CAAC,kBAAkB,EAAE;QACpC;AACF,IAAA,CAAC;AAEO,IAAA,4BAA4B,CAAC,KAAiB,EAAA;AACpD,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa;AACnC,QAAA,IAAI,EAAE,OAAO,YAAY,OAAO,CAAC;AAAE,YAAA,OAAO,KAAK;QAC/C,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC;IACtD;AAEA;;;;AAIG;AACK,IAAA,+BAA+B,CAAC,KAAiB,EAAA;AACvD,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa;QACnC,IAAI,EAAE,OAAO,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,KAAK;QACnE,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzD;AAEA;;;;;;AAMG;AACK,IAAA,sCAAsC,CAAC,KAAiB,EAAA;AAC9D,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa;QACnC,IAAI,EAAE,OAAO,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,KAAK;QACnE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC;AAC9D,QAAA,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,KAAK;AAC7B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc;QAC7C,IAAI,UAAU,KAAK,MAAM;AAAE,YAAA,OAAO,IAAI;;;;QAItC,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,iBAAiB,CAAC,YAAY,EAAE;YAC7D,IAAI,KAAK,CAAC,UAAU,EAAE,cAAc,KAAK,UAAU,EAAE;AACnD,gBAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjC;QACF;AACA,QAAA,OAAO,KAAK;IACd;AAEQ,IAAA,cAAc,CAAC,SAAkB,EAAA;QACvC,IAAI,CAAC,UAAU,EAAE;QACjB,IAAI,CAAC,WAAW,EAAE;AAClB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;AAC3B,QAAA,IAAI,CAAC,GAAG;YAAE;AACV,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK;AACxB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;;;;;AAKxB,QAAA,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE;AAC/B,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;QACvB,iBAAiB,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;AAE9D,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc;QAC/B,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC;QAC3D,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC;;;;;;QAO3D,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,iBAAiB,CAAC,YAAY,EAAE;AAC7D,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,gBAAA,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC;QAC7D;QAEA,IAAI,SAAS,EAAE;YACb,GAAG,CAAC,OAAO,EAAE;YACb;QACF;AACA,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC;QACtD,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC;IACxD;AAEA;;;;;;AAMG;IACK,KAAK,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK,KAAK;IAClC;uGAxZW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,UAAA,EAAA,EAAA,SAAA,EAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,sBAAA,EAAA,OAAA,EAAA,WAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,eAAA,EAAA,IAAA,EAAA,oBAAA,EAAA,0BAAA,EAAA,oBAAA,EAAA,6BAAA,EAAA,oBAAA,EAAA,yDAAA,EAAA,oBAAA,EAAA,aAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChF9B,8hBAmBA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED2DY,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAEL,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAtB7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,EAAA,aAAA,EAEjB,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,IAAI,EAAE,UAAU;AAChB,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,iBAAiB,EAAE,IAAI;AACvB,wBAAA,sBAAsB,EAAE,0BAA0B;AAClD,wBAAA,sBAAsB,EAAE,2BAA2B;AACnD,wBAAA,sBAAsB,EAAE,qDAAqD;AAC7E,wBAAA,sBAAsB,EAAE,aAAa;AACrC,wBAAA,cAAc,EAAE,gBAAgB;AAChC,wBAAA,cAAc,EAAE,sBAAsB;AACtC,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,iBAAiB,EAAE,kBAAkB;AACrC,wBAAA,iBAAiB,EAAE,kBAAkB;AACrC,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,qBAAqB,EAAE,qBAAqB;qBAC7C,EAAA,OAAA,EACQ,CAAC,MAAM,CAAC,EAAA,QAAA,EAAA,8hBAAA,EAAA;;;AE9EnB;;;;;AAKG;AAqBH;;;;;;;;;;AAUG;AACH,MAAM,iBAAiB,GAAwB;AAC7C,IAAA,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;AACxE,IAAA,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE;AAC3E,IAAA,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;AACtE,IAAA,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE;CAC1E;AAED;;;;;;;;;AASG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa,EAAA;IACjD,OAAO;AACL,QAAA,KAAK,EAAE,CAAC;AACR,QAAA,MAAM,EAAE,CAAC;AACT,QAAA,IAAI,CAAC,GAAA;AACH,YAAA,OAAO,KAAK,GAAG,MAAM,CAAC,OAAO;QAC/B,CAAC;AACD,QAAA,IAAI,CAAC,GAAA;AACH,YAAA,OAAO,KAAK,GAAG,MAAM,CAAC,OAAO;QAC/B,CAAC;KACF;AACH;AAEA;;;;;;;;;;;;;;;;AAgBG;MAaU,aAAa,CAAA;;IAEf,IAAI,GAAG,KAAK,CAAC,QAAQ,2EAAuB,KAAK,EAAE,eAAe,EAAA,CAAG;AAE7D,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC;AAClD,IAAA,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;AAC5B,IAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC;AACrC,IAAA,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC9B,IAAA,gBAAgB,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAChD,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhD;;;;;;;;;;;;;;;AAeG;IACgB,UAAU,GAAG,MAAM,CAAgB,IAAI;mFAAC;IAEnD,UAAU,GAAsB,IAAI;AAC5C;;;;AAIG;IACK,QAAQ,GAAwB,IAAI;AAC5C;;;;AAIG;IACK,cAAc,GAAuB,IAAI;AACjD;;;;;;;;;;;;;AAaG;AACc,IAAA,YAAY,GAAG,IAAI,GAAG,EAA6C;IAC5E,UAAU,GAAyC,IAAI;;IAGvD,UAAU,GAAyC,IAAI;IACvD,MAAM,GAAG,CAAC;IACV,MAAM,GAAG,CAAC;IACV,UAAU,GAAG,CAAC;IACd,UAAU,GAAG,CAAC;IACd,eAAe,GAAG,CAAC;IACnB,iBAAiB,GAAwB,IAAI;AAErD;;;;;;;;AAQG;AACK,IAAA,OAAO,UAAU,GAAyB,IAAI;;AAGtD,IAAA,OAAO,cAAc,GAAA;AACnB,QAAA,aAAa,CAAC,UAAU,EAAE,gBAAgB,EAAE;IAC9C;;AAGA,IAAA,OAAO,kBAAkB,GAAA;AACvB,QAAA,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE;IAC3C;AAEA;;;;;AAKG;AACH,IAAA,OAAO,WAAW,GAAA;AAChB,QAAA,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE;IAC1C;AAEA;;;;;;AAMG;AACK,IAAA,OAAgB,aAAa,GAAG,GAAG;AAC3C;;;;;AAKG;AACK,IAAA,OAAgB,WAAW,GAAG,GAAG;;AAGjC,IAAA,OAAgB,aAAa,GAAG,GAAG;;AAEnC,IAAA,OAAgB,oBAAoB,GAAG,EAAE;AAEjD,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;YAC7B,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,YAAY,EAAE;;;YAGnB,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE;gBAC5C,YAAY,CAAC,KAAK,CAAC;gBACnB,GAAG,CAAC,OAAO,EAAE;YACf;AACA,YAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AAC3B,QAAA,CAAC,CAAC;IACJ;;AAGU,IAAA,aAAa,CAAC,KAAiB,EAAA;QACvC,KAAK,CAAC,cAAc,EAAE;;;;QAItB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,GAAG,GAAG;YAAE;QAC7C,KAAK,CAAC,eAAe,EAAE;;;;;QAKvB,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5C;AAEA;;;;;;AAMG;AACO,IAAA,aAAa,CAAC,KAAmB,EAAA;AACzC,QAAA,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE;AACnF,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO;AAC3B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO;AAC3B,QAAA,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK;AAC7B,QAAA,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK;AAC7B,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAK;AAChC,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;YACtB,IAAI,CAAC,WAAW,EAAE;AAClB,YAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,YAAY,EAAE;YACnB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC;AACpD,QAAA,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAY,IAAI,CAAC,WAAW,EAAE;AAC/C,QAAA,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/E,IAAI,CAAC,iBAAiB,GAAG,MAAY,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1G;;AAGU,IAAA,aAAa,CAAC,KAAmB,EAAA;AACzC,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE;QAC9B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,oBAAoB,EAAE;YAC7G,IAAI,CAAC,WAAW,EAAE;QACpB;IACF;;IAGU,WAAW,GAAA;QACnB,IAAI,CAAC,WAAW,EAAE;IACpB;IAEQ,WAAW,GAAA;AACjB,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;AAC5B,YAAA,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAC7B,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;QACxB;AACA,QAAA,IAAI,CAAC,iBAAiB,IAAI;AAC1B,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;IAC/B;;IAGA,KAAK,GAAA;QACH,IAAI,CAAC,YAAY,EAAE;IACrB;;IAIQ,WAAW,CAAC,CAAS,EAAE,CAAS,EAAA;;;;;AAKtC,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,QAAA,IAAI,CAAC,cAAc;AACjB,YAAA,MAAM,YAAY,WAAW,IAAI,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,0BAA0B;AACrG,kBAAE;kBACA,IAAI;;;;;;;;;;AAWV,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC3B,aAAA,QAAQ;AACR,aAAA,mBAAmB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;;;aAGvC,sBAAsB,CAAC,KAAK;aAC5B,QAAQ,CAAC,IAAI;aACb,aAAa,CAAC,iBAAiB,CAAC;QAEnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACpC,gBAAgB;;;AAGhB,YAAA,cAAc,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;YAC5C,UAAU,EAAE,CAAC,yBAAyB,CAAC;AACxC,SAAA,CAAC;AAEF,QAAA,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC;AACrE,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;;;;;AAK9B,QAAA,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE;AAEhC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc;;;;;;QAO3C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAc,kBAAkB,CAAC;QAClE,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,iBAAiB,CAAC;YACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC;;;;;;;;;QAUA,MAAM,IAAI,GAAG,MAAY,gBAAgB,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;AAiB/D,QAAA,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;;;;AAK1B,QAAA,qBAAqB,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;;;;;;AAOhF,QAAA,MAAM,WAAW,GAAG,CAAC,KAAiB,KAAU;AAC9C,YAAA,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa;;;;;YAKnC,IAAI,OAAO,YAAY,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC;gBAAE;YAC/E,IAAI,CAAC,aAAa,EAAE;AACtB,QAAA,CAAC;QACD,MAAM,WAAW,GAAG,MAAY,IAAI,CAAC,gBAAgB,EAAE;AACvD,QAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,WAAW,CAAC;AAChD,QAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,WAAW,CAAC;AAChD,QAAA,aAAa,CAAC,UAAU,GAAG,IAAI;QAC/B,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,MAAK;AAC3C,YAAA,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC;AACnD,YAAA,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC;AACrD,QAAA,CAAC,CAAC;;;;;AAKF,QAAA,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;;;;QAK3E,MAAM,QAAQ,GAAG,MAAY,IAAI,CAAC,YAAY,EAAE;AAChD,QAAA,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,MAAK;AAC3C,YAAA,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC/D,YAAA,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAChD,QAAA,CAAC,CAAC;;;;;;;;;;AAWF,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;AAClC,QAAA,IAAI,CAAC;AACF,aAAA,oBAAoB,CAAC,IAAI,CAAC,UAAU;AACpC,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,QAAQ,GAAG,GAAG;gBAAE;YACxC,IAAI,CAAC,YAAY,EAAE;AACrB,QAAA,CAAC,CAAC;AAEJ,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;AAClB,aAAA,aAAa;AACb,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,KAAK,IAAG;AACjB,YAAA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;gBAC1B,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,YAAY,EAAE;gBACnB;YACF;AACA,YAAA,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE;;;;gBAIvB,IAAI,CAAC,YAAY,EAAE;gBACnB;YACF;;;;YAIA,IAAI,KAAK,CAAC,gBAAgB;gBAAE;AAC5B,YAAA,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC;AACrC,QAAA,CAAC,CAAC;IACN;IAEQ,YAAY,GAAA;QAClB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE;;;AAGtB,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,QAAA,MAAM,cAAc,GAAG,MAAM,YAAY,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,KAAK,IAAI;AACvG,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc;AACrC,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;QAC1B,IAAI,CAAC,gBAAgB,EAAE;;;;AAIvB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;AACzB,QAAA,IAAI,aAAa,CAAC,UAAU,KAAK,IAAI;AAAE,YAAA,aAAa,CAAC,UAAU,GAAG,IAAI;;;;;AAKtE,QAAA,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC;AACnC,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;AAC3B,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc;;;;AAI/B,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,+BAA+B,CAAC;;;;;;;;;AAStD,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM;;;;;;;;;AASjC,QAAA,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE;AAC5B,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACpB,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAK;AAC5B,YAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/B,GAAG,CAAC,OAAO,EAAE;AACf,QAAA,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC;QAC/B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC;;;AAGjC,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;;;;;;;AAOtB,QAAA,IAAI,cAAc;AAAE,YAAA,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;IACnD;AAEA;;;;;;;;;;;;;;;;AAgBG;AACK,IAAA,aAAa,CAAC,QAA4B,EAAA;QAChD,MAAM,MAAM,GACV,QAAQ,EAAE,WAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,0BAA0B,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa;QAC7G,MAAM,CAAC,KAAK,EAAE;;;;;AAKd,QAAA,IAAI,QAAQ,CAAC,aAAa,KAAK,MAAM;YAAE;AACvC,QAAA,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;QACrC,MAAM,CAAC,KAAK,EAAE;QACd,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3F;IAEQ,gBAAgB,GAAA;AACtB,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;AAC5B,YAAA,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAC7B,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;QACxB;IACF;IAEQ,aAAa,GAAA;QACnB,IAAI,CAAC,gBAAgB,EAAE;AACvB,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAK;AAChC,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;YACtB,IAAI,CAAC,YAAY,EAAE;AACrB,QAAA,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC;IAC/B;uGA/dW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,WAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,EAAA,UAAA,EAAA,EAAA,oBAAA,EAAA,cAAA,EAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAZzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,sBAAsB;AAC7B,wBAAA,sBAAsB,EAAE,cAAc;AACtC,wBAAA,eAAe,EAAE,uBAAuB;AACxC,wBAAA,eAAe,EAAE,uBAAuB;AACxC,wBAAA,eAAe,EAAE,uBAAuB;AACxC,wBAAA,aAAa,EAAE,eAAe;AAC9B,wBAAA,iBAAiB,EAAE,eAAe;AACnC,qBAAA;AACF,iBAAA;;;AC/FD;;;;;AAKG;AAIH;;;;;;;;;;;;;AAaG;MAYU,kBAAkB,CAAA;;AAEpB,IAAA,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,WAAW;mFAAC;uGAF1C,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAEY,WAAW,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAX1C,0FAA0F,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FASzF,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAX9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,QAAQ,EAAE,0FAA0F;AACpG,oBAAA,QAAQ,EAAE,eAAe;oBACzB,aAAa,EAAE,iBAAiB,CAAC,IAAI;;;;;AAKrC,oBAAA,IAAI,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE;AACtC,iBAAA;4FAG0C,WAAW,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACpCtD;;;;;AAKG;AAIH;;;;;;;;;;;;;;AAcG;MAWU,oBAAoB,CAAA;uGAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,+MARrB,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAQD,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAVhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,yBAAyB;AACnC,oBAAA,QAAQ,EAAE,EAAE;oBACZ,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,yBAAyB;AAChC,wBAAA,IAAI,EAAE,WAAW;AACjB,wBAAA,kBAAkB,EAAE,YAAY;AACjC,qBAAA;AACF,iBAAA;;;ACjCD;;AAEG;;;;"}
|
|
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 // `wrContextMenuTrigger`, not `wrContextMenu`: the PANEL component already\n // exports itself under the plain name, which is what `<wr-context-menu #menu>`\n // hands to `[wrContextMenu]=\"menu\"`. Two directives may share an `exportAs`\n // without a compile error — the reference resolves per element — so the clash\n // would only surface as the wrong instance on an element carrying both.\n exportAs: 'wrContextMenuTrigger',\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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"}
|