@radix-ng/primitives 0.51.0 → 1.0.0-beta.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 (178) hide show
  1. package/fesm2022/radix-ng-primitives-accordion.mjs +105 -38
  2. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  3. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +221 -129
  4. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-arrow.mjs +20 -4
  6. package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-avatar.mjs +54 -61
  9. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-button.mjs +123 -0
  11. package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
  12. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-checkbox.mjs +378 -54
  14. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-collapsible.mjs +182 -81
  16. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-collection.mjs +40 -57
  18. package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-context-menu.mjs +140 -424
  21. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-core.mjs +735 -744
  23. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-cropper.mjs +1 -0
  25. package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-date-field.mjs +51 -45
  27. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-dialog.mjs +655 -327
  29. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +70 -46
  31. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
  33. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
  34. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-field.mjs +363 -0
  36. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
  37. package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
  38. package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
  39. package/fesm2022/radix-ng-primitives-focus-scope.mjs +23 -8
  40. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  41. package/fesm2022/radix-ng-primitives-input.mjs +172 -0
  42. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
  43. package/fesm2022/radix-ng-primitives-label.mjs +6 -6
  44. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  45. package/fesm2022/radix-ng-primitives-menu.mjs +1480 -344
  46. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  47. package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
  48. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  49. package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
  50. package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
  51. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1052 -1553
  52. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  53. package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -367
  54. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  55. package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-popover.mjs +978 -989
  57. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  58. package/fesm2022/radix-ng-primitives-popper.mjs +91 -41
  59. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-portal.mjs +34 -10
  61. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
  63. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  64. package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
  65. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
  66. package/fesm2022/radix-ng-primitives-progress.mjs +223 -84
  67. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  68. package/fesm2022/radix-ng-primitives-radio.mjs +191 -51
  69. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  70. package/fesm2022/radix-ng-primitives-roving-focus.mjs +96 -50
  71. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  72. package/fesm2022/radix-ng-primitives-select.mjs +791 -509
  73. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  74. package/fesm2022/radix-ng-primitives-separator.mjs +12 -35
  75. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  76. package/fesm2022/radix-ng-primitives-slider.mjs +969 -717
  77. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  78. package/fesm2022/radix-ng-primitives-stepper.mjs +15 -19
  79. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  80. package/fesm2022/radix-ng-primitives-switch.mjs +125 -113
  81. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  82. package/fesm2022/radix-ng-primitives-tabs.mjs +381 -108
  83. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  84. package/fesm2022/radix-ng-primitives-time-field.mjs +55 -46
  85. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  86. package/fesm2022/radix-ng-primitives-toggle-group.mjs +121 -247
  87. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  88. package/fesm2022/radix-ng-primitives-toggle.mjs +98 -61
  89. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  90. package/fesm2022/radix-ng-primitives-toolbar.mjs +303 -92
  91. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  92. package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1071
  93. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  94. package/fesm2022/radix-ng-primitives-visually-hidden.mjs +25 -66
  95. package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
  96. package/meter/README.md +3 -0
  97. package/navigation-menu/README.md +2 -1
  98. package/package.json +31 -18
  99. package/portal/README.md +2 -0
  100. package/preview-card/README.md +3 -0
  101. package/schematics/collection.json +1 -0
  102. package/schematics/ng-add/index.d.ts +3 -2
  103. package/schematics/ng-add/index.js +62 -31
  104. package/schematics/ng-add/index.js.map +1 -1
  105. package/schematics/ng-add/package-config.d.ts +4 -2
  106. package/schematics/ng-add/package-config.js +10 -2
  107. package/schematics/ng-add/package-config.js.map +1 -1
  108. package/schematics/ng-add/schema.d.ts +3 -0
  109. package/schematics/ng-add/schema.js +3 -0
  110. package/schematics/ng-add/schema.js.map +1 -0
  111. package/schematics/ng-add/schema.json +14 -0
  112. package/select/README.md +2 -0
  113. package/types/radix-ng-primitives-accordion.d.ts +48 -14
  114. package/types/radix-ng-primitives-alert-dialog.d.ts +95 -38
  115. package/types/radix-ng-primitives-arrow.d.ts +1 -1
  116. package/types/radix-ng-primitives-aspect-ratio.d.ts +1 -1
  117. package/types/radix-ng-primitives-avatar.d.ts +7 -11
  118. package/types/radix-ng-primitives-button.d.ts +73 -0
  119. package/types/radix-ng-primitives-calendar.d.ts +1 -2
  120. package/types/radix-ng-primitives-checkbox.d.ts +201 -32
  121. package/types/radix-ng-primitives-collapsible.d.ts +112 -39
  122. package/types/radix-ng-primitives-collection.d.ts +38 -34
  123. package/types/radix-ng-primitives-config.d.ts +1 -1
  124. package/types/radix-ng-primitives-context-menu.d.ts +60 -116
  125. package/types/radix-ng-primitives-core.d.ts +307 -236
  126. package/types/radix-ng-primitives-cropper.d.ts +2 -2
  127. package/types/radix-ng-primitives-date-field.d.ts +38 -23
  128. package/types/radix-ng-primitives-dialog.d.ts +282 -165
  129. package/types/radix-ng-primitives-dismissable-layer.d.ts +15 -7
  130. package/types/radix-ng-primitives-drawer.d.ts +448 -0
  131. package/types/radix-ng-primitives-editable.d.ts +1 -1
  132. package/types/radix-ng-primitives-field.d.ts +373 -0
  133. package/types/radix-ng-primitives-fieldset.d.ts +48 -0
  134. package/types/radix-ng-primitives-focus-scope.d.ts +13 -5
  135. package/types/radix-ng-primitives-input.d.ts +87 -0
  136. package/types/radix-ng-primitives-label.d.ts +0 -1
  137. package/types/radix-ng-primitives-menu.d.ts +572 -99
  138. package/types/radix-ng-primitives-menubar.d.ts +60 -50
  139. package/types/radix-ng-primitives-meter.d.ts +193 -0
  140. package/types/radix-ng-primitives-navigation-menu.d.ts +422 -340
  141. package/types/radix-ng-primitives-number-field.d.ts +405 -145
  142. package/types/radix-ng-primitives-pagination.d.ts +2 -2
  143. package/types/radix-ng-primitives-popover.d.ts +365 -351
  144. package/types/radix-ng-primitives-popper.d.ts +49 -9
  145. package/types/radix-ng-primitives-portal.d.ts +14 -6
  146. package/types/radix-ng-primitives-presence.d.ts +28 -76
  147. package/types/radix-ng-primitives-preview-card.d.ts +359 -0
  148. package/types/radix-ng-primitives-progress.d.ts +174 -48
  149. package/types/radix-ng-primitives-radio.d.ts +55 -25
  150. package/types/radix-ng-primitives-roving-focus.d.ts +30 -21
  151. package/types/radix-ng-primitives-select.d.ts +475 -177
  152. package/types/radix-ng-primitives-separator.d.ts +7 -32
  153. package/types/radix-ng-primitives-slider.d.ts +315 -201
  154. package/types/radix-ng-primitives-stepper.d.ts +5 -7
  155. package/types/radix-ng-primitives-switch.d.ts +86 -71
  156. package/types/radix-ng-primitives-tabs.d.ts +213 -79
  157. package/types/radix-ng-primitives-time-field.d.ts +42 -27
  158. package/types/radix-ng-primitives-toggle-group.d.ts +85 -164
  159. package/types/radix-ng-primitives-toggle.d.ts +43 -53
  160. package/types/radix-ng-primitives-toolbar.d.ts +163 -38
  161. package/types/radix-ng-primitives-tooltip.d.ts +347 -384
  162. package/types/radix-ng-primitives-visually-hidden.d.ts +19 -19
  163. package/dropdown-menu/README.md +0 -1
  164. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -581
  165. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
  166. package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1238
  167. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
  168. package/fesm2022/radix-ng-primitives-select2.mjs +0 -897
  169. package/fesm2022/radix-ng-primitives-select2.mjs.map +0 -1
  170. package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -735
  171. package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
  172. package/hover-card/README.md +0 -3
  173. package/select2/README.md +0 -3
  174. package/tooltip2/README.md +0 -3
  175. package/types/radix-ng-primitives-dropdown-menu.d.ts +0 -171
  176. package/types/radix-ng-primitives-hover-card.d.ts +0 -471
  177. package/types/radix-ng-primitives-select2.d.ts +0 -511
  178. package/types/radix-ng-primitives-tooltip2.d.ts +0 -325
@@ -1,1129 +1,1118 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, TemplateRef, DestroyRef, computed, input, numberAttribute, booleanAttribute, output, effect, untracked, SimpleChange, Directive, ElementRef, NgZone, Renderer2, isDevMode, VERSION, Injectable, makeEnvironmentProviders, signal, contentChild, ViewContainerRef, afterNextRender, assertInInjectionContext, forwardRef, ContentChild, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/cdk/overlay';
4
- import { Overlay, CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
5
- import { RdxPositionSide, RdxPositionAlign, RDX_POSITIONING_DEFAULTS, getContentPosition, getAllPossibleConnectedPositions, injectDocument, injectWindow, getArrowPositionParams, getSideAndAlignFromAllPossibleConnectedPositions, RdxFocusInitialDirective } from '@radix-ng/primitives/core';
6
- import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
7
- import { filter, tap } from 'rxjs';
8
- import * as i1$1 from '@angular/cdk/a11y';
9
- import { CdkTrapFocus } from '@angular/cdk/a11y';
2
+ import { booleanAttribute, inject, DestroyRef, signal, model, input, output, computed, effect, untracked, Directive, ElementRef, numberAttribute, afterNextRender, NgModule } from '@angular/core';
3
+ import * as i1 from '@radix-ng/primitives/popper';
4
+ import { RdxPopper, RdxPopperContentWrapper, RdxPopperArrow, RdxPopperContent, provideRdxPopperContentConfig, RdxPopperAnchor } from '@radix-ng/primitives/popper';
5
+ import { createContext, useTransitionStatus, injectId, useScrollLock, useGraceArea } from '@radix-ng/primitives/core';
6
+ import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
7
+ import * as i2 from '@radix-ng/primitives/dismissable-layer';
8
+ import { RdxDismissableLayer, provideRdxDismissableLayerConfig } from '@radix-ng/primitives/dismissable-layer';
9
+ import * as i3 from '@radix-ng/primitives/focus-scope';
10
+ import { RdxFocusScope, provideRdxFocusScopeConfig } from '@radix-ng/primitives/focus-scope';
11
+ import * as i1$1 from '@radix-ng/primitives/portal';
12
+ import { RdxPortal } from '@radix-ng/primitives/portal';
13
+ import * as i1$2 from '@radix-ng/primitives/presence';
14
+ import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence';
10
15
 
11
- const RdxPopoverAnchorToken = new InjectionToken('RdxPopoverAnchorToken');
12
-
13
- const RdxPopoverArrowToken = new InjectionToken('RdxPopoverArrowToken');
14
-
15
- const RdxPopoverCloseToken = new InjectionToken('RdxPopoverCloseToken');
16
-
17
- const RdxPopoverContentAttributesToken = new InjectionToken('RdxPopoverContentAttributesToken');
18
-
19
- var RdxPopoverState;
20
- (function (RdxPopoverState) {
21
- RdxPopoverState["OPEN"] = "open";
22
- RdxPopoverState["CLOSED"] = "closed";
23
- })(RdxPopoverState || (RdxPopoverState = {}));
24
- var RdxPopoverAttachDetachEvent;
25
- (function (RdxPopoverAttachDetachEvent) {
26
- RdxPopoverAttachDetachEvent["ATTACH"] = "attach";
27
- RdxPopoverAttachDetachEvent["DETACH"] = "detach";
28
- })(RdxPopoverAttachDetachEvent || (RdxPopoverAttachDetachEvent = {}));
29
- var RdxPopoverAnimationStatus;
30
- (function (RdxPopoverAnimationStatus) {
31
- RdxPopoverAnimationStatus["OPEN_STARTED"] = "open_started";
32
- RdxPopoverAnimationStatus["OPEN_ENDED"] = "open_ended";
33
- RdxPopoverAnimationStatus["CLOSED_STARTED"] = "closed_started";
34
- RdxPopoverAnimationStatus["CLOSED_ENDED"] = "closed_ended";
35
- })(RdxPopoverAnimationStatus || (RdxPopoverAnimationStatus = {}));
36
-
37
- class RdxPopoverContentDirective {
16
+ const transformModal = (value) => value === 'trap-focus' ? value : booleanAttribute(value);
17
+ const context = () => contextFor(inject(RdxPopoverRoot));
18
+ const [injectRdxPopoverRootContext, provideRdxPopoverRootContext] = createContext('RdxPopoverRootContext');
19
+ /**
20
+ * Groups all parts of the popover.
21
+ */
22
+ class RdxPopoverRoot {
38
23
  constructor() {
39
- /** @ignore */
40
- this.popoverRoot = injectPopoverRoot();
41
- /** @ignore */
42
- this.templateRef = inject(TemplateRef);
43
- /** @ignore */
44
- this.overlay = inject(Overlay);
45
- /** @ignore */
24
+ this.popper = inject(RdxPopper);
46
25
  this.destroyRef = inject(DestroyRef);
47
- /** @ignore */
48
- this.connectedOverlay = inject(CdkConnectedOverlay);
49
- /** @ignore */
50
- this.name = computed(() => `rdx-popover-trigger-${this.popoverRoot.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
51
- /**
52
- * @description The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
53
- * @default top
54
- */
55
- this.side = input(RdxPositionSide.Top, ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
56
- /**
57
- * @description The distance in pixels from the trigger.
58
- * @default undefined
59
- */
60
- this.sideOffset = input(NaN, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
61
- /**
62
- * @description The preferred alignment against the trigger. May change when collisions occur.
63
- * @default center
64
- */
65
- this.align = input(RdxPositionAlign.Center, ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
26
+ this.hasAppliedDefaultOpen = false;
27
+ this.hasAppliedDefaultTriggerId = false;
28
+ this.hoverDelay = 300;
29
+ this.hoverCloseDelay = 0;
30
+ this.transition = useTransitionStatus((open) => {
31
+ this.instant.set(false);
32
+ this.onOpenChangeComplete.emit(open);
33
+ });
34
+ this.isHoverActive = signal(false, ...(ngDevMode ? [{ debugName: "isHoverActive" }] : /* istanbul ignore next */ []));
35
+ this.instant = signal(false, ...(ngDevMode ? [{ debugName: "instant" }] : /* istanbul ignore next */ []));
36
+ this.openChangeReason = signal('none', ...(ngDevMode ? [{ debugName: "openChangeReason" }] : /* istanbul ignore next */ []));
37
+ this.transitionStatus = this.transition.status;
66
38
  /**
67
- * @description An offset in pixels from the "start" or "end" alignment options.
68
- * @default undefined
39
+ * Whether the popover is currently open.
69
40
  */
70
- this.alignOffset = input(NaN, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
41
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
71
42
  /**
72
- * @description Whether to add some alternate positions of the content.
73
- * @default false
43
+ * Whether the popover is initially open.
74
44
  */
75
- this.alternatePositionsDisabled = input(false, { ...(ngDevMode ? { debugName: "alternatePositionsDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
76
- /** @description Whether to prevent `onOverlayEscapeKeyDown` handler from calling. */
77
- this.onOverlayEscapeKeyDownDisabled = input(false, { ...(ngDevMode ? { debugName: "onOverlayEscapeKeyDownDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
78
- /** @description Whether to prevent `onOverlayOutsideClick` handler from calling. */
79
- this.onOverlayOutsideClickDisabled = input(false, { ...(ngDevMode ? { debugName: "onOverlayOutsideClickDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
45
+ this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
80
46
  /**
81
- * @description Event handler called when the escape key is down.
82
- * It can be prevented by setting `onOverlayEscapeKeyDownDisabled` input to `true`.
47
+ * ID of the trigger associated with a controlled popover.
83
48
  */
84
- this.onOverlayEscapeKeyDown = output();
49
+ this.triggerId = model(null, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
85
50
  /**
86
- * @description Event handler called when a pointer event occurs outside the bounds of the component.
87
- * It can be prevented by setting `onOverlayOutsideClickDisabled` input to `true`.
51
+ * ID of the trigger associated with an initially open uncontrolled popover.
88
52
  */
89
- this.onOverlayOutsideClick = output();
53
+ this.defaultTriggerId = input(null, ...(ngDevMode ? [{ debugName: "defaultTriggerId" }] : /* istanbul ignore next */ []));
90
54
  /**
91
- * @description Event handler called after the overlay is open
55
+ * Determines whether the popover blocks outside interaction or only traps focus.
92
56
  */
93
- this.onOpen = output();
57
+ this.modal = input(false, { ...(ngDevMode ? { debugName: "modal" } : /* istanbul ignore next */ {}), transform: transformModal });
94
58
  /**
95
- * @description Event handler called after the overlay is closed
59
+ * Associates this root with detached trigger elements.
96
60
  */
97
- this.onClosed = output();
98
- /** @ingore */
99
- this.positions = computed(() => this.computePositions(), ...(ngDevMode ? [{ debugName: "positions" }] : /* istanbul ignore next */ []));
100
- this.onOriginChangeEffect();
101
- this.onPositionChangeEffect();
61
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
62
+ this.contentId = injectId('rdx-popover-content-');
63
+ this.descriptionId = signal(undefined, ...(ngDevMode ? [{ debugName: "descriptionId" }] : /* istanbul ignore next */ []));
64
+ this.titleId = signal(undefined, ...(ngDevMode ? [{ debugName: "titleId" }] : /* istanbul ignore next */ []));
65
+ this.trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
66
+ this.triggers = signal([], ...(ngDevMode ? [{ debugName: "triggers" }] : /* istanbul ignore next */ []));
67
+ this.payload = signal(undefined, ...(ngDevMode ? [{ debugName: "payload" }] : /* istanbul ignore next */ []));
68
+ this.isPointerDownOnTrigger = signal(false, ...(ngDevMode ? [{ debugName: "isPointerDownOnTrigger" }] : /* istanbul ignore next */ []));
69
+ this.popupCloseCount = signal(0, ...(ngDevMode ? [{ debugName: "popupCloseCount" }] : /* istanbul ignore next */ []));
70
+ this.onOpenChange = output();
71
+ this.onOpenChangeComplete = output();
72
+ this.registeredTriggers = new Map();
73
+ this.viewportTriggerChange = new Set();
74
+ this.state = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
75
+ let previousOpen = this.open();
76
+ effect(() => {
77
+ const defaultOpen = this.defaultOpen();
78
+ if (!this.hasAppliedDefaultOpen && defaultOpen) {
79
+ this.hasAppliedDefaultOpen = true;
80
+ this.open.set(defaultOpen);
81
+ }
82
+ });
83
+ effect(() => {
84
+ const defaultTriggerId = this.defaultTriggerId();
85
+ if (!this.hasAppliedDefaultTriggerId && defaultTriggerId !== null) {
86
+ this.hasAppliedDefaultTriggerId = true;
87
+ this.triggerId.set(defaultTriggerId);
88
+ }
89
+ });
90
+ effect(() => {
91
+ const triggerId = this.triggerId();
92
+ untracked(() => this.syncTriggerId(triggerId));
93
+ });
94
+ effect(() => {
95
+ const open = this.open();
96
+ if (open !== previousOpen) {
97
+ previousOpen = open;
98
+ untracked(() => this.transition.start(open));
99
+ }
100
+ });
101
+ effect((onCleanup) => {
102
+ const handle = this.handle();
103
+ if (handle) {
104
+ onCleanup(untracked(() => handle.registerRoot(contextFor(this))));
105
+ }
106
+ });
107
+ effect(() => this.popper.anchorOverride.set(this.trigger()));
108
+ this.destroyRef.onDestroy(() => {
109
+ this.clearHoverTimers();
110
+ if (this.instantFrame !== undefined) {
111
+ cancelAnimationFrame(this.instantFrame);
112
+ }
113
+ });
102
114
  }
103
- /** @ignore */
104
- ngOnInit() {
105
- this.setScrollStrategy();
106
- this.setHasBackdrop();
107
- this.setDisableClose();
108
- this.onAttach();
109
- this.onDetach();
110
- this.connectKeydownEscape();
111
- this.connectOutsideClick();
115
+ show(trigger = this.trigger(), payload, triggerId, reason = 'none', event = new Event('popover.open-change'), fromHover = false) {
116
+ this.clearHoverTimers();
117
+ this.isHoverActive.set(fromHover);
118
+ this.openChangeReason.set(reason);
119
+ const previousTrigger = this.trigger();
120
+ const changedTriggerWhileOpen = this.open() && previousTrigger !== trigger;
121
+ this.instant.set(changedTriggerWhileOpen || reason === 'trigger-focus');
122
+ if (changedTriggerWhileOpen) {
123
+ this.scheduleInstantReset();
124
+ }
125
+ if (trigger) {
126
+ if (previousTrigger && previousTrigger !== trigger) {
127
+ this.viewportTriggerChange.forEach((notify) => notify(previousTrigger, trigger));
128
+ }
129
+ this.trigger.set(trigger);
130
+ }
131
+ if (triggerId !== undefined) {
132
+ this.triggerId.set(triggerId);
133
+ }
134
+ this.payload.set(payload);
135
+ const changed = !this.open() || previousTrigger !== trigger;
136
+ this.open.set(true);
137
+ if (changed) {
138
+ this.emitOpenChange(true, reason, event);
139
+ }
112
140
  }
113
- /** @ignore */
114
- open() {
115
- if (this.connectedOverlay.open) {
141
+ close(reason = 'none', event = new Event('popover.open-change')) {
142
+ this.clearHoverTimers();
143
+ this.isHoverActive.set(false);
144
+ if (!this.open()) {
116
145
  return;
117
146
  }
118
- const prevOpen = this.connectedOverlay.open;
119
- this.connectedOverlay.open = true;
120
- this.fireOverlayNgOnChanges('open', this.connectedOverlay.open, prevOpen);
121
- }
122
- /** @ignore */
123
- close() {
124
- if (!this.connectedOverlay.open) {
147
+ this.instant.set(reason !== 'none' && reason !== 'trigger-hover');
148
+ this.openChangeReason.set(reason);
149
+ this.open.set(false);
150
+ this.emitOpenChange(false, reason, event);
151
+ }
152
+ toggle(triggerId, trigger, payload, event) {
153
+ this.clearHoverTimers();
154
+ if (this.open() && this.trigger() === trigger) {
155
+ this.close('trigger-press', event);
125
156
  return;
126
157
  }
127
- const prevOpen = this.connectedOverlay.open;
128
- this.connectedOverlay.open = false;
129
- this.fireOverlayNgOnChanges('open', this.connectedOverlay.open, prevOpen);
130
- }
131
- /** @ignore */
132
- positionChange() {
133
- return this.connectedOverlay.positionChange.asObservable();
134
- }
135
- /** @ignore */
136
- connectKeydownEscape() {
137
- this.connectedOverlay.overlayKeydown
138
- .asObservable()
139
- .pipe(filter(() => !this.onOverlayEscapeKeyDownDisabled() &&
140
- !this.popoverRoot.rdxCdkEventService?.primitivePreventedFromCdkEvent(this.popoverRoot, 'cdkOverlayEscapeKeyDown')), filter((event) => event.key === 'Escape'), tap((event) => {
141
- this.onOverlayEscapeKeyDown.emit(event);
142
- }), filter(() => !this.popoverRoot.firstDefaultOpen()), tap(() => {
143
- this.popoverRoot.handleClose();
144
- }), takeUntilDestroyed(this.destroyRef))
145
- .subscribe();
146
- }
147
- /** @ignore */
148
- connectOutsideClick() {
149
- this.connectedOverlay.overlayOutsideClick
150
- .asObservable()
151
- .pipe(filter(() => !this.onOverlayOutsideClickDisabled() &&
152
- !this.popoverRoot.rdxCdkEventService?.primitivePreventedFromCdkEvent(this.popoverRoot, 'cdkOverlayOutsideClick')),
153
- /**
154
- * Handle the situation when an anchor is added and the anchor becomes the origin of the overlay
155
- * hence the trigger will be considered the outside element
156
- */
157
- filter((event) => {
158
- return (!this.popoverRoot.popoverAnchorDirective() ||
159
- !this.popoverRoot
160
- .popoverTriggerDirective()
161
- .elementRef.nativeElement.contains(event.target));
162
- }), tap((event) => {
163
- this.onOverlayOutsideClick.emit(event);
164
- }), filter(() => !this.popoverRoot.firstDefaultOpen()), tap(() => {
165
- this.popoverRoot.handleClose();
166
- }), takeUntilDestroyed(this.destroyRef))
167
- .subscribe();
168
- }
169
- /** @ignore */
170
- onAttach() {
171
- this.connectedOverlay.attach
172
- .asObservable()
173
- .pipe(tap(() => {
174
- /**
175
- * `this.onOpen.emit();` is being delegated to the root directive due to the opening animation
176
- */
177
- this.popoverRoot.attachDetachEvent.set(RdxPopoverAttachDetachEvent.ATTACH);
178
- }), takeUntilDestroyed(this.destroyRef))
179
- .subscribe();
158
+ this.show(trigger, payload, triggerId, 'trigger-press', event);
180
159
  }
181
- /** @ignore */
182
- onDetach() {
183
- this.connectedOverlay.detach
184
- .asObservable()
185
- .pipe(tap(() => {
186
- /**
187
- * `this.onClosed.emit();` is being delegated to the root directive due to the closing animation
188
- */
189
- this.popoverRoot.attachDetachEvent.set(RdxPopoverAttachDetachEvent.DETACH);
190
- }), takeUntilDestroyed(this.destroyRef))
191
- .subscribe();
160
+ openOnHover(trigger, payload, triggerId, event) {
161
+ this.clearHoverTimers();
162
+ this.isHoverActive.set(true);
163
+ if (this.open()) {
164
+ this.show(trigger, payload, triggerId, 'trigger-hover', event, true);
165
+ return;
166
+ }
167
+ this.openTimer = setTimeout(() => this.show(trigger, payload, triggerId, 'trigger-hover', event, true), this.hoverDelay);
192
168
  }
193
- /** @ignore */
194
- setScrollStrategy() {
195
- const prevScrollStrategy = this.connectedOverlay.scrollStrategy;
196
- this.connectedOverlay.scrollStrategy = this.overlay.scrollStrategies.reposition();
197
- this.fireOverlayNgOnChanges('scrollStrategy', this.connectedOverlay.scrollStrategy, prevScrollStrategy);
169
+ closeOnHover() {
170
+ if (!this.isHoverActive()) {
171
+ return;
172
+ }
173
+ this.clearOpenTimer();
174
+ this.clearCloseTimer();
175
+ this.closeTimer = setTimeout(() => this.close('trigger-hover', new Event('popover.hover-close')), this.hoverCloseDelay);
176
+ }
177
+ cancelHoverClose() {
178
+ this.clearCloseTimer();
179
+ }
180
+ cancelHoverOpen() {
181
+ this.clearOpenTimer();
182
+ }
183
+ setHoverDelays(delay, closeDelay) {
184
+ this.hoverDelay = delay;
185
+ this.hoverCloseDelay = closeDelay;
186
+ }
187
+ registerTrigger(id, trigger, payload) {
188
+ this.registeredTriggers.set(id, { element: trigger, payload });
189
+ this.triggers.update((triggers) => (triggers.includes(trigger) ? triggers : [...triggers, trigger]));
190
+ if (this.triggerId() === id) {
191
+ this.trigger.set(trigger);
192
+ this.payload.set(payload());
193
+ }
194
+ else if (!this.trigger() && this.triggerId() === null) {
195
+ this.trigger.set(trigger);
196
+ this.payload.set(payload());
197
+ }
198
+ return () => {
199
+ if (this.registeredTriggers.get(id)?.element === trigger) {
200
+ this.registeredTriggers.delete(id);
201
+ }
202
+ this.triggers.update((triggers) => triggers.filter((candidate) => candidate !== trigger));
203
+ if (this.destroyRef.destroyed) {
204
+ return;
205
+ }
206
+ if (this.trigger() === trigger) {
207
+ const next = this.registeredTriggers.entries().next().value;
208
+ if (this.triggerId() !== null) {
209
+ this.triggerId.set(next?.[0] ?? null);
210
+ }
211
+ this.trigger.set(next?.[1].element);
212
+ this.payload.set(next?.[1].payload());
213
+ if (!next && !this.destroyRef.destroyed) {
214
+ this.close();
215
+ }
216
+ }
217
+ };
198
218
  }
199
- /** @ignore */
200
- setHasBackdrop() {
201
- const prevHasBackdrop = this.connectedOverlay.hasBackdrop;
202
- this.connectedOverlay.hasBackdrop = false;
203
- this.fireOverlayNgOnChanges('hasBackdrop', this.connectedOverlay.hasBackdrop, prevHasBackdrop);
219
+ registerViewport(onTriggerChange) {
220
+ this.viewportTriggerChange.add(onTriggerChange);
221
+ return () => this.viewportTriggerChange.delete(onTriggerChange);
204
222
  }
205
- /** @ignore */
206
- setDisableClose() {
207
- const prevDisableClose = this.connectedOverlay.disableClose;
208
- this.connectedOverlay.disableClose = true;
209
- this.fireOverlayNgOnChanges('disableClose', this.connectedOverlay.disableClose, prevDisableClose);
223
+ registerTransitionElement(element) {
224
+ return this.transition.registerElement(element);
210
225
  }
211
- /** @ignore */
212
- setOrigin(origin) {
213
- const prevOrigin = this.connectedOverlay.origin;
214
- this.connectedOverlay.origin = origin;
215
- this.fireOverlayNgOnChanges('origin', this.connectedOverlay.origin, prevOrigin);
226
+ syncTriggerId(triggerId) {
227
+ if (triggerId === null) {
228
+ this.trigger.set(undefined);
229
+ this.payload.set(undefined);
230
+ return;
231
+ }
232
+ const trigger = this.registeredTriggers.get(triggerId);
233
+ if (!trigger) {
234
+ this.trigger.set(undefined);
235
+ this.payload.set(undefined);
236
+ return;
237
+ }
238
+ if (trigger.element === this.trigger()) {
239
+ return;
240
+ }
241
+ const previousTrigger = this.trigger();
242
+ if (previousTrigger && this.open()) {
243
+ this.viewportTriggerChange.forEach((notify) => notify(previousTrigger, trigger.element));
244
+ }
245
+ this.trigger.set(trigger.element);
246
+ this.payload.set(trigger.payload());
247
+ }
248
+ emitOpenChange(open, reason, event) {
249
+ this.onOpenChange.emit({
250
+ open,
251
+ triggerId: this.triggerId(),
252
+ trigger: this.trigger(),
253
+ reason,
254
+ event
255
+ });
216
256
  }
217
- /** @ignore */
218
- setPositions(positions) {
219
- const prevPositions = this.connectedOverlay.positions;
220
- this.connectedOverlay.positions = positions;
221
- this.fireOverlayNgOnChanges('positions', this.connectedOverlay.positions, prevPositions);
222
- this.connectedOverlay.overlayRef?.updatePosition();
257
+ clearHoverTimers() {
258
+ this.clearOpenTimer();
259
+ this.clearCloseTimer();
223
260
  }
224
- /** @ignore */
225
- computePositions() {
226
- const arrowHeight = this.popoverRoot.popoverArrowDirective()?.height() ?? 0;
227
- const offsets = {
228
- sideOffset: arrowHeight + (isNaN(this.sideOffset()) ? RDX_POSITIONING_DEFAULTS.offsets.side : this.sideOffset()),
229
- alignOffset: isNaN(this.alignOffset()) ? RDX_POSITIONING_DEFAULTS.offsets.align : this.alignOffset()
230
- };
231
- const basePosition = getContentPosition({
232
- side: this.side(),
233
- align: this.align(),
234
- sideOffset: offsets.sideOffset,
235
- alignOffset: offsets.alignOffset
236
- });
237
- const positions = [basePosition];
238
- if (!this.alternatePositionsDisabled()) {
239
- /**
240
- * Alternate positions for better user experience along the X/Y axis (e.g. vertical/horizontal scrolling)
241
- */
242
- const allPossibleConnectedPositions = getAllPossibleConnectedPositions();
243
- allPossibleConnectedPositions.forEach((_, key) => {
244
- const sideAndAlignArray = key.split('|');
245
- if (sideAndAlignArray[0] !== this.side() ||
246
- sideAndAlignArray[1] !== this.align()) {
247
- positions.push(getContentPosition({
248
- side: sideAndAlignArray[0],
249
- align: sideAndAlignArray[1],
250
- sideOffset: offsets.sideOffset,
251
- alignOffset: offsets.alignOffset
252
- }));
253
- }
254
- });
261
+ clearOpenTimer() {
262
+ if (this.openTimer !== undefined) {
263
+ clearTimeout(this.openTimer);
264
+ this.openTimer = undefined;
255
265
  }
256
- return positions;
257
266
  }
258
- onOriginChangeEffect() {
259
- effect(() => {
260
- const origin = (this.popoverRoot.popoverAnchorDirective() ?? this.popoverRoot.popoverTriggerDirective())
261
- .overlayOrigin;
262
- untracked(() => {
263
- this.setOrigin(origin);
264
- });
265
- });
266
- }
267
- /** @ignore */
268
- onPositionChangeEffect() {
269
- effect(() => {
270
- const positions = this.positions();
271
- this.alternatePositionsDisabled();
272
- untracked(() => {
273
- this.setPositions(positions);
274
- });
275
- });
267
+ clearCloseTimer() {
268
+ if (this.closeTimer !== undefined) {
269
+ clearTimeout(this.closeTimer);
270
+ this.closeTimer = undefined;
271
+ }
276
272
  }
277
- /** @ignore */
278
- fireOverlayNgOnChanges(input, currentValue, previousValue, firstChange = false) {
279
- this.connectedOverlay.ngOnChanges({
280
- [input]: new SimpleChange(previousValue, currentValue, firstChange)
273
+ scheduleInstantReset() {
274
+ if (this.instantFrame !== undefined) {
275
+ cancelAnimationFrame(this.instantFrame);
276
+ }
277
+ this.instantFrame = requestAnimationFrame(() => {
278
+ this.instantFrame = undefined;
279
+ if (!this.destroyRef.destroyed && this.open()) {
280
+ this.instant.set(false);
281
+ }
281
282
  });
282
283
  }
283
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
284
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverContentDirective, isStandalone: true, selector: "[rdxPopoverContent]", inputs: { side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, alignOffset: { classPropertyName: "alignOffset", publicName: "alignOffset", isSignal: true, isRequired: false, transformFunction: null }, alternatePositionsDisabled: { classPropertyName: "alternatePositionsDisabled", publicName: "alternatePositionsDisabled", isSignal: true, isRequired: false, transformFunction: null }, onOverlayEscapeKeyDownDisabled: { classPropertyName: "onOverlayEscapeKeyDownDisabled", publicName: "onOverlayEscapeKeyDownDisabled", isSignal: true, isRequired: false, transformFunction: null }, onOverlayOutsideClickDisabled: { classPropertyName: "onOverlayOutsideClickDisabled", publicName: "onOverlayOutsideClickDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onOverlayEscapeKeyDown: "onOverlayEscapeKeyDown", onOverlayOutsideClick: "onOverlayOutsideClick", onOpen: "onOpen", onClosed: "onClosed" }, hostDirectives: [{ directive: i1.CdkConnectedOverlay }], ngImport: i0 }); }
284
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
285
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverRoot, isStandalone: true, selector: "[rdxPopoverRoot]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, triggerId: { classPropertyName: "triggerId", publicName: "triggerId", isSignal: true, isRequired: false, transformFunction: null }, defaultTriggerId: { classPropertyName: "defaultTriggerId", publicName: "defaultTriggerId", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", triggerId: "triggerIdChange", onOpenChange: "onOpenChange", onOpenChangeComplete: "onOpenChangeComplete" }, providers: [provideRdxPopoverRootContext(context)], exportAs: ["rdxPopoverRoot"], hostDirectives: [{ directive: i1.RdxPopper }], ngImport: i0 }); }
285
286
  }
286
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverContentDirective, decorators: [{
287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverRoot, decorators: [{
287
288
  type: Directive,
288
289
  args: [{
289
- selector: '[rdxPopoverContent]',
290
- hostDirectives: [CdkConnectedOverlay]
290
+ selector: '[rdxPopoverRoot]',
291
+ exportAs: 'rdxPopoverRoot',
292
+ providers: [provideRdxPopoverRootContext(context)],
293
+ hostDirectives: [RdxPopper]
291
294
  }]
292
- }], ctorParameters: () => [], propDecorators: { side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], alignOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignOffset", required: false }] }], alternatePositionsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "alternatePositionsDisabled", required: false }] }], onOverlayEscapeKeyDownDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOverlayEscapeKeyDownDisabled", required: false }] }], onOverlayOutsideClickDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOverlayOutsideClickDisabled", required: false }] }], onOverlayEscapeKeyDown: [{ type: i0.Output, args: ["onOverlayEscapeKeyDown"] }], onOverlayOutsideClick: [{ type: i0.Output, args: ["onOverlayOutsideClick"] }], onOpen: [{ type: i0.Output, args: ["onOpen"] }], onClosed: [{ type: i0.Output, args: ["onClosed"] }] } });
295
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], triggerId: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerId", required: false }] }, { type: i0.Output, args: ["triggerIdChange"] }], defaultTriggerId: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTriggerId", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], handle: [{ type: i0.Input, args: [{ isSignal: true, alias: "handle", required: false }] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
296
+ function contextFor(root) {
297
+ return {
298
+ contentId: root.contentId,
299
+ descriptionId: root.descriptionId.asReadonly(),
300
+ isOpen: root.open,
301
+ modal: root.modal,
302
+ titleId: root.titleId.asReadonly(),
303
+ trigger: root.trigger.asReadonly(),
304
+ triggers: root.triggers.asReadonly(),
305
+ payload: root.payload.asReadonly(),
306
+ hasPopupClose: computed(() => root.popupCloseCount() > 0),
307
+ isHoverActive: root.isHoverActive.asReadonly(),
308
+ instant: root.instant.asReadonly(),
309
+ openChangeReason: root.openChangeReason.asReadonly(),
310
+ isPointerDownOnTrigger: root.isPointerDownOnTrigger.asReadonly(),
311
+ close: (reason, event) => root.close(reason, event),
312
+ cancelHoverClose: () => root.cancelHoverClose(),
313
+ cancelHoverOpen: () => root.cancelHoverOpen(),
314
+ closeOnHover: () => root.closeOnHover(),
315
+ open: (trigger, payload, triggerId, reason, event) => root.show(trigger, payload, triggerId, reason, event),
316
+ openOnHover: (trigger, payload, triggerId, event) => root.openOnHover(trigger, payload, triggerId, event),
317
+ registerTrigger: (id, trigger, payload) => root.registerTrigger(id, trigger, payload),
318
+ setDescriptionId: (id) => root.descriptionId.set(id),
319
+ setTitleId: (id) => root.titleId.set(id),
320
+ setPointerDownOnTrigger: (pointerDown) => root.isPointerDownOnTrigger.set(pointerDown),
321
+ setHoverDelays: (delay, closeDelay) => root.setHoverDelays(delay, closeDelay),
322
+ registerPopupClose: () => {
323
+ root.popupCloseCount.update((count) => count + 1);
324
+ return () => root.popupCloseCount.update((count) => count - 1);
325
+ },
326
+ registerTransitionElement: (element) => root.registerTransitionElement(element),
327
+ transitionStatus: root.transitionStatus,
328
+ registerViewport: (onTriggerChange) => root.registerViewport(onTriggerChange),
329
+ toggle: (triggerId, trigger, payload, event) => root.toggle(triggerId, trigger, payload, event)
330
+ };
331
+ }
293
332
 
294
- class RdxPopoverTriggerDirective {
333
+ /**
334
+ * An optional arrow element rendered alongside the popover.
335
+ */
336
+ class RdxPopoverArrow {
295
337
  constructor() {
296
- /** @ignore */
297
- this.popoverRoot = injectPopoverRoot();
298
- /** @ignore */
299
- this.elementRef = inject(ElementRef);
300
- /** @ignore */
301
- this.overlayOrigin = inject(CdkOverlayOrigin);
302
- /** @ignore */
303
- this.name = computed(() => `rdx-popover-trigger-${this.popoverRoot.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
304
- }
305
- /** @ignore */
306
- click() {
307
- this.popoverRoot.handleToggle();
308
- }
309
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
310
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverTriggerDirective, isStandalone: true, selector: "[rdxPopoverTrigger]", host: { attributes: { "type": "button" }, listeners: { "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "popoverRoot.isOpen()", "attr.aria-controls": "popoverRoot.popoverContentDirective().name()", "attr.data-state": "popoverRoot.state()" } }, hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
338
+ this.rootContext = injectRdxPopoverRootContext();
339
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
340
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
341
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
342
+ this.uncentered = computed(() => this.wrapper?.arrowUncentered() ?? false, ...(ngDevMode ? [{ debugName: "uncentered" }] : /* istanbul ignore next */ []));
343
+ }
344
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverArrow, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
345
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverArrow, isStandalone: true, selector: "[rdxPopoverArrow]", host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-side": "side()", "attr.data-align": "align()", "attr.data-uncentered": "uncentered() ? \"\" : undefined" } }, hostDirectives: [{ directive: i1.RdxPopperArrow }], ngImport: i0 }); }
311
346
  }
312
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTriggerDirective, decorators: [{
347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverArrow, decorators: [{
313
348
  type: Directive,
314
349
  args: [{
315
- selector: '[rdxPopoverTrigger]',
316
- hostDirectives: [CdkOverlayOrigin],
350
+ selector: '[rdxPopoverArrow]',
351
+ hostDirectives: [RdxPopperArrow],
317
352
  host: {
318
- type: 'button',
319
- '[attr.id]': 'name()',
320
- '[attr.aria-haspopup]': '"dialog"',
321
- '[attr.aria-expanded]': 'popoverRoot.isOpen()',
322
- '[attr.aria-controls]': 'popoverRoot.popoverContentDirective().name()',
323
- '[attr.data-state]': 'popoverRoot.state()',
324
- '(click)': 'click()'
353
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
354
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
355
+ '[attr.data-side]': 'side()',
356
+ '[attr.data-align]': 'align()',
357
+ '[attr.data-uncentered]': 'uncentered() ? "" : undefined'
325
358
  }
326
359
  }]
327
360
  }] });
328
361
 
329
- const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__');
330
-
331
- function eventTypeAsPrimitiveConfigKey(eventType) {
332
- return `prevent${eventType[0].toUpperCase()}${eventType.slice(1)}`;
333
- }
334
- class RdxCdkEventService {
335
- #clickDomRootEventCallbacks;
362
+ /**
363
+ * An optional backdrop rendered behind the popup.
364
+ */
365
+ class RdxPopoverBackdrop {
336
366
  constructor() {
337
- this.document = injectDocument();
338
- this.destroyRef = inject(DestroyRef);
339
- this.ngZone = inject(NgZone);
340
- this.renderer2 = inject(Renderer2);
341
- this.window = injectWindow();
342
- this.onDestroyCallbacks = new Set([() => deleteRdxCdkEventServiceWindowKey(this.window)]);
343
- this.#clickDomRootEventCallbacks = new Set();
344
- this.#listenToClickDomRootEvent();
345
- this.#registerOnDestroyCallbacks();
346
- }
347
- registerPrimitive(primitiveInstance) {
348
- if (!this.primitiveConfigs) {
349
- this.primitiveConfigs = new Map();
350
- }
351
- if (!this.primitiveConfigs.has(primitiveInstance)) {
352
- this.primitiveConfigs.set(primitiveInstance, {});
353
- }
354
- }
355
- deregisterPrimitive(primitiveInstance) {
356
- if (this.primitiveConfigs?.has(primitiveInstance)) {
357
- this.primitiveConfigs.delete(primitiveInstance);
358
- }
367
+ this.rootContext = injectRdxPopoverRootContext();
359
368
  }
360
- preventPrimitiveFromCdkEvent(primitiveInstance, eventType) {
361
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
362
- }
363
- allowPrimitiveForCdkEvent(primitiveInstance, eventType) {
364
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
365
- }
366
- preventPrimitiveFromCdkMultiEvents(primitiveInstance, eventTypes) {
367
- eventTypes.forEach((eventType) => {
368
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
369
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
370
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverBackdrop, isStandalone: true, selector: "[rdxPopoverBackdrop]", host: { properties: { "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"" } }, ngImport: i0 }); }
371
+ }
372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverBackdrop, decorators: [{
373
+ type: Directive,
374
+ args: [{
375
+ selector: '[rdxPopoverBackdrop]',
376
+ host: {
377
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
378
+ '[attr.data-ending-style]': 'rootContext.transitionStatus() === "ending" ? "" : undefined',
379
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
380
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
381
+ '[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
382
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"'
383
+ }
384
+ }]
385
+ }] });
386
+
387
+ /**
388
+ * A container for the popover contents.
389
+ */
390
+ class RdxPopoverPopup {
391
+ constructor() {
392
+ this.rootContext = injectRdxPopoverRootContext();
393
+ this.dismissableLayer = inject(RdxDismissableLayer);
394
+ this.focusScope = inject(RdxFocusScope);
395
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
396
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
397
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
398
+ this.dismissDetails = {
399
+ reason: 'none',
400
+ event: new Event('popover.dismiss')
401
+ };
402
+ /**
403
+ * Event handler called when the escape key is down. Can be prevented.
404
+ */
405
+ this.escapeKeyDown = outputFromObservable(outputToObservable(this.dismissableLayer.escapeKeyDown));
406
+ /**
407
+ * Event handler called when a pointerdown event happens outside of the popup. Can be prevented.
408
+ */
409
+ this.pointerDownOutside = outputFromObservable(outputToObservable(this.dismissableLayer.pointerDownOutside));
410
+ /**
411
+ * Event handler called when focus moves outside of the popup. Can be prevented.
412
+ */
413
+ this.focusOutside = outputFromObservable(outputToObservable(this.dismissableLayer.focusOutside));
414
+ /**
415
+ * Event handler called when an interaction happens outside of the popup. Can be prevented.
416
+ */
417
+ this.interactOutside = outputFromObservable(outputToObservable(this.dismissableLayer.interactOutside));
418
+ /**
419
+ * Event handler called before focus moves into the popup. Can be prevented.
420
+ */
421
+ this.openAutoFocus = outputFromObservable(outputToObservable(this.focusScope.mountAutoFocus));
422
+ /**
423
+ * Event handler called before focus returns after the popup is removed. Can be prevented.
424
+ */
425
+ this.closeAutoFocus = outputFromObservable(outputToObservable(this.focusScope.unmountAutoFocus));
426
+ useScrollLock(computed(() => this.rootContext.modal() === true));
427
+ const unregisterTransitionElement = this.rootContext.registerTransitionElement(inject(ElementRef).nativeElement);
428
+ inject(DestroyRef).onDestroy(unregisterTransitionElement);
429
+ this.dismissableLayer.pointerDownOutside.subscribe((event) => {
430
+ this.dismissDetails = { reason: 'outside-press', event };
431
+ if (this.rootContext.triggers().some((trigger) => trigger.contains(event.target))) {
432
+ event.preventDefault();
433
+ }
369
434
  });
370
- }
371
- allowPrimitiveForCdkMultiEvents(primitiveInstance, eventTypes) {
372
- eventTypes.forEach((eventType) => {
373
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
435
+ this.dismissableLayer.focusOutside.subscribe((event) => {
436
+ this.dismissDetails = { reason: 'focus-out', event };
437
+ if (this.rootContext.isPointerDownOnTrigger()) {
438
+ event.preventDefault();
439
+ }
374
440
  });
375
- }
376
- setPreventPrimitiveFromCdkMixEvents(primitiveInstance, eventTypes) {
377
- Object.keys(eventTypes).forEach((eventType) => {
378
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, eventTypes[eventTypeAsPrimitiveConfigKey(eventType)]);
441
+ this.dismissableLayer.escapeKeyDown.subscribe((event) => {
442
+ this.dismissDetails = { reason: 'escape-key', event };
379
443
  });
380
- }
381
- primitivePreventedFromCdkEvent(primitiveInstance, eventType) {
382
- return this.primitiveConfigs?.get(primitiveInstance)?.[eventTypeAsPrimitiveConfigKey(eventType)];
383
- }
384
- addClickDomRootEventCallback(callback) {
385
- this.#clickDomRootEventCallbacks.add(callback);
386
- }
387
- removeClickDomRootEventCallback(callback) {
388
- return this.#clickDomRootEventCallbacks.delete(callback);
389
- }
390
- #setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, value) {
391
- if (!this.primitiveConfigs?.has(primitiveInstance)) {
392
- isDevMode() &&
393
- console.error('[RdxCdkEventService.preventPrimitiveFromCdkEvent] RDX Primitive instance has not been registered!', primitiveInstance);
394
- return;
395
- }
396
- switch (eventType) {
397
- case 'cdkOverlayOutsideClick':
398
- this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayOutsideClick = value;
399
- break;
400
- case 'cdkOverlayEscapeKeyDown':
401
- this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayEscapeKeyDown = value;
402
- break;
403
- }
404
- }
405
- #registerOnDestroyCallbacks() {
406
- this.destroyRef.onDestroy(() => {
407
- this.onDestroyCallbacks.forEach((onDestroyCallback) => onDestroyCallback());
408
- this.onDestroyCallbacks.clear();
444
+ this.focusScope.mountAutoFocus.subscribe((event) => {
445
+ if (this.rootContext.isHoverActive()) {
446
+ event.preventDefault();
447
+ }
448
+ });
449
+ this.dismissableLayer.dismiss.subscribe(() => {
450
+ this.rootContext.close(this.dismissDetails.reason, this.dismissDetails.event);
451
+ this.dismissDetails = { reason: 'none', event: new Event('popover.dismiss') };
409
452
  });
410
453
  }
411
- #listenToClickDomRootEvent() {
412
- const target = this.document;
413
- const eventName = 'click';
414
- const options = { capture: true };
415
- const callback = (event) => {
416
- this.#clickDomRootEventCallbacks.forEach((clickDomRootEventCallback) => clickDomRootEventCallback(event));
417
- };
418
- const major = parseInt(VERSION.major);
419
- const minor = parseInt(VERSION.minor);
420
- let destroyClickDomRootEventListener;
421
- /**
422
- * @see src/cdk/platform/features/backwards-compatibility.ts in @angular/cdk
423
- */
424
- if (major > 19 || (major === 19 && minor > 0) || (major === 0 && minor === 0)) {
425
- destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
426
- const destroyClickDomRootEventListenerInternal = this.renderer2.listen(target, eventName, callback, options);
427
- return () => {
428
- destroyClickDomRootEventListenerInternal();
429
- this.#clickDomRootEventCallbacks.clear();
454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
455
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverPopup, isStandalone: true, selector: "[rdxPopoverPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside", interactOutside: "interactOutside", openAutoFocus: "openAutoFocus", closeAutoFocus: "closeAutoFocus" }, host: { attributes: { "role": "dialog" }, listeners: { "pointerenter": "rootContext.cancelHoverClose()" }, properties: { "attr.aria-describedby": "rootContext.descriptionId()", "attr.aria-labelledby": "rootContext.titleId()", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"", "attr.data-align": "align()", "attr.data-side": "side()", "id": "rootContext.contentId" } }, providers: [
456
+ provideRdxDismissableLayerConfig(() => {
457
+ const rootContext = injectRdxPopoverRootContext();
458
+ return {
459
+ disableOutsidePointerEvents: computed(() => rootContext.modal() === true)
430
460
  };
431
- });
432
- }
433
- else {
434
- /**
435
- * This part can get removed when v19.1 or higher is on the board
436
- */
437
- destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
438
- target.addEventListener(eventName, callback, options);
439
- return () => {
440
- this.ngZone.runOutsideAngular(() => target.removeEventListener(eventName, callback, options));
441
- this.#clickDomRootEventCallbacks.clear();
461
+ }),
462
+ provideRdxFocusScopeConfig(() => {
463
+ const rootContext = injectRdxPopoverRootContext();
464
+ return {
465
+ trapped: computed(() => rootContext.modal() === 'trap-focus' ||
466
+ (rootContext.modal() === true && rootContext.hasPopupClose()))
442
467
  };
443
- });
468
+ })
469
+ ], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxDismissableLayer }, { directive: i3.RdxFocusScope }], ngImport: i0 }); }
470
+ }
471
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPopup, decorators: [{
472
+ type: Directive,
473
+ args: [{
474
+ selector: '[rdxPopoverPopup]',
475
+ hostDirectives: [RdxPopperContent, RdxDismissableLayer, RdxFocusScope],
476
+ providers: [
477
+ provideRdxDismissableLayerConfig(() => {
478
+ const rootContext = injectRdxPopoverRootContext();
479
+ return {
480
+ disableOutsidePointerEvents: computed(() => rootContext.modal() === true)
481
+ };
482
+ }),
483
+ provideRdxFocusScopeConfig(() => {
484
+ const rootContext = injectRdxPopoverRootContext();
485
+ return {
486
+ trapped: computed(() => rootContext.modal() === 'trap-focus' ||
487
+ (rootContext.modal() === true && rootContext.hasPopupClose()))
488
+ };
489
+ })
490
+ ],
491
+ host: {
492
+ role: 'dialog',
493
+ '[attr.aria-describedby]': 'rootContext.descriptionId()',
494
+ '[attr.aria-labelledby]': 'rootContext.titleId()',
495
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
496
+ '[attr.data-ending-style]': 'rootContext.transitionStatus() === "ending" ? "" : undefined',
497
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
498
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
499
+ '[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
500
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"',
501
+ '[attr.data-align]': 'align()',
502
+ '[attr.data-side]': 'side()',
503
+ '[id]': 'rootContext.contentId',
504
+ '(pointerenter)': 'rootContext.cancelHoverClose()'
505
+ }
506
+ }]
507
+ }], ctorParameters: () => [], propDecorators: { escapeKeyDown: [{ type: i0.Output, args: ["escapeKeyDown"] }], pointerDownOutside: [{ type: i0.Output, args: ["pointerDownOutside"] }], focusOutside: [{ type: i0.Output, args: ["focusOutside"] }], interactOutside: [{ type: i0.Output, args: ["interactOutside"] }], openAutoFocus: [{ type: i0.Output, args: ["openAutoFocus"] }], closeAutoFocus: [{ type: i0.Output, args: ["closeAutoFocus"] }] } });
508
+
509
+ /**
510
+ * A button that closes the popover.
511
+ */
512
+ class RdxPopoverClose {
513
+ constructor() {
514
+ this.rootContext = injectRdxPopoverRootContext();
515
+ if (inject(RdxPopoverPopup, { optional: true })) {
516
+ const unregister = this.rootContext.registerPopupClose();
517
+ inject(DestroyRef).onDestroy(unregister);
444
518
  }
445
- this.onDestroyCallbacks.add(destroyClickDomRootEventListener);
446
519
  }
447
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCdkEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
448
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCdkEventService }); }
520
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverClose, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
521
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverClose, isStandalone: true, selector: "button[rdxPopoverClose]", host: { attributes: { "type": "button" }, listeners: { "click": "rootContext.close(\"close-press\", $event)" } }, ngImport: i0 }); }
449
522
  }
450
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCdkEventService, decorators: [{
451
- type: Injectable
523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverClose, decorators: [{
524
+ type: Directive,
525
+ args: [{
526
+ selector: 'button[rdxPopoverClose]',
527
+ host: {
528
+ type: 'button',
529
+ '(click)': 'rootContext.close("close-press", $event)'
530
+ }
531
+ }]
452
532
  }], ctorParameters: () => [] });
453
- const RdxCdkEventServiceToken = new InjectionToken('RdxCdkEventServiceToken');
454
- const existsErrorMessage = 'RdxCdkEventService should be provided only once!';
455
- const deleteRdxCdkEventServiceWindowKey = (window) => {
456
- delete window[RdxCdkEventServiceWindowKey];
457
- };
458
- const getProvider = (throwWhenExists = true) => ({
459
- provide: RdxCdkEventServiceToken,
460
- useFactory: () => {
461
- isDevMode() && console.log('providing RdxCdkEventService...');
462
- const window = injectWindow();
463
- if (window[RdxCdkEventServiceWindowKey]) {
464
- if (throwWhenExists) {
465
- throw Error(existsErrorMessage);
466
- }
467
- else {
468
- isDevMode() && console.warn(existsErrorMessage);
469
- }
470
- }
471
- window[RdxCdkEventServiceWindowKey] ??= new RdxCdkEventService();
472
- return window[RdxCdkEventServiceWindowKey];
533
+
534
+ /**
535
+ * An accessible description for the popover.
536
+ */
537
+ class RdxPopoverDescription {
538
+ constructor() {
539
+ this.rootContext = injectRdxPopoverRootContext();
540
+ this.id = injectId('rdx-popover-description-');
541
+ this.rootContext.setDescriptionId(this.id);
542
+ inject(DestroyRef).onDestroy(() => this.rootContext.setDescriptionId(undefined));
543
+ }
544
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverDescription, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
545
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverDescription, isStandalone: true, selector: "[rdxPopoverDescription]", host: { properties: { "id": "id" } }, ngImport: i0 }); }
546
+ }
547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverDescription, decorators: [{
548
+ type: Directive,
549
+ args: [{
550
+ selector: '[rdxPopoverDescription]',
551
+ host: {
552
+ '[id]': 'id'
553
+ }
554
+ }]
555
+ }], ctorParameters: () => [] });
556
+
557
+ /**
558
+ * Moves the popover to a different part of the DOM.
559
+ */
560
+ class RdxPopoverPortal {
561
+ constructor() {
562
+ this.rootContext = injectRdxPopoverRootContext();
563
+ /**
564
+ * Optional container to portal the content into. Defaults to `document.body`.
565
+ */
566
+ this.container = input(...(ngDevMode ? [undefined, { debugName: "container" }] : /* istanbul ignore next */ []));
473
567
  }
474
- });
475
- const provideRdxCdkEventServiceInRoot = () => makeEnvironmentProviders([getProvider()]);
476
- const provideRdxCdkEventService = () => getProvider(false);
477
- const injectRdxCdkEventService = () => inject(RdxCdkEventServiceToken, { optional: true });
568
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
569
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverPortal, isStandalone: true, selector: "[rdxPopoverPortal]", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"" } }, hostDirectives: [{ directive: i1$1.RdxPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
570
+ }
571
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPortal, decorators: [{
572
+ type: Directive,
573
+ args: [{
574
+ selector: '[rdxPopoverPortal]',
575
+ hostDirectives: [
576
+ {
577
+ directive: RdxPortal,
578
+ inputs: ['container']
579
+ }
580
+ ],
581
+ host: {
582
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
583
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
584
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"'
585
+ }
586
+ }]
587
+ }], propDecorators: { container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: false }] }] } });
588
+
589
+ /**
590
+ * Mounts the portal while the popover is open and waits for CSS exit keyframes before unmounting.
591
+ */
592
+ class RdxPopoverPortalPresence {
593
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPortalPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
594
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverPortalPresence, isStandalone: true, selector: "ng-template[rdxPopoverPortalPresence]", providers: [
595
+ provideRdxPresenceContext(() => {
596
+ const context = injectRdxPopoverRootContext();
597
+ return { present: context.isOpen };
598
+ })
599
+ ], hostDirectives: [{ directive: i1$2.RdxPresenceDirective }], ngImport: i0 }); }
600
+ }
601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPortalPresence, decorators: [{
602
+ type: Directive,
603
+ args: [{
604
+ selector: 'ng-template[rdxPopoverPortalPresence]',
605
+ hostDirectives: [RdxPresenceDirective],
606
+ providers: [
607
+ provideRdxPresenceContext(() => {
608
+ const context = injectRdxPopoverRootContext();
609
+ return { present: context.isOpen };
610
+ })
611
+ ]
612
+ }]
613
+ }] });
478
614
 
479
- let nextId = 0;
480
- class RdxPopoverRootDirective {
615
+ /**
616
+ * Positions the popover against its trigger.
617
+ */
618
+ class RdxPopoverPositioner {
481
619
  constructor() {
482
- /** @ignore */
483
- this.uniqueId = signal(++nextId, ...(ngDevMode ? [{ debugName: "uniqueId" }] : /* istanbul ignore next */ []));
484
- /** @ignore */
485
- this.name = computed(() => `rdx-popover-root-${this.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
620
+ this.rootContext = injectRdxPopoverRootContext();
621
+ this.wrapper = inject(RdxPopperContentWrapper);
622
+ this.elementRef = inject(ElementRef);
623
+ this.triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
624
+ this.containerEl = signal(this.elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "containerEl" }] : /* istanbul ignore next */ []));
625
+ this.graceArea = useGraceArea(this.triggerEl, this.containerEl);
486
626
  /**
487
- * @description The anchor directive that comes form outside the popover root
488
- * @default undefined
627
+ * An element to position the popup against. Defaults to the trigger.
489
628
  */
490
- this.anchor = input(void 0, ...(ngDevMode ? [{ debugName: "anchor" }] : /* istanbul ignore next */ []));
629
+ this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
491
630
  /**
492
- * @description The open state of the popover when it is initially rendered. Use when you do not need to control its open state.
493
- * @default false
631
+ * The preferred side of the trigger to render against when open.
494
632
  */
495
- this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
633
+ this.side = input('bottom', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
496
634
  /**
497
- * @description The controlled state of the popover. `open` input take precedence of `defaultOpen` input.
498
- * @default undefined
635
+ * Distance between the trigger and the popup in pixels.
499
636
  */
500
- this.open = input(void 0, { ...(ngDevMode ? { debugName: "open" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
637
+ this.sideOffset = input(0, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
501
638
  /**
502
- * @description Whether to control the state of the popover from external. Use in conjunction with `open` input.
503
- * @default undefined
639
+ * How to align the popup relative to the specified side.
504
640
  */
505
- this.externalControl = input(void 0, { ...(ngDevMode ? { debugName: "externalControl" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
641
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
506
642
  /**
507
- * @description Whether to take into account CSS opening/closing animations.
508
- * @default false
643
+ * An offset in pixels from the `start` or `end` alignment options.
509
644
  */
510
- this.cssAnimation = input(false, { ...(ngDevMode ? { debugName: "cssAnimation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
645
+ this.alignOffset = input(0, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
511
646
  /**
512
- * @description Whether to take into account CSS opening animations. `cssAnimation` input must be set to 'true'
513
- * @default false
647
+ * Minimum distance to maintain between the arrow and the edges of the popup.
514
648
  */
515
- this.cssOpeningAnimation = input(false, { ...(ngDevMode ? { debugName: "cssOpeningAnimation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
649
+ this.arrowPadding = input(5, { ...(ngDevMode ? { debugName: "arrowPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
516
650
  /**
517
- * @description Whether to take into account CSS closing animations. `cssAnimation` input must be set to 'true'
518
- * @default false
651
+ * Whether to override side and alignment preferences to prevent collisions.
519
652
  */
520
- this.cssClosingAnimation = input(false, { ...(ngDevMode ? { debugName: "cssClosingAnimation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
521
- /** @ignore */
522
- this.cssAnimationStatus = signal(null, ...(ngDevMode ? [{ debugName: "cssAnimationStatus" }] : /* istanbul ignore next */ []));
523
- /** @ignore */
524
- this.popoverContentDirective = contentChild.required(RdxPopoverContentDirective);
525
- /** @ignore */
526
- this.popoverTriggerDirective = contentChild.required(RdxPopoverTriggerDirective);
527
- /** @ignore */
528
- this.popoverArrowDirective = contentChild(RdxPopoverArrowToken, ...(ngDevMode ? [{ debugName: "popoverArrowDirective" }] : /* istanbul ignore next */ []));
529
- /** @ignore */
530
- this.popoverCloseDirective = contentChild(RdxPopoverCloseToken, ...(ngDevMode ? [{ debugName: "popoverCloseDirective" }] : /* istanbul ignore next */ []));
531
- /** @ignore */
532
- this.popoverContentAttributesComponent = contentChild(RdxPopoverContentAttributesToken, ...(ngDevMode ? [{ debugName: "popoverContentAttributesComponent" }] : /* istanbul ignore next */ []));
533
- /** @ignore */
534
- this.internalPopoverAnchorDirective = contentChild(RdxPopoverAnchorToken, ...(ngDevMode ? [{ debugName: "internalPopoverAnchorDirective" }] : /* istanbul ignore next */ []));
535
- /** @ignore */
536
- this.viewContainerRef = inject(ViewContainerRef);
537
- /** @ignore */
538
- this.rdxCdkEventService = injectRdxCdkEventService();
539
- /** @ignore */
540
- this.destroyRef = inject(DestroyRef);
541
- /** @ignore */
542
- this.state = signal(RdxPopoverState.CLOSED, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
543
- /** @ignore */
544
- this.attachDetachEvent = signal(RdxPopoverAttachDetachEvent.DETACH, ...(ngDevMode ? [{ debugName: "attachDetachEvent" }] : /* istanbul ignore next */ []));
545
- /** @ignore */
546
- this.isFirstDefaultOpen = signal(false, ...(ngDevMode ? [{ debugName: "isFirstDefaultOpen" }] : /* istanbul ignore next */ []));
547
- /** @ignore */
548
- this.popoverAnchorDirective = computed(() => this.internalPopoverAnchorDirective() ?? this.anchor(), ...(ngDevMode ? [{ debugName: "popoverAnchorDirective" }] : /* istanbul ignore next */ []));
549
- /** @ignore */
550
- this.onAnchorChangeEffect = () => {
551
- effect(() => {
552
- const anchor = this.anchor();
553
- untracked(() => {
554
- if (anchor) {
555
- anchor.setPopoverRoot(this);
556
- }
557
- });
558
- });
559
- };
560
- this.rdxCdkEventService?.registerPrimitive(this);
561
- this.destroyRef.onDestroy(() => this.rdxCdkEventService?.deregisterPrimitive(this));
562
- this.onStateChangeEffect();
563
- this.onCssAnimationStatusChangeChangeEffect();
564
- this.onOpenChangeEffect();
565
- this.onIsFirstDefaultOpenChangeEffect();
566
- this.onAnchorChangeEffect();
567
- this.emitOpenOrClosedEventEffect();
568
- afterNextRender({
569
- write: () => {
570
- if (this.defaultOpen() && !this.open()) {
571
- this.isFirstDefaultOpen.set(true);
572
- }
573
- }
574
- });
575
- }
576
- /** @ignore */
577
- getAnimationParamsSnapshot() {
578
- return {
579
- cssAnimation: this.cssAnimation(),
580
- cssOpeningAnimation: this.cssOpeningAnimation(),
581
- cssClosingAnimation: this.cssClosingAnimation(),
582
- cssAnimationStatus: this.cssAnimationStatus(),
583
- attachDetachEvent: this.attachDetachEvent(),
584
- state: this.state(),
585
- canEmitOnOpenOrOnClosed: this.canEmitOnOpenOrOnClosed()
586
- };
587
- }
588
- /** @ignore */
589
- controlledExternally() {
590
- return this.externalControl;
591
- }
592
- /** @ignore */
593
- firstDefaultOpen() {
594
- return this.isFirstDefaultOpen();
595
- }
596
- /** @ignore */
597
- handleOpen() {
598
- if (this.externalControl()) {
599
- return;
600
- }
601
- this.setState(RdxPopoverState.OPEN);
602
- }
603
- /** @ignore */
604
- handleClose() {
605
- if (this.isFirstDefaultOpen()) {
606
- this.isFirstDefaultOpen.set(false);
607
- }
608
- if (this.externalControl()) {
609
- return;
610
- }
611
- this.setState(RdxPopoverState.CLOSED);
612
- }
613
- /** @ignore */
614
- handleToggle() {
615
- if (this.externalControl()) {
616
- return;
617
- }
618
- this.isOpen() ? this.handleClose() : this.handleOpen();
619
- }
620
- /** @ignore */
621
- isOpen(state) {
622
- return (state ?? this.state()) === RdxPopoverState.OPEN;
623
- }
624
- /** @ignore */
625
- setState(state = RdxPopoverState.CLOSED) {
626
- if (state === this.state()) {
627
- return;
628
- }
629
- this.state.set(state);
630
- }
631
- /** @ignore */
632
- openContent() {
633
- this.popoverContentDirective().open();
634
- if (!this.cssAnimation() || !this.cssOpeningAnimation()) {
635
- this.cssAnimationStatus.set(null);
636
- }
637
- }
638
- /** @ignore */
639
- closeContent() {
640
- this.popoverContentDirective().close();
641
- if (!this.cssAnimation() || !this.cssClosingAnimation()) {
642
- this.cssAnimationStatus.set(null);
643
- }
644
- }
645
- /** @ignore */
646
- emitOnOpen() {
647
- this.popoverContentDirective().onOpen.emit();
648
- }
649
- /** @ignore */
650
- emitOnClosed() {
651
- this.popoverContentDirective().onClosed.emit();
652
- }
653
- /** @ignore */
654
- ifOpenOrCloseWithoutAnimations(state) {
655
- return (!this.popoverContentAttributesComponent() ||
656
- !this.cssAnimation() ||
657
- (this.cssAnimation() && !this.cssClosingAnimation() && state === RdxPopoverState.CLOSED) ||
658
- (this.cssAnimation() && !this.cssOpeningAnimation() && state === RdxPopoverState.OPEN) ||
659
- // !this.cssAnimationStatus() ||
660
- (this.cssOpeningAnimation() &&
661
- state === RdxPopoverState.OPEN &&
662
- [RdxPopoverAnimationStatus.OPEN_STARTED].includes(this.cssAnimationStatus())) ||
663
- (this.cssClosingAnimation() &&
664
- state === RdxPopoverState.CLOSED &&
665
- [RdxPopoverAnimationStatus.CLOSED_STARTED].includes(this.cssAnimationStatus())));
666
- }
667
- /** @ignore */
668
- ifOpenOrCloseWithAnimations(cssAnimationStatus) {
669
- return (this.popoverContentAttributesComponent() &&
670
- this.cssAnimation() &&
671
- cssAnimationStatus &&
672
- ((this.cssOpeningAnimation() &&
673
- this.state() === RdxPopoverState.OPEN &&
674
- [RdxPopoverAnimationStatus.OPEN_ENDED].includes(cssAnimationStatus)) ||
675
- (this.cssClosingAnimation() &&
676
- this.state() === RdxPopoverState.CLOSED &&
677
- [RdxPopoverAnimationStatus.CLOSED_ENDED].includes(cssAnimationStatus))));
678
- }
679
- /** @ignore */
680
- openOrClose(state) {
681
- const isOpen = this.isOpen(state);
682
- isOpen ? this.openContent() : this.closeContent();
683
- }
684
- /** @ignore */
685
- emitOnOpenOrOnClosed(state) {
686
- this.isOpen(state)
687
- ? this.attachDetachEvent() === RdxPopoverAttachDetachEvent.ATTACH && this.emitOnOpen()
688
- : this.attachDetachEvent() === RdxPopoverAttachDetachEvent.DETACH && this.emitOnClosed();
689
- }
690
- /** @ignore */
691
- canEmitOnOpenOrOnClosed() {
692
- return (!this.cssAnimation() ||
693
- (!this.cssOpeningAnimation() && this.state() === RdxPopoverState.OPEN) ||
694
- (this.cssOpeningAnimation() &&
695
- this.state() === RdxPopoverState.OPEN &&
696
- this.cssAnimationStatus() === RdxPopoverAnimationStatus.OPEN_ENDED) ||
697
- (!this.cssClosingAnimation() && this.state() === RdxPopoverState.CLOSED) ||
698
- (this.cssClosingAnimation() &&
699
- this.state() === RdxPopoverState.CLOSED &&
700
- this.cssAnimationStatus() === RdxPopoverAnimationStatus.CLOSED_ENDED));
701
- }
702
- /** @ignore */
703
- onStateChangeEffect() {
704
- let isFirst = true;
705
- effect(() => {
706
- const state = this.state();
707
- untracked(() => {
708
- if (isFirst) {
709
- isFirst = false;
710
- return;
711
- }
712
- if (!this.ifOpenOrCloseWithoutAnimations(state)) {
713
- return;
714
- }
715
- this.openOrClose(state);
716
- });
717
- }, {});
718
- }
719
- /** @ignore */
720
- onCssAnimationStatusChangeChangeEffect() {
721
- let isFirst = true;
722
- effect(() => {
723
- const cssAnimationStatus = this.cssAnimationStatus();
724
- untracked(() => {
725
- if (isFirst) {
726
- isFirst = false;
727
- return;
728
- }
729
- if (!this.ifOpenOrCloseWithAnimations(cssAnimationStatus)) {
730
- return;
731
- }
732
- this.openOrClose(this.state());
733
- });
734
- });
735
- }
736
- /** @ignore */
737
- emitOpenOrClosedEventEffect() {
738
- let isFirst = true;
739
- effect(() => {
740
- this.attachDetachEvent();
741
- this.cssAnimationStatus();
742
- untracked(() => {
743
- if (isFirst) {
744
- isFirst = false;
745
- return;
746
- }
747
- const canEmitOpenClose = untracked(() => this.canEmitOnOpenOrOnClosed());
748
- if (!canEmitOpenClose) {
749
- return;
750
- }
751
- this.emitOnOpenOrOnClosed(this.state());
752
- });
753
- });
754
- }
755
- /** @ignore */
756
- onOpenChangeEffect() {
757
- effect(() => {
758
- const open = this.open();
759
- untracked(() => {
760
- this.setState(open ? RdxPopoverState.OPEN : RdxPopoverState.CLOSED);
761
- });
653
+ this.avoidCollisions = input(true, { ...(ngDevMode ? { debugName: "avoidCollisions" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
654
+ /**
655
+ * The element used as the collision boundary.
656
+ */
657
+ this.collisionBoundary = input(...(ngDevMode ? [undefined, { debugName: "collisionBoundary" }] : /* istanbul ignore next */ []));
658
+ /**
659
+ * Distance in pixels from the boundary edges where collision detection should occur.
660
+ */
661
+ this.collisionPadding = input(5, ...(ngDevMode ? [{ debugName: "collisionPadding" }] : /* istanbul ignore next */ []));
662
+ /**
663
+ * The sticky behavior on the alignment axis.
664
+ */
665
+ this.sticky = input('partial', ...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
666
+ /**
667
+ * Whether to hide the popup when the trigger becomes fully occluded.
668
+ */
669
+ this.hideWhenDetached = input(false, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
670
+ /**
671
+ * The CSS position strategy used by Floating UI.
672
+ */
673
+ this.positionStrategy = input('fixed', ...(ngDevMode ? [{ debugName: "positionStrategy" }] : /* istanbul ignore next */ []));
674
+ /**
675
+ * Whether to update position on every animation frame.
676
+ */
677
+ this.updatePositionStrategy = input('always', ...(ngDevMode ? [{ debugName: "updatePositionStrategy" }] : /* istanbul ignore next */ []));
678
+ /**
679
+ * Emits when the popup has been placed.
680
+ */
681
+ this.placed = outputFromObservable(outputToObservable(inject(RdxPopperContentWrapper).placed));
682
+ effect(() => this.triggerEl.set(this.rootContext.trigger() ?? null));
683
+ this.graceArea.onPointerExit(() => {
684
+ this.rootContext.closeOnHover();
762
685
  });
763
686
  }
764
- /** @ignore */
765
- onIsFirstDefaultOpenChangeEffect() {
766
- const effectRef = effect(() => {
767
- const defaultOpen = this.defaultOpen();
768
- untracked(() => {
769
- if (!defaultOpen || this.open()) {
770
- effectRef.destroy();
771
- return;
772
- }
773
- this.handleOpen();
774
- });
775
- }, ...(ngDevMode ? [{ debugName: "effectRef" }] : /* istanbul ignore next */ []));
776
- }
777
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
778
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.9", type: RdxPopoverRootDirective, isStandalone: true, selector: "[rdxPopoverRoot]", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, externalControl: { classPropertyName: "externalControl", publicName: "externalControl", isSignal: true, isRequired: false, transformFunction: null }, cssAnimation: { classPropertyName: "cssAnimation", publicName: "cssAnimation", isSignal: true, isRequired: false, transformFunction: null }, cssOpeningAnimation: { classPropertyName: "cssOpeningAnimation", publicName: "cssOpeningAnimation", isSignal: true, isRequired: false, transformFunction: null }, cssClosingAnimation: { classPropertyName: "cssClosingAnimation", publicName: "cssClosingAnimation", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "popoverContentDirective", first: true, predicate: RdxPopoverContentDirective, descendants: true, isSignal: true }, { propertyName: "popoverTriggerDirective", first: true, predicate: RdxPopoverTriggerDirective, descendants: true, isSignal: true }, { propertyName: "popoverArrowDirective", first: true, predicate: RdxPopoverArrowToken, descendants: true, isSignal: true }, { propertyName: "popoverCloseDirective", first: true, predicate: RdxPopoverCloseToken, descendants: true, isSignal: true }, { propertyName: "popoverContentAttributesComponent", first: true, predicate: RdxPopoverContentAttributesToken, descendants: true, isSignal: true }, { propertyName: "internalPopoverAnchorDirective", first: true, predicate: RdxPopoverAnchorToken, descendants: true, isSignal: true }], exportAs: ["rdxPopoverRoot"], ngImport: i0 }); }
687
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
688
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverPositioner, isStandalone: true, selector: "[rdxPopoverPositioner]", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, alignOffset: { classPropertyName: "alignOffset", publicName: "alignOffset", isSignal: true, isRequired: false, transformFunction: null }, arrowPadding: { classPropertyName: "arrowPadding", publicName: "arrowPadding", isSignal: true, isRequired: false, transformFunction: null }, avoidCollisions: { classPropertyName: "avoidCollisions", publicName: "avoidCollisions", isSignal: true, isRequired: false, transformFunction: null }, collisionBoundary: { classPropertyName: "collisionBoundary", publicName: "collisionBoundary", isSignal: true, isRequired: false, transformFunction: null }, collisionPadding: { classPropertyName: "collisionPadding", publicName: "collisionPadding", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, hideWhenDetached: { classPropertyName: "hideWhenDetached", publicName: "hideWhenDetached", isSignal: true, isRequired: false, transformFunction: null }, positionStrategy: { classPropertyName: "positionStrategy", publicName: "positionStrategy", isSignal: true, isRequired: false, transformFunction: null }, updatePositionStrategy: { classPropertyName: "updatePositionStrategy", publicName: "updatePositionStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { placed: "placed" }, host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-anchor-hidden": "wrapper.anchorHidden() ? \"\" : undefined", "attr.data-align": "wrapper.placedAlign()", "attr.data-side": "wrapper.placedSide()", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "style": "{\n '--anchor-width': 'var(--radix-popper-anchor-width)',\n '--anchor-height': 'var(--radix-popper-anchor-height)',\n '--available-width': 'var(--radix-popper-available-width)',\n '--available-height': 'var(--radix-popper-available-height)',\n '--positioner-width': 'var(--radix-popper-content-wrapper-width)',\n '--positioner-height': 'var(--radix-popper-content-wrapper-height)',\n '--transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-popover-content-transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-popover-content-available-width': 'var(--radix-popper-available-width)',\n '--radix-popover-content-available-height': 'var(--radix-popper-available-height)',\n '--radix-popover-trigger-width': 'var(--radix-popper-anchor-width)',\n '--radix-popover-trigger-height': 'var(--radix-popper-anchor-height)'\n }" } }, providers: [
689
+ provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
690
+ ], hostDirectives: [{ directive: i1.RdxPopperContentWrapper, inputs: ["anchor", "anchor", "side", "side", "sideOffset", "sideOffset", "align", "align", "alignOffset", "alignOffset", "arrowPadding", "arrowPadding", "avoidCollisions", "avoidCollisions", "collisionBoundary", "collisionBoundary", "collisionPadding", "collisionPadding", "sticky", "sticky", "hideWhenDetached", "hideWhenDetached", "positionStrategy", "positionStrategy", "updatePositionStrategy", "updatePositionStrategy"] }], ngImport: i0 }); }
779
691
  }
780
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverRootDirective, decorators: [{
692
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverPositioner, decorators: [{
781
693
  type: Directive,
782
694
  args: [{
783
- selector: '[rdxPopoverRoot]',
784
- exportAs: 'rdxPopoverRoot'
695
+ selector: '[rdxPopoverPositioner]',
696
+ providers: [
697
+ provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
698
+ ],
699
+ hostDirectives: [
700
+ {
701
+ directive: RdxPopperContentWrapper,
702
+ inputs: [
703
+ 'anchor',
704
+ 'side',
705
+ 'sideOffset',
706
+ 'align',
707
+ 'alignOffset',
708
+ 'arrowPadding',
709
+ 'avoidCollisions',
710
+ 'collisionBoundary',
711
+ 'collisionPadding',
712
+ 'sticky',
713
+ 'hideWhenDetached',
714
+ 'positionStrategy',
715
+ 'updatePositionStrategy'
716
+ ]
717
+ }
718
+ ],
719
+ host: {
720
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
721
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
722
+ '[attr.data-anchor-hidden]': 'wrapper.anchorHidden() ? "" : undefined',
723
+ '[attr.data-align]': 'wrapper.placedAlign()',
724
+ '[attr.data-side]': 'wrapper.placedSide()',
725
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
726
+ '[style]': `{
727
+ '--anchor-width': 'var(--radix-popper-anchor-width)',
728
+ '--anchor-height': 'var(--radix-popper-anchor-height)',
729
+ '--available-width': 'var(--radix-popper-available-width)',
730
+ '--available-height': 'var(--radix-popper-available-height)',
731
+ '--positioner-width': 'var(--radix-popper-content-wrapper-width)',
732
+ '--positioner-height': 'var(--radix-popper-content-wrapper-height)',
733
+ '--transform-origin': 'var(--radix-popper-transform-origin)',
734
+ '--radix-popover-content-transform-origin': 'var(--radix-popper-transform-origin)',
735
+ '--radix-popover-content-available-width': 'var(--radix-popper-available-width)',
736
+ '--radix-popover-content-available-height': 'var(--radix-popper-available-height)',
737
+ '--radix-popover-trigger-width': 'var(--radix-popper-anchor-width)',
738
+ '--radix-popover-trigger-height': 'var(--radix-popper-anchor-height)'
739
+ }`
740
+ }
785
741
  }]
786
- }], ctorParameters: () => [], propDecorators: { anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], externalControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "externalControl", required: false }] }], cssAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "cssAnimation", required: false }] }], cssOpeningAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "cssOpeningAnimation", required: false }] }], cssClosingAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "cssClosingAnimation", required: false }] }], popoverContentDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverContentDirective), { isSignal: true }] }], popoverTriggerDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverTriggerDirective), { isSignal: true }] }], popoverArrowDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverArrowToken), { isSignal: true }] }], popoverCloseDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverCloseToken), { isSignal: true }] }], popoverContentAttributesComponent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverContentAttributesToken), { isSignal: true }] }], internalPopoverAnchorDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxPopoverAnchorToken), { isSignal: true }] }] } });
742
+ }], ctorParameters: () => [], propDecorators: { anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], alignOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignOffset", required: false }] }], arrowPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowPadding", required: false }] }], avoidCollisions: [{ type: i0.Input, args: [{ isSignal: true, alias: "avoidCollisions", required: false }] }], collisionBoundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionBoundary", required: false }] }], collisionPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionPadding", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], hideWhenDetached: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideWhenDetached", required: false }] }], positionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionStrategy", required: false }] }], updatePositionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "updatePositionStrategy", required: false }] }], placed: [{ type: i0.Output, args: ["placed"] }] } });
787
743
 
788
- function injectPopoverRoot(optional = false) {
789
- isDevMode() && assertInInjectionContext(injectPopoverRoot);
790
- return inject(RdxPopoverRootDirective, { optional });
791
- }
792
-
793
- class RdxPopoverAnchorDirective {
744
+ /**
745
+ * An accessible title for the popover.
746
+ */
747
+ class RdxPopoverTitle {
794
748
  constructor() {
795
- /**
796
- * @ignore
797
- * If outside the root then null, otherwise the root directive - with optional `true` passed in as the first param.
798
- * If outside the root and non-null value that means the html structure is wrong - popover inside popover.
799
- * */
800
- this.popoverRoot = injectPopoverRoot(true);
801
- /** @ignore */
802
- this.elementRef = inject(ElementRef);
803
- /** @ignore */
804
- this.overlayOrigin = inject(CdkOverlayOrigin);
805
- /** @ignore */
806
- this.document = injectDocument();
807
- /** @ignore */
808
- this.name = computed(() => `rdx-popover-external-anchor-${this.popoverRoot?.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
749
+ this.rootContext = injectRdxPopoverRootContext();
750
+ this.id = injectId('rdx-popover-title-');
751
+ this.rootContext.setTitleId(this.id);
752
+ inject(DestroyRef).onDestroy(() => this.rootContext.setTitleId(undefined));
809
753
  }
810
- /** @ignore */
811
- click() {
812
- this.emitOutsideClick();
813
- }
814
- /** @ignore */
815
- setPopoverRoot(popoverRoot) {
816
- this.popoverRoot = popoverRoot;
817
- }
818
- emitOutsideClick() {
819
- if (!this.popoverRoot?.isOpen() ||
820
- this.popoverRoot?.popoverContentDirective().onOverlayOutsideClickDisabled()) {
821
- return;
822
- }
823
- const clickEvent = new MouseEvent('click', {
824
- view: this.document.defaultView,
825
- bubbles: true,
826
- cancelable: true,
827
- relatedTarget: this.elementRef.nativeElement
828
- });
829
- this.popoverRoot?.popoverTriggerDirective().elementRef.nativeElement.dispatchEvent(clickEvent);
830
- }
831
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
832
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverAnchorDirective, isStandalone: true, selector: "[rdxPopoverAnchor]", host: { attributes: { "type": "button" }, listeners: { "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"" } }, providers: [
833
- {
834
- provide: RdxPopoverAnchorToken,
835
- useExisting: forwardRef(() => RdxPopoverAnchorDirective)
836
- }
837
- ], exportAs: ["rdxPopoverAnchor"], hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
754
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTitle, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
755
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverTitle, isStandalone: true, selector: "[rdxPopoverTitle]", host: { properties: { "id": "id" } }, ngImport: i0 }); }
838
756
  }
839
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverAnchorDirective, decorators: [{
757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTitle, decorators: [{
840
758
  type: Directive,
841
759
  args: [{
842
- selector: '[rdxPopoverAnchor]',
843
- exportAs: 'rdxPopoverAnchor',
844
- hostDirectives: [CdkOverlayOrigin],
760
+ selector: '[rdxPopoverTitle]',
845
761
  host: {
846
- type: 'button',
847
- '[attr.id]': 'name()',
848
- '[attr.aria-haspopup]': '"dialog"',
849
- '(click)': 'click()'
850
- },
851
- providers: [
852
- {
853
- provide: RdxPopoverAnchorToken,
854
- useExisting: forwardRef(() => RdxPopoverAnchorDirective)
855
- }
856
- ]
762
+ '[id]': 'id'
763
+ }
857
764
  }]
858
- }] });
765
+ }], ctorParameters: () => [] });
859
766
 
860
- class RdxPopoverArrowDirective {
767
+ /**
768
+ * A button that opens the popover.
769
+ */
770
+ class RdxPopoverTrigger {
861
771
  constructor() {
862
- /** @ignore */
863
- this.renderer = inject(Renderer2);
864
- /** @ignore */
865
- this.popoverRoot = injectPopoverRoot();
866
- /** @ignore */
772
+ this.parentRootContext = injectRdxPopoverRootContext(true);
867
773
  this.elementRef = inject(ElementRef);
868
774
  /**
869
- * @description The width of the arrow in pixels.
870
- * @default 10
775
+ * Associates this trigger with a detached popover root.
871
776
  */
872
- this.width = input(RDX_POSITIONING_DEFAULTS.arrow.width, { ...(ngDevMode ? { debugName: "width" } : /* istanbul ignore next */ {}), transform: numberAttribute });
777
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
873
778
  /**
874
- * @description The height of the arrow in pixels.
875
- * @default 5
779
+ * Data associated with this trigger while it is active.
876
780
  */
877
- this.height = input(RDX_POSITIONING_DEFAULTS.arrow.height, { ...(ngDevMode ? { debugName: "height" } : /* istanbul ignore next */ {}), transform: numberAttribute });
878
- /** @ignore */
879
- this.arrowSvgElement = computed(() => {
880
- const width = this.width();
881
- const height = this.height();
882
- const svgElement = this.renderer.createElement('svg', 'svg');
883
- this.renderer.setAttribute(svgElement, 'viewBox', '0 0 30 10');
884
- this.renderer.setAttribute(svgElement, 'width', String(width));
885
- this.renderer.setAttribute(svgElement, 'height', String(height));
886
- const polygonElement = this.renderer.createElement('polygon', 'svg');
887
- this.renderer.setAttribute(polygonElement, 'points', '0,0 30,0 15,10');
888
- this.renderer.setAttribute(svgElement, 'preserveAspectRatio', 'none');
889
- this.renderer.appendChild(svgElement, polygonElement);
890
- return svgElement;
891
- }, ...(ngDevMode ? [{ debugName: "arrowSvgElement" }] : /* istanbul ignore next */ []));
892
- /** @ignore */
893
- this.currentArrowSvgElement = signal(void 0, ...(ngDevMode ? [{ debugName: "currentArrowSvgElement" }] : /* istanbul ignore next */ []));
894
- /** @ignore */
895
- this.position = toSignal(this.popoverRoot.popoverContentDirective().positionChange());
896
- afterNextRender({
897
- write: () => {
898
- if (this.elementRef.nativeElement.parentElement) {
899
- this.renderer.setStyle(this.elementRef.nativeElement.parentElement, 'position', 'relative');
900
- }
901
- this.renderer.setStyle(this.elementRef.nativeElement, 'position', 'absolute');
902
- this.renderer.setStyle(this.elementRef.nativeElement, 'boxSizing', '');
903
- this.renderer.setStyle(this.elementRef.nativeElement, 'fontSize', '0px');
781
+ this.payload = input(...(ngDevMode ? [undefined, { debugName: "payload" }] : /* istanbul ignore next */ []));
782
+ /**
783
+ * ID used to identify this trigger when opening a detached popover imperatively.
784
+ */
785
+ this.id = input(...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ []));
786
+ /**
787
+ * Whether the trigger should ignore user interaction.
788
+ */
789
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
790
+ /**
791
+ * Whether the popover should also open when this trigger is hovered.
792
+ */
793
+ this.openOnHover = input(false, { ...(ngDevMode ? { debugName: "openOnHover" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
794
+ /**
795
+ * How long to wait before opening the popover on hover, in milliseconds.
796
+ */
797
+ this.delay = input(300, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
798
+ /**
799
+ * How long to wait before closing a hover-opened popover, in milliseconds.
800
+ */
801
+ this.closeDelay = input(0, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
802
+ this.triggerId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
803
+ this.rootContext = computed(() => this.handle()?.context() ?? this.parentRootContext, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
804
+ this.isOpen = computed(() => this.rootContext()?.isOpen() === true && this.rootContext()?.trigger() === this.elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
805
+ this.isPressed = computed(() => this.isOpen() && this.rootContext()?.openChangeReason() === 'trigger-press', ...(ngDevMode ? [{ debugName: "isPressed" }] : /* istanbul ignore next */ []));
806
+ this.generatedId = injectId('rdx-popover-trigger-');
807
+ effect((onCleanup) => {
808
+ const handle = this.handle();
809
+ if (handle) {
810
+ onCleanup(untracked(() => handle.registerTrigger(this.triggerId(), this.elementRef.nativeElement, () => this.payload())));
811
+ }
812
+ else if (this.parentRootContext) {
813
+ onCleanup(untracked(() => this.parentRootContext.registerTrigger(this.triggerId(), this.elementRef.nativeElement, () => this.payload())));
904
814
  }
905
815
  });
906
- this.onArrowSvgElementChangeEffect();
907
- this.onContentPositionAndArrowDimensionsChangeEffect();
908
816
  }
909
- /** @ignore */
910
- setAnchorOrTriggerRect() {
911
- this.anchorOrTriggerRect = (this.popoverRoot.popoverAnchorDirective() ?? this.popoverRoot.popoverTriggerDirective()).elementRef.nativeElement.getBoundingClientRect();
817
+ handleClick(event) {
818
+ if (this.disabled()) {
819
+ return;
820
+ }
821
+ this.rootContext()?.setPointerDownOnTrigger(false);
822
+ if (this.handle()) {
823
+ this.handle().toggle(this.triggerId(), event);
824
+ }
825
+ else {
826
+ this.parentRootContext?.toggle(this.triggerId(), this.elementRef.nativeElement, this.payload(), event);
827
+ }
828
+ }
829
+ handlePointerEnter(event) {
830
+ const rootContext = this.rootContext();
831
+ if (event.pointerType === 'touch' || !rootContext || this.disabled() || !this.openOnHover()) {
832
+ return;
833
+ }
834
+ rootContext.setHoverDelays(this.delay(), this.closeDelay());
835
+ rootContext.openOnHover(this.elementRef.nativeElement, this.payload(), this.triggerId(), event);
912
836
  }
913
- /** @ignore */
914
- setPosition(position, arrowDimensions) {
915
- this.setAnchorOrTriggerRect();
916
- const posParams = getArrowPositionParams(getSideAndAlignFromAllPossibleConnectedPositions(position.connectionPair), { width: arrowDimensions.width, height: arrowDimensions.height }, { width: this.anchorOrTriggerRect.width, height: this.anchorOrTriggerRect.height });
917
- this.renderer.setStyle(this.elementRef.nativeElement, 'top', posParams.top);
918
- this.renderer.setStyle(this.elementRef.nativeElement, 'bottom', '');
919
- this.renderer.setStyle(this.elementRef.nativeElement, 'left', posParams.left);
920
- this.renderer.setStyle(this.elementRef.nativeElement, 'right', '');
921
- this.renderer.setStyle(this.elementRef.nativeElement, 'transform', posParams.transform);
922
- this.renderer.setStyle(this.elementRef.nativeElement, 'transformOrigin', posParams.transformOrigin);
837
+ handlePointerLeave(event) {
838
+ if (event.pointerType === 'touch' || !this.openOnHover()) {
839
+ return;
840
+ }
841
+ this.rootContext()?.cancelHoverOpen();
923
842
  }
924
- /** @ignore */
925
- onArrowSvgElementChangeEffect() {
926
- effect(() => {
927
- const arrowElement = this.arrowSvgElement();
928
- untracked(() => {
929
- const currentArrowSvgElement = this.currentArrowSvgElement();
930
- if (currentArrowSvgElement) {
931
- this.renderer.removeChild(this.elementRef.nativeElement, currentArrowSvgElement);
932
- }
933
- this.currentArrowSvgElement.set(arrowElement);
934
- this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.width()}px`);
935
- this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.height()}px`);
936
- this.renderer.appendChild(this.elementRef.nativeElement, this.currentArrowSvgElement());
937
- });
938
- });
843
+ handlePointerDown() {
844
+ this.rootContext()?.setPointerDownOnTrigger(true);
939
845
  }
940
- /** @ignore */
941
- onContentPositionAndArrowDimensionsChangeEffect() {
942
- effect(() => {
943
- const position = this.position();
944
- const arrowDimensions = { width: this.width(), height: this.height() };
945
- untracked(() => {
946
- if (!position) {
947
- return;
948
- }
949
- this.setPosition(position, arrowDimensions);
950
- });
951
- });
846
+ handlePointerUp() {
847
+ this.rootContext()?.setPointerDownOnTrigger(false);
952
848
  }
953
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverArrowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
954
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverArrowDirective, isStandalone: true, selector: "[rdxPopoverArrow]", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
955
- {
956
- provide: RdxPopoverArrowToken,
957
- useExisting: forwardRef(() => RdxPopoverArrowDirective)
958
- }
959
- ], ngImport: i0 }); }
849
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
850
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPopoverTrigger, isStandalone: true, selector: "button[rdxPopoverTrigger]", inputs: { handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null }, payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "click": "handleClick($event)", "pointerenter": "handlePointerEnter($event)", "pointerleave": "handlePointerLeave($event)", "pointerdown": "handlePointerDown()", "pointerup": "handlePointerUp()", "pointercancel": "handlePointerUp()" }, properties: { "attr.aria-controls": "rootContext()?.contentId", "attr.aria-expanded": "isOpen()", "attr.aria-haspopup": "\"dialog\"", "attr.data-state": "isOpen() ? \"open\" : \"closed\"", "attr.data-popup-open": "isOpen() ? \"\" : undefined", "attr.data-pressed": "isPressed() ? \"\" : undefined", "attr.disabled": "disabled() ? \"\" : undefined", "id": "triggerId()" } }, hostDirectives: [{ directive: i1.RdxPopperAnchor }], ngImport: i0 }); }
960
851
  }
961
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverArrowDirective, decorators: [{
852
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverTrigger, decorators: [{
962
853
  type: Directive,
963
854
  args: [{
964
- selector: '[rdxPopoverArrow]',
965
- providers: [
966
- {
967
- provide: RdxPopoverArrowToken,
968
- useExisting: forwardRef(() => RdxPopoverArrowDirective)
969
- }
970
- ]
855
+ selector: 'button[rdxPopoverTrigger]',
856
+ hostDirectives: [RdxPopperAnchor],
857
+ host: {
858
+ type: 'button',
859
+ '[attr.aria-controls]': 'rootContext()?.contentId',
860
+ '[attr.aria-expanded]': 'isOpen()',
861
+ '[attr.aria-haspopup]': '"dialog"',
862
+ '[attr.data-state]': 'isOpen() ? "open" : "closed"',
863
+ '[attr.data-popup-open]': 'isOpen() ? "" : undefined',
864
+ '[attr.data-pressed]': 'isPressed() ? "" : undefined',
865
+ '[attr.disabled]': 'disabled() ? "" : undefined',
866
+ '[id]': 'triggerId()',
867
+ '(click)': 'handleClick($event)',
868
+ '(pointerenter)': 'handlePointerEnter($event)',
869
+ '(pointerleave)': 'handlePointerLeave($event)',
870
+ '(pointerdown)': 'handlePointerDown()',
871
+ '(pointerup)': 'handlePointerUp()',
872
+ '(pointercancel)': 'handlePointerUp()'
873
+ }
971
874
  }]
972
- }], ctorParameters: () => [], propDecorators: { width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
875
+ }], ctorParameters: () => [], propDecorators: { handle: [{ type: i0.Input, args: [{ isSignal: true, alias: "handle", required: false }] }], payload: [{ type: i0.Input, args: [{ isSignal: true, alias: "payload", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], openOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnHover", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }] } });
973
876
 
974
- class RdxPopoverCloseDirective {
877
+ /**
878
+ * A viewport for animating content changes when a popover moves between triggers.
879
+ *
880
+ * Render one direct child inside the viewport. It is marked with `data-current`;
881
+ * when the active trigger changes, a DOM snapshot is retained as `data-previous`
882
+ * until its CSS animation or transition completes.
883
+ */
884
+ class RdxPopoverViewport {
975
885
  constructor() {
976
- /** @ignore */
977
- this.popoverRoot = injectPopoverRoot();
978
- /** @ignore */
886
+ this.rootContext = injectRdxPopoverRootContext();
979
887
  this.elementRef = inject(ElementRef);
980
- /** @ignore */
981
- this.renderer = inject(Renderer2);
982
- this.onIsControlledExternallyEffect();
983
- }
984
- /** @ignore */
985
- onIsControlledExternallyEffect() {
986
- effect(() => {
987
- const isControlledExternally = this.popoverRoot.controlledExternally()();
988
- untracked(() => {
989
- this.renderer.setStyle(this.elementRef.nativeElement, 'display', isControlledExternally ? 'none' : null);
990
- });
888
+ this.destroyRef = inject(DestroyRef);
889
+ this.activationDirection = signal(undefined, ...(ngDevMode ? [{ debugName: "activationDirection" }] : /* istanbul ignore next */ []));
890
+ this.transitioning = signal(false, ...(ngDevMode ? [{ debugName: "transitioning" }] : /* istanbul ignore next */ []));
891
+ const unregister = this.rootContext.registerViewport((previousTrigger, nextTrigger) => {
892
+ this.startTransition(previousTrigger, nextTrigger);
893
+ });
894
+ afterNextRender(() => {
895
+ this.markCurrent();
896
+ this.observer = new MutationObserver(() => this.markCurrent());
897
+ this.observer.observe(this.elementRef.nativeElement, { childList: true });
898
+ });
899
+ this.destroyRef.onDestroy(() => {
900
+ unregister();
901
+ this.observer?.disconnect();
902
+ this.cleanupPrevious();
991
903
  });
992
904
  }
993
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
994
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverCloseDirective, isStandalone: true, selector: "[rdxPopoverClose]", host: { attributes: { "type": "button" }, listeners: { "click": "popoverRoot.handleClose()" } }, providers: [
995
- {
996
- provide: RdxPopoverCloseToken,
997
- useExisting: forwardRef(() => RdxPopoverCloseDirective)
998
- }
999
- ], ngImport: i0 }); }
905
+ startTransition(previousTrigger, nextTrigger) {
906
+ const current = this.current();
907
+ if (!current) {
908
+ return;
909
+ }
910
+ this.cleanupPrevious();
911
+ this.activationDirection.set(getActivationDirection(previousTrigger, nextTrigger));
912
+ const previous = current.cloneNode(true);
913
+ const popup = this.elementRef.nativeElement.closest('[rdxPopoverPopup]');
914
+ const popupRect = popup?.getBoundingClientRect();
915
+ previous.removeAttribute('data-current');
916
+ previous.setAttribute('data-previous', '');
917
+ previous.setAttribute('aria-hidden', 'true');
918
+ previous.setAttribute('inert', '');
919
+ removeIds(previous);
920
+ if (popupRect) {
921
+ previous.style.setProperty('--popup-width', `${popupRect.width}px`);
922
+ previous.style.setProperty('--popup-height', `${popupRect.height}px`);
923
+ }
924
+ previous.addEventListener('animationend', () => this.cleanupPrevious(), { once: true });
925
+ previous.addEventListener('transitionend', () => this.cleanupPrevious(), { once: true });
926
+ this.previous = previous;
927
+ this.elementRef.nativeElement.insertBefore(previous, current);
928
+ this.transitioning.set(true);
929
+ queueMicrotask(() => this.scheduleCleanup(previous));
930
+ }
931
+ markCurrent() {
932
+ this.current()?.setAttribute('data-current', '');
933
+ }
934
+ current() {
935
+ return Array.from(this.elementRef.nativeElement.children).find((child) => child instanceof HTMLElement && !child.hasAttribute('data-previous'));
936
+ }
937
+ scheduleCleanup(previous) {
938
+ if (this.previous !== previous) {
939
+ return;
940
+ }
941
+ const style = getComputedStyle(previous);
942
+ const duration = Math.max(getMaxDuration(style.animationDuration, style.animationDelay), getMaxDuration(style.transitionDuration, style.transitionDelay));
943
+ this.cleanupTimer = setTimeout(() => this.cleanupPrevious(), duration > 0 ? duration + 50 : 0);
944
+ }
945
+ cleanupPrevious() {
946
+ if (this.cleanupTimer !== undefined) {
947
+ clearTimeout(this.cleanupTimer);
948
+ this.cleanupTimer = undefined;
949
+ }
950
+ this.previous?.remove();
951
+ this.previous = undefined;
952
+ this.transitioning.set(false);
953
+ }
954
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverViewport, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
955
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverViewport, isStandalone: true, selector: "[rdxPopoverViewport]", host: { properties: { "attr.data-activation-direction": "activationDirection()", "attr.data-transitioning": "transitioning() ? \"\" : undefined" } }, ngImport: i0 }); }
1000
956
  }
1001
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverCloseDirective, decorators: [{
957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverViewport, decorators: [{
1002
958
  type: Directive,
1003
959
  args: [{
1004
- selector: '[rdxPopoverClose]',
960
+ selector: '[rdxPopoverViewport]',
1005
961
  host: {
1006
- type: 'button',
1007
- '(click)': 'popoverRoot.handleClose()'
1008
- },
1009
- providers: [
1010
- {
1011
- provide: RdxPopoverCloseToken,
1012
- useExisting: forwardRef(() => RdxPopoverCloseDirective)
1013
- }
1014
- ]
962
+ '[attr.data-activation-direction]': 'activationDirection()',
963
+ '[attr.data-transitioning]': 'transitioning() ? "" : undefined'
964
+ }
1015
965
  }]
1016
966
  }], ctorParameters: () => [] });
967
+ function getActivationDirection(previous, next) {
968
+ const previousRect = previous.getBoundingClientRect();
969
+ const nextRect = next.getBoundingClientRect();
970
+ const previousCenter = getCenter(previousRect);
971
+ const nextCenter = getCenter(nextRect);
972
+ const directions = [];
973
+ if (nextCenter.x < previousCenter.x) {
974
+ directions.push('left');
975
+ }
976
+ else if (nextCenter.x > previousCenter.x) {
977
+ directions.push('right');
978
+ }
979
+ if (nextCenter.y < previousCenter.y) {
980
+ directions.push('up');
981
+ }
982
+ else if (nextCenter.y > previousCenter.y) {
983
+ directions.push('down');
984
+ }
985
+ return directions.join(' ') || undefined;
986
+ }
987
+ function removeIds(element) {
988
+ element.removeAttribute('id');
989
+ element.querySelectorAll('[id]').forEach((child) => child.removeAttribute('id'));
990
+ }
991
+ function getCenter(rect) {
992
+ return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
993
+ }
994
+ function getMaxDuration(durations, delays) {
995
+ const durationValues = durations.split(',').map(parseDuration);
996
+ const delayValues = delays.split(',').map(parseDuration);
997
+ return durationValues.reduce((max, duration, index) => {
998
+ const delay = delayValues[index % delayValues.length] ?? 0;
999
+ return Math.max(max, duration + delay);
1000
+ }, 0);
1001
+ }
1002
+ function parseDuration(value) {
1003
+ const duration = Number.parseFloat(value);
1004
+ if (Number.isNaN(duration)) {
1005
+ return 0;
1006
+ }
1007
+ return value.trim().endsWith('ms') ? duration : duration * 1000;
1008
+ }
1017
1009
 
1018
- class RdxPopoverContentAttributesComponent {
1010
+ class RdxPopoverHandle {
1019
1011
  constructor() {
1020
- /** @ignore */
1021
- this.focusTrapDirective = inject(CdkTrapFocus, { self: true });
1022
- /** @ignore */
1023
- this.popoverRoot = injectPopoverRoot();
1024
- /** @ignore */
1025
- this.name = computed(() => `rdx-popover-content-attributes-${this.popoverRoot.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
1026
- /** @ignore */
1027
- this.disableAnimation = computed(() => !this.canAnimate(), ...(ngDevMode ? [{ debugName: "disableAnimation" }] : /* istanbul ignore next */ []));
1028
- afterNextRender({
1029
- write: () => {
1030
- if (this.focusInitialDirective) {
1031
- return this.focusInitialDirective.focus();
1032
- }
1033
- this.focusTrapDirective.focusTrap.focusFirstTabbableElement();
1034
- }
1035
- });
1012
+ this.rootContext = signal(undefined, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
1013
+ this.triggers = new Map();
1014
+ this.rootTriggerCleanups = new Map();
1015
+ this.isOpen = computed(() => this.rootContext()?.isOpen() ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
1016
+ }
1017
+ open(triggerId) {
1018
+ const trigger = this.triggers.get(triggerId);
1019
+ if (!trigger) {
1020
+ throw new Error(`No popover trigger registered with id "${triggerId}".`);
1021
+ }
1022
+ this.rootContext()?.open(trigger.element, trigger.payload(), triggerId, 'imperative-action', new Event('popover.open'));
1036
1023
  }
1037
- /** @ignore */
1038
- onAnimationStart(_) {
1039
- this.popoverRoot.cssAnimationStatus.set(this.popoverRoot.state() === RdxPopoverState.OPEN
1040
- ? RdxPopoverAnimationStatus.OPEN_STARTED
1041
- : RdxPopoverAnimationStatus.CLOSED_STARTED);
1024
+ close() {
1025
+ this.rootContext()?.close('imperative-action', new Event('popover.close'));
1042
1026
  }
1043
- /** @ignore */
1044
- onAnimationEnd(_) {
1045
- this.popoverRoot.cssAnimationStatus.set(this.popoverRoot.state() === RdxPopoverState.OPEN
1046
- ? RdxPopoverAnimationStatus.OPEN_ENDED
1047
- : RdxPopoverAnimationStatus.CLOSED_ENDED);
1027
+ toggle(triggerId, event = new Event('popover.toggle')) {
1028
+ const trigger = this.triggers.get(triggerId);
1029
+ if (!trigger) {
1030
+ throw new Error(`No popover trigger registered with id "${triggerId}".`);
1031
+ }
1032
+ this.rootContext()?.toggle(triggerId, trigger.element, trigger.payload(), event);
1048
1033
  }
1049
- /** @ignore */
1050
- canAnimate() {
1051
- return (this.popoverRoot.cssAnimation() &&
1052
- ((this.popoverRoot.cssOpeningAnimation() && this.popoverRoot.state() === RdxPopoverState.OPEN) ||
1053
- (this.popoverRoot.cssClosingAnimation() && this.popoverRoot.state() === RdxPopoverState.CLOSED)));
1034
+ registerRoot(rootContext) {
1035
+ this.rootContext.set(rootContext);
1036
+ this.triggers.forEach((trigger, id) => {
1037
+ this.rootTriggerCleanups.set(id, rootContext.registerTrigger(id, trigger.element, trigger.payload));
1038
+ });
1039
+ return () => {
1040
+ if (this.rootContext() === rootContext) {
1041
+ this.rootTriggerCleanups.forEach((cleanup) => cleanup());
1042
+ this.rootTriggerCleanups.clear();
1043
+ this.rootContext.set(undefined);
1044
+ }
1045
+ };
1054
1046
  }
1055
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverContentAttributesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1056
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: RdxPopoverContentAttributesComponent, isStandalone: true, selector: "[rdxPopoverContentAttributes]", host: { listeners: { "animationstart": "onAnimationStart($event)", "animationend": "onAnimationEnd($event)" }, properties: { "attr.role": "\"dialog\"", "attr.id": "name()", "attr.data-state": "popoverRoot.state()", "attr.data-side": "popoverRoot.popoverContentDirective().side()", "attr.data-align": "popoverRoot.popoverContentDirective().align()", "style": "disableAnimation() ? {animation: \"none !important\"} : null" } }, providers: [
1057
- {
1058
- provide: RdxPopoverContentAttributesToken,
1059
- useExisting: forwardRef(() => RdxPopoverContentAttributesComponent)
1047
+ registerTrigger(id, trigger, payload) {
1048
+ this.rootTriggerCleanups.get(id)?.();
1049
+ this.triggers.set(id, { element: trigger, payload });
1050
+ const unregisterFromRoot = this.rootContext()?.registerTrigger(id, trigger, payload);
1051
+ if (unregisterFromRoot) {
1052
+ this.rootTriggerCleanups.set(id, unregisterFromRoot);
1053
+ }
1054
+ return () => {
1055
+ this.rootTriggerCleanups.get(id)?.();
1056
+ this.rootTriggerCleanups.delete(id);
1057
+ if (this.triggers.get(id)?.element === trigger) {
1058
+ this.triggers.delete(id);
1060
1059
  }
1061
- ], queries: [{ propertyName: "focusInitialDirective", first: true, predicate: RdxFocusInitialDirective, descendants: true }], hostDirectives: [{ directive: i1$1.CdkTrapFocus }], ngImport: i0, template: `
1062
- <ng-content />
1063
- `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1060
+ };
1061
+ }
1062
+ context() {
1063
+ return this.rootContext();
1064
+ }
1065
+ }
1066
+ function createRdxPopoverHandle() {
1067
+ return new RdxPopoverHandle();
1064
1068
  }
1065
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverContentAttributesComponent, decorators: [{
1066
- type: Component,
1067
- args: [{
1068
- selector: '[rdxPopoverContentAttributes]',
1069
- template: `
1070
- <ng-content />
1071
- `,
1072
- host: {
1073
- '[attr.role]': '"dialog"',
1074
- '[attr.id]': 'name()',
1075
- '[attr.data-state]': 'popoverRoot.state()',
1076
- '[attr.data-side]': 'popoverRoot.popoverContentDirective().side()',
1077
- '[attr.data-align]': 'popoverRoot.popoverContentDirective().align()',
1078
- '[style]': 'disableAnimation() ? {animation: "none !important"} : null',
1079
- '(animationstart)': 'onAnimationStart($event)',
1080
- '(animationend)': 'onAnimationEnd($event)'
1081
- },
1082
- hostDirectives: [CdkTrapFocus],
1083
- providers: [
1084
- {
1085
- provide: RdxPopoverContentAttributesToken,
1086
- useExisting: forwardRef(() => RdxPopoverContentAttributesComponent)
1087
- }
1088
- ],
1089
- changeDetection: ChangeDetectionStrategy.OnPush
1090
- }]
1091
- }], ctorParameters: () => [], propDecorators: { focusInitialDirective: [{
1092
- type: ContentChild,
1093
- args: [RdxFocusInitialDirective, { descendants: true }]
1094
- }] } });
1095
1069
 
1096
- const _imports = [
1097
- RdxPopoverArrowDirective,
1098
- RdxPopoverCloseDirective,
1099
- RdxPopoverContentDirective,
1100
- RdxPopoverTriggerDirective,
1101
- RdxPopoverRootDirective,
1102
- RdxPopoverAnchorDirective,
1103
- RdxPopoverContentAttributesComponent
1070
+ const popoverImports = [
1071
+ RdxPopoverRoot,
1072
+ RdxPopoverTrigger,
1073
+ RdxPopoverPortalPresence,
1074
+ RdxPopoverPortal,
1075
+ RdxPopoverBackdrop,
1076
+ RdxPopoverPositioner,
1077
+ RdxPopoverPopup,
1078
+ RdxPopoverArrow,
1079
+ RdxPopoverTitle,
1080
+ RdxPopoverDescription,
1081
+ RdxPopoverClose,
1082
+ RdxPopoverViewport
1104
1083
  ];
1105
1084
  class RdxPopoverModule {
1106
1085
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1107
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverModule, imports: [RdxPopoverArrowDirective,
1108
- RdxPopoverCloseDirective,
1109
- RdxPopoverContentDirective,
1110
- RdxPopoverTriggerDirective,
1111
- RdxPopoverRootDirective,
1112
- RdxPopoverAnchorDirective,
1113
- RdxPopoverContentAttributesComponent], exports: [RdxPopoverArrowDirective,
1114
- RdxPopoverCloseDirective,
1115
- RdxPopoverContentDirective,
1116
- RdxPopoverTriggerDirective,
1117
- RdxPopoverRootDirective,
1118
- RdxPopoverAnchorDirective,
1119
- RdxPopoverContentAttributesComponent] }); }
1086
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverModule, imports: [RdxPopoverRoot,
1087
+ RdxPopoverTrigger,
1088
+ RdxPopoverPortalPresence,
1089
+ RdxPopoverPortal,
1090
+ RdxPopoverBackdrop,
1091
+ RdxPopoverPositioner,
1092
+ RdxPopoverPopup,
1093
+ RdxPopoverArrow,
1094
+ RdxPopoverTitle,
1095
+ RdxPopoverDescription,
1096
+ RdxPopoverClose,
1097
+ RdxPopoverViewport], exports: [RdxPopoverRoot,
1098
+ RdxPopoverTrigger,
1099
+ RdxPopoverPortalPresence,
1100
+ RdxPopoverPortal,
1101
+ RdxPopoverBackdrop,
1102
+ RdxPopoverPositioner,
1103
+ RdxPopoverPopup,
1104
+ RdxPopoverArrow,
1105
+ RdxPopoverTitle,
1106
+ RdxPopoverDescription,
1107
+ RdxPopoverClose,
1108
+ RdxPopoverViewport] }); }
1120
1109
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverModule }); }
1121
1110
  }
1122
1111
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPopoverModule, decorators: [{
1123
1112
  type: NgModule,
1124
1113
  args: [{
1125
- imports: [..._imports],
1126
- exports: [..._imports]
1114
+ imports: [...popoverImports],
1115
+ exports: [...popoverImports]
1127
1116
  }]
1128
1117
  }] });
1129
1118
 
@@ -1131,5 +1120,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1131
1120
  * Generated bundle index. Do not edit.
1132
1121
  */
1133
1122
 
1134
- export { RdxPopoverAnchorDirective, RdxPopoverArrowDirective, RdxPopoverCloseDirective, RdxPopoverContentAttributesComponent, RdxPopoverContentDirective, RdxPopoverModule, RdxPopoverRootDirective, RdxPopoverTriggerDirective };
1123
+ export { RdxPopoverArrow, RdxPopoverBackdrop, RdxPopoverClose, RdxPopoverDescription, RdxPopoverHandle, RdxPopoverModule, RdxPopoverPopup, RdxPopoverPortal, RdxPopoverPortalPresence, RdxPopoverPositioner, RdxPopoverRoot, RdxPopoverTitle, RdxPopoverTrigger, RdxPopoverViewport, createRdxPopoverHandle, injectRdxPopoverRootContext, popoverImports, provideRdxPopoverRootContext };
1135
1124
  //# sourceMappingURL=radix-ng-primitives-popover.mjs.map