ng-primitives 0.111.0 → 0.111.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.
@@ -563,6 +563,8 @@ class NgpOverlay {
563
563
  this.cooldownManager = inject(NgpOverlayCooldownManager);
564
564
  /** Access any parent overlays */
565
565
  this.parentOverlay = inject(NgpOverlay, { optional: true });
566
+ /** Track child overlays for outside click detection */
567
+ this.childOverlays = new Set();
566
568
  /** Signal tracking the portal instance */
567
569
  this.portal = signal(null, ...(ngDevMode ? [{ debugName: "portal" }] : []));
568
570
  /** Signal tracking the overlay position */
@@ -638,6 +640,10 @@ class NgpOverlay {
638
640
  this.hideImmediate();
639
641
  }
640
642
  });
643
+ // Register with parent overlay for outside click detection
644
+ if (this.parentOverlay) {
645
+ this.parentOverlay.registerChildOverlay(this);
646
+ }
641
647
  // if there is a parent overlay and it is closed, close this overlay
642
648
  this.parentOverlay?.closing
643
649
  // we add a debounce here to ensure any dom events like clicks are processed first
@@ -664,7 +670,10 @@ class NgpOverlay {
664
670
  const isInsideAnchor = this.config.anchorElement
665
671
  ? path.includes(this.config.anchorElement)
666
672
  : false;
667
- if (!isInsideOverlay && !isInsideTrigger && !isInsideAnchor) {
673
+ if (!isInsideOverlay &&
674
+ !isInsideTrigger &&
675
+ !isInsideAnchor &&
676
+ !this.isInsideChildOverlay(path)) {
668
677
  this.hide();
669
678
  }
670
679
  });
@@ -679,7 +688,10 @@ class NgpOverlay {
679
688
  }
680
689
  });
681
690
  // Ensure cleanup on destroy
682
- this.destroyRef.onDestroy(() => this.destroy());
691
+ this.destroyRef.onDestroy(() => {
692
+ this.parentOverlay?.unregisterChildOverlay(this);
693
+ this.destroy();
694
+ });
683
695
  }
684
696
  /**
685
697
  * Show the overlay with the specified delay
@@ -880,6 +892,36 @@ class NgpOverlay {
880
892
  getElements() {
881
893
  return this.portal()?.getElements() ?? [];
882
894
  }
895
+ /**
896
+ * Register a child overlay for outside click detection.
897
+ * @internal
898
+ */
899
+ registerChildOverlay(child) {
900
+ this.childOverlays.add(child);
901
+ }
902
+ /**
903
+ * Unregister a child overlay.
904
+ * @internal
905
+ */
906
+ unregisterChildOverlay(child) {
907
+ this.childOverlays.delete(child);
908
+ }
909
+ /**
910
+ * Check if the event path includes any child overlay elements (recursively).
911
+ * @internal
912
+ */
913
+ isInsideChildOverlay(path) {
914
+ for (const child of this.childOverlays) {
915
+ const childElements = child.getElements();
916
+ if (childElements.some(el => path.includes(el))) {
917
+ return true;
918
+ }
919
+ if (child.isInsideChildOverlay(path)) {
920
+ return true;
921
+ }
922
+ }
923
+ return false;
924
+ }
883
925
  /**
884
926
  * Internal method to create the overlay
885
927
  * @param skipCooldown If true, skip registering with the cooldown manager
@@ -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 /** 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 // 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 (!isInsideOverlay && !isInsideTrigger && !isInsideAnchor) {\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(() => this.destroy());\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 * 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 * 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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"}
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.111.0",
5
+ "version": "0.111.1",
6
6
  "keywords": [
7
7
  "angular",
8
8
  "primitives",
package/portal/index.d.ts CHANGED
@@ -285,6 +285,8 @@ declare class NgpOverlay<T = unknown> implements CooldownOverlay {
285
285
  private readonly cooldownManager;
286
286
  /** Access any parent overlays */
287
287
  private readonly parentOverlay;
288
+ /** Track child overlays for outside click detection */
289
+ private readonly childOverlays;
288
290
  /** Signal tracking the portal instance */
289
291
  private readonly portal;
290
292
  /** Signal tracking the overlay position */
@@ -394,6 +396,21 @@ declare class NgpOverlay<T = unknown> implements CooldownOverlay {
394
396
  * Get the elements of the overlay
395
397
  */
396
398
  getElements(): HTMLElement[];
399
+ /**
400
+ * Register a child overlay for outside click detection.
401
+ * @internal
402
+ */
403
+ registerChildOverlay(child: NgpOverlay): void;
404
+ /**
405
+ * Unregister a child overlay.
406
+ * @internal
407
+ */
408
+ unregisterChildOverlay(child: NgpOverlay): void;
409
+ /**
410
+ * Check if the event path includes any child overlay elements (recursively).
411
+ * @internal
412
+ */
413
+ isInsideChildOverlay(path: EventTarget[]): boolean;
397
414
  /**
398
415
  * Internal method to create the overlay
399
416
  * @param skipCooldown If true, skip registering with the cooldown manager