@radix-ng/primitives 0.50.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 (207) hide show
  1. package/collection/README.md +1 -0
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +134 -66
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +224 -132
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-arrow.mjs +26 -10
  7. package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +6 -6
  9. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-avatar.mjs +68 -75
  11. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-button.mjs +123 -0
  13. package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
  14. package/fesm2022/radix-ng-primitives-calendar.mjs +104 -103
  15. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-checkbox.mjs +414 -80
  17. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-collapsible.mjs +193 -92
  19. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-collection.mjs +72 -0
  21. package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -0
  22. package/fesm2022/radix-ng-primitives-config.mjs +5 -5
  23. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-context-menu.mjs +143 -427
  25. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-core.mjs +757 -757
  27. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-cropper.mjs +55 -53
  29. package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-date-field.mjs +93 -86
  31. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-dialog.mjs +658 -330
  33. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +98 -76
  35. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
  37. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
  38. package/fesm2022/radix-ng-primitives-editable.mjs +20 -20
  39. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-field.mjs +363 -0
  41. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
  42. package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
  43. package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
  44. package/fesm2022/radix-ng-primitives-focus-guards.mjs +3 -3
  45. package/fesm2022/radix-ng-primitives-focus-guards.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-focus-scope.mjs +29 -14
  47. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-input.mjs +172 -0
  49. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
  50. package/fesm2022/radix-ng-primitives-label.mjs +11 -11
  51. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-menu.mjs +1484 -353
  53. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
  55. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
  57. package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
  58. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1060 -1553
  59. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -366
  61. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-pagination.mjs +51 -51
  63. package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
  64. package/fesm2022/radix-ng-primitives-popover.mjs +980 -995
  65. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  66. package/fesm2022/radix-ng-primitives-popper.mjs +137 -82
  67. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  68. package/fesm2022/radix-ng-primitives-portal.mjs +40 -16
  69. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  70. package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
  71. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  72. package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
  73. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
  74. package/fesm2022/radix-ng-primitives-progress.mjs +231 -92
  75. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  76. package/fesm2022/radix-ng-primitives-radio.mjs +211 -70
  77. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  78. package/fesm2022/radix-ng-primitives-roving-focus.mjs +127 -77
  79. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  80. package/fesm2022/radix-ng-primitives-select.mjs +791 -511
  81. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  82. package/fesm2022/radix-ng-primitives-separator.mjs +16 -45
  83. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  84. package/fesm2022/radix-ng-primitives-slider.mjs +976 -720
  85. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  86. package/fesm2022/radix-ng-primitives-stepper.mjs +69 -71
  87. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  88. package/fesm2022/radix-ng-primitives-switch.mjs +128 -124
  89. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  90. package/fesm2022/radix-ng-primitives-tabs.mjs +388 -115
  91. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  92. package/fesm2022/radix-ng-primitives-time-field.mjs +111 -117
  93. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  94. package/fesm2022/radix-ng-primitives-toggle-group.mjs +122 -248
  95. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  96. package/fesm2022/radix-ng-primitives-toggle.mjs +99 -62
  97. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  98. package/fesm2022/radix-ng-primitives-toolbar.mjs +307 -94
  99. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  100. package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1079
  101. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  102. package/fesm2022/radix-ng-primitives-visually-hidden.mjs +46 -87
  103. package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
  104. package/fesm2022/radix-ng-primitives.mjs.map +1 -1
  105. package/meter/README.md +3 -0
  106. package/navigation-menu/README.md +2 -1
  107. package/package.json +85 -63
  108. package/portal/README.md +2 -0
  109. package/preview-card/README.md +3 -0
  110. package/schematics/collection.json +1 -0
  111. package/schematics/ng-add/index.d.ts +3 -2
  112. package/schematics/ng-add/index.js +62 -31
  113. package/schematics/ng-add/index.js.map +1 -1
  114. package/schematics/ng-add/package-config.d.ts +4 -2
  115. package/schematics/ng-add/package-config.js +10 -2
  116. package/schematics/ng-add/package-config.js.map +1 -1
  117. package/schematics/ng-add/schema.d.ts +3 -0
  118. package/schematics/ng-add/schema.js +3 -0
  119. package/schematics/ng-add/schema.js.map +1 -0
  120. package/schematics/ng-add/schema.json +14 -0
  121. package/select/README.md +2 -0
  122. package/{accordion/index.d.ts → types/radix-ng-primitives-accordion.d.ts} +102 -67
  123. package/types/radix-ng-primitives-alert-dialog.d.ts +114 -0
  124. package/{arrow/index.d.ts → types/radix-ng-primitives-arrow.d.ts} +1 -1
  125. package/{aspect-ratio/index.d.ts → types/radix-ng-primitives-aspect-ratio.d.ts} +1 -1
  126. package/{avatar/index.d.ts → types/radix-ng-primitives-avatar.d.ts} +7 -11
  127. package/types/radix-ng-primitives-button.d.ts +73 -0
  128. package/{calendar/index.d.ts → types/radix-ng-primitives-calendar.d.ts} +2 -3
  129. package/types/radix-ng-primitives-checkbox.d.ts +337 -0
  130. package/types/radix-ng-primitives-collapsible.d.ts +159 -0
  131. package/types/radix-ng-primitives-collection.d.ts +44 -0
  132. package/{config/index.d.ts → types/radix-ng-primitives-config.d.ts} +1 -1
  133. package/types/radix-ng-primitives-context-menu.d.ts +73 -0
  134. package/{core/index.d.ts → types/radix-ng-primitives-core.d.ts} +311 -236
  135. package/{cropper/index.d.ts → types/radix-ng-primitives-cropper.d.ts} +6 -5
  136. package/{date-field/index.d.ts → types/radix-ng-primitives-date-field.d.ts} +42 -27
  137. package/types/radix-ng-primitives-dialog.d.ts +323 -0
  138. package/{dismissable-layer/index.d.ts → types/radix-ng-primitives-dismissable-layer.d.ts} +15 -7
  139. package/types/radix-ng-primitives-drawer.d.ts +448 -0
  140. package/{editable/index.d.ts → types/radix-ng-primitives-editable.d.ts} +1 -1
  141. package/types/radix-ng-primitives-field.d.ts +373 -0
  142. package/types/radix-ng-primitives-fieldset.d.ts +48 -0
  143. package/{focus-scope/index.d.ts → types/radix-ng-primitives-focus-scope.d.ts} +13 -5
  144. package/types/radix-ng-primitives-input.d.ts +87 -0
  145. package/{label/index.d.ts → types/radix-ng-primitives-label.d.ts} +0 -1
  146. package/types/radix-ng-primitives-menu.d.ts +612 -0
  147. package/types/radix-ng-primitives-menubar.d.ts +66 -0
  148. package/types/radix-ng-primitives-meter.d.ts +193 -0
  149. package/types/radix-ng-primitives-navigation-menu.d.ts +488 -0
  150. package/types/radix-ng-primitives-number-field.d.ts +464 -0
  151. package/{pagination/index.d.ts → types/radix-ng-primitives-pagination.d.ts} +2 -2
  152. package/types/radix-ng-primitives-popover.d.ts +416 -0
  153. package/{popper/index.d.ts → types/radix-ng-primitives-popper.d.ts} +50 -9
  154. package/types/radix-ng-primitives-portal.d.ts +30 -0
  155. package/types/radix-ng-primitives-presence.d.ts +55 -0
  156. package/types/radix-ng-primitives-preview-card.d.ts +359 -0
  157. package/types/radix-ng-primitives-progress.d.ts +206 -0
  158. package/{radio/index.d.ts → types/radix-ng-primitives-radio.d.ts} +56 -26
  159. package/{roving-focus/index.d.ts → types/radix-ng-primitives-roving-focus.d.ts} +38 -27
  160. package/types/radix-ng-primitives-select.d.ts +512 -0
  161. package/types/radix-ng-primitives-separator.d.ts +38 -0
  162. package/types/radix-ng-primitives-slider.d.ts +377 -0
  163. package/{stepper/index.d.ts → types/radix-ng-primitives-stepper.d.ts} +21 -22
  164. package/types/radix-ng-primitives-switch.d.ts +121 -0
  165. package/types/radix-ng-primitives-tabs.d.ts +247 -0
  166. package/{time-field/index.d.ts → types/radix-ng-primitives-time-field.d.ts} +46 -31
  167. package/types/radix-ng-primitives-toggle-group.d.ts +116 -0
  168. package/types/radix-ng-primitives-toggle.d.ts +65 -0
  169. package/types/radix-ng-primitives-toolbar.d.ts +180 -0
  170. package/types/radix-ng-primitives-tooltip.d.ts +395 -0
  171. package/{visually-hidden/index.d.ts → types/radix-ng-primitives-visually-hidden.d.ts} +19 -19
  172. package/alert-dialog/index.d.ts +0 -57
  173. package/checkbox/index.d.ts +0 -164
  174. package/collapsible/index.d.ts +0 -85
  175. package/context-menu/index.d.ts +0 -129
  176. package/dialog/index.d.ts +0 -205
  177. package/dropdown-menu/README.md +0 -1
  178. package/dropdown-menu/index.d.ts +0 -171
  179. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -583
  180. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
  181. package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1246
  182. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
  183. package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -740
  184. package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
  185. package/hover-card/README.md +0 -3
  186. package/hover-card/index.d.ts +0 -472
  187. package/menu/index.d.ts +0 -139
  188. package/menubar/index.d.ts +0 -56
  189. package/navigation-menu/index.d.ts +0 -405
  190. package/number-field/index.d.ts +0 -203
  191. package/popover/index.d.ts +0 -403
  192. package/portal/index.d.ts +0 -22
  193. package/presence/index.d.ts +0 -103
  194. package/progress/index.d.ts +0 -79
  195. package/select/index.d.ts +0 -214
  196. package/separator/index.d.ts +0 -63
  197. package/slider/index.d.ts +0 -263
  198. package/switch/index.d.ts +0 -105
  199. package/tabs/index.d.ts +0 -112
  200. package/toggle/index.d.ts +0 -75
  201. package/toggle-group/index.d.ts +0 -194
  202. package/toolbar/index.d.ts +0 -55
  203. package/tooltip/index.d.ts +0 -433
  204. package/tooltip2/README.md +0 -3
  205. package/tooltip2/index.d.ts +0 -325
  206. /package/{focus-guards/index.d.ts → types/radix-ng-primitives-focus-guards.d.ts} +0 -0
  207. /package/{index.d.ts → types/radix-ng-primitives.d.ts} +0 -0
@@ -1,1208 +1,819 @@
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, 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 } from '@radix-ng/primitives/core';
6
- import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
7
- import { filter, tap, Subject, map, debounce, timer } from 'rxjs';
2
+ import { InjectionToken, inject, signal, numberAttribute, DestroyRef, input, Directive, model, booleanAttribute, output, computed, effect, untracked, ElementRef, afterNextRender } from '@angular/core';
3
+ import { createContext, injectId, watch, useGraceArea } from '@radix-ng/primitives/core';
4
+ import * as i1 from '@radix-ng/primitives/popper';
5
+ import { RdxPopper, RdxPopperContentWrapper, RdxPopperArrow, RdxPopperContent, provideRdxPopperContentConfig, RdxPopperAnchor } from '@radix-ng/primitives/popper';
6
+ import { RdxVisuallyHiddenDirective } from '@radix-ng/primitives/visually-hidden';
7
+ import * as i1$1 from '@radix-ng/primitives/portal';
8
+ import { RdxPortal } from '@radix-ng/primitives/portal';
9
+ import * as i1$2 from '@radix-ng/primitives/presence';
10
+ import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence';
11
+ import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
12
+ import * as i1$3 from '@radix-ng/primitives/dismissable-layer';
13
+ import { RdxDismissableLayer } from '@radix-ng/primitives/dismissable-layer';
8
14
 
9
- const RdxTooltipAnchorToken = new InjectionToken('RdxTooltipAnchorToken');
10
-
11
- const RdxTooltipArrowToken = new InjectionToken('RdxTooltipArrowToken');
12
-
13
- const RdxTooltipCloseToken = new InjectionToken('RdxTooltipCloseToken');
15
+ const defaultTooltipConfig = {
16
+ delay: 600,
17
+ closeDelay: 0,
18
+ timeout: 400,
19
+ disableHoverablePopup: false
20
+ };
21
+ const RdxTooltipDefaultsToken = new InjectionToken('RdxTooltipDefaultsToken');
22
+ function provideRdxTooltipConfig(config) {
23
+ return [
24
+ {
25
+ provide: RdxTooltipDefaultsToken,
26
+ useValue: { ...defaultTooltipConfig, ...config }
27
+ }
28
+ ];
29
+ }
30
+ function injectRdxTooltipConfig() {
31
+ return { ...defaultTooltipConfig, ...inject(RdxTooltipDefaultsToken, { optional: true }) };
32
+ }
14
33
 
15
- const RdxTooltipContentAttributesToken = new InjectionToken('RdxTooltipContentAttributesToken');
34
+ /**
35
+ * Tracks the shared "instant" window for a group of tooltips. Once one tooltip
36
+ * opens, sibling tooltips open instantly until `timeout` ms after the last close.
37
+ */
38
+ function createTooltipInstantController(timeout, destroyRef) {
39
+ const instant = signal(false, ...(ngDevMode ? [{ debugName: "instant" }] : /* istanbul ignore next */ []));
40
+ const timer = useTimeoutFn(() => instant.set(false), timeout, { immediate: false }, destroyRef);
41
+ return {
42
+ isInstant: instant.asReadonly(),
43
+ onOpen: () => {
44
+ timer.stop();
45
+ instant.set(true);
46
+ },
47
+ onClose: () => {
48
+ timer.start();
49
+ }
50
+ };
51
+ }
52
+ function useTimeoutFn(cb, delay, options = {}, destroyRef) {
53
+ let id = null;
54
+ const resolveDelay = () => (typeof delay === 'function' ? delay() : delay);
55
+ const stop = () => {
56
+ if (id != null) {
57
+ clearTimeout(id);
58
+ id = null;
59
+ }
60
+ };
61
+ const start = () => {
62
+ stop();
63
+ const ms = resolveDelay();
64
+ if (ms <= 0) {
65
+ queueMicrotask(cb);
66
+ return;
67
+ }
68
+ id = window.setTimeout(() => {
69
+ id = null;
70
+ cb();
71
+ }, ms);
72
+ };
73
+ if (options.immediate) {
74
+ start();
75
+ }
76
+ if (destroyRef) {
77
+ destroyRef.onDestroy(stop);
78
+ }
79
+ return { start, stop, isPending: () => id != null };
80
+ }
16
81
 
17
- var RdxTooltipState;
18
- (function (RdxTooltipState) {
19
- RdxTooltipState["OPEN"] = "open";
20
- RdxTooltipState["CLOSED"] = "closed";
21
- })(RdxTooltipState || (RdxTooltipState = {}));
22
- var RdxTooltipAction;
23
- (function (RdxTooltipAction) {
24
- RdxTooltipAction["OPEN"] = "open";
25
- RdxTooltipAction["CLOSE"] = "close";
26
- })(RdxTooltipAction || (RdxTooltipAction = {}));
27
- var RdxTooltipAttachDetachEvent;
28
- (function (RdxTooltipAttachDetachEvent) {
29
- RdxTooltipAttachDetachEvent["ATTACH"] = "attach";
30
- RdxTooltipAttachDetachEvent["DETACH"] = "detach";
31
- })(RdxTooltipAttachDetachEvent || (RdxTooltipAttachDetachEvent = {}));
32
- var RdxTooltipAnimationStatus;
33
- (function (RdxTooltipAnimationStatus) {
34
- RdxTooltipAnimationStatus["OPEN_STARTED"] = "open_started";
35
- RdxTooltipAnimationStatus["OPEN_ENDED"] = "open_ended";
36
- RdxTooltipAnimationStatus["CLOSED_STARTED"] = "closed_started";
37
- RdxTooltipAnimationStatus["CLOSED_ENDED"] = "closed_ended";
38
- })(RdxTooltipAnimationStatus || (RdxTooltipAnimationStatus = {}));
82
+ const [injectRdxTooltipProviderContext, provideRdxTooltipProviderContext] = createContext('RdxTooltipProviderContext');
83
+ const numberOrUndefined = (value) => (value == null ? undefined : numberAttribute(value));
84
+ const providerContext = () => {
85
+ const provider = inject(RdxTooltipProvider);
86
+ return {
87
+ delay: provider.delay,
88
+ closeDelay: provider.closeDelay,
89
+ isInstant: provider.instant.isInstant,
90
+ onOpen: () => provider.instant.onOpen(),
91
+ onClose: () => provider.instant.onClose()
92
+ };
93
+ };
94
+ /**
95
+ * Shares delay configuration and an instant-open window across a group of tooltips.
96
+ * Once one tooltip opens, adjacent ones open instantly until `timeout` ms after the last close.
97
+ */
98
+ class RdxTooltipProvider {
99
+ constructor() {
100
+ this.defaultConfig = injectRdxTooltipConfig();
101
+ this.destroyRef = inject(DestroyRef);
102
+ /**
103
+ * How long to wait before opening tooltips in this group. Specified in milliseconds.
104
+ */
105
+ this.delay = input(undefined, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), transform: numberOrUndefined });
106
+ /**
107
+ * How long to wait before closing tooltips in this group. Specified in milliseconds.
108
+ */
109
+ this.closeDelay = input(undefined, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: numberOrUndefined });
110
+ /**
111
+ * The window during which an adjacent tooltip opens instantly. Specified in milliseconds.
112
+ */
113
+ this.timeout = input(this.defaultConfig.timeout, { ...(ngDevMode ? { debugName: "timeout" } : /* istanbul ignore next */ {}), transform: numberAttribute });
114
+ this.instant = createTooltipInstantController(() => this.timeout(), this.destroyRef);
115
+ }
116
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipProvider, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
117
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTooltipProvider, isStandalone: true, selector: "[rdxTooltipProvider]", inputs: { delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, timeout: { classPropertyName: "timeout", publicName: "timeout", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideRdxTooltipProviderContext(providerContext)], exportAs: ["rdxTooltipProvider"], ngImport: i0 }); }
118
+ }
119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipProvider, decorators: [{
120
+ type: Directive,
121
+ args: [{
122
+ selector: '[rdxTooltipProvider]',
123
+ exportAs: 'rdxTooltipProvider',
124
+ providers: [provideRdxTooltipProviderContext(providerContext)]
125
+ }]
126
+ }], propDecorators: { delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], timeout: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeout", required: false }] }] } });
39
127
 
40
- class RdxTooltipContentDirective {
128
+ const [injectRdxTooltipContext, provideRdxTooltipContext] = createContext('RdxTooltipContext');
129
+ const context = () => contextFor(inject(RdxTooltip));
130
+ class RdxTooltip {
41
131
  constructor() {
42
- /** @ignore */
43
- this.rootDirective = injectTooltipRoot();
44
- /** @ignore */
45
- this.templateRef = inject(TemplateRef);
46
- /** @ignore */
47
- this.overlay = inject(Overlay);
48
- /** @ignore */
132
+ this.defaultConfig = injectRdxTooltipConfig();
133
+ this.provider = injectRdxTooltipProviderContext(true);
134
+ this.popper = inject(RdxPopper);
49
135
  this.destroyRef = inject(DestroyRef);
50
- /** @ignore */
51
- this.connectedOverlay = inject(CdkConnectedOverlay);
52
- /** @ignore */
53
- this.name = computed(() => `rdx-tooltip-trigger-${this.rootDirective.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : []));
136
+ this.hasAppliedDefaultOpen = false;
54
137
  /**
55
- * @description The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
56
- * @default top
138
+ * Whether the tooltip is currently open.
57
139
  */
58
- this.side = input(RdxPositionSide.Top, ...(ngDevMode ? [{ debugName: "side" }] : []));
140
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
59
141
  /**
60
- * @description The distance in pixels from the trigger.
61
- * @default undefined
142
+ * Whether the tooltip is initially open. Uncontrolled.
62
143
  */
63
- this.sideOffset = input(NaN, ...(ngDevMode ? [{ debugName: "sideOffset", transform: numberAttribute }] : [{
64
- transform: numberAttribute
65
- }]));
144
+ this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
66
145
  /**
67
- * @description The preferred alignment against the trigger. May change when collisions occur.
68
- * @default center
146
+ * How long to wait before opening the tooltip. Specified in milliseconds.
147
+ * Falls back to the surrounding provider, then to the global config.
69
148
  */
70
- this.align = input(RdxPositionAlign.Center, ...(ngDevMode ? [{ debugName: "align" }] : []));
149
+ this.delay = input(undefined, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), transform: (value) => (value == null ? undefined : numberAttribute(value)) });
71
150
  /**
72
- * @description An offset in pixels from the "start" or "end" alignment options.
73
- * @default undefined
151
+ * How long to wait before closing the tooltip. Specified in milliseconds.
74
152
  */
75
- this.alignOffset = input(NaN, ...(ngDevMode ? [{ debugName: "alignOffset", transform: numberAttribute }] : [{
76
- transform: numberAttribute
77
- }]));
153
+ this.closeDelay = input(undefined, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: (value) => (value == null ? undefined : numberAttribute(value)) });
78
154
  /**
79
- * @description Whether to add some alternate positions of the content.
80
- * @default false
155
+ * When `true`, the tooltip closes as the pointer leaves the trigger instead of
156
+ * staying open while the pointer moves over the popup.
81
157
  */
82
- this.alternatePositionsDisabled = input(false, ...(ngDevMode ? [{ debugName: "alternatePositionsDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
83
- /** @description Whether to prevent `onOverlayEscapeKeyDown` handler from calling. */
84
- this.onOverlayEscapeKeyDownDisabled = input(false, ...(ngDevMode ? [{ debugName: "onOverlayEscapeKeyDownDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
85
- /** @description Whether to prevent `onOverlayOutsideClick` handler from calling. */
86
- this.onOverlayOutsideClickDisabled = input(false, ...(ngDevMode ? [{ debugName: "onOverlayOutsideClickDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
158
+ this.disableHoverablePopup = input(this.defaultConfig.disableHoverablePopup, { ...(ngDevMode ? { debugName: "disableHoverablePopup" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
87
159
  /**
88
- * @description Event handler called when the escape key is down.
89
- * It can be prevented by setting `onOverlayEscapeKeyDownDisabled` input to `true`.
160
+ * Determines which axis the tooltip should track the cursor on.
90
161
  */
91
- this.onOverlayEscapeKeyDown = output();
162
+ this.trackCursorAxis = input('none', ...(ngDevMode ? [{ debugName: "trackCursorAxis" }] : /* istanbul ignore next */ []));
92
163
  /**
93
- * @description Event handler called when a pointer event occurs outside the bounds of the component.
94
- * It can be prevented by setting `onOverlayOutsideClickDisabled` input to `true`.
164
+ * When `true`, the tooltip will not open.
95
165
  */
96
- this.onOverlayOutsideClick = output();
166
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
97
167
  /**
98
- * @description Event handler called after the overlay is open
168
+ * Associates this root with detached trigger elements.
99
169
  */
100
- this.onOpen = output();
170
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
101
171
  /**
102
- * @description Event handler called after the overlay is closed
172
+ * Event handler called when the open state changes.
103
173
  */
104
- this.onClosed = output();
105
- /** @ingore */
106
- this.positions = computed(() => this.computePositions(), ...(ngDevMode ? [{ debugName: "positions" }] : []));
107
- this.onOriginChangeEffect();
108
- this.onPositionChangeEffect();
174
+ this.onOpenChange = output();
175
+ this.contentId = injectId('rdx-tooltip-content-');
176
+ this.trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
177
+ this.triggers = signal([], ...(ngDevMode ? [{ debugName: "triggers" }] : /* istanbul ignore next */ []));
178
+ this.payload = signal(undefined, ...(ngDevMode ? [{ debugName: "payload" }] : /* istanbul ignore next */ []));
179
+ this.cursorPosition = signal(undefined, ...(ngDevMode ? [{ debugName: "cursorPosition" }] : /* istanbul ignore next */ []));
180
+ this.openedInstant = signal(false, ...(ngDevMode ? [{ debugName: "openedInstant" }] : /* istanbul ignore next */ []));
181
+ /** Local instant window used when this tooltip is not inside a provider. */
182
+ this.localInstant = createTooltipInstantController(() => this.defaultConfig.timeout, this.destroyRef);
183
+ this.instantGroup = this.provider ?? this.localInstant;
184
+ /** Per-trigger overrides set by the active trigger, taking precedence over the root/provider. */
185
+ this.triggerDelay = signal(undefined, ...(ngDevMode ? [{ debugName: "triggerDelay" }] : /* istanbul ignore next */ []));
186
+ this.triggerCloseDelay = signal(undefined, ...(ngDevMode ? [{ debugName: "triggerCloseDelay" }] : /* istanbul ignore next */ []));
187
+ this.resolvedDelay = computed(() => this.triggerDelay() ?? this.delay() ?? this.provider?.delay() ?? this.defaultConfig.delay, ...(ngDevMode ? [{ debugName: "resolvedDelay" }] : /* istanbul ignore next */ []));
188
+ this.resolvedCloseDelay = computed(() => this.triggerCloseDelay() ??
189
+ this.closeDelay() ??
190
+ this.provider?.closeDelay() ??
191
+ this.defaultConfig.closeDelay, ...(ngDevMode ? [{ debugName: "resolvedCloseDelay" }] : /* istanbul ignore next */ []));
192
+ /** Whether the most recent open happened without the delay. */
193
+ this.instant = this.openedInstant.asReadonly();
194
+ this.virtualAnchor = computed(() => {
195
+ const axis = this.trackCursorAxis();
196
+ const element = this.trigger();
197
+ if (axis === 'none' || !element) {
198
+ return element;
199
+ }
200
+ const position = this.cursorPosition();
201
+ if (!position) {
202
+ return element;
203
+ }
204
+ const followX = axis === 'x' || axis === 'both';
205
+ const followY = axis === 'y' || axis === 'both';
206
+ return {
207
+ getBoundingClientRect: () => {
208
+ const rect = element.getBoundingClientRect();
209
+ const width = followX ? 0 : rect.width;
210
+ const height = followY ? 0 : rect.height;
211
+ const x = followX ? position.x : rect.x;
212
+ const y = followY ? position.y : rect.y;
213
+ return { width, height, x, y, top: y, left: x, right: x + width, bottom: y + height };
214
+ }
215
+ };
216
+ }, ...(ngDevMode ? [{ debugName: "virtualAnchor" }] : /* istanbul ignore next */ []));
217
+ this.openTimer = useTimeoutFn(() => this.applyOpen(false), () => this.resolvedDelay(), { immediate: false }, this.destroyRef);
218
+ this.closeTimer = useTimeoutFn(() => this.applyClose(), () => this.resolvedCloseDelay(), { immediate: false }, this.destroyRef);
219
+ effect(() => {
220
+ const defaultOpen = this.defaultOpen();
221
+ if (!this.hasAppliedDefaultOpen && defaultOpen) {
222
+ this.hasAppliedDefaultOpen = true;
223
+ this.open.set(defaultOpen);
224
+ }
225
+ });
226
+ effect((onCleanup) => {
227
+ const handle = this.handle();
228
+ if (handle) {
229
+ onCleanup(untracked(() => handle.registerRoot(contextFor(this))));
230
+ }
231
+ });
232
+ // Keep the popper anchored to the active trigger, or to the cursor while tracking.
233
+ effect(() => this.popper.anchorOverride.set(this.virtualAnchor()));
234
+ watch([this.open], ([isOpen]) => {
235
+ this.onOpenChange.emit(isOpen);
236
+ if (isOpen) {
237
+ this.instantGroup.onOpen();
238
+ }
239
+ else {
240
+ this.instantGroup.onClose();
241
+ this.openedInstant.set(false);
242
+ }
243
+ }, { defer: true });
109
244
  }
110
- /** @ignore */
111
- ngOnInit() {
112
- this.setScrollStrategy();
113
- this.setHasBackdrop();
114
- this.setDisableClose();
115
- this.onAttach();
116
- this.onDetach();
117
- this.connectKeydownEscape();
118
- this.connectOutsideClick();
245
+ /** Opens immediately, optionally switching the active trigger/payload. */
246
+ show(trigger = this.trigger(), payload) {
247
+ this.applyOpen(true, trigger, payload);
119
248
  }
120
- /** @ignore */
121
- open() {
122
- if (this.connectedOverlay.open) {
123
- return;
249
+ close() {
250
+ this.openTimer.stop();
251
+ this.closeTimer.stop();
252
+ this.applyClose();
253
+ }
254
+ /** Closes after the resolved close delay, e.g. when the pointer or focus leaves. */
255
+ scheduleClose() {
256
+ this.openTimer.stop();
257
+ if (this.resolvedCloseDelay() <= 0) {
258
+ this.applyClose();
259
+ }
260
+ else {
261
+ this.closeTimer.start();
124
262
  }
125
- const prevOpen = this.connectedOverlay.open;
126
- this.connectedOverlay.open = true;
127
- this.fireOverlayNgOnChanges('open', this.connectedOverlay.open, prevOpen);
128
263
  }
129
- /** @ignore */
130
- close() {
131
- if (!this.connectedOverlay.open) {
264
+ /** Hover/focus entered — open after the delay, or instantly within the instant window. */
265
+ onTriggerEnter(trigger = this.trigger(), payload) {
266
+ if (this.disabled()) {
132
267
  return;
133
268
  }
134
- const prevOpen = this.connectedOverlay.open;
135
- this.connectedOverlay.open = false;
136
- this.fireOverlayNgOnChanges('open', this.connectedOverlay.open, prevOpen);
137
- }
138
- /** @ignore */
139
- positionChange() {
140
- return this.connectedOverlay.positionChange.asObservable();
141
- }
142
- /** @ignore */
143
- connectKeydownEscape() {
144
- this.connectedOverlay.overlayKeydown
145
- .asObservable()
146
- .pipe(filter(() => !this.onOverlayEscapeKeyDownDisabled() &&
147
- !this.rootDirective.rdxCdkEventService?.primitivePreventedFromCdkEvent(this.rootDirective, 'cdkOverlayEscapeKeyDown')), filter((event) => event.key === 'Escape'), tap((event) => {
148
- this.onOverlayEscapeKeyDown.emit(event);
149
- }), filter(() => !this.rootDirective.firstDefaultOpen()), tap(() => {
150
- this.rootDirective.handleClose();
151
- }), takeUntilDestroyed(this.destroyRef))
152
- .subscribe();
153
- }
154
- /** @ignore */
155
- connectOutsideClick() {
156
- this.connectedOverlay.overlayOutsideClick
157
- .asObservable()
158
- .pipe(filter(() => !this.onOverlayOutsideClickDisabled() &&
159
- !this.rootDirective.rdxCdkEventService?.primitivePreventedFromCdkEvent(this.rootDirective, 'cdkOverlayOutsideClick')),
160
- /**
161
- * Handle the situation when an anchor is added and the anchor becomes the origin of the overlay
162
- * hence the trigger will be considered the outside element
163
- */
164
- filter((event) => {
165
- return (!this.rootDirective.anchorDirective() ||
166
- !this.rootDirective
167
- .triggerDirective()
168
- .elementRef.nativeElement.contains(event.target));
169
- }), tap((event) => {
170
- this.onOverlayOutsideClick.emit(event);
171
- }), filter(() => !this.rootDirective.firstDefaultOpen()), tap(() => {
172
- this.rootDirective.handleClose();
173
- }), takeUntilDestroyed(this.destroyRef))
174
- .subscribe();
175
- }
176
- /** @ignore */
177
- onAttach() {
178
- this.connectedOverlay.attach
179
- .asObservable()
180
- .pipe(tap(() => {
181
- /**
182
- * `this.onOpen.emit();` is being delegated to the rootDirective directive due to the opening animation
183
- */
184
- this.rootDirective.attachDetachEvent.set(RdxTooltipAttachDetachEvent.ATTACH);
185
- }), takeUntilDestroyed(this.destroyRef))
186
- .subscribe();
187
- }
188
- /** @ignore */
189
- onDetach() {
190
- this.connectedOverlay.detach
191
- .asObservable()
192
- .pipe(tap(() => {
193
- /**
194
- * `this.onClosed.emit();` is being delegated to the rootDirective directive due to the closing animation
195
- */
196
- this.rootDirective.attachDetachEvent.set(RdxTooltipAttachDetachEvent.DETACH);
197
- }), takeUntilDestroyed(this.destroyRef))
198
- .subscribe();
199
- }
200
- /** @ignore */
201
- setScrollStrategy() {
202
- const prevScrollStrategy = this.connectedOverlay.scrollStrategy;
203
- this.connectedOverlay.scrollStrategy = this.overlay.scrollStrategies.reposition();
204
- this.fireOverlayNgOnChanges('scrollStrategy', this.connectedOverlay.scrollStrategy, prevScrollStrategy);
269
+ if (trigger) {
270
+ this.trigger.set(trigger);
271
+ }
272
+ this.payload.set(payload);
273
+ this.closeTimer.stop();
274
+ if (this.instantGroup.isInstant() || this.resolvedDelay() <= 0) {
275
+ this.applyOpen(true, trigger, payload);
276
+ }
277
+ else {
278
+ this.openTimer.start();
279
+ }
205
280
  }
206
- /** @ignore */
207
- setHasBackdrop() {
208
- const prevHasBackdrop = this.connectedOverlay.hasBackdrop;
209
- this.connectedOverlay.hasBackdrop = false;
210
- this.fireOverlayNgOnChanges('hasBackdrop', this.connectedOverlay.hasBackdrop, prevHasBackdrop);
281
+ onTriggerLeave() {
282
+ this.openTimer.stop();
283
+ if (this.disableHoverablePopup()) {
284
+ this.scheduleClose();
285
+ }
286
+ // Otherwise the positioner's grace area decides when to close.
211
287
  }
212
- /** @ignore */
213
- setDisableClose() {
214
- const prevDisableClose = this.connectedOverlay.disableClose;
215
- this.connectedOverlay.disableClose = true;
216
- this.fireOverlayNgOnChanges('disableClose', this.connectedOverlay.disableClose, prevDisableClose);
288
+ registerTrigger(trigger) {
289
+ this.triggers.update((triggers) => (triggers.includes(trigger) ? triggers : [...triggers, trigger]));
290
+ if (!this.trigger()) {
291
+ this.trigger.set(trigger);
292
+ }
293
+ return () => {
294
+ this.triggers.update((triggers) => triggers.filter((candidate) => candidate !== trigger));
295
+ if (this.trigger() === trigger) {
296
+ const nextTrigger = this.triggers()[0];
297
+ this.trigger.set(nextTrigger);
298
+ if (!nextTrigger && !this.destroyRef.destroyed) {
299
+ this.applyClose();
300
+ }
301
+ }
302
+ };
217
303
  }
218
- /** @ignore */
219
- setOrigin(origin) {
220
- const prevOrigin = this.connectedOverlay.origin;
221
- this.connectedOverlay.origin = origin;
222
- this.fireOverlayNgOnChanges('origin', this.connectedOverlay.origin, prevOrigin);
304
+ setCursorPosition(position) {
305
+ this.cursorPosition.set(position);
223
306
  }
224
- /** @ignore */
225
- setPositions(positions) {
226
- const prevPositions = this.connectedOverlay.positions;
227
- this.connectedOverlay.positions = positions;
228
- this.fireOverlayNgOnChanges('positions', this.connectedOverlay.positions, prevPositions);
229
- this.connectedOverlay.overlayRef?.updatePosition();
307
+ /** Applies per-trigger delay overrides from the trigger that is becoming active. */
308
+ setDelays(delay, closeDelay) {
309
+ this.triggerDelay.set(delay);
310
+ this.triggerCloseDelay.set(closeDelay);
230
311
  }
231
- /** @ignore */
232
- computePositions() {
233
- const arrowHeight = this.rootDirective.arrowDirective()?.height() ?? 0;
234
- const offsets = {
235
- sideOffset: arrowHeight + (isNaN(this.sideOffset()) ? RDX_POSITIONING_DEFAULTS.offsets.side : this.sideOffset()),
236
- alignOffset: isNaN(this.alignOffset()) ? RDX_POSITIONING_DEFAULTS.offsets.align : this.alignOffset()
237
- };
238
- const basePosition = getContentPosition({
239
- side: this.side(),
240
- align: this.align(),
241
- sideOffset: offsets.sideOffset,
242
- alignOffset: offsets.alignOffset
243
- });
244
- const positions = [basePosition];
245
- if (!this.alternatePositionsDisabled()) {
246
- /**
247
- * Alternate positions for better user experience along the X/Y axis (e.g. vertical/horizontal scrolling)
248
- */
249
- const allPossibleConnectedPositions = getAllPossibleConnectedPositions();
250
- allPossibleConnectedPositions.forEach((_, key) => {
251
- const sideAndAlignArray = key.split('|');
252
- if (sideAndAlignArray[0] !== this.side() ||
253
- sideAndAlignArray[1] !== this.align()) {
254
- positions.push(getContentPosition({
255
- side: sideAndAlignArray[0],
256
- align: sideAndAlignArray[1],
257
- sideOffset: offsets.sideOffset,
258
- alignOffset: offsets.alignOffset
259
- }));
260
- }
261
- });
312
+ applyOpen(instant, trigger = this.trigger(), payload) {
313
+ if (this.disabled()) {
314
+ return;
262
315
  }
263
- return positions;
316
+ this.openTimer.stop();
317
+ this.closeTimer.stop();
318
+ if (trigger) {
319
+ this.trigger.set(trigger);
320
+ }
321
+ if (payload !== undefined) {
322
+ this.payload.set(payload);
323
+ }
324
+ this.openedInstant.set(instant || this.instantGroup.isInstant());
325
+ this.open.set(true);
264
326
  }
265
- onOriginChangeEffect() {
266
- effect(() => {
267
- const origin = (this.rootDirective.anchorDirective() ?? this.rootDirective.triggerDirective())
268
- .overlayOrigin;
269
- untracked(() => {
270
- this.setOrigin(origin);
271
- });
272
- });
327
+ applyClose() {
328
+ this.openedInstant.set(this.instantGroup.isInstant());
329
+ this.open.set(false);
273
330
  }
274
- /** @ignore */
275
- onPositionChangeEffect() {
276
- effect(() => {
277
- const positions = this.positions();
278
- this.alternatePositionsDisabled();
279
- untracked(() => {
280
- this.setPositions(positions);
281
- });
282
- });
283
- }
284
- /** @ignore */
285
- fireOverlayNgOnChanges(input, currentValue, previousValue, firstChange = false) {
286
- this.connectedOverlay.ngOnChanges({
287
- [input]: new SimpleChange(previousValue, currentValue, firstChange)
331
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
332
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTooltip, isStandalone: true, selector: "[rdxTooltip]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", 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 }, disableHoverablePopup: { classPropertyName: "disableHoverablePopup", publicName: "disableHoverablePopup", isSignal: true, isRequired: false, transformFunction: null }, trackCursorAxis: { classPropertyName: "trackCursorAxis", publicName: "trackCursorAxis", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", onOpenChange: "onOpenChange" }, providers: [provideRdxTooltipContext(context)], exportAs: ["rdxTooltip"], hostDirectives: [{ directive: i1.RdxPopper }], ngImport: i0 }); }
333
+ }
334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltip, decorators: [{
335
+ type: Directive,
336
+ args: [{
337
+ selector: '[rdxTooltip]',
338
+ exportAs: 'rdxTooltip',
339
+ providers: [provideRdxTooltipContext(context)],
340
+ hostDirectives: [RdxPopper]
341
+ }]
342
+ }], 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 }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], disableHoverablePopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableHoverablePopup", required: false }] }], trackCursorAxis: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackCursorAxis", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], handle: [{ type: i0.Input, args: [{ isSignal: true, alias: "handle", required: false }] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }] } });
343
+ function contextFor(root) {
344
+ return {
345
+ contentId: root.contentId,
346
+ isOpen: root.open,
347
+ instant: root.instant,
348
+ disabled: root.disabled,
349
+ disableHoverablePopup: root.disableHoverablePopup,
350
+ trackCursorAxis: root.trackCursorAxis,
351
+ trigger: root.trigger.asReadonly(),
352
+ triggers: root.triggers.asReadonly(),
353
+ payload: root.payload.asReadonly(),
354
+ open: (trigger, payload) => root.show(trigger, payload),
355
+ close: () => root.close(),
356
+ closeDelayed: () => root.scheduleClose(),
357
+ registerTrigger: (trigger) => root.registerTrigger(trigger),
358
+ onTriggerEnter: (trigger, payload) => root.onTriggerEnter(trigger, payload),
359
+ onTriggerLeave: () => root.onTriggerLeave(),
360
+ setCursorPosition: (position) => root.setCursorPosition(position),
361
+ setDelays: (delay, closeDelay) => root.setDelays(delay, closeDelay)
362
+ };
363
+ }
364
+
365
+ class RdxTooltipArrow {
366
+ constructor() {
367
+ this.rootContext = injectRdxTooltipContext();
368
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
369
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
370
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
371
+ this.uncentered = computed(() => this.wrapper?.arrowUncentered() ?? false, ...(ngDevMode ? [{ debugName: "uncentered" }] : /* istanbul ignore next */ []));
372
+ this.isVisuallyHidden = !!inject(RdxVisuallyHiddenDirective, {
373
+ optional: true
288
374
  });
289
375
  }
290
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
291
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.3", type: RdxTooltipContentDirective, isStandalone: true, selector: "[rdxTooltipContent]", 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 }); }
376
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipArrow, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
377
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxTooltipArrow, isStandalone: true, selector: "[rdxTooltipArrow]", host: { properties: { "hidden": "isVisuallyHidden", "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 }); }
292
378
  }
293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipContentDirective, decorators: [{
379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipArrow, decorators: [{
294
380
  type: Directive,
295
381
  args: [{
296
- selector: '[rdxTooltipContent]',
297
- hostDirectives: [CdkConnectedOverlay]
382
+ selector: '[rdxTooltipArrow]',
383
+ hostDirectives: [RdxPopperArrow],
384
+ host: {
385
+ '[hidden]': 'isVisuallyHidden',
386
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
387
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
388
+ '[attr.data-side]': 'side()',
389
+ '[attr.data-align]': 'align()',
390
+ '[attr.data-uncentered]': 'uncentered() ? "" : undefined'
391
+ }
298
392
  }]
299
- }], ctorParameters: () => [] });
393
+ }] });
300
394
 
301
- class RdxTooltipTriggerDirective {
395
+ /**
396
+ * The tooltip popup. Renders the content with `role="tooltip"`.
397
+ */
398
+ class RdxTooltipPopup {
302
399
  constructor() {
303
- /** @ignore */
304
- this.rootDirective = injectTooltipRoot();
305
- /** @ignore */
306
- this.elementRef = inject(ElementRef);
307
- /** @ignore */
308
- this.overlayOrigin = inject(CdkOverlayOrigin);
309
- /** @ignore */
310
- this.name = computed(() => `rdx-tooltip-trigger-${this.rootDirective.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : []));
311
- }
312
- /** @ignore */
313
- pointerenter() {
314
- this.rootDirective.handleOpen();
400
+ this.rootContext = injectRdxTooltipContext();
401
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
402
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
403
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
315
404
  }
316
- /** @ignore */
317
- pointerleave() {
318
- this.rootDirective.handleClose();
319
- }
320
- /** @ignore */
321
- focus() {
322
- this.rootDirective.handleOpen();
323
- }
324
- /** @ignore */
325
- blur() {
326
- this.rootDirective.handleClose();
327
- }
328
- /** @ignore */
329
- click() {
330
- this.rootDirective.handleClose();
331
- }
332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
333
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.3", type: RdxTooltipTriggerDirective, isStandalone: true, selector: "[rdxTooltipTrigger]", host: { attributes: { "type": "button" }, listeners: { "pointerenter": "pointerenter()", "pointerleave": "pointerleave()", "focus": "focus()", "blur": "blur()", "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "rootDirective.isOpen()", "attr.aria-controls": "rootDirective.contentDirective().name()", "attr.data-state": "rootDirective.state()" } }, hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
405
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
406
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxTooltipPopup, isStandalone: true, selector: "[rdxTooltipPopup]", host: { attributes: { "role": "tooltip" }, properties: { "id": "rootContext.contentId", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-side": "side()", "attr.data-align": "align()" } }, hostDirectives: [{ directive: i1.RdxPopperContent }], ngImport: i0 }); }
334
407
  }
335
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipTriggerDirective, decorators: [{
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPopup, decorators: [{
336
409
  type: Directive,
337
410
  args: [{
338
- selector: '[rdxTooltipTrigger]',
339
- hostDirectives: [CdkOverlayOrigin],
411
+ selector: '[rdxTooltipPopup]',
412
+ hostDirectives: [RdxPopperContent],
340
413
  host: {
341
- type: 'button',
342
- '[attr.id]': 'name()',
343
- '[attr.aria-haspopup]': '"dialog"',
344
- '[attr.aria-expanded]': 'rootDirective.isOpen()',
345
- '[attr.aria-controls]': 'rootDirective.contentDirective().name()',
346
- '[attr.data-state]': 'rootDirective.state()',
347
- '(pointerenter)': 'pointerenter()',
348
- '(pointerleave)': 'pointerleave()',
349
- '(focus)': 'focus()',
350
- '(blur)': 'blur()',
351
- '(click)': 'click()'
414
+ role: 'tooltip',
415
+ '[id]': 'rootContext.contentId',
416
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
417
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
418
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
419
+ '[attr.data-side]': 'side()',
420
+ '[attr.data-align]': 'align()'
352
421
  }
353
422
  }]
354
423
  }] });
355
424
 
356
- const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__');
425
+ /**
426
+ * Moves the tooltip to a different part of the DOM.
427
+ */
428
+ class RdxTooltipPortal {
429
+ constructor() {
430
+ this.container = input.required(...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
431
+ }
432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
433
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTooltipPortal, isStandalone: true, selector: "[rdxTooltipPortal]", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: i1$1.RdxPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
434
+ }
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPortal, decorators: [{
436
+ type: Directive,
437
+ args: [{
438
+ selector: '[rdxTooltipPortal]',
439
+ hostDirectives: [
440
+ {
441
+ directive: RdxPortal,
442
+ inputs: ['container']
443
+ }
444
+ ]
445
+ }]
446
+ }], propDecorators: { container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: true }] }] } });
357
447
 
358
- function eventTypeAsPrimitiveConfigKey(eventType) {
359
- return `prevent${eventType[0].toUpperCase()}${eventType.slice(1)}`;
448
+ class RdxTooltipPortalPresence {
449
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPortalPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
450
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxTooltipPortalPresence, isStandalone: true, selector: "ng-template[rdxTooltipPortalPresence]", providers: [
451
+ provideRdxPresenceContext(() => {
452
+ const context = injectRdxTooltipContext();
453
+ return { present: context.isOpen };
454
+ })
455
+ ], hostDirectives: [{ directive: i1$2.RdxPresenceDirective }], ngImport: i0 }); }
360
456
  }
361
- class RdxCdkEventService {
362
- #clickDomRootEventCallbacks;
457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPortalPresence, decorators: [{
458
+ type: Directive,
459
+ args: [{
460
+ selector: 'ng-template[rdxTooltipPortalPresence]',
461
+ hostDirectives: [RdxPresenceDirective],
462
+ providers: [
463
+ provideRdxPresenceContext(() => {
464
+ const context = injectRdxTooltipContext();
465
+ return { present: context.isOpen };
466
+ })
467
+ ]
468
+ }]
469
+ }] });
470
+
471
+ /**
472
+ * Positions the tooltip popup against its trigger (or a custom anchor).
473
+ */
474
+ class RdxTooltipPositioner {
363
475
  constructor() {
364
- this.document = injectDocument();
476
+ this.rootContext = injectRdxTooltipContext();
477
+ this.wrapper = inject(RdxPopperContentWrapper);
365
478
  this.destroyRef = inject(DestroyRef);
366
- this.ngZone = inject(NgZone);
367
- this.renderer2 = inject(Renderer2);
368
- this.window = injectWindow();
369
- this.onDestroyCallbacks = new Set([() => deleteRdxCdkEventServiceWindowKey(this.window)]);
370
- this.#clickDomRootEventCallbacks = new Set();
371
- this.#listenToClickDomRootEvent();
372
- this.#registerOnDestroyCallbacks();
373
- }
374
- registerPrimitive(primitiveInstance) {
375
- if (!this.primitiveConfigs) {
376
- this.primitiveConfigs = new Map();
377
- }
378
- if (!this.primitiveConfigs.has(primitiveInstance)) {
379
- this.primitiveConfigs.set(primitiveInstance, {});
380
- }
381
- }
382
- deregisterPrimitive(primitiveInstance) {
383
- if (this.primitiveConfigs?.has(primitiveInstance)) {
384
- this.primitiveConfigs.delete(primitiveInstance);
385
- }
386
- }
387
- preventPrimitiveFromCdkEvent(primitiveInstance, eventType) {
388
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
389
- }
390
- allowPrimitiveForCdkEvent(primitiveInstance, eventType) {
391
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
392
- }
393
- preventPrimitiveFromCdkMultiEvents(primitiveInstance, eventTypes) {
394
- eventTypes.forEach((eventType) => {
395
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
396
- });
397
- }
398
- allowPrimitiveForCdkMultiEvents(primitiveInstance, eventTypes) {
399
- eventTypes.forEach((eventType) => {
400
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
401
- });
402
- }
403
- setPreventPrimitiveFromCdkMixEvents(primitiveInstance, eventTypes) {
404
- Object.keys(eventTypes).forEach((eventType) => {
405
- this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, eventTypes[eventTypeAsPrimitiveConfigKey(eventType)]);
406
- });
407
- }
408
- primitivePreventedFromCdkEvent(primitiveInstance, eventType) {
409
- return this.primitiveConfigs?.get(primitiveInstance)?.[eventTypeAsPrimitiveConfigKey(eventType)];
410
- }
411
- addClickDomRootEventCallback(callback) {
412
- this.#clickDomRootEventCallbacks.add(callback);
413
- }
414
- removeClickDomRootEventCallback(callback) {
415
- return this.#clickDomRootEventCallbacks.delete(callback);
416
- }
417
- #setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, value) {
418
- if (!this.primitiveConfigs?.has(primitiveInstance)) {
419
- isDevMode() &&
420
- console.error('[RdxCdkEventService.preventPrimitiveFromCdkEvent] RDX Primitive instance has not been registered!', primitiveInstance);
421
- return;
422
- }
423
- switch (eventType) {
424
- case 'cdkOverlayOutsideClick':
425
- this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayOutsideClick = value;
426
- break;
427
- case 'cdkOverlayEscapeKeyDown':
428
- this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayEscapeKeyDown = value;
429
- break;
430
- }
431
- }
432
- #registerOnDestroyCallbacks() {
433
- this.destroyRef.onDestroy(() => {
434
- this.onDestroyCallbacks.forEach((onDestroyCallback) => onDestroyCallback());
435
- this.onDestroyCallbacks.clear();
436
- });
437
- }
438
- #listenToClickDomRootEvent() {
439
- const target = this.document;
440
- const eventName = 'click';
441
- const options = { capture: true };
442
- const callback = (event) => {
443
- this.#clickDomRootEventCallbacks.forEach((clickDomRootEventCallback) => clickDomRootEventCallback(event));
444
- };
445
- const major = parseInt(VERSION.major);
446
- const minor = parseInt(VERSION.minor);
447
- let destroyClickDomRootEventListener;
479
+ this.dismissableLayer = inject(RdxDismissableLayer);
480
+ this.elementRef = inject(ElementRef);
448
481
  /**
449
- * @see src/cdk/platform/features/backwards-compatibility.ts in @angular/cdk
482
+ * An element to position the popup against. Defaults to the trigger.
450
483
  */
451
- if (major > 19 || (major === 19 && minor > 0) || (major === 0 && minor === 0)) {
452
- destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
453
- const destroyClickDomRootEventListenerInternal = this.renderer2.listen(target, eventName, callback, options);
454
- return () => {
455
- destroyClickDomRootEventListenerInternal();
456
- this.#clickDomRootEventCallbacks.clear();
457
- };
458
- });
459
- }
460
- else {
461
- /**
462
- * This part can get removed when v19.1 or higher is on the board
463
- */
464
- destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
465
- target.addEventListener(eventName, callback, options);
466
- return () => {
467
- this.ngZone.runOutsideAngular(() => target.removeEventListener(eventName, callback, options));
468
- this.#clickDomRootEventCallbacks.clear();
469
- };
470
- });
471
- }
472
- this.onDestroyCallbacks.add(destroyClickDomRootEventListener);
473
- }
474
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxCdkEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
475
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxCdkEventService }); }
476
- }
477
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxCdkEventService, decorators: [{
478
- type: Injectable
479
- }], ctorParameters: () => [] });
480
- const RdxCdkEventServiceToken = new InjectionToken('RdxCdkEventServiceToken');
481
- const existsErrorMessage = 'RdxCdkEventService should be provided only once!';
482
- const deleteRdxCdkEventServiceWindowKey = (window) => {
483
- delete window[RdxCdkEventServiceWindowKey];
484
- };
485
- const getProvider = (throwWhenExists = true) => ({
486
- provide: RdxCdkEventServiceToken,
487
- useFactory: () => {
488
- isDevMode() && console.log('providing RdxCdkEventService...');
489
- const window = injectWindow();
490
- if (window[RdxCdkEventServiceWindowKey]) {
491
- if (throwWhenExists) {
492
- throw Error(existsErrorMessage);
493
- }
494
- else {
495
- isDevMode() && console.warn(existsErrorMessage);
496
- }
497
- }
498
- window[RdxCdkEventServiceWindowKey] ??= new RdxCdkEventService();
499
- return window[RdxCdkEventServiceWindowKey];
500
- }
501
- });
502
- const provideRdxCdkEventServiceInRoot = () => makeEnvironmentProviders([getProvider()]);
503
- const provideRdxCdkEventService = () => getProvider(false);
504
- const injectRdxCdkEventService = () => inject(RdxCdkEventServiceToken, { optional: true });
505
-
506
- let nextId = 0;
507
- class RdxTooltipRootDirective {
508
- constructor() {
509
- /** @ignore */
510
- this.uniqueId = signal(++nextId, ...(ngDevMode ? [{ debugName: "uniqueId" }] : []));
511
- /** @ignore */
512
- this.name = computed(() => `rdx-tooltip-root-${this.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : []));
484
+ this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
513
485
  /**
514
- * @description The anchor directive that comes form outside the tooltip rootDirective
515
- * @default undefined
486
+ * The preferred side of the anchor to render against when open.
516
487
  */
517
- this.anchor = input(void 0, ...(ngDevMode ? [{ debugName: "anchor" }] : []));
488
+ this.side = input('top', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
518
489
  /**
519
- * @description The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
520
- * @default false
490
+ * The distance in pixels from the anchor.
521
491
  */
522
- this.defaultOpen = input(false, ...(ngDevMode ? [{ debugName: "defaultOpen", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
492
+ this.sideOffset = input(0, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
523
493
  /**
524
- * @description The controlled state of the tooltip. `open` input take precedence of `defaultOpen` input.
525
- * @default undefined
494
+ * The preferred alignment against the anchor.
526
495
  */
527
- this.open = input(void 0, ...(ngDevMode ? [{ debugName: "open", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
496
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
528
497
  /**
529
- * To customise the open delay for a specific tooltip.
498
+ * An offset in pixels from the `start` or `end` alignment options.
530
499
  */
531
- this.openDelay = input(500, ...(ngDevMode ? [{ debugName: "openDelay", transform: numberAttribute }] : [{
532
- transform: numberAttribute
533
- }]));
500
+ this.alignOffset = input(0, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
534
501
  /**
535
- * To customise the close delay for a specific tooltip.
502
+ * The padding between the arrow and the edges of the content.
536
503
  */
537
- this.closeDelay = input(200, ...(ngDevMode ? [{ debugName: "closeDelay", transform: numberAttribute }] : [{
538
- transform: numberAttribute
539
- }]));
504
+ this.arrowPadding = input(5, { ...(ngDevMode ? { debugName: "arrowPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
540
505
  /**
541
- * @description Whether to control the state of the tooltip from external. Use in conjunction with `open` input.
542
- * @default undefined
506
+ * When `true`, overrides the `side` and `align` preferences to prevent collisions with boundary edges.
543
507
  */
544
- this.externalControl = input(void 0, ...(ngDevMode ? [{ debugName: "externalControl", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
508
+ this.avoidCollisions = input(true, { ...(ngDevMode ? { debugName: "avoidCollisions" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
545
509
  /**
546
- * @description Whether to take into account CSS opening/closing animations.
547
- * @default false
510
+ * The element used as the collision boundary.
548
511
  */
549
- this.cssAnimation = input(false, ...(ngDevMode ? [{ debugName: "cssAnimation", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
512
+ this.collisionBoundary = input(...(ngDevMode ? [undefined, { debugName: "collisionBoundary" }] : /* istanbul ignore next */ []));
550
513
  /**
551
- * @description Whether to take into account CSS opening animations. `cssAnimation` input must be set to 'true'
552
- * @default false
514
+ * The distance in pixels from the boundary edges where collision detection should occur.
553
515
  */
554
- this.cssOpeningAnimation = input(false, ...(ngDevMode ? [{ debugName: "cssOpeningAnimation", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
516
+ this.collisionPadding = input(5, ...(ngDevMode ? [{ debugName: "collisionPadding" }] : /* istanbul ignore next */ []));
555
517
  /**
556
- * @description Whether to take into account CSS closing animations. `cssAnimation` input must be set to 'true'
557
- * @default false
518
+ * The sticky behavior on the `align` axis.
558
519
  */
559
- this.cssClosingAnimation = input(false, ...(ngDevMode ? [{ debugName: "cssClosingAnimation", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
560
- /** @ignore */
561
- this.cssAnimationStatus = signal(null, ...(ngDevMode ? [{ debugName: "cssAnimationStatus" }] : []));
562
- /** @ignore */
563
- this.contentDirective = contentChild.required(RdxTooltipContentDirective);
564
- /** @ignore */
565
- this.triggerDirective = contentChild.required(RdxTooltipTriggerDirective);
566
- /** @ignore */
567
- this.arrowDirective = contentChild(RdxTooltipArrowToken, ...(ngDevMode ? [{ debugName: "arrowDirective" }] : []));
568
- /** @ignore */
569
- this.closeDirective = contentChild(RdxTooltipCloseToken, ...(ngDevMode ? [{ debugName: "closeDirective" }] : []));
570
- /** @ignore */
571
- this.contentAttributesComponent = contentChild(RdxTooltipContentAttributesToken, ...(ngDevMode ? [{ debugName: "contentAttributesComponent" }] : []));
572
- /** @ignore */
573
- this.internalAnchorDirective = contentChild(RdxTooltipAnchorToken, ...(ngDevMode ? [{ debugName: "internalAnchorDirective" }] : []));
574
- /** @ignore */
575
- this.viewContainerRef = inject(ViewContainerRef);
576
- /** @ignore */
577
- this.rdxCdkEventService = injectRdxCdkEventService();
578
- /** @ignore */
579
- this.destroyRef = inject(DestroyRef);
580
- /** @ignore */
581
- this.state = signal(RdxTooltipState.CLOSED, ...(ngDevMode ? [{ debugName: "state" }] : []));
582
- /** @ignore */
583
- this.attachDetachEvent = signal(RdxTooltipAttachDetachEvent.DETACH, ...(ngDevMode ? [{ debugName: "attachDetachEvent" }] : []));
584
- /** @ignore */
585
- this.isFirstDefaultOpen = signal(false, ...(ngDevMode ? [{ debugName: "isFirstDefaultOpen" }] : []));
586
- /** @ignore */
587
- this.anchorDirective = computed(() => this.internalAnchorDirective() ?? this.anchor(), ...(ngDevMode ? [{ debugName: "anchorDirective" }] : []));
588
- /** @ignore */
589
- this.actionSubject$ = new Subject();
590
- /** @ignore */
591
- this.onAnchorChangeEffect = () => {
592
- effect(() => {
593
- const anchor = this.anchor();
594
- untracked(() => {
595
- if (anchor) {
596
- anchor.setRoot(this);
597
- }
598
- });
599
- });
600
- };
601
- this.rdxCdkEventService?.registerPrimitive(this);
602
- this.destroyRef.onDestroy(() => this.rdxCdkEventService?.deregisterPrimitive(this));
603
- this.actionSubscription();
604
- this.onStateChangeEffect();
605
- this.onCssAnimationStatusChangeChangeEffect();
606
- this.onOpenChangeEffect();
607
- this.onIsFirstDefaultOpenChangeEffect();
608
- this.onAnchorChangeEffect();
609
- this.emitOpenOrClosedEventEffect();
610
- afterNextRender({
611
- write: () => {
612
- if (this.defaultOpen() && !this.open()) {
613
- this.isFirstDefaultOpen.set(true);
614
- }
615
- }
616
- });
617
- }
618
- /** @ignore */
619
- getAnimationParamsSnapshot() {
620
- return {
621
- cssAnimation: this.cssAnimation(),
622
- cssOpeningAnimation: this.cssOpeningAnimation(),
623
- cssClosingAnimation: this.cssClosingAnimation(),
624
- cssAnimationStatus: this.cssAnimationStatus(),
625
- attachDetachEvent: this.attachDetachEvent(),
626
- state: this.state(),
627
- canEmitOnOpenOrOnClosed: this.canEmitOnOpenOrOnClosed()
628
- };
629
- }
630
- /** @ignore */
631
- controlledExternally() {
632
- return this.externalControl;
633
- }
634
- /** @ignore */
635
- firstDefaultOpen() {
636
- return this.isFirstDefaultOpen();
637
- }
638
- /** @ignore */
639
- handleOpen() {
640
- if (this.externalControl()) {
641
- return;
642
- }
643
- this.actionSubject$.next(RdxTooltipAction.OPEN);
644
- }
645
- /** @ignore */
646
- handleClose(closeButton) {
647
- if (this.isFirstDefaultOpen()) {
648
- this.isFirstDefaultOpen.set(false);
649
- }
650
- if (!closeButton && this.externalControl()) {
651
- return;
652
- }
653
- this.actionSubject$.next(RdxTooltipAction.CLOSE);
654
- }
655
- /** @ignore */
656
- handleToggle() {
657
- if (this.externalControl()) {
658
- return;
659
- }
660
- this.isOpen() ? this.handleClose() : this.handleOpen();
661
- }
662
- /** @ignore */
663
- isOpen(state) {
664
- return (state ?? this.state()) === RdxTooltipState.OPEN;
665
- }
666
- /** @ignore */
667
- setState(state = RdxTooltipState.CLOSED) {
668
- if (state === this.state()) {
669
- return;
670
- }
671
- this.state.set(state);
672
- }
673
- /** @ignore */
674
- openContent() {
675
- this.contentDirective().open();
676
- if (!this.cssAnimation() || !this.cssOpeningAnimation()) {
677
- this.cssAnimationStatus.set(null);
678
- }
679
- }
680
- /** @ignore */
681
- closeContent() {
682
- this.contentDirective().close();
683
- if (!this.cssAnimation() || !this.cssClosingAnimation()) {
684
- this.cssAnimationStatus.set(null);
685
- }
686
- }
687
- /** @ignore */
688
- emitOnOpen() {
689
- this.contentDirective().onOpen.emit();
690
- }
691
- /** @ignore */
692
- emitOnClosed() {
693
- this.contentDirective().onClosed.emit();
694
- }
695
- /** @ignore */
696
- ifOpenOrCloseWithoutAnimations(state) {
697
- return (!this.contentAttributesComponent() ||
698
- !this.cssAnimation() ||
699
- (this.cssAnimation() && !this.cssClosingAnimation() && state === RdxTooltipState.CLOSED) ||
700
- (this.cssAnimation() && !this.cssOpeningAnimation() && state === RdxTooltipState.OPEN) ||
701
- // !this.cssAnimationStatus() ||
702
- (this.cssOpeningAnimation() &&
703
- state === RdxTooltipState.OPEN &&
704
- [RdxTooltipAnimationStatus.OPEN_STARTED].includes(this.cssAnimationStatus())) ||
705
- (this.cssClosingAnimation() &&
706
- state === RdxTooltipState.CLOSED &&
707
- [RdxTooltipAnimationStatus.CLOSED_STARTED].includes(this.cssAnimationStatus())));
708
- }
709
- /** @ignore */
710
- ifOpenOrCloseWithAnimations(cssAnimationStatus) {
711
- return (this.contentAttributesComponent() &&
712
- this.cssAnimation() &&
713
- cssAnimationStatus &&
714
- ((this.cssOpeningAnimation() &&
715
- this.state() === RdxTooltipState.OPEN &&
716
- [RdxTooltipAnimationStatus.OPEN_ENDED].includes(cssAnimationStatus)) ||
717
- (this.cssClosingAnimation() &&
718
- this.state() === RdxTooltipState.CLOSED &&
719
- [RdxTooltipAnimationStatus.CLOSED_ENDED].includes(cssAnimationStatus))));
720
- }
721
- /** @ignore */
722
- openOrClose(state) {
723
- const isOpen = this.isOpen(state);
724
- isOpen ? this.openContent() : this.closeContent();
725
- }
726
- /** @ignore */
727
- emitOnOpenOrOnClosed(state) {
728
- this.isOpen(state)
729
- ? this.attachDetachEvent() === RdxTooltipAttachDetachEvent.ATTACH && this.emitOnOpen()
730
- : this.attachDetachEvent() === RdxTooltipAttachDetachEvent.DETACH && this.emitOnClosed();
731
- }
732
- /** @ignore */
733
- canEmitOnOpenOrOnClosed() {
734
- return (!this.cssAnimation() ||
735
- (!this.cssOpeningAnimation() && this.state() === RdxTooltipState.OPEN) ||
736
- (this.cssOpeningAnimation() &&
737
- this.state() === RdxTooltipState.OPEN &&
738
- this.cssAnimationStatus() === RdxTooltipAnimationStatus.OPEN_ENDED) ||
739
- (!this.cssClosingAnimation() && this.state() === RdxTooltipState.CLOSED) ||
740
- (this.cssClosingAnimation() &&
741
- this.state() === RdxTooltipState.CLOSED &&
742
- this.cssAnimationStatus() === RdxTooltipAnimationStatus.CLOSED_ENDED));
743
- }
744
- /** @ignore */
745
- onStateChangeEffect() {
746
- let isFirst = true;
747
- effect(() => {
748
- const state = this.state();
749
- untracked(() => {
750
- if (isFirst) {
751
- isFirst = false;
752
- return;
753
- }
754
- if (!this.ifOpenOrCloseWithoutAnimations(state)) {
755
- return;
756
- }
757
- this.openOrClose(state);
758
- });
759
- }, {});
760
- }
761
- /** @ignore */
762
- onCssAnimationStatusChangeChangeEffect() {
763
- let isFirst = true;
764
- effect(() => {
765
- const cssAnimationStatus = this.cssAnimationStatus();
766
- untracked(() => {
767
- if (isFirst) {
768
- isFirst = false;
769
- return;
770
- }
771
- if (!this.ifOpenOrCloseWithAnimations(cssAnimationStatus)) {
772
- return;
773
- }
774
- this.openOrClose(this.state());
775
- });
776
- });
777
- }
778
- /** @ignore */
779
- emitOpenOrClosedEventEffect() {
780
- let isFirst = true;
781
- effect(() => {
782
- this.attachDetachEvent();
783
- this.cssAnimationStatus();
784
- untracked(() => {
785
- if (isFirst) {
786
- isFirst = false;
787
- return;
788
- }
789
- const canEmitOpenClose = untracked(() => this.canEmitOnOpenOrOnClosed());
790
- if (!canEmitOpenClose) {
791
- return;
520
+ this.sticky = input('partial', ...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
521
+ /**
522
+ * Whether to hide the content when the trigger becomes fully occluded.
523
+ */
524
+ this.hideWhenDetached = input(false, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
525
+ /**
526
+ * The CSS position strategy used by Floating UI.
527
+ */
528
+ this.positionStrategy = input('fixed', ...(ngDevMode ? [{ debugName: "positionStrategy" }] : /* istanbul ignore next */ []));
529
+ /**
530
+ * Whether to update the position of the floating element on every animation frame if required.
531
+ */
532
+ this.updatePositionStrategy = input('always', ...(ngDevMode ? [{ debugName: "updatePositionStrategy" }] : /* istanbul ignore next */ []));
533
+ /**
534
+ * Emits when the element is placed.
535
+ */
536
+ this.placed = outputFromObservable(outputToObservable(this.wrapper.placed));
537
+ /**
538
+ * Event handler called when the escape key is down. Can be prevented.
539
+ */
540
+ this.escapeKeyDown = outputFromObservable(outputToObservable(this.dismissableLayer.escapeKeyDown));
541
+ /**
542
+ * Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented.
543
+ */
544
+ this.pointerDownOutside = outputFromObservable(outputToObservable(this.dismissableLayer.pointerDownOutside));
545
+ this.triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
546
+ this.containerEl = signal(null, ...(ngDevMode ? [{ debugName: "containerEl" }] : /* istanbul ignore next */ []));
547
+ this.graceArea = useGraceArea(this.triggerEl, this.containerEl, 300);
548
+ this.afterNextRender = afterNextRender(() => {
549
+ this.triggerEl.set(this.rootContext.trigger() ?? null);
550
+ this.containerEl.set(this.elementRef.nativeElement);
551
+ const handleScroll = (event) => {
552
+ const target = event.target;
553
+ const trigger = this.rootContext.trigger();
554
+ if (trigger && target?.contains(trigger)) {
555
+ this.rootContext.close();
792
556
  }
793
- this.emitOnOpenOrOnClosed(this.state());
794
- });
795
- });
796
- }
797
- /** @ignore */
798
- onOpenChangeEffect() {
799
- effect(() => {
800
- const open = this.open();
801
- untracked(() => {
802
- this.setState(open ? RdxTooltipState.OPEN : RdxTooltipState.CLOSED);
557
+ };
558
+ window.addEventListener('scroll', handleScroll, { capture: true });
559
+ this.destroyRef.onDestroy(() => {
560
+ window.removeEventListener('scroll', handleScroll, { capture: true });
803
561
  });
804
- });
805
- }
806
- /** @ignore */
807
- onIsFirstDefaultOpenChangeEffect() {
808
- const effectRef = effect(() => {
809
- const defaultOpen = this.defaultOpen();
810
- untracked(() => {
811
- if (!defaultOpen || this.open()) {
812
- effectRef.destroy();
562
+ this.graceArea.onPointerExit(() => {
563
+ if (this.rootContext.disableHoverablePopup())
813
564
  return;
814
- }
815
- this.handleOpen();
565
+ this.rootContext.closeDelayed();
816
566
  });
817
- }, ...(ngDevMode ? [{ debugName: "effectRef" }] : []));
818
- }
819
- /** @ignore */
820
- actionSubscription() {
821
- this.actionSubject$
822
- .asObservable()
823
- .pipe(map((action) => {
824
- switch (action) {
825
- case RdxTooltipAction.OPEN:
826
- return { action, duration: this.openDelay() };
827
- case RdxTooltipAction.CLOSE:
828
- return { action, duration: this.closeDelay() };
829
- }
830
- }), debounce((config) => timer(config.duration)), tap((config) => {
831
- switch (config.action) {
832
- case RdxTooltipAction.OPEN:
833
- this.setState(RdxTooltipState.OPEN);
834
- break;
835
- case RdxTooltipAction.CLOSE:
836
- this.setState(RdxTooltipState.CLOSED);
837
- break;
838
- }
839
- }), takeUntilDestroyed())
840
- .subscribe();
841
- }
842
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
843
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.3", type: RdxTooltipRootDirective, isStandalone: true, selector: "[rdxTooltipRoot]", 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 }, openDelay: { classPropertyName: "openDelay", publicName: "openDelay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", 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: "contentDirective", first: true, predicate: RdxTooltipContentDirective, descendants: true, isSignal: true }, { propertyName: "triggerDirective", first: true, predicate: RdxTooltipTriggerDirective, descendants: true, isSignal: true }, { propertyName: "arrowDirective", first: true, predicate: RdxTooltipArrowToken, descendants: true, isSignal: true }, { propertyName: "closeDirective", first: true, predicate: RdxTooltipCloseToken, descendants: true, isSignal: true }, { propertyName: "contentAttributesComponent", first: true, predicate: RdxTooltipContentAttributesToken, descendants: true, isSignal: true }, { propertyName: "internalAnchorDirective", first: true, predicate: RdxTooltipAnchorToken, descendants: true, isSignal: true }], exportAs: ["rdxTooltipRoot"], ngImport: i0 }); }
844
- }
845
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipRootDirective, decorators: [{
846
- type: Directive,
847
- args: [{
848
- selector: '[rdxTooltipRoot]',
849
- exportAs: 'rdxTooltipRoot'
850
- }]
851
- }], ctorParameters: () => [] });
852
-
853
- function injectTooltipRoot(optional = false) {
854
- isDevMode() && assertInInjectionContext(injectTooltipRoot);
855
- return inject(RdxTooltipRootDirective, { optional });
856
- }
857
-
858
- class RdxTooltipAnchorDirective {
859
- constructor() {
860
- /**
861
- * @ignore
862
- * If outside the rootDirective then null, otherwise the rootDirective directive - with optional `true` passed in as the first param.
863
- * If outside the rootDirective and non-null value that means the html structure is wrong - tooltip inside tooltip.
864
- * */
865
- this.rootDirective = injectTooltipRoot(true);
866
- /** @ignore */
867
- this.elementRef = inject(ElementRef);
868
- /** @ignore */
869
- this.overlayOrigin = inject(CdkOverlayOrigin);
870
- /** @ignore */
871
- this.document = injectDocument();
872
- /** @ignore */
873
- this.name = computed(() => `rdx-tooltip-external-anchor-${this.rootDirective?.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : []));
874
- }
875
- /** @ignore */
876
- click() {
877
- this.emitOutsideClick();
878
- }
879
- /** @ignore */
880
- setRoot(root) {
881
- this.rootDirective = root;
882
- }
883
- emitOutsideClick() {
884
- if (!this.rootDirective?.isOpen() || this.rootDirective?.contentDirective().onOverlayOutsideClickDisabled()) {
885
- return;
886
- }
887
- const clickEvent = new MouseEvent('click', {
888
- view: this.document.defaultView,
889
- bubbles: true,
890
- cancelable: true,
891
- relatedTarget: this.elementRef.nativeElement
892
567
  });
893
- this.rootDirective?.triggerDirective().elementRef.nativeElement.dispatchEvent(clickEvent);
568
+ this.dismissableLayer.focusOutside.subscribe((e) => e.preventDefault());
569
+ this.dismissableLayer.dismiss.subscribe(() => this.rootContext.close());
894
570
  }
895
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
896
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.3", type: RdxTooltipAnchorDirective, isStandalone: true, selector: "[rdxTooltipAnchor]", host: { attributes: { "type": "button" }, listeners: { "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"" } }, providers: [
897
- {
898
- provide: RdxTooltipAnchorToken,
899
- useExisting: forwardRef(() => RdxTooltipAnchorDirective)
900
- }
901
- ], exportAs: ["rdxTooltipAnchor"], hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
571
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
572
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTooltipPositioner, isStandalone: true, selector: "[rdxTooltipPositioner]", 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", escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside" }, host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-side": "wrapper.placedSide()", "attr.data-align": "wrapper.placedAlign()", "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 '--transform-origin': 'var(--radix-popper-transform-origin)'\n }" } }, providers: [provideRdxPopperContentConfig({ side: 'top', arrowPadding: 5, collisionPadding: 5 })], hostDirectives: [{ directive: i1$3.RdxDismissableLayer }, { 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 }); }
902
573
  }
903
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipAnchorDirective, decorators: [{
574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipPositioner, decorators: [{
904
575
  type: Directive,
905
576
  args: [{
906
- selector: '[rdxTooltipAnchor]',
907
- exportAs: 'rdxTooltipAnchor',
908
- hostDirectives: [CdkOverlayOrigin],
909
- host: {
910
- type: 'button',
911
- '[attr.id]': 'name()',
912
- '[attr.aria-haspopup]': '"dialog"',
913
- '(click)': 'click()'
914
- },
915
- providers: [
577
+ selector: '[rdxTooltipPositioner]',
578
+ providers: [provideRdxPopperContentConfig({ side: 'top', arrowPadding: 5, collisionPadding: 5 })],
579
+ hostDirectives: [
580
+ RdxDismissableLayer,
916
581
  {
917
- provide: RdxTooltipAnchorToken,
918
- useExisting: forwardRef(() => RdxTooltipAnchorDirective)
582
+ directive: RdxPopperContentWrapper,
583
+ inputs: [
584
+ 'anchor',
585
+ 'side',
586
+ 'sideOffset',
587
+ 'align',
588
+ 'alignOffset',
589
+ 'arrowPadding',
590
+ 'avoidCollisions',
591
+ 'collisionBoundary',
592
+ 'collisionPadding',
593
+ 'sticky',
594
+ 'hideWhenDetached',
595
+ 'positionStrategy',
596
+ 'updatePositionStrategy'
597
+ ]
919
598
  }
920
- ]
599
+ ],
600
+ host: {
601
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
602
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
603
+ '[attr.data-side]': 'wrapper.placedSide()',
604
+ '[attr.data-align]': 'wrapper.placedAlign()',
605
+ '[style]': `{
606
+ '--anchor-width': 'var(--radix-popper-anchor-width)',
607
+ '--anchor-height': 'var(--radix-popper-anchor-height)',
608
+ '--available-width': 'var(--radix-popper-available-width)',
609
+ '--available-height': 'var(--radix-popper-available-height)',
610
+ '--transform-origin': 'var(--radix-popper-transform-origin)'
611
+ }`
612
+ }
921
613
  }]
922
- }] });
614
+ }], 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"] }], escapeKeyDown: [{ type: i0.Output, args: ["escapeKeyDown"] }], pointerDownOutside: [{ type: i0.Output, args: ["pointerDownOutside"] }] } });
923
615
 
924
- class RdxTooltipArrowDirective {
616
+ class RdxTooltipTrigger {
925
617
  constructor() {
926
- /** @ignore */
927
- this.renderer = inject(Renderer2);
928
- /** @ignore */
929
- this.rootDirective = injectTooltipRoot();
930
- /** @ignore */
618
+ this.parentRootContext = injectRdxTooltipContext(true);
931
619
  this.elementRef = inject(ElementRef);
620
+ this.generatedId = injectId('rdx-tooltip-trigger-');
932
621
  /**
933
- * @description The width of the arrow in pixels.
934
- * @default 10
622
+ * Associates this trigger with a detached tooltip root.
935
623
  */
936
- this.width = input(RDX_POSITIONING_DEFAULTS.arrow.width, ...(ngDevMode ? [{ debugName: "width", transform: numberAttribute }] : [{ transform: numberAttribute }]));
624
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
937
625
  /**
938
- * @description The height of the arrow in pixels.
939
- * @default 5
626
+ * Data associated with this trigger while it is active.
940
627
  */
941
- this.height = input(RDX_POSITIONING_DEFAULTS.arrow.height, ...(ngDevMode ? [{ debugName: "height", transform: numberAttribute }] : [{ transform: numberAttribute }]));
942
- /** @ignore */
943
- this.arrowSvgElement = computed(() => {
944
- const width = this.width();
945
- const height = this.height();
946
- const svgElement = this.renderer.createElement('svg', 'svg');
947
- this.renderer.setAttribute(svgElement, 'viewBox', '0 0 30 10');
948
- this.renderer.setAttribute(svgElement, 'width', String(width));
949
- this.renderer.setAttribute(svgElement, 'height', String(height));
950
- const polygonElement = this.renderer.createElement('polygon', 'svg');
951
- this.renderer.setAttribute(polygonElement, 'points', '0,0 30,0 15,10');
952
- this.renderer.setAttribute(svgElement, 'preserveAspectRatio', 'none');
953
- this.renderer.appendChild(svgElement, polygonElement);
954
- return svgElement;
955
- }, ...(ngDevMode ? [{ debugName: "arrowSvgElement" }] : []));
956
- /** @ignore */
957
- this.currentArrowSvgElement = signal(void 0, ...(ngDevMode ? [{ debugName: "currentArrowSvgElement" }] : []));
958
- /** @ignore */
959
- this.position = toSignal(this.rootDirective.contentDirective().positionChange());
960
- afterNextRender({
961
- write: () => {
962
- if (this.elementRef.nativeElement.parentElement) {
963
- this.renderer.setStyle(this.elementRef.nativeElement.parentElement, 'position', 'relative');
964
- }
965
- this.renderer.setStyle(this.elementRef.nativeElement, 'position', 'absolute');
966
- this.renderer.setStyle(this.elementRef.nativeElement, 'boxSizing', '');
967
- this.renderer.setStyle(this.elementRef.nativeElement, 'fontSize', '0px');
628
+ this.payload = input(...(ngDevMode ? [undefined, { debugName: "payload" }] : /* istanbul ignore next */ []));
629
+ /**
630
+ * ID used to identify this trigger when opening a detached tooltip imperatively.
631
+ */
632
+ this.id = input(...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ []));
633
+ /**
634
+ * Whether the tooltip should close when the trigger is clicked.
635
+ * @defaultValue true
636
+ */
637
+ this.closeOnClick = input(true, { ...(ngDevMode ? { debugName: "closeOnClick" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
638
+ /**
639
+ * Whether this trigger is disabled. A disabled trigger never opens the tooltip.
640
+ * @defaultValue false
641
+ */
642
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
643
+ /**
644
+ * Overrides the open delay (ms) for this trigger. Falls back to the root/provider/global delay.
645
+ */
646
+ this.delay = input(undefined, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), transform: (value) => (value == null ? undefined : numberAttribute(value)) });
647
+ /**
648
+ * Overrides the close delay (ms) for this trigger. Falls back to the root/provider/global delay.
649
+ */
650
+ this.closeDelay = input(undefined, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: (value) => (value == null ? undefined : numberAttribute(value)) });
651
+ this.userOnPointerDown = input(undefined, { ...(ngDevMode ? { debugName: "userOnPointerDown" } : /* istanbul ignore next */ {}), alias: 'rdxOnPointerDown' });
652
+ this.triggerId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
653
+ this.rootContext = computed(() => this.handle()?.context() ?? this.parentRootContext, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
654
+ /** Disabled if either the root or this trigger is disabled. */
655
+ this.isDisabled = computed(() => (this.rootContext()?.disabled() ?? false) || this.disabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
656
+ /** Whether this specific trigger is the active anchor of an open tooltip. */
657
+ this.isOpen = computed(() => this.rootContext()?.isOpen() === true && this.rootContext()?.trigger() === this.elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
658
+ this.isPointerDown = signal(false, ...(ngDevMode ? [{ debugName: "isPointerDown" }] : /* istanbul ignore next */ []));
659
+ this.hasPointerMoveOpened = signal(false, ...(ngDevMode ? [{ debugName: "hasPointerMoveOpened" }] : /* istanbul ignore next */ []));
660
+ effect((onCleanup) => {
661
+ const handle = this.handle();
662
+ if (handle) {
663
+ onCleanup(untracked(() => handle.registerTrigger(this.triggerId(), this.elementRef.nativeElement, () => this.payload())));
664
+ }
665
+ else if (this.parentRootContext) {
666
+ onCleanup(untracked(() => this.parentRootContext.registerTrigger(this.elementRef.nativeElement)));
968
667
  }
969
668
  });
970
- this.onArrowSvgElementChangeEffect();
971
- this.onContentPositionAndArrowDimensionsChangeEffect();
972
669
  }
973
- /** @ignore */
974
- setAnchorOrTriggerRect() {
975
- this.anchorOrTriggerRect = (this.rootDirective.anchorDirective() ?? this.rootDirective.triggerDirective()).elementRef.nativeElement.getBoundingClientRect();
670
+ handleFocus() {
671
+ const rootContext = this.rootContext();
672
+ if (!rootContext || this.isDisabled() || this.isPointerDown()) {
673
+ return;
674
+ }
675
+ rootContext.setDelays(this.delay(), this.closeDelay());
676
+ rootContext.open(this.elementRef.nativeElement, this.payload());
976
677
  }
977
- /** @ignore */
978
- setPosition(position, arrowDimensions) {
979
- this.setAnchorOrTriggerRect();
980
- const posParams = getArrowPositionParams(getSideAndAlignFromAllPossibleConnectedPositions(position.connectionPair), { width: arrowDimensions.width, height: arrowDimensions.height }, { width: this.anchorOrTriggerRect.width, height: this.anchorOrTriggerRect.height });
981
- this.renderer.setStyle(this.elementRef.nativeElement, 'top', posParams.top);
982
- this.renderer.setStyle(this.elementRef.nativeElement, 'bottom', '');
983
- this.renderer.setStyle(this.elementRef.nativeElement, 'left', posParams.left);
984
- this.renderer.setStyle(this.elementRef.nativeElement, 'right', '');
985
- this.renderer.setStyle(this.elementRef.nativeElement, 'transform', posParams.transform);
986
- this.renderer.setStyle(this.elementRef.nativeElement, 'transformOrigin', posParams.transformOrigin);
678
+ handleBlur() {
679
+ this.rootContext()?.closeDelayed();
987
680
  }
988
- /** @ignore */
989
- onArrowSvgElementChangeEffect() {
990
- effect(() => {
991
- const arrowElement = this.arrowSvgElement();
992
- untracked(() => {
993
- const currentArrowSvgElement = this.currentArrowSvgElement();
994
- if (currentArrowSvgElement) {
995
- this.renderer.removeChild(this.elementRef.nativeElement, currentArrowSvgElement);
996
- }
997
- this.currentArrowSvgElement.set(arrowElement);
998
- this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.width()}px`);
999
- this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.height()}px`);
1000
- this.renderer.appendChild(this.elementRef.nativeElement, this.currentArrowSvgElement());
1001
- });
1002
- });
1003
- }
1004
- /** @ignore */
1005
- onContentPositionAndArrowDimensionsChangeEffect() {
1006
- effect(() => {
1007
- const position = this.position();
1008
- const arrowDimensions = { width: this.width(), height: this.height() };
1009
- untracked(() => {
1010
- if (!position) {
1011
- return;
1012
- }
1013
- this.setPosition(position, arrowDimensions);
1014
- });
1015
- });
681
+ handleClick() {
682
+ const rootContext = this.rootContext();
683
+ if (rootContext?.isOpen() && this.closeOnClick()) {
684
+ rootContext.close();
685
+ }
1016
686
  }
1017
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipArrowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1018
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.3", type: RdxTooltipArrowDirective, isStandalone: true, selector: "[rdxTooltipArrow]", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
1019
- {
1020
- provide: RdxTooltipArrowToken,
1021
- useExisting: forwardRef(() => RdxTooltipArrowDirective)
1022
- }
1023
- ], ngImport: i0 }); }
1024
- }
1025
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipArrowDirective, decorators: [{
1026
- type: Directive,
1027
- args: [{
1028
- selector: '[rdxTooltipArrow]',
1029
- providers: [
1030
- {
1031
- provide: RdxTooltipArrowToken,
1032
- useExisting: forwardRef(() => RdxTooltipArrowDirective)
1033
- }
1034
- ]
1035
- }]
1036
- }], ctorParameters: () => [] });
1037
-
1038
- /**
1039
- * TODO: to be removed? But it seems to be useful when controlled from outside
1040
- */
1041
- class RdxTooltipCloseDirective {
1042
- constructor() {
1043
- /** @ignore */
1044
- this.rootDirective = injectTooltipRoot();
1045
- /** @ignore */
1046
- this.elementRef = inject(ElementRef);
1047
- /** @ignore */
1048
- this.renderer = inject(Renderer2);
1049
- this.onIsControlledExternallyEffect();
687
+ handlePointerMove(event) {
688
+ if (event.pointerType === 'touch') {
689
+ return;
690
+ }
691
+ const rootContext = this.rootContext();
692
+ if (!rootContext || this.isDisabled()) {
693
+ return;
694
+ }
695
+ if (rootContext.trackCursorAxis() !== 'none') {
696
+ rootContext.setCursorPosition({ x: event.clientX, y: event.clientY });
697
+ }
698
+ if (!this.hasPointerMoveOpened()) {
699
+ rootContext.setDelays(this.delay(), this.closeDelay());
700
+ rootContext.onTriggerEnter(this.elementRef.nativeElement, this.payload());
701
+ this.hasPointerMoveOpened.set(true);
702
+ }
1050
703
  }
1051
- /** @ignore */
1052
- onIsControlledExternallyEffect() {
1053
- effect(() => {
1054
- const isControlledExternally = this.rootDirective.controlledExternally()();
1055
- untracked(() => {
1056
- this.renderer.setStyle(this.elementRef.nativeElement, 'display', isControlledExternally ? null : 'none');
1057
- });
1058
- });
704
+ handlePointerLeave() {
705
+ this.rootContext()?.onTriggerLeave();
706
+ this.hasPointerMoveOpened.set(false);
707
+ }
708
+ async handlePointerDown(event) {
709
+ const user = this.userOnPointerDown();
710
+ let result;
711
+ if (user) {
712
+ result = user(event);
713
+ if (result instanceof Promise)
714
+ result = await result;
715
+ }
716
+ if (event.defaultPrevented || result === false) {
717
+ return;
718
+ }
719
+ this.isPointerDown.set(true);
720
+ const handlePointerUp = () => {
721
+ setTimeout(() => this.isPointerDown.set(false), 1);
722
+ };
723
+ document.addEventListener('pointerup', handlePointerUp, { once: true });
1059
724
  }
1060
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1061
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.3", type: RdxTooltipCloseDirective, isStandalone: true, selector: "[rdxTooltipClose]", host: { attributes: { "type": "button" }, listeners: { "click": "rootDirective.handleClose(true)" } }, providers: [
1062
- {
1063
- provide: RdxTooltipCloseToken,
1064
- useExisting: forwardRef(() => RdxTooltipCloseDirective)
1065
- }
1066
- ], ngImport: i0 }); }
725
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
726
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTooltipTrigger, isStandalone: true, selector: "[rdxTooltipTrigger]", 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 }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", 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 }, userOnPointerDown: { classPropertyName: "userOnPointerDown", publicName: "rdxOnPointerDown", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button", "data-grace-area-trigger": "''" }, listeners: { "pointermove": "handlePointerMove($event)", "pointerleave": "handlePointerLeave()", "pointerdown": "handlePointerDown($event)", "focus": "handleFocus()", "blur": "handleBlur()", "click": "handleClick()" }, properties: { "id": "triggerId()", "attr.aria-describedby": "isOpen() ? rootContext()?.contentId : undefined", "attr.data-popup-open": "isOpen() ? \"\" : undefined", "attr.data-trigger-disabled": "isDisabled() ? \"\" : undefined" } }, hostDirectives: [{ directive: i1.RdxPopperAnchor }], ngImport: i0 }); }
1067
727
  }
1068
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipCloseDirective, decorators: [{
728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTooltipTrigger, decorators: [{
1069
729
  type: Directive,
1070
730
  args: [{
1071
- selector: '[rdxTooltipClose]',
731
+ selector: '[rdxTooltipTrigger]',
732
+ hostDirectives: [RdxPopperAnchor],
1072
733
  host: {
1073
734
  type: 'button',
1074
- '(click)': 'rootDirective.handleClose(true)'
1075
- },
1076
- providers: [
1077
- {
1078
- provide: RdxTooltipCloseToken,
1079
- useExisting: forwardRef(() => RdxTooltipCloseDirective)
1080
- }
1081
- ]
735
+ 'data-grace-area-trigger': "''",
736
+ '[id]': 'triggerId()',
737
+ '[attr.aria-describedby]': 'isOpen() ? rootContext()?.contentId : undefined',
738
+ '[attr.data-popup-open]': 'isOpen() ? "" : undefined',
739
+ '[attr.data-trigger-disabled]': 'isDisabled() ? "" : undefined',
740
+ '(pointermove)': 'handlePointerMove($event)',
741
+ '(pointerleave)': 'handlePointerLeave()',
742
+ '(pointerdown)': 'handlePointerDown($event)',
743
+ '(focus)': 'handleFocus()',
744
+ '(blur)': 'handleBlur()',
745
+ '(click)': 'handleClick()'
746
+ }
1082
747
  }]
1083
- }], ctorParameters: () => [] });
748
+ }], 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 }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], userOnPointerDown: [{ type: i0.Input, args: [{ isSignal: true, alias: "rdxOnPointerDown", required: false }] }] } });
1084
749
 
1085
- class RdxTooltipContentAttributesComponent {
750
+ class RdxTooltipHandle {
1086
751
  constructor() {
1087
- /** @ignore */
1088
- this.rootDirective = injectTooltipRoot();
1089
- /** @ignore */
1090
- this.name = computed(() => `rdx-tooltip-content-attributes-${this.rootDirective.uniqueId()}`, ...(ngDevMode ? [{ debugName: "name" }] : []));
1091
- /** @ignore */
1092
- this.disableAnimation = computed(() => !this.canAnimate(), ...(ngDevMode ? [{ debugName: "disableAnimation" }] : []));
1093
- }
1094
- /** @ignore */
1095
- onAnimationStart(_) {
1096
- this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxTooltipState.OPEN
1097
- ? RdxTooltipAnimationStatus.OPEN_STARTED
1098
- : RdxTooltipAnimationStatus.CLOSED_STARTED);
1099
- }
1100
- /** @ignore */
1101
- onAnimationEnd(_) {
1102
- this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxTooltipState.OPEN
1103
- ? RdxTooltipAnimationStatus.OPEN_ENDED
1104
- : RdxTooltipAnimationStatus.CLOSED_ENDED);
1105
- }
1106
- /** @ignore */
1107
- pointerenter() {
1108
- this.rootDirective.handleOpen();
752
+ this.rootContext = signal(undefined, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
753
+ this.triggers = new Map();
754
+ this.rootTriggerCleanups = new Map();
755
+ this.isOpen = computed(() => this.rootContext()?.isOpen() ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
756
+ }
757
+ open(triggerId) {
758
+ const trigger = this.triggers.get(triggerId);
759
+ if (!trigger) {
760
+ throw new Error(`No tooltip trigger registered with id "${triggerId}".`);
761
+ }
762
+ this.rootContext()?.open(trigger.element, trigger.payload());
1109
763
  }
1110
- /** @ignore */
1111
- pointerleave() {
1112
- this.rootDirective.handleClose();
764
+ close() {
765
+ this.rootContext()?.close();
1113
766
  }
1114
- /** @ignore */
1115
- focus() {
1116
- this.rootDirective.handleOpen();
767
+ registerRoot(rootContext) {
768
+ this.rootContext.set(rootContext);
769
+ this.triggers.forEach((trigger, id) => {
770
+ this.rootTriggerCleanups.set(id, rootContext.registerTrigger(trigger.element));
771
+ });
772
+ return () => {
773
+ if (this.rootContext() === rootContext) {
774
+ this.rootTriggerCleanups.forEach((cleanup) => cleanup());
775
+ this.rootTriggerCleanups.clear();
776
+ this.rootContext.set(undefined);
777
+ }
778
+ };
1117
779
  }
1118
- /** @ignore */
1119
- blur() {
1120
- this.rootDirective.handleClose();
780
+ registerTrigger(id, trigger, payload) {
781
+ this.rootTriggerCleanups.get(id)?.();
782
+ this.triggers.set(id, { element: trigger, payload });
783
+ const unregisterFromRoot = this.rootContext()?.registerTrigger(trigger);
784
+ if (unregisterFromRoot) {
785
+ this.rootTriggerCleanups.set(id, unregisterFromRoot);
786
+ }
787
+ return () => {
788
+ this.rootTriggerCleanups.get(id)?.();
789
+ this.rootTriggerCleanups.delete(id);
790
+ if (this.triggers.get(id)?.element === trigger) {
791
+ this.triggers.delete(id);
792
+ }
793
+ };
1121
794
  }
1122
- /** @ignore */
1123
- canAnimate() {
1124
- return (this.rootDirective.cssAnimation() &&
1125
- ((this.rootDirective.cssOpeningAnimation() && this.rootDirective.state() === RdxTooltipState.OPEN) ||
1126
- (this.rootDirective.cssClosingAnimation() && this.rootDirective.state() === RdxTooltipState.CLOSED)));
795
+ context() {
796
+ return this.rootContext();
1127
797
  }
1128
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipContentAttributesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1129
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: RdxTooltipContentAttributesComponent, isStandalone: true, selector: "[rdxTooltipContentAttributes]", host: { listeners: { "animationstart": "onAnimationStart($event)", "animationend": "onAnimationEnd($event)", "pointerenter": "pointerenter()", "pointerleave": "pointerleave()", "focus": "focus()", "blur": "blur()" }, properties: { "attr.role": "\"dialog\"", "attr.id": "name()", "attr.data-state": "rootDirective.state()", "attr.data-side": "rootDirective.contentDirective().side()", "attr.data-align": "rootDirective.contentDirective().align()", "style": "disableAnimation() ? {animation: \"none !important\"} : null" } }, providers: [
1130
- {
1131
- provide: RdxTooltipContentAttributesToken,
1132
- useExisting: forwardRef(() => RdxTooltipContentAttributesComponent)
1133
- }
1134
- ], ngImport: i0, template: `
1135
- <ng-content />
1136
- `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1137
798
  }
1138
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipContentAttributesComponent, decorators: [{
1139
- type: Component,
1140
- args: [{
1141
- selector: '[rdxTooltipContentAttributes]',
1142
- template: `
1143
- <ng-content />
1144
- `,
1145
- host: {
1146
- '[attr.role]': '"dialog"',
1147
- '[attr.id]': 'name()',
1148
- '[attr.data-state]': 'rootDirective.state()',
1149
- '[attr.data-side]': 'rootDirective.contentDirective().side()',
1150
- '[attr.data-align]': 'rootDirective.contentDirective().align()',
1151
- '[style]': 'disableAnimation() ? {animation: "none !important"} : null',
1152
- '(animationstart)': 'onAnimationStart($event)',
1153
- '(animationend)': 'onAnimationEnd($event)',
1154
- '(pointerenter)': 'pointerenter()',
1155
- '(pointerleave)': 'pointerleave()',
1156
- '(focus)': 'focus()',
1157
- '(blur)': 'blur()'
1158
- },
1159
- providers: [
1160
- {
1161
- provide: RdxTooltipContentAttributesToken,
1162
- useExisting: forwardRef(() => RdxTooltipContentAttributesComponent)
1163
- }
1164
- ],
1165
- changeDetection: ChangeDetectionStrategy.OnPush
1166
- }]
1167
- }] });
799
+ function createRdxTooltipHandle() {
800
+ return new RdxTooltipHandle();
801
+ }
1168
802
 
1169
- const _imports = [
1170
- RdxTooltipArrowDirective,
1171
- RdxTooltipCloseDirective,
1172
- RdxTooltipContentDirective,
1173
- RdxTooltipTriggerDirective,
1174
- RdxTooltipRootDirective,
1175
- RdxTooltipAnchorDirective,
1176
- RdxTooltipContentAttributesComponent
803
+ const tooltipImports = [
804
+ RdxTooltip,
805
+ RdxTooltipArrow,
806
+ RdxTooltipPopup,
807
+ RdxTooltipPortal,
808
+ RdxTooltipPortalPresence,
809
+ RdxTooltipPositioner,
810
+ RdxTooltipProvider,
811
+ RdxTooltipTrigger
1177
812
  ];
1178
- class RdxTooltipModule {
1179
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1180
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipModule, imports: [RdxTooltipArrowDirective,
1181
- RdxTooltipCloseDirective,
1182
- RdxTooltipContentDirective,
1183
- RdxTooltipTriggerDirective,
1184
- RdxTooltipRootDirective,
1185
- RdxTooltipAnchorDirective,
1186
- RdxTooltipContentAttributesComponent], exports: [RdxTooltipArrowDirective,
1187
- RdxTooltipCloseDirective,
1188
- RdxTooltipContentDirective,
1189
- RdxTooltipTriggerDirective,
1190
- RdxTooltipRootDirective,
1191
- RdxTooltipAnchorDirective,
1192
- RdxTooltipContentAttributesComponent] }); }
1193
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipModule }); }
1194
- }
1195
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: RdxTooltipModule, decorators: [{
1196
- type: NgModule,
1197
- args: [{
1198
- imports: [..._imports],
1199
- exports: [..._imports]
1200
- }]
1201
- }] });
1202
813
 
1203
814
  /**
1204
815
  * Generated bundle index. Do not edit.
1205
816
  */
1206
817
 
1207
- export { RdxTooltipAnchorDirective, RdxTooltipArrowDirective, RdxTooltipCloseDirective, RdxTooltipContentAttributesComponent, RdxTooltipContentDirective, RdxTooltipModule, RdxTooltipRootDirective, RdxTooltipTriggerDirective };
818
+ export { RdxTooltip, RdxTooltipArrow, RdxTooltipDefaultsToken, RdxTooltipHandle, RdxTooltipPopup, RdxTooltipPortal, RdxTooltipPortalPresence, RdxTooltipPositioner, RdxTooltipProvider, RdxTooltipTrigger, createRdxTooltipHandle, defaultTooltipConfig, injectRdxTooltipConfig, injectRdxTooltipContext, injectRdxTooltipProviderContext, provideRdxTooltipConfig, provideRdxTooltipContext, provideRdxTooltipProviderContext, tooltipImports };
1208
819
  //# sourceMappingURL=radix-ng-primitives-tooltip.mjs.map