ng-primitives 0.121.0 → 0.123.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/fesm2022/ng-primitives-combobox.mjs +23 -4
  2. package/fesm2022/ng-primitives-combobox.mjs.map +1 -1
  3. package/fesm2022/ng-primitives-context-menu.mjs +9 -3
  4. package/fesm2022/ng-primitives-context-menu.mjs.map +1 -1
  5. package/fesm2022/ng-primitives-date-picker.mjs +1 -1
  6. package/fesm2022/ng-primitives-date-picker.mjs.map +1 -1
  7. package/fesm2022/ng-primitives-internal.mjs +184 -3
  8. package/fesm2022/ng-primitives-internal.mjs.map +1 -1
  9. package/fesm2022/ng-primitives-menu.mjs +139 -21
  10. package/fesm2022/ng-primitives-menu.mjs.map +1 -1
  11. package/fesm2022/ng-primitives-navigation-menu.mjs +6 -2
  12. package/fesm2022/ng-primitives-navigation-menu.mjs.map +1 -1
  13. package/fesm2022/ng-primitives-popover.mjs +8 -3
  14. package/fesm2022/ng-primitives-popover.mjs.map +1 -1
  15. package/fesm2022/ng-primitives-portal.mjs +74 -12
  16. package/fesm2022/ng-primitives-portal.mjs.map +1 -1
  17. package/fesm2022/ng-primitives-select.mjs +17 -3
  18. package/fesm2022/ng-primitives-select.mjs.map +1 -1
  19. package/fesm2022/ng-primitives-toast.mjs +15 -12
  20. package/fesm2022/ng-primitives-toast.mjs.map +1 -1
  21. package/fesm2022/ng-primitives-tooltip.mjs +28 -123
  22. package/fesm2022/ng-primitives-tooltip.mjs.map +1 -1
  23. package/fesm2022/ng-primitives-utils.mjs +40 -23
  24. package/fesm2022/ng-primitives-utils.mjs.map +1 -1
  25. package/package.json +1 -1
  26. package/schematics/ng-generate/templates/toggle-group/toggle-group.__fileSuffix@dasherize__.ts.template +2 -2
  27. package/types/ng-primitives-combobox.d.ts +11 -1
  28. package/types/ng-primitives-context-menu.d.ts +16 -3
  29. package/types/ng-primitives-internal.d.ts +95 -3
  30. package/types/ng-primitives-menu.d.ts +58 -11
  31. package/types/ng-primitives-navigation-menu.d.ts +22 -9
  32. package/types/ng-primitives-popover.d.ts +9 -2
  33. package/types/ng-primitives-portal.d.ts +31 -1
  34. package/types/ng-primitives-select.d.ts +9 -2
  35. package/types/ng-primitives-toast.d.ts +4 -3
  36. package/types/ng-primitives-tooltip.d.ts +24 -17
  37. package/types/ng-primitives-utils.d.ts +12 -9
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { OnDestroy, ClassProvider, EffectCleanupRegisterFn, CreateEffectOptions, EffectRef, ElementRef, Signal, Injector } from '@angular/core';
2
+ import { OnDestroy, ClassProvider, Signal, EffectCleanupRegisterFn, CreateEffectOptions, EffectRef, ElementRef, Injector } from '@angular/core';
3
3
  import { Observable } from 'rxjs';
4
4
 
5
5
  declare class NgpExitAnimation implements OnDestroy {
@@ -45,6 +45,98 @@ declare class NgpExitAnimationManager {
45
45
  declare function provideExitAnimationManager(): ClassProvider;
46
46
  declare function injectExitAnimationManager(): NgpExitAnimationManager;
47
47
 
48
+ /**
49
+ * Fallback timeout (ms) after which an idle hover bridge closes the overlay.
50
+ * Shared so tooltip, menu and submenu hover-intent behaviour stay in sync.
51
+ */
52
+ declare const HOVER_BRIDGE_TIMEOUT_MS = 150;
53
+ /**
54
+ * Pointer movement below this magnitude (px) on the intent axis is treated as
55
+ * jitter, not a reversal, so a tiny backward twitch doesn't collapse the bridge.
56
+ */
57
+ declare const HOVER_BRIDGE_DIRECTION_TOLERANCE_PX = 2;
58
+ interface HoverBridgePoint {
59
+ x: number;
60
+ y: number;
61
+ }
62
+ /**
63
+ * The dominant axis and sign pointing from the trigger toward the target. Used
64
+ * to reject pointer movement heading away from the target while inside the corridor.
65
+ */
66
+ interface HoverBridgeDirection {
67
+ axis: 'x' | 'y';
68
+ sign: 1 | -1;
69
+ }
70
+ interface CreateHoverBridgePolygonOptions {
71
+ triggerRect: DOMRect | null;
72
+ targetRect: DOMRect | null;
73
+ exitPoint: HoverBridgePoint;
74
+ corridorHalfSize?: number;
75
+ }
76
+ /**
77
+ * Computes the dominant axis and sign from the trigger toward the target - i.e.
78
+ * which way the pointer must travel to reach the panel. Returns null if either
79
+ * rect is missing.
80
+ */
81
+ declare function getHoverBridgeDirection(triggerRect: DOMRect | null, targetRect: DOMRect | null): HoverBridgeDirection | null;
82
+ /**
83
+ * Builds a pointer grace polygon between the trigger exit point and the target overlay.
84
+ * The polygon is intentionally directional so moving away from the target exits quickly.
85
+ */
86
+ declare function createHoverBridgePolygon({ triggerRect, targetRect, exitPoint, corridorHalfSize, }: CreateHoverBridgePolygonOptions): HoverBridgePoint[] | null;
87
+ /**
88
+ * Returns true when the point lies inside the provided polygon.
89
+ */
90
+ declare function isPointInHoverBridgePolygon(point: HoverBridgePoint, polygon: HoverBridgePoint[]): boolean;
91
+
92
+ interface HoverBridgeOptions {
93
+ /** Whether the pointer is currently over the trigger or the panel (the "safe" area). */
94
+ isPointerInAnchor: () => boolean;
95
+ /** Close the overlay - called when the pointer leaves the corridor or the idle timer fires. */
96
+ close: () => void;
97
+ /**
98
+ * Require the pointer to keep heading toward the panel. When true, reversing
99
+ * away along the corridor's dominant axis closes the overlay (menu/submenu).
100
+ * Tooltips leave this off. Defaults to false.
101
+ */
102
+ requireForwardMovement?: boolean;
103
+ /**
104
+ * Reset the idle-fallback timer on valid in-corridor movement, so it only
105
+ * fires after the pointer genuinely stops. When false the timer is a fixed cap
106
+ * from the moment the corridor is built (tooltip's original semantics).
107
+ * Defaults to true.
108
+ */
109
+ resetFallbackOnMove?: boolean;
110
+ /** Idle-fallback timeout in ms. Defaults to HOVER_BRIDGE_TIMEOUT_MS. */
111
+ timeoutMs?: number;
112
+ }
113
+ interface HoverBridgeTrackOptions {
114
+ triggerRect: DOMRect | null;
115
+ targetRect: DOMRect | null;
116
+ exitPoint: HoverBridgePoint;
117
+ }
118
+ interface HoverBridgeController {
119
+ /** The active corridor polygon, or null when no bridge is in progress. */
120
+ readonly polygon: Signal<HoverBridgePoint[] | null>;
121
+ /** Whether a corridor is currently active. */
122
+ isActive(): boolean;
123
+ /**
124
+ * Build a corridor from the exit point toward the panel and start tracking the
125
+ * pointer. Returns false (and does nothing) when a polygon can't be built, so
126
+ * the caller can apply its own fallback.
127
+ */
128
+ track(options: HoverBridgeTrackOptions): boolean;
129
+ /** Tear down the corridor and its global listener/timer. */
130
+ clear(): void;
131
+ }
132
+ /**
133
+ * Shared safe-polygon hover-intent state machine used by the menu, submenu and
134
+ * tooltip triggers. While the pointer travels inside the corridor toward the
135
+ * panel the overlay stays open; it closes when the pointer leaves the corridor,
136
+ * reverses away (when requireForwardMovement is set) or idles past the timeout.
137
+ */
138
+ declare function createHoverBridge({ isPointerInAnchor, close, requireForwardMovement, resetFallbackOnMove, timeoutMs, }: HoverBridgeOptions): HoverBridgeController;
139
+
48
140
  /**
49
141
  * This implementation is heavily inspired by the great work on ngextension!
50
142
  * https://github.com/ngxtension/ngxtension-platform/blob/main/libs/ngxtension/explicit-effect/src/explicit-effect.ts
@@ -210,5 +302,5 @@ declare function injectDimensions(): Signal<Dimensions>;
210
302
 
211
303
  declare function scrollIntoViewIfNeeded(element: HTMLElement): void;
212
304
 
213
- export { NgpExitAnimation, NgpExitAnimationManager, StyleInjector, domSort, explicitEffect, fromMutationObserver, fromResizeEvent, injectDimensions, injectElementRef, injectExitAnimationManager, injectStyleInjector, observeResize, onDomRemoval, provideExitAnimationManager, scrollIntoViewIfNeeded, setupExitAnimation, setupOverflowListener };
214
- export type { Dimensions, NgpExitAnimationRef };
305
+ export { HOVER_BRIDGE_DIRECTION_TOLERANCE_PX, HOVER_BRIDGE_TIMEOUT_MS, NgpExitAnimation, NgpExitAnimationManager, StyleInjector, createHoverBridge, createHoverBridgePolygon, domSort, explicitEffect, fromMutationObserver, fromResizeEvent, getHoverBridgeDirection, injectDimensions, injectElementRef, injectExitAnimationManager, injectStyleInjector, isPointInHoverBridgePolygon, observeResize, onDomRemoval, provideExitAnimationManager, scrollIntoViewIfNeeded, setupExitAnimation, setupOverflowListener };
306
+ export type { Dimensions, HoverBridgeController, HoverBridgeDirection, HoverBridgeOptions, HoverBridgePoint, HoverBridgeTrackOptions, NgpExitAnimationRef };
@@ -393,6 +393,11 @@ interface NgpMenuTriggerState<T = unknown> {
393
393
  * Whether the menu should flip when there is not enough space.
394
394
  */
395
395
  readonly flip: WritableSignal<NgpFlip>;
396
+ /**
397
+ * The container in which the menu should be attached.
398
+ * @default document.body
399
+ */
400
+ readonly container: WritableSignal<HTMLElement | string | null>;
396
401
  /**
397
402
  * The context provided to the menu.
398
403
  */
@@ -427,6 +432,12 @@ interface NgpMenuTriggerState<T = unknown> {
427
432
  * @param context - The new context
428
433
  */
429
434
  setContext(context: T): void;
435
+ /**
436
+ * Set the container in which the menu should be attached. Takes effect the
437
+ * next time the menu is opened; it does not move a menu that is already open.
438
+ * @param container - The new container
439
+ */
440
+ setContainer(container: HTMLElement | string | null): void;
430
441
  /**
431
442
  * Show the menu.
432
443
  * @param origin - The focus origin
@@ -526,10 +537,12 @@ declare const NgpMenuTriggerStateToken: _angular_core.InjectionToken<WritableSig
526
537
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
527
538
  setOffset: (newOffset: NgpOffset) => void;
528
539
  setContext: (newContext: unknown) => void;
540
+ setContainer: (newContainer: HTMLElement | string | null) => void;
529
541
  setPointerOverContent: (isOver: boolean) => void;
530
542
  flip: WritableSignal<NgpFlip>;
543
+ container: WritableSignal<string | HTMLElement | null>;
531
544
  }>>;
532
- declare const ngpMenuTrigger: <T>({ disabled: _disabled, menu: _menu, placement: _placement, offset: _offset, flip: _flip, shift: _shift, context: _context, container, scrollBehavior, cooldown, triggers, showDelay, hideDelay, }: NgpMenuTriggerProps<T>) => {
545
+ declare const ngpMenuTrigger: <T>({ disabled: _disabled, menu: _menu, placement: _placement, offset: _offset, flip: _flip, shift: _shift, context: _context, container: _container, scrollBehavior, cooldown, triggers, showDelay, hideDelay, }: NgpMenuTriggerProps<T>) => {
533
546
  menu: WritableSignal<NgpOverlayContent<T> | undefined>;
534
547
  placement: WritableSignal<NgpMenuPlacement>;
535
548
  offset: WritableSignal<NgpOffset>;
@@ -546,8 +559,10 @@ declare const ngpMenuTrigger: <T>({ disabled: _disabled, menu: _menu, placement:
546
559
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
547
560
  setOffset: (newOffset: NgpOffset) => void;
548
561
  setContext: (newContext: T) => void;
562
+ setContainer: (newContainer: HTMLElement | string | null) => void;
549
563
  setPointerOverContent: (isOver: boolean) => void;
550
564
  flip: WritableSignal<NgpFlip>;
565
+ container: WritableSignal<string | HTMLElement | null>;
551
566
  };
552
567
  declare const provideMenuTriggerState: (opts?: {
553
568
  inherit?: boolean;
@@ -638,6 +653,11 @@ declare class NgpSubmenuTrigger<T = unknown> {
638
653
  * @default true
639
654
  */
640
655
  readonly flip: _angular_core.InputSignalWithTransform<NgpFlip, NgpFlipInput>;
656
+ /**
657
+ * Define the container in which the menu should be attached.
658
+ * @default document.body
659
+ */
660
+ readonly container: _angular_core.InputSignal<string | HTMLElement | null>;
641
661
  /**
642
662
  * Access the menu trigger state.
643
663
  */
@@ -661,7 +681,7 @@ declare class NgpSubmenuTrigger<T = unknown> {
661
681
  */
662
682
  focus(origin?: FocusOrigin): void;
663
683
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpSubmenuTrigger<any>, never>;
664
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpSubmenuTrigger<any>, "[ngpSubmenuTrigger]", ["ngpSubmenuTrigger"], { "menu": { "alias": "ngpSubmenuTrigger"; "required": false; "isSignal": true; }; "disabled": { "alias": "ngpSubmenuTriggerDisabled"; "required": false; "isSignal": true; }; "placement": { "alias": "ngpSubmenuTriggerPlacement"; "required": false; "isSignal": true; }; "offset": { "alias": "ngpSubmenuTriggerOffset"; "required": false; "isSignal": true; }; "flip": { "alias": "ngpSubmenuTriggerFlip"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
684
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpSubmenuTrigger<any>, "[ngpSubmenuTrigger]", ["ngpSubmenuTrigger"], { "menu": { "alias": "ngpSubmenuTrigger"; "required": false; "isSignal": true; }; "disabled": { "alias": "ngpSubmenuTriggerDisabled"; "required": false; "isSignal": true; }; "placement": { "alias": "ngpSubmenuTriggerPlacement"; "required": false; "isSignal": true; }; "offset": { "alias": "ngpSubmenuTriggerOffset"; "required": false; "isSignal": true; }; "flip": { "alias": "ngpSubmenuTriggerFlip"; "required": false; "isSignal": true; }; "container": { "alias": "ngpSubmenuTriggerContainer"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
665
685
  }
666
686
 
667
687
  interface NgpSubmenuTriggerState {
@@ -689,6 +709,11 @@ interface NgpSubmenuTriggerState {
689
709
  * Whether the menu should flip when there is not enough space.
690
710
  */
691
711
  readonly flip: WritableSignal<NgpFlip>;
712
+ /**
713
+ * The container in which the menu should be attached.
714
+ * @default document.body
715
+ */
716
+ readonly container: WritableSignal<HTMLElement | string | null>;
692
717
  /**
693
718
  * The focus origin used to open the submenu.
694
719
  * Used by the submenu's focus trap for :focus-visible styling.
@@ -735,14 +760,20 @@ interface NgpSubmenuTriggerState {
735
760
  * @param shouldFlip - Whether the menu should flip
736
761
  */
737
762
  setFlip(shouldFlip: NgpFlip): void;
763
+ /**
764
+ * Set the container in which the menu should be attached. Takes effect the
765
+ * next time the menu is opened; it does not move a menu that is already open.
766
+ * @param container - The new container
767
+ */
768
+ setContainer(container: HTMLElement | string | null): void;
738
769
  /**
739
770
  * Focus the trigger element.
740
771
  * @param origin - The focus origin
741
772
  */
742
773
  focus(origin: FocusOrigin): void;
743
774
  /**
744
- * Set whether the pointer is over the menu content.
745
- * For submenus, this is a no-op as hover is handled via showSubmenuOnHover.
775
+ * Set whether the pointer is over the submenu content. Entering the submenu
776
+ * tears down the hover bridge (the pointer arrived safely).
746
777
  * @param isOver - Whether the pointer is over the content
747
778
  * @internal
748
779
  */
@@ -769,6 +800,10 @@ interface NgpSubmenuTriggerProps<T = unknown> {
769
800
  * Whether the menu should flip when there is not enough space.
770
801
  */
771
802
  readonly flip?: Signal<NgpFlip>;
803
+ /**
804
+ * The container in which the menu should be attached.
805
+ */
806
+ readonly container?: Signal<HTMLElement | string | null>;
772
807
  }
773
808
  declare const NgpSubmenuTriggerStateToken: _angular_core.InjectionToken<WritableSignal<{
774
809
  placement: WritableSignal<NgpMenuPlacement>;
@@ -786,10 +821,12 @@ declare const NgpSubmenuTriggerStateToken: _angular_core.InjectionToken<Writable
786
821
  setFlip: (shouldFlip: NgpFlip) => void;
787
822
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
788
823
  setOffset: (newOffset: NgpOffset) => void;
824
+ setContainer: (newContainer: HTMLElement | string | null) => void;
789
825
  focus: (origin: FocusOrigin) => void;
790
- setPointerOverContent: (_isOver: boolean) => void;
826
+ setPointerOverContent: (isOver: boolean) => void;
827
+ container: WritableSignal<string | HTMLElement | null>;
791
828
  }>>;
792
- declare const ngpSubmenuTrigger: <T>({ disabled: _disabled, menu: _menu, placement: _placement, offset: _offset, flip: _flip, }: NgpSubmenuTriggerProps<T>) => {
829
+ declare const ngpSubmenuTrigger: <T>({ disabled: _disabled, menu: _menu, placement: _placement, offset: _offset, flip: _flip, container: _container, }: NgpSubmenuTriggerProps<T>) => {
793
830
  placement: WritableSignal<NgpMenuPlacement>;
794
831
  offset: WritableSignal<NgpOffset>;
795
832
  disabled: WritableSignal<boolean>;
@@ -805,8 +842,10 @@ declare const ngpSubmenuTrigger: <T>({ disabled: _disabled, menu: _menu, placeme
805
842
  setFlip: (shouldFlip: NgpFlip) => void;
806
843
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
807
844
  setOffset: (newOffset: NgpOffset) => void;
845
+ setContainer: (newContainer: HTMLElement | string | null) => void;
808
846
  focus: (origin: FocusOrigin) => void;
809
- setPointerOverContent: (_isOver: boolean) => void;
847
+ setPointerOverContent: (isOver: boolean) => void;
848
+ container: WritableSignal<string | HTMLElement | null>;
810
849
  };
811
850
  declare const injectSubmenuTriggerState: {
812
851
  (): Signal<{
@@ -825,8 +864,10 @@ declare const injectSubmenuTriggerState: {
825
864
  setFlip: (shouldFlip: NgpFlip) => void;
826
865
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
827
866
  setOffset: (newOffset: NgpOffset) => void;
867
+ setContainer: (newContainer: HTMLElement | string | null) => void;
828
868
  focus: (origin: FocusOrigin) => void;
829
- setPointerOverContent: (_isOver: boolean) => void;
869
+ setPointerOverContent: (isOver: boolean) => void;
870
+ container: WritableSignal<string | HTMLElement | null>;
830
871
  }>;
831
872
  (options: ng_primitives_state.StateInjectionOptions): Signal<{
832
873
  placement: WritableSignal<NgpMenuPlacement>;
@@ -844,8 +885,10 @@ declare const injectSubmenuTriggerState: {
844
885
  setFlip: (shouldFlip: NgpFlip) => void;
845
886
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
846
887
  setOffset: (newOffset: NgpOffset) => void;
888
+ setContainer: (newContainer: HTMLElement | string | null) => void;
847
889
  focus: (origin: FocusOrigin) => void;
848
- setPointerOverContent: (_isOver: boolean) => void;
890
+ setPointerOverContent: (isOver: boolean) => void;
891
+ container: WritableSignal<string | HTMLElement | null>;
849
892
  } | null>;
850
893
  (options?: ng_primitives_state.StateInjectionOptions): Signal<{
851
894
  placement: WritableSignal<NgpMenuPlacement>;
@@ -863,8 +906,10 @@ declare const injectSubmenuTriggerState: {
863
906
  setFlip: (shouldFlip: NgpFlip) => void;
864
907
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
865
908
  setOffset: (newOffset: NgpOffset) => void;
909
+ setContainer: (newContainer: HTMLElement | string | null) => void;
866
910
  focus: (origin: FocusOrigin) => void;
867
- setPointerOverContent: (_isOver: boolean) => void;
911
+ setPointerOverContent: (isOver: boolean) => void;
912
+ container: WritableSignal<string | HTMLElement | null>;
868
913
  }> | Signal<{
869
914
  placement: WritableSignal<NgpMenuPlacement>;
870
915
  offset: WritableSignal<NgpOffset>;
@@ -881,8 +926,10 @@ declare const injectSubmenuTriggerState: {
881
926
  setFlip: (shouldFlip: NgpFlip) => void;
882
927
  setPlacement: (newPlacement: NgpMenuPlacement) => void;
883
928
  setOffset: (newOffset: NgpOffset) => void;
929
+ setContainer: (newContainer: HTMLElement | string | null) => void;
884
930
  focus: (origin: FocusOrigin) => void;
885
- setPointerOverContent: (_isOver: boolean) => void;
931
+ setPointerOverContent: (isOver: boolean) => void;
932
+ container: WritableSignal<string | HTMLElement | null>;
886
933
  } | null>;
887
934
  };
888
935
  declare const provideSubmenuTriggerState: (opts?: {
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, Provider, Signal } from '@angular/core';
2
+ import { InjectionToken, Provider, Signal, WritableSignal } from '@angular/core';
3
3
  import { Placement } from '@floating-ui/dom';
4
4
  import { NgpOrientation } from 'ng-primitives/common';
5
5
  import { NgpOffset, NgpFlip, NgpShift, NgpOverlayContent, NgpOffsetInput, NgpFlipInput, NgpShiftInput } from 'ng-primitives/portal';
@@ -635,7 +635,7 @@ interface NgpNavigationMenuTriggerState {
635
635
  /**
636
636
  * The container for the content.
637
637
  */
638
- readonly container: Signal<HTMLElement | string | null>;
638
+ readonly container: WritableSignal<HTMLElement | string | null>;
639
639
  /**
640
640
  * Whether the content is currently open.
641
641
  */
@@ -670,6 +670,13 @@ interface NgpNavigationMenuTriggerState {
670
670
  * @param id The content ID
671
671
  */
672
672
  setContentId(id: string): void;
673
+ /**
674
+ * Set the container in which the content should be attached. Takes effect the
675
+ * next time the content is opened; it does not move content that is already
676
+ * open.
677
+ * @param container The new container
678
+ */
679
+ setContainer(container: HTMLElement | string | null): void;
673
680
  /**
674
681
  * Update pointer over content state.
675
682
  * @param isOver Whether pointer is over content
@@ -721,14 +728,14 @@ interface NgpNavigationMenuTriggerProps {
721
728
  */
722
729
  readonly cooldown?: Signal<number>;
723
730
  }
724
- declare const NgpNavigationMenuTriggerStateToken: _angular_core.InjectionToken<_angular_core.WritableSignal<{
731
+ declare const NgpNavigationMenuTriggerStateToken: _angular_core.InjectionToken<WritableSignal<{
725
732
  content: Signal<NgpOverlayContent<unknown> | undefined>;
726
733
  disabled: Signal<boolean>;
727
734
  placement: Signal<Placement>;
728
735
  offset: Signal<NgpOffset>;
729
736
  flip: Signal<NgpFlip>;
730
737
  shift: Signal<NgpShift>;
731
- container: Signal<string | HTMLElement | null>;
738
+ container: WritableSignal<string | HTMLElement | null>;
732
739
  open: Signal<boolean>;
733
740
  id: string;
734
741
  contentId: Signal<string | undefined>;
@@ -737,6 +744,7 @@ declare const NgpNavigationMenuTriggerStateToken: _angular_core.InjectionToken<_
737
744
  focusFirstContentItem: (retryCount?: number) => void;
738
745
  focusLastContentItem: (retryCount?: number) => void;
739
746
  setContentId: (newId: string) => void;
747
+ setContainer: (newContainer: HTMLElement | string | null) => void;
740
748
  setPointerOverContent: (isOver: boolean) => void;
741
749
  setFocusInsideContent: (isFocused: boolean) => void;
742
750
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -748,7 +756,7 @@ declare const ngpNavigationMenuTrigger: ({ content: _content, disabled: _disable
748
756
  offset: Signal<NgpOffset>;
749
757
  flip: Signal<NgpFlip>;
750
758
  shift: Signal<NgpShift>;
751
- container: Signal<string | HTMLElement | null>;
759
+ container: WritableSignal<string | HTMLElement | null>;
752
760
  open: Signal<boolean>;
753
761
  id: string;
754
762
  contentId: Signal<string | undefined>;
@@ -757,6 +765,7 @@ declare const ngpNavigationMenuTrigger: ({ content: _content, disabled: _disable
757
765
  focusFirstContentItem: (retryCount?: number) => void;
758
766
  focusLastContentItem: (retryCount?: number) => void;
759
767
  setContentId: (newId: string) => void;
768
+ setContainer: (newContainer: HTMLElement | string | null) => void;
760
769
  setPointerOverContent: (isOver: boolean) => void;
761
770
  setFocusInsideContent: (isFocused: boolean) => void;
762
771
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -769,7 +778,7 @@ declare const injectNavigationMenuTriggerState: {
769
778
  offset: Signal<NgpOffset>;
770
779
  flip: Signal<NgpFlip>;
771
780
  shift: Signal<NgpShift>;
772
- container: Signal<string | HTMLElement | null>;
781
+ container: WritableSignal<string | HTMLElement | null>;
773
782
  open: Signal<boolean>;
774
783
  id: string;
775
784
  contentId: Signal<string | undefined>;
@@ -778,6 +787,7 @@ declare const injectNavigationMenuTriggerState: {
778
787
  focusFirstContentItem: (retryCount?: number) => void;
779
788
  focusLastContentItem: (retryCount?: number) => void;
780
789
  setContentId: (newId: string) => void;
790
+ setContainer: (newContainer: HTMLElement | string | null) => void;
781
791
  setPointerOverContent: (isOver: boolean) => void;
782
792
  setFocusInsideContent: (isFocused: boolean) => void;
783
793
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -789,7 +799,7 @@ declare const injectNavigationMenuTriggerState: {
789
799
  offset: Signal<NgpOffset>;
790
800
  flip: Signal<NgpFlip>;
791
801
  shift: Signal<NgpShift>;
792
- container: Signal<string | HTMLElement | null>;
802
+ container: WritableSignal<string | HTMLElement | null>;
793
803
  open: Signal<boolean>;
794
804
  id: string;
795
805
  contentId: Signal<string | undefined>;
@@ -798,6 +808,7 @@ declare const injectNavigationMenuTriggerState: {
798
808
  focusFirstContentItem: (retryCount?: number) => void;
799
809
  focusLastContentItem: (retryCount?: number) => void;
800
810
  setContentId: (newId: string) => void;
811
+ setContainer: (newContainer: HTMLElement | string | null) => void;
801
812
  setPointerOverContent: (isOver: boolean) => void;
802
813
  setFocusInsideContent: (isFocused: boolean) => void;
803
814
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -809,7 +820,7 @@ declare const injectNavigationMenuTriggerState: {
809
820
  offset: Signal<NgpOffset>;
810
821
  flip: Signal<NgpFlip>;
811
822
  shift: Signal<NgpShift>;
812
- container: Signal<string | HTMLElement | null>;
823
+ container: WritableSignal<string | HTMLElement | null>;
813
824
  open: Signal<boolean>;
814
825
  id: string;
815
826
  contentId: Signal<string | undefined>;
@@ -818,6 +829,7 @@ declare const injectNavigationMenuTriggerState: {
818
829
  focusFirstContentItem: (retryCount?: number) => void;
819
830
  focusLastContentItem: (retryCount?: number) => void;
820
831
  setContentId: (newId: string) => void;
832
+ setContainer: (newContainer: HTMLElement | string | null) => void;
821
833
  setPointerOverContent: (isOver: boolean) => void;
822
834
  setFocusInsideContent: (isFocused: boolean) => void;
823
835
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -828,7 +840,7 @@ declare const injectNavigationMenuTriggerState: {
828
840
  offset: Signal<NgpOffset>;
829
841
  flip: Signal<NgpFlip>;
830
842
  shift: Signal<NgpShift>;
831
- container: Signal<string | HTMLElement | null>;
843
+ container: WritableSignal<string | HTMLElement | null>;
832
844
  open: Signal<boolean>;
833
845
  id: string;
834
846
  contentId: Signal<string | undefined>;
@@ -837,6 +849,7 @@ declare const injectNavigationMenuTriggerState: {
837
849
  focusFirstContentItem: (retryCount?: number) => void;
838
850
  focusLastContentItem: (retryCount?: number) => void;
839
851
  setContentId: (newId: string) => void;
852
+ setContainer: (newContainer: HTMLElement | string | null) => void;
840
853
  setPointerOverContent: (isOver: boolean) => void;
841
854
  setFocusInsideContent: (isFocused: boolean) => void;
842
855
  registerContentFocusFunctions: (focusFirst: () => void, focusLast: () => void) => void;
@@ -159,7 +159,7 @@ interface NgpPopoverTriggerState<T> {
159
159
  * Define the container in which the popover should be attached.
160
160
  * @default document.body
161
161
  */
162
- readonly container: Signal<HTMLElement | string | null>;
162
+ readonly container: WritableSignal<HTMLElement | string | null>;
163
163
  /**
164
164
  * Define whether the popover should close when clicking outside of it, or a guard function.
165
165
  * @default true
@@ -209,6 +209,13 @@ interface NgpPopoverTriggerState<T> {
209
209
  readonly open: Signal<boolean>;
210
210
  /** @internal onDestroy callback */
211
211
  destroy: () => void;
212
+ /**
213
+ * Set the container in which the popover should be attached. Takes effect the
214
+ * next time the popover is opened; it does not move a popover that is already
215
+ * open.
216
+ * @param container - The new container
217
+ */
218
+ setContainer: (container: HTMLElement | string | null) => void;
212
219
  /**
213
220
  * Show the popover.
214
221
  * @returns A promise that resolves when the popover has been shown
@@ -308,7 +315,7 @@ interface NgpPopoverTriggerProps<T> {
308
315
  readonly onOpenChange?: (value: boolean) => void;
309
316
  }
310
317
  declare const NgpPopoverTriggerStateToken: _angular_core.InjectionToken<WritableSignal<NgpPopoverTriggerState<unknown>>>;
311
- declare const ngpPopoverTrigger: <T>({ popover: _popover, disabled, placement, offset, showDelay, hideDelay, flip, shift, container, closeOnOutsideClick, closeOnEscape, scrollBehavior, context, anchor, trackPosition, cooldown, onOpenChange, }: NgpPopoverTriggerProps<T>) => NgpPopoverTriggerState<T>;
318
+ declare const ngpPopoverTrigger: <T>({ popover: _popover, disabled, placement, offset, showDelay, hideDelay, flip, shift, container: _container, closeOnOutsideClick, closeOnEscape, scrollBehavior, context, anchor, trackPosition, cooldown, onOpenChange, }: NgpPopoverTriggerProps<T>) => NgpPopoverTriggerState<T>;
312
319
  declare const providePopoverTriggerState: (opts?: {
313
320
  inherit?: boolean;
314
321
  }) => _angular_core.FactoryProvider;
@@ -102,6 +102,12 @@ interface CooldownOverlay {
102
102
  hideImmediate(): void;
103
103
  /** Optional signal to mark the transition as instant due to cooldown */
104
104
  instantTransition?: WritableSignal<boolean>;
105
+ /**
106
+ * Optional check for whether this overlay is a descendant of the given overlay
107
+ * (i.e. its trigger is rendered within the other overlay's content). Used to
108
+ * keep an ancestor open when a nested overlay of the same type is activated.
109
+ */
110
+ isDescendantOf?(other: CooldownOverlay): boolean;
105
111
  }
106
112
  /**
107
113
  * Singleton service that tracks close timestamps and active overlays per overlay type.
@@ -112,6 +118,13 @@ interface CooldownOverlay {
112
118
  */
113
119
  declare class NgpOverlayCooldownManager {
114
120
  private readonly lastCloseTimestamps;
121
+ /**
122
+ * Active overlays per type, stored as a stack ordered oldest-first / topmost-last.
123
+ * Most types only ever hold a single overlay, but when an overlay is nested inside
124
+ * another of the same type (e.g. a popover whose trigger lives inside another
125
+ * popover) the child is pushed on top of its ancestor instead of evicting it.
126
+ * Closing the child then restores the ancestor as the active overlay.
127
+ */
115
128
  private readonly activeOverlays;
116
129
  /**
117
130
  * Record the close timestamp for an overlay type.
@@ -127,7 +140,14 @@ declare class NgpOverlayCooldownManager {
127
140
  isWithinCooldown(overlayType: string, duration: number): boolean;
128
141
  /**
129
142
  * Register an overlay as active for its type.
130
- * Any existing overlay of the same type will be closed immediately.
143
+ *
144
+ * Any existing overlay of the same type is closed immediately so that only one
145
+ * overlay of each type is open at a time - *unless* it is an ancestor of the
146
+ * overlay being registered. A nested overlay (its trigger rendered inside an
147
+ * ancestor overlay's content) is stacked on top of its ancestor instead of
148
+ * evicting it, allowing legitimate nesting to coexist while sibling overlays
149
+ * still replace one another.
150
+ *
131
151
  * @param overlayType The type identifier for the overlay group
132
152
  * @param overlay The overlay instance
133
153
  * @param cooldown The cooldown duration - if > 0, enables instant transitions
@@ -629,6 +649,16 @@ declare class NgpOverlay<T = unknown> implements CooldownOverlay {
629
649
  * @internal
630
650
  */
631
651
  unregisterChildOverlay(child: NgpOverlay): void;
652
+ /**
653
+ * Determine whether this overlay is a descendant of the given overlay - i.e.
654
+ * its trigger is rendered within the other overlay's content. Walks the parent
655
+ * overlay chain established through dependency injection.
656
+ *
657
+ * Used by the cooldown manager to avoid evicting an ancestor overlay when a
658
+ * nested overlay of the same type is activated.
659
+ * @internal
660
+ */
661
+ isDescendantOf(other: CooldownOverlay): boolean;
632
662
  /**
633
663
  * Check if the event path includes any child overlay elements (recursively).
634
664
  * @internal
@@ -229,7 +229,7 @@ interface NgpSelectState<T> {
229
229
  /** The position of the dropdown. */
230
230
  readonly placement: Signal<Placement>;
231
231
  /** The container for the dropdown. */
232
- readonly container: Signal<HTMLElement | string | null>;
232
+ readonly container: WritableSignal<HTMLElement | string | null>;
233
233
  /** Whether the dropdown should flip when there is not enough space. Can be a boolean to enable/disable, or an object with padding and fallbackPlacements options. */
234
234
  readonly flip: Signal<NgpFlip>;
235
235
  /**
@@ -381,6 +381,13 @@ interface NgpSelectState<T> {
381
381
  * `setDisabledState` integration.
382
382
  */
383
383
  setDisabled(disabled: boolean): void;
384
+ /**
385
+ * Set the container in which the dropdown should be attached. Takes effect the
386
+ * next time the dropdown is opened; it does not move a dropdown that is already
387
+ * open.
388
+ * @param container - The new container
389
+ */
390
+ setContainer(container: HTMLElement | string | null): void;
384
391
  /**
385
392
  * Observable that emits whenever the value changes.
386
393
  */
@@ -427,7 +434,7 @@ interface NgpSelectProps<T> {
427
434
  readonly allOptions?: Signal<T[] | undefined>;
428
435
  }
429
436
  declare const NgpSelectStateToken: _angular_core.InjectionToken<WritableSignal<NgpSelectState<unknown>>>;
430
- declare const ngpSelect: <T>({ id, value: _value, multiple, disabled: _disabled, compareWith, placement, container, flip, offset, scrollToOption, allOptions, onValueChange, onOpenChange, }: NgpSelectProps<T>) => NgpSelectState<T>;
437
+ declare const ngpSelect: <T>({ id, value: _value, multiple, disabled: _disabled, compareWith, placement, container: _container, flip, offset, scrollToOption, allOptions, onValueChange, onOpenChange, }: NgpSelectProps<T>) => NgpSelectState<T>;
431
438
  declare const provideSelectState: (opts?: {
432
439
  inherit?: boolean;
433
440
  }) => _angular_core.FactoryProvider;
@@ -48,6 +48,7 @@ interface NgpToastOptions$1 {
48
48
  declare class NgpToast {
49
49
  private readonly manager;
50
50
  private readonly injector;
51
+ private readonly elementRef;
51
52
  protected readonly config: ng_primitives_toast.NgpToastConfig;
52
53
  /** @internal */
53
54
  readonly options: NgpToastOptions$1;
@@ -108,9 +109,9 @@ declare class NgpToast {
108
109
  */
109
110
  private readonly timer;
110
111
  constructor();
111
- protected onPointerDown(event: PointerEvent): void;
112
- protected onPointerMove(event: PointerEvent): void;
113
- protected onPointerUp(): void;
112
+ private onPointerDown;
113
+ private onPointerMove;
114
+ private onPointerUp;
114
115
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgpToast, never>;
115
116
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgpToast, "[ngpToast]", ["ngpToast"], {}, {}, never, never, true, never>;
116
117
  }