@radix-ng/primitives 0.50.0 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/collection/README.md +1 -0
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +134 -66
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +224 -132
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-arrow.mjs +26 -10
  7. package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +6 -6
  9. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-avatar.mjs +68 -75
  11. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-button.mjs +123 -0
  13. package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
  14. package/fesm2022/radix-ng-primitives-calendar.mjs +104 -103
  15. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-checkbox.mjs +414 -80
  17. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-collapsible.mjs +193 -92
  19. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-collection.mjs +72 -0
  21. package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -0
  22. package/fesm2022/radix-ng-primitives-config.mjs +5 -5
  23. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-context-menu.mjs +143 -427
  25. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-core.mjs +757 -757
  27. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-cropper.mjs +55 -53
  29. package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-date-field.mjs +93 -86
  31. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-dialog.mjs +658 -330
  33. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +98 -76
  35. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
  37. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
  38. package/fesm2022/radix-ng-primitives-editable.mjs +20 -20
  39. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-field.mjs +363 -0
  41. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
  42. package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
  43. package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
  44. package/fesm2022/radix-ng-primitives-focus-guards.mjs +3 -3
  45. package/fesm2022/radix-ng-primitives-focus-guards.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-focus-scope.mjs +29 -14
  47. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-input.mjs +172 -0
  49. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
  50. package/fesm2022/radix-ng-primitives-label.mjs +11 -11
  51. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-menu.mjs +1484 -353
  53. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
  55. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
  57. package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
  58. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1060 -1553
  59. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -366
  61. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-pagination.mjs +51 -51
  63. package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
  64. package/fesm2022/radix-ng-primitives-popover.mjs +980 -995
  65. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  66. package/fesm2022/radix-ng-primitives-popper.mjs +137 -82
  67. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  68. package/fesm2022/radix-ng-primitives-portal.mjs +40 -16
  69. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  70. package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
  71. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  72. package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
  73. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
  74. package/fesm2022/radix-ng-primitives-progress.mjs +231 -92
  75. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  76. package/fesm2022/radix-ng-primitives-radio.mjs +211 -70
  77. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  78. package/fesm2022/radix-ng-primitives-roving-focus.mjs +127 -77
  79. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  80. package/fesm2022/radix-ng-primitives-select.mjs +791 -511
  81. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  82. package/fesm2022/radix-ng-primitives-separator.mjs +16 -45
  83. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  84. package/fesm2022/radix-ng-primitives-slider.mjs +976 -720
  85. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  86. package/fesm2022/radix-ng-primitives-stepper.mjs +69 -71
  87. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  88. package/fesm2022/radix-ng-primitives-switch.mjs +128 -124
  89. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  90. package/fesm2022/radix-ng-primitives-tabs.mjs +388 -115
  91. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  92. package/fesm2022/radix-ng-primitives-time-field.mjs +111 -117
  93. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  94. package/fesm2022/radix-ng-primitives-toggle-group.mjs +122 -248
  95. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  96. package/fesm2022/radix-ng-primitives-toggle.mjs +99 -62
  97. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  98. package/fesm2022/radix-ng-primitives-toolbar.mjs +307 -94
  99. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  100. package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1079
  101. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  102. package/fesm2022/radix-ng-primitives-visually-hidden.mjs +46 -87
  103. package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
  104. package/fesm2022/radix-ng-primitives.mjs.map +1 -1
  105. package/meter/README.md +3 -0
  106. package/navigation-menu/README.md +2 -1
  107. package/package.json +85 -63
  108. package/portal/README.md +2 -0
  109. package/preview-card/README.md +3 -0
  110. package/schematics/collection.json +1 -0
  111. package/schematics/ng-add/index.d.ts +3 -2
  112. package/schematics/ng-add/index.js +62 -31
  113. package/schematics/ng-add/index.js.map +1 -1
  114. package/schematics/ng-add/package-config.d.ts +4 -2
  115. package/schematics/ng-add/package-config.js +10 -2
  116. package/schematics/ng-add/package-config.js.map +1 -1
  117. package/schematics/ng-add/schema.d.ts +3 -0
  118. package/schematics/ng-add/schema.js +3 -0
  119. package/schematics/ng-add/schema.js.map +1 -0
  120. package/schematics/ng-add/schema.json +14 -0
  121. package/select/README.md +2 -0
  122. package/{accordion/index.d.ts → types/radix-ng-primitives-accordion.d.ts} +102 -67
  123. package/types/radix-ng-primitives-alert-dialog.d.ts +114 -0
  124. package/{arrow/index.d.ts → types/radix-ng-primitives-arrow.d.ts} +1 -1
  125. package/{aspect-ratio/index.d.ts → types/radix-ng-primitives-aspect-ratio.d.ts} +1 -1
  126. package/{avatar/index.d.ts → types/radix-ng-primitives-avatar.d.ts} +7 -11
  127. package/types/radix-ng-primitives-button.d.ts +73 -0
  128. package/{calendar/index.d.ts → types/radix-ng-primitives-calendar.d.ts} +2 -3
  129. package/types/radix-ng-primitives-checkbox.d.ts +337 -0
  130. package/types/radix-ng-primitives-collapsible.d.ts +159 -0
  131. package/types/radix-ng-primitives-collection.d.ts +44 -0
  132. package/{config/index.d.ts → types/radix-ng-primitives-config.d.ts} +1 -1
  133. package/types/radix-ng-primitives-context-menu.d.ts +73 -0
  134. package/{core/index.d.ts → types/radix-ng-primitives-core.d.ts} +311 -236
  135. package/{cropper/index.d.ts → types/radix-ng-primitives-cropper.d.ts} +6 -5
  136. package/{date-field/index.d.ts → types/radix-ng-primitives-date-field.d.ts} +42 -27
  137. package/types/radix-ng-primitives-dialog.d.ts +323 -0
  138. package/{dismissable-layer/index.d.ts → types/radix-ng-primitives-dismissable-layer.d.ts} +15 -7
  139. package/types/radix-ng-primitives-drawer.d.ts +448 -0
  140. package/{editable/index.d.ts → types/radix-ng-primitives-editable.d.ts} +1 -1
  141. package/types/radix-ng-primitives-field.d.ts +373 -0
  142. package/types/radix-ng-primitives-fieldset.d.ts +48 -0
  143. package/{focus-scope/index.d.ts → types/radix-ng-primitives-focus-scope.d.ts} +13 -5
  144. package/types/radix-ng-primitives-input.d.ts +87 -0
  145. package/{label/index.d.ts → types/radix-ng-primitives-label.d.ts} +0 -1
  146. package/types/radix-ng-primitives-menu.d.ts +612 -0
  147. package/types/radix-ng-primitives-menubar.d.ts +66 -0
  148. package/types/radix-ng-primitives-meter.d.ts +193 -0
  149. package/types/radix-ng-primitives-navigation-menu.d.ts +488 -0
  150. package/types/radix-ng-primitives-number-field.d.ts +464 -0
  151. package/{pagination/index.d.ts → types/radix-ng-primitives-pagination.d.ts} +2 -2
  152. package/types/radix-ng-primitives-popover.d.ts +416 -0
  153. package/{popper/index.d.ts → types/radix-ng-primitives-popper.d.ts} +50 -9
  154. package/types/radix-ng-primitives-portal.d.ts +30 -0
  155. package/types/radix-ng-primitives-presence.d.ts +55 -0
  156. package/types/radix-ng-primitives-preview-card.d.ts +359 -0
  157. package/types/radix-ng-primitives-progress.d.ts +206 -0
  158. package/{radio/index.d.ts → types/radix-ng-primitives-radio.d.ts} +56 -26
  159. package/{roving-focus/index.d.ts → types/radix-ng-primitives-roving-focus.d.ts} +38 -27
  160. package/types/radix-ng-primitives-select.d.ts +512 -0
  161. package/types/radix-ng-primitives-separator.d.ts +38 -0
  162. package/types/radix-ng-primitives-slider.d.ts +377 -0
  163. package/{stepper/index.d.ts → types/radix-ng-primitives-stepper.d.ts} +21 -22
  164. package/types/radix-ng-primitives-switch.d.ts +121 -0
  165. package/types/radix-ng-primitives-tabs.d.ts +247 -0
  166. package/{time-field/index.d.ts → types/radix-ng-primitives-time-field.d.ts} +46 -31
  167. package/types/radix-ng-primitives-toggle-group.d.ts +116 -0
  168. package/types/radix-ng-primitives-toggle.d.ts +65 -0
  169. package/types/radix-ng-primitives-toolbar.d.ts +180 -0
  170. package/types/radix-ng-primitives-tooltip.d.ts +395 -0
  171. package/{visually-hidden/index.d.ts → types/radix-ng-primitives-visually-hidden.d.ts} +19 -19
  172. package/alert-dialog/index.d.ts +0 -57
  173. package/checkbox/index.d.ts +0 -164
  174. package/collapsible/index.d.ts +0 -85
  175. package/context-menu/index.d.ts +0 -129
  176. package/dialog/index.d.ts +0 -205
  177. package/dropdown-menu/README.md +0 -1
  178. package/dropdown-menu/index.d.ts +0 -171
  179. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -583
  180. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
  181. package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1246
  182. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
  183. package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -740
  184. package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
  185. package/hover-card/README.md +0 -3
  186. package/hover-card/index.d.ts +0 -472
  187. package/menu/index.d.ts +0 -139
  188. package/menubar/index.d.ts +0 -56
  189. package/navigation-menu/index.d.ts +0 -405
  190. package/number-field/index.d.ts +0 -203
  191. package/popover/index.d.ts +0 -403
  192. package/portal/index.d.ts +0 -22
  193. package/presence/index.d.ts +0 -103
  194. package/progress/index.d.ts +0 -79
  195. package/select/index.d.ts +0 -214
  196. package/separator/index.d.ts +0 -63
  197. package/slider/index.d.ts +0 -263
  198. package/switch/index.d.ts +0 -105
  199. package/tabs/index.d.ts +0 -112
  200. package/toggle/index.d.ts +0 -75
  201. package/toggle-group/index.d.ts +0 -194
  202. package/toolbar/index.d.ts +0 -55
  203. package/tooltip/index.d.ts +0 -433
  204. package/tooltip2/README.md +0 -3
  205. package/tooltip2/index.d.ts +0 -325
  206. /package/{focus-guards/index.d.ts → types/radix-ng-primitives-focus-guards.d.ts} +0 -0
  207. /package/{index.d.ts → types/radix-ng-primitives.d.ts} +0 -0
@@ -0,0 +1,997 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, DestroyRef, signal, model, input, booleanAttribute, output, computed, effect, untracked, Directive, ElementRef, numberAttribute, afterNextRender, NgModule } from '@angular/core';
3
+ import * as i1 from '@radix-ng/primitives/popper';
4
+ import { RdxPopper, RdxPopperContentWrapper, RdxPopperArrow, RdxPopperContent, provideRdxPopperContentConfig, RdxPopperAnchor } from '@radix-ng/primitives/popper';
5
+ import { createContext, useTransitionStatus, injectId, useGraceArea } from '@radix-ng/primitives/core';
6
+ import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
7
+ import * as i2 from '@radix-ng/primitives/dismissable-layer';
8
+ import { RdxDismissableLayer, provideRdxDismissableLayerConfig } from '@radix-ng/primitives/dismissable-layer';
9
+ import * as i1$1 from '@radix-ng/primitives/portal';
10
+ import { RdxPortal } from '@radix-ng/primitives/portal';
11
+ import * as i1$2 from '@radix-ng/primitives/presence';
12
+ import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence';
13
+
14
+ const context = () => contextFor(inject(RdxPreviewCardRoot));
15
+ const [injectRdxPreviewCardRootContext, provideRdxPreviewCardRootContext] = createContext('RdxPreviewCardRootContext');
16
+ /**
17
+ * Groups all parts of the preview-card.
18
+ */
19
+ class RdxPreviewCardRoot {
20
+ constructor() {
21
+ this.popper = inject(RdxPopper);
22
+ this.destroyRef = inject(DestroyRef);
23
+ /** Shared open/close transition state machine (completes on the real animationend). */
24
+ this.transition = useTransitionStatus((open) => {
25
+ this.instant.set(false);
26
+ this.onOpenChangeComplete.emit(open);
27
+ });
28
+ this.hasAppliedDefaultOpen = false;
29
+ this.hasAppliedDefaultTriggerId = false;
30
+ this.hoverDelay = 600;
31
+ this.hoverCloseDelay = 300;
32
+ this.isHoverActive = signal(false, ...(ngDevMode ? [{ debugName: "isHoverActive" }] : /* istanbul ignore next */ []));
33
+ this.instant = signal(false, ...(ngDevMode ? [{ debugName: "instant" }] : /* istanbul ignore next */ []));
34
+ this.openChangeReason = signal('none', ...(ngDevMode ? [{ debugName: "openChangeReason" }] : /* istanbul ignore next */ []));
35
+ this.transitionStatus = this.transition.status;
36
+ /**
37
+ * Whether the preview-card is currently open.
38
+ */
39
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
40
+ /**
41
+ * Whether the preview-card is initially open.
42
+ */
43
+ this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
44
+ /**
45
+ * ID of the trigger associated with a controlled preview-card.
46
+ */
47
+ this.triggerId = model(null, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
48
+ /**
49
+ * ID of the trigger associated with an initially open uncontrolled preview-card.
50
+ */
51
+ this.defaultTriggerId = input(null, ...(ngDevMode ? [{ debugName: "defaultTriggerId" }] : /* istanbul ignore next */ []));
52
+ /**
53
+ * Associates this root with detached trigger elements.
54
+ */
55
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
56
+ this.contentId = injectId('rdx-preview-card-content-');
57
+ this.trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
58
+ this.triggers = signal([], ...(ngDevMode ? [{ debugName: "triggers" }] : /* istanbul ignore next */ []));
59
+ this.payload = signal(undefined, ...(ngDevMode ? [{ debugName: "payload" }] : /* istanbul ignore next */ []));
60
+ this.isPointerDownOnTrigger = signal(false, ...(ngDevMode ? [{ debugName: "isPointerDownOnTrigger" }] : /* istanbul ignore next */ []));
61
+ this.onOpenChange = output();
62
+ this.onOpenChangeComplete = output();
63
+ this.registeredTriggers = new Map();
64
+ this.viewportTriggerChange = new Set();
65
+ this.state = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
66
+ let previousOpen = this.open();
67
+ effect(() => {
68
+ const defaultOpen = this.defaultOpen();
69
+ if (!this.hasAppliedDefaultOpen && defaultOpen) {
70
+ this.hasAppliedDefaultOpen = true;
71
+ this.open.set(defaultOpen);
72
+ }
73
+ });
74
+ effect(() => {
75
+ const defaultTriggerId = this.defaultTriggerId();
76
+ if (!this.hasAppliedDefaultTriggerId && defaultTriggerId !== null) {
77
+ this.hasAppliedDefaultTriggerId = true;
78
+ this.triggerId.set(defaultTriggerId);
79
+ }
80
+ });
81
+ effect(() => {
82
+ const triggerId = this.triggerId();
83
+ untracked(() => this.syncTriggerId(triggerId));
84
+ });
85
+ effect(() => {
86
+ const open = this.open();
87
+ if (open !== previousOpen) {
88
+ previousOpen = open;
89
+ untracked(() => this.transition.start(open));
90
+ }
91
+ });
92
+ effect((onCleanup) => {
93
+ const handle = this.handle();
94
+ if (handle) {
95
+ onCleanup(untracked(() => handle.registerRoot(contextFor(this))));
96
+ }
97
+ });
98
+ effect(() => this.popper.anchorOverride.set(this.trigger()));
99
+ this.destroyRef.onDestroy(() => {
100
+ this.clearHoverTimers();
101
+ if (this.instantFrame !== undefined) {
102
+ cancelAnimationFrame(this.instantFrame);
103
+ }
104
+ });
105
+ }
106
+ show(trigger = this.trigger(), payload, triggerId, reason = 'none', event = new Event('preview-card.open-change'), fromHover = false) {
107
+ this.clearHoverTimers();
108
+ this.isHoverActive.set(fromHover);
109
+ this.openChangeReason.set(reason);
110
+ const previousTrigger = this.trigger();
111
+ const changedTriggerWhileOpen = this.open() && previousTrigger !== trigger;
112
+ this.instant.set(changedTriggerWhileOpen || reason === 'trigger-focus');
113
+ if (changedTriggerWhileOpen) {
114
+ this.scheduleInstantReset();
115
+ }
116
+ if (trigger) {
117
+ if (previousTrigger && previousTrigger !== trigger) {
118
+ this.viewportTriggerChange.forEach((notify) => notify(previousTrigger, trigger));
119
+ }
120
+ this.trigger.set(trigger);
121
+ }
122
+ if (triggerId !== undefined) {
123
+ this.triggerId.set(triggerId);
124
+ }
125
+ this.payload.set(payload);
126
+ const changed = !this.open() || previousTrigger !== trigger;
127
+ this.open.set(true);
128
+ if (changed) {
129
+ this.emitOpenChange(true, reason, event);
130
+ }
131
+ }
132
+ close(reason = 'none', event = new Event('preview-card.open-change')) {
133
+ this.clearHoverTimers();
134
+ this.isHoverActive.set(false);
135
+ if (!this.open()) {
136
+ return;
137
+ }
138
+ this.instant.set(reason !== 'none' && reason !== 'trigger-hover');
139
+ this.openChangeReason.set(reason);
140
+ this.open.set(false);
141
+ this.emitOpenChange(false, reason, event);
142
+ }
143
+ toggle(triggerId, trigger, payload, event) {
144
+ this.clearHoverTimers();
145
+ if (this.open() && this.trigger() === trigger) {
146
+ this.close('trigger-press', event);
147
+ return;
148
+ }
149
+ this.show(trigger, payload, triggerId, 'trigger-press', event);
150
+ }
151
+ openWithDelay(trigger, payload, triggerId, reason, event) {
152
+ this.clearHoverTimers();
153
+ this.isHoverActive.set(true);
154
+ if (this.open()) {
155
+ this.show(trigger, payload, triggerId, reason, event, true);
156
+ return;
157
+ }
158
+ this.openTimer = setTimeout(() => this.show(trigger, payload, triggerId, reason, event, true), this.hoverDelay);
159
+ }
160
+ closeOnHover() {
161
+ if (!this.isHoverActive()) {
162
+ return;
163
+ }
164
+ this.clearOpenTimer();
165
+ this.clearCloseTimer();
166
+ this.closeTimer = setTimeout(() => this.close('trigger-hover', new Event('preview-card.hover-close')), this.hoverCloseDelay);
167
+ }
168
+ cancelHoverClose() {
169
+ this.clearCloseTimer();
170
+ }
171
+ cancelHoverOpen() {
172
+ this.clearOpenTimer();
173
+ }
174
+ setHoverDelays(delay, closeDelay) {
175
+ this.hoverDelay = delay;
176
+ this.hoverCloseDelay = closeDelay;
177
+ }
178
+ registerTrigger(id, trigger, payload) {
179
+ this.registeredTriggers.set(id, { element: trigger, payload });
180
+ this.triggers.update((triggers) => (triggers.includes(trigger) ? triggers : [...triggers, trigger]));
181
+ if (this.triggerId() === id) {
182
+ this.trigger.set(trigger);
183
+ this.payload.set(payload());
184
+ }
185
+ else if (!this.trigger() && this.triggerId() === null) {
186
+ this.trigger.set(trigger);
187
+ this.payload.set(payload());
188
+ }
189
+ return () => {
190
+ if (this.registeredTriggers.get(id)?.element === trigger) {
191
+ this.registeredTriggers.delete(id);
192
+ }
193
+ this.triggers.update((triggers) => triggers.filter((candidate) => candidate !== trigger));
194
+ if (this.destroyRef.destroyed) {
195
+ return;
196
+ }
197
+ if (this.trigger() === trigger) {
198
+ const next = this.registeredTriggers.entries().next().value;
199
+ if (this.triggerId() !== null) {
200
+ this.triggerId.set(next?.[0] ?? null);
201
+ }
202
+ this.trigger.set(next?.[1].element);
203
+ this.payload.set(next?.[1].payload());
204
+ if (!next && !this.destroyRef.destroyed) {
205
+ this.close();
206
+ }
207
+ }
208
+ };
209
+ }
210
+ registerViewport(onTriggerChange) {
211
+ this.viewportTriggerChange.add(onTriggerChange);
212
+ return () => this.viewportTriggerChange.delete(onTriggerChange);
213
+ }
214
+ registerTransitionElement(element) {
215
+ return this.transition.registerElement(element);
216
+ }
217
+ syncTriggerId(triggerId) {
218
+ if (triggerId === null) {
219
+ this.trigger.set(undefined);
220
+ this.payload.set(undefined);
221
+ return;
222
+ }
223
+ const trigger = this.registeredTriggers.get(triggerId);
224
+ if (!trigger) {
225
+ this.trigger.set(undefined);
226
+ this.payload.set(undefined);
227
+ return;
228
+ }
229
+ if (trigger.element === this.trigger()) {
230
+ return;
231
+ }
232
+ const previousTrigger = this.trigger();
233
+ if (previousTrigger && this.open()) {
234
+ this.viewportTriggerChange.forEach((notify) => notify(previousTrigger, trigger.element));
235
+ }
236
+ this.trigger.set(trigger.element);
237
+ this.payload.set(trigger.payload());
238
+ }
239
+ emitOpenChange(open, reason, event) {
240
+ this.onOpenChange.emit({
241
+ open,
242
+ triggerId: this.triggerId(),
243
+ trigger: this.trigger(),
244
+ reason,
245
+ event
246
+ });
247
+ }
248
+ clearHoverTimers() {
249
+ this.clearOpenTimer();
250
+ this.clearCloseTimer();
251
+ }
252
+ clearOpenTimer() {
253
+ if (this.openTimer !== undefined) {
254
+ clearTimeout(this.openTimer);
255
+ this.openTimer = undefined;
256
+ }
257
+ }
258
+ clearCloseTimer() {
259
+ if (this.closeTimer !== undefined) {
260
+ clearTimeout(this.closeTimer);
261
+ this.closeTimer = undefined;
262
+ }
263
+ }
264
+ scheduleInstantReset() {
265
+ if (this.instantFrame !== undefined) {
266
+ cancelAnimationFrame(this.instantFrame);
267
+ }
268
+ this.instantFrame = requestAnimationFrame(() => {
269
+ this.instantFrame = undefined;
270
+ if (!this.destroyRef.destroyed && this.open()) {
271
+ this.instant.set(false);
272
+ }
273
+ });
274
+ }
275
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
276
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPreviewCardRoot, isStandalone: true, selector: "[rdxPreviewCardRoot]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, triggerId: { classPropertyName: "triggerId", publicName: "triggerId", isSignal: true, isRequired: false, transformFunction: null }, defaultTriggerId: { classPropertyName: "defaultTriggerId", publicName: "defaultTriggerId", isSignal: true, isRequired: false, transformFunction: null }, handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", triggerId: "triggerIdChange", onOpenChange: "onOpenChange", onOpenChangeComplete: "onOpenChangeComplete" }, providers: [provideRdxPreviewCardRootContext(context)], exportAs: ["rdxPreviewCardRoot"], hostDirectives: [{ directive: i1.RdxPopper }], ngImport: i0 }); }
277
+ }
278
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardRoot, decorators: [{
279
+ type: Directive,
280
+ args: [{
281
+ selector: '[rdxPreviewCardRoot]',
282
+ exportAs: 'rdxPreviewCardRoot',
283
+ providers: [provideRdxPreviewCardRootContext(context)],
284
+ hostDirectives: [RdxPopper]
285
+ }]
286
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], triggerId: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerId", required: false }] }, { type: i0.Output, args: ["triggerIdChange"] }], defaultTriggerId: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTriggerId", required: false }] }], handle: [{ type: i0.Input, args: [{ isSignal: true, alias: "handle", required: false }] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
287
+ function contextFor(root) {
288
+ return {
289
+ contentId: root.contentId,
290
+ isOpen: root.open.asReadonly(),
291
+ trigger: root.trigger.asReadonly(),
292
+ triggers: root.triggers.asReadonly(),
293
+ payload: root.payload.asReadonly(),
294
+ isHoverActive: root.isHoverActive.asReadonly(),
295
+ instant: root.instant.asReadonly(),
296
+ openChangeReason: root.openChangeReason.asReadonly(),
297
+ isPointerDownOnTrigger: root.isPointerDownOnTrigger.asReadonly(),
298
+ close: (reason, event) => root.close(reason, event),
299
+ cancelHoverClose: () => root.cancelHoverClose(),
300
+ cancelHoverOpen: () => root.cancelHoverOpen(),
301
+ closeOnHover: () => root.closeOnHover(),
302
+ open: (trigger, payload, triggerId, reason, event) => root.show(trigger, payload, triggerId, reason, event),
303
+ openWithDelay: (trigger, payload, triggerId, reason, event) => root.openWithDelay(trigger, payload, triggerId, reason, event),
304
+ registerTrigger: (id, trigger, payload) => root.registerTrigger(id, trigger, payload),
305
+ setPointerDownOnTrigger: (pointerDown) => root.isPointerDownOnTrigger.set(pointerDown),
306
+ setHoverDelays: (delay, closeDelay) => root.setHoverDelays(delay, closeDelay),
307
+ registerTransitionElement: (element) => root.registerTransitionElement(element),
308
+ transitionStatus: root.transitionStatus,
309
+ registerViewport: (onTriggerChange) => root.registerViewport(onTriggerChange),
310
+ toggle: (triggerId, trigger, payload, event) => root.toggle(triggerId, trigger, payload, event)
311
+ };
312
+ }
313
+
314
+ /**
315
+ * An optional arrow element rendered alongside the preview-card.
316
+ */
317
+ class RdxPreviewCardArrow {
318
+ constructor() {
319
+ this.rootContext = injectRdxPreviewCardRootContext();
320
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
321
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
322
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
323
+ this.uncentered = computed(() => this.wrapper?.arrowUncentered() ?? false, ...(ngDevMode ? [{ debugName: "uncentered" }] : /* istanbul ignore next */ []));
324
+ }
325
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardArrow, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
326
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPreviewCardArrow, isStandalone: true, selector: "[rdxPreviewCardArrow]", host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-side": "side()", "attr.data-align": "align()", "attr.data-uncentered": "uncentered() ? \"\" : undefined" } }, hostDirectives: [{ directive: i1.RdxPopperArrow }], ngImport: i0 }); }
327
+ }
328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardArrow, decorators: [{
329
+ type: Directive,
330
+ args: [{
331
+ selector: '[rdxPreviewCardArrow]',
332
+ hostDirectives: [RdxPopperArrow],
333
+ host: {
334
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
335
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
336
+ '[attr.data-side]': 'side()',
337
+ '[attr.data-align]': 'align()',
338
+ '[attr.data-uncentered]': 'uncentered() ? "" : undefined'
339
+ }
340
+ }]
341
+ }] });
342
+
343
+ /**
344
+ * An optional backdrop rendered behind the popup.
345
+ */
346
+ class RdxPreviewCardBackdrop {
347
+ constructor() {
348
+ this.rootContext = injectRdxPreviewCardRootContext();
349
+ }
350
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
351
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPreviewCardBackdrop, isStandalone: true, selector: "[rdxPreviewCardBackdrop]", host: { properties: { "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"" } }, ngImport: i0 }); }
352
+ }
353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardBackdrop, decorators: [{
354
+ type: Directive,
355
+ args: [{
356
+ selector: '[rdxPreviewCardBackdrop]',
357
+ host: {
358
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
359
+ '[attr.data-ending-style]': 'rootContext.transitionStatus() === "ending" ? "" : undefined',
360
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
361
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
362
+ '[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
363
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"'
364
+ }
365
+ }]
366
+ }] });
367
+
368
+ /**
369
+ * A container for the preview-card contents.
370
+ */
371
+ class RdxPreviewCardPopup {
372
+ constructor() {
373
+ this.rootContext = injectRdxPreviewCardRootContext();
374
+ this.dismissableLayer = inject(RdxDismissableLayer);
375
+ this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
376
+ this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
377
+ this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
378
+ this.dismissDetails = {
379
+ reason: 'none',
380
+ event: new Event('preview-card.dismiss')
381
+ };
382
+ /**
383
+ * Event handler called when the escape key is down. Can be prevented.
384
+ */
385
+ this.escapeKeyDown = outputFromObservable(outputToObservable(this.dismissableLayer.escapeKeyDown));
386
+ /**
387
+ * Event handler called when a pointerdown event happens outside of the popup. Can be prevented.
388
+ */
389
+ this.pointerDownOutside = outputFromObservable(outputToObservable(this.dismissableLayer.pointerDownOutside));
390
+ /**
391
+ * Event handler called when focus moves outside of the popup. Can be prevented.
392
+ */
393
+ this.focusOutside = outputFromObservable(outputToObservable(this.dismissableLayer.focusOutside));
394
+ /**
395
+ * Event handler called when an interaction happens outside of the popup. Can be prevented.
396
+ */
397
+ this.interactOutside = outputFromObservable(outputToObservable(this.dismissableLayer.interactOutside));
398
+ const unregisterTransitionElement = this.rootContext.registerTransitionElement(inject(ElementRef).nativeElement);
399
+ inject(DestroyRef).onDestroy(() => {
400
+ unregisterTransitionElement();
401
+ });
402
+ this.dismissableLayer.pointerDownOutside.subscribe((event) => {
403
+ this.dismissDetails = { reason: 'outside-press', event };
404
+ if (this.rootContext.triggers().some((trigger) => trigger.contains(event.target))) {
405
+ event.preventDefault();
406
+ }
407
+ });
408
+ this.dismissableLayer.focusOutside.subscribe((event) => {
409
+ this.dismissDetails = { reason: 'none', event };
410
+ if (this.rootContext.isPointerDownOnTrigger()) {
411
+ event.preventDefault();
412
+ }
413
+ });
414
+ this.dismissableLayer.escapeKeyDown.subscribe((event) => {
415
+ this.dismissDetails = { reason: 'escape-key', event };
416
+ });
417
+ this.dismissableLayer.dismiss.subscribe(() => {
418
+ this.rootContext.close(this.dismissDetails.reason, this.dismissDetails.event);
419
+ this.dismissDetails = { reason: 'none', event: new Event('preview-card.dismiss') };
420
+ });
421
+ }
422
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
423
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPreviewCardPopup, isStandalone: true, selector: "[rdxPreviewCardPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside", interactOutside: "interactOutside" }, host: { listeners: { "pointerenter": "rootContext.cancelHoverClose()" }, properties: { "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"", "attr.data-align": "align()", "attr.data-side": "side()", "id": "rootContext.contentId" } }, providers: [
424
+ provideRdxDismissableLayerConfig(() => {
425
+ return {
426
+ disableOutsidePointerEvents: signal(false)
427
+ };
428
+ })
429
+ ], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxDismissableLayer }], ngImport: i0 }); }
430
+ }
431
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPopup, decorators: [{
432
+ type: Directive,
433
+ args: [{
434
+ selector: '[rdxPreviewCardPopup]',
435
+ hostDirectives: [RdxPopperContent, RdxDismissableLayer],
436
+ providers: [
437
+ provideRdxDismissableLayerConfig(() => {
438
+ return {
439
+ disableOutsidePointerEvents: signal(false)
440
+ };
441
+ })
442
+ ],
443
+ host: {
444
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
445
+ '[attr.data-ending-style]': 'rootContext.transitionStatus() === "ending" ? "" : undefined',
446
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
447
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
448
+ '[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
449
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"',
450
+ '[attr.data-align]': 'align()',
451
+ '[attr.data-side]': 'side()',
452
+ '[id]': 'rootContext.contentId',
453
+ '(pointerenter)': 'rootContext.cancelHoverClose()'
454
+ }
455
+ }]
456
+ }], ctorParameters: () => [], propDecorators: { escapeKeyDown: [{ type: i0.Output, args: ["escapeKeyDown"] }], pointerDownOutside: [{ type: i0.Output, args: ["pointerDownOutside"] }], focusOutside: [{ type: i0.Output, args: ["focusOutside"] }], interactOutside: [{ type: i0.Output, args: ["interactOutside"] }] } });
457
+
458
+ /**
459
+ * Moves the preview-card to a different part of the DOM.
460
+ */
461
+ class RdxPreviewCardPortal {
462
+ constructor() {
463
+ this.rootContext = injectRdxPreviewCardRootContext();
464
+ /**
465
+ * Optional container to portal the content into. Defaults to `document.body`.
466
+ */
467
+ this.container = input(...(ngDevMode ? [undefined, { debugName: "container" }] : /* istanbul ignore next */ []));
468
+ }
469
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
470
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPreviewCardPortal, isStandalone: true, selector: "[rdxPreviewCardPortal]", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"" } }, hostDirectives: [{ directive: i1$1.RdxPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
471
+ }
472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPortal, decorators: [{
473
+ type: Directive,
474
+ args: [{
475
+ selector: '[rdxPreviewCardPortal]',
476
+ hostDirectives: [
477
+ {
478
+ directive: RdxPortal,
479
+ inputs: ['container']
480
+ }
481
+ ],
482
+ host: {
483
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
484
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
485
+ '[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"'
486
+ }
487
+ }]
488
+ }], propDecorators: { container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: false }] }] } });
489
+
490
+ /**
491
+ * Mounts the portal while the preview-card is open and waits for CSS exit keyframes before unmounting.
492
+ */
493
+ class RdxPreviewCardPortalPresence {
494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPortalPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
495
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPreviewCardPortalPresence, isStandalone: true, selector: "ng-template[rdxPreviewCardPortalPresence]", providers: [
496
+ provideRdxPresenceContext(() => {
497
+ const context = injectRdxPreviewCardRootContext();
498
+ return { present: context.isOpen };
499
+ })
500
+ ], hostDirectives: [{ directive: i1$2.RdxPresenceDirective }], ngImport: i0 }); }
501
+ }
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPortalPresence, decorators: [{
503
+ type: Directive,
504
+ args: [{
505
+ selector: 'ng-template[rdxPreviewCardPortalPresence]',
506
+ hostDirectives: [RdxPresenceDirective],
507
+ providers: [
508
+ provideRdxPresenceContext(() => {
509
+ const context = injectRdxPreviewCardRootContext();
510
+ return { present: context.isOpen };
511
+ })
512
+ ]
513
+ }]
514
+ }] });
515
+
516
+ /**
517
+ * Positions the preview-card against its trigger.
518
+ */
519
+ class RdxPreviewCardPositioner {
520
+ constructor() {
521
+ this.rootContext = injectRdxPreviewCardRootContext();
522
+ this.wrapper = inject(RdxPopperContentWrapper);
523
+ this.elementRef = inject(ElementRef);
524
+ this.triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
525
+ this.containerEl = signal(this.elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "containerEl" }] : /* istanbul ignore next */ []));
526
+ this.graceArea = useGraceArea(this.triggerEl, this.containerEl);
527
+ /**
528
+ * An element to position the popup against. Defaults to the trigger.
529
+ */
530
+ this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
531
+ /**
532
+ * The preferred side of the trigger to render against when open.
533
+ */
534
+ this.side = input('bottom', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
535
+ /**
536
+ * Distance between the trigger and the popup in pixels.
537
+ */
538
+ this.sideOffset = input(0, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
539
+ /**
540
+ * How to align the popup relative to the specified side.
541
+ */
542
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
543
+ /**
544
+ * An offset in pixels from the `start` or `end` alignment options.
545
+ */
546
+ this.alignOffset = input(0, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
547
+ /**
548
+ * Minimum distance to maintain between the arrow and the edges of the popup.
549
+ */
550
+ this.arrowPadding = input(5, { ...(ngDevMode ? { debugName: "arrowPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
551
+ /**
552
+ * Whether to override side and alignment preferences to prevent collisions.
553
+ */
554
+ this.avoidCollisions = input(true, { ...(ngDevMode ? { debugName: "avoidCollisions" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
555
+ /**
556
+ * The element used as the collision boundary.
557
+ */
558
+ this.collisionBoundary = input(...(ngDevMode ? [undefined, { debugName: "collisionBoundary" }] : /* istanbul ignore next */ []));
559
+ /**
560
+ * Distance in pixels from the boundary edges where collision detection should occur.
561
+ */
562
+ this.collisionPadding = input(5, ...(ngDevMode ? [{ debugName: "collisionPadding" }] : /* istanbul ignore next */ []));
563
+ /**
564
+ * The sticky behavior on the alignment axis.
565
+ */
566
+ this.sticky = input('partial', ...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
567
+ /**
568
+ * Whether to hide the popup when the trigger becomes fully occluded.
569
+ */
570
+ this.hideWhenDetached = input(false, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
571
+ /**
572
+ * The CSS position strategy used by Floating UI.
573
+ */
574
+ this.positionStrategy = input('fixed', ...(ngDevMode ? [{ debugName: "positionStrategy" }] : /* istanbul ignore next */ []));
575
+ /**
576
+ * Whether to update position on every animation frame.
577
+ */
578
+ this.updatePositionStrategy = input('always', ...(ngDevMode ? [{ debugName: "updatePositionStrategy" }] : /* istanbul ignore next */ []));
579
+ /**
580
+ * Emits when the popup has been placed.
581
+ */
582
+ this.placed = outputFromObservable(outputToObservable(inject(RdxPopperContentWrapper).placed));
583
+ effect(() => this.triggerEl.set(this.rootContext.trigger() ?? null));
584
+ this.graceArea.onPointerExit(() => {
585
+ this.rootContext.closeOnHover();
586
+ });
587
+ }
588
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
589
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPreviewCardPositioner, isStandalone: true, selector: "[rdxPreviewCardPositioner]", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, alignOffset: { classPropertyName: "alignOffset", publicName: "alignOffset", isSignal: true, isRequired: false, transformFunction: null }, arrowPadding: { classPropertyName: "arrowPadding", publicName: "arrowPadding", isSignal: true, isRequired: false, transformFunction: null }, avoidCollisions: { classPropertyName: "avoidCollisions", publicName: "avoidCollisions", isSignal: true, isRequired: false, transformFunction: null }, collisionBoundary: { classPropertyName: "collisionBoundary", publicName: "collisionBoundary", isSignal: true, isRequired: false, transformFunction: null }, collisionPadding: { classPropertyName: "collisionPadding", publicName: "collisionPadding", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, hideWhenDetached: { classPropertyName: "hideWhenDetached", publicName: "hideWhenDetached", isSignal: true, isRequired: false, transformFunction: null }, positionStrategy: { classPropertyName: "positionStrategy", publicName: "positionStrategy", isSignal: true, isRequired: false, transformFunction: null }, updatePositionStrategy: { classPropertyName: "updatePositionStrategy", publicName: "updatePositionStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { placed: "placed" }, host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-anchor-hidden": "wrapper.anchorHidden() ? \"\" : undefined", "attr.data-align": "wrapper.placedAlign()", "attr.data-side": "wrapper.placedSide()", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "style": "{\n '--anchor-width': 'var(--radix-popper-anchor-width)',\n '--anchor-height': 'var(--radix-popper-anchor-height)',\n '--available-width': 'var(--radix-popper-available-width)',\n '--available-height': 'var(--radix-popper-available-height)',\n '--positioner-width': 'var(--radix-popper-content-wrapper-width)',\n '--positioner-height': 'var(--radix-popper-content-wrapper-height)',\n '--transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-preview-card-content-transform-origin': 'var(--radix-popper-transform-origin)',\n '--radix-preview-card-content-available-width': 'var(--radix-popper-available-width)',\n '--radix-preview-card-content-available-height': 'var(--radix-popper-available-height)',\n '--radix-preview-card-trigger-width': 'var(--radix-popper-anchor-width)',\n '--radix-preview-card-trigger-height': 'var(--radix-popper-anchor-height)'\n }" } }, providers: [
590
+ provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
591
+ ], hostDirectives: [{ directive: i1.RdxPopperContentWrapper, inputs: ["anchor", "anchor", "side", "side", "sideOffset", "sideOffset", "align", "align", "alignOffset", "alignOffset", "arrowPadding", "arrowPadding", "avoidCollisions", "avoidCollisions", "collisionBoundary", "collisionBoundary", "collisionPadding", "collisionPadding", "sticky", "sticky", "hideWhenDetached", "hideWhenDetached", "positionStrategy", "positionStrategy", "updatePositionStrategy", "updatePositionStrategy"] }], ngImport: i0 }); }
592
+ }
593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardPositioner, decorators: [{
594
+ type: Directive,
595
+ args: [{
596
+ selector: '[rdxPreviewCardPositioner]',
597
+ providers: [
598
+ provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
599
+ ],
600
+ hostDirectives: [
601
+ {
602
+ directive: RdxPopperContentWrapper,
603
+ inputs: [
604
+ 'anchor',
605
+ 'side',
606
+ 'sideOffset',
607
+ 'align',
608
+ 'alignOffset',
609
+ 'arrowPadding',
610
+ 'avoidCollisions',
611
+ 'collisionBoundary',
612
+ 'collisionPadding',
613
+ 'sticky',
614
+ 'hideWhenDetached',
615
+ 'positionStrategy',
616
+ 'updatePositionStrategy'
617
+ ]
618
+ }
619
+ ],
620
+ host: {
621
+ '[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
622
+ '[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
623
+ '[attr.data-anchor-hidden]': 'wrapper.anchorHidden() ? "" : undefined',
624
+ '[attr.data-align]': 'wrapper.placedAlign()',
625
+ '[attr.data-side]': 'wrapper.placedSide()',
626
+ '[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
627
+ '[style]': `{
628
+ '--anchor-width': 'var(--radix-popper-anchor-width)',
629
+ '--anchor-height': 'var(--radix-popper-anchor-height)',
630
+ '--available-width': 'var(--radix-popper-available-width)',
631
+ '--available-height': 'var(--radix-popper-available-height)',
632
+ '--positioner-width': 'var(--radix-popper-content-wrapper-width)',
633
+ '--positioner-height': 'var(--radix-popper-content-wrapper-height)',
634
+ '--transform-origin': 'var(--radix-popper-transform-origin)',
635
+ '--radix-preview-card-content-transform-origin': 'var(--radix-popper-transform-origin)',
636
+ '--radix-preview-card-content-available-width': 'var(--radix-popper-available-width)',
637
+ '--radix-preview-card-content-available-height': 'var(--radix-popper-available-height)',
638
+ '--radix-preview-card-trigger-width': 'var(--radix-popper-anchor-width)',
639
+ '--radix-preview-card-trigger-height': 'var(--radix-popper-anchor-height)'
640
+ }`
641
+ }
642
+ }]
643
+ }], ctorParameters: () => [], propDecorators: { anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], alignOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignOffset", required: false }] }], arrowPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowPadding", required: false }] }], avoidCollisions: [{ type: i0.Input, args: [{ isSignal: true, alias: "avoidCollisions", required: false }] }], collisionBoundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionBoundary", required: false }] }], collisionPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionPadding", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], hideWhenDetached: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideWhenDetached", required: false }] }], positionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionStrategy", required: false }] }], updatePositionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "updatePositionStrategy", required: false }] }], placed: [{ type: i0.Output, args: ["placed"] }] } });
644
+
645
+ /**
646
+ * A link or element that opens the preview card.
647
+ */
648
+ class RdxPreviewCardTrigger {
649
+ constructor() {
650
+ this.parentRootContext = injectRdxPreviewCardRootContext(true);
651
+ this.elementRef = inject(ElementRef);
652
+ /**
653
+ * Associates this trigger with a detached preview-card root.
654
+ */
655
+ this.handle = input(...(ngDevMode ? [undefined, { debugName: "handle" }] : /* istanbul ignore next */ []));
656
+ /**
657
+ * Data associated with this trigger while it is active.
658
+ */
659
+ this.payload = input(...(ngDevMode ? [undefined, { debugName: "payload" }] : /* istanbul ignore next */ []));
660
+ /**
661
+ * ID used to identify this trigger when opening a detached preview-card imperatively.
662
+ */
663
+ this.id = input(...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ []));
664
+ /**
665
+ * Whether the trigger should ignore user interaction.
666
+ */
667
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
668
+ /**
669
+ * How long to wait before opening the preview-card on hover, in milliseconds.
670
+ */
671
+ this.delay = input(600, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
672
+ /**
673
+ * How long to wait before closing a hover-opened preview-card, in milliseconds.
674
+ */
675
+ this.closeDelay = input(300, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
676
+ this.triggerId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
677
+ this.rootContext = computed(() => this.handle()?.context() ?? this.parentRootContext, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
678
+ this.isOpen = computed(() => this.rootContext()?.isOpen() === true && this.rootContext()?.trigger() === this.elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
679
+ this.isPressed = computed(() => this.isOpen() && this.rootContext()?.openChangeReason() === 'trigger-press', ...(ngDevMode ? [{ debugName: "isPressed" }] : /* istanbul ignore next */ []));
680
+ this.generatedId = injectId('rdx-preview-card-trigger-');
681
+ effect((onCleanup) => {
682
+ const handle = this.handle();
683
+ if (handle) {
684
+ onCleanup(untracked(() => handle.registerTrigger(this.triggerId(), this.elementRef.nativeElement, () => this.payload())));
685
+ }
686
+ else if (this.parentRootContext) {
687
+ onCleanup(untracked(() => this.parentRootContext.registerTrigger(this.triggerId(), this.elementRef.nativeElement, () => this.payload())));
688
+ }
689
+ });
690
+ }
691
+ handleClick(event) {
692
+ if (this.disabled()) {
693
+ return;
694
+ }
695
+ this.rootContext()?.setPointerDownOnTrigger(false);
696
+ this.rootContext()?.close('trigger-press', event);
697
+ }
698
+ handlePointerEnter(event) {
699
+ const rootContext = this.rootContext();
700
+ if (event.pointerType === 'touch' || !rootContext || this.disabled()) {
701
+ return;
702
+ }
703
+ rootContext.setHoverDelays(this.delay(), this.closeDelay());
704
+ rootContext.openWithDelay(this.elementRef.nativeElement, this.payload(), this.triggerId(), 'trigger-hover', event);
705
+ }
706
+ handlePointerLeave(event) {
707
+ if (event.pointerType === 'touch') {
708
+ return;
709
+ }
710
+ this.rootContext()?.cancelHoverOpen();
711
+ }
712
+ handleFocus(event) {
713
+ const rootContext = this.rootContext();
714
+ if (!rootContext || this.disabled()) {
715
+ return;
716
+ }
717
+ rootContext.setHoverDelays(this.delay(), this.closeDelay());
718
+ rootContext.openWithDelay(this.elementRef.nativeElement, this.payload(), this.triggerId(), 'trigger-focus', event);
719
+ }
720
+ handleBlur(event) {
721
+ this.rootContext()?.close('trigger-focus', event);
722
+ }
723
+ handlePointerDown() {
724
+ this.rootContext()?.setPointerDownOnTrigger(true);
725
+ }
726
+ handlePointerUp() {
727
+ this.rootContext()?.setPointerDownOnTrigger(false);
728
+ }
729
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
730
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxPreviewCardTrigger, isStandalone: true, selector: "[rdxPreviewCardTrigger]", inputs: { handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null }, payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "handleClick($event)", "pointerenter": "handlePointerEnter($event)", "pointerleave": "handlePointerLeave($event)", "focus": "handleFocus($event)", "blur": "handleBlur($event)", "pointerdown": "handlePointerDown()", "pointerup": "handlePointerUp()", "pointercancel": "handlePointerUp()" }, properties: { "attr.aria-controls": "rootContext()?.contentId", "attr.aria-disabled": "disabled() ? \"true\" : undefined", "attr.aria-expanded": "isOpen()", "attr.aria-haspopup": "\"dialog\"", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-state": "isOpen() ? \"open\" : \"closed\"", "attr.data-popup-open": "isOpen() ? \"\" : undefined", "attr.data-pressed": "isPressed() ? \"\" : undefined", "id": "triggerId()" } }, hostDirectives: [{ directive: i1.RdxPopperAnchor }], ngImport: i0 }); }
731
+ }
732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardTrigger, decorators: [{
733
+ type: Directive,
734
+ args: [{
735
+ selector: '[rdxPreviewCardTrigger]',
736
+ hostDirectives: [RdxPopperAnchor],
737
+ host: {
738
+ '[attr.aria-controls]': 'rootContext()?.contentId',
739
+ '[attr.aria-disabled]': 'disabled() ? "true" : undefined',
740
+ '[attr.aria-expanded]': 'isOpen()',
741
+ '[attr.aria-haspopup]': '"dialog"',
742
+ '[attr.data-disabled]': 'disabled() ? "" : undefined',
743
+ '[attr.data-state]': 'isOpen() ? "open" : "closed"',
744
+ '[attr.data-popup-open]': 'isOpen() ? "" : undefined',
745
+ '[attr.data-pressed]': 'isPressed() ? "" : undefined',
746
+ '[id]': 'triggerId()',
747
+ '(click)': 'handleClick($event)',
748
+ '(pointerenter)': 'handlePointerEnter($event)',
749
+ '(pointerleave)': 'handlePointerLeave($event)',
750
+ '(focus)': 'handleFocus($event)',
751
+ '(blur)': 'handleBlur($event)',
752
+ '(pointerdown)': 'handlePointerDown()',
753
+ '(pointerup)': 'handlePointerUp()',
754
+ '(pointercancel)': 'handlePointerUp()'
755
+ }
756
+ }]
757
+ }], ctorParameters: () => [], propDecorators: { handle: [{ type: i0.Input, args: [{ isSignal: true, alias: "handle", required: false }] }], payload: [{ type: i0.Input, args: [{ isSignal: true, alias: "payload", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }] } });
758
+
759
+ /**
760
+ * A viewport for animating content changes when a preview-card moves between triggers.
761
+ *
762
+ * Render one direct child inside the viewport. It is marked with `data-current`;
763
+ * when the active trigger changes, a DOM snapshot is retained as `data-previous`
764
+ * until its CSS animation or transition completes.
765
+ */
766
+ class RdxPreviewCardViewport {
767
+ constructor() {
768
+ this.rootContext = injectRdxPreviewCardRootContext();
769
+ this.elementRef = inject(ElementRef);
770
+ this.destroyRef = inject(DestroyRef);
771
+ this.activationDirection = signal(undefined, ...(ngDevMode ? [{ debugName: "activationDirection" }] : /* istanbul ignore next */ []));
772
+ this.transitioning = signal(false, ...(ngDevMode ? [{ debugName: "transitioning" }] : /* istanbul ignore next */ []));
773
+ const unregister = this.rootContext.registerViewport((previousTrigger, nextTrigger) => {
774
+ this.startTransition(previousTrigger, nextTrigger);
775
+ });
776
+ afterNextRender(() => {
777
+ this.markCurrent();
778
+ this.observer = new MutationObserver(() => this.markCurrent());
779
+ this.observer.observe(this.elementRef.nativeElement, { childList: true });
780
+ });
781
+ this.destroyRef.onDestroy(() => {
782
+ unregister();
783
+ this.observer?.disconnect();
784
+ this.cleanupPrevious();
785
+ });
786
+ }
787
+ startTransition(previousTrigger, nextTrigger) {
788
+ const current = this.current();
789
+ if (!current) {
790
+ return;
791
+ }
792
+ this.cleanupPrevious();
793
+ this.activationDirection.set(getActivationDirection(previousTrigger, nextTrigger));
794
+ const previous = current.cloneNode(true);
795
+ const popup = this.elementRef.nativeElement.closest('[rdxPreviewCardPopup]');
796
+ const popupRect = popup?.getBoundingClientRect();
797
+ previous.removeAttribute('data-current');
798
+ previous.setAttribute('data-previous', '');
799
+ previous.setAttribute('aria-hidden', 'true');
800
+ previous.setAttribute('inert', '');
801
+ removeIds(previous);
802
+ if (popupRect) {
803
+ previous.style.setProperty('--popup-width', `${popupRect.width}px`);
804
+ previous.style.setProperty('--popup-height', `${popupRect.height}px`);
805
+ }
806
+ previous.addEventListener('animationend', () => this.cleanupPrevious(), { once: true });
807
+ previous.addEventListener('transitionend', () => this.cleanupPrevious(), { once: true });
808
+ this.previous = previous;
809
+ this.elementRef.nativeElement.insertBefore(previous, current);
810
+ this.transitioning.set(true);
811
+ queueMicrotask(() => this.scheduleCleanup(previous));
812
+ }
813
+ markCurrent() {
814
+ this.current()?.setAttribute('data-current', '');
815
+ }
816
+ current() {
817
+ return Array.from(this.elementRef.nativeElement.children).find((child) => child instanceof HTMLElement && !child.hasAttribute('data-previous'));
818
+ }
819
+ scheduleCleanup(previous) {
820
+ if (this.previous !== previous) {
821
+ return;
822
+ }
823
+ const style = getComputedStyle(previous);
824
+ const duration = Math.max(getMaxDuration(style.animationDuration, style.animationDelay), getMaxDuration(style.transitionDuration, style.transitionDelay));
825
+ this.cleanupTimer = setTimeout(() => this.cleanupPrevious(), duration > 0 ? duration + 50 : 0);
826
+ }
827
+ cleanupPrevious() {
828
+ if (this.cleanupTimer !== undefined) {
829
+ clearTimeout(this.cleanupTimer);
830
+ this.cleanupTimer = undefined;
831
+ }
832
+ this.previous?.remove();
833
+ this.previous = undefined;
834
+ this.transitioning.set(false);
835
+ }
836
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardViewport, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
837
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxPreviewCardViewport, isStandalone: true, selector: "[rdxPreviewCardViewport]", host: { properties: { "attr.data-activation-direction": "activationDirection()", "attr.data-transitioning": "transitioning() ? \"\" : undefined" } }, ngImport: i0 }); }
838
+ }
839
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardViewport, decorators: [{
840
+ type: Directive,
841
+ args: [{
842
+ selector: '[rdxPreviewCardViewport]',
843
+ host: {
844
+ '[attr.data-activation-direction]': 'activationDirection()',
845
+ '[attr.data-transitioning]': 'transitioning() ? "" : undefined'
846
+ }
847
+ }]
848
+ }], ctorParameters: () => [] });
849
+ function getActivationDirection(previous, next) {
850
+ const previousRect = previous.getBoundingClientRect();
851
+ const nextRect = next.getBoundingClientRect();
852
+ const previousCenter = getCenter(previousRect);
853
+ const nextCenter = getCenter(nextRect);
854
+ const directions = [];
855
+ if (nextCenter.x < previousCenter.x) {
856
+ directions.push('left');
857
+ }
858
+ else if (nextCenter.x > previousCenter.x) {
859
+ directions.push('right');
860
+ }
861
+ if (nextCenter.y < previousCenter.y) {
862
+ directions.push('up');
863
+ }
864
+ else if (nextCenter.y > previousCenter.y) {
865
+ directions.push('down');
866
+ }
867
+ return directions.join(' ') || undefined;
868
+ }
869
+ function removeIds(element) {
870
+ element.removeAttribute('id');
871
+ element.querySelectorAll('[id]').forEach((child) => child.removeAttribute('id'));
872
+ }
873
+ function getCenter(rect) {
874
+ return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
875
+ }
876
+ function getMaxDuration(durations, delays) {
877
+ const durationValues = durations.split(',').map(parseDuration);
878
+ const delayValues = delays.split(',').map(parseDuration);
879
+ return durationValues.reduce((max, duration, index) => {
880
+ const delay = delayValues[index % delayValues.length] ?? 0;
881
+ return Math.max(max, duration + delay);
882
+ }, 0);
883
+ }
884
+ function parseDuration(value) {
885
+ const duration = Number.parseFloat(value);
886
+ if (Number.isNaN(duration)) {
887
+ return 0;
888
+ }
889
+ return value.trim().endsWith('ms') ? duration : duration * 1000;
890
+ }
891
+
892
+ class RdxPreviewCardHandle {
893
+ constructor() {
894
+ this.rootContext = signal(undefined, ...(ngDevMode ? [{ debugName: "rootContext" }] : /* istanbul ignore next */ []));
895
+ this.triggers = new Map();
896
+ this.rootTriggerCleanups = new Map();
897
+ this.isOpen = computed(() => this.rootContext()?.isOpen() ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
898
+ }
899
+ open(triggerId) {
900
+ const trigger = this.triggers.get(triggerId);
901
+ if (!trigger) {
902
+ throw new Error(`No preview-card trigger registered with id "${triggerId}".`);
903
+ }
904
+ this.rootContext()?.open(trigger.element, trigger.payload(), triggerId, 'imperative-action', new Event('preview-card.open'));
905
+ }
906
+ close() {
907
+ this.rootContext()?.close('imperative-action', new Event('preview-card.close'));
908
+ }
909
+ toggle(triggerId, event = new Event('preview-card.toggle')) {
910
+ const trigger = this.triggers.get(triggerId);
911
+ if (!trigger) {
912
+ throw new Error(`No preview-card trigger registered with id "${triggerId}".`);
913
+ }
914
+ this.rootContext()?.toggle(triggerId, trigger.element, trigger.payload(), event);
915
+ }
916
+ registerRoot(rootContext) {
917
+ this.rootContext.set(rootContext);
918
+ this.triggers.forEach((trigger, id) => {
919
+ this.rootTriggerCleanups.set(id, rootContext.registerTrigger(id, trigger.element, trigger.payload));
920
+ });
921
+ return () => {
922
+ if (this.rootContext() === rootContext) {
923
+ this.rootTriggerCleanups.forEach((cleanup) => cleanup());
924
+ this.rootTriggerCleanups.clear();
925
+ this.rootContext.set(undefined);
926
+ }
927
+ };
928
+ }
929
+ registerTrigger(id, trigger, payload) {
930
+ this.rootTriggerCleanups.get(id)?.();
931
+ this.triggers.set(id, { element: trigger, payload });
932
+ const unregisterFromRoot = this.rootContext()?.registerTrigger(id, trigger, payload);
933
+ if (unregisterFromRoot) {
934
+ this.rootTriggerCleanups.set(id, unregisterFromRoot);
935
+ }
936
+ return () => {
937
+ this.rootTriggerCleanups.get(id)?.();
938
+ this.rootTriggerCleanups.delete(id);
939
+ if (this.triggers.get(id)?.element === trigger) {
940
+ this.triggers.delete(id);
941
+ }
942
+ };
943
+ }
944
+ context() {
945
+ return this.rootContext();
946
+ }
947
+ }
948
+ function createRdxPreviewCardHandle() {
949
+ return new RdxPreviewCardHandle();
950
+ }
951
+
952
+ const previewCardImports = [
953
+ RdxPreviewCardRoot,
954
+ RdxPreviewCardTrigger,
955
+ RdxPreviewCardPortalPresence,
956
+ RdxPreviewCardPortal,
957
+ RdxPreviewCardBackdrop,
958
+ RdxPreviewCardPositioner,
959
+ RdxPreviewCardPopup,
960
+ RdxPreviewCardArrow,
961
+ RdxPreviewCardViewport
962
+ ];
963
+ class RdxPreviewCardModule {
964
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
965
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardModule, imports: [RdxPreviewCardRoot,
966
+ RdxPreviewCardTrigger,
967
+ RdxPreviewCardPortalPresence,
968
+ RdxPreviewCardPortal,
969
+ RdxPreviewCardBackdrop,
970
+ RdxPreviewCardPositioner,
971
+ RdxPreviewCardPopup,
972
+ RdxPreviewCardArrow,
973
+ RdxPreviewCardViewport], exports: [RdxPreviewCardRoot,
974
+ RdxPreviewCardTrigger,
975
+ RdxPreviewCardPortalPresence,
976
+ RdxPreviewCardPortal,
977
+ RdxPreviewCardBackdrop,
978
+ RdxPreviewCardPositioner,
979
+ RdxPreviewCardPopup,
980
+ RdxPreviewCardArrow,
981
+ RdxPreviewCardViewport] }); }
982
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardModule }); }
983
+ }
984
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxPreviewCardModule, decorators: [{
985
+ type: NgModule,
986
+ args: [{
987
+ imports: [...previewCardImports],
988
+ exports: [...previewCardImports]
989
+ }]
990
+ }] });
991
+
992
+ /**
993
+ * Generated bundle index. Do not edit.
994
+ */
995
+
996
+ export { RdxPreviewCardArrow, RdxPreviewCardBackdrop, RdxPreviewCardHandle, RdxPreviewCardModule, RdxPreviewCardPopup, RdxPreviewCardPortal, RdxPreviewCardPortalPresence, RdxPreviewCardPositioner, RdxPreviewCardRoot, RdxPreviewCardTrigger, RdxPreviewCardViewport, createRdxPreviewCardHandle, injectRdxPreviewCardRootContext, previewCardImports, provideRdxPreviewCardRootContext };
997
+ //# sourceMappingURL=radix-ng-primitives-preview-card.mjs.map