ng-primitives 0.112.0 → 0.112.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -75,6 +75,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
|
|
|
75
75
|
}], ctorParameters: () => [] });
|
|
76
76
|
function setupExitAnimation({ element, immediate, }) {
|
|
77
77
|
let state = 'enter';
|
|
78
|
+
let exitResolve = null;
|
|
78
79
|
function setState(newState) {
|
|
79
80
|
state = newState;
|
|
80
81
|
// remove all current animation state attributes
|
|
@@ -98,13 +99,18 @@ function setupExitAnimation({ element, immediate, }) {
|
|
|
98
99
|
return {
|
|
99
100
|
exit: () => {
|
|
100
101
|
return new Promise((resolve, reject) => {
|
|
102
|
+
exitResolve = resolve;
|
|
101
103
|
setState('exit');
|
|
102
104
|
const animations = element.getAnimations();
|
|
103
105
|
// Wait for the exit animations to finish
|
|
104
106
|
if (animations.length > 0) {
|
|
105
107
|
Promise.all(animations.map(anim => anim.finished))
|
|
106
|
-
.then(() =>
|
|
108
|
+
.then(() => {
|
|
109
|
+
exitResolve = null;
|
|
110
|
+
resolve();
|
|
111
|
+
})
|
|
107
112
|
.catch(err => {
|
|
113
|
+
exitResolve = null;
|
|
108
114
|
// AbortError is expected when element is removed during animation
|
|
109
115
|
// e.g. when the user navigates away to another page
|
|
110
116
|
// Note: Animation.finished can reject with DOMException which may not pass instanceof Error
|
|
@@ -117,10 +123,27 @@ function setupExitAnimation({ element, immediate, }) {
|
|
|
117
123
|
});
|
|
118
124
|
}
|
|
119
125
|
else {
|
|
126
|
+
exitResolve = null;
|
|
120
127
|
resolve();
|
|
121
128
|
}
|
|
122
129
|
});
|
|
123
130
|
},
|
|
131
|
+
cancel: () => {
|
|
132
|
+
if (state === 'exit') {
|
|
133
|
+
// Cancel any running animations
|
|
134
|
+
const animations = element.getAnimations();
|
|
135
|
+
for (const anim of animations) {
|
|
136
|
+
anim.cancel();
|
|
137
|
+
}
|
|
138
|
+
// Transition back to enter state
|
|
139
|
+
setState('enter');
|
|
140
|
+
// Resolve the pending exit promise so detach() completes
|
|
141
|
+
if (exitResolve) {
|
|
142
|
+
exitResolve();
|
|
143
|
+
exitResolve = null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
124
147
|
};
|
|
125
148
|
}
|
|
126
149
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-primitives-internal.mjs","sources":["../../../../packages/ng-primitives/internal/src/utilities/element-ref.ts","../../../../packages/ng-primitives/internal/src/exit-animation/exit-animation-manager.ts","../../../../packages/ng-primitives/internal/src/exit-animation/exit-animation.ts","../../../../packages/ng-primitives/internal/src/signals/explicit-effect.ts","../../../../packages/ng-primitives/internal/src/style-injector/style-injector.ts","../../../../packages/ng-primitives/internal/src/utilities/resize.ts","../../../../packages/ng-primitives/internal/src/utilities/dom-removal.ts","../../../../packages/ng-primitives/internal/src/utilities/dom-sort.ts","../../../../packages/ng-primitives/internal/src/utilities/mutation-observer.ts","../../../../packages/ng-primitives/internal/src/utilities/overflow.ts","../../../../packages/ng-primitives/internal/src/utilities/scrolling.ts","../../../../packages/ng-primitives/internal/src/ng-primitives-internal.ts"],"sourcesContent":["import { ElementRef, inject } from '@angular/core';\n\n/**\n * A simple utility function to inject an element reference with less boilerplate.\n * @returns The element reference.\n */\nexport function injectElementRef<T extends HTMLElement>(): ElementRef<T> {\n return inject(ElementRef);\n}\n","import { ClassProvider, inject, Injectable } from '@angular/core';\nimport type { NgpExitAnimation } from './exit-animation';\n\n@Injectable()\nexport class NgpExitAnimationManager {\n /** Store the instances of the exit animation directive. */\n private readonly instances: NgpExitAnimation[] = [];\n\n /** Add an instance to the manager. */\n add(instance: NgpExitAnimation): void {\n this.instances.push(instance);\n }\n\n /** Remove an instance from the manager. */\n remove(instance: NgpExitAnimation): void {\n const index = this.instances.indexOf(instance);\n if (index !== -1) {\n this.instances.splice(index, 1);\n }\n }\n\n /** Exit all instances. */\n async exit(): Promise<void> {\n await Promise.all(this.instances.map(instance => instance.exit()));\n }\n}\n\nexport function provideExitAnimationManager(): ClassProvider {\n return { provide: NgpExitAnimationManager, useClass: NgpExitAnimationManager };\n}\n\nexport function injectExitAnimationManager(): NgpExitAnimationManager {\n return inject(NgpExitAnimationManager);\n}\n","import { Directive, OnDestroy } from '@angular/core';\nimport { injectElementRef } from '../utilities/element-ref';\nimport { injectExitAnimationManager } from './exit-animation-manager';\n\n@Directive({\n selector: '[ngpExitAnimation]',\n exportAs: 'ngpExitAnimation',\n})\nexport class NgpExitAnimation implements OnDestroy {\n /** The animation manager. */\n private readonly animationManager = injectExitAnimationManager();\n /** Access the element reference. */\n protected readonly elementRef = injectElementRef();\n\n /** Exist animation reference. */\n protected readonly ref = setupExitAnimation({ element: this.elementRef.nativeElement });\n\n constructor() {\n this.animationManager.add(this);\n }\n\n ngOnDestroy(): void {\n this.animationManager.remove(this);\n }\n\n /** Mark the element as exiting. */\n async exit(): Promise<void> {\n await this.ref.exit();\n }\n}\n\ninterface NgpExitAnimationOptions {\n /** The element to animate. */\n element: HTMLElement;\n /** If true, skip requestAnimationFrame delay and set enter state immediately. */\n immediate?: boolean;\n}\n\nexport interface NgpExitAnimationRef {\n /** Mark the element as exiting and wait for the animation to finish. */\n exit: () => Promise<void>;\n}\n\nexport function setupExitAnimation({\n element,\n immediate,\n}: NgpExitAnimationOptions): NgpExitAnimationRef {\n let state: 'enter' | 'exit' = 'enter';\n\n function setState(newState: 'enter' | 'exit') {\n state = newState;\n\n // remove all current animation state attributes\n element.removeAttribute('data-enter');\n element.removeAttribute('data-exit');\n\n // add the new animation state attribute\n if (state === 'enter') {\n element.setAttribute('data-enter', '');\n } else if (state === 'exit') {\n element.setAttribute('data-exit', '');\n }\n }\n\n // Set the initial state to 'enter' - immediately if instant, otherwise next frame\n if (immediate) {\n setState('enter');\n } else {\n requestAnimationFrame(() => setState('enter'));\n }\n\n return {\n exit: () => {\n return new Promise((resolve, reject) => {\n setState('exit');\n\n const animations = element.getAnimations();\n\n // Wait for the exit animations to finish\n if (animations.length > 0) {\n Promise.all(animations.map(anim => anim.finished))\n .then(() => resolve())\n .catch(err => {\n // AbortError is expected when element is removed during animation\n // e.g. when the user navigates away to another page\n // Note: Animation.finished can reject with DOMException which may not pass instanceof Error\n if ((err as { name?: string })?.name === 'AbortError') {\n resolve();\n } else {\n reject(err);\n }\n });\n } else {\n resolve();\n }\n });\n },\n };\n}\n","/**\n * This implementation is heavily inspired by the great work on ngextension!\n * https://github.com/ngxtension/ngxtension-platform/blob/main/libs/ngxtension/explicit-effect/src/explicit-effect.ts\n */\nimport {\n CreateEffectOptions,\n EffectCleanupRegisterFn,\n EffectRef,\n effect,\n untracked,\n} from '@angular/core';\n\n/**\n * We want to have the Tuple in order to use the types in the function signature\n */\ntype ExplicitEffectValues<T> = {\n [K in keyof T]: () => T[K];\n};\n\n/**\n * This explicit effect function will take the dependencies and the function to run when the dependencies change.\n * @param deps - The dependencies that the effect will run on\n * @param fn - The function to run when the dependencies change\n * @param options - The options for the effect with the addition of defer (it allows the computation to run on first change, not immediately)\n */\nexport function explicitEffect<Input extends readonly unknown[], Params = Input>(\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateEffectOptions,\n): EffectRef {\n return effect(onCleanup => {\n const depValues = deps.map(s => s());\n untracked(() => fn(depValues as Params, onCleanup));\n }, options);\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { CSP_NONCE, inject, Injectable, PLATFORM_ID } from '@angular/core';\n\n/**\n * A utility service for injecting styles into the document.\n * Angular doesn't allow directives to specify styles, only components.\n * As we ship directives, occasionally we need to associate styles with them.\n * This service allows us to programmatically inject styles into the document.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class StyleInjector {\n /**\n * Access the CSP nonce\n */\n private readonly cspNonce = inject(CSP_NONCE, { optional: true });\n\n /**\n * Access the document.\n */\n private readonly document = inject(DOCUMENT);\n\n /**\n * Detect the platform.\n */\n private readonly platformId = inject(PLATFORM_ID);\n\n /**\n * Store the map of style elements with their unique identifiers.\n */\n private readonly styleElements = new Map<string, HTMLStyleElement>();\n\n constructor() {\n if (isPlatformBrowser(this.platformId)) {\n this.collectServerStyles();\n }\n }\n\n /**\n * Inject a style into the document.\n * @param id The unique identifier for the style.\n * @param style The style to inject.\n */\n add(id: string, style: string): void {\n if (this.styleElements.has(id)) {\n return;\n }\n\n const styleElement = this.document.createElement('style');\n styleElement.setAttribute('data-ngp-style', id);\n styleElement.textContent = style;\n\n // If a CSP nonce is provided, set it on the style element\n if (this.cspNonce) {\n styleElement.setAttribute('nonce', this.cspNonce);\n }\n\n this.document.head.appendChild(styleElement);\n this.styleElements.set(id, styleElement);\n }\n\n /**\n * Remove a style from the document.\n * @param id The unique identifier for the style.\n */\n remove(id: string): void {\n const styleElement = this.styleElements.get(id);\n\n if (styleElement) {\n this.document.head.removeChild(styleElement);\n this.styleElements.delete(id);\n }\n }\n\n /**\n * Collect any styles that were rendered by the server.\n */\n private collectServerStyles(): void {\n const styleElements = this.document.querySelectorAll<HTMLStyleElement>('style[data-ngp-style]');\n\n styleElements.forEach(styleElement => {\n const id = styleElement.getAttribute('data-ngp-style');\n\n if (id) {\n this.styleElements.set(id, styleElement);\n }\n });\n }\n}\n\nexport function injectStyleInjector(): StyleInjector {\n return inject(StyleInjector);\n}\n","import { isPlatformServer } from '@angular/common';\nimport {\n DestroyRef,\n effect,\n inject,\n Injector,\n PLATFORM_ID,\n signal,\n Signal,\n untracked,\n} from '@angular/core';\nimport { isUndefined, safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { Observable, Subscription } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { explicitEffect } from '../signals/explicit-effect';\nimport { injectElementRef } from './element-ref';\n\ninterface NgpResizeObserverOptions {\n /**\n * Whether to listen for events.\n */\n disabled?: Signal<boolean>;\n\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n}\n\n/**\n * A simple helper function to create a resize observer as an RxJS Observable.\n * @param element The element to observe for resize events.\n * @returns The resize event as an Observable.\n */\nexport function fromResizeEvent(\n element: HTMLElement,\n { disabled = signal(false), injector }: NgpResizeObserverOptions = {},\n): Observable<Dimensions> {\n const platformId = injector?.get(PLATFORM_ID) ?? inject(PLATFORM_ID);\n\n return new Observable(observable => {\n // ResizeObserver may not be available in all environments, so check for its existence\n if (isPlatformServer(platformId) || isUndefined(window?.ResizeObserver)) {\n // ResizeObserver is not available (SSR or unsupported browser)\n // Complete the observable without emitting any values\n observable.complete();\n return;\n }\n\n let observer: ResizeObserver | null = null;\n\n function setupOrTeardownObserver() {\n if (disabled()) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n return;\n }\n\n if (!observer) {\n observer = new ResizeObserver(entries => {\n // if there are no entries, ignore the event\n if (!entries.length) {\n return;\n }\n\n // otherwise, take the first entry and emit the dimensions\n const entry = entries[0];\n\n let width: number, height: number;\n\n if ('borderBoxSize' in entry) {\n const borderSizeEntry = entry['borderBoxSize'];\n // this may be different across browsers so normalize it\n const borderSize = Array.isArray(borderSizeEntry)\n ? borderSizeEntry[0]\n : borderSizeEntry;\n\n width = borderSize['inlineSize'];\n height = borderSize['blockSize'];\n } else {\n // fallback for browsers that don't support borderBoxSize\n width = element.offsetWidth;\n height = element.offsetHeight;\n }\n\n // For inline elements, ResizeObserver may report 0,0 dimensions\n // Use getBoundingClientRect as fallback for inline elements with zero dimensions\n if ((width === 0 || height === 0) && getComputedStyle(element).display === 'inline') {\n const rect = element.getBoundingClientRect();\n width = rect.width;\n height = rect.height;\n }\n\n observable.next({ width, height });\n });\n\n observer.observe(element);\n }\n }\n\n setupOrTeardownObserver();\n\n explicitEffect([disabled], () => setupOrTeardownObserver(), { injector });\n\n return () => observer?.disconnect();\n });\n}\n\n/**\n * A utility function to observe any element for resize events and return the dimensions as a signal.\n */\nexport function observeResize(elementFn: () => HTMLElement | undefined): Signal<Dimensions> {\n const dimensions = signal<Dimensions>({ width: 0, height: 0 });\n const injector = inject(Injector);\n const destroyRef = inject(DestroyRef);\n\n // store the subscription to the resize event\n let subscription: Subscription | null = null;\n\n effect(() => {\n const targetElement = elementFn();\n\n untracked(() => {\n if (!targetElement) {\n return;\n }\n\n // if we already have a subscription, unsubscribe from it\n subscription?.unsubscribe();\n\n // create a new subscription to the resize event\n subscription = fromResizeEvent(targetElement, { injector })\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(event => dimensions.set({ width: event.width, height: event.height }));\n });\n });\n\n return dimensions;\n}\n\nexport interface Dimensions {\n width: number;\n height: number;\n}\n\n/**\n * A simple utility to get the dimensions of an element as a signal.\n */\nexport function injectDimensions(): Signal<Dimensions> {\n const elementRef = injectElementRef<HTMLElement>();\n const destroyRef = inject(DestroyRef);\n const dimensions = signal<Dimensions>({ width: 0, height: 0 });\n\n fromResizeEvent(elementRef.nativeElement)\n .pipe(\n safeTakeUntilDestroyed(destroyRef),\n map(({ width, height }) => ({ width, height })),\n )\n .subscribe(event => dimensions.set(event));\n\n return dimensions;\n}\n","import { isPlatformServer } from '@angular/common';\nimport { inject, PLATFORM_ID } from '@angular/core';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { fromResizeEvent } from './resize';\n\n/**\n * Whenever an element is removed from the DOM, we call the callback.\n * @param element The element to watch for removal.\n * @param callback The callback to call when the element is removed.\n */\nexport function onDomRemoval(element: HTMLElement, callback: () => void): void {\n const platform = inject(PLATFORM_ID);\n\n // Dont run this on the server\n if (isPlatformServer(platform)) {\n return;\n }\n\n // This is a bit of a hack, but it works. If the element dimensions become zero,\n // it's likely that the element has been removed from the DOM.\n fromResizeEvent(element)\n .pipe(safeTakeUntilDestroyed())\n .subscribe(dimensions => {\n // we check the dimensions first to short-circuit the check as it's faster\n if (dimensions.width === 0 && dimensions.height === 0 && !document.body.contains(element)) {\n callback();\n }\n });\n}\n","/**\n * This function sorts DOM elements based on their position in the document.\n * However items can also explitly define their index in which case it will be used\n * to sort the elements first. This allows for both natural DOM order sorting as well\n * as custom order for cases like virtual scrolling where items might be rendered\n * out of order.\n */\nexport function domSort<T>(\n items: T[],\n getElement: (item: T) => HTMLElement,\n getIndex?: (item: T) => number | undefined,\n): T[] {\n return items.slice().sort((a, b) => {\n const indexA = getIndex?.(a);\n const indexB = getIndex?.(b);\n\n if (indexA !== undefined && indexB !== undefined) {\n return indexA - indexB;\n }\n\n if (indexA !== undefined) {\n return -1;\n }\n\n if (indexB !== undefined) {\n return 1;\n }\n\n const elementA = getElement(a);\n const elementB = getElement(b);\n\n return elementA.compareDocumentPosition(elementB) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n });\n}\n","import { Injector, Signal, signal } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { explicitEffect } from '../signals/explicit-effect';\n\ninterface NgpMutationObserverOptions {\n /**\n * Whether to listen for events.\n */\n disabled?: Signal<boolean>;\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n /**\n * Whether the childList should be observed.\n */\n childList?: boolean;\n /**\n * Whether the subtree should be observed.\n */\n subtree?: boolean;\n /**\n * Whether the attributes should be observed.\n */\n attributes?: boolean;\n /**\n * Whether the characterData should be observed.\n */\n characterData?: boolean;\n /**\n * Whether the attributeFilter should be observed.\n */\n attributeFilter?: string[];\n}\n\n/**\n * This function sets up a mutation observer to listen for changes in the DOM.\n * It will stop listening when the `disabled` signal is true, and re-enable when it is false.\n * @param options - Options for the mutation observer\n */\nexport function fromMutationObserver(\n element: HTMLElement,\n {\n childList,\n subtree,\n attributes,\n characterData,\n disabled = signal(false),\n injector,\n }: NgpMutationObserverOptions = {},\n): Observable<MutationRecord[]> {\n return new Observable<MutationRecord[]>(observable => {\n let observer: MutationObserver | null = null;\n\n function setupOrTeardownObserver() {\n if (disabled()) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n return;\n }\n\n observer = new MutationObserver(mutations => observable.next(mutations));\n observer.observe(element, { childList, subtree, attributes, characterData });\n }\n\n setupOrTeardownObserver();\n\n // any time the disabled state changes, we need to re-evaluate the observer\n explicitEffect([disabled], () => setupOrTeardownObserver(), { injector });\n\n return () => observer?.disconnect();\n });\n}\n","import { DestroyRef, inject, Injector, Signal, signal } from '@angular/core';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { merge } from 'rxjs';\nimport { fromMutationObserver } from './mutation-observer';\nimport { fromResizeEvent } from './resize';\n\ninterface NgpOverflowListenerOptions {\n /**\n * Whether to listen for overflow changes.\n */\n disabled?: Signal<boolean>;\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n}\n\nexport function setupOverflowListener(\n element: HTMLElement,\n { disabled = signal(false), injector }: NgpOverflowListenerOptions,\n): Signal<boolean> {\n const hasOverflow = signal<boolean>(false);\n const destroyRef = injector?.get(DestroyRef) ?? inject(DestroyRef);\n\n // Merge both observables and update hasOverflow on any event\n\n merge(\n fromResizeEvent(element, { disabled, injector }),\n fromMutationObserver(element, { disabled, injector, characterData: true }),\n )\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(() =>\n hasOverflow.set(\n element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight,\n ),\n );\n\n return hasOverflow;\n}\n","function getScrollableAncestor(element: HTMLElement): HTMLElement | null {\n let parent = element.parentElement;\n while (parent) {\n const style = window.getComputedStyle(parent);\n if (/(auto|scroll)/.test(style.overflowY) || /(auto|scroll)/.test(style.overflowX)) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n}\n\nexport function scrollIntoViewIfNeeded(element: HTMLElement): void {\n const scrollableAncestor = getScrollableAncestor(element);\n if (!scrollableAncestor) return;\n\n const parentRect = scrollableAncestor.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n if (elementRect.top < parentRect.top) {\n scrollableAncestor.scrollTop -= parentRect.top - elementRect.top;\n } else if (elementRect.bottom > parentRect.bottom) {\n scrollableAncestor.scrollTop += elementRect.bottom - parentRect.bottom;\n }\n\n if (elementRect.left < parentRect.left) {\n scrollableAncestor.scrollLeft -= parentRect.left - elementRect.left;\n } else if (elementRect.right > parentRect.right) {\n scrollableAncestor.scrollLeft += elementRect.right - parentRect.right;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-primitives-internal.mjs","sources":["../../../../packages/ng-primitives/internal/src/utilities/element-ref.ts","../../../../packages/ng-primitives/internal/src/exit-animation/exit-animation-manager.ts","../../../../packages/ng-primitives/internal/src/exit-animation/exit-animation.ts","../../../../packages/ng-primitives/internal/src/signals/explicit-effect.ts","../../../../packages/ng-primitives/internal/src/style-injector/style-injector.ts","../../../../packages/ng-primitives/internal/src/utilities/resize.ts","../../../../packages/ng-primitives/internal/src/utilities/dom-removal.ts","../../../../packages/ng-primitives/internal/src/utilities/dom-sort.ts","../../../../packages/ng-primitives/internal/src/utilities/mutation-observer.ts","../../../../packages/ng-primitives/internal/src/utilities/overflow.ts","../../../../packages/ng-primitives/internal/src/utilities/scrolling.ts","../../../../packages/ng-primitives/internal/src/ng-primitives-internal.ts"],"sourcesContent":["import { ElementRef, inject } from '@angular/core';\n\n/**\n * A simple utility function to inject an element reference with less boilerplate.\n * @returns The element reference.\n */\nexport function injectElementRef<T extends HTMLElement>(): ElementRef<T> {\n return inject(ElementRef);\n}\n","import { ClassProvider, inject, Injectable } from '@angular/core';\nimport type { NgpExitAnimation } from './exit-animation';\n\n@Injectable()\nexport class NgpExitAnimationManager {\n /** Store the instances of the exit animation directive. */\n private readonly instances: NgpExitAnimation[] = [];\n\n /** Add an instance to the manager. */\n add(instance: NgpExitAnimation): void {\n this.instances.push(instance);\n }\n\n /** Remove an instance from the manager. */\n remove(instance: NgpExitAnimation): void {\n const index = this.instances.indexOf(instance);\n if (index !== -1) {\n this.instances.splice(index, 1);\n }\n }\n\n /** Exit all instances. */\n async exit(): Promise<void> {\n await Promise.all(this.instances.map(instance => instance.exit()));\n }\n}\n\nexport function provideExitAnimationManager(): ClassProvider {\n return { provide: NgpExitAnimationManager, useClass: NgpExitAnimationManager };\n}\n\nexport function injectExitAnimationManager(): NgpExitAnimationManager {\n return inject(NgpExitAnimationManager);\n}\n","import { Directive, OnDestroy } from '@angular/core';\nimport { injectElementRef } from '../utilities/element-ref';\nimport { injectExitAnimationManager } from './exit-animation-manager';\n\n@Directive({\n selector: '[ngpExitAnimation]',\n exportAs: 'ngpExitAnimation',\n})\nexport class NgpExitAnimation implements OnDestroy {\n /** The animation manager. */\n private readonly animationManager = injectExitAnimationManager();\n /** Access the element reference. */\n protected readonly elementRef = injectElementRef();\n\n /** Exist animation reference. */\n protected readonly ref = setupExitAnimation({ element: this.elementRef.nativeElement });\n\n constructor() {\n this.animationManager.add(this);\n }\n\n ngOnDestroy(): void {\n this.animationManager.remove(this);\n }\n\n /** Mark the element as exiting. */\n async exit(): Promise<void> {\n await this.ref.exit();\n }\n}\n\ninterface NgpExitAnimationOptions {\n /** The element to animate. */\n element: HTMLElement;\n /** If true, skip requestAnimationFrame delay and set enter state immediately. */\n immediate?: boolean;\n}\n\nexport interface NgpExitAnimationRef {\n /** Mark the element as exiting and wait for the animation to finish. */\n exit: () => Promise<void>;\n /** Cancel an in-progress exit animation and transition back to enter state. */\n cancel: () => void;\n}\n\nexport function setupExitAnimation({\n element,\n immediate,\n}: NgpExitAnimationOptions): NgpExitAnimationRef {\n let state: 'enter' | 'exit' = 'enter';\n let exitResolve: (() => void) | null = null;\n\n function setState(newState: 'enter' | 'exit') {\n state = newState;\n\n // remove all current animation state attributes\n element.removeAttribute('data-enter');\n element.removeAttribute('data-exit');\n\n // add the new animation state attribute\n if (state === 'enter') {\n element.setAttribute('data-enter', '');\n } else if (state === 'exit') {\n element.setAttribute('data-exit', '');\n }\n }\n\n // Set the initial state to 'enter' - immediately if instant, otherwise next frame\n if (immediate) {\n setState('enter');\n } else {\n requestAnimationFrame(() => setState('enter'));\n }\n\n return {\n exit: () => {\n return new Promise((resolve, reject) => {\n exitResolve = resolve;\n setState('exit');\n\n const animations = element.getAnimations();\n\n // Wait for the exit animations to finish\n if (animations.length > 0) {\n Promise.all(animations.map(anim => anim.finished))\n .then(() => {\n exitResolve = null;\n resolve();\n })\n .catch(err => {\n exitResolve = null;\n // AbortError is expected when element is removed during animation\n // e.g. when the user navigates away to another page\n // Note: Animation.finished can reject with DOMException which may not pass instanceof Error\n if ((err as { name?: string })?.name === 'AbortError') {\n resolve();\n } else {\n reject(err);\n }\n });\n } else {\n exitResolve = null;\n resolve();\n }\n });\n },\n cancel: () => {\n if (state === 'exit') {\n // Cancel any running animations\n const animations = element.getAnimations();\n for (const anim of animations) {\n anim.cancel();\n }\n // Transition back to enter state\n setState('enter');\n // Resolve the pending exit promise so detach() completes\n if (exitResolve) {\n exitResolve();\n exitResolve = null;\n }\n }\n },\n };\n}\n","/**\n * This implementation is heavily inspired by the great work on ngextension!\n * https://github.com/ngxtension/ngxtension-platform/blob/main/libs/ngxtension/explicit-effect/src/explicit-effect.ts\n */\nimport {\n CreateEffectOptions,\n EffectCleanupRegisterFn,\n EffectRef,\n effect,\n untracked,\n} from '@angular/core';\n\n/**\n * We want to have the Tuple in order to use the types in the function signature\n */\ntype ExplicitEffectValues<T> = {\n [K in keyof T]: () => T[K];\n};\n\n/**\n * This explicit effect function will take the dependencies and the function to run when the dependencies change.\n * @param deps - The dependencies that the effect will run on\n * @param fn - The function to run when the dependencies change\n * @param options - The options for the effect with the addition of defer (it allows the computation to run on first change, not immediately)\n */\nexport function explicitEffect<Input extends readonly unknown[], Params = Input>(\n deps: readonly [...ExplicitEffectValues<Input>],\n fn: (deps: Params, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateEffectOptions,\n): EffectRef {\n return effect(onCleanup => {\n const depValues = deps.map(s => s());\n untracked(() => fn(depValues as Params, onCleanup));\n }, options);\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { CSP_NONCE, inject, Injectable, PLATFORM_ID } from '@angular/core';\n\n/**\n * A utility service for injecting styles into the document.\n * Angular doesn't allow directives to specify styles, only components.\n * As we ship directives, occasionally we need to associate styles with them.\n * This service allows us to programmatically inject styles into the document.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class StyleInjector {\n /**\n * Access the CSP nonce\n */\n private readonly cspNonce = inject(CSP_NONCE, { optional: true });\n\n /**\n * Access the document.\n */\n private readonly document = inject(DOCUMENT);\n\n /**\n * Detect the platform.\n */\n private readonly platformId = inject(PLATFORM_ID);\n\n /**\n * Store the map of style elements with their unique identifiers.\n */\n private readonly styleElements = new Map<string, HTMLStyleElement>();\n\n constructor() {\n if (isPlatformBrowser(this.platformId)) {\n this.collectServerStyles();\n }\n }\n\n /**\n * Inject a style into the document.\n * @param id The unique identifier for the style.\n * @param style The style to inject.\n */\n add(id: string, style: string): void {\n if (this.styleElements.has(id)) {\n return;\n }\n\n const styleElement = this.document.createElement('style');\n styleElement.setAttribute('data-ngp-style', id);\n styleElement.textContent = style;\n\n // If a CSP nonce is provided, set it on the style element\n if (this.cspNonce) {\n styleElement.setAttribute('nonce', this.cspNonce);\n }\n\n this.document.head.appendChild(styleElement);\n this.styleElements.set(id, styleElement);\n }\n\n /**\n * Remove a style from the document.\n * @param id The unique identifier for the style.\n */\n remove(id: string): void {\n const styleElement = this.styleElements.get(id);\n\n if (styleElement) {\n this.document.head.removeChild(styleElement);\n this.styleElements.delete(id);\n }\n }\n\n /**\n * Collect any styles that were rendered by the server.\n */\n private collectServerStyles(): void {\n const styleElements = this.document.querySelectorAll<HTMLStyleElement>('style[data-ngp-style]');\n\n styleElements.forEach(styleElement => {\n const id = styleElement.getAttribute('data-ngp-style');\n\n if (id) {\n this.styleElements.set(id, styleElement);\n }\n });\n }\n}\n\nexport function injectStyleInjector(): StyleInjector {\n return inject(StyleInjector);\n}\n","import { isPlatformServer } from '@angular/common';\nimport {\n DestroyRef,\n effect,\n inject,\n Injector,\n PLATFORM_ID,\n signal,\n Signal,\n untracked,\n} from '@angular/core';\nimport { isUndefined, safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { Observable, Subscription } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { explicitEffect } from '../signals/explicit-effect';\nimport { injectElementRef } from './element-ref';\n\ninterface NgpResizeObserverOptions {\n /**\n * Whether to listen for events.\n */\n disabled?: Signal<boolean>;\n\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n}\n\n/**\n * A simple helper function to create a resize observer as an RxJS Observable.\n * @param element The element to observe for resize events.\n * @returns The resize event as an Observable.\n */\nexport function fromResizeEvent(\n element: HTMLElement,\n { disabled = signal(false), injector }: NgpResizeObserverOptions = {},\n): Observable<Dimensions> {\n const platformId = injector?.get(PLATFORM_ID) ?? inject(PLATFORM_ID);\n\n return new Observable(observable => {\n // ResizeObserver may not be available in all environments, so check for its existence\n if (isPlatformServer(platformId) || isUndefined(window?.ResizeObserver)) {\n // ResizeObserver is not available (SSR or unsupported browser)\n // Complete the observable without emitting any values\n observable.complete();\n return;\n }\n\n let observer: ResizeObserver | null = null;\n\n function setupOrTeardownObserver() {\n if (disabled()) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n return;\n }\n\n if (!observer) {\n observer = new ResizeObserver(entries => {\n // if there are no entries, ignore the event\n if (!entries.length) {\n return;\n }\n\n // otherwise, take the first entry and emit the dimensions\n const entry = entries[0];\n\n let width: number, height: number;\n\n if ('borderBoxSize' in entry) {\n const borderSizeEntry = entry['borderBoxSize'];\n // this may be different across browsers so normalize it\n const borderSize = Array.isArray(borderSizeEntry)\n ? borderSizeEntry[0]\n : borderSizeEntry;\n\n width = borderSize['inlineSize'];\n height = borderSize['blockSize'];\n } else {\n // fallback for browsers that don't support borderBoxSize\n width = element.offsetWidth;\n height = element.offsetHeight;\n }\n\n // For inline elements, ResizeObserver may report 0,0 dimensions\n // Use getBoundingClientRect as fallback for inline elements with zero dimensions\n if ((width === 0 || height === 0) && getComputedStyle(element).display === 'inline') {\n const rect = element.getBoundingClientRect();\n width = rect.width;\n height = rect.height;\n }\n\n observable.next({ width, height });\n });\n\n observer.observe(element);\n }\n }\n\n setupOrTeardownObserver();\n\n explicitEffect([disabled], () => setupOrTeardownObserver(), { injector });\n\n return () => observer?.disconnect();\n });\n}\n\n/**\n * A utility function to observe any element for resize events and return the dimensions as a signal.\n */\nexport function observeResize(elementFn: () => HTMLElement | undefined): Signal<Dimensions> {\n const dimensions = signal<Dimensions>({ width: 0, height: 0 });\n const injector = inject(Injector);\n const destroyRef = inject(DestroyRef);\n\n // store the subscription to the resize event\n let subscription: Subscription | null = null;\n\n effect(() => {\n const targetElement = elementFn();\n\n untracked(() => {\n if (!targetElement) {\n return;\n }\n\n // if we already have a subscription, unsubscribe from it\n subscription?.unsubscribe();\n\n // create a new subscription to the resize event\n subscription = fromResizeEvent(targetElement, { injector })\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(event => dimensions.set({ width: event.width, height: event.height }));\n });\n });\n\n return dimensions;\n}\n\nexport interface Dimensions {\n width: number;\n height: number;\n}\n\n/**\n * A simple utility to get the dimensions of an element as a signal.\n */\nexport function injectDimensions(): Signal<Dimensions> {\n const elementRef = injectElementRef<HTMLElement>();\n const destroyRef = inject(DestroyRef);\n const dimensions = signal<Dimensions>({ width: 0, height: 0 });\n\n fromResizeEvent(elementRef.nativeElement)\n .pipe(\n safeTakeUntilDestroyed(destroyRef),\n map(({ width, height }) => ({ width, height })),\n )\n .subscribe(event => dimensions.set(event));\n\n return dimensions;\n}\n","import { isPlatformServer } from '@angular/common';\nimport { inject, PLATFORM_ID } from '@angular/core';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { fromResizeEvent } from './resize';\n\n/**\n * Whenever an element is removed from the DOM, we call the callback.\n * @param element The element to watch for removal.\n * @param callback The callback to call when the element is removed.\n */\nexport function onDomRemoval(element: HTMLElement, callback: () => void): void {\n const platform = inject(PLATFORM_ID);\n\n // Dont run this on the server\n if (isPlatformServer(platform)) {\n return;\n }\n\n // This is a bit of a hack, but it works. If the element dimensions become zero,\n // it's likely that the element has been removed from the DOM.\n fromResizeEvent(element)\n .pipe(safeTakeUntilDestroyed())\n .subscribe(dimensions => {\n // we check the dimensions first to short-circuit the check as it's faster\n if (dimensions.width === 0 && dimensions.height === 0 && !document.body.contains(element)) {\n callback();\n }\n });\n}\n","/**\n * This function sorts DOM elements based on their position in the document.\n * However items can also explitly define their index in which case it will be used\n * to sort the elements first. This allows for both natural DOM order sorting as well\n * as custom order for cases like virtual scrolling where items might be rendered\n * out of order.\n */\nexport function domSort<T>(\n items: T[],\n getElement: (item: T) => HTMLElement,\n getIndex?: (item: T) => number | undefined,\n): T[] {\n return items.slice().sort((a, b) => {\n const indexA = getIndex?.(a);\n const indexB = getIndex?.(b);\n\n if (indexA !== undefined && indexB !== undefined) {\n return indexA - indexB;\n }\n\n if (indexA !== undefined) {\n return -1;\n }\n\n if (indexB !== undefined) {\n return 1;\n }\n\n const elementA = getElement(a);\n const elementB = getElement(b);\n\n return elementA.compareDocumentPosition(elementB) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n });\n}\n","import { Injector, Signal, signal } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { explicitEffect } from '../signals/explicit-effect';\n\ninterface NgpMutationObserverOptions {\n /**\n * Whether to listen for events.\n */\n disabled?: Signal<boolean>;\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n /**\n * Whether the childList should be observed.\n */\n childList?: boolean;\n /**\n * Whether the subtree should be observed.\n */\n subtree?: boolean;\n /**\n * Whether the attributes should be observed.\n */\n attributes?: boolean;\n /**\n * Whether the characterData should be observed.\n */\n characterData?: boolean;\n /**\n * Whether the attributeFilter should be observed.\n */\n attributeFilter?: string[];\n}\n\n/**\n * This function sets up a mutation observer to listen for changes in the DOM.\n * It will stop listening when the `disabled` signal is true, and re-enable when it is false.\n * @param options - Options for the mutation observer\n */\nexport function fromMutationObserver(\n element: HTMLElement,\n {\n childList,\n subtree,\n attributes,\n characterData,\n disabled = signal(false),\n injector,\n }: NgpMutationObserverOptions = {},\n): Observable<MutationRecord[]> {\n return new Observable<MutationRecord[]>(observable => {\n let observer: MutationObserver | null = null;\n\n function setupOrTeardownObserver() {\n if (disabled()) {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n return;\n }\n\n observer = new MutationObserver(mutations => observable.next(mutations));\n observer.observe(element, { childList, subtree, attributes, characterData });\n }\n\n setupOrTeardownObserver();\n\n // any time the disabled state changes, we need to re-evaluate the observer\n explicitEffect([disabled], () => setupOrTeardownObserver(), { injector });\n\n return () => observer?.disconnect();\n });\n}\n","import { DestroyRef, inject, Injector, Signal, signal } from '@angular/core';\nimport { safeTakeUntilDestroyed } from 'ng-primitives/utils';\nimport { merge } from 'rxjs';\nimport { fromMutationObserver } from './mutation-observer';\nimport { fromResizeEvent } from './resize';\n\ninterface NgpOverflowListenerOptions {\n /**\n * Whether to listen for overflow changes.\n */\n disabled?: Signal<boolean>;\n /**\n * The injector to use when called from outside of the injector context.\n */\n injector?: Injector;\n}\n\nexport function setupOverflowListener(\n element: HTMLElement,\n { disabled = signal(false), injector }: NgpOverflowListenerOptions,\n): Signal<boolean> {\n const hasOverflow = signal<boolean>(false);\n const destroyRef = injector?.get(DestroyRef) ?? inject(DestroyRef);\n\n // Merge both observables and update hasOverflow on any event\n\n merge(\n fromResizeEvent(element, { disabled, injector }),\n fromMutationObserver(element, { disabled, injector, characterData: true }),\n )\n .pipe(safeTakeUntilDestroyed(destroyRef))\n .subscribe(() =>\n hasOverflow.set(\n element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight,\n ),\n );\n\n return hasOverflow;\n}\n","function getScrollableAncestor(element: HTMLElement): HTMLElement | null {\n let parent = element.parentElement;\n while (parent) {\n const style = window.getComputedStyle(parent);\n if (/(auto|scroll)/.test(style.overflowY) || /(auto|scroll)/.test(style.overflowX)) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n}\n\nexport function scrollIntoViewIfNeeded(element: HTMLElement): void {\n const scrollableAncestor = getScrollableAncestor(element);\n if (!scrollableAncestor) return;\n\n const parentRect = scrollableAncestor.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n if (elementRect.top < parentRect.top) {\n scrollableAncestor.scrollTop -= parentRect.top - elementRect.top;\n } else if (elementRect.bottom > parentRect.bottom) {\n scrollableAncestor.scrollTop += elementRect.bottom - parentRect.bottom;\n }\n\n if (elementRect.left < parentRect.left) {\n scrollableAncestor.scrollLeft -= parentRect.left - elementRect.left;\n } else if (elementRect.right > parentRect.right) {\n scrollableAncestor.scrollLeft += elementRect.right - parentRect.right;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -184,6 +184,7 @@ class NgpComponentPortal extends NgpPortal {
|
|
|
184
184
|
super(viewContainerRef, injector);
|
|
185
185
|
this.viewRef = null;
|
|
186
186
|
this.isDestroying = false;
|
|
187
|
+
this.detachCancelled = false;
|
|
187
188
|
this.exitAnimationRef = null;
|
|
188
189
|
this.componentPortal = new ComponentPortal(component, viewContainerRef, injector);
|
|
189
190
|
}
|
|
@@ -221,6 +222,16 @@ class NgpComponentPortal extends NgpPortal {
|
|
|
221
222
|
getAttached() {
|
|
222
223
|
return !!this.viewRef && this.viewRef.location.nativeElement.isConnected;
|
|
223
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Cancel an in-progress detach operation.
|
|
227
|
+
*/
|
|
228
|
+
cancelDetach() {
|
|
229
|
+
if (this.isDestroying) {
|
|
230
|
+
this.detachCancelled = true;
|
|
231
|
+
this.exitAnimationRef?.cancel();
|
|
232
|
+
this.isDestroying = false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
224
235
|
/**
|
|
225
236
|
* Detach the portal from the DOM.
|
|
226
237
|
* @param immediate If true, skip exit animations and remove immediately
|
|
@@ -230,10 +241,16 @@ class NgpComponentPortal extends NgpPortal {
|
|
|
230
241
|
return;
|
|
231
242
|
}
|
|
232
243
|
this.isDestroying = true;
|
|
244
|
+
this.detachCancelled = false;
|
|
233
245
|
// Only wait for exit animation if not immediate
|
|
234
246
|
if (!immediate) {
|
|
235
247
|
await this.exitAnimationRef?.exit();
|
|
236
248
|
}
|
|
249
|
+
// If cancelled during exit animation, don't destroy
|
|
250
|
+
if (this.detachCancelled) {
|
|
251
|
+
this.detachCancelled = false;
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
237
254
|
if (this.viewRef) {
|
|
238
255
|
this.viewRef.destroy();
|
|
239
256
|
this.viewRef = null;
|
|
@@ -246,6 +263,7 @@ class NgpTemplatePortal extends NgpPortal {
|
|
|
246
263
|
this.viewRef = null;
|
|
247
264
|
this.exitAnimationRefs = [];
|
|
248
265
|
this.isDestroying = false;
|
|
266
|
+
this.detachCancelled = false;
|
|
249
267
|
this.templatePortal = new TemplatePortal(template, viewContainerRef, context, injector);
|
|
250
268
|
}
|
|
251
269
|
/**
|
|
@@ -286,6 +304,18 @@ class NgpTemplatePortal extends NgpPortal {
|
|
|
286
304
|
getAttached() {
|
|
287
305
|
return !!this.viewRef && this.viewRef.rootNodes.length > 0;
|
|
288
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Cancel an in-progress detach operation.
|
|
309
|
+
*/
|
|
310
|
+
cancelDetach() {
|
|
311
|
+
if (this.isDestroying) {
|
|
312
|
+
this.detachCancelled = true;
|
|
313
|
+
for (const ref of this.exitAnimationRefs) {
|
|
314
|
+
ref.cancel();
|
|
315
|
+
}
|
|
316
|
+
this.isDestroying = false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
289
319
|
/**
|
|
290
320
|
* Detach the portal from the DOM.
|
|
291
321
|
* @param immediate If true, skip exit animations and remove immediately
|
|
@@ -295,10 +325,16 @@ class NgpTemplatePortal extends NgpPortal {
|
|
|
295
325
|
return;
|
|
296
326
|
}
|
|
297
327
|
this.isDestroying = true;
|
|
328
|
+
this.detachCancelled = false;
|
|
298
329
|
// Only wait for exit animations if not immediate
|
|
299
330
|
if (!immediate) {
|
|
300
331
|
await Promise.all(this.exitAnimationRefs.map(ref => ref.exit()));
|
|
301
332
|
}
|
|
333
|
+
// If cancelled during exit animation, don't destroy
|
|
334
|
+
if (this.detachCancelled) {
|
|
335
|
+
this.detachCancelled = false;
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
302
338
|
if (this.viewRef) {
|
|
303
339
|
this.viewRef.destroy();
|
|
304
340
|
this.viewRef = null;
|
|
@@ -587,6 +623,8 @@ class NgpOverlay {
|
|
|
587
623
|
this.availableHeight = signal(null, ...(ngDevMode ? [{ debugName: "availableHeight" }] : []));
|
|
588
624
|
/** Signal tracking the final placement of the overlay */
|
|
589
625
|
this.finalPlacement = signal(undefined, ...(ngDevMode ? [{ debugName: "finalPlacement" }] : []));
|
|
626
|
+
/** Portal currently being destroyed (for cancel support during exit animations) */
|
|
627
|
+
this.destroyingPortal = null;
|
|
590
628
|
/** Signal tracking whether the overlay is open */
|
|
591
629
|
this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
592
630
|
/** A unique id for the overlay */
|
|
@@ -704,6 +742,13 @@ class NgpOverlay {
|
|
|
704
742
|
this.closeTimeout();
|
|
705
743
|
this.closeTimeout = undefined;
|
|
706
744
|
}
|
|
745
|
+
// If destruction is in progress (exit animation running), cancel it
|
|
746
|
+
// and reuse the existing overlay instead of creating a new one.
|
|
747
|
+
if (this.destroyingPortal) {
|
|
748
|
+
this.cancelDestruction();
|
|
749
|
+
resolve();
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
707
752
|
// Don't proceed if already opening or open
|
|
708
753
|
if (this.openTimeout || this.isOpen()) {
|
|
709
754
|
return;
|
|
@@ -743,6 +788,38 @@ class NgpOverlay {
|
|
|
743
788
|
this.closeTimeout();
|
|
744
789
|
this.closeTimeout = undefined;
|
|
745
790
|
}
|
|
791
|
+
// Also cancel in-progress destruction (exit animation running)
|
|
792
|
+
if (this.destroyingPortal) {
|
|
793
|
+
this.cancelDestruction();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Cancel an in-progress overlay destruction. This cancels exit animations,
|
|
798
|
+
* restores the portal, and re-enables positioning and scroll strategy.
|
|
799
|
+
* Used when show() or cancelPendingClose() is called during exit animation.
|
|
800
|
+
*/
|
|
801
|
+
cancelDestruction() {
|
|
802
|
+
const portal = this.destroyingPortal;
|
|
803
|
+
if (!portal) {
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
this.destroyingPortal = null;
|
|
807
|
+
portal.cancelDetach();
|
|
808
|
+
// Restore the portal
|
|
809
|
+
this.portal.set(portal);
|
|
810
|
+
// Re-setup positioning
|
|
811
|
+
const elements = portal.getElements();
|
|
812
|
+
const outletElement = elements.find(el => el.hasAttribute('data-overlay')) ?? elements[0];
|
|
813
|
+
if (outletElement) {
|
|
814
|
+
this.setupPositioning(outletElement);
|
|
815
|
+
}
|
|
816
|
+
// Re-enable scroll strategy
|
|
817
|
+
this.scrollStrategy = this.createScrollStrategy();
|
|
818
|
+
this.scrollStrategy.enable();
|
|
819
|
+
// Re-register with cooldown if needed
|
|
820
|
+
if (this.config.overlayType) {
|
|
821
|
+
this.cooldownManager.registerActive(this.config.overlayType, this, this.config.cooldown ?? 0);
|
|
822
|
+
}
|
|
746
823
|
}
|
|
747
824
|
/**
|
|
748
825
|
* Hide the overlay with the specified delay
|
|
@@ -1098,17 +1175,25 @@ class NgpOverlay {
|
|
|
1098
1175
|
// Clean up positioning
|
|
1099
1176
|
this.disposePositioning?.();
|
|
1100
1177
|
this.disposePositioning = undefined;
|
|
1101
|
-
//
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
this.isOpen.set(false);
|
|
1105
|
-
// Reset final placement
|
|
1106
|
-
this.finalPlacement.set(undefined);
|
|
1107
|
-
// Reset instant transition flag
|
|
1108
|
-
this.instantTransition.set(false);
|
|
1178
|
+
// Track the destroying portal so cancelDestruction() can restore it
|
|
1179
|
+
// if show() is called during the exit animation.
|
|
1180
|
+
this.destroyingPortal = portal;
|
|
1109
1181
|
// disable scroll strategy
|
|
1110
1182
|
this.scrollStrategy.disable();
|
|
1111
1183
|
this.scrollStrategy = new NoopScrollStrategy();
|
|
1184
|
+
// Detach the portal (waits for exit animations unless immediate).
|
|
1185
|
+
// During this await, cancelDestruction() may be called if the user
|
|
1186
|
+
// re-hovers the trigger. (See: https://github.com/ng-primitives/ng-primitives/issues/681)
|
|
1187
|
+
await portal.detach(immediate);
|
|
1188
|
+
// Only complete destruction if it was not cancelled during exit animation.
|
|
1189
|
+
// finalPlacement and instantTransition are intentionally cleared here
|
|
1190
|
+
// (not before the await) so they remain valid if destruction is cancelled.
|
|
1191
|
+
if (this.destroyingPortal === portal) {
|
|
1192
|
+
this.destroyingPortal = null;
|
|
1193
|
+
this.isOpen.set(false);
|
|
1194
|
+
this.finalPlacement.set(undefined);
|
|
1195
|
+
this.instantTransition.set(false);
|
|
1196
|
+
}
|
|
1112
1197
|
}
|
|
1113
1198
|
/**
|
|
1114
1199
|
* Get the transform origin for the overlay
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-primitives-portal.mjs","sources":["../../../../packages/ng-primitives/portal/src/flip.ts","../../../../packages/ng-primitives/portal/src/offset.ts","../../../../packages/ng-primitives/portal/src/overlay-cooldown.ts","../../../../packages/ng-primitives/portal/src/overlay-token.ts","../../../../packages/ng-primitives/portal/src/portal.ts","../../../../packages/ng-primitives/portal/src/scroll-strategy.ts","../../../../packages/ng-primitives/portal/src/overlay.ts","../../../../packages/ng-primitives/portal/src/overlay-arrow-state.ts","../../../../packages/ng-primitives/portal/src/shift.ts","../../../../packages/ng-primitives/portal/src/ng-primitives-portal.ts"],"sourcesContent":["import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { type Placement } from '@floating-ui/dom';\nimport { isNil, isObject } from 'ng-primitives/utils';\n\n/**\n * Options for configuring flip behavior to keep the floating element in view.\n * The flip middleware ensures the floating element flips to the opposite side\n * when it would otherwise overflow the viewport.\n */\nexport interface NgpFlipOptions {\n /**\n * The minimum padding between the floating element and the viewport edges.\n * Prevents the floating element from touching the edges of the viewport.\n * @default 0\n */\n padding?: number;\n\n /**\n * Placements to try sequentially if the preferred placement does not fit.\n * @default [oppositePlacement] (computed)\n */\n fallbackPlacements?: Placement[];\n}\n\n/**\n * Type representing all valid flip values.\n * Can be a boolean (enable/disable), undefined, or an object with detailed options.\n */\nexport type NgpFlip = boolean | NgpFlipOptions | undefined;\n\n/**\n * Input type for flip that also accepts string representations of booleans\n */\nexport type NgpFlipInput = NgpFlip | string;\n\n/**\n * Transform function to coerce flip input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced flip value\n */\nexport function coerceFlip(value: NgpFlipInput | null | undefined): NgpFlip {\n if (isNil(value)) {\n return undefined;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Handle boolean values\n if (typeof value === 'boolean') {\n return value;\n }\n\n // Handle empty attribute values (Angular boolean attribute semantics)\n if (value === '') {\n return true;\n }\n\n // Handle string boolean values\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n // Handle string number values for padding shorthand\n const numValue = coerceNumberProperty(value, null);\n if (numValue !== null && !isNaN(numValue)) {\n return { padding: numValue };\n }\n\n return undefined;\n}\n","import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isObject, isNil } from 'ng-primitives/utils';\n\n/**\n * Options for configuring offset between a floating element and its reference element.\n * Can be a single number for uniform offset or an object for axis-specific control.\n */\nexport interface NgpOffsetOptions {\n /**\n * The offset along the main axis (the axis that runs along the side of the floating element).\n * Represents the distance between the floating element and the reference element.\n * @default 0\n */\n mainAxis?: number;\n\n /**\n * The offset along the cross axis (the axis that runs along the alignment of the floating element).\n * Represents the skidding between the floating element and the reference element.\n * @default 0\n */\n crossAxis?: number;\n\n /**\n * Same axis as crossAxis but applies only to aligned placements and inverts the end alignment.\n * When set to a number, it overrides the crossAxis value.\n * @default null\n */\n alignmentAxis?: number | null;\n}\n\n/**\n * Type representing all valid offset values.\n * Can be a number (applies to mainAxis) or an object with axis-specific offsets.\n */\nexport type NgpOffset = number | NgpOffsetOptions;\n\n/**\n * Input type for offset that also accepts string representations of numbers\n */\nexport type NgpOffsetInput = NgpOffset | string;\n\n/**\n * Transform function to coerce offset input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced offset value\n */\nexport function coerceOffset(value: NgpOffsetInput | null | undefined): NgpOffset {\n if (isNil(value)) {\n return 0;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Use CDK's coerceNumberProperty for consistent number coercion\n // This handles strings, numbers, and other input types just like Angular CDK inputs\n return coerceNumberProperty(value, 0);\n}\n","import { Injectable, WritableSignal } from '@angular/core';\n\n/** Interface for overlays that can be closed immediately */\nexport interface CooldownOverlay {\n hideImmediate(): void;\n /** Optional signal to mark the transition as instant due to cooldown */\n instantTransition?: WritableSignal<boolean>;\n}\n\n/**\n * Singleton service that tracks close timestamps and active overlays per overlay type.\n * This enables the cooldown feature where quickly moving between triggers\n * of the same overlay type (e.g., tooltip to tooltip) shows the second\n * overlay immediately without the showDelay, and closes the first immediately.\n * @internal\n */\n@Injectable({ providedIn: 'root' })\nexport class NgpOverlayCooldownManager {\n private readonly lastCloseTimestamps = new Map<string, number>();\n private readonly activeOverlays = new Map<string, CooldownOverlay>();\n\n /**\n * Record the close timestamp for an overlay type.\n * @param overlayType The type identifier for the overlay group\n */\n recordClose(overlayType: string): void {\n this.lastCloseTimestamps.set(overlayType, Date.now());\n }\n\n /**\n * Check if the overlay type is within its cooldown period.\n * @param overlayType The type identifier for the overlay group\n * @param duration The cooldown duration in milliseconds\n * @returns true if within cooldown period, false otherwise\n */\n isWithinCooldown(overlayType: string, duration: number): boolean {\n const lastClose = this.lastCloseTimestamps.get(overlayType);\n if (lastClose === undefined) {\n return false;\n }\n return Date.now() - lastClose < duration;\n }\n\n /**\n * Register an overlay as active for its type.\n * Any existing overlay of the same type will be closed immediately.\n * @param overlayType The type identifier for the overlay group\n * @param overlay The overlay instance\n * @param cooldown The cooldown duration - if > 0, enables instant transitions\n */\n registerActive(overlayType: string, overlay: CooldownOverlay, cooldown: number): void {\n const existing = this.activeOverlays.get(overlayType);\n\n // If there's an existing overlay and cooldown is enabled, close it immediately.\n // This ensures instant DOM swap when hovering between items of the same type.\n if (existing && existing !== overlay && cooldown > 0) {\n existing.instantTransition?.set(true);\n existing.hideImmediate();\n }\n\n this.activeOverlays.set(overlayType, overlay);\n }\n\n /**\n * Unregister an overlay when it closes.\n * @param overlayType The type identifier for the overlay group\n * @param overlay The overlay instance to remove\n */\n unregisterActive(overlayType: string, overlay: CooldownOverlay): void {\n if (this.activeOverlays.get(overlayType) === overlay) {\n this.activeOverlays.delete(overlayType);\n }\n }\n\n /**\n * Check if there's an active overlay of the given type.\n * @param overlayType The type identifier for the overlay group\n * @returns true if there's an active overlay, false otherwise\n */\n hasActiveOverlay(overlayType: string): boolean {\n return this.activeOverlays.has(overlayType);\n }\n}\n","import { inject, InjectionToken, Signal, ValueProvider } from '@angular/core';\n\nconst NgpOverlayContextToken = new InjectionToken<unknown>('NgpOverlayContextToken');\n\n/**\n * Injects the context for the overlay.\n * @internal\n */\nexport function injectOverlayContext<T>(): Signal<T> {\n return inject(NgpOverlayContextToken) as Signal<T>;\n}\n\n/**\n * Provides the context for the overlay.\n * @param value The value to provide as the context.\n * @internal\n */\nexport function provideOverlayContext<T>(value: Signal<T | undefined> | undefined): ValueProvider {\n return { provide: NgpOverlayContextToken, useValue: value };\n}\n","import { VERSION } from '@angular/cdk';\nimport { ComponentPortal, DomPortalOutlet, TemplatePortal } from '@angular/cdk/portal';\nimport {\n ApplicationRef,\n ComponentRef,\n EmbeddedViewRef,\n Injector,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgpExitAnimationRef, setupExitAnimation } from 'ng-primitives/internal';\n\nexport interface NgpPortalAttachOptions {\n /** If true, skip enter animation delay and set enter state immediately. */\n immediate?: boolean;\n}\n\nexport abstract class NgpPortal {\n constructor(\n protected readonly viewContainerRef: ViewContainerRef | null,\n protected readonly injector: Injector,\n ) {}\n\n /**\n * Get the elements of the portal.\n */\n abstract getElements(): HTMLElement[];\n\n /**\n * Detect changes in the portal.\n */\n abstract detectChanges(): void;\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n abstract getAttached(): boolean;\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n abstract attach(container: HTMLElement, options?: NgpPortalAttachOptions): this;\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n abstract detach(immediate?: boolean): Promise<void>;\n\n /**\n * Angular v20 removes `_unusedComponentFactoryResolver` and `_document` from DomPortalOutlet's\n * constructor signature as they have been deprecated since v18, and replaced with optional\n * `_appRef` and `_defaultInjector` params.\n * This temporary change ensures consistent behaviour for consumers using ng v20+.\n * @see {@link https://github.com/angular/components/pull/24504 The implementing PR} for the new implementation.\n * @see {@link https://github.com/angular/components/blob/732a0d7ab69ec25925cc06a0fb17b0fb16a4b0ae/src/cdk/portal/dom-portal-outlet.ts#L27 The latest v20 version comments}\n * describe the importance of passing the `_appRef` and `_defaultInjector` when it comes to component portals\n */\n // todo: remove this compat fix once support for v19 is dropped when v21 is released\n // - should aim to add appRef also to prevent unforeseen issues in certain edge cases\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected _getDomPortalOutletCtorParamsCompat(): (ApplicationRef | Injector | undefined | any)[] {\n return Number(VERSION.major) >= 20 ? [this.injector] : [undefined, this.injector];\n }\n}\n\nexport class NgpComponentPortal<T> extends NgpPortal {\n private readonly componentPortal: ComponentPortal<T>;\n private viewRef: ComponentRef<T> | null = null;\n private isDestroying = false;\n private exitAnimationRef: NgpExitAnimationRef | null = null;\n\n constructor(component: Type<T>, viewContainerRef: ViewContainerRef | null, injector: Injector) {\n super(viewContainerRef, injector);\n this.componentPortal = new ComponentPortal(component, viewContainerRef, injector);\n }\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n attach(container: HTMLElement, options?: NgpPortalAttachOptions): this {\n const appRef = this.injector.get(ApplicationRef);\n const domOutlet =\n Number(VERSION.major) >= 20\n ? new DomPortalOutlet(container, appRef, this.injector)\n : // @ts-expect-error: Compatibility for Angular versions < 20\n new DomPortalOutlet(container, undefined, appRef, this.injector);\n\n this.viewRef = domOutlet.attach(this.componentPortal);\n\n const element = this.viewRef.location.nativeElement as HTMLElement;\n\n this.exitAnimationRef = setupExitAnimation({ element, immediate: options?.immediate });\n\n return this;\n }\n\n /**\n * Get the root elements of the portal.\n */\n getElements(): HTMLElement[] {\n return this.viewRef ? [this.viewRef.location.nativeElement] : [];\n }\n\n /**\n * Detect changes in the portal.\n */\n detectChanges(): void {\n this.viewRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n getAttached(): boolean {\n return !!this.viewRef && (this.viewRef.location.nativeElement as HTMLElement).isConnected;\n }\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n async detach(immediate?: boolean): Promise<void> {\n if (this.isDestroying) {\n return;\n }\n this.isDestroying = true;\n\n // Only wait for exit animation if not immediate\n if (!immediate) {\n await this.exitAnimationRef?.exit();\n }\n\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n}\n\nexport class NgpTemplatePortal<T> extends NgpPortal {\n private readonly templatePortal: TemplatePortal<T>;\n private viewRef: EmbeddedViewRef<T> | null = null;\n private exitAnimationRefs: NgpExitAnimationRef[] = [];\n private isDestroying = false;\n\n constructor(\n template: TemplateRef<T>,\n viewContainerRef: ViewContainerRef,\n injector: Injector,\n context?: T,\n ) {\n super(viewContainerRef, injector);\n this.templatePortal = new TemplatePortal(template, viewContainerRef, context, injector);\n }\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n attach(container: HTMLElement, options?: NgpPortalAttachOptions): this {\n const domOutlet = new DomPortalOutlet(\n container,\n undefined,\n ...this._getDomPortalOutletCtorParamsCompat(),\n );\n this.viewRef = domOutlet.attach(this.templatePortal);\n\n for (const rootNode of this.viewRef.rootNodes) {\n if (rootNode instanceof HTMLElement) {\n // Setup exit animation for each root node\n const exitAnimationRef = setupExitAnimation({\n element: rootNode,\n immediate: options?.immediate,\n });\n this.exitAnimationRefs.push(exitAnimationRef);\n }\n }\n\n return this;\n }\n\n /**\n * Get the root elements of the portal.\n */\n getElements(): HTMLElement[] {\n return this.viewRef ? this.viewRef.rootNodes : [];\n }\n\n /**\n * Detect changes in the portal.\n */\n detectChanges(): void {\n this.viewRef?.detectChanges();\n }\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n getAttached(): boolean {\n return !!this.viewRef && this.viewRef.rootNodes.length > 0;\n }\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n async detach(immediate?: boolean): Promise<void> {\n if (this.isDestroying) {\n return;\n }\n\n this.isDestroying = true;\n\n // Only wait for exit animations if not immediate\n if (!immediate) {\n await Promise.all(this.exitAnimationRefs.map(ref => ref.exit()));\n }\n\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n}\n\nexport function createPortal<T>(\n componentOrTemplate: Type<T> | TemplateRef<T>,\n viewContainerRef: ViewContainerRef | null,\n injector: Injector,\n context?: T,\n): NgpPortal {\n if (componentOrTemplate instanceof TemplateRef) {\n if (!viewContainerRef) {\n throw new Error('A ViewContainerRef is required to create a TemplatePortal.');\n }\n\n return new NgpTemplatePortal(componentOrTemplate, viewContainerRef, injector, context);\n } else {\n return new NgpComponentPortal(componentOrTemplate, viewContainerRef, injector);\n }\n}\n","/**\n * This code is largely based on the CDK Overlay's scroll strategy implementation, however it\n * has been modified so that it does not rely on the CDK's global overlay styles.\n */\nimport { coerceCssPixelValue } from '@angular/cdk/coercion';\nimport { ViewportRuler } from '@angular/cdk/overlay';\nimport { getOverflowAncestors } from '@floating-ui/dom';\nimport { isFunction, isObject } from 'ng-primitives/utils';\n\nexport interface ScrollStrategy {\n enable(): void;\n disable(): void;\n}\n\n/** Cached result of the check that indicates whether the browser supports scroll behaviors. */\nlet scrollBehaviorSupported: boolean | undefined;\n\nexport function supportsScrollBehavior(): boolean {\n if (scrollBehaviorSupported != null) {\n return scrollBehaviorSupported;\n }\n\n // If we're not in the browser, it can't be supported. Also check for `Element`, because\n // some projects stub out the global `document` during SSR which can throw us off.\n if (!isObject(document) || !document || !isFunction(Element) || !Element) {\n return (scrollBehaviorSupported = false);\n }\n\n // If the element can have a `scrollBehavior` style, we can be sure that it's supported.\n if ('scrollBehavior' in document.documentElement!.style) {\n return (scrollBehaviorSupported = true);\n }\n\n // Check if scrollTo is supported and if it's been polyfilled\n const scrollToFunction = Element.prototype.scrollTo;\n if (!scrollToFunction) {\n return (scrollBehaviorSupported = false);\n }\n\n // We can detect if the function has been polyfilled by calling `toString` on it. Native\n // functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get\n // the actual function source. Via https://davidwalsh.name/detect-native-function. Consider\n // polyfilled functions as supporting scroll behavior.\n return (scrollBehaviorSupported = !/\\{\\s*\\[native code\\]\\s*\\}/.test(scrollToFunction.toString()));\n}\n\ninterface HTMLStyles {\n top: string;\n left: string;\n position: string;\n overflowY: string;\n width: string;\n}\n\nexport class BlockScrollStrategy implements ScrollStrategy {\n private readonly previousHTMLStyles: HTMLStyles = {\n top: '',\n left: '',\n position: '',\n overflowY: '',\n width: '',\n };\n private previousScrollPosition = { top: 0, left: 0 };\n private isEnabled = false;\n\n constructor(\n private readonly viewportRuler: ViewportRuler,\n private readonly document: Document,\n ) {}\n\n /** Blocks page-level scroll while the attached overlay is open. */\n enable() {\n if (this.canBeEnabled()) {\n const root = this.document.documentElement!;\n\n this.previousScrollPosition = this.viewportRuler.getViewportScrollPosition();\n\n // Cache the previous inline styles in case the user had set them.\n this.previousHTMLStyles.left = root.style.left || '';\n this.previousHTMLStyles.top = root.style.top || '';\n this.previousHTMLStyles.position = root.style.position || '';\n this.previousHTMLStyles.overflowY = root.style.overflowY || '';\n this.previousHTMLStyles.width = root.style.width || '';\n\n // Set the styles to block scrolling.\n root.style.position = 'fixed';\n\n // Necessary for the content not to lose its width. Note that we're using 100%, instead of\n // 100vw, because 100vw includes the width plus the scrollbar, whereas 100% is the width\n // that the element had before we made it `fixed`.\n root.style.width = '100%';\n\n // Note: this will always add a scrollbar to whatever element it is on, which can\n // potentially result in double scrollbars. It shouldn't be an issue, because we won't\n // block scrolling on a page that doesn't have a scrollbar in the first place.\n root.style.overflowY = 'scroll';\n\n // Note: we're using the `html` node, instead of the `body`, because the `body` may\n // have the user agent margin, whereas the `html` is guaranteed not to have one.\n root.style.left = coerceCssPixelValue(-this.previousScrollPosition.left);\n root.style.top = coerceCssPixelValue(-this.previousScrollPosition.top);\n root.setAttribute('data-scrollblock', '');\n this.isEnabled = true;\n }\n }\n\n /** Unblocks page-level scroll while the attached overlay is open. */\n disable(): void {\n if (this.isEnabled) {\n const html = this.document.documentElement!;\n const body = this.document.body!;\n const htmlStyle = html.style;\n const bodyStyle = body.style;\n const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';\n const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';\n\n this.isEnabled = false;\n\n htmlStyle.left = this.previousHTMLStyles.left;\n htmlStyle.top = this.previousHTMLStyles.top;\n htmlStyle.position = this.previousHTMLStyles.position;\n htmlStyle.overflowY = this.previousHTMLStyles.overflowY;\n htmlStyle.width = this.previousHTMLStyles.width;\n html.removeAttribute('data-scrollblock');\n\n // Disable user-defined smooth scrolling temporarily while we restore the scroll position.\n // See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior\n // Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,\n // because it can throw off feature detections in `supportsScrollBehavior` which\n // checks for `'scrollBehavior' in documentElement.style`.\n if (scrollBehaviorSupported) {\n htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';\n }\n\n window.scroll(this.previousScrollPosition.left, this.previousScrollPosition.top);\n\n if (scrollBehaviorSupported) {\n htmlStyle.scrollBehavior = previousHtmlScrollBehavior;\n bodyStyle.scrollBehavior = previousBodyScrollBehavior;\n }\n }\n }\n\n private canBeEnabled(): boolean {\n // Since the scroll strategies can't be singletons, we have to use a global CSS class\n // (`cdk-global-scrollblock`) to make sure that we don't try to disable global\n // scrolling multiple times.\n const html = this.document.documentElement!;\n\n if (html.classList.contains('cdk-global-scrollblock') || this.isEnabled) {\n return false;\n }\n\n const viewport = this.viewportRuler.getViewportSize();\n return html.scrollHeight > viewport.height || html.scrollWidth > viewport.width;\n }\n}\n\nexport class CloseScrollStrategy implements ScrollStrategy {\n private cleanups: (() => void)[] = [];\n\n constructor(\n private readonly triggerElement: HTMLElement,\n private readonly onClose: () => void,\n private readonly overlayElements: () => HTMLElement[],\n ) {}\n\n enable(): void {\n // Guard against double-enable: remove any existing listeners first\n this.disable();\n\n const ancestors = getOverflowAncestors(this.triggerElement);\n\n const handler = (event: Event) => {\n const target = event.target;\n\n // Don't close if the scroll happened inside the overlay\n if (target instanceof Node) {\n const elements = this.overlayElements();\n if (elements.some(el => el.contains(target))) {\n return;\n }\n }\n\n // Stop listening immediately to prevent redundant close calls from rapid scroll events\n this.disable();\n this.onClose();\n };\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', handler, { passive: true });\n this.cleanups.push(() => ancestor.removeEventListener('scroll', handler));\n }\n }\n\n disable(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups = [];\n }\n}\n\nexport class NoopScrollStrategy implements ScrollStrategy {\n enable(): void {\n // No operation for enabling\n }\n\n disable(): void {\n // No operation for disabling\n }\n}\n","import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\nimport { ViewportRuler } from '@angular/cdk/overlay';\nimport { DOCUMENT } from '@angular/common';\nimport {\n DestroyRef,\n Injector,\n Provider,\n Signal,\n TemplateRef,\n Type,\n ViewContainerRef,\n computed,\n inject,\n runInInjectionContext,\n signal,\n} from '@angular/core';\nimport { ControlContainer } from '@angular/forms';\nimport {\n Middleware,\n Placement,\n Strategy,\n VirtualElement,\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n shift,\n size,\n} from '@floating-ui/dom';\nimport { explicitEffect, fromResizeEvent } from 'ng-primitives/internal';\nimport { injectDisposables, safeTakeUntilDestroyed, uniqueId } from 'ng-primitives/utils';\nimport { Subject, fromEvent } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { NgpFlip } from './flip';\nimport { NgpOffset } from './offset';\nimport { CooldownOverlay, NgpOverlayCooldownManager } from './overlay-cooldown';\nimport { provideOverlayContext } from './overlay-token';\nimport { NgpPortal, createPortal } from './portal';\nimport { NgpPosition } from './position';\nimport {\n BlockScrollStrategy,\n CloseScrollStrategy,\n NoopScrollStrategy,\n ScrollStrategy,\n} from './scroll-strategy';\nimport { NgpShift } from './shift';\n\n/**\n * Bit value of the internal `SkipSelf` inject flag used by Angular's DI system.\n * This value is part of Angular's ABI and is stable across versions 19+.\n * @see InjectFlags.SkipSelf / InternalInjectFlags.SkipSelf\n */\nconst SKIP_SELF_FLAG = 4;\n\n/** Check whether the given inject flags include `SkipSelf`. */\nfunction hasSkipSelfFlag(flags: unknown): boolean {\n if (typeof flags === 'number') {\n return (flags & SKIP_SELF_FLAG) !== 0;\n }\n if (flags != null && typeof flags === 'object' && 'skipSelf' in flags) {\n return !!(flags as { skipSelf: unknown }).skipSelf;\n }\n return false;\n}\n\n/**\n * An injector wrapper that intercepts `ControlContainer` lookups carrying the\n * `SkipSelf` flag and short-circuits them to `notFoundValue`.\n *\n * ## Why this is needed\n *\n * Angular's `lookupTokenUsingEmbeddedInjector` passes the original inject flags\n * to the embedded view injector's `.get()` call. For directives that use\n * `@Host() @SkipSelf()` (e.g. `FormControlName`, `FormGroupName`):\n *\n * - **Without this wrapper**: `R3Injector.get()` honors `SkipSelf` by skipping\n * its own `ControlContainer: null` record and delegates to the parent injector\n * (the trigger element's injector), which may find the **outer** form's\n * `ControlContainer` — leaking the wrong form context into child components.\n *\n * - **If we stripped SkipSelf entirely**: `R3Injector` would find its own\n * `ControlContainer: null` and return `null`. But this `null` is returned\n * for ALL `ControlContainer` lookups within the portaled view, killing child\n * components' own `FormGroupDirective` resolution (NG01050).\n *\n * ## The fix\n *\n * For `ControlContainer` + `SkipSelf`, return `notFoundValue` directly. This\n * causes `lookupTokenUsingEmbeddedInjector` to skip this boundary and eventually\n * return `NOT_FOUND`, letting `lookupTokenUsingNodeInjector` run — which correctly\n * finds the child component's own `FormGroupDirective` via the element injector chain.\n *\n * For `ControlContainer` without `SkipSelf` (e.g. `NgModel` uses `@Host()` only),\n * delegation proceeds normally and finds `ControlContainer: null`, preventing the\n * outer form from leaking.\n *\n * @see https://github.com/angular/angular/issues/57390\n * @see https://github.com/ng-primitives/ng-primitives/issues/677\n * @internal\n */\nclass EmbeddedViewInjector extends Injector {\n constructor(private readonly delegate: Injector) {\n super();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(token: any, notFoundValue?: any, flags?: any): any {\n if (token === ControlContainer && hasSkipSelfFlag(flags)) {\n return notFoundValue;\n }\n return this.delegate.get(token, notFoundValue, flags);\n }\n}\n\n/**\n * Configuration options for creating an overlay\n * @internal\n */\nexport interface NgpOverlayConfig<T = unknown> {\n /** Content to display in the overlay (component or template) */\n content: NgpOverlayContent<T>;\n\n /** The element that triggers the overlay */\n triggerElement: HTMLElement;\n\n /** The element to use for positioning the overlay (if different from trigger) */\n anchorElement?: HTMLElement | null;\n\n /** The injector to use for creating the portal */\n injector: Injector;\n /** ViewContainerRef to use for creating the portal */\n viewContainerRef: ViewContainerRef;\n\n /** Context data to pass to the overlay content */\n context?: Signal<T | undefined>;\n\n /** Container element or selector to attach the overlay to (defaults to document.body) */\n container?: HTMLElement | string | null;\n\n /** Preferred placement of the overlay relative to the trigger. */\n placement?: Signal<Placement>;\n\n /** Offset distance between the overlay and trigger. Can be a number or an object with axis-specific offsets */\n offset?: NgpOffset;\n\n /** Shift configuration to keep the overlay in view. Can be a boolean, an object with options, or undefined */\n shift?: NgpShift;\n\n /** Whether to enable flip behavior when space is limited, or an object with flip options */\n flip?: NgpFlip;\n\n /** Delay before showing the overlay in milliseconds */\n showDelay?: number;\n\n /** Delay before hiding the overlay in milliseconds */\n hideDelay?: number;\n\n /** Whether the overlay should be positioned with fixed or absolute strategy */\n strategy?: Strategy;\n\n /** The scroll strategy to use for the overlay */\n scrollBehaviour?: 'reposition' | 'block' | 'close';\n /** Whether to close the overlay when clicking outside */\n closeOnOutsideClick?: boolean;\n /** Whether to close the overlay when pressing escape */\n closeOnEscape?: boolean;\n /**\n * Whether to restore focus to the trigger element when hiding the overlay.\n * Can be a boolean or a signal that returns a boolean.\n */\n restoreFocus?: boolean | Signal<boolean>;\n\n /**\n * Optional callback to update an external close origin signal.\n * Called when the overlay is hidden with the focus origin.\n * @internal\n */\n onClose?: (origin: FocusOrigin) => void;\n /** Additional middleware for floating UI positioning */\n additionalMiddleware?: Middleware[];\n\n /** Additional providers */\n providers?: Provider[];\n\n /** Whether to track the trigger element position on every animation frame. Useful for moving elements like slider thumbs. */\n trackPosition?: boolean;\n\n /**\n * Programmatic position for the overlay. When provided, the overlay will be positioned\n * at these coordinates instead of anchoring to the trigger element.\n * Use with trackPosition for smooth cursor following.\n */\n position?: Signal<NgpPosition | null>;\n\n /**\n * Overlay type identifier for cooldown grouping.\n * When set, overlays of the same type share a cooldown period.\n * For example, 'tooltip' ensures quickly moving between tooltips shows\n * the second one immediately without the showDelay.\n */\n overlayType?: string;\n\n /**\n * Cooldown duration in milliseconds.\n * When moving from one overlay of the same type to another within this duration,\n * the showDelay is skipped for the new overlay.\n * @default 300\n */\n cooldown?: number;\n}\n\n/** Type for overlay content which can be either a template or component */\nexport type NgpOverlayContent<T> = TemplateRef<NgpOverlayTemplateContext<T>> | Type<unknown>;\n\n/** Context for template-based overlays */\nexport type NgpOverlayTemplateContext<T> = {\n $implicit: T;\n};\n\n/**\n * NgpOverlay manages the lifecycle and positioning of overlay UI elements.\n * It abstracts the common behavior shared by tooltips, popovers, menus, etc.\n * @internal\n */\nexport class NgpOverlay<T = unknown> implements CooldownOverlay {\n private readonly disposables = injectDisposables();\n private readonly document = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n private readonly viewContainerRef: ViewContainerRef;\n private readonly viewportRuler = inject(ViewportRuler);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly cooldownManager = inject(NgpOverlayCooldownManager);\n /** Access any parent overlays */\n private readonly parentOverlay = inject(NgpOverlay, { optional: true });\n /** Track child overlays for outside click detection */\n private readonly childOverlays = new Set<NgpOverlay>();\n /** Signal tracking the portal instance */\n private readonly portal = signal<NgpPortal | null>(null);\n\n /** Signal tracking the overlay position */\n readonly position = signal<{ x: number | undefined; y: number | undefined }>({\n x: undefined,\n y: undefined,\n });\n\n /**\n * Determine if the overlay has been positioned\n * @internal\n */\n readonly isPositioned = computed(\n () => this.position().x !== undefined && this.position().y !== undefined,\n );\n\n /** Signal tracking the trigger element width */\n readonly triggerWidth = signal<number | null>(null);\n\n /** The transform origin for the overlay */\n readonly transformOrigin = signal<string>('center center');\n\n /** Signal tracking the available width before the overlay overflows the viewport */\n readonly availableWidth = signal<number | null>(null);\n\n /** Signal tracking the available height before the overlay overflows the viewport */\n readonly availableHeight = signal<number | null>(null);\n\n /** Signal tracking the final placement of the overlay */\n readonly finalPlacement = signal<Placement | undefined>(undefined);\n\n /** Function to dispose the positioning auto-update */\n private disposePositioning?: () => void;\n\n /** Timeout handle for showing the overlay */\n private openTimeout?: () => void;\n\n /** Timeout handle for hiding the overlay */\n private closeTimeout?: () => void;\n\n /** Signal tracking whether the overlay is open */\n readonly isOpen = signal(false);\n\n /** A unique id for the overlay */\n readonly id = signal<string>(uniqueId('ngp-overlay'));\n\n /**\n * Signal tracking the focus origin used to close the overlay.\n * Updated when hide() is called.\n * @internal\n */\n readonly closeOrigin = signal<FocusOrigin>('program');\n\n /** The aria-describedby attribute for accessibility */\n readonly ariaDescribedBy = computed(() => (this.isOpen() ? this.id() : undefined));\n\n /** The scroll strategy */\n private scrollStrategy = new NoopScrollStrategy();\n\n /** An observable that emits when the overlay is closing */\n readonly closing = new Subject<void>();\n\n /**\n * Signal tracking whether the current transition is instant due to cooldown.\n * When true, CSS can skip animations using the data-instant attribute.\n */\n readonly instantTransition = signal(false);\n\n /** Store the arrow element */\n private arrowElement: HTMLElement | null = null;\n\n /** Store the arrow padding signal */\n private arrowPadding: Signal<number | undefined> | undefined = undefined;\n\n /** @internal The position of the arrow */\n readonly arrowPosition = signal<{ x: number | undefined; y: number | undefined }>({\n x: undefined,\n y: undefined,\n });\n\n /**\n * Creates a new overlay instance\n * @param config Initial configuration for the overlay\n * @param destroyRef Reference for automatic cleanup\n */\n constructor(private config: NgpOverlayConfig<T>) {\n // we cannot inject the viewContainerRef as this can throw an error during hydration in SSR\n this.viewContainerRef = config.viewContainerRef;\n\n // Listen for placement signal changes to update position\n if (config.placement) {\n explicitEffect([config.placement], () => this.updatePosition());\n }\n\n // Listen for position signal changes to update position\n if (config.position) {\n explicitEffect([config.position], () => this.updatePosition());\n }\n\n // this must be done after the config is set\n this.transformOrigin.set(this.getTransformOrigin());\n\n // Monitor trigger element resize\n const elementToMonitor = this.config.anchorElement || this.config.triggerElement;\n fromResizeEvent(elementToMonitor)\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(({ width, height }) => {\n this.triggerWidth.set(width);\n\n // if the element has been hidden, hide immediately\n if (width === 0 || height === 0) {\n this.hideImmediate();\n }\n });\n\n // Register with parent overlay for outside click detection\n if (this.parentOverlay) {\n this.parentOverlay.registerChildOverlay(this);\n }\n\n // if there is a parent overlay and it is closed, close this overlay\n this.parentOverlay?.closing\n // we add a debounce here to ensure any dom events like clicks are processed first\n .pipe(debounceTime(0), safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (this.isOpen()) {\n this.hideImmediate();\n }\n });\n\n // If closeOnOutsideClick is enabled, set up a click listener\n fromEvent<MouseEvent>(this.document, 'mouseup', { capture: true })\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (!this.config.closeOnOutsideClick) {\n return;\n }\n\n const overlay = this.portal();\n\n if (!overlay || !this.isOpen()) {\n return;\n }\n\n const path = event.composedPath();\n const isInsideOverlay = overlay.getElements().some(el => path.includes(el));\n const isInsideTrigger = path.includes(this.config.triggerElement);\n const isInsideAnchor = this.config.anchorElement\n ? path.includes(this.config.anchorElement)\n : false;\n\n if (\n !isInsideOverlay &&\n !isInsideTrigger &&\n !isInsideAnchor &&\n !this.isInsideChildOverlay(path)\n ) {\n this.hide();\n }\n });\n\n // If closeOnEscape is enabled, set up a keydown listener\n fromEvent<KeyboardEvent>(this.document, 'keydown', { capture: true })\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (!this.config.closeOnEscape) return;\n if (event.key === 'Escape' && this.isOpen()) {\n this.hide({ origin: 'keyboard', immediate: true });\n }\n });\n\n // Ensure cleanup on destroy\n this.destroyRef.onDestroy(() => {\n this.parentOverlay?.unregisterChildOverlay(this);\n this.destroy();\n });\n }\n\n /**\n * Show the overlay with the specified delay\n * @param options Optional options for showing the overlay\n */\n show(options?: { skipCooldown?: boolean }): Promise<void> {\n return new Promise<void>(resolve => {\n // If closing is in progress, cancel it\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n // Don't proceed if already opening or open\n if (this.openTimeout || this.isOpen()) {\n return;\n }\n\n // Use the provided delay or fall back to config\n let delay = this.config.showDelay ?? 0;\n let isInstantDueToCooldown = false;\n\n // Check cooldown regardless of delay value - we need to detect instant transitions\n // even when showDelay is 0, so CSS can skip animations via data-instant attribute.\n // However, if cooldown is explicitly set to 0, disable cooldown behavior entirely.\n // Skip cooldown detection entirely when skipCooldown is true (e.g. programmatic show).\n if (!options?.skipCooldown && this.config.overlayType) {\n const cooldownDuration = this.config.cooldown ?? 300;\n if (\n cooldownDuration > 0 &&\n (this.cooldownManager.isWithinCooldown(this.config.overlayType, cooldownDuration) ||\n this.cooldownManager.hasActiveOverlay(this.config.overlayType))\n ) {\n delay = 0; // Skip delay (no-op if already 0)\n isInstantDueToCooldown = true;\n }\n }\n\n // Set instant transition flag based on whether delay was skipped due to cooldown\n this.instantTransition.set(isInstantDueToCooldown);\n\n this.openTimeout = this.disposables.setTimeout(() => {\n this.openTimeout = undefined;\n this.createOverlay(options?.skipCooldown);\n resolve();\n }, delay);\n });\n }\n\n /**\n * Stop any pending close operation. This is useful for example, if we move the mouse from the tooltip trigger to the tooltip itself.\n * This will prevent the tooltip from closing immediately when the mouse leaves the trigger.\n * @internal\n */\n cancelPendingClose(): void {\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n }\n\n /**\n * Hide the overlay with the specified delay\n * @param options Optional options for hiding the overlay\n */\n hide(options?: OverlayTriggerOptions): void {\n // If opening is in progress, cancel it\n if (this.openTimeout) {\n this.openTimeout();\n this.openTimeout = undefined;\n }\n\n // Don't proceed if already closing or closed unless immediate is true\n if ((this.closeTimeout && !options?.immediate) || !this.isOpen()) {\n return;\n }\n\n // If immediate and there's a pending close, cancel it first\n // (we'll dispose immediately instead of waiting for the old timeout)\n if (options?.immediate && this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n this.closing.next();\n\n // Check cooldown BEFORE recording, then record for the next overlay\n let delay = this.config.hideDelay ?? 0;\n if (this.config.overlayType) {\n // Skip delay if within cooldown period for this overlay type\n if (delay > 0) {\n const cooldownDuration = this.config.cooldown ?? 300;\n if (this.cooldownManager.isWithinCooldown(this.config.overlayType, cooldownDuration)) {\n delay = 0;\n }\n }\n // Record close timestamp so the next overlay of the same type can see it\n this.cooldownManager.recordClose(this.config.overlayType);\n }\n\n const dispose = async () => {\n this.closeTimeout = undefined;\n\n // If show() was called while we were waiting, abort the close\n if (this.openTimeout) {\n return;\n }\n\n const origin = options?.origin ?? 'program';\n\n // Update the close origin signal so computed signals can react\n this.closeOrigin.set(origin);\n\n // Call the onClose callback if provided (for external signal updates)\n this.config.onClose?.(origin);\n\n // Determine if focus should be restored\n const shouldRestoreFocus =\n typeof this.config.restoreFocus === 'function'\n ? this.config.restoreFocus()\n : (this.config.restoreFocus ?? false);\n\n if (shouldRestoreFocus) {\n this.focusMonitor.focusVia(this.config.triggerElement, options?.origin ?? 'program', {\n preventScroll: true,\n });\n }\n\n await this.destroyOverlay();\n };\n\n if (options?.immediate) {\n // If immediate, dispose right away\n dispose();\n } else {\n // Reset instant transition for normal closes so exit animations can play.\n // When being replaced by another overlay during cooldown, hideImmediate()\n // is called instead (which doesn't come through here), and registerActive\n // sets instantTransition to true before that call.\n this.instantTransition.set(false);\n // Remove data-instant attribute so CSS exit animations can play\n for (const element of this.getElements()) {\n element.removeAttribute('data-instant');\n }\n this.closeTimeout = this.disposables.setTimeout(dispose, delay);\n }\n }\n\n /**\n * Update the configuration of this overlay\n * @param config New configuration (partial)\n */\n updateConfig(config: Partial<NgpOverlayConfig<T>>): void {\n this.config = { ...this.config, ...config };\n\n // If the overlay is already open, update its position\n if (this.isOpen()) {\n this.updatePosition();\n }\n }\n\n /**\n * Immediately hide the overlay without any delay.\n * When called during cooldown transitions, this destroys the overlay\n * immediately without exit animations.\n */\n hideImmediate(): void {\n // Cancel any pending operations\n if (this.openTimeout) {\n this.openTimeout();\n this.openTimeout = undefined;\n }\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n // Emit closing event\n this.closing.next();\n\n // Update close origin and call callback (default to 'program' for immediate closes)\n this.closeOrigin.set('program');\n this.config.onClose?.('program');\n\n // Destroy immediately without animations\n this.destroyOverlay(true);\n }\n\n /**\n * Toggle the overlay open/closed state\n */\n toggle(): void {\n if (this.isOpen()) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Force update the position of the overlay\n */\n updatePosition(): void {\n const portal = this.portal();\n\n if (!portal) {\n return;\n }\n\n const elements = portal.getElements();\n\n if (elements.length === 0) {\n return;\n }\n\n const overlayElement = elements[0] as HTMLElement;\n\n // Compute new position\n this.computePosition(overlayElement);\n }\n\n /**\n * Completely destroy this overlay instance\n */\n destroy(): void {\n this.hideImmediate();\n this.disposePositioning?.();\n this.scrollStrategy.disable();\n }\n\n /**\n * Get the elements of the overlay\n */\n getElements(): HTMLElement[] {\n return this.portal()?.getElements() ?? [];\n }\n\n /**\n * Register a child overlay for outside click detection.\n * @internal\n */\n registerChildOverlay(child: NgpOverlay): void {\n this.childOverlays.add(child);\n }\n\n /**\n * Unregister a child overlay.\n * @internal\n */\n unregisterChildOverlay(child: NgpOverlay): void {\n this.childOverlays.delete(child);\n }\n\n /**\n * Check if the event path includes any child overlay elements (recursively).\n * @internal\n */\n isInsideChildOverlay(path: EventTarget[]): boolean {\n for (const child of this.childOverlays) {\n const childElements = child.getElements();\n if (childElements.some(el => path.includes(el))) {\n return true;\n }\n if (child.isInsideChildOverlay(path)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal method to create the overlay\n * @param skipCooldown If true, skip registering with the cooldown manager\n */\n private createOverlay(skipCooldown?: boolean): void {\n if (!this.config.content) {\n throw new Error('Overlay content must be provided');\n }\n\n // Create a new portal with context.\n // The injector is wrapped in EmbeddedViewInjector to work around an Angular 19 bug\n // where @SkipSelf() causes the embedded view injector's ControlContainer: null to be\n // bypassed. See https://github.com/angular/angular/issues/57390\n const portal = createPortal(\n this.config.content,\n this.viewContainerRef,\n new EmbeddedViewInjector(\n Injector.create({\n parent: this.config.injector,\n providers: [\n ...(this.config.providers || []),\n { provide: NgpOverlay, useValue: this },\n provideOverlayContext<T>(this.config.context),\n { provide: ControlContainer, useValue: null },\n ],\n }),\n ),\n { $implicit: this.config.context } as NgpOverlayTemplateContext<T>,\n );\n\n // Attach portal to container (skip enter animation delay if instant transition)\n const container = this.resolveContainer();\n const isInstant = this.instantTransition();\n portal.attach(container, { immediate: isInstant });\n\n // Update portal signal\n this.portal.set(portal);\n\n // If instant transition is active, set data-instant attribute synchronously\n // so CSS can use it for styling purposes\n if (isInstant) {\n for (const element of portal.getElements()) {\n element.setAttribute('data-instant', '');\n }\n }\n\n // Ensure view is up to date\n portal.detectChanges();\n\n // find a dedicated outlet element\n // this is the element that has the `data-overlay` attribute\n // if no such element exists, we use the first element in the portal\n const outletElement =\n portal.getElements().find(el => el.hasAttribute('data-overlay')) ?? portal.getElements()[0];\n\n if (!outletElement) {\n throw new Error('Overlay element is not available.');\n }\n\n // Set up positioning\n this.setupPositioning(outletElement);\n\n // Mark as open\n this.isOpen.set(true);\n\n // Register as active overlay for this type (skip when cooldown is bypassed)\n if (this.config.overlayType && !skipCooldown) {\n this.cooldownManager.registerActive(this.config.overlayType, this, this.config.cooldown ?? 0);\n }\n\n this.scrollStrategy = this.createScrollStrategy();\n this.scrollStrategy.enable();\n }\n\n /**\n * Create the appropriate scroll strategy based on the configuration.\n */\n private createScrollStrategy(): ScrollStrategy {\n switch (this.config.scrollBehaviour) {\n case 'block':\n return new BlockScrollStrategy(this.viewportRuler, this.document);\n case 'close':\n return new CloseScrollStrategy(\n this.config.anchorElement || this.config.triggerElement,\n () => this.hide({ immediate: true }),\n () => this.getElements(),\n );\n default:\n return new NoopScrollStrategy();\n }\n }\n\n /**\n * Internal method to setup positioning of the overlay\n */\n private setupPositioning(overlayElement: HTMLElement): void {\n // Determine positioning strategy based on overlay element's CSS\n const strategy =\n getComputedStyle(overlayElement).position === 'fixed'\n ? 'fixed'\n : this.config.strategy || 'absolute';\n\n // Get the reference for auto-update - use trigger element for resize/scroll tracking\n // even when using programmatic position (the virtual element is created dynamically in computePosition)\n const referenceElement = this.config.anchorElement || this.config.triggerElement;\n\n // Setup auto-update for positioning\n this.disposePositioning = autoUpdate(\n referenceElement,\n overlayElement,\n () => this.computePosition(overlayElement, strategy),\n { animationFrame: this.config.trackPosition ?? false },\n );\n }\n\n /**\n * Compute the overlay position using floating-ui\n */\n private async computePosition(\n overlayElement: HTMLElement,\n strategy: Strategy = 'absolute',\n ): Promise<void> {\n // Create middleware array\n // Order matters: offset → flip → shift → size → arrow (per Floating UI docs)\n const middleware: Middleware[] = [offset(this.config.offset ?? 0)];\n\n // Add flip middleware if requested\n // Flip must come before shift so that shift doesn't prevent flip from triggering\n const flipConfig = this.config.flip;\n if (flipConfig !== false) {\n const flipOptions = flipConfig === undefined || flipConfig === true ? {} : flipConfig;\n middleware.push(flip(flipOptions));\n }\n\n // Add shift middleware (enabled by default for backward compatibility)\n // Shift keeps the overlay in view by shifting it along its axis when it would otherwise overflow the viewport\n const shiftConfig = this.config.shift;\n if (shiftConfig !== false) {\n const shiftOptions = shiftConfig === undefined || shiftConfig === true ? {} : shiftConfig;\n middleware.push(shift(shiftOptions));\n }\n\n // Add size middleware to expose available dimensions\n middleware.push(\n size({\n apply: ({ availableWidth, availableHeight }) => {\n this.availableWidth.set(availableWidth);\n this.availableHeight.set(availableHeight);\n },\n }),\n );\n\n // Add any additional middleware\n if (this.config.additionalMiddleware) {\n middleware.push(...this.config.additionalMiddleware);\n }\n\n // If the arrow element is registered, add arrow middleware\n if (this.arrowElement) {\n middleware.push(arrow({ element: this.arrowElement, padding: this.arrowPadding?.() }));\n }\n\n // Compute the position\n const placement = this.config.placement?.() ?? 'top';\n\n // Use programmatic position if provided, otherwise use anchor/trigger element\n const referenceElement = this.getPositionReference();\n\n const position = await computePosition(referenceElement, overlayElement, {\n placement,\n middleware,\n strategy,\n });\n\n // Update position signal\n this.position.set({ x: position.x, y: position.y });\n\n // Update final placement signal\n this.finalPlacement.set(position.placement);\n\n // Update arrow position if available\n if (this.arrowElement) {\n this.arrowPosition.set({\n x: position.middlewareData.arrow?.x,\n y: position.middlewareData.arrow?.y,\n });\n }\n\n // Ensure view is updated\n this.portal()?.detectChanges();\n }\n\n /**\n * Get the reference element for positioning. When a programmatic position is provided,\n * creates a virtual element at that position. Otherwise returns the anchor or trigger element.\n */\n private getPositionReference(): HTMLElement | VirtualElement {\n const pos = this.config.position?.();\n if (pos) {\n // Create virtual element that reads position fresh on each call\n return {\n getBoundingClientRect: () => {\n const currentPos = this.config.position?.() ?? pos;\n return new DOMRect(currentPos.x, currentPos.y, 0, 0);\n },\n contextElement: this.config.triggerElement,\n };\n }\n return this.config.anchorElement || this.config.triggerElement;\n }\n\n /**\n * Internal method to destroy the overlay portal\n * @param immediate If true, skip exit animations and remove immediately\n */\n private async destroyOverlay(immediate?: boolean): Promise<void> {\n const portal = this.portal();\n\n if (!portal) {\n return;\n }\n\n // Unregister from active overlays\n if (this.config.overlayType) {\n this.cooldownManager.unregisterActive(this.config.overlayType, this);\n }\n\n // Clear portal reference to prevent double destruction\n this.portal.set(null);\n\n // Clean up positioning\n this.disposePositioning?.();\n this.disposePositioning = undefined;\n\n // Detach the portal (skip animations if immediate)\n await portal.detach(immediate);\n\n // Mark as closed\n this.isOpen.set(false);\n\n // Reset final placement\n this.finalPlacement.set(undefined);\n\n // Reset instant transition flag\n this.instantTransition.set(false);\n\n // disable scroll strategy\n this.scrollStrategy.disable();\n this.scrollStrategy = new NoopScrollStrategy();\n }\n\n /**\n * Get the transform origin for the overlay\n */\n private getTransformOrigin(): string {\n const placement = this.config.placement?.() ?? 'top';\n const basePlacement = placement.split('-')[0]; // Extract \"top\", \"bottom\", etc.\n const alignment = placement.split('-')[1]; // Extract \"start\" or \"end\"\n\n const map: Record<string, string> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n };\n\n let x = 'center';\n let y = 'center';\n\n if (basePlacement === 'top' || basePlacement === 'bottom') {\n y = map[basePlacement];\n if (alignment === 'start') x = 'left';\n else if (alignment === 'end') x = 'right';\n } else {\n x = map[basePlacement];\n if (alignment === 'start') y = 'top';\n else if (alignment === 'end') y = 'bottom';\n }\n\n return `${y} ${x}`;\n }\n\n /**\n * Register the arrow element for positioning\n * @param arrowElement The arrow element\n * @param padding Optional padding signal between the arrow and the edges of the floating element\n * @internal\n */\n registerArrow(arrowElement: HTMLElement | null, padding?: Signal<number | undefined>): void {\n this.arrowElement = arrowElement;\n this.arrowPadding = padding;\n }\n\n /**\n * Remove the registered arrow element\n * @internal\n */\n unregisterArrow(): void {\n this.arrowElement = null;\n this.arrowPadding = undefined;\n }\n\n /**\n * Resolve the container element from the configuration\n * @internal\n */\n private resolveContainer(): HTMLElement {\n if (!this.config.container) {\n return this.document.body;\n }\n\n if (typeof this.config.container === 'string') {\n const element = this.document.querySelector(this.config.container);\n if (!element) {\n // Fallback to document.body if the container is not found\n console.warn(\n `NgPrimitives: Container element with selector \"${this.config.container}\" not found. Falling back to document.body.`,\n );\n return this.document.body;\n }\n\n return element as HTMLElement;\n }\n\n return this.config.container;\n }\n}\n\n/**\n * Helper function to create an overlay in a single call\n * @internal\n */\nexport function createOverlay<T>(config: NgpOverlayConfig<T>): NgpOverlay<T> {\n // we run the overlay creation in the injector context to ensure that it can call the inject function\n return runInInjectionContext(config.injector, () => new NgpOverlay<T>(config));\n}\n\n/**\n * Helper function to inject the NgpOverlay instance\n * @internal\n */\nexport function injectOverlay<T>(): NgpOverlay<T> {\n return inject(NgpOverlay);\n}\n\nexport interface OverlayTriggerOptions {\n /**\n * Whether the visibility change should be immediate.\n */\n immediate?: boolean;\n /**\n * The origin of the focus event that triggered the visibility change.\n */\n origin?: FocusOrigin;\n}\n","import { computed, signal, Signal, WritableSignal } from '@angular/core';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport {\n controlled,\n createPrimitive,\n dataBinding,\n onDestroy,\n styleBinding,\n} from 'ng-primitives/state';\nimport { injectOverlay } from './overlay';\n\n/**\n * The state interface for the overlay arrow.\n */\nexport interface NgpOverlayArrowState {\n /**\n * The x position of the arrow.\n */\n readonly x: Signal<number | undefined>;\n /**\n * The y position of the arrow.\n */\n readonly y: Signal<number | undefined>;\n /**\n * The final placement of the overlay.\n */\n readonly placement: Signal<string | undefined>;\n /**\n * The padding between the arrow and the edges of the floating element.\n */\n readonly padding: WritableSignal<number | undefined>;\n /**\n * Set the padding between the arrow and the edges of the floating element.\n * @param value The padding value in pixels\n */\n setPadding(value: number | undefined): void;\n}\n\n/**\n * The props interface for the overlay arrow.\n */\nexport interface NgpOverlayArrowProps {\n /**\n * Padding between the arrow and the edges of the floating element.\n * This prevents the arrow from overflowing the rounded corners.\n */\n readonly padding?: Signal<number | undefined>;\n}\n\nexport const [\n NgpOverlayArrowStateToken,\n ngpOverlayArrow,\n injectOverlayArrowState,\n provideOverlayArrowState,\n] = createPrimitive(\n 'NgpOverlayArrow',\n ({ padding: _padding = signal(undefined) }: NgpOverlayArrowProps) => {\n const overlay = injectOverlay();\n const element = injectElementRef();\n const padding = controlled(_padding);\n\n // register the arrow element with the overlay\n overlay.registerArrow(element.nativeElement, padding);\n\n // cleanup the arrow element on destroy\n onDestroy(() => overlay.unregisterArrow());\n\n const x = computed(() => overlay.arrowPosition().x);\n const y = computed(() => overlay.arrowPosition().y);\n const placement = computed(() => overlay.finalPlacement());\n\n // bind the arrow position styles\n styleBinding(element, 'inset-inline-start.px', () => x() ?? null);\n styleBinding(element, 'inset-block-start.px', () => y() ?? null);\n dataBinding(element, 'data-placement', () => placement() ?? null);\n\n function setPadding(value: number | undefined): void {\n padding.set(value);\n }\n\n return {\n x,\n y,\n placement,\n padding,\n setPadding,\n } satisfies NgpOverlayArrowState;\n },\n);\n","import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isNil, isObject } from 'ng-primitives/utils';\n\n/**\n * Options for configuring shift behavior to keep the floating element in view.\n * The shift middleware ensures the floating element stays visible by shifting it\n * within the viewport when it would otherwise overflow.\n */\nexport interface NgpShiftOptions {\n /**\n * The minimum padding between the floating element and the viewport edges.\n * Prevents the floating element from touching the edges of the viewport.\n * @default 0\n */\n padding?: number;\n\n /**\n * The limiter function that determines how much the floating element can shift.\n * Common limiters from @floating-ui/dom include:\n * - limitShift: Limits shifting to prevent the reference element from being obscured\n * @default undefined\n */\n limiter?: {\n fn: (state: unknown) => { x: number; y: number };\n options?: unknown;\n };\n}\n\n/**\n * Type representing all valid shift values.\n * Can be a boolean (enable/disable), undefined, or an object with detailed options.\n */\nexport type NgpShift = boolean | NgpShiftOptions | undefined;\n\n/**\n * Input type for shift that also accepts string representations of booleans\n */\nexport type NgpShiftInput = NgpShift | string;\n\n/**\n * Transform function to coerce shift input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced shift value\n */\nexport function coerceShift(value: NgpShiftInput | null | undefined): NgpShift {\n if (isNil(value)) {\n return undefined;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Handle boolean values\n if (typeof value === 'boolean') {\n return value;\n }\n\n // Handle string boolean values\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n // Handle string number values for padding shorthand\n const numValue = coerceNumberProperty(value, null);\n if (numValue !== null && !isNaN(numValue)) {\n return { padding: numValue };\n }\n\n return undefined;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-primitives-portal.mjs","sources":["../../../../packages/ng-primitives/portal/src/flip.ts","../../../../packages/ng-primitives/portal/src/offset.ts","../../../../packages/ng-primitives/portal/src/overlay-cooldown.ts","../../../../packages/ng-primitives/portal/src/overlay-token.ts","../../../../packages/ng-primitives/portal/src/portal.ts","../../../../packages/ng-primitives/portal/src/scroll-strategy.ts","../../../../packages/ng-primitives/portal/src/overlay.ts","../../../../packages/ng-primitives/portal/src/overlay-arrow-state.ts","../../../../packages/ng-primitives/portal/src/shift.ts","../../../../packages/ng-primitives/portal/src/ng-primitives-portal.ts"],"sourcesContent":["import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { type Placement } from '@floating-ui/dom';\nimport { isNil, isObject } from 'ng-primitives/utils';\n\n/**\n * Options for configuring flip behavior to keep the floating element in view.\n * The flip middleware ensures the floating element flips to the opposite side\n * when it would otherwise overflow the viewport.\n */\nexport interface NgpFlipOptions {\n /**\n * The minimum padding between the floating element and the viewport edges.\n * Prevents the floating element from touching the edges of the viewport.\n * @default 0\n */\n padding?: number;\n\n /**\n * Placements to try sequentially if the preferred placement does not fit.\n * @default [oppositePlacement] (computed)\n */\n fallbackPlacements?: Placement[];\n}\n\n/**\n * Type representing all valid flip values.\n * Can be a boolean (enable/disable), undefined, or an object with detailed options.\n */\nexport type NgpFlip = boolean | NgpFlipOptions | undefined;\n\n/**\n * Input type for flip that also accepts string representations of booleans\n */\nexport type NgpFlipInput = NgpFlip | string;\n\n/**\n * Transform function to coerce flip input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced flip value\n */\nexport function coerceFlip(value: NgpFlipInput | null | undefined): NgpFlip {\n if (isNil(value)) {\n return undefined;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Handle boolean values\n if (typeof value === 'boolean') {\n return value;\n }\n\n // Handle empty attribute values (Angular boolean attribute semantics)\n if (value === '') {\n return true;\n }\n\n // Handle string boolean values\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n // Handle string number values for padding shorthand\n const numValue = coerceNumberProperty(value, null);\n if (numValue !== null && !isNaN(numValue)) {\n return { padding: numValue };\n }\n\n return undefined;\n}\n","import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isObject, isNil } from 'ng-primitives/utils';\n\n/**\n * Options for configuring offset between a floating element and its reference element.\n * Can be a single number for uniform offset or an object for axis-specific control.\n */\nexport interface NgpOffsetOptions {\n /**\n * The offset along the main axis (the axis that runs along the side of the floating element).\n * Represents the distance between the floating element and the reference element.\n * @default 0\n */\n mainAxis?: number;\n\n /**\n * The offset along the cross axis (the axis that runs along the alignment of the floating element).\n * Represents the skidding between the floating element and the reference element.\n * @default 0\n */\n crossAxis?: number;\n\n /**\n * Same axis as crossAxis but applies only to aligned placements and inverts the end alignment.\n * When set to a number, it overrides the crossAxis value.\n * @default null\n */\n alignmentAxis?: number | null;\n}\n\n/**\n * Type representing all valid offset values.\n * Can be a number (applies to mainAxis) or an object with axis-specific offsets.\n */\nexport type NgpOffset = number | NgpOffsetOptions;\n\n/**\n * Input type for offset that also accepts string representations of numbers\n */\nexport type NgpOffsetInput = NgpOffset | string;\n\n/**\n * Transform function to coerce offset input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced offset value\n */\nexport function coerceOffset(value: NgpOffsetInput | null | undefined): NgpOffset {\n if (isNil(value)) {\n return 0;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Use CDK's coerceNumberProperty for consistent number coercion\n // This handles strings, numbers, and other input types just like Angular CDK inputs\n return coerceNumberProperty(value, 0);\n}\n","import { Injectable, WritableSignal } from '@angular/core';\n\n/** Interface for overlays that can be closed immediately */\nexport interface CooldownOverlay {\n hideImmediate(): void;\n /** Optional signal to mark the transition as instant due to cooldown */\n instantTransition?: WritableSignal<boolean>;\n}\n\n/**\n * Singleton service that tracks close timestamps and active overlays per overlay type.\n * This enables the cooldown feature where quickly moving between triggers\n * of the same overlay type (e.g., tooltip to tooltip) shows the second\n * overlay immediately without the showDelay, and closes the first immediately.\n * @internal\n */\n@Injectable({ providedIn: 'root' })\nexport class NgpOverlayCooldownManager {\n private readonly lastCloseTimestamps = new Map<string, number>();\n private readonly activeOverlays = new Map<string, CooldownOverlay>();\n\n /**\n * Record the close timestamp for an overlay type.\n * @param overlayType The type identifier for the overlay group\n */\n recordClose(overlayType: string): void {\n this.lastCloseTimestamps.set(overlayType, Date.now());\n }\n\n /**\n * Check if the overlay type is within its cooldown period.\n * @param overlayType The type identifier for the overlay group\n * @param duration The cooldown duration in milliseconds\n * @returns true if within cooldown period, false otherwise\n */\n isWithinCooldown(overlayType: string, duration: number): boolean {\n const lastClose = this.lastCloseTimestamps.get(overlayType);\n if (lastClose === undefined) {\n return false;\n }\n return Date.now() - lastClose < duration;\n }\n\n /**\n * Register an overlay as active for its type.\n * Any existing overlay of the same type will be closed immediately.\n * @param overlayType The type identifier for the overlay group\n * @param overlay The overlay instance\n * @param cooldown The cooldown duration - if > 0, enables instant transitions\n */\n registerActive(overlayType: string, overlay: CooldownOverlay, cooldown: number): void {\n const existing = this.activeOverlays.get(overlayType);\n\n // If there's an existing overlay and cooldown is enabled, close it immediately.\n // This ensures instant DOM swap when hovering between items of the same type.\n if (existing && existing !== overlay && cooldown > 0) {\n existing.instantTransition?.set(true);\n existing.hideImmediate();\n }\n\n this.activeOverlays.set(overlayType, overlay);\n }\n\n /**\n * Unregister an overlay when it closes.\n * @param overlayType The type identifier for the overlay group\n * @param overlay The overlay instance to remove\n */\n unregisterActive(overlayType: string, overlay: CooldownOverlay): void {\n if (this.activeOverlays.get(overlayType) === overlay) {\n this.activeOverlays.delete(overlayType);\n }\n }\n\n /**\n * Check if there's an active overlay of the given type.\n * @param overlayType The type identifier for the overlay group\n * @returns true if there's an active overlay, false otherwise\n */\n hasActiveOverlay(overlayType: string): boolean {\n return this.activeOverlays.has(overlayType);\n }\n}\n","import { inject, InjectionToken, Signal, ValueProvider } from '@angular/core';\n\nconst NgpOverlayContextToken = new InjectionToken<unknown>('NgpOverlayContextToken');\n\n/**\n * Injects the context for the overlay.\n * @internal\n */\nexport function injectOverlayContext<T>(): Signal<T> {\n return inject(NgpOverlayContextToken) as Signal<T>;\n}\n\n/**\n * Provides the context for the overlay.\n * @param value The value to provide as the context.\n * @internal\n */\nexport function provideOverlayContext<T>(value: Signal<T | undefined> | undefined): ValueProvider {\n return { provide: NgpOverlayContextToken, useValue: value };\n}\n","import { VERSION } from '@angular/cdk';\nimport { ComponentPortal, DomPortalOutlet, TemplatePortal } from '@angular/cdk/portal';\nimport {\n ApplicationRef,\n ComponentRef,\n EmbeddedViewRef,\n Injector,\n TemplateRef,\n Type,\n ViewContainerRef,\n} from '@angular/core';\nimport { NgpExitAnimationRef, setupExitAnimation } from 'ng-primitives/internal';\n\nexport interface NgpPortalAttachOptions {\n /** If true, skip enter animation delay and set enter state immediately. */\n immediate?: boolean;\n}\n\nexport abstract class NgpPortal {\n constructor(\n protected readonly viewContainerRef: ViewContainerRef | null,\n protected readonly injector: Injector,\n ) {}\n\n /**\n * Get the elements of the portal.\n */\n abstract getElements(): HTMLElement[];\n\n /**\n * Detect changes in the portal.\n */\n abstract detectChanges(): void;\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n abstract getAttached(): boolean;\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n abstract attach(container: HTMLElement, options?: NgpPortalAttachOptions): this;\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n abstract detach(immediate?: boolean): Promise<void>;\n\n /**\n * Cancel an in-progress detach operation. If exit animations are running,\n * they are cancelled and the portal transitions back to the enter state.\n */\n abstract cancelDetach(): void;\n\n /**\n * Angular v20 removes `_unusedComponentFactoryResolver` and `_document` from DomPortalOutlet's\n * constructor signature as they have been deprecated since v18, and replaced with optional\n * `_appRef` and `_defaultInjector` params.\n * This temporary change ensures consistent behaviour for consumers using ng v20+.\n * @see {@link https://github.com/angular/components/pull/24504 The implementing PR} for the new implementation.\n * @see {@link https://github.com/angular/components/blob/732a0d7ab69ec25925cc06a0fb17b0fb16a4b0ae/src/cdk/portal/dom-portal-outlet.ts#L27 The latest v20 version comments}\n * describe the importance of passing the `_appRef` and `_defaultInjector` when it comes to component portals\n */\n // todo: remove this compat fix once support for v19 is dropped when v21 is released\n // - should aim to add appRef also to prevent unforeseen issues in certain edge cases\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected _getDomPortalOutletCtorParamsCompat(): (ApplicationRef | Injector | undefined | any)[] {\n return Number(VERSION.major) >= 20 ? [this.injector] : [undefined, this.injector];\n }\n}\n\nexport class NgpComponentPortal<T> extends NgpPortal {\n private readonly componentPortal: ComponentPortal<T>;\n private viewRef: ComponentRef<T> | null = null;\n private isDestroying = false;\n private detachCancelled = false;\n private exitAnimationRef: NgpExitAnimationRef | null = null;\n\n constructor(component: Type<T>, viewContainerRef: ViewContainerRef | null, injector: Injector) {\n super(viewContainerRef, injector);\n this.componentPortal = new ComponentPortal(component, viewContainerRef, injector);\n }\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n attach(container: HTMLElement, options?: NgpPortalAttachOptions): this {\n const appRef = this.injector.get(ApplicationRef);\n const domOutlet =\n Number(VERSION.major) >= 20\n ? new DomPortalOutlet(container, appRef, this.injector)\n : // @ts-expect-error: Compatibility for Angular versions < 20\n new DomPortalOutlet(container, undefined, appRef, this.injector);\n\n this.viewRef = domOutlet.attach(this.componentPortal);\n\n const element = this.viewRef.location.nativeElement as HTMLElement;\n\n this.exitAnimationRef = setupExitAnimation({ element, immediate: options?.immediate });\n\n return this;\n }\n\n /**\n * Get the root elements of the portal.\n */\n getElements(): HTMLElement[] {\n return this.viewRef ? [this.viewRef.location.nativeElement] : [];\n }\n\n /**\n * Detect changes in the portal.\n */\n detectChanges(): void {\n this.viewRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n getAttached(): boolean {\n return !!this.viewRef && (this.viewRef.location.nativeElement as HTMLElement).isConnected;\n }\n\n /**\n * Cancel an in-progress detach operation.\n */\n cancelDetach(): void {\n if (this.isDestroying) {\n this.detachCancelled = true;\n this.exitAnimationRef?.cancel();\n this.isDestroying = false;\n }\n }\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n async detach(immediate?: boolean): Promise<void> {\n if (this.isDestroying) {\n return;\n }\n this.isDestroying = true;\n this.detachCancelled = false;\n\n // Only wait for exit animation if not immediate\n if (!immediate) {\n await this.exitAnimationRef?.exit();\n }\n\n // If cancelled during exit animation, don't destroy\n if (this.detachCancelled) {\n this.detachCancelled = false;\n return;\n }\n\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n}\n\nexport class NgpTemplatePortal<T> extends NgpPortal {\n private readonly templatePortal: TemplatePortal<T>;\n private viewRef: EmbeddedViewRef<T> | null = null;\n private exitAnimationRefs: NgpExitAnimationRef[] = [];\n private isDestroying = false;\n private detachCancelled = false;\n\n constructor(\n template: TemplateRef<T>,\n viewContainerRef: ViewContainerRef,\n injector: Injector,\n context?: T,\n ) {\n super(viewContainerRef, injector);\n this.templatePortal = new TemplatePortal(template, viewContainerRef, context, injector);\n }\n\n /**\n * Attach the portal to a DOM element.\n * @param container The DOM element to attach the portal to.\n * @param options Optional attach configuration\n */\n attach(container: HTMLElement, options?: NgpPortalAttachOptions): this {\n const domOutlet = new DomPortalOutlet(\n container,\n undefined,\n ...this._getDomPortalOutletCtorParamsCompat(),\n );\n this.viewRef = domOutlet.attach(this.templatePortal);\n\n for (const rootNode of this.viewRef.rootNodes) {\n if (rootNode instanceof HTMLElement) {\n // Setup exit animation for each root node\n const exitAnimationRef = setupExitAnimation({\n element: rootNode,\n immediate: options?.immediate,\n });\n this.exitAnimationRefs.push(exitAnimationRef);\n }\n }\n\n return this;\n }\n\n /**\n * Get the root elements of the portal.\n */\n getElements(): HTMLElement[] {\n return this.viewRef ? this.viewRef.rootNodes : [];\n }\n\n /**\n * Detect changes in the portal.\n */\n detectChanges(): void {\n this.viewRef?.detectChanges();\n }\n\n /**\n * Whether the portal is attached to a DOM element.\n */\n getAttached(): boolean {\n return !!this.viewRef && this.viewRef.rootNodes.length > 0;\n }\n\n /**\n * Cancel an in-progress detach operation.\n */\n cancelDetach(): void {\n if (this.isDestroying) {\n this.detachCancelled = true;\n for (const ref of this.exitAnimationRefs) {\n ref.cancel();\n }\n this.isDestroying = false;\n }\n }\n\n /**\n * Detach the portal from the DOM.\n * @param immediate If true, skip exit animations and remove immediately\n */\n async detach(immediate?: boolean): Promise<void> {\n if (this.isDestroying) {\n return;\n }\n\n this.isDestroying = true;\n this.detachCancelled = false;\n\n // Only wait for exit animations if not immediate\n if (!immediate) {\n await Promise.all(this.exitAnimationRefs.map(ref => ref.exit()));\n }\n\n // If cancelled during exit animation, don't destroy\n if (this.detachCancelled) {\n this.detachCancelled = false;\n return;\n }\n\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n}\n\nexport function createPortal<T>(\n componentOrTemplate: Type<T> | TemplateRef<T>,\n viewContainerRef: ViewContainerRef | null,\n injector: Injector,\n context?: T,\n): NgpPortal {\n if (componentOrTemplate instanceof TemplateRef) {\n if (!viewContainerRef) {\n throw new Error('A ViewContainerRef is required to create a TemplatePortal.');\n }\n\n return new NgpTemplatePortal(componentOrTemplate, viewContainerRef, injector, context);\n } else {\n return new NgpComponentPortal(componentOrTemplate, viewContainerRef, injector);\n }\n}\n","/**\n * This code is largely based on the CDK Overlay's scroll strategy implementation, however it\n * has been modified so that it does not rely on the CDK's global overlay styles.\n */\nimport { coerceCssPixelValue } from '@angular/cdk/coercion';\nimport { ViewportRuler } from '@angular/cdk/overlay';\nimport { getOverflowAncestors } from '@floating-ui/dom';\nimport { isFunction, isObject } from 'ng-primitives/utils';\n\nexport interface ScrollStrategy {\n enable(): void;\n disable(): void;\n}\n\n/** Cached result of the check that indicates whether the browser supports scroll behaviors. */\nlet scrollBehaviorSupported: boolean | undefined;\n\nexport function supportsScrollBehavior(): boolean {\n if (scrollBehaviorSupported != null) {\n return scrollBehaviorSupported;\n }\n\n // If we're not in the browser, it can't be supported. Also check for `Element`, because\n // some projects stub out the global `document` during SSR which can throw us off.\n if (!isObject(document) || !document || !isFunction(Element) || !Element) {\n return (scrollBehaviorSupported = false);\n }\n\n // If the element can have a `scrollBehavior` style, we can be sure that it's supported.\n if ('scrollBehavior' in document.documentElement!.style) {\n return (scrollBehaviorSupported = true);\n }\n\n // Check if scrollTo is supported and if it's been polyfilled\n const scrollToFunction = Element.prototype.scrollTo;\n if (!scrollToFunction) {\n return (scrollBehaviorSupported = false);\n }\n\n // We can detect if the function has been polyfilled by calling `toString` on it. Native\n // functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get\n // the actual function source. Via https://davidwalsh.name/detect-native-function. Consider\n // polyfilled functions as supporting scroll behavior.\n return (scrollBehaviorSupported = !/\\{\\s*\\[native code\\]\\s*\\}/.test(scrollToFunction.toString()));\n}\n\ninterface HTMLStyles {\n top: string;\n left: string;\n position: string;\n overflowY: string;\n width: string;\n}\n\nexport class BlockScrollStrategy implements ScrollStrategy {\n private readonly previousHTMLStyles: HTMLStyles = {\n top: '',\n left: '',\n position: '',\n overflowY: '',\n width: '',\n };\n private previousScrollPosition = { top: 0, left: 0 };\n private isEnabled = false;\n\n constructor(\n private readonly viewportRuler: ViewportRuler,\n private readonly document: Document,\n ) {}\n\n /** Blocks page-level scroll while the attached overlay is open. */\n enable() {\n if (this.canBeEnabled()) {\n const root = this.document.documentElement!;\n\n this.previousScrollPosition = this.viewportRuler.getViewportScrollPosition();\n\n // Cache the previous inline styles in case the user had set them.\n this.previousHTMLStyles.left = root.style.left || '';\n this.previousHTMLStyles.top = root.style.top || '';\n this.previousHTMLStyles.position = root.style.position || '';\n this.previousHTMLStyles.overflowY = root.style.overflowY || '';\n this.previousHTMLStyles.width = root.style.width || '';\n\n // Set the styles to block scrolling.\n root.style.position = 'fixed';\n\n // Necessary for the content not to lose its width. Note that we're using 100%, instead of\n // 100vw, because 100vw includes the width plus the scrollbar, whereas 100% is the width\n // that the element had before we made it `fixed`.\n root.style.width = '100%';\n\n // Note: this will always add a scrollbar to whatever element it is on, which can\n // potentially result in double scrollbars. It shouldn't be an issue, because we won't\n // block scrolling on a page that doesn't have a scrollbar in the first place.\n root.style.overflowY = 'scroll';\n\n // Note: we're using the `html` node, instead of the `body`, because the `body` may\n // have the user agent margin, whereas the `html` is guaranteed not to have one.\n root.style.left = coerceCssPixelValue(-this.previousScrollPosition.left);\n root.style.top = coerceCssPixelValue(-this.previousScrollPosition.top);\n root.setAttribute('data-scrollblock', '');\n this.isEnabled = true;\n }\n }\n\n /** Unblocks page-level scroll while the attached overlay is open. */\n disable(): void {\n if (this.isEnabled) {\n const html = this.document.documentElement!;\n const body = this.document.body!;\n const htmlStyle = html.style;\n const bodyStyle = body.style;\n const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';\n const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';\n\n this.isEnabled = false;\n\n htmlStyle.left = this.previousHTMLStyles.left;\n htmlStyle.top = this.previousHTMLStyles.top;\n htmlStyle.position = this.previousHTMLStyles.position;\n htmlStyle.overflowY = this.previousHTMLStyles.overflowY;\n htmlStyle.width = this.previousHTMLStyles.width;\n html.removeAttribute('data-scrollblock');\n\n // Disable user-defined smooth scrolling temporarily while we restore the scroll position.\n // See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior\n // Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,\n // because it can throw off feature detections in `supportsScrollBehavior` which\n // checks for `'scrollBehavior' in documentElement.style`.\n if (scrollBehaviorSupported) {\n htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';\n }\n\n window.scroll(this.previousScrollPosition.left, this.previousScrollPosition.top);\n\n if (scrollBehaviorSupported) {\n htmlStyle.scrollBehavior = previousHtmlScrollBehavior;\n bodyStyle.scrollBehavior = previousBodyScrollBehavior;\n }\n }\n }\n\n private canBeEnabled(): boolean {\n // Since the scroll strategies can't be singletons, we have to use a global CSS class\n // (`cdk-global-scrollblock`) to make sure that we don't try to disable global\n // scrolling multiple times.\n const html = this.document.documentElement!;\n\n if (html.classList.contains('cdk-global-scrollblock') || this.isEnabled) {\n return false;\n }\n\n const viewport = this.viewportRuler.getViewportSize();\n return html.scrollHeight > viewport.height || html.scrollWidth > viewport.width;\n }\n}\n\nexport class CloseScrollStrategy implements ScrollStrategy {\n private cleanups: (() => void)[] = [];\n\n constructor(\n private readonly triggerElement: HTMLElement,\n private readonly onClose: () => void,\n private readonly overlayElements: () => HTMLElement[],\n ) {}\n\n enable(): void {\n // Guard against double-enable: remove any existing listeners first\n this.disable();\n\n const ancestors = getOverflowAncestors(this.triggerElement);\n\n const handler = (event: Event) => {\n const target = event.target;\n\n // Don't close if the scroll happened inside the overlay\n if (target instanceof Node) {\n const elements = this.overlayElements();\n if (elements.some(el => el.contains(target))) {\n return;\n }\n }\n\n // Stop listening immediately to prevent redundant close calls from rapid scroll events\n this.disable();\n this.onClose();\n };\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', handler, { passive: true });\n this.cleanups.push(() => ancestor.removeEventListener('scroll', handler));\n }\n }\n\n disable(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups = [];\n }\n}\n\nexport class NoopScrollStrategy implements ScrollStrategy {\n enable(): void {\n // No operation for enabling\n }\n\n disable(): void {\n // No operation for disabling\n }\n}\n","import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\nimport { ViewportRuler } from '@angular/cdk/overlay';\nimport { DOCUMENT } from '@angular/common';\nimport {\n DestroyRef,\n Injector,\n Provider,\n Signal,\n TemplateRef,\n Type,\n ViewContainerRef,\n computed,\n inject,\n runInInjectionContext,\n signal,\n} from '@angular/core';\nimport { ControlContainer } from '@angular/forms';\nimport {\n Middleware,\n Placement,\n Strategy,\n VirtualElement,\n arrow,\n autoUpdate,\n computePosition,\n flip,\n offset,\n shift,\n size,\n} from '@floating-ui/dom';\nimport { explicitEffect, fromResizeEvent } from 'ng-primitives/internal';\nimport { injectDisposables, safeTakeUntilDestroyed, uniqueId } from 'ng-primitives/utils';\nimport { Subject, fromEvent } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { NgpFlip } from './flip';\nimport { NgpOffset } from './offset';\nimport { CooldownOverlay, NgpOverlayCooldownManager } from './overlay-cooldown';\nimport { provideOverlayContext } from './overlay-token';\nimport { NgpPortal, createPortal } from './portal';\nimport { NgpPosition } from './position';\nimport {\n BlockScrollStrategy,\n CloseScrollStrategy,\n NoopScrollStrategy,\n ScrollStrategy,\n} from './scroll-strategy';\nimport { NgpShift } from './shift';\n\n/**\n * Bit value of the internal `SkipSelf` inject flag used by Angular's DI system.\n * This value is part of Angular's ABI and is stable across versions 19+.\n * @see InjectFlags.SkipSelf / InternalInjectFlags.SkipSelf\n */\nconst SKIP_SELF_FLAG = 4;\n\n/** Check whether the given inject flags include `SkipSelf`. */\nfunction hasSkipSelfFlag(flags: unknown): boolean {\n if (typeof flags === 'number') {\n return (flags & SKIP_SELF_FLAG) !== 0;\n }\n if (flags != null && typeof flags === 'object' && 'skipSelf' in flags) {\n return !!(flags as { skipSelf: unknown }).skipSelf;\n }\n return false;\n}\n\n/**\n * An injector wrapper that intercepts `ControlContainer` lookups carrying the\n * `SkipSelf` flag and short-circuits them to `notFoundValue`.\n *\n * ## Why this is needed\n *\n * Angular's `lookupTokenUsingEmbeddedInjector` passes the original inject flags\n * to the embedded view injector's `.get()` call. For directives that use\n * `@Host() @SkipSelf()` (e.g. `FormControlName`, `FormGroupName`):\n *\n * - **Without this wrapper**: `R3Injector.get()` honors `SkipSelf` by skipping\n * its own `ControlContainer: null` record and delegates to the parent injector\n * (the trigger element's injector), which may find the **outer** form's\n * `ControlContainer` — leaking the wrong form context into child components.\n *\n * - **If we stripped SkipSelf entirely**: `R3Injector` would find its own\n * `ControlContainer: null` and return `null`. But this `null` is returned\n * for ALL `ControlContainer` lookups within the portaled view, killing child\n * components' own `FormGroupDirective` resolution (NG01050).\n *\n * ## The fix\n *\n * For `ControlContainer` + `SkipSelf`, return `notFoundValue` directly. This\n * causes `lookupTokenUsingEmbeddedInjector` to skip this boundary and eventually\n * return `NOT_FOUND`, letting `lookupTokenUsingNodeInjector` run — which correctly\n * finds the child component's own `FormGroupDirective` via the element injector chain.\n *\n * For `ControlContainer` without `SkipSelf` (e.g. `NgModel` uses `@Host()` only),\n * delegation proceeds normally and finds `ControlContainer: null`, preventing the\n * outer form from leaking.\n *\n * @see https://github.com/angular/angular/issues/57390\n * @see https://github.com/ng-primitives/ng-primitives/issues/677\n * @internal\n */\nclass EmbeddedViewInjector extends Injector {\n constructor(private readonly delegate: Injector) {\n super();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(token: any, notFoundValue?: any, flags?: any): any {\n if (token === ControlContainer && hasSkipSelfFlag(flags)) {\n return notFoundValue;\n }\n return this.delegate.get(token, notFoundValue, flags);\n }\n}\n\n/**\n * Configuration options for creating an overlay\n * @internal\n */\nexport interface NgpOverlayConfig<T = unknown> {\n /** Content to display in the overlay (component or template) */\n content: NgpOverlayContent<T>;\n\n /** The element that triggers the overlay */\n triggerElement: HTMLElement;\n\n /** The element to use for positioning the overlay (if different from trigger) */\n anchorElement?: HTMLElement | null;\n\n /** The injector to use for creating the portal */\n injector: Injector;\n /** ViewContainerRef to use for creating the portal */\n viewContainerRef: ViewContainerRef;\n\n /** Context data to pass to the overlay content */\n context?: Signal<T | undefined>;\n\n /** Container element or selector to attach the overlay to (defaults to document.body) */\n container?: HTMLElement | string | null;\n\n /** Preferred placement of the overlay relative to the trigger. */\n placement?: Signal<Placement>;\n\n /** Offset distance between the overlay and trigger. Can be a number or an object with axis-specific offsets */\n offset?: NgpOffset;\n\n /** Shift configuration to keep the overlay in view. Can be a boolean, an object with options, or undefined */\n shift?: NgpShift;\n\n /** Whether to enable flip behavior when space is limited, or an object with flip options */\n flip?: NgpFlip;\n\n /** Delay before showing the overlay in milliseconds */\n showDelay?: number;\n\n /** Delay before hiding the overlay in milliseconds */\n hideDelay?: number;\n\n /** Whether the overlay should be positioned with fixed or absolute strategy */\n strategy?: Strategy;\n\n /** The scroll strategy to use for the overlay */\n scrollBehaviour?: 'reposition' | 'block' | 'close';\n /** Whether to close the overlay when clicking outside */\n closeOnOutsideClick?: boolean;\n /** Whether to close the overlay when pressing escape */\n closeOnEscape?: boolean;\n /**\n * Whether to restore focus to the trigger element when hiding the overlay.\n * Can be a boolean or a signal that returns a boolean.\n */\n restoreFocus?: boolean | Signal<boolean>;\n\n /**\n * Optional callback to update an external close origin signal.\n * Called when the overlay is hidden with the focus origin.\n * @internal\n */\n onClose?: (origin: FocusOrigin) => void;\n /** Additional middleware for floating UI positioning */\n additionalMiddleware?: Middleware[];\n\n /** Additional providers */\n providers?: Provider[];\n\n /** Whether to track the trigger element position on every animation frame. Useful for moving elements like slider thumbs. */\n trackPosition?: boolean;\n\n /**\n * Programmatic position for the overlay. When provided, the overlay will be positioned\n * at these coordinates instead of anchoring to the trigger element.\n * Use with trackPosition for smooth cursor following.\n */\n position?: Signal<NgpPosition | null>;\n\n /**\n * Overlay type identifier for cooldown grouping.\n * When set, overlays of the same type share a cooldown period.\n * For example, 'tooltip' ensures quickly moving between tooltips shows\n * the second one immediately without the showDelay.\n */\n overlayType?: string;\n\n /**\n * Cooldown duration in milliseconds.\n * When moving from one overlay of the same type to another within this duration,\n * the showDelay is skipped for the new overlay.\n * @default 300\n */\n cooldown?: number;\n}\n\n/** Type for overlay content which can be either a template or component */\nexport type NgpOverlayContent<T> = TemplateRef<NgpOverlayTemplateContext<T>> | Type<unknown>;\n\n/** Context for template-based overlays */\nexport type NgpOverlayTemplateContext<T> = {\n $implicit: T;\n};\n\n/**\n * NgpOverlay manages the lifecycle and positioning of overlay UI elements.\n * It abstracts the common behavior shared by tooltips, popovers, menus, etc.\n * @internal\n */\nexport class NgpOverlay<T = unknown> implements CooldownOverlay {\n private readonly disposables = injectDisposables();\n private readonly document = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n private readonly viewContainerRef: ViewContainerRef;\n private readonly viewportRuler = inject(ViewportRuler);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly cooldownManager = inject(NgpOverlayCooldownManager);\n /** Access any parent overlays */\n private readonly parentOverlay = inject(NgpOverlay, { optional: true });\n /** Track child overlays for outside click detection */\n private readonly childOverlays = new Set<NgpOverlay>();\n /** Signal tracking the portal instance */\n private readonly portal = signal<NgpPortal | null>(null);\n\n /** Signal tracking the overlay position */\n readonly position = signal<{ x: number | undefined; y: number | undefined }>({\n x: undefined,\n y: undefined,\n });\n\n /**\n * Determine if the overlay has been positioned\n * @internal\n */\n readonly isPositioned = computed(\n () => this.position().x !== undefined && this.position().y !== undefined,\n );\n\n /** Signal tracking the trigger element width */\n readonly triggerWidth = signal<number | null>(null);\n\n /** The transform origin for the overlay */\n readonly transformOrigin = signal<string>('center center');\n\n /** Signal tracking the available width before the overlay overflows the viewport */\n readonly availableWidth = signal<number | null>(null);\n\n /** Signal tracking the available height before the overlay overflows the viewport */\n readonly availableHeight = signal<number | null>(null);\n\n /** Signal tracking the final placement of the overlay */\n readonly finalPlacement = signal<Placement | undefined>(undefined);\n\n /** Function to dispose the positioning auto-update */\n private disposePositioning?: () => void;\n\n /** Timeout handle for showing the overlay */\n private openTimeout?: () => void;\n\n /** Timeout handle for hiding the overlay */\n private closeTimeout?: () => void;\n\n /** Portal currently being destroyed (for cancel support during exit animations) */\n private destroyingPortal: NgpPortal | null = null;\n\n /** Signal tracking whether the overlay is open */\n readonly isOpen = signal(false);\n\n /** A unique id for the overlay */\n readonly id = signal<string>(uniqueId('ngp-overlay'));\n\n /**\n * Signal tracking the focus origin used to close the overlay.\n * Updated when hide() is called.\n * @internal\n */\n readonly closeOrigin = signal<FocusOrigin>('program');\n\n /** The aria-describedby attribute for accessibility */\n readonly ariaDescribedBy = computed(() => (this.isOpen() ? this.id() : undefined));\n\n /** The scroll strategy */\n private scrollStrategy = new NoopScrollStrategy();\n\n /** An observable that emits when the overlay is closing */\n readonly closing = new Subject<void>();\n\n /**\n * Signal tracking whether the current transition is instant due to cooldown.\n * When true, CSS can skip animations using the data-instant attribute.\n */\n readonly instantTransition = signal(false);\n\n /** Store the arrow element */\n private arrowElement: HTMLElement | null = null;\n\n /** Store the arrow padding signal */\n private arrowPadding: Signal<number | undefined> | undefined = undefined;\n\n /** @internal The position of the arrow */\n readonly arrowPosition = signal<{ x: number | undefined; y: number | undefined }>({\n x: undefined,\n y: undefined,\n });\n\n /**\n * Creates a new overlay instance\n * @param config Initial configuration for the overlay\n * @param destroyRef Reference for automatic cleanup\n */\n constructor(private config: NgpOverlayConfig<T>) {\n // we cannot inject the viewContainerRef as this can throw an error during hydration in SSR\n this.viewContainerRef = config.viewContainerRef;\n\n // Listen for placement signal changes to update position\n if (config.placement) {\n explicitEffect([config.placement], () => this.updatePosition());\n }\n\n // Listen for position signal changes to update position\n if (config.position) {\n explicitEffect([config.position], () => this.updatePosition());\n }\n\n // this must be done after the config is set\n this.transformOrigin.set(this.getTransformOrigin());\n\n // Monitor trigger element resize\n const elementToMonitor = this.config.anchorElement || this.config.triggerElement;\n fromResizeEvent(elementToMonitor)\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(({ width, height }) => {\n this.triggerWidth.set(width);\n\n // if the element has been hidden, hide immediately\n if (width === 0 || height === 0) {\n this.hideImmediate();\n }\n });\n\n // Register with parent overlay for outside click detection\n if (this.parentOverlay) {\n this.parentOverlay.registerChildOverlay(this);\n }\n\n // if there is a parent overlay and it is closed, close this overlay\n this.parentOverlay?.closing\n // we add a debounce here to ensure any dom events like clicks are processed first\n .pipe(debounceTime(0), safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (this.isOpen()) {\n this.hideImmediate();\n }\n });\n\n // If closeOnOutsideClick is enabled, set up a click listener\n fromEvent<MouseEvent>(this.document, 'mouseup', { capture: true })\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (!this.config.closeOnOutsideClick) {\n return;\n }\n\n const overlay = this.portal();\n\n if (!overlay || !this.isOpen()) {\n return;\n }\n\n const path = event.composedPath();\n const isInsideOverlay = overlay.getElements().some(el => path.includes(el));\n const isInsideTrigger = path.includes(this.config.triggerElement);\n const isInsideAnchor = this.config.anchorElement\n ? path.includes(this.config.anchorElement)\n : false;\n\n if (\n !isInsideOverlay &&\n !isInsideTrigger &&\n !isInsideAnchor &&\n !this.isInsideChildOverlay(path)\n ) {\n this.hide();\n }\n });\n\n // If closeOnEscape is enabled, set up a keydown listener\n fromEvent<KeyboardEvent>(this.document, 'keydown', { capture: true })\n .pipe(safeTakeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (!this.config.closeOnEscape) return;\n if (event.key === 'Escape' && this.isOpen()) {\n this.hide({ origin: 'keyboard', immediate: true });\n }\n });\n\n // Ensure cleanup on destroy\n this.destroyRef.onDestroy(() => {\n this.parentOverlay?.unregisterChildOverlay(this);\n this.destroy();\n });\n }\n\n /**\n * Show the overlay with the specified delay\n * @param options Optional options for showing the overlay\n */\n show(options?: { skipCooldown?: boolean }): Promise<void> {\n return new Promise<void>(resolve => {\n // If closing is in progress, cancel it\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n // If destruction is in progress (exit animation running), cancel it\n // and reuse the existing overlay instead of creating a new one.\n if (this.destroyingPortal) {\n this.cancelDestruction();\n resolve();\n return;\n }\n\n // Don't proceed if already opening or open\n if (this.openTimeout || this.isOpen()) {\n return;\n }\n\n // Use the provided delay or fall back to config\n let delay = this.config.showDelay ?? 0;\n let isInstantDueToCooldown = false;\n\n // Check cooldown regardless of delay value - we need to detect instant transitions\n // even when showDelay is 0, so CSS can skip animations via data-instant attribute.\n // However, if cooldown is explicitly set to 0, disable cooldown behavior entirely.\n // Skip cooldown detection entirely when skipCooldown is true (e.g. programmatic show).\n if (!options?.skipCooldown && this.config.overlayType) {\n const cooldownDuration = this.config.cooldown ?? 300;\n if (\n cooldownDuration > 0 &&\n (this.cooldownManager.isWithinCooldown(this.config.overlayType, cooldownDuration) ||\n this.cooldownManager.hasActiveOverlay(this.config.overlayType))\n ) {\n delay = 0; // Skip delay (no-op if already 0)\n isInstantDueToCooldown = true;\n }\n }\n\n // Set instant transition flag based on whether delay was skipped due to cooldown\n this.instantTransition.set(isInstantDueToCooldown);\n\n this.openTimeout = this.disposables.setTimeout(() => {\n this.openTimeout = undefined;\n this.createOverlay(options?.skipCooldown);\n resolve();\n }, delay);\n });\n }\n\n /**\n * Stop any pending close operation. This is useful for example, if we move the mouse from the tooltip trigger to the tooltip itself.\n * This will prevent the tooltip from closing immediately when the mouse leaves the trigger.\n * @internal\n */\n cancelPendingClose(): void {\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n // Also cancel in-progress destruction (exit animation running)\n if (this.destroyingPortal) {\n this.cancelDestruction();\n }\n }\n\n /**\n * Cancel an in-progress overlay destruction. This cancels exit animations,\n * restores the portal, and re-enables positioning and scroll strategy.\n * Used when show() or cancelPendingClose() is called during exit animation.\n */\n private cancelDestruction(): void {\n const portal = this.destroyingPortal;\n if (!portal) {\n return;\n }\n\n this.destroyingPortal = null;\n portal.cancelDetach();\n\n // Restore the portal\n this.portal.set(portal);\n\n // Re-setup positioning\n const elements = portal.getElements();\n const outletElement = elements.find(el => el.hasAttribute('data-overlay')) ?? elements[0];\n if (outletElement) {\n this.setupPositioning(outletElement);\n }\n\n // Re-enable scroll strategy\n this.scrollStrategy = this.createScrollStrategy();\n this.scrollStrategy.enable();\n\n // Re-register with cooldown if needed\n if (this.config.overlayType) {\n this.cooldownManager.registerActive(this.config.overlayType, this, this.config.cooldown ?? 0);\n }\n }\n\n /**\n * Hide the overlay with the specified delay\n * @param options Optional options for hiding the overlay\n */\n hide(options?: OverlayTriggerOptions): void {\n // If opening is in progress, cancel it\n if (this.openTimeout) {\n this.openTimeout();\n this.openTimeout = undefined;\n }\n\n // Don't proceed if already closing or closed unless immediate is true\n if ((this.closeTimeout && !options?.immediate) || !this.isOpen()) {\n return;\n }\n\n // If immediate and there's a pending close, cancel it first\n // (we'll dispose immediately instead of waiting for the old timeout)\n if (options?.immediate && this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n this.closing.next();\n\n // Check cooldown BEFORE recording, then record for the next overlay\n let delay = this.config.hideDelay ?? 0;\n if (this.config.overlayType) {\n // Skip delay if within cooldown period for this overlay type\n if (delay > 0) {\n const cooldownDuration = this.config.cooldown ?? 300;\n if (this.cooldownManager.isWithinCooldown(this.config.overlayType, cooldownDuration)) {\n delay = 0;\n }\n }\n // Record close timestamp so the next overlay of the same type can see it\n this.cooldownManager.recordClose(this.config.overlayType);\n }\n\n const dispose = async () => {\n this.closeTimeout = undefined;\n\n // If show() was called while we were waiting, abort the close\n if (this.openTimeout) {\n return;\n }\n\n const origin = options?.origin ?? 'program';\n\n // Update the close origin signal so computed signals can react\n this.closeOrigin.set(origin);\n\n // Call the onClose callback if provided (for external signal updates)\n this.config.onClose?.(origin);\n\n // Determine if focus should be restored\n const shouldRestoreFocus =\n typeof this.config.restoreFocus === 'function'\n ? this.config.restoreFocus()\n : (this.config.restoreFocus ?? false);\n\n if (shouldRestoreFocus) {\n this.focusMonitor.focusVia(this.config.triggerElement, options?.origin ?? 'program', {\n preventScroll: true,\n });\n }\n\n await this.destroyOverlay();\n };\n\n if (options?.immediate) {\n // If immediate, dispose right away\n dispose();\n } else {\n // Reset instant transition for normal closes so exit animations can play.\n // When being replaced by another overlay during cooldown, hideImmediate()\n // is called instead (which doesn't come through here), and registerActive\n // sets instantTransition to true before that call.\n this.instantTransition.set(false);\n // Remove data-instant attribute so CSS exit animations can play\n for (const element of this.getElements()) {\n element.removeAttribute('data-instant');\n }\n this.closeTimeout = this.disposables.setTimeout(dispose, delay);\n }\n }\n\n /**\n * Update the configuration of this overlay\n * @param config New configuration (partial)\n */\n updateConfig(config: Partial<NgpOverlayConfig<T>>): void {\n this.config = { ...this.config, ...config };\n\n // If the overlay is already open, update its position\n if (this.isOpen()) {\n this.updatePosition();\n }\n }\n\n /**\n * Immediately hide the overlay without any delay.\n * When called during cooldown transitions, this destroys the overlay\n * immediately without exit animations.\n */\n hideImmediate(): void {\n // Cancel any pending operations\n if (this.openTimeout) {\n this.openTimeout();\n this.openTimeout = undefined;\n }\n if (this.closeTimeout) {\n this.closeTimeout();\n this.closeTimeout = undefined;\n }\n\n // Emit closing event\n this.closing.next();\n\n // Update close origin and call callback (default to 'program' for immediate closes)\n this.closeOrigin.set('program');\n this.config.onClose?.('program');\n\n // Destroy immediately without animations\n this.destroyOverlay(true);\n }\n\n /**\n * Toggle the overlay open/closed state\n */\n toggle(): void {\n if (this.isOpen()) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Force update the position of the overlay\n */\n updatePosition(): void {\n const portal = this.portal();\n\n if (!portal) {\n return;\n }\n\n const elements = portal.getElements();\n\n if (elements.length === 0) {\n return;\n }\n\n const overlayElement = elements[0] as HTMLElement;\n\n // Compute new position\n this.computePosition(overlayElement);\n }\n\n /**\n * Completely destroy this overlay instance\n */\n destroy(): void {\n this.hideImmediate();\n this.disposePositioning?.();\n this.scrollStrategy.disable();\n }\n\n /**\n * Get the elements of the overlay\n */\n getElements(): HTMLElement[] {\n return this.portal()?.getElements() ?? [];\n }\n\n /**\n * Register a child overlay for outside click detection.\n * @internal\n */\n registerChildOverlay(child: NgpOverlay): void {\n this.childOverlays.add(child);\n }\n\n /**\n * Unregister a child overlay.\n * @internal\n */\n unregisterChildOverlay(child: NgpOverlay): void {\n this.childOverlays.delete(child);\n }\n\n /**\n * Check if the event path includes any child overlay elements (recursively).\n * @internal\n */\n isInsideChildOverlay(path: EventTarget[]): boolean {\n for (const child of this.childOverlays) {\n const childElements = child.getElements();\n if (childElements.some(el => path.includes(el))) {\n return true;\n }\n if (child.isInsideChildOverlay(path)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal method to create the overlay\n * @param skipCooldown If true, skip registering with the cooldown manager\n */\n private createOverlay(skipCooldown?: boolean): void {\n if (!this.config.content) {\n throw new Error('Overlay content must be provided');\n }\n\n // Create a new portal with context.\n // The injector is wrapped in EmbeddedViewInjector to work around an Angular 19 bug\n // where @SkipSelf() causes the embedded view injector's ControlContainer: null to be\n // bypassed. See https://github.com/angular/angular/issues/57390\n const portal = createPortal(\n this.config.content,\n this.viewContainerRef,\n new EmbeddedViewInjector(\n Injector.create({\n parent: this.config.injector,\n providers: [\n ...(this.config.providers || []),\n { provide: NgpOverlay, useValue: this },\n provideOverlayContext<T>(this.config.context),\n { provide: ControlContainer, useValue: null },\n ],\n }),\n ),\n { $implicit: this.config.context } as NgpOverlayTemplateContext<T>,\n );\n\n // Attach portal to container (skip enter animation delay if instant transition)\n const container = this.resolveContainer();\n const isInstant = this.instantTransition();\n portal.attach(container, { immediate: isInstant });\n\n // Update portal signal\n this.portal.set(portal);\n\n // If instant transition is active, set data-instant attribute synchronously\n // so CSS can use it for styling purposes\n if (isInstant) {\n for (const element of portal.getElements()) {\n element.setAttribute('data-instant', '');\n }\n }\n\n // Ensure view is up to date\n portal.detectChanges();\n\n // find a dedicated outlet element\n // this is the element that has the `data-overlay` attribute\n // if no such element exists, we use the first element in the portal\n const outletElement =\n portal.getElements().find(el => el.hasAttribute('data-overlay')) ?? portal.getElements()[0];\n\n if (!outletElement) {\n throw new Error('Overlay element is not available.');\n }\n\n // Set up positioning\n this.setupPositioning(outletElement);\n\n // Mark as open\n this.isOpen.set(true);\n\n // Register as active overlay for this type (skip when cooldown is bypassed)\n if (this.config.overlayType && !skipCooldown) {\n this.cooldownManager.registerActive(this.config.overlayType, this, this.config.cooldown ?? 0);\n }\n\n this.scrollStrategy = this.createScrollStrategy();\n this.scrollStrategy.enable();\n }\n\n /**\n * Create the appropriate scroll strategy based on the configuration.\n */\n private createScrollStrategy(): ScrollStrategy {\n switch (this.config.scrollBehaviour) {\n case 'block':\n return new BlockScrollStrategy(this.viewportRuler, this.document);\n case 'close':\n return new CloseScrollStrategy(\n this.config.anchorElement || this.config.triggerElement,\n () => this.hide({ immediate: true }),\n () => this.getElements(),\n );\n default:\n return new NoopScrollStrategy();\n }\n }\n\n /**\n * Internal method to setup positioning of the overlay\n */\n private setupPositioning(overlayElement: HTMLElement): void {\n // Determine positioning strategy based on overlay element's CSS\n const strategy =\n getComputedStyle(overlayElement).position === 'fixed'\n ? 'fixed'\n : this.config.strategy || 'absolute';\n\n // Get the reference for auto-update - use trigger element for resize/scroll tracking\n // even when using programmatic position (the virtual element is created dynamically in computePosition)\n const referenceElement = this.config.anchorElement || this.config.triggerElement;\n\n // Setup auto-update for positioning\n this.disposePositioning = autoUpdate(\n referenceElement,\n overlayElement,\n () => this.computePosition(overlayElement, strategy),\n { animationFrame: this.config.trackPosition ?? false },\n );\n }\n\n /**\n * Compute the overlay position using floating-ui\n */\n private async computePosition(\n overlayElement: HTMLElement,\n strategy: Strategy = 'absolute',\n ): Promise<void> {\n // Create middleware array\n // Order matters: offset → flip → shift → size → arrow (per Floating UI docs)\n const middleware: Middleware[] = [offset(this.config.offset ?? 0)];\n\n // Add flip middleware if requested\n // Flip must come before shift so that shift doesn't prevent flip from triggering\n const flipConfig = this.config.flip;\n if (flipConfig !== false) {\n const flipOptions = flipConfig === undefined || flipConfig === true ? {} : flipConfig;\n middleware.push(flip(flipOptions));\n }\n\n // Add shift middleware (enabled by default for backward compatibility)\n // Shift keeps the overlay in view by shifting it along its axis when it would otherwise overflow the viewport\n const shiftConfig = this.config.shift;\n if (shiftConfig !== false) {\n const shiftOptions = shiftConfig === undefined || shiftConfig === true ? {} : shiftConfig;\n middleware.push(shift(shiftOptions));\n }\n\n // Add size middleware to expose available dimensions\n middleware.push(\n size({\n apply: ({ availableWidth, availableHeight }) => {\n this.availableWidth.set(availableWidth);\n this.availableHeight.set(availableHeight);\n },\n }),\n );\n\n // Add any additional middleware\n if (this.config.additionalMiddleware) {\n middleware.push(...this.config.additionalMiddleware);\n }\n\n // If the arrow element is registered, add arrow middleware\n if (this.arrowElement) {\n middleware.push(arrow({ element: this.arrowElement, padding: this.arrowPadding?.() }));\n }\n\n // Compute the position\n const placement = this.config.placement?.() ?? 'top';\n\n // Use programmatic position if provided, otherwise use anchor/trigger element\n const referenceElement = this.getPositionReference();\n\n const position = await computePosition(referenceElement, overlayElement, {\n placement,\n middleware,\n strategy,\n });\n\n // Update position signal\n this.position.set({ x: position.x, y: position.y });\n\n // Update final placement signal\n this.finalPlacement.set(position.placement);\n\n // Update arrow position if available\n if (this.arrowElement) {\n this.arrowPosition.set({\n x: position.middlewareData.arrow?.x,\n y: position.middlewareData.arrow?.y,\n });\n }\n\n // Ensure view is updated\n this.portal()?.detectChanges();\n }\n\n /**\n * Get the reference element for positioning. When a programmatic position is provided,\n * creates a virtual element at that position. Otherwise returns the anchor or trigger element.\n */\n private getPositionReference(): HTMLElement | VirtualElement {\n const pos = this.config.position?.();\n if (pos) {\n // Create virtual element that reads position fresh on each call\n return {\n getBoundingClientRect: () => {\n const currentPos = this.config.position?.() ?? pos;\n return new DOMRect(currentPos.x, currentPos.y, 0, 0);\n },\n contextElement: this.config.triggerElement,\n };\n }\n return this.config.anchorElement || this.config.triggerElement;\n }\n\n /**\n * Internal method to destroy the overlay portal\n * @param immediate If true, skip exit animations and remove immediately\n */\n private async destroyOverlay(immediate?: boolean): Promise<void> {\n const portal = this.portal();\n\n if (!portal) {\n return;\n }\n\n // Unregister from active overlays\n if (this.config.overlayType) {\n this.cooldownManager.unregisterActive(this.config.overlayType, this);\n }\n\n // Clear portal reference to prevent double destruction\n this.portal.set(null);\n\n // Clean up positioning\n this.disposePositioning?.();\n this.disposePositioning = undefined;\n\n // Track the destroying portal so cancelDestruction() can restore it\n // if show() is called during the exit animation.\n this.destroyingPortal = portal;\n\n // disable scroll strategy\n this.scrollStrategy.disable();\n this.scrollStrategy = new NoopScrollStrategy();\n\n // Detach the portal (waits for exit animations unless immediate).\n // During this await, cancelDestruction() may be called if the user\n // re-hovers the trigger. (See: https://github.com/ng-primitives/ng-primitives/issues/681)\n await portal.detach(immediate);\n\n // Only complete destruction if it was not cancelled during exit animation.\n // finalPlacement and instantTransition are intentionally cleared here\n // (not before the await) so they remain valid if destruction is cancelled.\n if (this.destroyingPortal === portal) {\n this.destroyingPortal = null;\n this.isOpen.set(false);\n this.finalPlacement.set(undefined);\n this.instantTransition.set(false);\n }\n }\n\n /**\n * Get the transform origin for the overlay\n */\n private getTransformOrigin(): string {\n const placement = this.config.placement?.() ?? 'top';\n const basePlacement = placement.split('-')[0]; // Extract \"top\", \"bottom\", etc.\n const alignment = placement.split('-')[1]; // Extract \"start\" or \"end\"\n\n const map: Record<string, string> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n };\n\n let x = 'center';\n let y = 'center';\n\n if (basePlacement === 'top' || basePlacement === 'bottom') {\n y = map[basePlacement];\n if (alignment === 'start') x = 'left';\n else if (alignment === 'end') x = 'right';\n } else {\n x = map[basePlacement];\n if (alignment === 'start') y = 'top';\n else if (alignment === 'end') y = 'bottom';\n }\n\n return `${y} ${x}`;\n }\n\n /**\n * Register the arrow element for positioning\n * @param arrowElement The arrow element\n * @param padding Optional padding signal between the arrow and the edges of the floating element\n * @internal\n */\n registerArrow(arrowElement: HTMLElement | null, padding?: Signal<number | undefined>): void {\n this.arrowElement = arrowElement;\n this.arrowPadding = padding;\n }\n\n /**\n * Remove the registered arrow element\n * @internal\n */\n unregisterArrow(): void {\n this.arrowElement = null;\n this.arrowPadding = undefined;\n }\n\n /**\n * Resolve the container element from the configuration\n * @internal\n */\n private resolveContainer(): HTMLElement {\n if (!this.config.container) {\n return this.document.body;\n }\n\n if (typeof this.config.container === 'string') {\n const element = this.document.querySelector(this.config.container);\n if (!element) {\n // Fallback to document.body if the container is not found\n console.warn(\n `NgPrimitives: Container element with selector \"${this.config.container}\" not found. Falling back to document.body.`,\n );\n return this.document.body;\n }\n\n return element as HTMLElement;\n }\n\n return this.config.container;\n }\n}\n\n/**\n * Helper function to create an overlay in a single call\n * @internal\n */\nexport function createOverlay<T>(config: NgpOverlayConfig<T>): NgpOverlay<T> {\n // we run the overlay creation in the injector context to ensure that it can call the inject function\n return runInInjectionContext(config.injector, () => new NgpOverlay<T>(config));\n}\n\n/**\n * Helper function to inject the NgpOverlay instance\n * @internal\n */\nexport function injectOverlay<T>(): NgpOverlay<T> {\n return inject(NgpOverlay);\n}\n\nexport interface OverlayTriggerOptions {\n /**\n * Whether the visibility change should be immediate.\n */\n immediate?: boolean;\n /**\n * The origin of the focus event that triggered the visibility change.\n */\n origin?: FocusOrigin;\n}\n","import { computed, signal, Signal, WritableSignal } from '@angular/core';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport {\n controlled,\n createPrimitive,\n dataBinding,\n onDestroy,\n styleBinding,\n} from 'ng-primitives/state';\nimport { injectOverlay } from './overlay';\n\n/**\n * The state interface for the overlay arrow.\n */\nexport interface NgpOverlayArrowState {\n /**\n * The x position of the arrow.\n */\n readonly x: Signal<number | undefined>;\n /**\n * The y position of the arrow.\n */\n readonly y: Signal<number | undefined>;\n /**\n * The final placement of the overlay.\n */\n readonly placement: Signal<string | undefined>;\n /**\n * The padding between the arrow and the edges of the floating element.\n */\n readonly padding: WritableSignal<number | undefined>;\n /**\n * Set the padding between the arrow and the edges of the floating element.\n * @param value The padding value in pixels\n */\n setPadding(value: number | undefined): void;\n}\n\n/**\n * The props interface for the overlay arrow.\n */\nexport interface NgpOverlayArrowProps {\n /**\n * Padding between the arrow and the edges of the floating element.\n * This prevents the arrow from overflowing the rounded corners.\n */\n readonly padding?: Signal<number | undefined>;\n}\n\nexport const [\n NgpOverlayArrowStateToken,\n ngpOverlayArrow,\n injectOverlayArrowState,\n provideOverlayArrowState,\n] = createPrimitive(\n 'NgpOverlayArrow',\n ({ padding: _padding = signal(undefined) }: NgpOverlayArrowProps) => {\n const overlay = injectOverlay();\n const element = injectElementRef();\n const padding = controlled(_padding);\n\n // register the arrow element with the overlay\n overlay.registerArrow(element.nativeElement, padding);\n\n // cleanup the arrow element on destroy\n onDestroy(() => overlay.unregisterArrow());\n\n const x = computed(() => overlay.arrowPosition().x);\n const y = computed(() => overlay.arrowPosition().y);\n const placement = computed(() => overlay.finalPlacement());\n\n // bind the arrow position styles\n styleBinding(element, 'inset-inline-start.px', () => x() ?? null);\n styleBinding(element, 'inset-block-start.px', () => y() ?? null);\n dataBinding(element, 'data-placement', () => placement() ?? null);\n\n function setPadding(value: number | undefined): void {\n padding.set(value);\n }\n\n return {\n x,\n y,\n placement,\n padding,\n setPadding,\n } satisfies NgpOverlayArrowState;\n },\n);\n","import { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isNil, isObject } from 'ng-primitives/utils';\n\n/**\n * Options for configuring shift behavior to keep the floating element in view.\n * The shift middleware ensures the floating element stays visible by shifting it\n * within the viewport when it would otherwise overflow.\n */\nexport interface NgpShiftOptions {\n /**\n * The minimum padding between the floating element and the viewport edges.\n * Prevents the floating element from touching the edges of the viewport.\n * @default 0\n */\n padding?: number;\n\n /**\n * The limiter function that determines how much the floating element can shift.\n * Common limiters from @floating-ui/dom include:\n * - limitShift: Limits shifting to prevent the reference element from being obscured\n * @default undefined\n */\n limiter?: {\n fn: (state: unknown) => { x: number; y: number };\n options?: unknown;\n };\n}\n\n/**\n * Type representing all valid shift values.\n * Can be a boolean (enable/disable), undefined, or an object with detailed options.\n */\nexport type NgpShift = boolean | NgpShiftOptions | undefined;\n\n/**\n * Input type for shift that also accepts string representations of booleans\n */\nexport type NgpShiftInput = NgpShift | string;\n\n/**\n * Transform function to coerce shift input values to the correct type\n * @param value The input value to coerce\n * @returns The coerced shift value\n */\nexport function coerceShift(value: NgpShiftInput | null | undefined): NgpShift {\n if (isNil(value)) {\n return undefined;\n }\n\n if (isObject(value)) {\n return value;\n }\n\n // Handle boolean values\n if (typeof value === 'boolean') {\n return value;\n }\n\n // Handle string boolean values\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n // Handle string number values for padding shorthand\n const numValue = coerceNumberProperty(value, null);\n if (numValue !== null && !isNaN(numValue)) {\n return { padding: numValue };\n }\n\n return undefined;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/internal/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ interface NgpExitAnimationOptions {
|
|
|
25
25
|
interface NgpExitAnimationRef {
|
|
26
26
|
/** Mark the element as exiting and wait for the animation to finish. */
|
|
27
27
|
exit: () => Promise<void>;
|
|
28
|
+
/** Cancel an in-progress exit animation and transition back to enter state. */
|
|
29
|
+
cancel: () => void;
|
|
28
30
|
}
|
|
29
31
|
declare function setupExitAnimation({ element, immediate, }: NgpExitAnimationOptions): NgpExitAnimationRef;
|
|
30
32
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "ng-primitives",
|
|
3
3
|
"description": "Angular Primitives is a low-level headless UI component library with a focus on accessibility, customization, and developer experience. ",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "0.112.
|
|
5
|
+
"version": "0.112.1",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"angular",
|
|
8
8
|
"primitives",
|
package/portal/index.d.ts
CHANGED
|
@@ -315,6 +315,8 @@ declare class NgpOverlay<T = unknown> implements CooldownOverlay {
|
|
|
315
315
|
private openTimeout?;
|
|
316
316
|
/** Timeout handle for hiding the overlay */
|
|
317
317
|
private closeTimeout?;
|
|
318
|
+
/** Portal currently being destroyed (for cancel support during exit animations) */
|
|
319
|
+
private destroyingPortal;
|
|
318
320
|
/** Signal tracking whether the overlay is open */
|
|
319
321
|
readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
320
322
|
/** A unique id for the overlay */
|
|
@@ -364,6 +366,12 @@ declare class NgpOverlay<T = unknown> implements CooldownOverlay {
|
|
|
364
366
|
* @internal
|
|
365
367
|
*/
|
|
366
368
|
cancelPendingClose(): void;
|
|
369
|
+
/**
|
|
370
|
+
* Cancel an in-progress overlay destruction. This cancels exit animations,
|
|
371
|
+
* restores the portal, and re-enables positioning and scroll strategy.
|
|
372
|
+
* Used when show() or cancelPendingClose() is called during exit animation.
|
|
373
|
+
*/
|
|
374
|
+
private cancelDestruction;
|
|
367
375
|
/**
|
|
368
376
|
* Hide the overlay with the specified delay
|
|
369
377
|
* @param options Optional options for hiding the overlay
|
|
@@ -615,6 +623,11 @@ declare abstract class NgpPortal {
|
|
|
615
623
|
* @param immediate If true, skip exit animations and remove immediately
|
|
616
624
|
*/
|
|
617
625
|
abstract detach(immediate?: boolean): Promise<void>;
|
|
626
|
+
/**
|
|
627
|
+
* Cancel an in-progress detach operation. If exit animations are running,
|
|
628
|
+
* they are cancelled and the portal transitions back to the enter state.
|
|
629
|
+
*/
|
|
630
|
+
abstract cancelDetach(): void;
|
|
618
631
|
/**
|
|
619
632
|
* Angular v20 removes `_unusedComponentFactoryResolver` and `_document` from DomPortalOutlet's
|
|
620
633
|
* constructor signature as they have been deprecated since v18, and replaced with optional
|
|
@@ -630,6 +643,7 @@ declare class NgpComponentPortal<T> extends NgpPortal {
|
|
|
630
643
|
private readonly componentPortal;
|
|
631
644
|
private viewRef;
|
|
632
645
|
private isDestroying;
|
|
646
|
+
private detachCancelled;
|
|
633
647
|
private exitAnimationRef;
|
|
634
648
|
constructor(component: Type<T>, viewContainerRef: ViewContainerRef | null, injector: Injector);
|
|
635
649
|
/**
|
|
@@ -650,6 +664,10 @@ declare class NgpComponentPortal<T> extends NgpPortal {
|
|
|
650
664
|
* Whether the portal is attached to a DOM element.
|
|
651
665
|
*/
|
|
652
666
|
getAttached(): boolean;
|
|
667
|
+
/**
|
|
668
|
+
* Cancel an in-progress detach operation.
|
|
669
|
+
*/
|
|
670
|
+
cancelDetach(): void;
|
|
653
671
|
/**
|
|
654
672
|
* Detach the portal from the DOM.
|
|
655
673
|
* @param immediate If true, skip exit animations and remove immediately
|
|
@@ -661,6 +679,7 @@ declare class NgpTemplatePortal<T> extends NgpPortal {
|
|
|
661
679
|
private viewRef;
|
|
662
680
|
private exitAnimationRefs;
|
|
663
681
|
private isDestroying;
|
|
682
|
+
private detachCancelled;
|
|
664
683
|
constructor(template: TemplateRef<T>, viewContainerRef: ViewContainerRef, injector: Injector, context?: T);
|
|
665
684
|
/**
|
|
666
685
|
* Attach the portal to a DOM element.
|
|
@@ -680,6 +699,10 @@ declare class NgpTemplatePortal<T> extends NgpPortal {
|
|
|
680
699
|
* Whether the portal is attached to a DOM element.
|
|
681
700
|
*/
|
|
682
701
|
getAttached(): boolean;
|
|
702
|
+
/**
|
|
703
|
+
* Cancel an in-progress detach operation.
|
|
704
|
+
*/
|
|
705
|
+
cancelDetach(): void;
|
|
683
706
|
/**
|
|
684
707
|
* Detach the portal from the DOM.
|
|
685
708
|
* @param immediate If true, skip exit animations and remove immediately
|