@radix-ng/primitives 0.25.0 → 0.27.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 (55) hide show
  1. package/compodoc/documentation.json +25078 -12716
  2. package/core/src/positioning/constants.d.ts +2 -1
  3. package/core/src/positioning/types.d.ts +16 -5
  4. package/fesm2022/radix-ng-primitives-core.mjs +22 -9
  5. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-hover-card.mjs +1213 -0
  7. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +1 -0
  8. package/fesm2022/radix-ng-primitives-popover.mjs +20 -29
  9. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-tooltip.mjs +984 -355
  11. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  12. package/hover-card/README.md +3 -0
  13. package/hover-card/index.d.ts +20 -0
  14. package/hover-card/src/hover-card-anchor.directive.d.ts +28 -0
  15. package/hover-card/src/hover-card-anchor.token.d.ts +3 -0
  16. package/hover-card/src/hover-card-arrow.directive.d.ts +40 -0
  17. package/hover-card/src/hover-card-arrow.token.d.ts +3 -0
  18. package/hover-card/src/hover-card-close.directive.d.ts +18 -0
  19. package/hover-card/src/hover-card-close.token.d.ts +3 -0
  20. package/hover-card/src/hover-card-content-attributes.component.d.ts +25 -0
  21. package/hover-card/src/hover-card-content-attributes.token.d.ts +3 -0
  22. package/hover-card/src/hover-card-content.directive.d.ts +104 -0
  23. package/hover-card/src/hover-card-root.directive.d.ts +168 -0
  24. package/hover-card/src/hover-card-root.inject.d.ts +3 -0
  25. package/hover-card/src/hover-card-trigger.directive.d.ts +26 -0
  26. package/hover-card/src/hover-card.types.d.ts +18 -0
  27. package/hover-card/src/utils/cdk-event.service.d.ts +30 -0
  28. package/hover-card/src/utils/constants.d.ts +1 -0
  29. package/hover-card/src/utils/types.d.ts +7 -0
  30. package/package.json +5 -1
  31. package/popover/src/popover-arrow.directive.d.ts +3 -2
  32. package/popover/src/popover-content.directive.d.ts +6 -5
  33. package/popover/src/popover-root.directive.d.ts +8 -8
  34. package/popover/src/popover-trigger.directive.d.ts +1 -1
  35. package/tooltip/README.md +2 -0
  36. package/tooltip/index.d.ts +9 -6
  37. package/tooltip/src/tooltip-anchor.directive.d.ts +28 -0
  38. package/tooltip/src/tooltip-anchor.token.d.ts +3 -0
  39. package/tooltip/src/tooltip-arrow.directive.d.ts +18 -16
  40. package/tooltip/src/tooltip-close.directive.d.ts +18 -0
  41. package/tooltip/src/tooltip-close.token.d.ts +3 -0
  42. package/tooltip/src/tooltip-content-attributes.component.d.ts +25 -0
  43. package/tooltip/src/tooltip-content-attributes.token.d.ts +3 -0
  44. package/tooltip/src/tooltip-content.directive.d.ts +85 -16
  45. package/tooltip/src/tooltip-root.directive.d.ts +121 -59
  46. package/tooltip/src/tooltip-root.inject.d.ts +3 -0
  47. package/tooltip/src/tooltip-trigger.directive.d.ts +11 -11
  48. package/tooltip/src/tooltip.types.d.ts +18 -7
  49. package/tooltip/src/utils/cdk-event.service.d.ts +30 -0
  50. package/tooltip/src/utils/constants.d.ts +1 -0
  51. package/tooltip/src/utils/types.d.ts +7 -0
  52. package/popover/src/popover.constants.d.ts +0 -6
  53. package/tooltip/src/tooltip-content-attributes.directive.d.ts +0 -8
  54. package/tooltip/src/tooltip-content.token.d.ts +0 -3
  55. package/tooltip/src/tooltip.config.d.ts +0 -6
@@ -1,400 +1,950 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, ElementRef, Directive, ViewContainerRef, DestroyRef, PLATFORM_ID, input, output, signal, computed, contentChild, effect, untracked, forwardRef, Renderer2, afterNextRender, TemplateRef, NgModule } from '@angular/core';
3
- import { injectDocument, injectWindow, getArrowPositionParams, getSideAndAlignFromAllPossibleConnectedPositions, RdxPositionSide, RdxPositionAlign, getContentPosition } from '@radix-ng/primitives/core';
4
- import { Overlay } from '@angular/cdk/overlay';
5
- import { TemplatePortal } from '@angular/cdk/portal';
6
- import { isPlatformBrowser } from '@angular/common';
7
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
- import { filter, take, asyncScheduler } from 'rxjs';
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, Component, ChangeDetectionStrategy, 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';
8
+
9
+ const RdxTooltipAnchorToken = new InjectionToken('RdxTooltipAnchorToken');
9
10
 
10
11
  const RdxTooltipArrowToken = new InjectionToken('RdxTooltipArrowToken');
11
12
 
12
- const RdxTooltipContentToken = new InjectionToken('RdxTooltipContentToken');
13
+ const RdxTooltipCloseToken = new InjectionToken('RdxTooltipCloseToken');
13
14
 
14
- class RdxTooltipTriggerDirective {
15
+ const RdxTooltipContentAttributesToken = new InjectionToken('RdxTooltipContentAttributesToken');
16
+
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 = {}));
39
+
40
+ class RdxTooltipContentDirective {
15
41
  constructor() {
16
42
  /** @ignore */
17
- this.tooltipRoot = injectTooltipRoot();
43
+ this.rootDirective = injectTooltipRoot();
18
44
  /** @ignore */
19
- this.elementRef = inject((ElementRef));
45
+ this.templateRef = inject(TemplateRef);
20
46
  /** @ignore */
21
- this.isPointerDown = false;
47
+ this.overlay = inject(Overlay);
22
48
  /** @ignore */
23
- this.isPointerInside = false;
49
+ this.destroyRef = inject(DestroyRef);
50
+ /** @ignore */
51
+ this.connectedOverlay = inject(CdkConnectedOverlay);
52
+ /** @ignore */
53
+ this.name = computed(() => `rdx-tooltip-trigger-${this.rootDirective.uniqueId()}`);
54
+ /**
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
57
+ */
58
+ this.side = input(RdxPositionSide.Top);
59
+ /**
60
+ * @description The distance in pixels from the trigger.
61
+ * @default undefined
62
+ */
63
+ this.sideOffset = input(NaN, {
64
+ transform: numberAttribute
65
+ });
66
+ /**
67
+ * @description The preferred alignment against the trigger. May change when collisions occur.
68
+ * @default center
69
+ */
70
+ this.align = input(RdxPositionAlign.Center);
71
+ /**
72
+ * @description An offset in pixels from the "start" or "end" alignment options.
73
+ * @default undefined
74
+ */
75
+ this.alignOffset = input(NaN, {
76
+ transform: numberAttribute
77
+ });
78
+ /**
79
+ * @description Whether to add some alternate positions of the content.
80
+ * @default false
81
+ */
82
+ this.alternatePositionsDisabled = input(false, { transform: booleanAttribute });
83
+ /** @description Whether to prevent `onOverlayEscapeKeyDown` handler from calling. */
84
+ this.onOverlayEscapeKeyDownDisabled = input(false, { transform: booleanAttribute });
85
+ /** @description Whether to prevent `onOverlayOutsideClick` handler from calling. */
86
+ this.onOverlayOutsideClickDisabled = input(false, { transform: booleanAttribute });
87
+ /**
88
+ * @description Event handler called when the escape key is down.
89
+ * It can be prevented by setting `onOverlayEscapeKeyDownDisabled` input to `true`.
90
+ */
91
+ this.onOverlayEscapeKeyDown = output();
92
+ /**
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`.
95
+ */
96
+ this.onOverlayOutsideClick = output();
97
+ /**
98
+ * @description Event handler called after the overlay is open
99
+ */
100
+ this.onOpen = output();
101
+ /**
102
+ * @description Event handler called after the overlay is closed
103
+ */
104
+ this.onClosed = output();
105
+ /** @ingore */
106
+ this.positions = computed(() => this.computePositions());
107
+ this.onOriginChangeEffect();
108
+ this.onPositionChangeEffect();
24
109
  }
25
110
  /** @ignore */
26
- onPointerMove(event) {
27
- if (event.pointerType === 'touch') {
111
+ ngOnInit() {
112
+ this.setScrollStrategy();
113
+ this.setHasBackdrop();
114
+ this.setDisableClose();
115
+ this.onAttach();
116
+ this.onDetach();
117
+ this.connectKeydownEscape();
118
+ this.connectOutsideClick();
119
+ }
120
+ /** @ignore */
121
+ open() {
122
+ if (this.connectedOverlay.open) {
28
123
  return;
29
124
  }
30
- if (!this.isPointerInside) {
31
- this.tooltipRoot.onTriggerEnter();
32
- this.isPointerInside = true;
125
+ const prevOpen = this.connectedOverlay.open;
126
+ this.connectedOverlay.open = true;
127
+ this.fireOverlayNgOnChanges('open', this.connectedOverlay.open, prevOpen);
128
+ }
129
+ /** @ignore */
130
+ close() {
131
+ if (!this.connectedOverlay.open) {
132
+ return;
33
133
  }
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);
205
+ }
206
+ /** @ignore */
207
+ setHasBackdrop() {
208
+ const prevHasBackdrop = this.connectedOverlay.hasBackdrop;
209
+ this.connectedOverlay.hasBackdrop = false;
210
+ this.fireOverlayNgOnChanges('hasBackdrop', this.connectedOverlay.hasBackdrop, prevHasBackdrop);
34
211
  }
35
212
  /** @ignore */
36
- onPointerLeave() {
37
- this.isPointerInside = false;
38
- this.tooltipRoot.onTriggerLeave();
213
+ setDisableClose() {
214
+ const prevDisableClose = this.connectedOverlay.disableClose;
215
+ this.connectedOverlay.disableClose = true;
216
+ this.fireOverlayNgOnChanges('disableClose', this.connectedOverlay.disableClose, prevDisableClose);
39
217
  }
40
218
  /** @ignore */
41
- onPointerDown() {
42
- this.isPointerDown = true;
43
- this.elementRef.nativeElement.addEventListener('pointerup', () => {
44
- this.isPointerDown = false;
45
- }, { once: true });
219
+ setOrigin(origin) {
220
+ const prevOrigin = this.connectedOverlay.origin;
221
+ this.connectedOverlay.origin = origin;
222
+ this.fireOverlayNgOnChanges('origin', this.connectedOverlay.origin, prevOrigin);
46
223
  }
47
224
  /** @ignore */
48
- onFocus() {
49
- if (!this.isPointerDown) {
50
- this.tooltipRoot.handleOpen();
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();
230
+ }
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
+ });
51
262
  }
263
+ return positions;
264
+ }
265
+ onOriginChangeEffect() {
266
+ effect(() => {
267
+ const origin = (this.rootDirective.anchorDirective() ?? this.rootDirective.triggerDirective())
268
+ .overlayOrigin;
269
+ untracked(() => {
270
+ this.setOrigin(origin);
271
+ });
272
+ });
273
+ }
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)
288
+ });
289
+ }
290
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
291
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", 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 }); }
292
+ }
293
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentDirective, decorators: [{
294
+ type: Directive,
295
+ args: [{
296
+ selector: '[rdxTooltipContent]',
297
+ hostDirectives: [
298
+ CdkConnectedOverlay
299
+ ]
300
+ }]
301
+ }], ctorParameters: () => [] });
302
+
303
+ class RdxTooltipTriggerDirective {
304
+ constructor() {
305
+ /** @ignore */
306
+ this.rootDirective = injectTooltipRoot();
307
+ /** @ignore */
308
+ this.elementRef = inject(ElementRef);
309
+ /** @ignore */
310
+ this.overlayOrigin = inject(CdkOverlayOrigin);
311
+ /** @ignore */
312
+ this.name = computed(() => `rdx-tooltip-trigger-${this.rootDirective.uniqueId()}`);
313
+ }
314
+ /** @ignore */
315
+ pointerenter() {
316
+ this.rootDirective.handleOpen();
317
+ }
318
+ /** @ignore */
319
+ pointerleave() {
320
+ this.rootDirective.handleClose();
321
+ }
322
+ /** @ignore */
323
+ focus() {
324
+ this.rootDirective.handleOpen();
52
325
  }
53
326
  /** @ignore */
54
- onBlur() {
55
- this.tooltipRoot.handleClose();
327
+ blur() {
328
+ this.rootDirective.handleClose();
56
329
  }
57
330
  /** @ignore */
58
- onClick() {
59
- this.tooltipRoot.handleClose();
331
+ click() {
332
+ this.rootDirective.handleClose();
60
333
  }
61
334
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
62
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxTooltipTriggerDirective, isStandalone: true, selector: "[rdxTooltipTrigger]", host: { listeners: { "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave()", "pointerdown": "onPointerDown()", "focus": "onFocus()", "blur": "onBlur()", "click": "onClick()" }, properties: { "attr.data-state": "tooltipRoot.state()" } }, ngImport: i0 }); }
335
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", 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 }); }
63
336
  }
64
337
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipTriggerDirective, decorators: [{
65
338
  type: Directive,
66
339
  args: [{
67
340
  selector: '[rdxTooltipTrigger]',
68
- standalone: true,
341
+ hostDirectives: [CdkOverlayOrigin],
69
342
  host: {
70
- '[attr.data-state]': 'tooltipRoot.state()',
71
- '(pointermove)': 'onPointerMove($event)',
72
- '(pointerleave)': 'onPointerLeave()',
73
- '(pointerdown)': 'onPointerDown()',
74
- '(focus)': 'onFocus()',
75
- '(blur)': 'onBlur()',
76
- '(click)': 'onClick()'
343
+ type: 'button',
344
+ '[attr.id]': 'name()',
345
+ '[attr.aria-haspopup]': '"dialog"',
346
+ '[attr.aria-expanded]': 'rootDirective.isOpen()',
347
+ '[attr.aria-controls]': 'rootDirective.contentDirective().name()',
348
+ '[attr.data-state]': 'rootDirective.state()',
349
+ '(pointerenter)': 'pointerenter()',
350
+ '(pointerleave)': 'pointerleave()',
351
+ '(focus)': 'focus()',
352
+ '(blur)': 'blur()',
353
+ '(click)': 'click()'
77
354
  }
78
355
  }]
79
356
  }] });
80
357
 
81
- const defaultTooltipConfig = {
82
- delayDuration: 700,
83
- skipDelayDuration: 300
84
- };
85
- const RdxTooltipConfigToken = new InjectionToken('RdxTooltipConfigToken');
86
- function provideRdxTooltipConfig(config) {
87
- return [
88
- {
89
- provide: RdxTooltipConfigToken,
90
- useValue: { ...defaultTooltipConfig, ...config }
91
- }
92
- ];
358
+ const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__');
359
+
360
+ function eventTypeAsPrimitiveConfigKey(eventType) {
361
+ return `prevent${eventType[0].toUpperCase()}${eventType.slice(1)}`;
93
362
  }
94
- function injectTooltipConfig() {
95
- return inject(RdxTooltipConfigToken, { optional: true }) ?? defaultTooltipConfig;
363
+ class RdxCdkEventService {
364
+ #clickDomRootEventCallbacks;
365
+ constructor() {
366
+ this.document = injectDocument();
367
+ this.destroyRef = inject(DestroyRef);
368
+ this.ngZone = inject(NgZone);
369
+ this.renderer2 = inject(Renderer2);
370
+ this.window = injectWindow();
371
+ this.onDestroyCallbacks = new Set([() => deleteRdxCdkEventServiceWindowKey(this.window)]);
372
+ this.#clickDomRootEventCallbacks = new Set();
373
+ this.#listenToClickDomRootEvent();
374
+ this.#registerOnDestroyCallbacks();
375
+ }
376
+ registerPrimitive(primitiveInstance) {
377
+ if (!this.primitiveConfigs) {
378
+ this.primitiveConfigs = new Map();
379
+ }
380
+ if (!this.primitiveConfigs.has(primitiveInstance)) {
381
+ this.primitiveConfigs.set(primitiveInstance, {});
382
+ }
383
+ }
384
+ deregisterPrimitive(primitiveInstance) {
385
+ if (this.primitiveConfigs?.has(primitiveInstance)) {
386
+ this.primitiveConfigs.delete(primitiveInstance);
387
+ }
388
+ }
389
+ preventPrimitiveFromCdkEvent(primitiveInstance, eventType) {
390
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
391
+ }
392
+ allowPrimitiveForCdkEvent(primitiveInstance, eventType) {
393
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
394
+ }
395
+ preventPrimitiveFromCdkMultiEvents(primitiveInstance, eventTypes) {
396
+ eventTypes.forEach((eventType) => {
397
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
398
+ });
399
+ }
400
+ allowPrimitiveForCdkMultiEvents(primitiveInstance, eventTypes) {
401
+ eventTypes.forEach((eventType) => {
402
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
403
+ });
404
+ }
405
+ setPreventPrimitiveFromCdkMixEvents(primitiveInstance, eventTypes) {
406
+ Object.keys(eventTypes).forEach((eventType) => {
407
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, eventTypes[eventTypeAsPrimitiveConfigKey(eventType)]);
408
+ });
409
+ }
410
+ primitivePreventedFromCdkEvent(primitiveInstance, eventType) {
411
+ return this.primitiveConfigs?.get(primitiveInstance)?.[eventTypeAsPrimitiveConfigKey(eventType)];
412
+ }
413
+ addClickDomRootEventCallback(callback) {
414
+ this.#clickDomRootEventCallbacks.add(callback);
415
+ }
416
+ removeClickDomRootEventCallback(callback) {
417
+ return this.#clickDomRootEventCallbacks.delete(callback);
418
+ }
419
+ #setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, value) {
420
+ if (!this.primitiveConfigs?.has(primitiveInstance)) {
421
+ isDevMode() &&
422
+ console.error('[RdxCdkEventService.preventPrimitiveFromCdkEvent] RDX Primitive instance has not been registered!', primitiveInstance);
423
+ return;
424
+ }
425
+ switch (eventType) {
426
+ case 'cdkOverlayOutsideClick':
427
+ this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayOutsideClick = value;
428
+ break;
429
+ case 'cdkOverlayEscapeKeyDown':
430
+ this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayEscapeKeyDown = value;
431
+ break;
432
+ }
433
+ }
434
+ #registerOnDestroyCallbacks() {
435
+ this.destroyRef.onDestroy(() => {
436
+ this.onDestroyCallbacks.forEach((onDestroyCallback) => onDestroyCallback());
437
+ this.onDestroyCallbacks.clear();
438
+ });
439
+ }
440
+ #listenToClickDomRootEvent() {
441
+ const target = this.document;
442
+ const eventName = 'click';
443
+ const options = { capture: true };
444
+ const callback = (event) => {
445
+ this.#clickDomRootEventCallbacks.forEach((clickDomRootEventCallback) => clickDomRootEventCallback(event));
446
+ };
447
+ const major = parseInt(VERSION.major);
448
+ const minor = parseInt(VERSION.minor);
449
+ let destroyClickDomRootEventListener;
450
+ /**
451
+ * @see src/cdk/platform/features/backwards-compatibility.ts in @angular/cdk
452
+ */
453
+ if (major > 19 || (major === 19 && minor > 0) || (major === 0 && minor === 0)) {
454
+ destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
455
+ const destroyClickDomRootEventListenerInternal = this.renderer2.listen(target, eventName, callback,
456
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
457
+ // @ts-expect-error
458
+ options);
459
+ return () => {
460
+ destroyClickDomRootEventListenerInternal();
461
+ this.#clickDomRootEventCallbacks.clear();
462
+ };
463
+ });
464
+ }
465
+ else {
466
+ /**
467
+ * This part can get removed when v19.1 or higher is on the board
468
+ */
469
+ destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
470
+ target.addEventListener(eventName, callback, options);
471
+ return () => {
472
+ this.ngZone.runOutsideAngular(() => target.removeEventListener(eventName, callback, options));
473
+ this.#clickDomRootEventCallbacks.clear();
474
+ };
475
+ });
476
+ }
477
+ this.onDestroyCallbacks.add(destroyClickDomRootEventListener);
478
+ }
479
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
480
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService }); }
96
481
  }
482
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService, decorators: [{
483
+ type: Injectable
484
+ }], ctorParameters: () => [] });
485
+ const RdxCdkEventServiceToken = new InjectionToken('RdxCdkEventServiceToken');
486
+ const existsErrorMessage = 'RdxCdkEventService should be provided only once!';
487
+ const deleteRdxCdkEventServiceWindowKey = (window) => {
488
+ delete window[RdxCdkEventServiceWindowKey];
489
+ };
490
+ const getProvider = (throwWhenExists = true) => ({
491
+ provide: RdxCdkEventServiceToken,
492
+ useFactory: () => {
493
+ isDevMode() && console.log('providing RdxCdkEventService...');
494
+ const window = injectWindow();
495
+ if (window[RdxCdkEventServiceWindowKey]) {
496
+ if (throwWhenExists) {
497
+ throw Error(existsErrorMessage);
498
+ }
499
+ else {
500
+ isDevMode() && console.warn(existsErrorMessage);
501
+ }
502
+ }
503
+ window[RdxCdkEventServiceWindowKey] ??= new RdxCdkEventService();
504
+ return window[RdxCdkEventServiceWindowKey];
505
+ }
506
+ });
507
+ const provideRdxCdkEventServiceInRoot = () => makeEnvironmentProviders([getProvider()]);
508
+ const provideRdxCdkEventService = () => getProvider(false);
509
+ const injectRdxCdkEventService = () => inject(RdxCdkEventServiceToken, { optional: true });
97
510
 
98
- const RdxTooltipRootToken = new InjectionToken('RdxTooltipRootToken');
99
- function injectTooltipRoot() {
100
- return inject(RdxTooltipRootToken);
101
- }
511
+ let nextId = 0;
102
512
  class RdxTooltipRootDirective {
103
513
  constructor() {
104
514
  /** @ignore */
105
- this.viewContainerRef = inject(ViewContainerRef);
106
- /** @ignore */
107
- this.destroyRef = inject(DestroyRef);
515
+ this.uniqueId = signal(++nextId);
108
516
  /** @ignore */
109
- this.overlay = inject(Overlay);
110
- /** @ignore */
111
- this.platformId = inject(PLATFORM_ID);
112
- /** @ignore */
113
- this.document = injectDocument();
114
- /** @ignore */
115
- this.window = injectWindow();
116
- /** @ignore */
117
- this.tooltipConfig = injectTooltipConfig();
517
+ this.name = computed(() => `rdx-tooltip-root-${this.uniqueId()}`);
118
518
  /**
119
- * The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
519
+ * @description The anchor directive that comes form outside the tooltip rootDirective
520
+ * @default undefined
120
521
  */
121
- this.defaultOpen = input(false);
522
+ this.anchor = input(void 0);
122
523
  /**
123
- * The controlled open state of the tooltip. Must be used in conjunction with onOpenChange.
524
+ * @description The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
525
+ * @default false
124
526
  */
125
- this.open = input();
527
+ this.defaultOpen = input(false, { transform: booleanAttribute });
126
528
  /**
127
- * Override the duration given to the configuration to customise the open delay for a specific tooltip.
529
+ * @description The controlled state of the tooltip. `open` input take precedence of `defaultOpen` input.
530
+ * @default undefined
128
531
  */
129
- this.delayDuration = input(this.tooltipConfig.delayDuration);
130
- /** @ignore */
131
- this.disableHoverableContent = input(this.tooltipConfig.disableHoverableContent ?? false);
532
+ this.open = input(void 0, { transform: booleanAttribute });
132
533
  /**
133
- * Event handler called when the open state of the tooltip changes.
534
+ * To customise the open delay for a specific tooltip.
134
535
  */
135
- this.onOpenChange = output();
536
+ this.openDelay = input(500, {
537
+ transform: numberAttribute
538
+ });
539
+ /**
540
+ * To customise the close delay for a specific tooltip.
541
+ */
542
+ this.closeDelay = input(200, {
543
+ transform: numberAttribute
544
+ });
545
+ /**
546
+ * @description Whether to control the state of the tooltip from external. Use in conjunction with `open` input.
547
+ * @default undefined
548
+ */
549
+ this.externalControl = input(void 0, { transform: booleanAttribute });
550
+ /**
551
+ * @description Whether to take into account CSS opening/closing animations.
552
+ * @default false
553
+ */
554
+ this.cssAnimation = input(false, { transform: booleanAttribute });
555
+ /**
556
+ * @description Whether to take into account CSS opening animations. `cssAnimation` input must be set to 'true'
557
+ * @default false
558
+ */
559
+ this.cssOpeningAnimation = input(false, { transform: booleanAttribute });
560
+ /**
561
+ * @description Whether to take into account CSS closing animations. `cssAnimation` input must be set to 'true'
562
+ * @default false
563
+ */
564
+ this.cssClosingAnimation = input(false, { transform: booleanAttribute });
136
565
  /** @ignore */
137
- this.isOpen = signal(this.defaultOpen());
566
+ this.cssAnimationStatus = signal(null);
138
567
  /** @ignore */
139
- this.isOpenDelayed = signal(true);
568
+ this.contentDirective = contentChild.required(RdxTooltipContentDirective);
140
569
  /** @ignore */
141
- this.wasOpenDelayed = signal(false);
570
+ this.triggerDirective = contentChild.required(RdxTooltipTriggerDirective);
142
571
  /** @ignore */
143
- this.state = computed(() => {
144
- const currentIsOpen = this.isOpen();
145
- const currentWasOpenDelayed = this.wasOpenDelayed();
146
- if (currentIsOpen) {
147
- return currentWasOpenDelayed ? 'delayed-open' : 'instant-open';
148
- }
149
- return 'closed';
150
- });
572
+ this.arrowDirective = contentChild(RdxTooltipArrowToken);
573
+ /** @ignore */
574
+ this.closeDirective = contentChild(RdxTooltipCloseToken);
151
575
  /** @ignore */
152
- this.tooltipContentDirective = contentChild.required(RdxTooltipContentToken);
576
+ this.contentAttributesComponent = contentChild(RdxTooltipContentAttributesToken);
153
577
  /** @ignore */
154
- this.tooltipTriggerDirective = contentChild.required(RdxTooltipTriggerDirective);
578
+ this.internalAnchorDirective = contentChild(RdxTooltipAnchorToken);
155
579
  /** @ignore */
156
- this.openTimer = 0;
580
+ this.viewContainerRef = inject(ViewContainerRef);
157
581
  /** @ignore */
158
- this.skipDelayTimer = 0;
582
+ this.rdxCdkEventService = injectRdxCdkEventService();
159
583
  /** @ignore */
160
- this.isControlledExternally = false;
584
+ this.destroyRef = inject(DestroyRef);
161
585
  /** @ignore */
162
- this.onIsOpenChangeEffect = effect(() => {
163
- const isOpen = this.isOpen();
164
- untracked(() => {
165
- if (isOpen) {
166
- this.show();
167
- }
168
- else {
169
- this.hide();
170
- }
171
- });
172
- });
586
+ this.state = signal(RdxTooltipState.CLOSED);
173
587
  /** @ignore */
174
- this.onPositionChangeEffect = effect(() => {
175
- const position = this.tooltipContentDirective().position();
176
- if (this.overlayRef) {
177
- const positionStrategy = this.getPositionStrategy(position);
178
- this.overlayRef.updatePositionStrategy(positionStrategy);
179
- }
180
- });
588
+ this.attachDetachEvent = signal(RdxTooltipAttachDetachEvent.DETACH);
181
589
  /** @ignore */
182
- this.onOpenChangeEffect = effect(() => {
183
- const currentOpen = this.open();
184
- this.isControlledExternally = currentOpen !== undefined;
185
- untracked(() => {
186
- if (this.isControlledExternally) {
187
- this.setOpen(currentOpen);
188
- }
590
+ this.isFirstDefaultOpen = signal(false);
591
+ /** @ignore */
592
+ this.anchorDirective = computed(() => this.internalAnchorDirective() ?? this.anchor());
593
+ /** @ignore */
594
+ this.actionSubject$ = new Subject();
595
+ /** @ignore */
596
+ this.onAnchorChangeEffect = () => {
597
+ effect(() => {
598
+ const anchor = this.anchor();
599
+ untracked(() => {
600
+ if (anchor) {
601
+ anchor.setRoot(this);
602
+ }
603
+ });
189
604
  });
605
+ };
606
+ this.rdxCdkEventService?.registerPrimitive(this);
607
+ this.destroyRef.onDestroy(() => this.rdxCdkEventService?.deregisterPrimitive(this));
608
+ this.actionSubscription();
609
+ this.onStateChangeEffect();
610
+ this.onCssAnimationStatusChangeChangeEffect();
611
+ this.onOpenChangeEffect();
612
+ this.onIsFirstDefaultOpenChangeEffect();
613
+ this.onAnchorChangeEffect();
614
+ this.emitOpenOrClosedEventEffect();
615
+ afterNextRender({
616
+ write: () => {
617
+ if (this.defaultOpen() && !this.open()) {
618
+ this.isFirstDefaultOpen.set(true);
619
+ }
620
+ }
190
621
  });
191
622
  }
192
623
  /** @ignore */
193
- ngOnInit() {
194
- if (this.defaultOpen()) {
195
- this.handleOpen();
196
- }
197
- this.isControlledExternally = this.open() !== undefined;
624
+ getAnimationParamsSnapshot() {
625
+ return {
626
+ cssAnimation: this.cssAnimation(),
627
+ cssOpeningAnimation: this.cssOpeningAnimation(),
628
+ cssClosingAnimation: this.cssClosingAnimation(),
629
+ cssAnimationStatus: this.cssAnimationStatus(),
630
+ attachDetachEvent: this.attachDetachEvent(),
631
+ state: this.state(),
632
+ canEmitOnOpenOrOnClosed: this.canEmitOnOpenOrOnClosed()
633
+ };
198
634
  }
199
635
  /** @ignore */
200
- onTriggerEnter() {
201
- if (this.isControlledExternally) {
202
- return;
203
- }
204
- if (this.isOpenDelayed()) {
205
- this.handleDelayedOpen();
206
- }
207
- else {
208
- this.handleOpen();
209
- }
210
- }
211
- /** @ignore */
212
- onTriggerLeave() {
213
- this.clearTimeout(this.openTimer);
214
- this.handleClose();
636
+ controlledExternally() {
637
+ return this.externalControl;
215
638
  }
216
639
  /** @ignore */
217
- onOpen() {
218
- this.clearTimeout(this.skipDelayTimer);
219
- this.isOpenDelayed.set(false);
220
- }
221
- /** @ignore */
222
- onClose() {
223
- this.clearTimeout(this.skipDelayTimer);
224
- if (isPlatformBrowser(this.platformId)) {
225
- this.skipDelayTimer = this.window.setTimeout(() => {
226
- this.isOpenDelayed.set(true);
227
- }, this.tooltipConfig.skipDelayDuration);
228
- }
640
+ firstDefaultOpen() {
641
+ return this.isFirstDefaultOpen();
229
642
  }
230
643
  /** @ignore */
231
644
  handleOpen() {
232
- if (this.isControlledExternally) {
645
+ if (this.externalControl()) {
233
646
  return;
234
647
  }
235
- this.wasOpenDelayed.set(false);
236
- this.setOpen(true);
648
+ this.actionSubject$.next(RdxTooltipAction.OPEN);
237
649
  }
238
650
  /** @ignore */
239
- handleClose() {
240
- if (this.isControlledExternally) {
651
+ handleClose(closeButton) {
652
+ if (this.isFirstDefaultOpen()) {
653
+ this.isFirstDefaultOpen.set(false);
654
+ }
655
+ if (!closeButton && this.externalControl()) {
241
656
  return;
242
657
  }
243
- this.clearTimeout(this.openTimer);
244
- this.setOpen(false);
658
+ this.actionSubject$.next(RdxTooltipAction.CLOSE);
245
659
  }
246
660
  /** @ignore */
247
- handleOverlayKeydown() {
248
- if (!this.overlayRef) {
661
+ handleToggle() {
662
+ if (this.externalControl()) {
249
663
  return;
250
664
  }
251
- this.overlayRef
252
- .keydownEvents()
253
- .pipe(filter((event) => event.key === 'Escape'), takeUntilDestroyed(this.destroyRef))
254
- .subscribe((event) => {
255
- this.tooltipContentDirective().onEscapeKeyDown.emit(event);
256
- if (!event.defaultPrevented) {
257
- this.handleClose();
258
- }
259
- });
665
+ this.isOpen() ? this.handleClose() : this.handleOpen();
260
666
  }
261
667
  /** @ignore */
262
- handlePointerDownOutside() {
263
- if (!this.overlayRef) {
668
+ isOpen(state) {
669
+ return (state ?? this.state()) === RdxTooltipState.OPEN;
670
+ }
671
+ /** @ignore */
672
+ setState(state = RdxTooltipState.CLOSED) {
673
+ if (state === this.state()) {
264
674
  return;
265
675
  }
266
- this.overlayRef
267
- .outsidePointerEvents()
268
- .pipe(takeUntilDestroyed(this.destroyRef))
269
- .subscribe((event) => this.tooltipContentDirective().onPointerDownOutside.emit(event));
270
- }
271
- /** @ignore */
272
- handleDelayedOpen() {
273
- this.clearTimeout(this.openTimer);
274
- if (isPlatformBrowser(this.platformId)) {
275
- this.openTimer = this.window.setTimeout(() => {
276
- this.wasOpenDelayed.set(true);
277
- this.setOpen(true);
278
- }, this.delayDuration());
279
- }
676
+ this.state.set(state);
280
677
  }
281
678
  /** @ignore */
282
- setOpen(open = false) {
283
- if (open) {
284
- this.onOpen();
285
- this.document.dispatchEvent(new CustomEvent('tooltip.open'));
679
+ openContent() {
680
+ this.contentDirective().open();
681
+ if (!this.cssAnimation() || !this.cssOpeningAnimation()) {
682
+ this.cssAnimationStatus.set(null);
286
683
  }
287
- else {
288
- this.onClose();
289
- }
290
- this.isOpen.set(open);
291
- this.onOpenChange.emit(open);
292
684
  }
293
685
  /** @ignore */
294
- createOverlayRef() {
295
- if (this.overlayRef) {
296
- return this.overlayRef;
686
+ closeContent() {
687
+ this.contentDirective().close();
688
+ if (!this.cssAnimation() || !this.cssClosingAnimation()) {
689
+ this.cssAnimationStatus.set(null);
297
690
  }
298
- this.overlayRef = this.overlay.create({
299
- direction: undefined,
300
- positionStrategy: this.getPositionStrategy(this.tooltipContentDirective().position()),
301
- scrollStrategy: this.overlay.scrollStrategies.close()
691
+ }
692
+ /** @ignore */
693
+ emitOnOpen() {
694
+ this.contentDirective().onOpen.emit();
695
+ }
696
+ /** @ignore */
697
+ emitOnClosed() {
698
+ this.contentDirective().onClosed.emit();
699
+ }
700
+ /** @ignore */
701
+ ifOpenOrCloseWithoutAnimations(state) {
702
+ return (!this.contentAttributesComponent() ||
703
+ !this.cssAnimation() ||
704
+ (this.cssAnimation() && !this.cssClosingAnimation() && state === RdxTooltipState.CLOSED) ||
705
+ (this.cssAnimation() && !this.cssOpeningAnimation() && state === RdxTooltipState.OPEN) ||
706
+ // !this.cssAnimationStatus() ||
707
+ (this.cssOpeningAnimation() &&
708
+ state === RdxTooltipState.OPEN &&
709
+ [RdxTooltipAnimationStatus.OPEN_STARTED].includes(this.cssAnimationStatus())) ||
710
+ (this.cssClosingAnimation() &&
711
+ state === RdxTooltipState.CLOSED &&
712
+ [RdxTooltipAnimationStatus.CLOSED_STARTED].includes(this.cssAnimationStatus())));
713
+ }
714
+ /** @ignore */
715
+ ifOpenOrCloseWithAnimations(cssAnimationStatus) {
716
+ return (this.contentAttributesComponent() &&
717
+ this.cssAnimation() &&
718
+ cssAnimationStatus &&
719
+ ((this.cssOpeningAnimation() &&
720
+ this.state() === RdxTooltipState.OPEN &&
721
+ [RdxTooltipAnimationStatus.OPEN_ENDED].includes(cssAnimationStatus)) ||
722
+ (this.cssClosingAnimation() &&
723
+ this.state() === RdxTooltipState.CLOSED &&
724
+ [RdxTooltipAnimationStatus.CLOSED_ENDED].includes(cssAnimationStatus))));
725
+ }
726
+ /** @ignore */
727
+ openOrClose(state) {
728
+ const isOpen = this.isOpen(state);
729
+ isOpen ? this.openContent() : this.closeContent();
730
+ }
731
+ /** @ignore */
732
+ emitOnOpenOrOnClosed(state) {
733
+ this.isOpen(state)
734
+ ? this.attachDetachEvent() === RdxTooltipAttachDetachEvent.ATTACH && this.emitOnOpen()
735
+ : this.attachDetachEvent() === RdxTooltipAttachDetachEvent.DETACH && this.emitOnClosed();
736
+ }
737
+ /** @ignore */
738
+ canEmitOnOpenOrOnClosed() {
739
+ return (!this.cssAnimation() ||
740
+ (!this.cssOpeningAnimation() && this.state() === RdxTooltipState.OPEN) ||
741
+ (this.cssOpeningAnimation() &&
742
+ this.state() === RdxTooltipState.OPEN &&
743
+ this.cssAnimationStatus() === RdxTooltipAnimationStatus.OPEN_ENDED) ||
744
+ (!this.cssClosingAnimation() && this.state() === RdxTooltipState.CLOSED) ||
745
+ (this.cssClosingAnimation() &&
746
+ this.state() === RdxTooltipState.CLOSED &&
747
+ this.cssAnimationStatus() === RdxTooltipAnimationStatus.CLOSED_ENDED));
748
+ }
749
+ /** @ignore */
750
+ onStateChangeEffect() {
751
+ let isFirst = true;
752
+ effect(() => {
753
+ const state = this.state();
754
+ untracked(() => {
755
+ if (isFirst) {
756
+ isFirst = false;
757
+ return;
758
+ }
759
+ if (!this.ifOpenOrCloseWithoutAnimations(state)) {
760
+ return;
761
+ }
762
+ this.openOrClose(state);
763
+ });
764
+ }, {});
765
+ }
766
+ /** @ignore */
767
+ onCssAnimationStatusChangeChangeEffect() {
768
+ let isFirst = true;
769
+ effect(() => {
770
+ const cssAnimationStatus = this.cssAnimationStatus();
771
+ untracked(() => {
772
+ if (isFirst) {
773
+ isFirst = false;
774
+ return;
775
+ }
776
+ if (!this.ifOpenOrCloseWithAnimations(cssAnimationStatus)) {
777
+ return;
778
+ }
779
+ this.openOrClose(this.state());
780
+ });
302
781
  });
303
- this.overlayRef
304
- .detachments()
305
- .pipe(take(1), takeUntilDestroyed(this.destroyRef))
306
- .subscribe(() => this.detach());
307
- this.handleOverlayKeydown();
308
- this.handlePointerDownOutside();
309
- return this.overlayRef;
310
- }
311
- /** @ignore */
312
- show() {
313
- this.overlayRef = this.createOverlayRef();
314
- this.detach();
315
- this.portal =
316
- this.portal ||
317
- new TemplatePortal(this.tooltipContentDirective().templateRef, this.viewContainerRef, {
318
- state: this.state,
319
- side: this.tooltipContentDirective().side
320
- });
321
- this.instance = this.overlayRef.attach(this.portal);
322
782
  }
323
783
  /** @ignore */
324
- detach() {
325
- if (this.overlayRef?.hasAttached()) {
326
- this.overlayRef.detach();
327
- }
784
+ emitOpenOrClosedEventEffect() {
785
+ let isFirst = true;
786
+ effect(() => {
787
+ this.attachDetachEvent();
788
+ this.cssAnimationStatus();
789
+ untracked(() => {
790
+ if (isFirst) {
791
+ isFirst = false;
792
+ return;
793
+ }
794
+ const canEmitOpenClose = untracked(() => this.canEmitOnOpenOrOnClosed());
795
+ if (!canEmitOpenClose) {
796
+ return;
797
+ }
798
+ this.emitOnOpenOrOnClosed(this.state());
799
+ });
800
+ });
328
801
  }
329
802
  /** @ignore */
330
- hide() {
331
- if (this.isControlledExternally && this.open()) {
332
- return;
333
- }
334
- asyncScheduler.schedule(() => {
335
- this.instance?.destroy();
336
- }, this.tooltipConfig.hideDelayDuration ?? 0);
803
+ onOpenChangeEffect() {
804
+ effect(() => {
805
+ const open = this.open();
806
+ untracked(() => {
807
+ this.setState(open ? RdxTooltipState.OPEN : RdxTooltipState.CLOSED);
808
+ });
809
+ });
337
810
  }
338
811
  /** @ignore */
339
- getPositionStrategy(connectedPosition) {
340
- return this.overlay
341
- .position()
342
- .flexibleConnectedTo(this.tooltipTriggerDirective().elementRef)
343
- .withFlexibleDimensions(false)
344
- .withPositions([
345
- connectedPosition
346
- ])
347
- .withLockedPosition();
812
+ onIsFirstDefaultOpenChangeEffect() {
813
+ const effectRef = effect(() => {
814
+ const defaultOpen = this.defaultOpen();
815
+ untracked(() => {
816
+ if (!defaultOpen || this.open()) {
817
+ effectRef.destroy();
818
+ return;
819
+ }
820
+ this.handleOpen();
821
+ });
822
+ });
348
823
  }
349
824
  /** @ignore */
350
- clearTimeout(timeoutId) {
351
- if (isPlatformBrowser(this.platformId)) {
352
- this.window.clearTimeout(timeoutId);
353
- }
825
+ actionSubscription() {
826
+ this.actionSubject$
827
+ .asObservable()
828
+ .pipe(map((action) => {
829
+ console.log(action);
830
+ switch (action) {
831
+ case RdxTooltipAction.OPEN:
832
+ return { action, duration: this.openDelay() };
833
+ case RdxTooltipAction.CLOSE:
834
+ return { action, duration: this.closeDelay() };
835
+ }
836
+ }), debounce((config) => timer(config.duration)), tap((config) => {
837
+ switch (config.action) {
838
+ case RdxTooltipAction.OPEN:
839
+ this.setState(RdxTooltipState.OPEN);
840
+ break;
841
+ case RdxTooltipAction.CLOSE:
842
+ this.setState(RdxTooltipState.CLOSED);
843
+ break;
844
+ }
845
+ }), takeUntilDestroyed())
846
+ .subscribe();
354
847
  }
355
848
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
356
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.0.5", type: RdxTooltipRootDirective, isStandalone: true, selector: "[rdxTooltipRoot]", inputs: { defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, delayDuration: { classPropertyName: "delayDuration", publicName: "delayDuration", isSignal: true, isRequired: false, transformFunction: null }, disableHoverableContent: { classPropertyName: "disableHoverableContent", publicName: "disableHoverableContent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onOpenChange: "onOpenChange" }, providers: [
357
- {
358
- provide: RdxTooltipRootToken,
359
- useExisting: forwardRef(() => RdxTooltipRootDirective)
360
- }
361
- ], queries: [{ propertyName: "tooltipContentDirective", first: true, predicate: RdxTooltipContentToken, descendants: true, isSignal: true }, { propertyName: "tooltipTriggerDirective", first: true, predicate: RdxTooltipTriggerDirective, descendants: true, isSignal: true }], exportAs: ["rdxTooltipRoot"], ngImport: i0 }); }
849
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.0.5", 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 }); }
362
850
  }
363
851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipRootDirective, decorators: [{
364
852
  type: Directive,
365
853
  args: [{
366
854
  selector: '[rdxTooltipRoot]',
367
- standalone: true,
855
+ exportAs: 'rdxTooltipRoot'
856
+ }]
857
+ }], ctorParameters: () => [] });
858
+
859
+ function injectTooltipRoot(optional = false) {
860
+ isDevMode() && assertInInjectionContext(injectTooltipRoot);
861
+ return inject(RdxTooltipRootDirective, { optional });
862
+ }
863
+
864
+ class RdxTooltipAnchorDirective {
865
+ constructor() {
866
+ /**
867
+ * @ignore
868
+ * If outside the rootDirective then null, otherwise the rootDirective directive - with optional `true` passed in as the first param.
869
+ * If outside the rootDirective and non-null value that means the html structure is wrong - tooltip inside tooltip.
870
+ * */
871
+ this.rootDirective = injectTooltipRoot(true);
872
+ /** @ignore */
873
+ this.elementRef = inject(ElementRef);
874
+ /** @ignore */
875
+ this.overlayOrigin = inject(CdkOverlayOrigin);
876
+ /** @ignore */
877
+ this.document = injectDocument();
878
+ /** @ignore */
879
+ this.name = computed(() => `rdx-tooltip-external-anchor-${this.rootDirective?.uniqueId()}`);
880
+ }
881
+ /** @ignore */
882
+ click() {
883
+ this.emitOutsideClick();
884
+ }
885
+ /** @ignore */
886
+ setRoot(root) {
887
+ this.rootDirective = root;
888
+ }
889
+ emitOutsideClick() {
890
+ if (!this.rootDirective?.isOpen() || this.rootDirective?.contentDirective().onOverlayOutsideClickDisabled()) {
891
+ return;
892
+ }
893
+ const clickEvent = new MouseEvent('click', {
894
+ view: this.document.defaultView,
895
+ bubbles: true,
896
+ cancelable: true,
897
+ relatedTarget: this.elementRef.nativeElement
898
+ });
899
+ this.rootDirective?.triggerDirective().elementRef.nativeElement.dispatchEvent(clickEvent);
900
+ }
901
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
902
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxTooltipAnchorDirective, isStandalone: true, selector: "[rdxTooltipAnchor]", host: { attributes: { "type": "button" }, listeners: { "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"" } }, providers: [
903
+ {
904
+ provide: RdxTooltipAnchorToken,
905
+ useExisting: forwardRef(() => RdxTooltipAnchorDirective)
906
+ }
907
+ ], exportAs: ["rdxTooltipAnchor"], hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
908
+ }
909
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipAnchorDirective, decorators: [{
910
+ type: Directive,
911
+ args: [{
912
+ selector: '[rdxTooltipAnchor]',
913
+ exportAs: 'rdxTooltipAnchor',
914
+ hostDirectives: [CdkOverlayOrigin],
915
+ host: {
916
+ type: 'button',
917
+ '[attr.id]': 'name()',
918
+ '[attr.aria-haspopup]': '"dialog"',
919
+ '(click)': 'click()'
920
+ },
368
921
  providers: [
369
922
  {
370
- provide: RdxTooltipRootToken,
371
- useExisting: forwardRef(() => RdxTooltipRootDirective)
923
+ provide: RdxTooltipAnchorToken,
924
+ useExisting: forwardRef(() => RdxTooltipAnchorDirective)
372
925
  }
373
- ],
374
- exportAs: 'rdxTooltipRoot'
926
+ ]
375
927
  }]
376
928
  }] });
377
929
 
378
930
  class RdxTooltipArrowDirective {
379
931
  constructor() {
380
- /** @ignore */
381
- this.tooltipRoot = injectTooltipRoot();
382
932
  /** @ignore */
383
933
  this.renderer = inject(Renderer2);
384
934
  /** @ignore */
385
- this.contentDirective = inject(RdxTooltipContentToken);
935
+ this.rootDirective = injectTooltipRoot();
386
936
  /** @ignore */
387
937
  this.elementRef = inject(ElementRef);
388
938
  /**
389
- * The width of the arrow in pixels.
939
+ * @description The width of the arrow in pixels.
940
+ * @default 10
390
941
  */
391
- this.width = input(10);
942
+ this.width = input(RDX_POSITIONING_DEFAULTS.arrow.width, { transform: numberAttribute });
392
943
  /**
393
- * The height of the arrow in pixels.
944
+ * @description The height of the arrow in pixels.
945
+ * @default 5
394
946
  */
395
- this.height = input(5);
396
- /** @ignore */
397
- this.currentArrowSvgElement = signal(void 0);
947
+ this.height = input(RDX_POSITIONING_DEFAULTS.arrow.height, { transform: numberAttribute });
398
948
  /** @ignore */
399
949
  this.arrowSvgElement = computed(() => {
400
950
  const width = this.width();
@@ -410,30 +960,9 @@ class RdxTooltipArrowDirective {
410
960
  return svgElement;
411
961
  });
412
962
  /** @ignore */
413
- this.onArrowSvgElementChangeEffect = effect(() => {
414
- const arrowElement = this.arrowSvgElement();
415
- untracked(() => {
416
- const currentArrowSvgElement = this.currentArrowSvgElement();
417
- if (currentArrowSvgElement) {
418
- this.renderer.removeChild(this.elementRef.nativeElement, currentArrowSvgElement);
419
- }
420
- this.currentArrowSvgElement.set(arrowElement);
421
- this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.width()}px`);
422
- this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.height()}px`);
423
- this.renderer.appendChild(this.elementRef.nativeElement, this.currentArrowSvgElement());
424
- });
425
- });
963
+ this.currentArrowSvgElement = signal(void 0);
426
964
  /** @ignore */
427
- this.onContentPositionAndArrowDimensionsChangeEffect = effect(() => {
428
- const position = this.contentDirective.position();
429
- const arrowDimensions = { width: this.width(), height: this.height() };
430
- untracked(() => {
431
- if (!position) {
432
- return;
433
- }
434
- this.setPosition(position, arrowDimensions);
435
- });
436
- });
965
+ this.position = toSignal(this.rootDirective.contentDirective().positionChange());
437
966
  afterNextRender({
438
967
  write: () => {
439
968
  if (this.elementRef.nativeElement.parentElement) {
@@ -444,20 +973,52 @@ class RdxTooltipArrowDirective {
444
973
  this.renderer.setStyle(this.elementRef.nativeElement, 'fontSize', '0px');
445
974
  }
446
975
  });
976
+ this.onArrowSvgElementChangeEffect();
977
+ this.onContentPositionAndArrowDimensionsChangeEffect();
447
978
  }
448
979
  /** @ignore */
449
- setTriggerRect() {
450
- this.triggerRect = this.tooltipRoot.tooltipTriggerDirective().elementRef.nativeElement.getBoundingClientRect();
980
+ setAnchorOrTriggerRect() {
981
+ this.anchorOrTriggerRect = (this.rootDirective.anchorDirective() ?? this.rootDirective.triggerDirective()).elementRef.nativeElement.getBoundingClientRect();
451
982
  }
452
983
  /** @ignore */
453
984
  setPosition(position, arrowDimensions) {
454
- this.setTriggerRect();
455
- const posParams = getArrowPositionParams(getSideAndAlignFromAllPossibleConnectedPositions(position), { width: arrowDimensions.width, height: arrowDimensions.height }, { width: this.triggerRect.width, height: this.triggerRect.height });
985
+ this.setAnchorOrTriggerRect();
986
+ const posParams = getArrowPositionParams(getSideAndAlignFromAllPossibleConnectedPositions(position.connectionPair), { width: arrowDimensions.width, height: arrowDimensions.height }, { width: this.anchorOrTriggerRect.width, height: this.anchorOrTriggerRect.height });
456
987
  this.renderer.setStyle(this.elementRef.nativeElement, 'top', posParams.top);
457
988
  this.renderer.setStyle(this.elementRef.nativeElement, 'bottom', '');
458
989
  this.renderer.setStyle(this.elementRef.nativeElement, 'left', posParams.left);
459
990
  this.renderer.setStyle(this.elementRef.nativeElement, 'right', '');
460
991
  this.renderer.setStyle(this.elementRef.nativeElement, 'transform', posParams.transform);
992
+ this.renderer.setStyle(this.elementRef.nativeElement, 'transformOrigin', posParams.transformOrigin);
993
+ }
994
+ /** @ignore */
995
+ onArrowSvgElementChangeEffect() {
996
+ effect(() => {
997
+ const arrowElement = this.arrowSvgElement();
998
+ untracked(() => {
999
+ const currentArrowSvgElement = this.currentArrowSvgElement();
1000
+ if (currentArrowSvgElement) {
1001
+ this.renderer.removeChild(this.elementRef.nativeElement, currentArrowSvgElement);
1002
+ }
1003
+ this.currentArrowSvgElement.set(arrowElement);
1004
+ this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.width()}px`);
1005
+ this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.height()}px`);
1006
+ this.renderer.appendChild(this.elementRef.nativeElement, this.currentArrowSvgElement());
1007
+ });
1008
+ });
1009
+ }
1010
+ /** @ignore */
1011
+ onContentPositionAndArrowDimensionsChangeEffect() {
1012
+ effect(() => {
1013
+ const position = this.position();
1014
+ const arrowDimensions = { width: this.width(), height: this.height() };
1015
+ untracked(() => {
1016
+ if (!position) {
1017
+ return;
1018
+ }
1019
+ this.setPosition(position, arrowDimensions);
1020
+ });
1021
+ });
461
1022
  }
462
1023
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipArrowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
463
1024
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", 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: [
@@ -471,7 +1032,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
471
1032
  type: Directive,
472
1033
  args: [{
473
1034
  selector: '[rdxTooltipArrow]',
474
- standalone: true,
475
1035
  providers: [
476
1036
  {
477
1037
  provide: RdxTooltipArrowToken,
@@ -481,92 +1041,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
481
1041
  }]
482
1042
  }], ctorParameters: () => [] });
483
1043
 
484
- class RdxTooltipContentAttributesDirective {
1044
+ /**
1045
+ * TODO: to be removed? But it seems to be useful when controlled from outside
1046
+ */
1047
+ class RdxTooltipCloseDirective {
485
1048
  constructor() {
486
- this.tooltipRoot = inject(RdxTooltipRootDirective);
487
- this.tooltipContent = inject(RdxTooltipContentToken);
1049
+ /** @ignore */
1050
+ this.rootDirective = injectTooltipRoot();
1051
+ /** @ignore */
1052
+ this.elementRef = inject(ElementRef);
1053
+ /** @ignore */
1054
+ this.renderer = inject(Renderer2);
1055
+ this.onIsControlledExternallyEffect();
488
1056
  }
489
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentAttributesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
490
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxTooltipContentAttributesDirective, isStandalone: true, selector: "[rdxTooltipContentAttributes]", host: { properties: { "attr.data-state": "tooltipRoot.state()", "attr.data-side": "tooltipContent.side()" } }, ngImport: i0 }); }
1057
+ /** @ignore */
1058
+ onIsControlledExternallyEffect() {
1059
+ effect(() => {
1060
+ const isControlledExternally = this.rootDirective.controlledExternally()();
1061
+ untracked(() => {
1062
+ this.renderer.setStyle(this.elementRef.nativeElement, 'display', isControlledExternally ? null : 'none');
1063
+ });
1064
+ });
1065
+ }
1066
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1067
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxTooltipCloseDirective, isStandalone: true, selector: "[rdxTooltipClose]", host: { attributes: { "type": "button" }, listeners: { "click": "rootDirective.handleClose(true)" } }, providers: [
1068
+ {
1069
+ provide: RdxTooltipCloseToken,
1070
+ useExisting: forwardRef(() => RdxTooltipCloseDirective)
1071
+ }
1072
+ ], ngImport: i0 }); }
491
1073
  }
492
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentAttributesDirective, decorators: [{
1074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipCloseDirective, decorators: [{
493
1075
  type: Directive,
494
1076
  args: [{
495
- selector: '[rdxTooltipContentAttributes]',
496
- standalone: true,
1077
+ selector: '[rdxTooltipClose]',
497
1078
  host: {
498
- '[attr.data-state]': 'tooltipRoot.state()',
499
- '[attr.data-side]': 'tooltipContent.side()'
500
- }
1079
+ type: 'button',
1080
+ '(click)': 'rootDirective.handleClose(true)'
1081
+ },
1082
+ providers: [
1083
+ {
1084
+ provide: RdxTooltipCloseToken,
1085
+ useExisting: forwardRef(() => RdxTooltipCloseDirective)
1086
+ }
1087
+ ]
501
1088
  }]
502
- }] });
1089
+ }], ctorParameters: () => [] });
503
1090
 
504
- class RdxTooltipContentDirective {
1091
+ class RdxTooltipContentAttributesComponent {
505
1092
  constructor() {
506
1093
  /** @ignore */
507
- this.templateRef = inject(TemplateRef);
508
- /**
509
- * The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
510
- */
511
- this.side = input(RdxPositionSide.Top);
512
- /**
513
- * The distance in pixels from the trigger.
514
- */
515
- this.sideOffset = input(0);
516
- /**
517
- * The preferred alignment against the trigger. May change when collisions occur.
518
- */
519
- this.align = input(RdxPositionAlign.Center);
520
- /**
521
- * An offset in pixels from the "start" or "end" alignment options.
522
- */
523
- this.alignOffset = input(0);
524
- /** @ingore */
525
- this.position = computed(() => getContentPosition({
526
- side: this.side(),
527
- align: this.align(),
528
- sideOffset: this.sideOffset(),
529
- alignOffset: this.alignOffset()
530
- }));
531
- /**
532
- * Event handler called when the escape key is down. It can be prevented by calling event.preventDefault.
533
- */
534
- this.onEscapeKeyDown = output();
535
- /**
536
- * Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling event.preventDefault.
537
- */
538
- this.onPointerDownOutside = output();
1094
+ this.rootDirective = injectTooltipRoot();
1095
+ /** @ignore */
1096
+ this.name = computed(() => `rdx-tooltip-content-attributes-${this.rootDirective.uniqueId()}`);
1097
+ /** @ignore */
1098
+ this.disableAnimation = computed(() => !this.canAnimate());
539
1099
  }
540
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
541
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", 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 } }, outputs: { onEscapeKeyDown: "onEscapeKeyDown", onPointerDownOutside: "onPointerDownOutside" }, providers: [{ provide: RdxTooltipContentToken, useExisting: forwardRef(() => RdxTooltipContentDirective) }], ngImport: i0 }); }
1100
+ /** @ignore */
1101
+ onAnimationStart(_) {
1102
+ this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxTooltipState.OPEN
1103
+ ? RdxTooltipAnimationStatus.OPEN_STARTED
1104
+ : RdxTooltipAnimationStatus.CLOSED_STARTED);
1105
+ }
1106
+ /** @ignore */
1107
+ onAnimationEnd(_) {
1108
+ this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxTooltipState.OPEN
1109
+ ? RdxTooltipAnimationStatus.OPEN_ENDED
1110
+ : RdxTooltipAnimationStatus.CLOSED_ENDED);
1111
+ }
1112
+ /** @ignore */
1113
+ pointerenter() {
1114
+ this.rootDirective.handleOpen();
1115
+ }
1116
+ /** @ignore */
1117
+ pointerleave() {
1118
+ this.rootDirective.handleClose();
1119
+ }
1120
+ /** @ignore */
1121
+ focus() {
1122
+ this.rootDirective.handleOpen();
1123
+ }
1124
+ /** @ignore */
1125
+ blur() {
1126
+ this.rootDirective.handleClose();
1127
+ }
1128
+ /** @ignore */
1129
+ canAnimate() {
1130
+ return (this.rootDirective.cssAnimation() &&
1131
+ ((this.rootDirective.cssOpeningAnimation() && this.rootDirective.state() === RdxTooltipState.OPEN) ||
1132
+ (this.rootDirective.cssClosingAnimation() && this.rootDirective.state() === RdxTooltipState.CLOSED)));
1133
+ }
1134
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentAttributesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", 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: [
1136
+ {
1137
+ provide: RdxTooltipContentAttributesToken,
1138
+ useExisting: forwardRef(() => RdxTooltipContentAttributesComponent)
1139
+ }
1140
+ ], ngImport: i0, template: `
1141
+ <ng-content />
1142
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
542
1143
  }
543
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentDirective, decorators: [{
544
- type: Directive,
1144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipContentAttributesComponent, decorators: [{
1145
+ type: Component,
545
1146
  args: [{
546
- selector: '[rdxTooltipContent]',
547
- standalone: true,
548
- providers: [{ provide: RdxTooltipContentToken, useExisting: forwardRef(() => RdxTooltipContentDirective) }]
1147
+ selector: '[rdxTooltipContentAttributes]',
1148
+ template: `
1149
+ <ng-content />
1150
+ `,
1151
+ host: {
1152
+ '[attr.role]': '"dialog"',
1153
+ '[attr.id]': 'name()',
1154
+ '[attr.data-state]': 'rootDirective.state()',
1155
+ '[attr.data-side]': 'rootDirective.contentDirective().side()',
1156
+ '[attr.data-align]': 'rootDirective.contentDirective().align()',
1157
+ '[style]': 'disableAnimation() ? {animation: "none !important"} : null',
1158
+ '(animationstart)': 'onAnimationStart($event)',
1159
+ '(animationend)': 'onAnimationEnd($event)',
1160
+ '(pointerenter)': 'pointerenter()',
1161
+ '(pointerleave)': 'pointerleave()',
1162
+ '(focus)': 'focus()',
1163
+ '(blur)': 'blur()'
1164
+ },
1165
+ providers: [
1166
+ {
1167
+ provide: RdxTooltipContentAttributesToken,
1168
+ useExisting: forwardRef(() => RdxTooltipContentAttributesComponent)
1169
+ }
1170
+ ],
1171
+ changeDetection: ChangeDetectionStrategy.OnPush
549
1172
  }]
550
1173
  }] });
551
1174
 
552
1175
  const _imports = [
553
1176
  RdxTooltipArrowDirective,
1177
+ RdxTooltipCloseDirective,
554
1178
  RdxTooltipContentDirective,
555
1179
  RdxTooltipTriggerDirective,
556
- RdxTooltipContentAttributesDirective,
557
- RdxTooltipRootDirective
1180
+ RdxTooltipRootDirective,
1181
+ RdxTooltipAnchorDirective,
1182
+ RdxTooltipContentAttributesComponent
558
1183
  ];
559
1184
  class RdxTooltipModule {
560
1185
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
561
1186
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipModule, imports: [RdxTooltipArrowDirective,
1187
+ RdxTooltipCloseDirective,
562
1188
  RdxTooltipContentDirective,
563
1189
  RdxTooltipTriggerDirective,
564
- RdxTooltipContentAttributesDirective,
565
- RdxTooltipRootDirective], exports: [RdxTooltipArrowDirective,
1190
+ RdxTooltipRootDirective,
1191
+ RdxTooltipAnchorDirective,
1192
+ RdxTooltipContentAttributesComponent], exports: [RdxTooltipArrowDirective,
1193
+ RdxTooltipCloseDirective,
566
1194
  RdxTooltipContentDirective,
567
1195
  RdxTooltipTriggerDirective,
568
- RdxTooltipContentAttributesDirective,
569
- RdxTooltipRootDirective] }); }
1196
+ RdxTooltipRootDirective,
1197
+ RdxTooltipAnchorDirective,
1198
+ RdxTooltipContentAttributesComponent] }); }
570
1199
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipModule }); }
571
1200
  }
572
1201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxTooltipModule, decorators: [{
@@ -581,5 +1210,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
581
1210
  * Generated bundle index. Do not edit.
582
1211
  */
583
1212
 
584
- export { RdxTooltipArrowDirective, RdxTooltipContentAttributesDirective, RdxTooltipContentDirective, RdxTooltipModule, RdxTooltipRootDirective, RdxTooltipRootToken, RdxTooltipTriggerDirective, injectTooltipRoot };
1213
+ export { RdxTooltipAnchorDirective, RdxTooltipArrowDirective, RdxTooltipCloseDirective, RdxTooltipContentAttributesComponent, RdxTooltipContentDirective, RdxTooltipModule, RdxTooltipRootDirective, RdxTooltipTriggerDirective };
585
1214
  //# sourceMappingURL=radix-ng-primitives-tooltip.mjs.map