@radix-ng/primitives 0.26.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 (32) hide show
  1. package/compodoc/documentation.json +13329 -6250
  2. package/fesm2022/radix-ng-primitives-core.mjs +1 -1
  3. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-hover-card.mjs +1213 -0
  5. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +1 -0
  6. package/fesm2022/radix-ng-primitives-popover.mjs +1 -3
  7. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-tooltip.mjs +23 -5
  9. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  10. package/hover-card/README.md +3 -0
  11. package/hover-card/index.d.ts +20 -0
  12. package/hover-card/src/hover-card-anchor.directive.d.ts +28 -0
  13. package/hover-card/src/hover-card-anchor.token.d.ts +3 -0
  14. package/hover-card/src/hover-card-arrow.directive.d.ts +40 -0
  15. package/hover-card/src/hover-card-arrow.token.d.ts +3 -0
  16. package/hover-card/src/hover-card-close.directive.d.ts +18 -0
  17. package/hover-card/src/hover-card-close.token.d.ts +3 -0
  18. package/hover-card/src/hover-card-content-attributes.component.d.ts +25 -0
  19. package/hover-card/src/hover-card-content-attributes.token.d.ts +3 -0
  20. package/hover-card/src/hover-card-content.directive.d.ts +104 -0
  21. package/hover-card/src/hover-card-root.directive.d.ts +168 -0
  22. package/hover-card/src/hover-card-root.inject.d.ts +3 -0
  23. package/hover-card/src/hover-card-trigger.directive.d.ts +26 -0
  24. package/hover-card/src/hover-card.types.d.ts +18 -0
  25. package/hover-card/src/utils/cdk-event.service.d.ts +30 -0
  26. package/hover-card/src/utils/constants.d.ts +1 -0
  27. package/hover-card/src/utils/types.d.ts +7 -0
  28. package/package.json +5 -1
  29. package/popover/src/popover-root.directive.d.ts +4 -4
  30. package/popover/src/popover-trigger.directive.d.ts +1 -1
  31. package/tooltip/src/tooltip-content-attributes.component.d.ts +8 -0
  32. package/tooltip/src/tooltip-root.directive.d.ts +4 -4
@@ -0,0 +1,1213 @@
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, 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 RdxHoverCardAnchorToken = new InjectionToken('RdxHoverCardAnchorToken');
10
+
11
+ const RdxHoverCardArrowToken = new InjectionToken('RdxHoverCardArrowToken');
12
+
13
+ const RdxHoverCardCloseToken = new InjectionToken('RdxHoverCardCloseToken');
14
+
15
+ const RdxHoverCardContentAttributesToken = new InjectionToken('RdxHoverCardContentAttributesToken');
16
+
17
+ var RdxHoverCardState;
18
+ (function (RdxHoverCardState) {
19
+ RdxHoverCardState["OPEN"] = "open";
20
+ RdxHoverCardState["CLOSED"] = "closed";
21
+ })(RdxHoverCardState || (RdxHoverCardState = {}));
22
+ var RdxHoverCardAction;
23
+ (function (RdxHoverCardAction) {
24
+ RdxHoverCardAction["OPEN"] = "open";
25
+ RdxHoverCardAction["CLOSE"] = "close";
26
+ })(RdxHoverCardAction || (RdxHoverCardAction = {}));
27
+ var RdxHoverCardAttachDetachEvent;
28
+ (function (RdxHoverCardAttachDetachEvent) {
29
+ RdxHoverCardAttachDetachEvent["ATTACH"] = "attach";
30
+ RdxHoverCardAttachDetachEvent["DETACH"] = "detach";
31
+ })(RdxHoverCardAttachDetachEvent || (RdxHoverCardAttachDetachEvent = {}));
32
+ var RdxHoverCardAnimationStatus;
33
+ (function (RdxHoverCardAnimationStatus) {
34
+ RdxHoverCardAnimationStatus["OPEN_STARTED"] = "open_started";
35
+ RdxHoverCardAnimationStatus["OPEN_ENDED"] = "open_ended";
36
+ RdxHoverCardAnimationStatus["CLOSED_STARTED"] = "closed_started";
37
+ RdxHoverCardAnimationStatus["CLOSED_ENDED"] = "closed_ended";
38
+ })(RdxHoverCardAnimationStatus || (RdxHoverCardAnimationStatus = {}));
39
+
40
+ class RdxHoverCardContentDirective {
41
+ constructor() {
42
+ /** @ignore */
43
+ this.rootDirective = injectHoverCardRoot();
44
+ /** @ignore */
45
+ this.templateRef = inject(TemplateRef);
46
+ /** @ignore */
47
+ this.overlay = inject(Overlay);
48
+ /** @ignore */
49
+ this.destroyRef = inject(DestroyRef);
50
+ /** @ignore */
51
+ this.connectedOverlay = inject(CdkConnectedOverlay);
52
+ /** @ignore */
53
+ this.name = computed(() => `rdx-hover-card-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();
109
+ }
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();
119
+ }
120
+ /** @ignore */
121
+ open() {
122
+ if (this.connectedOverlay.open) {
123
+ return;
124
+ }
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;
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(RdxHoverCardAttachDetachEvent.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(RdxHoverCardAttachDetachEvent.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);
211
+ }
212
+ /** @ignore */
213
+ setDisableClose() {
214
+ const prevDisableClose = this.connectedOverlay.disableClose;
215
+ this.connectedOverlay.disableClose = true;
216
+ this.fireOverlayNgOnChanges('disableClose', this.connectedOverlay.disableClose, prevDisableClose);
217
+ }
218
+ /** @ignore */
219
+ setOrigin(origin) {
220
+ const prevOrigin = this.connectedOverlay.origin;
221
+ this.connectedOverlay.origin = origin;
222
+ this.fireOverlayNgOnChanges('origin', this.connectedOverlay.origin, prevOrigin);
223
+ }
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();
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
+ });
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: RdxHoverCardContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
291
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", type: RdxHoverCardContentDirective, isStandalone: true, selector: "[rdxHoverCardContent]", 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: RdxHoverCardContentDirective, decorators: [{
294
+ type: Directive,
295
+ args: [{
296
+ selector: '[rdxHoverCardContent]',
297
+ hostDirectives: [
298
+ CdkConnectedOverlay
299
+ ]
300
+ }]
301
+ }], ctorParameters: () => [] });
302
+
303
+ class RdxHoverCardTriggerDirective {
304
+ constructor() {
305
+ /** @ignore */
306
+ this.rootDirective = injectHoverCardRoot();
307
+ /** @ignore */
308
+ this.elementRef = inject(ElementRef);
309
+ /** @ignore */
310
+ this.overlayOrigin = inject(CdkOverlayOrigin);
311
+ /** @ignore */
312
+ this.name = computed(() => `rdx-hover-card-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();
325
+ }
326
+ /** @ignore */
327
+ blur() {
328
+ this.rootDirective.handleClose();
329
+ }
330
+ /** @ignore */
331
+ click() {
332
+ this.rootDirective.handleClose();
333
+ }
334
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
335
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxHoverCardTriggerDirective, isStandalone: true, selector: "[rdxHoverCardTrigger]", host: { 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 }); }
336
+ }
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardTriggerDirective, decorators: [{
338
+ type: Directive,
339
+ args: [{
340
+ selector: '[rdxHoverCardTrigger]',
341
+ hostDirectives: [CdkOverlayOrigin],
342
+ host: {
343
+ '[attr.id]': 'name()',
344
+ '[attr.aria-haspopup]': '"dialog"',
345
+ '[attr.aria-expanded]': 'rootDirective.isOpen()',
346
+ '[attr.aria-controls]': 'rootDirective.contentDirective().name()',
347
+ '[attr.data-state]': 'rootDirective.state()',
348
+ '(pointerenter)': 'pointerenter()',
349
+ '(pointerleave)': 'pointerleave()',
350
+ '(focus)': 'focus()',
351
+ '(blur)': 'blur()',
352
+ '(click)': 'click()'
353
+ }
354
+ }]
355
+ }] });
356
+
357
+ const RdxCdkEventServiceWindowKey = Symbol('__RdxCdkEventService__');
358
+
359
+ function eventTypeAsPrimitiveConfigKey(eventType) {
360
+ return `prevent${eventType[0].toUpperCase()}${eventType.slice(1)}`;
361
+ }
362
+ class RdxCdkEventService {
363
+ #clickDomRootEventCallbacks;
364
+ constructor() {
365
+ this.document = injectDocument();
366
+ this.destroyRef = inject(DestroyRef);
367
+ this.ngZone = inject(NgZone);
368
+ this.renderer2 = inject(Renderer2);
369
+ this.window = injectWindow();
370
+ this.onDestroyCallbacks = new Set([() => deleteRdxCdkEventServiceWindowKey(this.window)]);
371
+ this.#clickDomRootEventCallbacks = new Set();
372
+ this.#listenToClickDomRootEvent();
373
+ this.#registerOnDestroyCallbacks();
374
+ }
375
+ registerPrimitive(primitiveInstance) {
376
+ if (!this.primitiveConfigs) {
377
+ this.primitiveConfigs = new Map();
378
+ }
379
+ if (!this.primitiveConfigs.has(primitiveInstance)) {
380
+ this.primitiveConfigs.set(primitiveInstance, {});
381
+ }
382
+ }
383
+ deregisterPrimitive(primitiveInstance) {
384
+ if (this.primitiveConfigs?.has(primitiveInstance)) {
385
+ this.primitiveConfigs.delete(primitiveInstance);
386
+ }
387
+ }
388
+ preventPrimitiveFromCdkEvent(primitiveInstance, eventType) {
389
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
390
+ }
391
+ allowPrimitiveForCdkEvent(primitiveInstance, eventType) {
392
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
393
+ }
394
+ preventPrimitiveFromCdkMultiEvents(primitiveInstance, eventTypes) {
395
+ eventTypes.forEach((eventType) => {
396
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, true);
397
+ });
398
+ }
399
+ allowPrimitiveForCdkMultiEvents(primitiveInstance, eventTypes) {
400
+ eventTypes.forEach((eventType) => {
401
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, false);
402
+ });
403
+ }
404
+ setPreventPrimitiveFromCdkMixEvents(primitiveInstance, eventTypes) {
405
+ Object.keys(eventTypes).forEach((eventType) => {
406
+ this.#setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, eventTypes[eventTypeAsPrimitiveConfigKey(eventType)]);
407
+ });
408
+ }
409
+ primitivePreventedFromCdkEvent(primitiveInstance, eventType) {
410
+ return this.primitiveConfigs?.get(primitiveInstance)?.[eventTypeAsPrimitiveConfigKey(eventType)];
411
+ }
412
+ addClickDomRootEventCallback(callback) {
413
+ this.#clickDomRootEventCallbacks.add(callback);
414
+ }
415
+ removeClickDomRootEventCallback(callback) {
416
+ return this.#clickDomRootEventCallbacks.delete(callback);
417
+ }
418
+ #setPreventPrimitiveFromCdkEvent(primitiveInstance, eventType, value) {
419
+ if (!this.primitiveConfigs?.has(primitiveInstance)) {
420
+ isDevMode() &&
421
+ console.error('[RdxCdkEventService.preventPrimitiveFromCdkEvent] RDX Primitive instance has not been registered!', primitiveInstance);
422
+ return;
423
+ }
424
+ switch (eventType) {
425
+ case 'cdkOverlayOutsideClick':
426
+ this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayOutsideClick = value;
427
+ break;
428
+ case 'cdkOverlayEscapeKeyDown':
429
+ this.primitiveConfigs.get(primitiveInstance).preventCdkOverlayEscapeKeyDown = value;
430
+ break;
431
+ }
432
+ }
433
+ #registerOnDestroyCallbacks() {
434
+ this.destroyRef.onDestroy(() => {
435
+ this.onDestroyCallbacks.forEach((onDestroyCallback) => onDestroyCallback());
436
+ this.onDestroyCallbacks.clear();
437
+ });
438
+ }
439
+ #listenToClickDomRootEvent() {
440
+ const target = this.document;
441
+ const eventName = 'click';
442
+ const options = { capture: true };
443
+ const callback = (event) => {
444
+ this.#clickDomRootEventCallbacks.forEach((clickDomRootEventCallback) => clickDomRootEventCallback(event));
445
+ };
446
+ const major = parseInt(VERSION.major);
447
+ const minor = parseInt(VERSION.minor);
448
+ let destroyClickDomRootEventListener;
449
+ /**
450
+ * @see src/cdk/platform/features/backwards-compatibility.ts in @angular/cdk
451
+ */
452
+ if (major > 19 || (major === 19 && minor > 0) || (major === 0 && minor === 0)) {
453
+ destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
454
+ const destroyClickDomRootEventListenerInternal = this.renderer2.listen(target, eventName, callback,
455
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
456
+ // @ts-expect-error
457
+ options);
458
+ return () => {
459
+ destroyClickDomRootEventListenerInternal();
460
+ this.#clickDomRootEventCallbacks.clear();
461
+ };
462
+ });
463
+ }
464
+ else {
465
+ /**
466
+ * This part can get removed when v19.1 or higher is on the board
467
+ */
468
+ destroyClickDomRootEventListener = this.ngZone.runOutsideAngular(() => {
469
+ target.addEventListener(eventName, callback, options);
470
+ return () => {
471
+ this.ngZone.runOutsideAngular(() => target.removeEventListener(eventName, callback, options));
472
+ this.#clickDomRootEventCallbacks.clear();
473
+ };
474
+ });
475
+ }
476
+ this.onDestroyCallbacks.add(destroyClickDomRootEventListener);
477
+ }
478
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
479
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService }); }
480
+ }
481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxCdkEventService, decorators: [{
482
+ type: Injectable
483
+ }], ctorParameters: () => [] });
484
+ const RdxCdkEventServiceToken = new InjectionToken('RdxCdkEventServiceToken');
485
+ const existsErrorMessage = 'RdxCdkEventService should be provided only once!';
486
+ const deleteRdxCdkEventServiceWindowKey = (window) => {
487
+ delete window[RdxCdkEventServiceWindowKey];
488
+ };
489
+ const getProvider = (throwWhenExists = true) => ({
490
+ provide: RdxCdkEventServiceToken,
491
+ useFactory: () => {
492
+ isDevMode() && console.log('providing RdxCdkEventService...');
493
+ const window = injectWindow();
494
+ if (window[RdxCdkEventServiceWindowKey]) {
495
+ if (throwWhenExists) {
496
+ throw Error(existsErrorMessage);
497
+ }
498
+ else {
499
+ isDevMode() && console.warn(existsErrorMessage);
500
+ }
501
+ }
502
+ window[RdxCdkEventServiceWindowKey] ??= new RdxCdkEventService();
503
+ return window[RdxCdkEventServiceWindowKey];
504
+ }
505
+ });
506
+ const provideRdxCdkEventServiceInRoot = () => makeEnvironmentProviders([getProvider()]);
507
+ const provideRdxCdkEventService = () => getProvider(false);
508
+ const injectRdxCdkEventService = () => inject(RdxCdkEventServiceToken, { optional: true });
509
+
510
+ let nextId = 0;
511
+ class RdxHoverCardRootDirective {
512
+ constructor() {
513
+ /** @ignore */
514
+ this.uniqueId = signal(++nextId);
515
+ /** @ignore */
516
+ this.name = computed(() => `rdx-hover-card-root-${this.uniqueId()}`);
517
+ /**
518
+ * @description The anchor directive that comes form outside the hover-card rootDirective
519
+ * @default undefined
520
+ */
521
+ this.anchor = input(void 0);
522
+ /**
523
+ * @description The open state of the hover-card when it is initially rendered. Use when you do not need to control its open state.
524
+ * @default false
525
+ */
526
+ this.defaultOpen = input(false, { transform: booleanAttribute });
527
+ /**
528
+ * @description The controlled state of the hover-card. `open` input take precedence of `defaultOpen` input.
529
+ * @default undefined
530
+ */
531
+ this.open = input(void 0, { transform: booleanAttribute });
532
+ /**
533
+ * To customise the open delay for a specific hover-card.
534
+ */
535
+ this.openDelay = input(500, {
536
+ transform: numberAttribute
537
+ });
538
+ /**
539
+ * To customise the close delay for a specific hover-card.
540
+ */
541
+ this.closeDelay = input(200, {
542
+ transform: numberAttribute
543
+ });
544
+ /**
545
+ * @description Whether to control the state of the hover-card from external. Use in conjunction with `open` input.
546
+ * @default undefined
547
+ */
548
+ this.externalControl = input(void 0, { transform: booleanAttribute });
549
+ /**
550
+ * @description Whether to take into account CSS opening/closing animations.
551
+ * @default false
552
+ */
553
+ this.cssAnimation = input(false, { transform: booleanAttribute });
554
+ /**
555
+ * @description Whether to take into account CSS opening animations. `cssAnimation` input must be set to 'true'
556
+ * @default false
557
+ */
558
+ this.cssOpeningAnimation = input(false, { transform: booleanAttribute });
559
+ /**
560
+ * @description Whether to take into account CSS closing animations. `cssAnimation` input must be set to 'true'
561
+ * @default false
562
+ */
563
+ this.cssClosingAnimation = input(false, { transform: booleanAttribute });
564
+ /** @ignore */
565
+ this.cssAnimationStatus = signal(null);
566
+ /** @ignore */
567
+ this.contentDirective = contentChild.required(RdxHoverCardContentDirective);
568
+ /** @ignore */
569
+ this.triggerDirective = contentChild.required(RdxHoverCardTriggerDirective);
570
+ /** @ignore */
571
+ this.arrowDirective = contentChild(RdxHoverCardArrowToken);
572
+ /** @ignore */
573
+ this.closeDirective = contentChild(RdxHoverCardCloseToken);
574
+ /** @ignore */
575
+ this.contentAttributesComponent = contentChild(RdxHoverCardContentAttributesToken);
576
+ /** @ignore */
577
+ this.internalAnchorDirective = contentChild(RdxHoverCardAnchorToken);
578
+ /** @ignore */
579
+ this.viewContainerRef = inject(ViewContainerRef);
580
+ /** @ignore */
581
+ this.rdxCdkEventService = injectRdxCdkEventService();
582
+ /** @ignore */
583
+ this.destroyRef = inject(DestroyRef);
584
+ /** @ignore */
585
+ this.state = signal(RdxHoverCardState.CLOSED);
586
+ /** @ignore */
587
+ this.attachDetachEvent = signal(RdxHoverCardAttachDetachEvent.DETACH);
588
+ /** @ignore */
589
+ this.isFirstDefaultOpen = signal(false);
590
+ /** @ignore */
591
+ this.anchorDirective = computed(() => this.internalAnchorDirective() ?? this.anchor());
592
+ /** @ignore */
593
+ this.actionSubject$ = new Subject();
594
+ /** @ignore */
595
+ this.onAnchorChangeEffect = () => {
596
+ effect(() => {
597
+ const anchor = this.anchor();
598
+ untracked(() => {
599
+ if (anchor) {
600
+ anchor.setRoot(this);
601
+ }
602
+ });
603
+ });
604
+ };
605
+ this.rdxCdkEventService?.registerPrimitive(this);
606
+ this.destroyRef.onDestroy(() => this.rdxCdkEventService?.deregisterPrimitive(this));
607
+ this.actionSubscription();
608
+ this.onStateChangeEffect();
609
+ this.onCssAnimationStatusChangeChangeEffect();
610
+ this.onOpenChangeEffect();
611
+ this.onIsFirstDefaultOpenChangeEffect();
612
+ this.onAnchorChangeEffect();
613
+ this.emitOpenOrClosedEventEffect();
614
+ afterNextRender({
615
+ write: () => {
616
+ if (this.defaultOpen() && !this.open()) {
617
+ this.isFirstDefaultOpen.set(true);
618
+ }
619
+ }
620
+ });
621
+ }
622
+ /** @ignore */
623
+ getAnimationParamsSnapshot() {
624
+ return {
625
+ cssAnimation: this.cssAnimation(),
626
+ cssOpeningAnimation: this.cssOpeningAnimation(),
627
+ cssClosingAnimation: this.cssClosingAnimation(),
628
+ cssAnimationStatus: this.cssAnimationStatus(),
629
+ attachDetachEvent: this.attachDetachEvent(),
630
+ state: this.state(),
631
+ canEmitOnOpenOrOnClosed: this.canEmitOnOpenOrOnClosed()
632
+ };
633
+ }
634
+ /** @ignore */
635
+ controlledExternally() {
636
+ return this.externalControl;
637
+ }
638
+ /** @ignore */
639
+ firstDefaultOpen() {
640
+ return this.isFirstDefaultOpen();
641
+ }
642
+ /** @ignore */
643
+ handleOpen() {
644
+ if (this.externalControl()) {
645
+ return;
646
+ }
647
+ this.actionSubject$.next(RdxHoverCardAction.OPEN);
648
+ }
649
+ /** @ignore */
650
+ handleClose(closeButton) {
651
+ if (this.isFirstDefaultOpen()) {
652
+ this.isFirstDefaultOpen.set(false);
653
+ }
654
+ if (!closeButton && this.externalControl()) {
655
+ return;
656
+ }
657
+ this.actionSubject$.next(RdxHoverCardAction.CLOSE);
658
+ }
659
+ /** @ignore */
660
+ handleToggle() {
661
+ if (this.externalControl()) {
662
+ return;
663
+ }
664
+ this.isOpen() ? this.handleClose() : this.handleOpen();
665
+ }
666
+ /** @ignore */
667
+ isOpen(state) {
668
+ return (state ?? this.state()) === RdxHoverCardState.OPEN;
669
+ }
670
+ /** @ignore */
671
+ setState(state = RdxHoverCardState.CLOSED) {
672
+ if (state === this.state()) {
673
+ return;
674
+ }
675
+ this.state.set(state);
676
+ }
677
+ /** @ignore */
678
+ openContent() {
679
+ this.contentDirective().open();
680
+ if (!this.cssAnimation() || !this.cssOpeningAnimation()) {
681
+ this.cssAnimationStatus.set(null);
682
+ }
683
+ }
684
+ /** @ignore */
685
+ closeContent() {
686
+ this.contentDirective().close();
687
+ if (!this.cssAnimation() || !this.cssClosingAnimation()) {
688
+ this.cssAnimationStatus.set(null);
689
+ }
690
+ }
691
+ /** @ignore */
692
+ emitOnOpen() {
693
+ this.contentDirective().onOpen.emit();
694
+ }
695
+ /** @ignore */
696
+ emitOnClosed() {
697
+ this.contentDirective().onClosed.emit();
698
+ }
699
+ /** @ignore */
700
+ ifOpenOrCloseWithoutAnimations(state) {
701
+ return (!this.contentAttributesComponent() ||
702
+ !this.cssAnimation() ||
703
+ (this.cssAnimation() && !this.cssClosingAnimation() && state === RdxHoverCardState.CLOSED) ||
704
+ (this.cssAnimation() && !this.cssOpeningAnimation() && state === RdxHoverCardState.OPEN) ||
705
+ // !this.cssAnimationStatus() ||
706
+ (this.cssOpeningAnimation() &&
707
+ state === RdxHoverCardState.OPEN &&
708
+ [RdxHoverCardAnimationStatus.OPEN_STARTED].includes(this.cssAnimationStatus())) ||
709
+ (this.cssClosingAnimation() &&
710
+ state === RdxHoverCardState.CLOSED &&
711
+ [RdxHoverCardAnimationStatus.CLOSED_STARTED].includes(this.cssAnimationStatus())));
712
+ }
713
+ /** @ignore */
714
+ ifOpenOrCloseWithAnimations(cssAnimationStatus) {
715
+ return (this.contentAttributesComponent() &&
716
+ this.cssAnimation() &&
717
+ cssAnimationStatus &&
718
+ ((this.cssOpeningAnimation() &&
719
+ this.state() === RdxHoverCardState.OPEN &&
720
+ [RdxHoverCardAnimationStatus.OPEN_ENDED].includes(cssAnimationStatus)) ||
721
+ (this.cssClosingAnimation() &&
722
+ this.state() === RdxHoverCardState.CLOSED &&
723
+ [RdxHoverCardAnimationStatus.CLOSED_ENDED].includes(cssAnimationStatus))));
724
+ }
725
+ /** @ignore */
726
+ openOrClose(state) {
727
+ const isOpen = this.isOpen(state);
728
+ isOpen ? this.openContent() : this.closeContent();
729
+ }
730
+ /** @ignore */
731
+ emitOnOpenOrOnClosed(state) {
732
+ this.isOpen(state)
733
+ ? this.attachDetachEvent() === RdxHoverCardAttachDetachEvent.ATTACH && this.emitOnOpen()
734
+ : this.attachDetachEvent() === RdxHoverCardAttachDetachEvent.DETACH && this.emitOnClosed();
735
+ }
736
+ /** @ignore */
737
+ canEmitOnOpenOrOnClosed() {
738
+ return (!this.cssAnimation() ||
739
+ (!this.cssOpeningAnimation() && this.state() === RdxHoverCardState.OPEN) ||
740
+ (this.cssOpeningAnimation() &&
741
+ this.state() === RdxHoverCardState.OPEN &&
742
+ this.cssAnimationStatus() === RdxHoverCardAnimationStatus.OPEN_ENDED) ||
743
+ (!this.cssClosingAnimation() && this.state() === RdxHoverCardState.CLOSED) ||
744
+ (this.cssClosingAnimation() &&
745
+ this.state() === RdxHoverCardState.CLOSED &&
746
+ this.cssAnimationStatus() === RdxHoverCardAnimationStatus.CLOSED_ENDED));
747
+ }
748
+ /** @ignore */
749
+ onStateChangeEffect() {
750
+ let isFirst = true;
751
+ effect(() => {
752
+ const state = this.state();
753
+ untracked(() => {
754
+ if (isFirst) {
755
+ isFirst = false;
756
+ return;
757
+ }
758
+ if (!this.ifOpenOrCloseWithoutAnimations(state)) {
759
+ return;
760
+ }
761
+ this.openOrClose(state);
762
+ });
763
+ }, {});
764
+ }
765
+ /** @ignore */
766
+ onCssAnimationStatusChangeChangeEffect() {
767
+ let isFirst = true;
768
+ effect(() => {
769
+ const cssAnimationStatus = this.cssAnimationStatus();
770
+ untracked(() => {
771
+ if (isFirst) {
772
+ isFirst = false;
773
+ return;
774
+ }
775
+ if (!this.ifOpenOrCloseWithAnimations(cssAnimationStatus)) {
776
+ return;
777
+ }
778
+ this.openOrClose(this.state());
779
+ });
780
+ });
781
+ }
782
+ /** @ignore */
783
+ emitOpenOrClosedEventEffect() {
784
+ let isFirst = true;
785
+ effect(() => {
786
+ this.attachDetachEvent();
787
+ this.cssAnimationStatus();
788
+ untracked(() => {
789
+ if (isFirst) {
790
+ isFirst = false;
791
+ return;
792
+ }
793
+ const canEmitOpenClose = untracked(() => this.canEmitOnOpenOrOnClosed());
794
+ if (!canEmitOpenClose) {
795
+ return;
796
+ }
797
+ this.emitOnOpenOrOnClosed(this.state());
798
+ });
799
+ });
800
+ }
801
+ /** @ignore */
802
+ onOpenChangeEffect() {
803
+ effect(() => {
804
+ const open = this.open();
805
+ untracked(() => {
806
+ this.setState(open ? RdxHoverCardState.OPEN : RdxHoverCardState.CLOSED);
807
+ });
808
+ });
809
+ }
810
+ /** @ignore */
811
+ onIsFirstDefaultOpenChangeEffect() {
812
+ const effectRef = effect(() => {
813
+ const defaultOpen = this.defaultOpen();
814
+ untracked(() => {
815
+ if (!defaultOpen || this.open()) {
816
+ effectRef.destroy();
817
+ return;
818
+ }
819
+ this.handleOpen();
820
+ });
821
+ });
822
+ }
823
+ /** @ignore */
824
+ actionSubscription() {
825
+ this.actionSubject$
826
+ .asObservable()
827
+ .pipe(map((action) => {
828
+ console.log(action);
829
+ switch (action) {
830
+ case RdxHoverCardAction.OPEN:
831
+ return { action, duration: this.openDelay() };
832
+ case RdxHoverCardAction.CLOSE:
833
+ return { action, duration: this.closeDelay() };
834
+ }
835
+ }), debounce((config) => timer(config.duration)), tap((config) => {
836
+ switch (config.action) {
837
+ case RdxHoverCardAction.OPEN:
838
+ this.setState(RdxHoverCardState.OPEN);
839
+ break;
840
+ case RdxHoverCardAction.CLOSE:
841
+ this.setState(RdxHoverCardState.CLOSED);
842
+ break;
843
+ }
844
+ }), takeUntilDestroyed())
845
+ .subscribe();
846
+ }
847
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
848
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.0.5", type: RdxHoverCardRootDirective, isStandalone: true, selector: "[rdxHoverCardRoot]", 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: RdxHoverCardContentDirective, descendants: true, isSignal: true }, { propertyName: "triggerDirective", first: true, predicate: RdxHoverCardTriggerDirective, descendants: true, isSignal: true }, { propertyName: "arrowDirective", first: true, predicate: RdxHoverCardArrowToken, descendants: true, isSignal: true }, { propertyName: "closeDirective", first: true, predicate: RdxHoverCardCloseToken, descendants: true, isSignal: true }, { propertyName: "contentAttributesComponent", first: true, predicate: RdxHoverCardContentAttributesToken, descendants: true, isSignal: true }, { propertyName: "internalAnchorDirective", first: true, predicate: RdxHoverCardAnchorToken, descendants: true, isSignal: true }], exportAs: ["rdxHoverCardRoot"], ngImport: i0 }); }
849
+ }
850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardRootDirective, decorators: [{
851
+ type: Directive,
852
+ args: [{
853
+ selector: '[rdxHoverCardRoot]',
854
+ exportAs: 'rdxHoverCardRoot'
855
+ }]
856
+ }], ctorParameters: () => [] });
857
+
858
+ function injectHoverCardRoot(optional = false) {
859
+ isDevMode() && assertInInjectionContext(injectHoverCardRoot);
860
+ return inject(RdxHoverCardRootDirective, { optional });
861
+ }
862
+
863
+ class RdxHoverCardAnchorDirective {
864
+ constructor() {
865
+ /**
866
+ * @ignore
867
+ * If outside the rootDirective then null, otherwise the rootDirective directive - with optional `true` passed in as the first param.
868
+ * If outside the rootDirective and non-null value that means the html structure is wrong - hover-card inside hover-card.
869
+ * */
870
+ this.rootDirective = injectHoverCardRoot(true);
871
+ /** @ignore */
872
+ this.elementRef = inject(ElementRef);
873
+ /** @ignore */
874
+ this.overlayOrigin = inject(CdkOverlayOrigin);
875
+ /** @ignore */
876
+ this.document = injectDocument();
877
+ /** @ignore */
878
+ this.name = computed(() => `rdx-hover-card-external-anchor-${this.rootDirective?.uniqueId()}`);
879
+ }
880
+ /** @ignore */
881
+ click() {
882
+ this.emitOutsideClick();
883
+ }
884
+ /** @ignore */
885
+ setRoot(root) {
886
+ this.rootDirective = root;
887
+ }
888
+ emitOutsideClick() {
889
+ if (!this.rootDirective?.isOpen() || this.rootDirective?.contentDirective().onOverlayOutsideClickDisabled()) {
890
+ return;
891
+ }
892
+ const clickEvent = new MouseEvent('click', {
893
+ view: this.document.defaultView,
894
+ bubbles: true,
895
+ cancelable: true,
896
+ relatedTarget: this.elementRef.nativeElement
897
+ });
898
+ this.rootDirective?.triggerDirective().elementRef.nativeElement.dispatchEvent(clickEvent);
899
+ }
900
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardAnchorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
901
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxHoverCardAnchorDirective, isStandalone: true, selector: "[rdxHoverCardAnchor]", host: { attributes: { "type": "button" }, listeners: { "click": "click()" }, properties: { "attr.id": "name()", "attr.aria-haspopup": "\"dialog\"" } }, providers: [
902
+ {
903
+ provide: RdxHoverCardAnchorToken,
904
+ useExisting: forwardRef(() => RdxHoverCardAnchorDirective)
905
+ }
906
+ ], exportAs: ["rdxHoverCardAnchor"], hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 }); }
907
+ }
908
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardAnchorDirective, decorators: [{
909
+ type: Directive,
910
+ args: [{
911
+ selector: '[rdxHoverCardAnchor]',
912
+ exportAs: 'rdxHoverCardAnchor',
913
+ hostDirectives: [CdkOverlayOrigin],
914
+ host: {
915
+ type: 'button',
916
+ '[attr.id]': 'name()',
917
+ '[attr.aria-haspopup]': '"dialog"',
918
+ '(click)': 'click()'
919
+ },
920
+ providers: [
921
+ {
922
+ provide: RdxHoverCardAnchorToken,
923
+ useExisting: forwardRef(() => RdxHoverCardAnchorDirective)
924
+ }
925
+ ]
926
+ }]
927
+ }] });
928
+
929
+ class RdxHoverCardArrowDirective {
930
+ constructor() {
931
+ /** @ignore */
932
+ this.renderer = inject(Renderer2);
933
+ /** @ignore */
934
+ this.rootDirective = injectHoverCardRoot();
935
+ /** @ignore */
936
+ this.elementRef = inject(ElementRef);
937
+ /**
938
+ * @description The width of the arrow in pixels.
939
+ * @default 10
940
+ */
941
+ this.width = input(RDX_POSITIONING_DEFAULTS.arrow.width, { transform: numberAttribute });
942
+ /**
943
+ * @description The height of the arrow in pixels.
944
+ * @default 5
945
+ */
946
+ this.height = input(RDX_POSITIONING_DEFAULTS.arrow.height, { transform: numberAttribute });
947
+ /** @ignore */
948
+ this.arrowSvgElement = computed(() => {
949
+ const width = this.width();
950
+ const height = this.height();
951
+ const svgElement = this.renderer.createElement('svg', 'svg');
952
+ this.renderer.setAttribute(svgElement, 'viewBox', '0 0 30 10');
953
+ this.renderer.setAttribute(svgElement, 'width', String(width));
954
+ this.renderer.setAttribute(svgElement, 'height', String(height));
955
+ const polygonElement = this.renderer.createElement('polygon', 'svg');
956
+ this.renderer.setAttribute(polygonElement, 'points', '0,0 30,0 15,10');
957
+ this.renderer.setAttribute(svgElement, 'preserveAspectRatio', 'none');
958
+ this.renderer.appendChild(svgElement, polygonElement);
959
+ return svgElement;
960
+ });
961
+ /** @ignore */
962
+ this.currentArrowSvgElement = signal(void 0);
963
+ /** @ignore */
964
+ this.position = toSignal(this.rootDirective.contentDirective().positionChange());
965
+ afterNextRender({
966
+ write: () => {
967
+ if (this.elementRef.nativeElement.parentElement) {
968
+ this.renderer.setStyle(this.elementRef.nativeElement.parentElement, 'position', 'relative');
969
+ }
970
+ this.renderer.setStyle(this.elementRef.nativeElement, 'position', 'absolute');
971
+ this.renderer.setStyle(this.elementRef.nativeElement, 'boxSizing', '');
972
+ this.renderer.setStyle(this.elementRef.nativeElement, 'fontSize', '0px');
973
+ }
974
+ });
975
+ this.onArrowSvgElementChangeEffect();
976
+ this.onContentPositionAndArrowDimensionsChangeEffect();
977
+ }
978
+ /** @ignore */
979
+ setAnchorOrTriggerRect() {
980
+ this.anchorOrTriggerRect = (this.rootDirective.anchorDirective() ?? this.rootDirective.triggerDirective()).elementRef.nativeElement.getBoundingClientRect();
981
+ }
982
+ /** @ignore */
983
+ setPosition(position, arrowDimensions) {
984
+ this.setAnchorOrTriggerRect();
985
+ const posParams = getArrowPositionParams(getSideAndAlignFromAllPossibleConnectedPositions(position.connectionPair), { width: arrowDimensions.width, height: arrowDimensions.height }, { width: this.anchorOrTriggerRect.width, height: this.anchorOrTriggerRect.height });
986
+ this.renderer.setStyle(this.elementRef.nativeElement, 'top', posParams.top);
987
+ this.renderer.setStyle(this.elementRef.nativeElement, 'bottom', '');
988
+ this.renderer.setStyle(this.elementRef.nativeElement, 'left', posParams.left);
989
+ this.renderer.setStyle(this.elementRef.nativeElement, 'right', '');
990
+ this.renderer.setStyle(this.elementRef.nativeElement, 'transform', posParams.transform);
991
+ this.renderer.setStyle(this.elementRef.nativeElement, 'transformOrigin', posParams.transformOrigin);
992
+ }
993
+ /** @ignore */
994
+ onArrowSvgElementChangeEffect() {
995
+ effect(() => {
996
+ const arrowElement = this.arrowSvgElement();
997
+ untracked(() => {
998
+ const currentArrowSvgElement = this.currentArrowSvgElement();
999
+ if (currentArrowSvgElement) {
1000
+ this.renderer.removeChild(this.elementRef.nativeElement, currentArrowSvgElement);
1001
+ }
1002
+ this.currentArrowSvgElement.set(arrowElement);
1003
+ this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.width()}px`);
1004
+ this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.height()}px`);
1005
+ this.renderer.appendChild(this.elementRef.nativeElement, this.currentArrowSvgElement());
1006
+ });
1007
+ });
1008
+ }
1009
+ /** @ignore */
1010
+ onContentPositionAndArrowDimensionsChangeEffect() {
1011
+ effect(() => {
1012
+ const position = this.position();
1013
+ const arrowDimensions = { width: this.width(), height: this.height() };
1014
+ untracked(() => {
1015
+ if (!position) {
1016
+ return;
1017
+ }
1018
+ this.setPosition(position, arrowDimensions);
1019
+ });
1020
+ });
1021
+ }
1022
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardArrowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1023
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.5", type: RdxHoverCardArrowDirective, isStandalone: true, selector: "[rdxHoverCardArrow]", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
1024
+ {
1025
+ provide: RdxHoverCardArrowToken,
1026
+ useExisting: forwardRef(() => RdxHoverCardArrowDirective)
1027
+ }
1028
+ ], ngImport: i0 }); }
1029
+ }
1030
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardArrowDirective, decorators: [{
1031
+ type: Directive,
1032
+ args: [{
1033
+ selector: '[rdxHoverCardArrow]',
1034
+ providers: [
1035
+ {
1036
+ provide: RdxHoverCardArrowToken,
1037
+ useExisting: forwardRef(() => RdxHoverCardArrowDirective)
1038
+ }
1039
+ ]
1040
+ }]
1041
+ }], ctorParameters: () => [] });
1042
+
1043
+ /**
1044
+ * TODO: to be removed? But it seems to be useful when controlled from outside
1045
+ */
1046
+ class RdxHoverCardCloseDirective {
1047
+ constructor() {
1048
+ /** @ignore */
1049
+ this.rootDirective = injectHoverCardRoot();
1050
+ /** @ignore */
1051
+ this.elementRef = inject(ElementRef);
1052
+ /** @ignore */
1053
+ this.renderer = inject(Renderer2);
1054
+ this.onIsControlledExternallyEffect();
1055
+ }
1056
+ /** @ignore */
1057
+ onIsControlledExternallyEffect() {
1058
+ effect(() => {
1059
+ const isControlledExternally = this.rootDirective.controlledExternally()();
1060
+ untracked(() => {
1061
+ this.renderer.setStyle(this.elementRef.nativeElement, 'display', isControlledExternally ? null : 'none');
1062
+ });
1063
+ });
1064
+ }
1065
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1066
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: RdxHoverCardCloseDirective, isStandalone: true, selector: "[rdxHoverCardClose]", host: { attributes: { "type": "button" }, listeners: { "click": "rootDirective.handleClose(true)" } }, providers: [
1067
+ {
1068
+ provide: RdxHoverCardCloseToken,
1069
+ useExisting: forwardRef(() => RdxHoverCardCloseDirective)
1070
+ }
1071
+ ], ngImport: i0 }); }
1072
+ }
1073
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardCloseDirective, decorators: [{
1074
+ type: Directive,
1075
+ args: [{
1076
+ selector: '[rdxHoverCardClose]',
1077
+ host: {
1078
+ type: 'button',
1079
+ '(click)': 'rootDirective.handleClose(true)'
1080
+ },
1081
+ providers: [
1082
+ {
1083
+ provide: RdxHoverCardCloseToken,
1084
+ useExisting: forwardRef(() => RdxHoverCardCloseDirective)
1085
+ }
1086
+ ]
1087
+ }]
1088
+ }], ctorParameters: () => [] });
1089
+
1090
+ class RdxHoverCardContentAttributesComponent {
1091
+ constructor() {
1092
+ /** @ignore */
1093
+ this.rootDirective = injectHoverCardRoot();
1094
+ /** @ignore */
1095
+ this.name = computed(() => `rdx-hover-card-content-attributes-${this.rootDirective.uniqueId()}`);
1096
+ /** @ignore */
1097
+ this.disableAnimation = computed(() => !this.canAnimate());
1098
+ }
1099
+ /** @ignore */
1100
+ onAnimationStart(_) {
1101
+ this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxHoverCardState.OPEN
1102
+ ? RdxHoverCardAnimationStatus.OPEN_STARTED
1103
+ : RdxHoverCardAnimationStatus.CLOSED_STARTED);
1104
+ }
1105
+ /** @ignore */
1106
+ onAnimationEnd(_) {
1107
+ this.rootDirective.cssAnimationStatus.set(this.rootDirective.state() === RdxHoverCardState.OPEN
1108
+ ? RdxHoverCardAnimationStatus.OPEN_ENDED
1109
+ : RdxHoverCardAnimationStatus.CLOSED_ENDED);
1110
+ }
1111
+ /** @ignore */
1112
+ pointerenter() {
1113
+ this.rootDirective.handleOpen();
1114
+ }
1115
+ /** @ignore */
1116
+ pointerleave() {
1117
+ this.rootDirective.handleClose();
1118
+ }
1119
+ /** @ignore */
1120
+ focus() {
1121
+ this.rootDirective.handleOpen();
1122
+ }
1123
+ /** @ignore */
1124
+ blur() {
1125
+ this.rootDirective.handleClose();
1126
+ }
1127
+ /** @ignore */
1128
+ canAnimate() {
1129
+ return (this.rootDirective.cssAnimation() &&
1130
+ ((this.rootDirective.cssOpeningAnimation() && this.rootDirective.state() === RdxHoverCardState.OPEN) ||
1131
+ (this.rootDirective.cssClosingAnimation() && this.rootDirective.state() === RdxHoverCardState.CLOSED)));
1132
+ }
1133
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardContentAttributesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1134
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: RdxHoverCardContentAttributesComponent, isStandalone: true, selector: "[rdxHoverCardContentAttributes]", 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: [
1135
+ {
1136
+ provide: RdxHoverCardContentAttributesToken,
1137
+ useExisting: forwardRef(() => RdxHoverCardContentAttributesComponent)
1138
+ }
1139
+ ], ngImport: i0, template: `
1140
+ <ng-content />
1141
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1142
+ }
1143
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardContentAttributesComponent, decorators: [{
1144
+ type: Component,
1145
+ args: [{
1146
+ selector: '[rdxHoverCardContentAttributes]',
1147
+ template: `
1148
+ <ng-content />
1149
+ `,
1150
+ host: {
1151
+ '[attr.role]': '"dialog"',
1152
+ '[attr.id]': 'name()',
1153
+ '[attr.data-state]': 'rootDirective.state()',
1154
+ '[attr.data-side]': 'rootDirective.contentDirective().side()',
1155
+ '[attr.data-align]': 'rootDirective.contentDirective().align()',
1156
+ '[style]': 'disableAnimation() ? {animation: "none !important"} : null',
1157
+ '(animationstart)': 'onAnimationStart($event)',
1158
+ '(animationend)': 'onAnimationEnd($event)',
1159
+ '(pointerenter)': 'pointerenter()',
1160
+ '(pointerleave)': 'pointerleave()',
1161
+ '(focus)': 'focus()',
1162
+ '(blur)': 'blur()'
1163
+ },
1164
+ providers: [
1165
+ {
1166
+ provide: RdxHoverCardContentAttributesToken,
1167
+ useExisting: forwardRef(() => RdxHoverCardContentAttributesComponent)
1168
+ }
1169
+ ],
1170
+ changeDetection: ChangeDetectionStrategy.OnPush
1171
+ }]
1172
+ }] });
1173
+
1174
+ const _imports = [
1175
+ RdxHoverCardArrowDirective,
1176
+ RdxHoverCardCloseDirective,
1177
+ RdxHoverCardContentDirective,
1178
+ RdxHoverCardTriggerDirective,
1179
+ RdxHoverCardRootDirective,
1180
+ RdxHoverCardAnchorDirective,
1181
+ RdxHoverCardContentAttributesComponent
1182
+ ];
1183
+ class RdxHoverCardModule {
1184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1185
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardModule, imports: [RdxHoverCardArrowDirective,
1186
+ RdxHoverCardCloseDirective,
1187
+ RdxHoverCardContentDirective,
1188
+ RdxHoverCardTriggerDirective,
1189
+ RdxHoverCardRootDirective,
1190
+ RdxHoverCardAnchorDirective,
1191
+ RdxHoverCardContentAttributesComponent], exports: [RdxHoverCardArrowDirective,
1192
+ RdxHoverCardCloseDirective,
1193
+ RdxHoverCardContentDirective,
1194
+ RdxHoverCardTriggerDirective,
1195
+ RdxHoverCardRootDirective,
1196
+ RdxHoverCardAnchorDirective,
1197
+ RdxHoverCardContentAttributesComponent] }); }
1198
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardModule }); }
1199
+ }
1200
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RdxHoverCardModule, decorators: [{
1201
+ type: NgModule,
1202
+ args: [{
1203
+ imports: [..._imports],
1204
+ exports: [..._imports]
1205
+ }]
1206
+ }] });
1207
+
1208
+ /**
1209
+ * Generated bundle index. Do not edit.
1210
+ */
1211
+
1212
+ export { RdxHoverCardAnchorDirective, RdxHoverCardArrowDirective, RdxHoverCardCloseDirective, RdxHoverCardContentAttributesComponent, RdxHoverCardContentDirective, RdxHoverCardModule, RdxHoverCardRootDirective, RdxHoverCardTriggerDirective };
1213
+ //# sourceMappingURL=radix-ng-primitives-hover-card.mjs.map