@raintonic/formaui 0.3.1 → 0.9.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 (238) hide show
  1. package/CHANGELOG.md +80 -35
  2. package/README.md +22 -26
  3. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs +39 -41
  4. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -1
  5. package/fesm2022/raintonic-formaui-cdk-form-field.mjs +207 -3
  6. package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -1
  7. package/fesm2022/raintonic-formaui-cdk-overlay.mjs +27 -2
  8. package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -1
  9. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +5 -12
  10. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -1
  11. package/fesm2022/raintonic-formaui-components-accordion.mjs +8 -5
  12. package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -1
  13. package/fesm2022/raintonic-formaui-components-alert.mjs +16 -2
  14. package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -1
  15. package/fesm2022/raintonic-formaui-components-autocomplete.mjs +255 -462
  16. package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -1
  17. package/fesm2022/raintonic-formaui-components-avatar.mjs +34 -59
  18. package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -1
  19. package/fesm2022/raintonic-formaui-components-badge.mjs +2 -2
  20. package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -1
  21. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +4 -4
  22. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -1
  23. package/fesm2022/raintonic-formaui-components-button-group.mjs +2 -2
  24. package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -1
  25. package/fesm2022/raintonic-formaui-components-button.mjs +15 -20
  26. package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -1
  27. package/fesm2022/raintonic-formaui-components-card.mjs +2 -2
  28. package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -1
  29. package/fesm2022/raintonic-formaui-components-checkbox.mjs +2 -2
  30. package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -1
  31. package/fesm2022/raintonic-formaui-components-chip.mjs +97 -0
  32. package/fesm2022/raintonic-formaui-components-chip.mjs.map +1 -0
  33. package/fesm2022/raintonic-formaui-components-data-table.mjs +69 -29
  34. package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -1
  35. package/fesm2022/raintonic-formaui-components-date-picker.mjs +223 -144
  36. package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -1
  37. package/fesm2022/raintonic-formaui-components-divider.mjs +2 -2
  38. package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -1
  39. package/fesm2022/raintonic-formaui-components-drawer.mjs +2 -2
  40. package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -1
  41. package/fesm2022/raintonic-formaui-components-dropdown-menu.mjs +888 -0
  42. package/fesm2022/raintonic-formaui-components-dropdown-menu.mjs.map +1 -0
  43. package/fesm2022/raintonic-formaui-components-dual-tier-navigation.mjs +774 -0
  44. package/fesm2022/raintonic-formaui-components-dual-tier-navigation.mjs.map +1 -0
  45. package/fesm2022/raintonic-formaui-components-empty-state.mjs +2 -2
  46. package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -1
  47. package/fesm2022/raintonic-formaui-components-file-upload.mjs +2 -2
  48. package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -1
  49. package/fesm2022/raintonic-formaui-components-form-field.mjs +81 -50
  50. package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -1
  51. package/fesm2022/raintonic-formaui-components-icon.mjs +2 -2
  52. package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -1
  53. package/fesm2022/raintonic-formaui-components-input.mjs +47 -12
  54. package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -1
  55. package/fesm2022/raintonic-formaui-components-list.mjs +4 -4
  56. package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -1
  57. package/fesm2022/raintonic-formaui-components-number-input.mjs +20 -12
  58. package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -1
  59. package/fesm2022/raintonic-formaui-components-paginator.mjs +2 -2
  60. package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -1
  61. package/fesm2022/raintonic-formaui-components-password-input.mjs +35 -110
  62. package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -1
  63. package/fesm2022/raintonic-formaui-components-popover.mjs +3 -2
  64. package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -1
  65. package/fesm2022/raintonic-formaui-components-progressbar.mjs +3 -2
  66. package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -1
  67. package/fesm2022/raintonic-formaui-components-radio.mjs +5 -6
  68. package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -1
  69. package/fesm2022/raintonic-formaui-components-select.mjs +257 -412
  70. package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -1
  71. package/fesm2022/raintonic-formaui-components-side-panel.mjs +2 -2
  72. package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -1
  73. package/fesm2022/raintonic-formaui-components-sidebar-nav-menu.mjs +525 -0
  74. package/fesm2022/raintonic-formaui-components-sidebar-nav-menu.mjs.map +1 -0
  75. package/fesm2022/raintonic-formaui-components-skeleton.mjs +2 -2
  76. package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -1
  77. package/fesm2022/raintonic-formaui-components-slider.mjs +2 -2
  78. package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -1
  79. package/fesm2022/raintonic-formaui-components-spinner.mjs +2 -2
  80. package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -1
  81. package/fesm2022/raintonic-formaui-components-stepper.mjs +50 -45
  82. package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -1
  83. package/fesm2022/raintonic-formaui-components-strength-meter.mjs +149 -0
  84. package/fesm2022/raintonic-formaui-components-strength-meter.mjs.map +1 -0
  85. package/fesm2022/raintonic-formaui-components-tab.mjs +2 -2
  86. package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -1
  87. package/fesm2022/raintonic-formaui-components-time-picker.mjs +194 -154
  88. package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -1
  89. package/fesm2022/raintonic-formaui-components-toggle-group.mjs +302 -0
  90. package/fesm2022/raintonic-formaui-components-toggle-group.mjs.map +1 -0
  91. package/fesm2022/raintonic-formaui-components-toggle.mjs +2 -2
  92. package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -1
  93. package/fesm2022/raintonic-formaui-components-toolbar.mjs +2 -2
  94. package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -1
  95. package/fesm2022/raintonic-formaui-components-tooltip.mjs +10 -4
  96. package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -1
  97. package/fesm2022/raintonic-formaui-components-topbar.mjs +60 -0
  98. package/fesm2022/raintonic-formaui-components-topbar.mjs.map +1 -0
  99. package/fesm2022/raintonic-formaui-components-tree-select.mjs +59 -69
  100. package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -1
  101. package/fesm2022/raintonic-formaui-components-tree-table.mjs +2 -2
  102. package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -1
  103. package/fesm2022/raintonic-formaui-components-tree.mjs +31 -5
  104. package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -1
  105. package/fesm2022/raintonic-formaui-core.mjs +279 -1
  106. package/fesm2022/raintonic-formaui-core.mjs.map +1 -1
  107. package/fesm2022/raintonic-formaui-services-breakpoint.mjs +93 -0
  108. package/fesm2022/raintonic-formaui-services-breakpoint.mjs.map +1 -0
  109. package/fesm2022/raintonic-formaui-services-dialog.mjs +314 -16
  110. package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -1
  111. package/fesm2022/raintonic-formaui-services-notification.mjs +93 -29
  112. package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -1
  113. package/fesm2022/raintonic-formaui-services-theme.mjs +46 -196
  114. package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -1
  115. package/fesm2022/raintonic-formaui.mjs +1 -1
  116. package/fesm2022/raintonic-formaui.mjs.map +1 -1
  117. package/llms-full.txt +2329 -450
  118. package/llms.txt +36 -33
  119. package/package.json +42 -19
  120. package/styles/fonts/Geist-Bold.woff2 +0 -0
  121. package/styles/fonts/Geist-Italic.woff2 +0 -0
  122. package/styles/fonts/Geist-Light.woff2 +0 -0
  123. package/styles/fonts/Geist-Medium.woff2 +0 -0
  124. package/styles/fonts/Geist-Regular.woff2 +0 -0
  125. package/styles/fonts/Geist-SemiBold.woff2 +0 -0
  126. package/styles/fonts/GeistMono-Regular.woff2 +0 -0
  127. package/styles/generated/_tokens.scss +906 -0
  128. package/styles/index.scss +11 -10
  129. package/styles/partials/_brand.scss +46 -0
  130. package/styles/partials/_constants.scss +22 -20
  131. package/styles/partials/_fonts.scss +54 -10
  132. package/styles/partials/_grid.scss +29 -18
  133. package/styles/partials/_mixins.scss +69 -27
  134. package/styles/partials/_motion.scss +28 -33
  135. package/styles/partials/_theme.scss +28 -255
  136. package/styles/partials/_type.scss +117 -0
  137. package/styles/partials/_typography.scss +45 -45
  138. package/styles/partials/_utilities.scss +198 -98
  139. package/styles/partials/components/_button.scss +144 -75
  140. package/styles/partials/components/_dialog.scss +181 -180
  141. package/styles/partials/components/_overlay.scss +87 -87
  142. package/styles/partials/themes/_dark.scss +3 -268
  143. package/styles/partials/themes/_light.scss +4 -268
  144. package/styles/styles.css +7744 -0
  145. package/styles/styles.entry.scss +3 -0
  146. package/styles/utilities.css +4802 -0
  147. package/styles/utilities.entry.scss +3 -0
  148. package/types/raintonic-formaui-cdk-drag-drop.d.ts +0 -1
  149. package/types/raintonic-formaui-cdk-drag-drop.d.ts.map +1 -1
  150. package/types/raintonic-formaui-cdk-form-field.d.ts +118 -2
  151. package/types/raintonic-formaui-cdk-form-field.d.ts.map +1 -1
  152. package/types/raintonic-formaui-cdk-overlay.d.ts +2 -0
  153. package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -1
  154. package/types/raintonic-formaui-cdk-virtual-scroll.d.ts +0 -1
  155. package/types/raintonic-formaui-cdk-virtual-scroll.d.ts.map +1 -1
  156. package/types/raintonic-formaui-components-accordion.d.ts +1 -1
  157. package/types/raintonic-formaui-components-accordion.d.ts.map +1 -1
  158. package/types/raintonic-formaui-components-alert.d.ts +6 -1
  159. package/types/raintonic-formaui-components-alert.d.ts.map +1 -1
  160. package/types/raintonic-formaui-components-autocomplete.d.ts +73 -116
  161. package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -1
  162. package/types/raintonic-formaui-components-avatar.d.ts +13 -31
  163. package/types/raintonic-formaui-components-avatar.d.ts.map +1 -1
  164. package/types/raintonic-formaui-components-button.d.ts +4 -10
  165. package/types/raintonic-formaui-components-button.d.ts.map +1 -1
  166. package/types/raintonic-formaui-components-chip.d.ts +43 -0
  167. package/types/raintonic-formaui-components-chip.d.ts.map +1 -0
  168. package/types/raintonic-formaui-components-data-table.d.ts +48 -11
  169. package/types/raintonic-formaui-components-data-table.d.ts.map +1 -1
  170. package/types/raintonic-formaui-components-date-picker.d.ts +59 -23
  171. package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -1
  172. package/types/raintonic-formaui-components-dropdown-menu.d.ts +394 -0
  173. package/types/raintonic-formaui-components-dropdown-menu.d.ts.map +1 -0
  174. package/types/raintonic-formaui-components-dual-tier-navigation.d.ts +87 -0
  175. package/types/raintonic-formaui-components-dual-tier-navigation.d.ts.map +1 -0
  176. package/types/raintonic-formaui-components-form-field.d.ts +51 -21
  177. package/types/raintonic-formaui-components-form-field.d.ts.map +1 -1
  178. package/types/raintonic-formaui-components-input.d.ts +20 -11
  179. package/types/raintonic-formaui-components-input.d.ts.map +1 -1
  180. package/types/raintonic-formaui-components-number-input.d.ts +5 -3
  181. package/types/raintonic-formaui-components-number-input.d.ts.map +1 -1
  182. package/types/raintonic-formaui-components-password-input.d.ts +18 -32
  183. package/types/raintonic-formaui-components-password-input.d.ts.map +1 -1
  184. package/types/raintonic-formaui-components-popover.d.ts.map +1 -1
  185. package/types/raintonic-formaui-components-progressbar.d.ts +1 -1
  186. package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -1
  187. package/types/raintonic-formaui-components-radio.d.ts +1 -2
  188. package/types/raintonic-formaui-components-radio.d.ts.map +1 -1
  189. package/types/raintonic-formaui-components-select.d.ts +107 -76
  190. package/types/raintonic-formaui-components-select.d.ts.map +1 -1
  191. package/types/raintonic-formaui-components-sidebar-nav-menu.d.ts +223 -0
  192. package/types/raintonic-formaui-components-sidebar-nav-menu.d.ts.map +1 -0
  193. package/types/raintonic-formaui-components-stepper.d.ts +4 -2
  194. package/types/raintonic-formaui-components-stepper.d.ts.map +1 -1
  195. package/types/raintonic-formaui-components-strength-meter.d.ts +78 -0
  196. package/types/raintonic-formaui-components-strength-meter.d.ts.map +1 -0
  197. package/types/raintonic-formaui-components-time-picker.d.ts +44 -24
  198. package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -1
  199. package/types/raintonic-formaui-components-toggle-group.d.ts +100 -0
  200. package/types/raintonic-formaui-components-toggle-group.d.ts.map +1 -0
  201. package/types/raintonic-formaui-components-tooltip.d.ts +2 -1
  202. package/types/raintonic-formaui-components-tooltip.d.ts.map +1 -1
  203. package/types/raintonic-formaui-components-topbar.d.ts +48 -0
  204. package/types/raintonic-formaui-components-topbar.d.ts.map +1 -0
  205. package/types/raintonic-formaui-components-tree-select.d.ts +25 -9
  206. package/types/raintonic-formaui-components-tree-select.d.ts.map +1 -1
  207. package/types/raintonic-formaui-components-tree.d.ts +12 -1
  208. package/types/raintonic-formaui-components-tree.d.ts.map +1 -1
  209. package/types/raintonic-formaui-core.d.ts +243 -5
  210. package/types/raintonic-formaui-core.d.ts.map +1 -1
  211. package/types/raintonic-formaui-services-breakpoint.d.ts +44 -0
  212. package/types/raintonic-formaui-services-breakpoint.d.ts.map +1 -0
  213. package/types/raintonic-formaui-services-dialog.d.ts +141 -2
  214. package/types/raintonic-formaui-services-dialog.d.ts.map +1 -1
  215. package/types/raintonic-formaui-services-notification.d.ts +24 -2
  216. package/types/raintonic-formaui-services-notification.d.ts.map +1 -1
  217. package/types/raintonic-formaui-services-theme.d.ts +13 -103
  218. package/types/raintonic-formaui-services-theme.d.ts.map +1 -1
  219. package/types/raintonic-formaui.d.ts +1 -1
  220. package/fesm2022/raintonic-formaui-components-big-menu.mjs +0 -86
  221. package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +0 -1
  222. package/fesm2022/raintonic-formaui-components-menu.mjs +0 -896
  223. package/fesm2022/raintonic-formaui-components-menu.mjs.map +0 -1
  224. package/fesm2022/raintonic-formaui-components-sidebar.mjs +0 -275
  225. package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +0 -1
  226. package/fesm2022/raintonic-formaui-components-tag.mjs +0 -95
  227. package/fesm2022/raintonic-formaui-components-tag.mjs.map +0 -1
  228. package/styles/_fonts-entry.scss +0 -3
  229. package/styles/fonts/inter-tight-latin-italic.woff2 +0 -0
  230. package/styles/fonts/inter-tight-latin.woff2 +0 -0
  231. package/types/raintonic-formaui-components-big-menu.d.ts +0 -73
  232. package/types/raintonic-formaui-components-big-menu.d.ts.map +0 -1
  233. package/types/raintonic-formaui-components-menu.d.ts +0 -403
  234. package/types/raintonic-formaui-components-menu.d.ts.map +0 -1
  235. package/types/raintonic-formaui-components-sidebar.d.ts +0 -185
  236. package/types/raintonic-formaui-components-sidebar.d.ts.map +0 -1
  237. package/types/raintonic-formaui-components-tag.d.ts +0 -43
  238. package/types/raintonic-formaui-components-tag.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-services-dialog.mjs","sources":["../../../lib/services/dialog/dialog.types.ts","../../../lib/services/dialog/dialog-ref.ts","../../../lib/services/dialog/dialog-container.component.ts","../../../lib/services/dialog/confirm-dialog.component.ts","../../../lib/services/dialog/confirm-dialog.component.html","../../../lib/services/dialog/dialog.service.ts","../../../lib/services/dialog/raintonic-formaui-services-dialog.ts"],"sourcesContent":["import { InjectionToken, Injector, Type, ViewContainerRef } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Injection token for dialog data passed to the dialog component\r\n */\r\nexport const FUI_DIALOG_DATA = new InjectionToken<unknown>('FuiDialogData');\r\n\r\n/**\r\n * Injection token for the dialog scroll strategy\r\n */\r\nexport const FUI_DIALOG_DEFAULT_OPTIONS = new InjectionToken<FuiDialogConfig>('FuiDialogDefaultOptions');\r\n\r\n/**\r\n * Role attribute for the dialog\r\n */\r\nexport type FuiDialogRole = 'dialog' | 'alertdialog';\r\n\r\n/**\r\n * Configuration for opening a dialog\r\n */\r\nexport interface FuiDialogConfig<D = unknown> {\r\n /** ID for the dialog. If omitted, a unique one will be generated */\r\n id?: string;\r\n\r\n /** Role attribute for the dialog element */\r\n role?: FuiDialogRole;\r\n\r\n /** CSS class(es) to apply to the overlay pane */\r\n panelClass?: string | string[];\r\n\r\n /** Whether the dialog has a backdrop */\r\n hasBackdrop?: boolean;\r\n\r\n /** CSS class(es) to apply to the backdrop */\r\n backdropClass?: string | string[];\r\n\r\n /** Whether the user can close the dialog by clicking on the backdrop */\r\n disableClose?: boolean;\r\n\r\n /** Width of the dialog */\r\n width?: string;\r\n\r\n /** Height of the dialog */\r\n height?: string;\r\n\r\n /** Min-width of the dialog */\r\n minWidth?: string | number;\r\n\r\n /** Min-height of the dialog */\r\n minHeight?: string | number;\r\n\r\n /** Max-width of the dialog. Defaults to 80vw */\r\n maxWidth?: string | number;\r\n\r\n /** Max-height of the dialog */\r\n maxHeight?: string | number;\r\n\r\n /** Position of the dialog */\r\n position?: FuiDialogPosition;\r\n\r\n /** Data to pass to the dialog component */\r\n data?: D | null;\r\n\r\n /** Layout direction for the dialog content */\r\n direction?: 'ltr' | 'rtl';\r\n\r\n /** ARIA label for the dialog */\r\n ariaLabel?: string | null;\r\n\r\n /** ID of the element that labels the dialog */\r\n ariaLabelledBy?: string | null;\r\n\r\n /** ID of the element that describes the dialog */\r\n ariaDescribedBy?: string | null;\r\n\r\n /** Whether to focus the first focusable element on open */\r\n autoFocus?: FuiAutoFocusTarget | string | boolean;\r\n\r\n /** Whether to restore focus to the previously focused element on close */\r\n restoreFocus?: boolean;\r\n\r\n /** Whether the dialog should close when the user goes backwards/forwards in history */\r\n closeOnNavigation?: boolean;\r\n\r\n /** Duration of the enter animation in ms */\r\n enterAnimationDuration?: string | number;\r\n\r\n /** Duration of the exit animation in ms */\r\n exitAnimationDuration?: string | number;\r\n\r\n /** Alternate ViewContainerRef to use for creating the dialog */\r\n viewContainerRef?: ViewContainerRef;\r\n\r\n /** Injector used for the dialog component */\r\n injector?: Injector;\r\n\r\n /** Component to instantiate as the dialog container (internal use) */\r\n containerComponent?: Type<FuiDialogContainerBase>;\r\n\r\n /** Whether to delay the focus trap */\r\n delayFocusTrap?: boolean;\r\n}\r\n\r\n/**\r\n * Target for auto focus within the dialog\r\n */\r\nexport type FuiAutoFocusTarget = 'dialog' | 'first-tabbable' | 'first-heading';\r\n\r\n/**\r\n * Position of the dialog\r\n */\r\nexport interface FuiDialogPosition {\r\n /** Override for the dialog's top position */\r\n top?: string;\r\n /** Override for the dialog's bottom position */\r\n bottom?: string;\r\n /** Override for the dialog's left position */\r\n left?: string;\r\n /** Override for the dialog's right position */\r\n right?: string;\r\n}\r\n\r\n/**\r\n * State of the dialog animation\r\n */\r\nexport type FuiDialogState = 'void' | 'enter' | 'exit';\r\n\r\n/**\r\n * Base interface for dialog container\r\n */\r\nexport interface FuiDialogContainerBase {\r\n /** Starts the dialog exit animation */\r\n _startExitAnimation(): void;\r\n}\r\n\r\n/**\r\n * Reference to an opened dialog\r\n */\r\nexport interface IFuiDialogRef<T = unknown, R = unknown> {\r\n /** Unique ID for this dialog instance */\r\n readonly id: string;\r\n\r\n /** The component instance if the dialog was created with a component */\r\n readonly componentInstance: T | null;\r\n\r\n /** Whether the user is allowed to close the dialog */\r\n disableClose: boolean;\r\n\r\n /** Observable that emits when the dialog has been opened */\r\n readonly afterOpened: Observable<void>;\r\n\r\n /** Observable that emits when the dialog has started closing */\r\n readonly beforeClosed: Observable<R | undefined>;\r\n\r\n /** Observable that emits when the dialog has finished closing */\r\n readonly afterClosed: Observable<R | undefined>;\r\n\r\n /** Observable that emits when the backdrop is clicked */\r\n readonly backdropClick: Observable<MouseEvent>;\r\n\r\n /** Observable that emits when a keydown event occurs on the overlay */\r\n readonly keydownEvents: Observable<KeyboardEvent>;\r\n\r\n /**\r\n * Closes the dialog with an optional result\r\n * @param dialogResult Result to return to the dialog opener\r\n */\r\n close(dialogResult?: R): void;\r\n\r\n /**\r\n * Updates the dialog's position\r\n * @param position New position configuration\r\n */\r\n updatePosition(position?: FuiDialogPosition): void;\r\n\r\n /**\r\n * Updates the dialog's dimensions\r\n * @param width New width\r\n * @param height New height\r\n */\r\n updateSize(width?: string, height?: string): void;\r\n\r\n /**\r\n * Adds CSS classes to the dialog panel\r\n * @param classes Classes to add\r\n */\r\n addPanelClass(classes: string | string[]): void;\r\n\r\n /**\r\n * Removes CSS classes from the dialog panel\r\n * @param classes Classes to remove\r\n */\r\n removePanelClass(classes: string | string[]): void;\r\n\r\n /**\r\n * Gets the current state of the dialog's lifecycle\r\n */\r\n getState(): FuiDialogState;\r\n}\r\n\r\n/**\r\n * Result from opening a dialog\r\n */\r\nexport interface FuiDialogOpenResult<T, R> {\r\n /** Reference to the opened dialog */\r\n dialogRef: IFuiDialogRef<T, R>;\r\n /** Reference to the component instance if dialog was created with a component */\r\n componentRef?: T;\r\n}\r\n\r\n// Confirm Dialog types\r\nexport type FuiConfirmDialogVariant = 'info' | 'warning' | 'danger';\r\n\r\nexport interface FuiConfirmDialogConfig {\r\n title: string;\r\n message: string;\r\n confirmText?: string;\r\n cancelText?: string;\r\n variant?: FuiConfirmDialogVariant;\r\n}\r\n","import { Observable, Subject } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\nimport { FuiOverlayRef, FuiGlobalPositionStrategy } from '@raintonic/formaui/cdk/overlay';\r\nimport { FuiDialogConfig, FuiDialogPosition, IFuiDialogRef, FuiDialogState } from './dialog.types';\r\n\r\n/**\r\n * # FuiDialogRefImpl\r\n *\r\n * Implementation of the FuiDialogRef interface. This class manages the lifecycle\r\n * of an individual dialog instance, providing methods to close, update position/size,\r\n * and observe dialog events.\r\n *\r\n * ## Features\r\n * - Dialog result handling\r\n * - Position and size updates\r\n * - Event observables (backdrop click, keydown, lifecycle)\r\n * - CSS class management\r\n * - Focus management integration\r\n */\r\nexport class FuiDialogRef<T = unknown, R = unknown> implements IFuiDialogRef<T, R> {\r\n private readonly _id: string;\r\n private _componentInstance: T | null = null;\r\n private _result: R | undefined;\r\n private _state: FuiDialogState = 'enter';\r\n\r\n // Event subjects\r\n private readonly _afterOpened = new Subject<void>();\r\n private readonly _beforeClosed = new Subject<R | undefined>();\r\n private readonly _afterClosed = new Subject<R | undefined>();\r\n\r\n // Configuration\r\n disableClose: boolean;\r\n\r\n constructor(\r\n private readonly _overlayRef: FuiOverlayRef,\r\n private _config: FuiDialogConfig,\r\n id?: string,\r\n ) {\r\n this._id = id ?? this._generateId();\r\n this.disableClose = _config.disableClose ?? false;\r\n\r\n this._setupEventHandlers();\r\n }\r\n\r\n /** Unique ID for this dialog instance */\r\n get id(): string {\r\n return this._id;\r\n }\r\n\r\n /** The component instance if the dialog was created with a component */\r\n get componentInstance(): T | null {\r\n return this._componentInstance;\r\n }\r\n\r\n /** Sets the component instance (internal use) */\r\n set componentInstance(instance: T | null) {\r\n this._componentInstance = instance;\r\n }\r\n\r\n /** Observable that emits when the dialog has been opened */\r\n get afterOpened(): Observable<void> {\r\n return this._afterOpened.asObservable();\r\n }\r\n\r\n /** Observable that emits when the dialog has started closing */\r\n get beforeClosed(): Observable<R | undefined> {\r\n return this._beforeClosed.asObservable();\r\n }\r\n\r\n /** Observable that emits when the dialog has finished closing */\r\n get afterClosed(): Observable<R | undefined> {\r\n return this._afterClosed.asObservable();\r\n }\r\n\r\n /** Observable that emits when the backdrop is clicked */\r\n get backdropClick(): Observable<MouseEvent> {\r\n return this._overlayRef.backdropClick;\r\n }\r\n\r\n /** Observable that emits when a keydown event occurs on the overlay */\r\n get keydownEvents(): Observable<KeyboardEvent> {\r\n return this._overlayRef.keydownEvents;\r\n }\r\n\r\n /**\r\n * Closes the dialog with an optional result\r\n */\r\n close(dialogResult?: R): void {\r\n if (this._state === 'exit') {\r\n return;\r\n }\r\n\r\n this._result = dialogResult;\r\n this._state = 'exit';\r\n\r\n // Emit before closed event\r\n this._beforeClosed.next(dialogResult);\r\n this._beforeClosed.complete();\r\n\r\n // Get animation duration from config\r\n const exitDuration = this._parseAnimationDuration(this._config.exitAnimationDuration);\r\n\r\n if (exitDuration > 0) {\r\n // Add exit animation class\r\n this._overlayRef.addPanelClass('fui-dialog-exit');\r\n\r\n // Wait for animation then dispose\r\n setTimeout(() => {\r\n this._finishDialogClose();\r\n }, exitDuration);\r\n } else {\r\n this._finishDialogClose();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the dialog's position\r\n */\r\n updatePosition(position?: FuiDialogPosition): void {\r\n const strategy = this._overlayRef.getConfig().positionStrategy as FuiGlobalPositionStrategy;\r\n\r\n if (strategy) {\r\n if (position?.left || position?.right) {\r\n if (position?.left) {\r\n strategy.left(position.left);\r\n } else if (position?.right) {\r\n strategy.right(position.right);\r\n }\r\n } else {\r\n strategy.centerHorizontally();\r\n }\r\n\r\n if (position?.top || position?.bottom) {\r\n if (position?.top) {\r\n strategy.top(position.top);\r\n } else if (position?.bottom) {\r\n strategy.bottom(position.bottom);\r\n }\r\n } else {\r\n strategy.centerVertically();\r\n }\r\n\r\n this._overlayRef.updatePosition();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the dialog's dimensions\r\n */\r\n updateSize(width?: string, height?: string): void {\r\n this._overlayRef.updateSize({\r\n width: width ?? undefined,\r\n height: height ?? undefined,\r\n });\r\n }\r\n\r\n /**\r\n * Adds CSS classes to the dialog panel\r\n */\r\n addPanelClass(classes: string | string[]): void {\r\n this._overlayRef.addPanelClass(classes);\r\n }\r\n\r\n /**\r\n * Removes CSS classes from the dialog panel\r\n */\r\n removePanelClass(classes: string | string[]): void {\r\n this._overlayRef.removePanelClass(classes);\r\n }\r\n\r\n /**\r\n * Gets the current state of the dialog's lifecycle\r\n */\r\n getState(): FuiDialogState {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Notifies that the dialog has been opened (internal use)\r\n */\r\n _notifyOpened(): void {\r\n this._afterOpened.next();\r\n this._afterOpened.complete();\r\n }\r\n\r\n private _setupEventHandlers(): void {\r\n // Handle backdrop clicks\r\n this._overlayRef.backdropClick.subscribe(() => {\r\n if (!this.disableClose) {\r\n this.close();\r\n }\r\n });\r\n\r\n // Handle escape key\r\n this._overlayRef.keydownEvents\r\n .pipe(filter((event) => event.key === 'Escape' && !this.disableClose))\r\n .subscribe((event) => {\r\n event.preventDefault();\r\n this.close();\r\n });\r\n }\r\n\r\n private _finishDialogClose(): void {\r\n // Dispose the overlay\r\n this._overlayRef.dispose();\r\n\r\n // Emit after closed event\r\n this._afterClosed.next(this._result);\r\n this._afterClosed.complete();\r\n }\r\n\r\n private _parseAnimationDuration(duration: string | number | undefined): number {\r\n if (duration === undefined) {\r\n return 200; // Default 200ms\r\n }\r\n\r\n if (typeof duration === 'number') {\r\n return duration;\r\n }\r\n\r\n // Parse CSS duration string (e.g., '200ms', '0.2s')\r\n const match = /^(\\d+(?:\\.\\d+)?)(ms|s)$/.exec(duration);\r\n if (match) {\r\n const value = parseFloat(match[1]);\r\n const unit = match[2];\r\n return unit === 's' ? value * 1000 : value;\r\n }\r\n\r\n return 200;\r\n }\r\n\r\n private _generateId(): string {\r\n return `fui-dialog-${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n}\r\n","import {\r\n Component,\r\n ElementRef,\r\n ViewChild,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n ChangeDetectionStrategy,\r\n signal,\r\n computed,\r\n HostListener,\r\n} from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FuiDialogConfig, FuiDialogContainerBase } from './dialog.types';\r\n\r\n/**\r\n * # FuiDialogContainerComponent\r\n *\r\n * Internal container component that hosts the dialog content. This component\r\n * handles focus trapping, animations, and accessibility attributes.\r\n *\r\n * ## Features\r\n * - Focus trapping within the dialog\r\n * - Configurable ARIA attributes\r\n * - Enter/exit animations\r\n * - Focus restoration on close\r\n */\r\n@Component({\r\n selector: 'fui-dialog-container',\r\n standalone: true,\r\n imports: [],\r\n template: `\r\n <div\r\n #dialogContainer\r\n class=\"fui-dialog-container\"\r\n [class.fui-dialog-enter]=\"animationState() === 'enter'\"\r\n [class.fui-dialog-exit]=\"animationState() === 'exit'\"\r\n [attr.role]=\"config.role || 'dialog'\"\r\n [attr.aria-modal]=\"true\"\r\n [attr.aria-label]=\"config.ariaLabel\"\r\n [attr.aria-labelledby]=\"config.ariaLabelledBy\"\r\n [attr.aria-describedby]=\"config.ariaDescribedBy\"\r\n tabindex=\"-1\"\r\n >\r\n <div class=\"fui-dialog-content\" aria-live=\"polite\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n outline: 0;\r\n }\r\n\r\n .fui-dialog-container {\r\n display: flex;\r\n flex-direction: column;\r\n box-sizing: border-box;\r\n overflow: auto;\r\n outline: 0;\r\n max-height: inherit;\r\n border: 1px solid var(--fui-border-color);\r\n border-radius: var(--fui-border-radius-md);\r\n background: var(--fui-surface-00);\r\n box-shadow: var(--fui-dialog-box-shadow, var(--fui-shadow-05));\r\n }\r\n\r\n .fui-dialog-content {\r\n display: contents;\r\n }\r\n\r\n .fui-dialog-enter {\r\n animation: fui-dialog-enter var(--fui-duration-moderate-02) var(--fui-ease-entrance);\r\n }\r\n\r\n .fui-dialog-exit {\r\n animation: fui-dialog-exit var(--fui-duration-moderate-01) var(--fui-ease-exit);\r\n }\r\n\r\n @keyframes fui-dialog-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n }\r\n\r\n @keyframes fui-dialog-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .fui-dialog-enter,\r\n .fui-dialog-exit {\r\n animation: none;\r\n }\r\n }\r\n `,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'fui-dialog-container-host',\r\n },\r\n})\r\nexport class FuiDialogContainerComponent implements FuiDialogContainerBase, AfterViewInit, OnDestroy {\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n @ViewChild('dialogContainer', { static: true })\r\n private _dialogContainer!: ElementRef<HTMLElement>;\r\n\r\n /** Configuration for the dialog */\r\n config!: FuiDialogConfig;\r\n\r\n /** The previously focused element before the dialog was opened */\r\n private _elementFocusedBeforeDialogWasOpened: HTMLElement | null = null;\r\n\r\n /** Animation state of the dialog */\r\n readonly animationState = signal<'void' | 'enter' | 'exit'>('void');\r\n\r\n /** Whether the dialog is currently animating */\r\n readonly isAnimating = computed(() => this.animationState() !== 'void');\r\n\r\n ngAfterViewInit(): void {\r\n this._trapFocus();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._restoreFocus();\r\n }\r\n\r\n /**\r\n * Handles keydown events for focus trap cycling within the dialog.\r\n * Tab loops from last to first focusable element, Shift+Tab from first to last.\r\n */\r\n @HostListener('keydown', ['$event'])\r\n _onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Tab') {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const firstFocusable = focusableElements[0];\r\n const lastFocusable = focusableElements[focusableElements.length - 1];\r\n const activeElement = this._document.activeElement;\r\n\r\n if (event.shiftKey) {\r\n // Shift+Tab: if on first element, wrap to last\r\n if (activeElement === firstFocusable || activeElement === this._dialogContainer.nativeElement) {\r\n event.preventDefault();\r\n lastFocusable.focus();\r\n }\r\n } else {\r\n // Tab: if on last element, wrap to first\r\n if (activeElement === lastFocusable) {\r\n event.preventDefault();\r\n firstFocusable.focus();\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the dialog container with the given configuration\r\n */\r\n _initializeWithConfig(config: FuiDialogConfig): void {\r\n this.config = config;\r\n }\r\n\r\n /**\r\n * Starts the enter animation\r\n */\r\n _startEnterAnimation(): void {\r\n this.animationState.set('enter');\r\n }\r\n\r\n /**\r\n * Starts the exit animation\r\n */\r\n _startExitAnimation(): void {\r\n this.animationState.set('exit');\r\n }\r\n\r\n /**\r\n * Gets the native element of the container\r\n */\r\n _getHostElement(): HTMLElement {\r\n return this._elementRef.nativeElement;\r\n }\r\n\r\n /**\r\n * Saves the element that was focused before the dialog opened and traps focus\r\n */\r\n private _trapFocus(): void {\r\n // Store the currently focused element\r\n this._elementFocusedBeforeDialogWasOpened = this._document.activeElement as HTMLElement;\r\n\r\n // Focus the dialog container\r\n const autoFocus = this.config?.autoFocus ?? 'first-tabbable';\r\n\r\n if (autoFocus === false || autoFocus === 'dialog') {\r\n // Focus the dialog container itself\r\n this._dialogContainer.nativeElement.focus();\r\n } else if (autoFocus === 'first-tabbable') {\r\n this._focusFirstTabbableElement();\r\n } else if (autoFocus === 'first-heading') {\r\n this._focusFirstHeading();\r\n } else if (typeof autoFocus === 'string') {\r\n // Focus a specific element by selector\r\n this._focusBySelector(autoFocus);\r\n } else {\r\n // Default: focus first tabbable\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses the first tabbable element within the dialog\r\n */\r\n private _focusFirstTabbableElement(): void {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length > 0) {\r\n focusableElements[0].focus();\r\n } else {\r\n // Fallback to container\r\n this._dialogContainer.nativeElement.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses the first heading element within the dialog\r\n */\r\n private _focusFirstHeading(): void {\r\n const heading = this._dialogContainer.nativeElement.querySelector<HTMLElement>(\r\n 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]',\r\n );\r\n\r\n if (heading) {\r\n // Make heading focusable if it's not already\r\n if (!heading.hasAttribute('tabindex')) {\r\n heading.setAttribute('tabindex', '-1');\r\n }\r\n heading.focus();\r\n } else {\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses an element matching the given selector\r\n */\r\n private _focusBySelector(selector: string): void {\r\n const element = this._dialogContainer.nativeElement.querySelector<HTMLElement>(selector);\r\n if (element) {\r\n element.focus();\r\n } else {\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Gets all focusable elements within the dialog\r\n */\r\n private _getFocusableElements(): HTMLElement[] {\r\n const focusableSelectors = [\r\n 'a[href]',\r\n 'button:not([disabled])',\r\n 'textarea:not([disabled])',\r\n 'input:not([disabled])',\r\n 'select:not([disabled])',\r\n '[tabindex]:not([tabindex=\"-1\"])',\r\n '[contenteditable=\"true\"]',\r\n ].join(',');\r\n\r\n return Array.from(this._dialogContainer.nativeElement.querySelectorAll<HTMLElement>(focusableSelectors)).filter(\r\n (el) => {\r\n // Filter out elements that are not visible\r\n return el.offsetParent !== null;\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Restores focus to the element that was focused before the dialog opened\r\n */\r\n private _restoreFocus(): void {\r\n const shouldRestoreFocus = this.config?.restoreFocus !== false;\r\n\r\n if (shouldRestoreFocus && this._elementFocusedBeforeDialogWasOpened) {\r\n // Check if the element is still in the DOM and can receive focus\r\n if (typeof this._elementFocusedBeforeDialogWasOpened.focus === 'function') {\r\n this._elementFocusedBeforeDialogWasOpened.focus();\r\n }\r\n }\r\n\r\n this._elementFocusedBeforeDialogWasOpened = null;\r\n }\r\n}\r\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, inject } from '@angular/core';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\r\nimport { FUI_DIALOG_DATA, FuiConfirmDialogConfig } from './dialog.types';\r\nimport { FuiDialogRef } from './dialog-ref';\r\n\r\n@Component({\r\n selector: 'fui-confirm-dialog',\r\n standalone: true,\r\n imports: [FuiIconComponent, FuiButtonDirective],\r\n templateUrl: './confirm-dialog.component.html',\r\n styleUrls: ['./confirm-dialog.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: { class: 'fui-confirm-dialog' },\r\n})\r\nexport class FuiConfirmDialogComponent {\r\n private readonly data = inject(FUI_DIALOG_DATA) as FuiConfirmDialogConfig;\r\n private readonly dialogRef = inject(FuiDialogRef);\r\n\r\n readonly title = this.data.title;\r\n readonly message = this.data.message;\r\n readonly confirmText = this.data.confirmText ?? 'Confirm';\r\n readonly cancelText = this.data.cancelText ?? 'Cancel';\r\n readonly variant = this.data.variant ?? 'info';\r\n\r\n readonly icon = computed(() => {\r\n switch (this.variant) {\r\n case 'warning':\r\n return 'warning-diamond';\r\n case 'danger':\r\n return 'warning-octagon';\r\n default:\r\n return 'info';\r\n }\r\n });\r\n\r\n readonly confirmButtonVariant = computed(() => {\r\n switch (this.variant) {\r\n case 'danger':\r\n return 'destructive';\r\n case 'warning':\r\n return 'primary';\r\n default:\r\n return 'primary';\r\n }\r\n });\r\n\r\n onConfirm(): void {\r\n this.dialogRef.close(true);\r\n }\r\n\r\n onCancel(): void {\r\n this.dialogRef.close(false);\r\n }\r\n}\r\n","<div class=\"fui-confirm-dialog__header\">\r\n <fui-icon class=\"fui-confirm-dialog__icon fui-confirm-dialog__icon--{{ variant }}\" [name]=\"icon()\" size=\"lg\" />\r\n <h2 class=\"fui-confirm-dialog__title\" id=\"confirm-dialog-title\">{{ title }}</h2>\r\n</div>\r\n\r\n<div class=\"fui-confirm-dialog__body\" id=\"confirm-dialog-description\">\r\n <p class=\"fui-confirm-dialog__message\">{{ message }}</p>\r\n</div>\r\n\r\n<div class=\"fui-confirm-dialog__actions\">\r\n <button fuiButton variant=\"tertiary\" (click)=\"onCancel()\">{{ cancelText }}</button>\r\n <button fuiButton [variant]=\"confirmButtonVariant()\" (click)=\"onConfirm()\">{{ confirmText }}</button>\r\n</div>\r\n","import {\r\n Injectable,\r\n Injector,\r\n ComponentRef,\r\n TemplateRef,\r\n Type,\r\n createComponent,\r\n EnvironmentInjector,\r\n inject,\r\n EmbeddedViewRef,\r\n StaticProvider,\r\n ApplicationRef,\r\n} from '@angular/core';\r\nimport { Observable, Subject, defer } from 'rxjs';\r\nimport { map, startWith } from 'rxjs/operators';\r\nimport { FuiOverlayService, FuiOverlayRef, FuiOverlayConfig } from '@raintonic/formaui/cdk/overlay';\r\nimport { FuiDialogConfig, IFuiDialogRef, FUI_DIALOG_DATA, FuiConfirmDialogConfig } from './dialog.types';\r\nimport { FuiDialogRef } from './dialog-ref';\r\nimport { FuiDialogContainerComponent } from './dialog-container.component';\r\nimport { FuiConfirmDialogComponent } from './confirm-dialog.component';\r\n\r\n/**\r\n * # FuiDialogService\r\n *\r\n * Service for opening modal dialogs. This service provides a comprehensive\r\n * dialog system similar to Angular Material's MatDialog, built on top of\r\n * the FuiOverlayService.\r\n *\r\n * ## Features\r\n * - Open dialogs with components or templates\r\n * - Pass data to dialog components\r\n * - Configure positioning, sizing, and behavior\r\n * - Get results from dialogs via observables\r\n * - Manage multiple open dialogs\r\n * - Automatic focus management and accessibility\r\n *\r\n * ## Usage\r\n *\r\n * ### Opening a Component Dialog\r\n * ```typescript\r\n * const dialogRef = this.dialog.open(MyDialogComponent, {\r\n * width: '400px',\r\n * data: { name: 'John' }\r\n * });\r\n *\r\n * dialogRef.afterClosed().subscribe(result => {\r\n * console.log('Dialog result:', result);\r\n * });\r\n * ```\r\n *\r\n * ### Opening a Template Dialog\r\n * ```typescript\r\n * const dialogRef = this.dialog.open(myTemplateRef, {\r\n * width: '300px',\r\n * hasBackdrop: true\r\n * });\r\n * ```\r\n *\r\n * ### Accessing Data in Dialog Component\r\n * ```typescript\r\n * export class MyDialogComponent {\r\n * private readonly data = inject(FUI_DIALOG_DATA);\r\n * private readonly dialogRef = inject(FuiDialogRef);\r\n *\r\n * onClose() {\r\n * this.dialogRef.close('result');\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class FuiDialogService {\r\n private readonly _overlayService = inject(FuiOverlayService);\r\n private readonly _environmentInjector = inject(EnvironmentInjector);\r\n private readonly _injector = inject(Injector);\r\n private readonly _appRef = inject(ApplicationRef);\r\n\r\n private readonly _openDialogs: IFuiDialogRef[] = [];\r\n private readonly _afterOpenedSubject = new Subject<IFuiDialogRef>();\r\n private readonly _afterAllClosedSubject = new Subject<void>();\r\n\r\n private _nextUniqueId = 0;\r\n\r\n /**\r\n * Observable that emits when a dialog is opened\r\n */\r\n readonly afterOpened: Observable<IFuiDialogRef> = this._afterOpenedSubject.asObservable();\r\n\r\n /**\r\n * Observable that emits when all dialogs are closed\r\n */\r\n readonly afterAllClosed: Observable<void> = defer(() =>\r\n this._openDialogs.length ? this._getAfterAllClosed() : this._getAfterAllClosed().pipe(startWith(undefined)),\r\n );\r\n\r\n /**\r\n * Gets all currently open dialogs\r\n */\r\n get openDialogs(): IFuiDialogRef[] {\r\n return this._openDialogs.slice();\r\n }\r\n\r\n /**\r\n * Opens a dialog containing the given component or template\r\n * @param componentOrTemplateRef Component type or TemplateRef to display\r\n * @param config Configuration options for the dialog\r\n * @returns Reference to the opened dialog\r\n */\r\n open<T, D = unknown, R = unknown>(\r\n componentOrTemplateRef: Type<T> | TemplateRef<T>,\r\n config?: FuiDialogConfig<D>,\r\n ): FuiDialogRef<T, R> {\r\n const mergedConfig = this._applyConfigDefaults(config);\r\n const overlayRef = this._createOverlay(mergedConfig);\r\n const dialogContainer = this._attachDialogContainer(overlayRef, mergedConfig);\r\n const dialogRef = this._createDialogRef<T, R>(overlayRef, dialogContainer, mergedConfig);\r\n\r\n if (componentOrTemplateRef instanceof TemplateRef) {\r\n this._attachTemplateContent(dialogContainer, componentOrTemplateRef, dialogRef);\r\n } else {\r\n const componentRef = this._attachComponentContent<T, R>(\r\n dialogContainer,\r\n componentOrTemplateRef,\r\n dialogRef,\r\n mergedConfig,\r\n );\r\n dialogRef.componentInstance = componentRef.instance;\r\n }\r\n\r\n // Track open dialogs\r\n this._openDialogs.push(dialogRef);\r\n\r\n // Handle dialog close\r\n dialogRef.afterClosed.subscribe(() => {\r\n this._removeOpenDialog(dialogRef);\r\n });\r\n\r\n // Start enter animation and notify opened\r\n dialogContainer._startEnterAnimation();\r\n\r\n // Notify that dialog has been opened\r\n requestAnimationFrame(() => {\r\n dialogRef._notifyOpened();\r\n this._afterOpenedSubject.next(dialogRef);\r\n });\r\n\r\n return dialogRef;\r\n }\r\n\r\n /**\r\n * Closes all open dialogs\r\n */\r\n closeAll(): void {\r\n const dialogs = this._openDialogs.slice();\r\n dialogs.forEach((dialog) => {\r\n dialog.close();\r\n });\r\n }\r\n\r\n /**\r\n * Gets a dialog by its ID\r\n * @param id Dialog ID\r\n * @returns The dialog reference or undefined\r\n */\r\n getDialogById(id: string): IFuiDialogRef | undefined {\r\n return this._openDialogs.find((dialog) => dialog.id === id);\r\n }\r\n\r\n private _createOverlay(config: FuiDialogConfig): FuiOverlayRef {\r\n const overlayConfig = this._getOverlayConfig(config);\r\n return this._overlayService.create(overlayConfig);\r\n }\r\n\r\n private _getOverlayConfig(config: FuiDialogConfig): FuiOverlayConfig {\r\n // Create position strategy\r\n const positionStrategy = this._overlayService.position().global();\r\n\r\n // Apply positioning\r\n if (config.position?.left || config.position?.right) {\r\n if (config.position.left) {\r\n positionStrategy.left(config.position.left);\r\n } else if (config.position.right) {\r\n positionStrategy.right(config.position.right);\r\n }\r\n } else {\r\n positionStrategy.centerHorizontally();\r\n }\r\n\r\n if (config.position?.top || config.position?.bottom) {\r\n if (config.position.top) {\r\n positionStrategy.top(config.position.top);\r\n } else if (config.position.bottom) {\r\n positionStrategy.bottom(config.position.bottom);\r\n }\r\n } else {\r\n positionStrategy.centerVertically();\r\n }\r\n\r\n return {\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.block(),\r\n hasBackdrop: config.hasBackdrop ?? true,\r\n backdropClass: this._getBackdropClass(config),\r\n backdropClickBehavior: config.disableClose ? 'ignore' : 'close',\r\n panelClass: this._getPanelClass(config),\r\n width: config.width,\r\n height: config.height,\r\n minWidth: config.minWidth,\r\n minHeight: config.minHeight,\r\n maxWidth: config.maxWidth,\r\n maxHeight: config.maxHeight,\r\n direction: config.direction,\r\n };\r\n }\r\n\r\n private _getBackdropClass(config: FuiDialogConfig): string[] {\r\n const baseClass = 'fui-dialog-backdrop';\r\n let customClasses: string[] = [];\r\n if (config.backdropClass) {\r\n customClasses = Array.isArray(config.backdropClass) ? config.backdropClass : [config.backdropClass];\r\n }\r\n\r\n return [baseClass, ...customClasses];\r\n }\r\n\r\n private _getPanelClass(config: FuiDialogConfig): string[] {\r\n const baseClass = 'fui-dialog-panel';\r\n let customPanelClasses: string[] = [];\r\n if (config.panelClass) {\r\n customPanelClasses = Array.isArray(config.panelClass) ? config.panelClass : [config.panelClass];\r\n }\r\n\r\n return [baseClass, ...customPanelClasses];\r\n }\r\n\r\n private _attachDialogContainer(overlayRef: FuiOverlayRef, config: FuiDialogConfig): FuiDialogContainerComponent {\r\n const containerRef = createComponent(FuiDialogContainerComponent, {\r\n environmentInjector: this._environmentInjector,\r\n });\r\n\r\n // Initialize the container with config\r\n containerRef.instance._initializeWithConfig(config);\r\n\r\n // Trigger change detection\r\n containerRef.changeDetectorRef.detectChanges();\r\n\r\n // Attach to overlay\r\n overlayRef.attach(containerRef);\r\n\r\n return containerRef.instance;\r\n }\r\n\r\n private _createDialogRef<T, R>(\r\n overlayRef: FuiOverlayRef,\r\n container: FuiDialogContainerComponent,\r\n config: FuiDialogConfig,\r\n ): FuiDialogRef<T, R> {\r\n const dialogId = config.id ?? `fui-dialog-${this._nextUniqueId++}`;\r\n return new FuiDialogRef<T, R>(overlayRef, config, dialogId);\r\n }\r\n\r\n private _attachComponentContent<T, R>(\r\n container: FuiDialogContainerComponent,\r\n component: Type<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n config: FuiDialogConfig,\r\n ): ComponentRef<T> {\r\n // Create custom injector with dialog data and ref\r\n const providers: StaticProvider[] = [\r\n { provide: FUI_DIALOG_DATA, useValue: config.data },\r\n { provide: FuiDialogRef, useValue: dialogRef },\r\n ];\r\n\r\n const injector = Injector.create({\r\n parent: config.injector ?? this._injector,\r\n providers,\r\n });\r\n\r\n // Create the component\r\n const componentRef = createComponent(component, {\r\n environmentInjector: this._environmentInjector,\r\n elementInjector: injector,\r\n });\r\n\r\n // Attach to ApplicationRef to connect it to Angular's change detection tree\r\n // This is crucial for form controls and event bindings to work properly\r\n this._appRef.attachView(componentRef.hostView);\r\n\r\n // Append to container\r\n const hostElement = container._getHostElement();\r\n const containerElement = hostElement.querySelector('.fui-dialog-container');\r\n if (containerElement) {\r\n containerElement.appendChild(componentRef.location.nativeElement);\r\n }\r\n\r\n // Trigger change detection\r\n componentRef.changeDetectorRef.detectChanges();\r\n\r\n return componentRef;\r\n }\r\n\r\n private _attachTemplateContent<T, R>(\r\n container: FuiDialogContainerComponent,\r\n template: TemplateRef<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n ): EmbeddedViewRef<T> {\r\n // Create the embedded view\r\n const context = { $implicit: dialogRef } as Record<string, unknown>;\r\n const viewRef = template.createEmbeddedView(context as T);\r\n\r\n // Attach to ApplicationRef to connect it to Angular's change detection tree\r\n this._appRef.attachView(viewRef);\r\n\r\n // Append to container\r\n const hostElement = container._getHostElement();\r\n const containerElement = hostElement.querySelector('.fui-dialog-container');\r\n if (containerElement) {\r\n viewRef.rootNodes.forEach((node) => {\r\n containerElement.appendChild(node);\r\n });\r\n }\r\n\r\n // Mark for check\r\n viewRef.detectChanges();\r\n\r\n return viewRef;\r\n }\r\n\r\n private _removeOpenDialog(dialogRef: IFuiDialogRef): void {\r\n const index = this._openDialogs.indexOf(dialogRef);\r\n if (index > -1) {\r\n this._openDialogs.splice(index, 1);\r\n\r\n // Emit if all dialogs are closed\r\n if (this._openDialogs.length === 0) {\r\n this._afterAllClosedSubject.next();\r\n }\r\n }\r\n }\r\n\r\n private _getAfterAllClosed(): Observable<void> {\r\n return this._afterAllClosedSubject.asObservable();\r\n }\r\n\r\n /**\r\n * Opens a confirmation dialog and returns an Observable<boolean>.\r\n * Resolves to `true` when confirmed, `false` when cancelled, ESC, or backdrop click.\r\n */\r\n confirm(config: FuiConfirmDialogConfig): Observable<boolean> {\r\n const dialogRef = this.open(FuiConfirmDialogComponent, {\r\n width: '28rem',\r\n maxWidth: '90vw',\r\n data: config,\r\n role: config.variant === 'danger' ? 'alertdialog' : 'dialog',\r\n ariaLabelledBy: 'confirm-dialog-title',\r\n ariaDescribedBy: 'confirm-dialog-description',\r\n disableClose: false,\r\n });\r\n\r\n return dialogRef.afterClosed.pipe(map((result) => result === true));\r\n }\r\n\r\n private _applyConfigDefaults(config?: FuiDialogConfig): FuiDialogConfig {\r\n return {\r\n role: 'dialog',\r\n hasBackdrop: true,\r\n disableClose: false,\r\n maxWidth: '80vw',\r\n autoFocus: 'first-tabbable',\r\n restoreFocus: true,\r\n closeOnNavigation: true,\r\n enterAnimationDuration: 200,\r\n exitAnimationDuration: 150,\r\n ...config,\r\n };\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"raintonic-formaui-services-dialog.mjs","sources":["../../../lib/services/dialog/dialog.types.ts","../../../lib/services/dialog/dialog-ref.ts","../../../lib/services/dialog/dialog-container.component.ts","../../../lib/services/dialog/drawer-container/drawer-container.component.ts","../../../lib/services/dialog/drawer-container/drawer-container.component.html","../../../lib/services/dialog/confirm-dialog.component.ts","../../../lib/services/dialog/confirm-dialog.component.html","../../../lib/services/dialog/dialog.service.ts","../../../lib/services/dialog/raintonic-formaui-services-dialog.ts"],"sourcesContent":["import { InjectionToken, Injector, Type, ViewContainerRef } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Injection token for dialog data passed to the dialog component\r\n */\r\nexport const FUI_DIALOG_DATA = new InjectionToken<unknown>('FuiDialogData');\r\n\r\n/**\r\n * Injection token for the dialog scroll strategy\r\n */\r\nexport const FUI_DIALOG_DEFAULT_OPTIONS = new InjectionToken<FuiDialogConfig>('FuiDialogDefaultOptions');\r\n\r\n/**\r\n * Role attribute for the dialog\r\n */\r\nexport type FuiDialogRole = 'dialog' | 'alertdialog';\r\n\r\n/**\r\n * Configuration for opening a dialog\r\n */\r\nexport interface FuiDialogConfig<D = unknown> {\r\n /** ID for the dialog. If omitted, a unique one will be generated */\r\n id?: string;\r\n\r\n /** Role attribute for the dialog element */\r\n role?: FuiDialogRole;\r\n\r\n /** CSS class(es) to apply to the overlay pane */\r\n panelClass?: string | string[];\r\n\r\n /** Whether the dialog has a backdrop */\r\n hasBackdrop?: boolean;\r\n\r\n /** CSS class(es) to apply to the backdrop */\r\n backdropClass?: string | string[];\r\n\r\n /** Whether the user can close the dialog by clicking on the backdrop */\r\n disableClose?: boolean;\r\n\r\n /** Width of the dialog */\r\n width?: string;\r\n\r\n /** Height of the dialog */\r\n height?: string;\r\n\r\n /** Min-width of the dialog */\r\n minWidth?: string | number;\r\n\r\n /** Min-height of the dialog */\r\n minHeight?: string | number;\r\n\r\n /** Max-width of the dialog. Defaults to 80vw */\r\n maxWidth?: string | number;\r\n\r\n /** Max-height of the dialog */\r\n maxHeight?: string | number;\r\n\r\n /** Position of the dialog */\r\n position?: FuiDialogPosition;\r\n\r\n /** Data to pass to the dialog component */\r\n data?: D | null;\r\n\r\n /** Layout direction for the dialog content */\r\n direction?: 'ltr' | 'rtl';\r\n\r\n /** ARIA label for the dialog */\r\n ariaLabel?: string | null;\r\n\r\n /** ID of the element that labels the dialog */\r\n ariaLabelledBy?: string | null;\r\n\r\n /** ID of the element that describes the dialog */\r\n ariaDescribedBy?: string | null;\r\n\r\n /** Whether to focus the first focusable element on open */\r\n autoFocus?: FuiAutoFocusTarget | string | boolean;\r\n\r\n /** Whether to restore focus to the previously focused element on close */\r\n restoreFocus?: boolean;\r\n\r\n /** Whether the dialog should close when the user goes backwards/forwards in history */\r\n closeOnNavigation?: boolean;\r\n\r\n /** Duration of the enter animation in ms */\r\n enterAnimationDuration?: string | number;\r\n\r\n /** Duration of the exit animation in ms */\r\n exitAnimationDuration?: string | number;\r\n\r\n /** Alternate ViewContainerRef to use for creating the dialog */\r\n viewContainerRef?: ViewContainerRef;\r\n\r\n /** Injector used for the dialog component */\r\n injector?: Injector;\r\n\r\n /** Component to instantiate as the dialog container (internal use) */\r\n containerComponent?: Type<FuiDialogContainerBase>;\r\n\r\n /** Whether to delay the focus trap */\r\n delayFocusTrap?: boolean;\r\n}\r\n\r\n/**\r\n * Target for auto focus within the dialog\r\n */\r\nexport type FuiAutoFocusTarget = 'dialog' | 'first-tabbable' | 'first-heading';\r\n\r\n/**\r\n * Position of the dialog\r\n */\r\nexport interface FuiDialogPosition {\r\n /** Override for the dialog's top position */\r\n top?: string;\r\n /** Override for the dialog's bottom position */\r\n bottom?: string;\r\n /** Override for the dialog's left position */\r\n left?: string;\r\n /** Override for the dialog's right position */\r\n right?: string;\r\n}\r\n\r\n/**\r\n * State of the dialog animation\r\n */\r\nexport type FuiDialogState = 'void' | 'enter' | 'exit';\r\n\r\n/**\r\n * Base interface for dialog container\r\n */\r\nexport interface FuiDialogContainerBase {\r\n /** Starts the dialog exit animation */\r\n _startExitAnimation(): void;\r\n}\r\n\r\n/**\r\n * Reference to an opened dialog\r\n */\r\nexport interface IFuiDialogRef<T = unknown, R = unknown> {\r\n /** Unique ID for this dialog instance */\r\n readonly id: string;\r\n\r\n /** The component instance if the dialog was created with a component */\r\n readonly componentInstance: T | null;\r\n\r\n /** Whether the user is allowed to close the dialog */\r\n disableClose: boolean;\r\n\r\n /** Observable that emits when the dialog has been opened */\r\n readonly afterOpened: Observable<void>;\r\n\r\n /** Observable that emits when the dialog has started closing */\r\n readonly beforeClosed: Observable<R | undefined>;\r\n\r\n /** Observable that emits when the dialog has finished closing */\r\n readonly afterClosed: Observable<R | undefined>;\r\n\r\n /** Observable that emits when the backdrop is clicked */\r\n readonly backdropClick: Observable<MouseEvent>;\r\n\r\n /** Observable that emits when a keydown event occurs on the overlay */\r\n readonly keydownEvents: Observable<KeyboardEvent>;\r\n\r\n /**\r\n * Closes the dialog with an optional result\r\n * @param dialogResult Result to return to the dialog opener\r\n */\r\n close(dialogResult?: R): void;\r\n\r\n /**\r\n * Updates the dialog's position\r\n * @param position New position configuration\r\n */\r\n updatePosition(position?: FuiDialogPosition): void;\r\n\r\n /**\r\n * Updates the dialog's dimensions\r\n * @param width New width\r\n * @param height New height\r\n */\r\n updateSize(width?: string, height?: string): void;\r\n\r\n /**\r\n * Adds CSS classes to the dialog panel\r\n * @param classes Classes to add\r\n */\r\n addPanelClass(classes: string | string[]): void;\r\n\r\n /**\r\n * Removes CSS classes from the dialog panel\r\n * @param classes Classes to remove\r\n */\r\n removePanelClass(classes: string | string[]): void;\r\n\r\n /**\r\n * Gets the current state of the dialog's lifecycle\r\n */\r\n getState(): FuiDialogState;\r\n}\r\n\r\n/**\r\n * Result from opening a dialog\r\n */\r\nexport interface FuiDialogOpenResult<T, R> {\r\n /** Reference to the opened dialog */\r\n dialogRef: IFuiDialogRef<T, R>;\r\n /** Reference to the component instance if dialog was created with a component */\r\n componentRef?: T;\r\n}\r\n\r\n// ── Drawer types ──\r\n\r\n/** Position of the drawer relative to the viewport edge */\r\nexport type DrawerPosition = 'left' | 'right' | 'top' | 'bottom';\r\n\r\n/** Size preset for the drawer */\r\nexport type DrawerSize = 'sm' | 'md' | 'lg' | 'full';\r\n\r\n/** Size presets mapped to CSS values */\r\nexport const DRAWER_SIZE_VALUES: Record<DrawerSize, string> = {\r\n sm: '320px',\r\n md: '480px',\r\n lg: '640px',\r\n full: '100%',\r\n};\r\n\r\n/**\r\n * Configuration for opening a drawer via DialogService.openAsDrawer()\r\n */\r\nexport interface FuiDrawerConfig<D = unknown> {\r\n /** ID for the drawer. If omitted, a unique one will be generated */\r\n id?: string;\r\n\r\n /** Position of the drawer (which viewport edge it slides from). Default: 'right'. */\r\n position?: DrawerPosition;\r\n\r\n /** Size of the drawer. For left/right positions this controls width; for top/bottom it controls height. */\r\n size?: string;\r\n\r\n /** Title displayed in the drawer header. Omit for no header. */\r\n title?: string;\r\n\r\n /** Whether to show the close button in the header. Default: true. */\r\n showCloseButton?: boolean;\r\n\r\n /** CSS class(es) to apply to the overlay pane */\r\n panelClass?: string | string[];\r\n\r\n /** Whether the drawer has a backdrop. Default: true. */\r\n hasBackdrop?: boolean;\r\n\r\n /** CSS class(es) to apply to the backdrop */\r\n backdropClass?: string | string[];\r\n\r\n /** Whether the user can close the drawer by clicking on the backdrop. Default: true. */\r\n disableClose?: boolean;\r\n\r\n /** Data to pass to the drawer component */\r\n data?: D | null;\r\n\r\n /** Layout direction for the drawer content */\r\n direction?: 'ltr' | 'rtl';\r\n\r\n /** ARIA label for the drawer */\r\n ariaLabel?: string | null;\r\n\r\n /** ID of the element that labels the drawer */\r\n ariaLabelledBy?: string | null;\r\n\r\n /** Whether to restore focus to the previously focused element on close. Default: true. */\r\n restoreFocus?: boolean;\r\n\r\n /** Alternate ViewContainerRef to use for creating the drawer */\r\n viewContainerRef?: ViewContainerRef;\r\n\r\n /** Injector used for the drawer component */\r\n injector?: Injector;\r\n}\r\n\r\n// Confirm Dialog types\r\nexport type FuiConfirmDialogVariant = 'info' | 'warning' | 'danger';\r\n\r\nexport interface FuiConfirmDialogConfig {\r\n title: string;\r\n message: string;\r\n confirmText?: string;\r\n cancelText?: string;\r\n variant?: FuiConfirmDialogVariant;\r\n}\r\n","import { Observable, Subject } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\nimport { FuiOverlayRef, FuiGlobalPositionStrategy } from '@raintonic/formaui/cdk/overlay';\r\nimport { FuiDialogConfig, FuiDialogPosition, IFuiDialogRef, FuiDialogState } from './dialog.types';\r\n\r\n/**\r\n * # FuiDialogRefImpl\r\n *\r\n * Implementation of the FuiDialogRef interface. This class manages the lifecycle\r\n * of an individual dialog instance, providing methods to close, update position/size,\r\n * and observe dialog events.\r\n *\r\n * ## Features\r\n * - Dialog result handling\r\n * - Position and size updates\r\n * - Event observables (backdrop click, keydown, lifecycle)\r\n * - CSS class management\r\n * - Focus management integration\r\n */\r\nexport class FuiDialogRef<T = unknown, R = unknown> implements IFuiDialogRef<T, R> {\r\n private readonly _id: string;\r\n private _componentInstance: T | null = null;\r\n private _result: R | undefined;\r\n private _state: FuiDialogState = 'enter';\r\n\r\n // Event subjects\r\n private readonly _afterOpened = new Subject<void>();\r\n private readonly _beforeClosed = new Subject<R | undefined>();\r\n private readonly _afterClosed = new Subject<R | undefined>();\r\n\r\n // Configuration\r\n disableClose: boolean;\r\n\r\n constructor(\r\n private readonly _overlayRef: FuiOverlayRef,\r\n private _config: FuiDialogConfig,\r\n id?: string,\r\n ) {\r\n this._id = id ?? this._generateId();\r\n this.disableClose = _config.disableClose ?? false;\r\n\r\n this._setupEventHandlers();\r\n }\r\n\r\n /** Unique ID for this dialog instance */\r\n get id(): string {\r\n return this._id;\r\n }\r\n\r\n /** The component instance if the dialog was created with a component */\r\n get componentInstance(): T | null {\r\n return this._componentInstance;\r\n }\r\n\r\n /** Sets the component instance (internal use) */\r\n set componentInstance(instance: T | null) {\r\n this._componentInstance = instance;\r\n }\r\n\r\n /** Observable that emits when the dialog has been opened */\r\n get afterOpened(): Observable<void> {\r\n return this._afterOpened.asObservable();\r\n }\r\n\r\n /** Observable that emits when the dialog has started closing */\r\n get beforeClosed(): Observable<R | undefined> {\r\n return this._beforeClosed.asObservable();\r\n }\r\n\r\n /** Observable that emits when the dialog has finished closing */\r\n get afterClosed(): Observable<R | undefined> {\r\n return this._afterClosed.asObservable();\r\n }\r\n\r\n /** Observable that emits when the backdrop is clicked */\r\n get backdropClick(): Observable<MouseEvent> {\r\n return this._overlayRef.backdropClick;\r\n }\r\n\r\n /** Observable that emits when a keydown event occurs on the overlay */\r\n get keydownEvents(): Observable<KeyboardEvent> {\r\n return this._overlayRef.keydownEvents;\r\n }\r\n\r\n /**\r\n * Closes the dialog with an optional result\r\n */\r\n close(dialogResult?: R): void {\r\n if (this._state === 'exit') {\r\n return;\r\n }\r\n\r\n this._result = dialogResult;\r\n this._state = 'exit';\r\n\r\n // Emit before closed event\r\n this._beforeClosed.next(dialogResult);\r\n this._beforeClosed.complete();\r\n\r\n // Get animation duration from config\r\n const exitDuration = this._parseAnimationDuration(this._config.exitAnimationDuration);\r\n\r\n if (exitDuration > 0) {\r\n // Add exit animation class\r\n this._overlayRef.addPanelClass('fui-dialog-exit');\r\n\r\n // Wait for animation then dispose\r\n setTimeout(() => {\r\n this._finishDialogClose();\r\n }, exitDuration);\r\n } else {\r\n this._finishDialogClose();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the dialog's position\r\n */\r\n updatePosition(position?: FuiDialogPosition): void {\r\n const strategy = this._overlayRef.getConfig().positionStrategy as FuiGlobalPositionStrategy;\r\n\r\n if (strategy) {\r\n if (position?.left || position?.right) {\r\n if (position?.left) {\r\n strategy.left(position.left);\r\n } else if (position?.right) {\r\n strategy.right(position.right);\r\n }\r\n } else {\r\n strategy.centerHorizontally();\r\n }\r\n\r\n if (position?.top || position?.bottom) {\r\n if (position?.top) {\r\n strategy.top(position.top);\r\n } else if (position?.bottom) {\r\n strategy.bottom(position.bottom);\r\n }\r\n } else {\r\n strategy.centerVertically();\r\n }\r\n\r\n this._overlayRef.updatePosition();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the dialog's dimensions\r\n */\r\n updateSize(width?: string, height?: string): void {\r\n this._overlayRef.updateSize({\r\n width: width ?? undefined,\r\n height: height ?? undefined,\r\n });\r\n }\r\n\r\n /**\r\n * Adds CSS classes to the dialog panel\r\n */\r\n addPanelClass(classes: string | string[]): void {\r\n this._overlayRef.addPanelClass(classes);\r\n }\r\n\r\n /**\r\n * Removes CSS classes from the dialog panel\r\n */\r\n removePanelClass(classes: string | string[]): void {\r\n this._overlayRef.removePanelClass(classes);\r\n }\r\n\r\n /**\r\n * Gets the current state of the dialog's lifecycle\r\n */\r\n getState(): FuiDialogState {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Notifies that the dialog has been opened (internal use)\r\n */\r\n _notifyOpened(): void {\r\n this._afterOpened.next();\r\n this._afterOpened.complete();\r\n }\r\n\r\n private _setupEventHandlers(): void {\r\n // Handle backdrop clicks\r\n this._overlayRef.backdropClick.subscribe(() => {\r\n if (!this.disableClose) {\r\n this.close();\r\n }\r\n });\r\n\r\n // Handle escape key\r\n this._overlayRef.keydownEvents\r\n .pipe(filter((event) => event.key === 'Escape' && !this.disableClose))\r\n .subscribe((event) => {\r\n event.preventDefault();\r\n this.close();\r\n });\r\n }\r\n\r\n private _finishDialogClose(): void {\r\n // Dispose the overlay\r\n this._overlayRef.dispose();\r\n\r\n // Emit after closed event\r\n this._afterClosed.next(this._result);\r\n this._afterClosed.complete();\r\n }\r\n\r\n private _parseAnimationDuration(duration: string | number | undefined): number {\r\n if (duration === undefined) {\r\n return 200; // Default 200ms\r\n }\r\n\r\n if (typeof duration === 'number') {\r\n return duration;\r\n }\r\n\r\n // Parse CSS duration string (e.g., '200ms', '0.2s')\r\n const match = /^(\\d+(?:\\.\\d+)?)(ms|s)$/.exec(duration);\r\n if (match) {\r\n const value = parseFloat(match[1]);\r\n const unit = match[2];\r\n return unit === 's' ? value * 1000 : value;\r\n }\r\n\r\n return 200;\r\n }\r\n\r\n private _generateId(): string {\r\n return `fui-dialog-${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n}\r\n","import {\r\n Component,\r\n ElementRef,\r\n ViewChild,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n ChangeDetectionStrategy,\r\n signal,\r\n computed,\r\n HostListener,\r\n} from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FuiDialogConfig, FuiDialogContainerBase } from './dialog.types';\r\n\r\n/**\r\n * # FuiDialogContainerComponent\r\n *\r\n * Internal container component that hosts the dialog content. This component\r\n * handles focus trapping, animations, and accessibility attributes.\r\n *\r\n * ## Features\r\n * - Focus trapping within the dialog\r\n * - Configurable ARIA attributes\r\n * - Enter/exit animations\r\n * - Focus restoration on close\r\n */\r\n@Component({\r\n selector: 'fui-dialog-container',\r\n standalone: true,\r\n imports: [],\r\n template: `\r\n <div\r\n #dialogContainer\r\n class=\"fui-dialog-container\"\r\n [class.fui-dialog-enter]=\"animationState() === 'enter'\"\r\n [class.fui-dialog-exit]=\"animationState() === 'exit'\"\r\n [attr.role]=\"config.role || 'dialog'\"\r\n [attr.aria-modal]=\"true\"\r\n [attr.aria-label]=\"config.ariaLabel\"\r\n [attr.aria-labelledby]=\"config.ariaLabelledBy\"\r\n [attr.aria-describedby]=\"config.ariaDescribedBy\"\r\n tabindex=\"-1\"\r\n >\r\n <div class=\"fui-dialog-content\" aria-live=\"polite\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n outline: 0;\r\n }\r\n\r\n .fui-dialog-container {\r\n display: flex;\r\n flex-direction: column;\r\n box-sizing: border-box;\r\n overflow: auto;\r\n outline: 0;\r\n max-height: inherit;\r\n border: 1px solid var(--fui-border-default);\r\n border-radius: var(--fui-radius-md);\r\n background: var(--fui-bg-default);\r\n box-shadow: var(--fui-dialog-box-shadow, var(--fui-shadow-xl));\r\n }\r\n\r\n .fui-dialog-content {\r\n display: contents;\r\n }\r\n\r\n .fui-dialog-enter {\r\n animation: fui-dialog-enter var(--fui-duration-moderate) var(--fui-ease-out);\r\n }\r\n\r\n .fui-dialog-exit {\r\n animation: fui-dialog-exit var(--fui-duration-base) var(--fui-ease-in);\r\n }\r\n\r\n @keyframes fui-dialog-enter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n }\r\n\r\n @keyframes fui-dialog-exit {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .fui-dialog-enter,\r\n .fui-dialog-exit {\r\n animation: none;\r\n }\r\n }\r\n `,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'fui-dialog-container-host',\r\n },\r\n})\r\nexport class FuiDialogContainerComponent implements FuiDialogContainerBase, AfterViewInit, OnDestroy {\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n @ViewChild('dialogContainer', { static: true })\r\n private _dialogContainer!: ElementRef<HTMLElement>;\r\n\r\n /** Configuration for the dialog */\r\n config!: FuiDialogConfig;\r\n\r\n /** The previously focused element before the dialog was opened */\r\n private _elementFocusedBeforeDialogWasOpened: HTMLElement | null = null;\r\n\r\n /** Animation state of the dialog */\r\n readonly animationState = signal<'void' | 'enter' | 'exit'>('void');\r\n\r\n /** Whether the dialog is currently animating */\r\n readonly isAnimating = computed(() => this.animationState() !== 'void');\r\n\r\n ngAfterViewInit(): void {\r\n this._trapFocus();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._restoreFocus();\r\n }\r\n\r\n /**\r\n * Handles keydown events for focus trap cycling within the dialog.\r\n * Tab loops from last to first focusable element, Shift+Tab from first to last.\r\n */\r\n @HostListener('keydown', ['$event'])\r\n _onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Tab') {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const firstFocusable = focusableElements[0];\r\n const lastFocusable = focusableElements[focusableElements.length - 1];\r\n const activeElement = this._document.activeElement;\r\n\r\n if (event.shiftKey) {\r\n // Shift+Tab: if on first element, wrap to last\r\n if (activeElement === firstFocusable || activeElement === this._dialogContainer.nativeElement) {\r\n event.preventDefault();\r\n lastFocusable.focus();\r\n }\r\n } else {\r\n // Tab: if on last element, wrap to first\r\n if (activeElement === lastFocusable) {\r\n event.preventDefault();\r\n firstFocusable.focus();\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the dialog container with the given configuration\r\n */\r\n _initializeWithConfig(config: FuiDialogConfig): void {\r\n this.config = config;\r\n }\r\n\r\n /**\r\n * Starts the enter animation\r\n */\r\n _startEnterAnimation(): void {\r\n this.animationState.set('enter');\r\n }\r\n\r\n /**\r\n * Starts the exit animation\r\n */\r\n _startExitAnimation(): void {\r\n this.animationState.set('exit');\r\n }\r\n\r\n /**\r\n * Gets the native element of the container\r\n */\r\n _getHostElement(): HTMLElement {\r\n return this._elementRef.nativeElement;\r\n }\r\n\r\n /**\r\n * Saves the element that was focused before the dialog opened and traps focus\r\n */\r\n private _trapFocus(): void {\r\n // Store the currently focused element\r\n this._elementFocusedBeforeDialogWasOpened = this._document.activeElement as HTMLElement;\r\n\r\n // Focus the dialog container\r\n const autoFocus = this.config?.autoFocus ?? 'first-tabbable';\r\n\r\n if (autoFocus === false || autoFocus === 'dialog') {\r\n // Focus the dialog container itself\r\n this._dialogContainer.nativeElement.focus();\r\n } else if (autoFocus === 'first-tabbable') {\r\n this._focusFirstTabbableElement();\r\n } else if (autoFocus === 'first-heading') {\r\n this._focusFirstHeading();\r\n } else if (typeof autoFocus === 'string') {\r\n // Focus a specific element by selector\r\n this._focusBySelector(autoFocus);\r\n } else {\r\n // Default: focus first tabbable\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses the first tabbable element within the dialog\r\n */\r\n private _focusFirstTabbableElement(): void {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length > 0) {\r\n focusableElements[0].focus();\r\n } else {\r\n // Fallback to container\r\n this._dialogContainer.nativeElement.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses the first heading element within the dialog\r\n */\r\n private _focusFirstHeading(): void {\r\n const heading = this._dialogContainer.nativeElement.querySelector<HTMLElement>(\r\n 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]',\r\n );\r\n\r\n if (heading) {\r\n // Make heading focusable if it's not already\r\n if (!heading.hasAttribute('tabindex')) {\r\n heading.setAttribute('tabindex', '-1');\r\n }\r\n heading.focus();\r\n } else {\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Focuses an element matching the given selector\r\n */\r\n private _focusBySelector(selector: string): void {\r\n const element = this._dialogContainer.nativeElement.querySelector<HTMLElement>(selector);\r\n if (element) {\r\n element.focus();\r\n } else {\r\n this._focusFirstTabbableElement();\r\n }\r\n }\r\n\r\n /**\r\n * Gets all focusable elements within the dialog\r\n */\r\n private _getFocusableElements(): HTMLElement[] {\r\n const focusableSelectors = [\r\n 'a[href]',\r\n 'button:not([disabled])',\r\n 'textarea:not([disabled])',\r\n 'input:not([disabled])',\r\n 'select:not([disabled])',\r\n '[tabindex]:not([tabindex=\"-1\"])',\r\n '[contenteditable=\"true\"]',\r\n ].join(',');\r\n\r\n return Array.from(this._dialogContainer.nativeElement.querySelectorAll<HTMLElement>(focusableSelectors)).filter(\r\n (el) => {\r\n // Filter out elements that are not visible\r\n return el.offsetParent !== null;\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Restores focus to the element that was focused before the dialog opened\r\n */\r\n private _restoreFocus(): void {\r\n const shouldRestoreFocus = this.config?.restoreFocus !== false;\r\n\r\n if (shouldRestoreFocus && this._elementFocusedBeforeDialogWasOpened) {\r\n // Check if the element is still in the DOM and can receive focus\r\n if (typeof this._elementFocusedBeforeDialogWasOpened.focus === 'function') {\r\n this._elementFocusedBeforeDialogWasOpened.focus();\r\n }\r\n }\r\n\r\n this._elementFocusedBeforeDialogWasOpened = null;\r\n }\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ViewEncapsulation,\r\n ElementRef,\r\n ViewChild,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n HostListener,\r\n output,\r\n Renderer2,\r\n} from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { DrawerPosition } from '../dialog.types';\r\n\r\n/**\r\n * # FuiDialogDrawerContainerComponent\r\n *\r\n * Internal container component used by `FuiDialogService.openAsDrawer()`. Renders\r\n * the drawer chrome (header, content slot, optional footer) with a position-based\r\n * slide animation.\r\n *\r\n * Unlike the standalone `FuiDrawerComponent` (which manages its own backdrop and\r\n * fixed positioning), this component delegates backdrop and positioning to the CDK\r\n * overlay. The container's host element carries position classes and toggles the\r\n * open class to trigger CSS transitions on the child panel — mirroring the original\r\n * drawer's animation model.\r\n */\r\n@Component({\r\n selector: 'fui-dialog-drawer-container',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './drawer-container.component.html',\r\n styleUrls: ['./drawer-container.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-drawer-service',\r\n '[class.fui-drawer-service--left]': 'position === \"left\"',\r\n '[class.fui-drawer-service--right]': 'position === \"right\"',\r\n '[class.fui-drawer-service--top]': 'position === \"top\"',\r\n '[class.fui-drawer-service--bottom]': 'position === \"bottom\"',\r\n },\r\n})\r\nexport class FuiDialogDrawerContainerComponent implements AfterViewInit, OnDestroy {\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _renderer = inject(Renderer2);\r\n private readonly _elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n @ViewChild('drawerPanel', { static: true })\r\n private _drawerPanel!: ElementRef<HTMLElement>;\r\n\r\n /** Which edge the drawer slides from */\r\n position: DrawerPosition = 'right';\r\n\r\n\r\n title: string | null = null;\r\n\r\n /** Whether to show the close button in the header */\r\n showCloseButton = true;\r\n\r\n /** ARIA label */\r\n ariaLabel: string | null = null;\r\n\r\n /** ARIA labelled-by element ID */\r\n ariaLabelledBy: string | null = null;\r\n\r\n /** Emitted when the close button is clicked */\r\n readonly closed = output();\r\n\r\n /** Element that had focus before the drawer opened (for restoration) */\r\n private _previouslyFocusedElement: HTMLElement | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this._renderer.addClass(this._elementRef.nativeElement, 'fui-drawer-service--open');\r\n });\r\n this._trapFocus();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._restoreFocus();\r\n }\r\n\r\n /**\r\n * Returns the host element (for internal use by DialogService when projecting content).\r\n */\r\n _getHostElement(): HTMLElement {\r\n return this._elementRef.nativeElement;\r\n }\r\n\r\n /**\r\n * Appends a DOM element to the drawer's content area (for internal use).\r\n */\r\n _appendToContent(element: HTMLElement): void {\r\n const contentArea = this._elementRef.nativeElement.querySelector('.fui-drawer-service-content');\r\n if (contentArea) {\r\n this._renderer.appendChild(contentArea, element);\r\n }\r\n }\r\n\r\n /**\r\n * Handles keydown events for focus trap cycling within the drawer.\r\n * Tab loops from last to first focusable element, Shift+Tab from first to last.\r\n */\r\n @HostListener('keydown', ['$event'])\r\n _onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Tab') {\r\n const focusableElements = this._getFocusableElements();\r\n if (focusableElements.length === 0) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n const firstFocusable = focusableElements[0];\r\n const lastFocusable = focusableElements[focusableElements.length - 1];\r\n const activeElement = this._document.activeElement;\r\n\r\n if (event.shiftKey) {\r\n if (activeElement === firstFocusable) {\r\n event.preventDefault();\r\n lastFocusable.focus();\r\n }\r\n } else {\r\n if (activeElement === lastFocusable) {\r\n event.preventDefault();\r\n firstFocusable.focus();\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Focuses the first tabbable element in the drawer panel.\r\n */\r\n private _trapFocus(): void {\r\n this._previouslyFocusedElement = this._document.activeElement as HTMLElement;\r\n\r\n const focusable = this._getFocusableElements();\r\n if (focusable.length > 0) {\r\n focusable[0].focus();\r\n } else {\r\n this._drawerPanel.nativeElement.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Restores focus to the element that was focused before the drawer opened.\r\n */\r\n private _restoreFocus(): void {\r\n if (this._previouslyFocusedElement && typeof this._previouslyFocusedElement.focus === 'function') {\r\n this._previouslyFocusedElement.focus();\r\n }\r\n this._previouslyFocusedElement = null;\r\n }\r\n\r\n /**\r\n * Returns all focusable elements currently visible inside the drawer.\r\n */\r\n private _getFocusableElements(): HTMLElement[] {\r\n const selectors = [\r\n 'a[href]',\r\n 'button:not([disabled])',\r\n 'textarea:not([disabled])',\r\n 'input:not([disabled])',\r\n 'select:not([disabled])',\r\n '[tabindex]:not([tabindex=\"-1\"])',\r\n '[contenteditable=\"true\"]',\r\n ].join(',');\r\n\r\n return Array.from(this._drawerPanel.nativeElement.querySelectorAll<HTMLElement>(selectors)).filter(\r\n (el) => el.getClientRects().length > 0,\r\n );\r\n }\r\n}\r\n","<div\r\n #drawerPanel\r\n class=\"fui-drawer-service-panel\"\r\n [attr.role]=\"'dialog'\"\r\n [attr.aria-modal]=\"true\"\r\n [attr.aria-label]=\"ariaLabel || title || null\"\r\n [attr.aria-labelledby]=\"ariaLabelledBy\"\r\n tabindex=\"-1\"\r\n>\r\n @if (title || showCloseButton) {\r\n <div class=\"fui-drawer-service-header\">\r\n @if (title) {\r\n <h2 class=\"fui-drawer-service-title\">{{ title }}</h2>\r\n }\r\n @if (showCloseButton) {\r\n <button\r\n type=\"button\"\r\n class=\"fui-drawer-service-close\"\r\n (click)=\"closed.emit()\"\r\n [attr.aria-label]=\"'Close drawer'\"\r\n >\r\n <fui-icon name=\"x\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"fui-drawer-service-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <div class=\"fui-drawer-service-footer\">\r\n <ng-content select=\"[drawerFooter]\"></ng-content>\r\n </div>\r\n</div>\r\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, inject } from '@angular/core';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\r\nimport { FUI_DIALOG_DATA, FuiConfirmDialogConfig } from './dialog.types';\r\nimport { FuiDialogRef } from './dialog-ref';\r\n\r\n@Component({\r\n selector: 'fui-confirm-dialog',\r\n standalone: true,\r\n imports: [FuiIconComponent, FuiButtonDirective],\r\n templateUrl: './confirm-dialog.component.html',\r\n styleUrls: ['./confirm-dialog.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: { class: 'fui-confirm-dialog' },\r\n})\r\nexport class FuiConfirmDialogComponent {\r\n private readonly data = inject(FUI_DIALOG_DATA) as FuiConfirmDialogConfig;\r\n private readonly dialogRef = inject(FuiDialogRef);\r\n\r\n readonly title = this.data.title;\r\n readonly message = this.data.message;\r\n readonly confirmText = this.data.confirmText ?? 'Confirm';\r\n readonly cancelText = this.data.cancelText ?? 'Cancel';\r\n readonly variant = this.data.variant ?? 'info';\r\n\r\n readonly icon = computed(() => {\r\n switch (this.variant) {\r\n case 'warning':\r\n return 'warning-diamond';\r\n case 'danger':\r\n return 'warning-octagon';\r\n default:\r\n return 'info';\r\n }\r\n });\r\n\r\n readonly confirmButtonVariant = computed(() => {\r\n switch (this.variant) {\r\n case 'danger':\r\n return 'destructive';\r\n case 'warning':\r\n return 'primary';\r\n default:\r\n return 'primary';\r\n }\r\n });\r\n\r\n onConfirm(): void {\r\n this.dialogRef.close(true);\r\n }\r\n\r\n onCancel(): void {\r\n this.dialogRef.close(false);\r\n }\r\n}\r\n","<div class=\"fui-confirm-dialog__header\">\r\n <fui-icon class=\"fui-confirm-dialog__icon fui-confirm-dialog__icon--{{ variant }}\" [name]=\"icon()\" size=\"lg\" />\r\n <h2 class=\"fui-confirm-dialog__title\" id=\"confirm-dialog-title\">{{ title }}</h2>\r\n</div>\r\n\r\n<div class=\"fui-confirm-dialog__body\" id=\"confirm-dialog-description\">\r\n <p class=\"fui-confirm-dialog__message\">{{ message }}</p>\r\n</div>\r\n\r\n<div class=\"fui-confirm-dialog__actions\">\r\n <button fuiButton variant=\"tertiary\" (click)=\"onCancel()\">{{ cancelText }}</button>\r\n <button fuiButton [variant]=\"confirmButtonVariant()\" (click)=\"onConfirm()\">{{ confirmText }}</button>\r\n</div>\r\n","import {\r\n Injectable,\r\n Injector,\r\n ComponentRef,\r\n TemplateRef,\r\n Type,\r\n createComponent,\r\n EnvironmentInjector,\r\n inject,\r\n EmbeddedViewRef,\r\n StaticProvider,\r\n ApplicationRef,\r\n} from '@angular/core';\r\nimport { Observable, Subject, defer } from 'rxjs';\r\nimport { map, startWith } from 'rxjs/operators';\r\nimport { FuiOverlayService, FuiOverlayRef, FuiOverlayConfig } from '@raintonic/formaui/cdk/overlay';\r\nimport { FuiDialogConfig, IFuiDialogRef, FUI_DIALOG_DATA, FuiConfirmDialogConfig, FuiDrawerConfig, DrawerSize, DRAWER_SIZE_VALUES } from './dialog.types';\r\nimport { FuiDialogRef } from './dialog-ref';\r\nimport { FuiDialogContainerComponent } from './dialog-container.component';\r\nimport { FuiDialogDrawerContainerComponent } from './drawer-container/drawer-container.component';\r\nimport { FuiConfirmDialogComponent } from './confirm-dialog.component';\r\n\r\n/**\r\n * # FuiDialogService\r\n *\r\n * Service for opening modal dialogs. This service provides a comprehensive\r\n * dialog system similar to Angular Material's MatDialog, built on top of\r\n * the FuiOverlayService.\r\n *\r\n * ## Features\r\n * - Open dialogs with components or templates\r\n * - Pass data to dialog components\r\n * - Configure positioning, sizing, and behavior\r\n * - Get results from dialogs via observables\r\n * - Manage multiple open dialogs\r\n * - Automatic focus management and accessibility\r\n *\r\n * ## Usage\r\n *\r\n * ### Opening a Component Dialog\r\n * ```typescript\r\n * const dialogRef = this.dialog.open(MyDialogComponent, {\r\n * width: '400px',\r\n * data: { name: 'John' }\r\n * });\r\n *\r\n * dialogRef.afterClosed().subscribe(result => {\r\n * console.log('Dialog result:', result);\r\n * });\r\n * ```\r\n *\r\n * ### Opening a Template Dialog\r\n * ```typescript\r\n * const dialogRef = this.dialog.open(myTemplateRef, {\r\n * width: '300px',\r\n * hasBackdrop: true\r\n * });\r\n * ```\r\n *\r\n * ### Accessing Data in Dialog Component\r\n * ```typescript\r\n * export class MyDialogComponent {\r\n * private readonly data = inject(FUI_DIALOG_DATA);\r\n * private readonly dialogRef = inject(FuiDialogRef);\r\n *\r\n * onClose() {\r\n * this.dialogRef.close('result');\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class FuiDialogService {\r\n private readonly _overlayService = inject(FuiOverlayService);\r\n private readonly _environmentInjector = inject(EnvironmentInjector);\r\n private readonly _injector = inject(Injector);\r\n private readonly _appRef = inject(ApplicationRef);\r\n\r\n private readonly _openDialogs: IFuiDialogRef[] = [];\r\n private readonly _afterOpenedSubject = new Subject<IFuiDialogRef>();\r\n private readonly _afterAllClosedSubject = new Subject<void>();\r\n\r\n private _nextUniqueId = 0;\r\n\r\n /**\r\n * Observable that emits when a dialog is opened\r\n */\r\n readonly afterOpened: Observable<IFuiDialogRef> = this._afterOpenedSubject.asObservable();\r\n\r\n /**\r\n * Observable that emits when all dialogs are closed\r\n */\r\n readonly afterAllClosed: Observable<void> = defer(() =>\r\n this._openDialogs.length ? this._getAfterAllClosed() : this._getAfterAllClosed().pipe(startWith(undefined)),\r\n );\r\n\r\n /**\r\n * Gets all currently open dialogs\r\n */\r\n get openDialogs(): IFuiDialogRef[] {\r\n return this._openDialogs.slice();\r\n }\r\n\r\n /**\r\n * Opens a dialog containing the given component or template\r\n * @param componentOrTemplateRef Component type or TemplateRef to display\r\n * @param config Configuration options for the dialog\r\n * @returns Reference to the opened dialog\r\n */\r\n open<T, D = unknown, R = unknown>(\r\n componentOrTemplateRef: Type<T> | TemplateRef<T>,\r\n config?: FuiDialogConfig<D>,\r\n ): FuiDialogRef<T, R> {\r\n const mergedConfig = this._applyConfigDefaults(config);\r\n const overlayRef = this._createOverlay(mergedConfig);\r\n const dialogContainer = this._attachDialogContainer(overlayRef, mergedConfig);\r\n const dialogRef = this._createDialogRef<T, R>(overlayRef, dialogContainer, mergedConfig);\r\n\r\n if (componentOrTemplateRef instanceof TemplateRef) {\r\n this._attachTemplateContent(dialogContainer, componentOrTemplateRef, dialogRef);\r\n } else {\r\n const componentRef = this._attachComponentContent<T, R>(\r\n dialogContainer,\r\n componentOrTemplateRef,\r\n dialogRef,\r\n mergedConfig,\r\n );\r\n dialogRef.componentInstance = componentRef.instance;\r\n }\r\n\r\n // Track open dialogs\r\n this._openDialogs.push(dialogRef);\r\n\r\n // Handle dialog close\r\n dialogRef.afterClosed.subscribe(() => {\r\n this._removeOpenDialog(dialogRef);\r\n });\r\n\r\n // Start enter animation and notify opened\r\n dialogContainer._startEnterAnimation();\r\n\r\n // Notify that dialog has been opened\r\n requestAnimationFrame(() => {\r\n dialogRef._notifyOpened();\r\n this._afterOpenedSubject.next(dialogRef);\r\n });\r\n\r\n return dialogRef;\r\n }\r\n\r\n /**\r\n * Closes all open dialogs\r\n */\r\n closeAll(): void {\r\n const dialogs = this._openDialogs.slice();\r\n dialogs.forEach((dialog) => {\r\n dialog.close();\r\n });\r\n }\r\n\r\n /**\r\n * Gets a dialog by its ID\r\n * @param id Dialog ID\r\n * @returns The dialog reference or undefined\r\n */\r\n getDialogById(id: string): IFuiDialogRef | undefined {\r\n return this._openDialogs.find((dialog) => dialog.id === id);\r\n }\r\n\r\n private _createOverlay(config: FuiDialogConfig): FuiOverlayRef {\r\n const overlayConfig = this._getOverlayConfig(config);\r\n return this._overlayService.create(overlayConfig);\r\n }\r\n\r\n private _getOverlayConfig(config: FuiDialogConfig): FuiOverlayConfig {\r\n // Create position strategy\r\n const positionStrategy = this._overlayService.position().global();\r\n\r\n // Apply positioning\r\n if (config.position?.left || config.position?.right) {\r\n if (config.position.left) {\r\n positionStrategy.left(config.position.left);\r\n } else if (config.position.right) {\r\n positionStrategy.right(config.position.right);\r\n }\r\n } else {\r\n positionStrategy.centerHorizontally();\r\n }\r\n\r\n if (config.position?.top || config.position?.bottom) {\r\n if (config.position.top) {\r\n positionStrategy.top(config.position.top);\r\n } else if (config.position.bottom) {\r\n positionStrategy.bottom(config.position.bottom);\r\n }\r\n } else {\r\n positionStrategy.centerVertically();\r\n }\r\n\r\n return {\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.block(),\r\n hasBackdrop: config.hasBackdrop ?? true,\r\n backdropClass: this._getBackdropClass(config),\r\n backdropClickBehavior: config.disableClose ? 'ignore' : 'close',\r\n panelClass: this._getPanelClass(config),\r\n width: config.width,\r\n height: config.height,\r\n minWidth: config.minWidth,\r\n minHeight: config.minHeight,\r\n maxWidth: config.maxWidth,\r\n maxHeight: config.maxHeight,\r\n direction: config.direction,\r\n };\r\n }\r\n\r\n private _getBackdropClass(config: FuiDialogConfig): string[] {\r\n const baseClass = 'fui-dialog-backdrop';\r\n let customClasses: string[] = [];\r\n if (config.backdropClass) {\r\n customClasses = Array.isArray(config.backdropClass) ? config.backdropClass : [config.backdropClass];\r\n }\r\n\r\n return [baseClass, ...customClasses];\r\n }\r\n\r\n private _getPanelClass(config: FuiDialogConfig): string[] {\r\n const baseClass = 'fui-dialog-panel';\r\n let customPanelClasses: string[] = [];\r\n if (config.panelClass) {\r\n customPanelClasses = Array.isArray(config.panelClass) ? config.panelClass : [config.panelClass];\r\n }\r\n\r\n return [baseClass, ...customPanelClasses];\r\n }\r\n\r\n private _attachDialogContainer(overlayRef: FuiOverlayRef, config: FuiDialogConfig): FuiDialogContainerComponent {\r\n const containerRef = createComponent(FuiDialogContainerComponent, {\r\n environmentInjector: this._environmentInjector,\r\n });\r\n\r\n // Initialize the container with config\r\n containerRef.instance._initializeWithConfig(config);\r\n\r\n // Trigger change detection\r\n containerRef.changeDetectorRef.detectChanges();\r\n\r\n // Attach to overlay\r\n overlayRef.attach(containerRef);\r\n\r\n return containerRef.instance;\r\n }\r\n\r\n private _createDialogRef<T, R>(\r\n overlayRef: FuiOverlayRef,\r\n container: FuiDialogContainerComponent,\r\n config: FuiDialogConfig,\r\n ): FuiDialogRef<T, R> {\r\n const dialogId = config.id ?? `fui-dialog-${this._nextUniqueId++}`;\r\n return new FuiDialogRef<T, R>(overlayRef, config, dialogId);\r\n }\r\n\r\n private _attachComponentContent<T, R>(\r\n container: FuiDialogContainerComponent,\r\n component: Type<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n config: FuiDialogConfig,\r\n ): ComponentRef<T> {\r\n return this._createAndAttachContentComponent(\r\n component,\r\n dialogRef,\r\n config,\r\n (el) => {\r\n const hostElement = container._getHostElement();\r\n const containerElement = hostElement.querySelector('.fui-dialog-container');\r\n if (containerElement) {\r\n containerElement.appendChild(el);\r\n }\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Shared helper: creates a component with dialog/drawer data and ref providers,\r\n * attaches it to ApplicationRef for change detection, runs initial CD, and\r\n * delegates DOM insertion to the provided callback.\r\n */\r\n private _createAndAttachContentComponent<T, R>(\r\n component: Type<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n config: { data?: unknown; injector?: Injector },\r\n appendTo: (nativeElement: HTMLElement) => void,\r\n ): ComponentRef<T> {\r\n const providers: StaticProvider[] = [\r\n { provide: FUI_DIALOG_DATA, useValue: config.data },\r\n { provide: FuiDialogRef, useValue: dialogRef },\r\n ];\r\n\r\n const injector = Injector.create({\r\n parent: config.injector ?? this._injector,\r\n providers,\r\n });\r\n\r\n const componentRef = createComponent(component, {\r\n environmentInjector: this._environmentInjector,\r\n elementInjector: injector,\r\n });\r\n\r\n // Attach to ApplicationRef to connect it to Angular's change detection tree\r\n this._appRef.attachView(componentRef.hostView);\r\n\r\n // Delegate DOM insertion to caller\r\n appendTo(componentRef.location.nativeElement);\r\n\r\n componentRef.changeDetectorRef.detectChanges();\r\n\r\n return componentRef;\r\n }\r\n\r\n private _attachTemplateContent<T, R>(\r\n container: FuiDialogContainerComponent,\r\n template: TemplateRef<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n ): EmbeddedViewRef<T> {\r\n // Create the embedded view\r\n const context = { $implicit: dialogRef } as Record<string, unknown>;\r\n const viewRef = template.createEmbeddedView(context as T);\r\n\r\n // Attach to ApplicationRef to connect it to Angular's change detection tree\r\n this._appRef.attachView(viewRef);\r\n\r\n // Append to container\r\n const hostElement = container._getHostElement();\r\n const containerElement = hostElement.querySelector('.fui-dialog-container');\r\n if (containerElement) {\r\n viewRef.rootNodes.forEach((node) => {\r\n containerElement.appendChild(node);\r\n });\r\n }\r\n\r\n // Mark for check\r\n viewRef.detectChanges();\r\n\r\n return viewRef;\r\n }\r\n\r\n private _removeOpenDialog(dialogRef: IFuiDialogRef): void {\r\n const index = this._openDialogs.indexOf(dialogRef);\r\n if (index > -1) {\r\n this._openDialogs.splice(index, 1);\r\n\r\n // Emit if all dialogs are closed\r\n if (this._openDialogs.length === 0) {\r\n this._afterAllClosedSubject.next();\r\n }\r\n }\r\n }\r\n\r\n private _getAfterAllClosed(): Observable<void> {\r\n return this._afterAllClosedSubject.asObservable();\r\n }\r\n\r\n /**\r\n * Opens a component or template as a drawer that slides in from the specified\r\n * viewport edge. Built on the same overlay infrastructure as `open()`, but\r\n * anchored to the viewport edge with a slide animation instead of a centered modal.\r\n *\r\n * @param componentOrTemplateRef Component type or TemplateRef to display\r\n * @param config Configuration options for the drawer (position, size, etc.)\r\n * @returns Reference to the opened drawer (same lifecycle API as a dialog)\r\n *\r\n * ## Usage\r\n * ```typescript\r\n * const drawerRef = this.dialog.openAsDrawer(MyPanelComponent, {\r\n * position: 'right',\r\n * size: 'md',\r\n * title: 'Settings'\r\n * });\r\n * drawerRef.afterClosed().subscribe(result => console.log(result));\r\n * ```\r\n */\r\n openAsDrawer<T, D = unknown, R = unknown>(\r\n componentOrTemplateRef: Type<T> | TemplateRef<T>,\r\n config?: FuiDrawerConfig<D>,\r\n ): FuiDialogRef<T, R> {\r\n const mergedConfig = this._applyDrawerConfigDefaults(config);\r\n const overlayRef = this._createDrawerOverlay(mergedConfig);\r\n const drawerContainer = this._attachDrawerContainer(overlayRef, mergedConfig);\r\n const dialogRef = this._createDialogRef<T, R>(overlayRef, drawerContainer as unknown as FuiDialogContainerComponent, mergedConfig as unknown as FuiDialogConfig);\r\n\r\n if (componentOrTemplateRef instanceof TemplateRef) {\r\n this._attachTemplateContent(\r\n drawerContainer as unknown as FuiDialogContainerComponent,\r\n componentOrTemplateRef,\r\n dialogRef,\r\n );\r\n } else {\r\n const componentRef = this._attachDrawerComponentContent<T, R>(\r\n drawerContainer,\r\n componentOrTemplateRef,\r\n dialogRef,\r\n mergedConfig,\r\n );\r\n dialogRef.componentInstance = componentRef.instance;\r\n }\r\n\r\n // Listen for drawer close button click\r\n const subscription = drawerContainer.closed.subscribe(() => {\r\n dialogRef.close();\r\n subscription.unsubscribe();\r\n });\r\n\r\n // Track open dialogs\r\n this._openDialogs.push(dialogRef);\r\n\r\n dialogRef.afterClosed.subscribe(() => {\r\n this._removeOpenDialog(dialogRef);\r\n });\r\n\r\n // Notify opened\r\n requestAnimationFrame(() => {\r\n dialogRef._notifyOpened();\r\n this._afterOpenedSubject.next(dialogRef);\r\n });\r\n\r\n return dialogRef;\r\n }\r\n\r\n /**\r\n * Opens a confirmation dialog and returns an Observable<boolean>.\r\n * Resolves to `true` when confirmed, `false` when cancelled, ESC, or backdrop click.\r\n */\r\n confirm(config: FuiConfirmDialogConfig): Observable<boolean> {\r\n const dialogRef = this.open(FuiConfirmDialogComponent, {\r\n width: '28rem',\r\n maxWidth: '90vw',\r\n data: config,\r\n role: config.variant === 'danger' ? 'alertdialog' : 'dialog',\r\n ariaLabelledBy: 'confirm-dialog-title',\r\n ariaDescribedBy: 'confirm-dialog-description',\r\n disableClose: false,\r\n });\r\n\r\n return dialogRef.afterClosed.pipe(map((result) => result === true));\r\n }\r\n\r\n // ── Drawer-specific helpers ──\r\n\r\n private _createDrawerOverlay(config: FuiDrawerConfig): FuiOverlayRef {\r\n const overlayConfig = this._getDrawerOverlayConfig(config);\r\n return this._overlayService.create(overlayConfig);\r\n }\r\n\r\n private _getDrawerOverlayConfig(config: FuiDrawerConfig): FuiOverlayConfig {\r\n const position = config.position ?? 'right';\r\n const sizeValue = this._resolveDrawerSize(config.size);\r\n const isHorizontal = position === 'left' || position === 'right';\r\n\r\n const positionStrategy = this._overlayService.position().global();\r\n\r\n // Anchor to viewport edge\r\n switch (position) {\r\n case 'left':\r\n positionStrategy.left('0').top('0');\r\n break;\r\n case 'right':\r\n positionStrategy.right('0').top('0');\r\n break;\r\n case 'top':\r\n positionStrategy.top('0').left('0');\r\n break;\r\n case 'bottom':\r\n positionStrategy.bottom('0').left('0');\r\n break;\r\n }\r\n\r\n // Set the drawer dimension (width for left/right, height for top/bottom)\r\n if (isHorizontal) {\r\n positionStrategy.width(sizeValue);\r\n positionStrategy.height('100%');\r\n } else {\r\n positionStrategy.height(sizeValue);\r\n positionStrategy.width('100%');\r\n }\r\n\r\n return {\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.block(),\r\n hasBackdrop: config.hasBackdrop ?? true,\r\n backdropClass: this._getDrawerBackdropClass(config),\r\n backdropClickBehavior: config.disableClose ? 'ignore' : 'close',\r\n panelClass: this._getDrawerPanelClass(config),\r\n direction: config.direction,\r\n };\r\n }\r\n\r\n private _attachDrawerContainer(\r\n overlayRef: FuiOverlayRef,\r\n config: FuiDrawerConfig,\r\n ): FuiDialogDrawerContainerComponent {\r\n const containerRef = createComponent(FuiDialogDrawerContainerComponent, {\r\n environmentInjector: this._environmentInjector,\r\n });\r\n\r\n const instance = containerRef.instance;\r\n instance.position = config.position ?? 'right';\r\n instance.title = config.title ?? null;\r\n instance.showCloseButton = config.showCloseButton ?? true;\r\n instance.ariaLabel = config.ariaLabel ?? null;\r\n instance.ariaLabelledBy = config.ariaLabelledBy ?? null;\r\n\r\n containerRef.changeDetectorRef.detectChanges();\r\n overlayRef.attach(containerRef);\r\n\r\n return instance;\r\n }\r\n\r\n private _attachDrawerComponentContent<T, R>(\r\n container: FuiDialogDrawerContainerComponent,\r\n component: Type<T>,\r\n dialogRef: FuiDialogRef<T, R>,\r\n config: FuiDrawerConfig,\r\n ): ComponentRef<T> {\r\n return this._createAndAttachContentComponent(\r\n component,\r\n dialogRef,\r\n config,\r\n (el) => { container._appendToContent(el); },\r\n );\r\n }\r\n\r\n private _resolveDrawerSize(size?: DrawerSize | string): string {\r\n if (!size) {\r\n return DRAWER_SIZE_VALUES.md;\r\n }\r\n return DRAWER_SIZE_VALUES[size as DrawerSize] ?? size;\r\n }\r\n\r\n private _getDrawerBackdropClass(config: FuiDrawerConfig): string[] {\r\n const baseClass = 'fui-drawer-service-backdrop';\r\n const customClasses: string[] = config.backdropClass\r\n ? Array.isArray(config.backdropClass)\r\n ? config.backdropClass\r\n : [config.backdropClass]\r\n : [];\r\n return [baseClass, ...customClasses];\r\n }\r\n\r\n private _getDrawerPanelClass(config: FuiDrawerConfig): string[] {\r\n const baseClass = 'fui-drawer-service-panel-container';\r\n const customClasses: string[] = config.panelClass\r\n ? Array.isArray(config.panelClass)\r\n ? config.panelClass\r\n : [config.panelClass]\r\n : [];\r\n return [baseClass, ...customClasses];\r\n }\r\n\r\n private _applyDrawerConfigDefaults(config?: FuiDrawerConfig): FuiDrawerConfig {\r\n return {\r\n position: 'right',\r\n size: 'md',\r\n showCloseButton: true,\r\n hasBackdrop: true,\r\n disableClose: false,\r\n restoreFocus: true,\r\n ...config,\r\n };\r\n }\r\n\r\n // ── End drawer-specific helpers ──\r\n\r\n private _applyConfigDefaults(config?: FuiDialogConfig): FuiDialogConfig {\r\n return {\r\n role: 'dialog',\r\n hasBackdrop: true,\r\n disableClose: false,\r\n maxWidth: '80vw',\r\n autoFocus: 'first-tabbable',\r\n restoreFocus: true,\r\n closeOnNavigation: true,\r\n enterAnimationDuration: 200,\r\n exitAnimationDuration: 150,\r\n ...config,\r\n };\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -56,10 +56,19 @@ class FuiNotificationContainerComponent {
56
56
  * Progress values for each notification (0-100)
57
57
  */
58
58
  progressValues = signal(new Map(), ...(ngDevMode ? [{ debugName: "progressValues" }] : /* istanbul ignore next */ []));
59
+ static UPDATE_INTERVAL_MS = 50;
59
60
  /**
60
- * Timers for auto-dismiss
61
+ * Per-notification timer state for auto-dismiss. Holds the active interval+timeout pair
62
+ * plus the metadata needed to compute remaining duration when pause/resume cycles occur.
61
63
  */
62
- timers = new Map();
64
+ _timerStates = new Map();
65
+ /**
66
+ * Per-notification interaction counter. Increments on mouseenter/focusin, decrements on
67
+ * mouseleave/focusout. Timer is paused when count goes 0→1, resumed when 1→0.
68
+ * Why: hover and focus can overlap (e.g. user hovers, then tabs into the close button).
69
+ * A single boolean flag would resume too early when one source leaves but the other holds.
70
+ */
71
+ _interactionCounts = new Map();
63
72
  constructor() {
64
73
  // Set up effect to manage timers when notifications change
65
74
  effect(() => {
@@ -110,49 +119,104 @@ class FuiNotificationContainerComponent {
110
119
  const duration = notification.config.duration ?? 5000;
111
120
  return duration > 0;
112
121
  }
122
+ /**
123
+ * Increment the interaction count for a notification. Called on mouseenter and focusin.
124
+ * Pauses the timer when the count transitions from 0 to 1.
125
+ */
126
+ onInteractionEnter(notificationId) {
127
+ const newCount = (this._interactionCounts.get(notificationId) ?? 0) + 1;
128
+ this._interactionCounts.set(notificationId, newCount);
129
+ if (newCount === 1) {
130
+ this._pauseTimer(notificationId);
131
+ }
132
+ }
133
+ /**
134
+ * Decrement the interaction count for a notification. Called on mouseleave and focusout.
135
+ * Resumes the timer when the count transitions back to 0.
136
+ */
137
+ onInteractionLeave(notificationId) {
138
+ const newCount = Math.max(0, (this._interactionCounts.get(notificationId) ?? 0) - 1);
139
+ this._interactionCounts.set(notificationId, newCount);
140
+ if (newCount === 0) {
141
+ this._resumeTimer(notificationId);
142
+ }
143
+ }
113
144
  _setupAutoDismiss(notification, duration) {
114
145
  const startTime = Date.now();
115
- const updateInterval = 50; // Update progress every 50ms for smooth animation
116
- // Update progress bar
117
- const interval = setInterval(() => {
118
- const elapsed = Date.now() - startTime;
119
- const progress = Math.max(0, 100 - (elapsed / duration) * 100);
120
- this.progressValues.update((values) => {
121
- const newValues = new Map(values);
122
- newValues.set(notification.id, progress);
123
- return newValues;
124
- });
125
- if (progress <= 0) {
126
- clearInterval(interval);
127
- }
128
- }, updateInterval);
129
- // Auto-dismiss after duration
146
+ const interval = this._startProgressInterval(notification.id, startTime, duration);
130
147
  const timeout = setTimeout(() => {
131
148
  notification.close();
132
149
  }, duration);
133
- this.timers.set(notification.id, { interval, timeout });
150
+ this._timerStates.set(notification.id, {
151
+ interval,
152
+ timeout,
153
+ notification,
154
+ originalDuration: duration,
155
+ isPaused: false,
156
+ });
134
157
  }
135
158
  _removeNotification(notification) {
136
- // Clear timers
137
- const timers = this.timers.get(notification.id);
138
- if (timers) {
139
- clearInterval(timers.interval);
140
- clearTimeout(timers.timeout);
141
- this.timers.delete(notification.id);
159
+ const state = this._timerStates.get(notification.id);
160
+ if (state) {
161
+ clearInterval(state.interval);
162
+ clearTimeout(state.timeout);
163
+ this._timerStates.delete(notification.id);
142
164
  }
143
- // Remove from progress map
165
+ this._interactionCounts.delete(notification.id);
144
166
  this.progressValues.update((values) => {
145
167
  const newValues = new Map(values);
146
168
  newValues.delete(notification.id);
147
169
  return newValues;
148
170
  });
149
- // Remove from notifications list
150
171
  this.notifications.update((notifications) => notifications.filter((n) => n.id !== notification.id));
151
- // Notify that notification is dismissed
152
172
  notification._dismiss();
153
173
  }
174
+ _pauseTimer(notificationId) {
175
+ const state = this._timerStates.get(notificationId);
176
+ if (!state || state.isPaused)
177
+ return;
178
+ clearInterval(state.interval);
179
+ clearTimeout(state.timeout);
180
+ state.isPaused = true;
181
+ }
182
+ _resumeTimer(notificationId) {
183
+ const state = this._timerStates.get(notificationId);
184
+ if (!state?.isPaused)
185
+ return;
186
+ state.isPaused = false;
187
+ // Compute remaining duration from current progress (0-100)
188
+ const currentProgress = this.progressValues().get(notificationId) ?? 100;
189
+ const remainingDuration = (currentProgress / 100) * state.originalDuration;
190
+ if (remainingDuration <= 0) {
191
+ state.notification.close();
192
+ return;
193
+ }
194
+ // Restart the progress interval from current progress
195
+ const elapsedBeforeResume = state.originalDuration - remainingDuration;
196
+ const newStartTime = Date.now() - elapsedBeforeResume;
197
+ const newInterval = this._startProgressInterval(notificationId, newStartTime, state.originalDuration);
198
+ const newTimeout = setTimeout(() => {
199
+ state.notification.close();
200
+ }, remainingDuration);
201
+ state.interval = newInterval;
202
+ state.timeout = newTimeout;
203
+ }
204
+ _startProgressInterval(notificationId, startTime, totalDuration) {
205
+ const interval = setInterval(() => {
206
+ const elapsed = Date.now() - startTime;
207
+ const progress = Math.max(0, 100 - (elapsed / totalDuration) * 100);
208
+ this.progressValues.update((values) => {
209
+ const newValues = new Map(values);
210
+ newValues.set(notificationId, progress);
211
+ return newValues;
212
+ });
213
+ if (progress <= 0)
214
+ clearInterval(interval);
215
+ }, FuiNotificationContainerComponent.UPDATE_INTERVAL_MS);
216
+ return interval;
217
+ }
154
218
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
155
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiNotificationContainerComponent, isStandalone: true, selector: "fui-notification-container", host: { attributes: { "role": "log", "aria-live": "polite", "aria-atomic": "false" }, classAttribute: "fui-notification-container" }, ngImport: i0, template: "<div class=\"fui-notification-container__stack\">\r\n @for (notification of notifications(); track notification.id) {\r\n <div class=\"fui-notification-container__item\" role=\"alert\" aria-atomic=\"true\">\r\n <fui-alert\r\n [variant]=\"notification.config.variant\"\r\n [title]=\"notification.config.title\"\r\n [description]=\"notification.config.description ?? null\"\r\n [closeable]=\"notification.config.closeable ?? true\"\r\n [icon]=\"notification.config.icon ?? null\"\r\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\r\n (closed)=\"onNotificationClose(notification)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-border-radius-md);--fui-notification-shadow: var(--fui-shadow-03);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-05);--fui-notification-gap: var(--fui-spacing-04);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-04)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition:all var(--fui-duration-moderate-01) var(--fui-ease-standard) 0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-04));padding:0 var(--fui-spacing-05) var(--fui-spacing-03)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: FuiAlertComponent, selector: "fui-alert", inputs: ["variant", "title", "progress", "description", "closeable", "icon"], outputs: ["closed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
219
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiNotificationContainerComponent, isStandalone: true, selector: "fui-notification-container", host: { attributes: { "role": "log", "aria-live": "polite", "aria-atomic": "false" }, classAttribute: "fui-notification-container" }, ngImport: i0, template: "<div class=\"fui-notification-container__stack\">\r\n @for (notification of notifications(); track notification.id) {\r\n <div\r\n class=\"fui-notification-container__item\"\r\n role=\"alert\"\r\n aria-atomic=\"true\"\r\n (mouseenter)=\"onInteractionEnter(notification.id)\"\r\n (mouseleave)=\"onInteractionLeave(notification.id)\"\r\n (focusin)=\"onInteractionEnter(notification.id)\"\r\n (focusout)=\"onInteractionLeave(notification.id)\"\r\n >\r\n <fui-alert\r\n [variant]=\"notification.config.variant\"\r\n [title]=\"notification.config.title\"\r\n [description]=\"notification.config.description ?? null\"\r\n [closeable]=\"notification.config.closeable ?? true\"\r\n [icon]=\"notification.config.icon ?? null\"\r\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\r\n (closed)=\"onNotificationClose(notification)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-radius-md);--fui-notification-shadow: var(--fui-shadow-md);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-7);--fui-notification-gap: var(--fui-spacing-6);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-6)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition-property:all;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-6));padding:0 var(--fui-spacing-7) var(--fui-spacing-4)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: FuiAlertComponent, selector: "fui-alert", inputs: ["variant", "title", "progress", "description", "closeable", "icon"], outputs: ["closed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
156
220
  }
157
221
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNotificationContainerComponent, decorators: [{
158
222
  type: Component,
@@ -161,7 +225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
161
225
  role: 'log',
162
226
  'aria-live': 'polite',
163
227
  'aria-atomic': 'false',
164
- }, template: "<div class=\"fui-notification-container__stack\">\r\n @for (notification of notifications(); track notification.id) {\r\n <div class=\"fui-notification-container__item\" role=\"alert\" aria-atomic=\"true\">\r\n <fui-alert\r\n [variant]=\"notification.config.variant\"\r\n [title]=\"notification.config.title\"\r\n [description]=\"notification.config.description ?? null\"\r\n [closeable]=\"notification.config.closeable ?? true\"\r\n [icon]=\"notification.config.icon ?? null\"\r\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\r\n (closed)=\"onNotificationClose(notification)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-border-radius-md);--fui-notification-shadow: var(--fui-shadow-03);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-05);--fui-notification-gap: var(--fui-spacing-04);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-04)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition:all var(--fui-duration-moderate-01) var(--fui-ease-standard) 0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-04));padding:0 var(--fui-spacing-05) var(--fui-spacing-03)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
228
+ }, template: "<div class=\"fui-notification-container__stack\">\r\n @for (notification of notifications(); track notification.id) {\r\n <div\r\n class=\"fui-notification-container__item\"\r\n role=\"alert\"\r\n aria-atomic=\"true\"\r\n (mouseenter)=\"onInteractionEnter(notification.id)\"\r\n (mouseleave)=\"onInteractionLeave(notification.id)\"\r\n (focusin)=\"onInteractionEnter(notification.id)\"\r\n (focusout)=\"onInteractionLeave(notification.id)\"\r\n >\r\n <fui-alert\r\n [variant]=\"notification.config.variant\"\r\n [title]=\"notification.config.title\"\r\n [description]=\"notification.config.description ?? null\"\r\n [closeable]=\"notification.config.closeable ?? true\"\r\n [icon]=\"notification.config.icon ?? null\"\r\n [progress]=\"shouldShowProgress(notification) ? getProgress(notification.id) : -1\"\r\n (closed)=\"onNotificationClose(notification)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-notification-container{--fui-notification-bg: transparent;--fui-notification-radius: var(--fui-radius-md);--fui-notification-shadow: var(--fui-shadow-md);--fui-notification-shadow-hover: var(--fui-shadow-lg);--fui-notification-z-index: 9999;--fui-notification-padding: var(--fui-spacing-7);--fui-notification-gap: var(--fui-spacing-6);--fui-notification-min-width: 320px;--fui-notification-max-width: 500px;position:fixed;pointer-events:none;z-index:var(--fui-notification-z-index);display:flex;flex-direction:column;padding:var(--fui-notification-padding);gap:var(--fui-notification-gap)}.fui-notification-container__stack{display:flex;flex-direction:column;gap:var(--fui-spacing-6)}.fui-notification-container__item{pointer-events:auto;min-width:var(--fui-notification-min-width);max-width:var(--fui-notification-max-width);background-color:var(--fui-notification-bg);border-radius:var(--fui-notification-radius);box-shadow:var(--fui-notification-shadow);animation:slideIn .3s ease-out;transition-property:all;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-notification-container__item:hover{transform:translateY(-2px);box-shadow:var(--fui-notification-shadow-hover)}.fui-notification-container__progress{margin-top:calc(-1 * var(--fui-spacing-6));padding:0 var(--fui-spacing-7) var(--fui-spacing-4)}@media(prefers-reduced-motion:reduce){.fui-notification-container .fui-notification-container__item{animation:none;transition:none}.fui-notification-container .fui-notification-container__item:hover{transform:none}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fui-notification-container--top-left{top:0;left:0;align-items:flex-start}.fui-notification-container--top-center{top:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--top-right{top:0;right:0;align-items:flex-end}.fui-notification-container--bottom-left{bottom:0;left:0;align-items:flex-start}.fui-notification-container--bottom-left .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-left .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-center{bottom:0;left:50%;transform:translate(-50%);align-items:center}.fui-notification-container--bottom-center .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-center .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}.fui-notification-container--bottom-right{bottom:0;right:0;align-items:flex-end}.fui-notification-container--bottom-right .fui-notification-container__stack{flex-direction:column-reverse}.fui-notification-container--bottom-right .fui-notification-container__item{animation:slideInFromBottom .3s ease-out}@keyframes slideInFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
165
229
  }], ctorParameters: () => [] });
166
230
 
167
231
  /**