@raintonic/formaui 0.4.0 → 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 +19 -1
  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-components-autocomplete.mjs","sources":["../../../lib/components/autocomplete/autocomplete.intl.ts","../../../lib/components/autocomplete/autocomplete.component.ts","../../../lib/components/autocomplete/autocomplete.component.html","../../../lib/components/autocomplete/raintonic-formaui-components-autocomplete.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiAutocompleteIntl extends FuiIntlBase {\r\n addButtonLabel = 'Add New';\r\n refreshButtonLabel = 'Refresh';\r\n noOptionsText = 'No options found';\r\n searchPlaceholder = 'Search...';\r\n clearSelectionAriaLabel = 'Clear selection';\r\n noResultsAvailableText = 'No results available.';\r\n\r\n resultsAvailableText(count: number): string {\r\n return `${count} results available.`;\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n computed,\r\n contentChildren,\r\n DoCheck,\r\n effect,\r\n ElementRef,\r\n inject,\r\n InjectionToken,\r\n NgZone,\r\n input,\r\n InputSignal,\r\n OnDestroy,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n Signal,\r\n ViewChild,\r\n ViewEncapsulation,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport {\r\n ControlValueAccessor,\r\n FormGroupDirective,\r\n NG_VALUE_ACCESSOR,\r\n NgControl,\r\n NgForm,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { fromEvent, Subject, Subscription } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport { FuiOptionComponent } from '@raintonic/formaui/components/select';\r\nimport { FuiOverlayService, FuiOverlayRef, FuiConnectedPosition } from '@raintonic/formaui/cdk/overlay';\r\nimport { FuiAutocompleteIntl } from './autocomplete.intl';\r\n\r\n/**\r\n * Injection token used to provide the parent autocomplete to options\r\n */\r\nexport const FUI_AUTOCOMPLETE = new InjectionToken<FuiAutocompleteComponent>('FUI_AUTOCOMPLETE');\r\n\r\n/**\r\n * Selection change event object emitted when the autocomplete's selection changes\r\n */\r\nexport interface FuiAutocompleteChange {\r\n source: FuiAutocompleteComponent;\r\n value: unknown;\r\n}\r\n\r\n/**\r\n * # fui-autocomplete Component\r\n *\r\n * An autocomplete component designed to work seamlessly with fui-form-field.\r\n * Similar to Angular Material's mat-autocomplete integration with mat-form-field.\r\n * Provides full Reactive Forms support with validation, filtering, and optional\r\n * add/refresh actions.\r\n *\r\n * ## Features\r\n * - Works inside fui-form-field like mat-autocomplete\r\n * - Full Reactive Forms integration (ControlValueAccessor)\r\n * - Options via projected content (fui-option)\r\n * - Built-in search/filter input in the panel\r\n * - Optional \"Add New\" and \"Refresh\" action buttons\r\n * - Disabled and readonly states\r\n * - Full accessibility support\r\n * - Full keyboard navigation (Arrow keys, Enter, Escape, Home, End, PageUp, PageDown)\r\n * - Uses overlay service for proper positioning\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Autocomplete with Form Field\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-autocomplete placeholder=\"Search countries...\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * <fui-option value=\"mx\">Mexico</fui-option>\r\n * </fui-autocomplete>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With Reactive Forms and Validation\r\n * ```html\r\n * <form [formGroup]=\"form\">\r\n * <fui-form-field>\r\n * <label>Country</label>\r\n * <fui-autocomplete formControlName=\"country\" placeholder=\"Select a country\">\r\n * <fui-option value=\"us\">United States</fui-option>\r\n * <fui-option value=\"ca\">Canada</fui-option>\r\n * </fui-autocomplete>\r\n * <fui-error *ngIf=\"form.get('country')?.hasError('required')\">\r\n * Country is required\r\n * </fui-error>\r\n * </fui-form-field>\r\n * </form>\r\n * ```\r\n *\r\n * ### With Add/Refresh Buttons\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Category</label>\r\n * <fui-autocomplete\r\n * placeholder=\"Search categories...\"\r\n * [showAddButton]=\"true\"\r\n * [showRefreshButton]=\"true\"\r\n * (addNew)=\"openAddCategoryDialog()\"\r\n * (refresh)=\"refreshCategories()\">\r\n * @for (category of categories; track category.id) {\r\n * <fui-option [value]=\"category.id\">{{ category.name }}</fui-option>\r\n * }\r\n * </fui-autocomplete>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-autocomplete',\r\n standalone: true,\r\n imports: [FuiIconComponent, ReactiveFormsModule, FuiButtonDirective],\r\n templateUrl: './autocomplete.component.html',\r\n styleUrls: ['./autocomplete.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-autocomplete',\r\n '[attr.id]': 'id',\r\n '[class.fui-autocomplete--open]': 'panelOpen()',\r\n '[class.fui-autocomplete--disabled]': 'disabled()',\r\n '[class.fui-autocomplete--focused]': 'focused()',\r\n '[class.fui-autocomplete--error]': 'errorState()',\r\n '[class.fui-autocomplete--readonly]': '_readOnly()',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiAutocompleteComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiAutocompleteComponent,\r\n },\r\n {\r\n provide: FUI_AUTOCOMPLETE,\r\n useExisting: FuiAutocompleteComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiAutocompleteComponent implements ControlValueAccessor, FuiFormFieldControl, DoCheck, OnDestroy {\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-autocomplete';\r\n\r\n // Injected dependencies required by input resolvers (must be declared before computed fields below)\r\n readonly intl = inject(FuiAutocompleteIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n // Inputs using signal-based API\r\n readonly placeholderInput: InputSignal<string> = input('', {\r\n alias: 'placeholder',\r\n });\r\n readonly disabledInput: InputSignal<boolean> = input(false, {\r\n alias: 'disabled',\r\n });\r\n readonly readonly: InputSignal<boolean> = input(false);\r\n readonly showAddButton: InputSignal<boolean> = input(false);\r\n readonly showRefreshButton: InputSignal<boolean> = input(false);\r\n readonly addButtonLabel = input<string | undefined>(undefined);\r\n readonly refreshButtonLabel = input<string | undefined>(undefined);\r\n readonly noOptionsText = input<string | undefined>(undefined);\r\n readonly searchPlaceholder = input<string | undefined>(undefined);\r\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\r\n\r\n // Resolved i18n labels: per-instance input wins, Intl service is fallback\r\n readonly resolvedAddButtonLabel = computed(() => this.addButtonLabel() ?? this.intl.addButtonLabel);\r\n readonly resolvedRefreshButtonLabel = computed(() => this.refreshButtonLabel() ?? this.intl.refreshButtonLabel);\r\n readonly resolvedNoOptionsText = computed(() => this.noOptionsText() ?? this.intl.noOptionsText);\r\n readonly resolvedSearchPlaceholder = computed(() => this.searchPlaceholder() ?? this.intl.searchPlaceholder);\r\n\r\n /**\r\n * Whether to compare option values using object identity or deep equality\r\n */\r\n readonly compareWith: InputSignal<(o1: unknown, o2: unknown) => boolean> = input<\r\n (o1: unknown, o2: unknown) => boolean\r\n >((o1, o2) => o1 === o2);\r\n\r\n // Outputs\r\n readonly valueChange: OutputEmitterRef<unknown> = output<unknown>();\r\n readonly selectionChange: OutputEmitterRef<FuiAutocompleteChange> = output<FuiAutocompleteChange>();\r\n readonly openedChange: OutputEmitterRef<boolean> = output<boolean>();\r\n readonly addNew: OutputEmitterRef<void> = output();\r\n readonly refresh: OutputEmitterRef<void> = output();\r\n readonly searchChange: OutputEmitterRef<string> = output<string>();\r\n\r\n // Internal state signals\r\n private readonly _value: WritableSignal<unknown> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n readonly _readOnly: WritableSignal<boolean> = signal(false);\r\n\r\n // FuiFormFieldControl implementation\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-autocomplete-${FuiAutocompleteComponent.nextId++}`;\r\n _ariaDescribedby: string | null = null;\r\n\r\n // Error state\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n readonly errorState = this._errorState;\r\n\r\n // Form control references\r\n private _parentForm = inject(NgForm, { optional: true });\r\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\r\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\r\n private readonly _ngControlRef = injectNgControl();\r\n get ngControl(): NgControl | null {\r\n return this._ngControlRef.ngControl;\r\n }\r\n\r\n // Interface implementation\r\n readonly placeholder = computed(() => this.placeholderInput());\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n readonly required = this._required;\r\n\r\n readonly value = this._value;\r\n readonly focused = this._focused;\r\n\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\r\n\r\n readonly empty = computed(() => {\r\n const val = this._value();\r\n return val === null || val === undefined;\r\n });\r\n\r\n readonly id = this._uid;\r\n\r\n // ViewChild for trigger and panel\r\n @ViewChild('trigger', { static: false }) trigger?: ElementRef<HTMLDivElement>;\r\n @ViewChild('panel', { static: false }) panel?: ElementRef<HTMLDivElement>;\r\n @ViewChild('searchInput', { static: false })\r\n searchInput?: ElementRef<HTMLInputElement>;\r\n\r\n // ContentChildren for options\r\n readonly options = contentChildren(FuiOptionComponent, { descendants: true });\r\n\r\n // Panel open/close state\r\n readonly panelOpen = signal(false);\r\n\r\n // Search term for filtering\r\n readonly searchTerm: WritableSignal<string> = signal('');\r\n\r\n // Active option index for keyboard navigation\r\n readonly activeOptionIndex: WritableSignal<number> = signal(-1);\r\n\r\n // Live announcement for screen readers\r\n readonly _liveAnnouncement = signal('');\r\n\r\n _announce(message: string): void {\r\n this._liveAnnouncement.set('');\r\n setTimeout(() => {\r\n this._liveAnnouncement.set(message);\r\n }, 50);\r\n }\r\n\r\n // Overlay reference\r\n private _overlayRef: FuiOverlayRef | null = null;\r\n private _overlaySubscriptions = new Subscription();\r\n\r\n // Services\r\n private readonly _overlayService = inject(FuiOverlayService);\r\n private readonly _elementRef = inject(ElementRef);\r\n private readonly _document = inject(DOCUMENT);\r\n private readonly _ngZone = inject(NgZone);\r\n private _outsideClickSub?: Subscription;\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: unknown) => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n private _onTouched: () => void = () => {\r\n // Intentionally empty: will be replaced by Angular forms\r\n };\r\n\r\n // Computed properties\r\n readonly displayValue: Signal<string> = computed(() => {\r\n const currentValue = this.value();\r\n const opts = this.options();\r\n\r\n if (currentValue === null || currentValue === undefined) {\r\n return '';\r\n }\r\n\r\n const selectedOption = opts.find((opt) => this.compareWith()(opt.value(), currentValue));\r\n return selectedOption ? selectedOption.getLabel() : String(currentValue);\r\n });\r\n\r\n // Filtered options based on search term\r\n readonly filteredOptions: Signal<FuiOptionComponent[]> = computed(() => {\r\n const opts = this.options();\r\n const term = this.searchTerm().toLowerCase().trim();\r\n\r\n if (!term) {\r\n return opts.filter((opt) => !opt.disabled());\r\n }\r\n\r\n return opts.filter((opt) => !opt.disabled() && opt.getLabel().toLowerCase().includes(term));\r\n });\r\n\r\n readonly hasFilteredOptions: Signal<boolean> = computed(() => {\r\n return this.filteredOptions().length > 0;\r\n });\r\n\r\n constructor() {\r\n // Set valueAccessor after NgControl is resolved\r\n void Promise.resolve().then(() => {\r\n if (this._ngControlRef.ngControl) {\r\n this._ngControlRef.ngControl.valueAccessor = this;\r\n }\r\n });\r\n\r\n // Subscribe to Intl changes to trigger re-render when labels mutate at runtime\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n // Track all reactive inputs and internal signals\r\n this.placeholderInput();\r\n this.readonly();\r\n this.disabledInput();\r\n this.errorStateMatcher();\r\n this._focused();\r\n this._disabled();\r\n this._value();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n\r\n // Emit state change\r\n this.stateChanges.next();\r\n });\r\n\r\n // Effect to update options selected state when value changes\r\n effect(() => {\r\n const currentValue = this._value();\r\n const opts = this.options();\r\n const compareFn = this.compareWith();\r\n\r\n opts.forEach((option) => {\r\n const optValue = option.value();\r\n const isSelected = compareFn(currentValue, optValue);\r\n\r\n if (isSelected) {\r\n option.select();\r\n } else {\r\n option.deselect();\r\n }\r\n });\r\n\r\n // Notify form-field that state may have changed\r\n this.stateChanges.next();\r\n });\r\n }\r\n\r\n ngDoCheck(): void {\r\n if (this.ngControl) {\r\n updateErrorState(\r\n this.ngControl,\r\n this._errorState,\r\n this.errorStateMatcher(),\r\n this._defaultErrorStateMatcher,\r\n this._parentForm,\r\n this._parentFormGroup,\r\n this.stateChanges,\r\n );\r\n syncRequiredState(this.ngControl, this._required, this.stateChanges);\r\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n this._outsideClickSub?.unsubscribe();\r\n this._disposeOverlay();\r\n }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: unknown): void {\r\n this._value.set(value ?? null);\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this._disabled.set(isDisabled);\r\n this.stateChanges.next();\r\n }\r\n\r\n // FuiFormFieldControl implementation\r\n onContainerClick(_event: MouseEvent): void {\r\n if (!this.disabled()) {\r\n this.toggle();\r\n }\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n }\r\n\r\n setReadOnly(readOnly: boolean): void {\r\n this._readOnly.set(readOnly);\r\n }\r\n\r\n // Public methods\r\n clear(event: Event): void {\r\n event.stopPropagation();\r\n this._value.set(null);\r\n this._onChange(null);\r\n this.valueChange.emit(null);\r\n this.selectionChange.emit({ source: this, value: null });\r\n this.stateChanges.next();\r\n }\r\n\r\n focus(): void {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n\r\n blur(): void {\r\n this.trigger?.nativeElement.blur();\r\n }\r\n\r\n // Toggle panel open/close\r\n toggle(): void {\r\n if (this.disabled()) return;\r\n if (this.panelOpen()) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n }\r\n\r\n // Open the dropdown panel\r\n open(): void {\r\n if (this.disabled() || this.readonly() || this.panelOpen()) return;\r\n\r\n this.panelOpen.set(true);\r\n this._focused.set(true);\r\n this.searchTerm.set('');\r\n this.openedChange.emit(true);\r\n\r\n // Set active option to currently selected or first option\r\n this._setInitialActiveOption();\r\n\r\n // Create overlay after the view updates\r\n setTimeout(() => {\r\n this._createOverlay();\r\n this._scrollToActiveOption();\r\n this._listenForOutsideClicks();\r\n // Focus the search input\r\n this.searchInput?.nativeElement.focus();\r\n }, 0);\r\n }\r\n\r\n // Close the dropdown panel\r\n close(): void {\r\n if (!this.panelOpen()) return;\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n this.panelOpen.set(false);\r\n this._focused.set(false);\r\n this.activeOptionIndex.set(-1);\r\n this.searchTerm.set('');\r\n this._disposeOverlay();\r\n this.openedChange.emit(false);\r\n this._onTouched();\r\n\r\n // Clear active state on all options\r\n this.options().forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n\r\n // Return focus to trigger\r\n setTimeout(() => {\r\n this.trigger?.nativeElement.focus();\r\n }, 0);\r\n }\r\n\r\n // Handle option selection (called by FuiOptionComponent or internally)\r\n _onOptionSelected(option: FuiOptionComponent): void {\r\n const newValue = option.value();\r\n\r\n // Deselect previous option\r\n const opts = this.options();\r\n opts.forEach((opt) => {\r\n if (opt !== option) {\r\n opt.deselect();\r\n }\r\n });\r\n\r\n option.select();\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.selectionChange.emit({ source: this, value: newValue });\r\n this._announce(`${option.getLabel()} selected`);\r\n this.close();\r\n\r\n this.stateChanges.next();\r\n }\r\n\r\n // Handle search input\r\n onSearchInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const term = target.value;\r\n this.searchTerm.set(term);\r\n this.searchChange.emit(term);\r\n\r\n // Reset active index when search changes\r\n const filtered = this.filteredOptions();\r\n if (filtered.length > 0) {\r\n this._setActiveOptionIndex(0);\r\n } else {\r\n this.activeOptionIndex.set(-1);\r\n }\r\n }\r\n\r\n // Handle add new action\r\n onAddNew(): void {\r\n this.close();\r\n this.addNew.emit();\r\n }\r\n\r\n // Handle refresh action\r\n onRefresh(): void {\r\n this.refresh.emit();\r\n // Keep panel open and clear search\r\n this.searchTerm.set('');\r\n }\r\n\r\n // Get display value for trigger\r\n _getDisplayValue(): string {\r\n return this.displayValue();\r\n }\r\n\r\n // Handle keyboard navigation\r\n _handleKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n const isOpen = this.panelOpen();\r\n\r\n if (!isOpen) {\r\n this._handleClosedKeydown(event);\r\n } else {\r\n this._handleOpenKeydown(event);\r\n }\r\n }\r\n\r\n // Handle keydown when panel is closed\r\n private _handleClosedKeydown(event: KeyboardEvent): void {\r\n const key = event.key;\r\n\r\n switch (key) {\r\n case 'Enter':\r\n case ' ':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.open();\r\n break;\r\n }\r\n }\r\n\r\n // Handle keydown when panel is open (for search input)\r\n _handlePanelKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n const key = event.key;\r\n const opts = this.filteredOptions();\r\n const activeIndex = this.activeOptionIndex();\r\n\r\n switch (key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._setNextActiveOption(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._setNextActiveOption(-1);\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n this._setActiveOptionIndex(0);\r\n }\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n this._setActiveOptionIndex(opts.length - 1);\r\n }\r\n break;\r\n case 'PageDown':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n const pageSize = Math.min(10, opts.length);\r\n const newIndex = Math.min(activeIndex + pageSize, opts.length - 1);\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n break;\r\n case 'PageUp':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n const pageSize = Math.min(10, opts.length);\r\n const newIndex = Math.max(activeIndex - pageSize, 0);\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n break;\r\n case 'Enter':\r\n event.preventDefault();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n this._onOptionSelected(opts[activeIndex]);\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n this.close();\r\n break;\r\n case 'Tab':\r\n // Allow tab to close and move to next element\r\n this.close();\r\n break;\r\n }\r\n }\r\n\r\n // Handle keydown when panel is open (for trigger)\r\n private _handleOpenKeydown(event: KeyboardEvent): void {\r\n // Delegate to panel keydown handler\r\n this._handlePanelKeydown(event);\r\n }\r\n\r\n // Set the next active option based on delta\r\n private _setNextActiveOption(delta: number): void {\r\n const opts = this.filteredOptions();\r\n if (opts.length === 0) return;\r\n\r\n let currentIndex = this.activeOptionIndex();\r\n if (currentIndex < 0) {\r\n currentIndex = delta > 0 ? -1 : opts.length;\r\n }\r\n\r\n let newIndex = currentIndex + delta;\r\n\r\n // Wrap around\r\n if (newIndex < 0) {\r\n newIndex = opts.length - 1;\r\n } else if (newIndex >= opts.length) {\r\n newIndex = 0;\r\n }\r\n\r\n this._setActiveOptionIndex(newIndex);\r\n }\r\n\r\n // Set the active option index\r\n private _setActiveOptionIndex(index: number): void {\r\n const opts = this.filteredOptions();\r\n if (index < 0 || index >= opts.length) return;\r\n\r\n // Update active state on options\r\n const allOpts = this.options();\r\n allOpts.forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n\r\n const activeOption = opts[index];\r\n activeOption.setActive();\r\n this.activeOptionIndex.set(index);\r\n this._scrollToActiveOption();\r\n this._announce(`${activeOption.getLabel()}, ${index + 1} of ${opts.length}`);\r\n }\r\n\r\n // Set initial active option when opening\r\n private _setInitialActiveOption(): void {\r\n const opts = this.filteredOptions();\r\n if (opts.length === 0) {\r\n this.activeOptionIndex.set(-1);\r\n return;\r\n }\r\n\r\n const currentValue = this._value();\r\n const compareFn = this.compareWith();\r\n\r\n // Find the selected option\r\n let selectedIndex = -1;\r\n if (currentValue !== null && currentValue !== undefined) {\r\n selectedIndex = opts.findIndex((opt) => compareFn(opt.value(), currentValue));\r\n }\r\n\r\n const initialIndex = selectedIndex >= 0 ? selectedIndex : 0;\r\n this._setActiveOptionIndex(initialIndex);\r\n }\r\n\r\n // Scroll to active option\r\n private _scrollToActiveOption(): void {\r\n const opts = this.filteredOptions();\r\n const activeIndex = this.activeOptionIndex();\r\n\r\n if (activeIndex < 0 || activeIndex >= opts.length) return;\r\n\r\n const activeOption = opts[activeIndex];\r\n const element = activeOption._getHostElement();\r\n const panelElement = this.panel?.nativeElement;\r\n\r\n if (element && panelElement) {\r\n const optionsContainer = panelElement.querySelector('.fui-autocomplete__options');\r\n if (optionsContainer) {\r\n const optionTop = element.offsetTop - (optionsContainer as HTMLElement).offsetTop;\r\n const optionBottom = optionTop + element.offsetHeight;\r\n const containerTop = optionsContainer.scrollTop;\r\n const containerBottom = containerTop + optionsContainer.clientHeight;\r\n\r\n if (optionTop < containerTop) {\r\n optionsContainer.scrollTop = optionTop;\r\n } else if (optionBottom > containerBottom) {\r\n optionsContainer.scrollTop = optionBottom - optionsContainer.clientHeight;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Start listening for outside clicks when panel opens\r\n private _listenForOutsideClicks(): void {\r\n this._outsideClickSub?.unsubscribe();\r\n\r\n this._ngZone.runOutsideAngular(() => {\r\n setTimeout(() => {\r\n this._outsideClickSub = fromEvent<MouseEvent>(this._document, 'click')\r\n .pipe(\r\n filter(() => this.panelOpen()),\r\n filter((event) => {\r\n const target = event.target as HTMLElement;\r\n const triggerElement = this.trigger?.nativeElement;\r\n const panelElement = this.panel?.nativeElement;\r\n const overlayElement = this._overlayRef?.overlayElement;\r\n return (\r\n !triggerElement?.contains(target) &&\r\n !panelElement?.contains(target) &&\r\n !overlayElement?.contains(target)\r\n );\r\n }),\r\n )\r\n .subscribe(() => {\r\n this._ngZone.run(() => {\r\n this.close();\r\n });\r\n });\r\n });\r\n });\r\n }\r\n\r\n // Create overlay for panel\r\n private _createOverlay(): void {\r\n if (this._overlayRef || !this.panel || !this.trigger) return;\r\n\r\n const triggerElement = this.trigger.nativeElement;\r\n const triggerWidth = triggerElement.getBoundingClientRect().width;\r\n\r\n const positions: FuiConnectedPosition[] = [\r\n {\r\n originX: 'start',\r\n originY: 'bottom',\r\n overlayX: 'start',\r\n overlayY: 'top',\r\n offsetY: 4,\r\n },\r\n {\r\n originX: 'start',\r\n originY: 'top',\r\n overlayX: 'start',\r\n overlayY: 'bottom',\r\n offsetY: -4,\r\n },\r\n ];\r\n\r\n const positionStrategy = this._overlayService\r\n .position()\r\n .connectedTo(triggerElement, positions)\r\n .withPush(true)\r\n .withViewportMargin(8);\r\n\r\n this._overlayRef = this._overlayService.create({\r\n positionStrategy,\r\n scrollStrategy: this._overlayService.scrollStrategies.reposition(),\r\n hasBackdrop: true,\r\n backdropClass: 'fui-autocomplete-backdrop',\r\n backdropClickBehavior: 'close',\r\n panelClass: ['fui-autocomplete-overlay-panel'],\r\n minWidth: triggerWidth,\r\n });\r\n\r\n // Track overlay subscriptions for proper cleanup\r\n this._overlaySubscriptions.unsubscribe();\r\n this._overlaySubscriptions = new Subscription();\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.backdropClick.subscribe(() => {\r\n this.close();\r\n }),\r\n );\r\n\r\n this._overlaySubscriptions.add(\r\n this._overlayRef.keydownEvents.subscribe((event) => {\r\n if (event.key === 'Escape') {\r\n this.close();\r\n }\r\n }),\r\n );\r\n\r\n // Attach panel to overlay\r\n const panelElement = this.panel.nativeElement;\r\n this._overlayRef.attach(panelElement);\r\n }\r\n\r\n // Dispose overlay\r\n private _disposeOverlay(): void {\r\n this._overlaySubscriptions.unsubscribe();\r\n if (this._overlayRef) {\r\n this._overlayRef.dispose();\r\n this._overlayRef = null;\r\n }\r\n }\r\n\r\n // Get the active option's id for aria-activedescendant\r\n _getActiveDescendant(): string | null {\r\n const opts = this.filteredOptions();\r\n const activeIndex = this.activeOptionIndex();\r\n if (activeIndex >= 0 && activeIndex < opts.length) {\r\n return opts[activeIndex].id;\r\n }\r\n return null;\r\n }\r\n\r\n // Set active option by index (for template use)\r\n setActiveOption(index: number, option: FuiOptionComponent): void {\r\n const allOpts = this.options();\r\n allOpts.forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n option.setActive();\r\n this.activeOptionIndex.set(index);\r\n }\r\n\r\n // Mat-autocomplete compatibility methods\r\n get selected(): unknown {\r\n return this.value;\r\n }\r\n}\r\n","<!-- Autocomplete Trigger -->\r\n<div\r\n #trigger\r\n [id]=\"id\"\r\n class=\"fui-autocomplete__trigger\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n [attr.role]=\"'combobox'\"\r\n [attr.aria-haspopup]=\"'listbox'\"\r\n [attr.aria-expanded]=\"panelOpen()\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n [attr.aria-required]=\"required()\"\r\n aria-autocomplete=\"list\"\r\n [attr.aria-activedescendant]=\"panelOpen() ? _getActiveDescendant() : null\"\r\n [attr.aria-controls]=\"panelOpen() ? id + '-panel' : null\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n>\r\n <span class=\"fui-autocomplete__value\">\r\n @if (empty()) {\r\n <span class=\"fui-autocomplete__placeholder\">{{ placeholder() }}</span>\r\n } @else {\r\n <span class=\"fui-autocomplete__value-text\">{{ _getDisplayValue() }}</span>\r\n }\r\n </span>\r\n\r\n @if (!_readOnly()) {\r\n <!-- Clear button — visible only when a value is selected and not disabled -->\r\n @if (!empty() && !disabled()) {\r\n <span class=\"fui-autocomplete__clear\" role=\"button\" [attr.aria-label]=\"intl.clearSelectionAriaLabel\" (click)=\"clear($event)\">\r\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path\r\n d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\"\r\n />\r\n </svg>\r\n </span>\r\n }\r\n\r\n <!-- Dropdown arrow icon -->\r\n <svg\r\n class=\"fui-autocomplete__arrow\"\r\n [class.fui-autocomplete__arrow--open]=\"panelOpen()\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"currentColor\"\r\n aria-hidden=\"true\"\r\n >\r\n <path d=\"M8 11L3 6l.7-.7L8 9.6l4.3-4.3L13 6z\" />\r\n </svg>\r\n }\r\n</div>\r\n\r\n<!-- Hidden container for projected options (used for data binding) -->\r\n<div class=\"fui-autocomplete__options-source\">\r\n <ng-content></ng-content>\r\n</div>\r\n\r\n<!-- Dropdown Panel -->\r\n@if (panelOpen()) {\r\n <div #panel [id]=\"id + '-panel'\" class=\"fui-autocomplete__panel\" [attr.aria-label]=\"placeholder()\">\r\n <!-- Search Input -->\r\n <div class=\"fui-autocomplete__search\">\r\n <fui-icon name=\"magnifying-glass\" size=\"sm\" class=\"fui-autocomplete__search-icon\"> </fui-icon>\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"fui-autocomplete__search-input\"\r\n [placeholder]=\"resolvedSearchPlaceholder()\"\r\n [value]=\"searchTerm()\"\r\n autocomplete=\"off\"\r\n role=\"searchbox\"\r\n [attr.aria-label]=\"resolvedSearchPlaceholder()\"\r\n [attr.aria-controls]=\"id + '-panel-listbox'\"\r\n [attr.aria-activedescendant]=\"_getActiveDescendant()\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"_handlePanelKeydown($event)\"\r\n />\r\n </div>\r\n <!-- Live region for announcing result count to screen readers -->\r\n <div class=\"fui-sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">\r\n @if (_liveAnnouncement()) {\r\n {{ _liveAnnouncement() }}\r\n } @else if (hasFilteredOptions()) {\r\n {{ intl.resultsAvailableText(filteredOptions().length) }}\r\n } @else {\r\n {{ intl.noResultsAvailableText }}\r\n }\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n @if (showAddButton() || showRefreshButton()) {\r\n <div class=\"fui-autocomplete__actions\">\r\n @if (showAddButton()) {\r\n <button\r\n type=\"button\"\r\n fuiButton\r\n variant=\"tertiary\"\r\n size=\"sm\"\r\n class=\"fui-autocomplete__action-button\"\r\n (click)=\"onAddNew()\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n {{ resolvedAddButtonLabel() }}\r\n </button>\r\n }\r\n @if (showRefreshButton()) {\r\n <button\r\n type=\"button\"\r\n fuiButton\r\n variant=\"tertiary\"\r\n size=\"sm\"\r\n class=\"fui-autocomplete__action-button\"\r\n (click)=\"onRefresh()\"\r\n >\r\n <fui-icon name=\"refresh-cw\" size=\"sm\"></fui-icon>\r\n {{ resolvedRefreshButtonLabel() }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Options List -->\r\n <div\r\n class=\"fui-autocomplete__options\"\r\n [id]=\"id + '-panel-listbox'\"\r\n role=\"listbox\"\r\n [attr.aria-label]=\"placeholder()\"\r\n >\r\n @if (hasFilteredOptions()) {\r\n @for (option of filteredOptions(); track option.id; let i = $index) {\r\n <div\r\n class=\"fui-autocomplete__option\"\r\n [class.fui-autocomplete__option--active]=\"activeOptionIndex() === i\"\r\n [class.fui-autocomplete__option--selected]=\"option._selected()\"\r\n role=\"option\"\r\n [attr.id]=\"option.id\"\r\n [attr.aria-selected]=\"option._selected()\"\r\n (click)=\"_onOptionSelected(option)\"\r\n (mouseenter)=\"setActiveOption(i, option)\"\r\n (mouseleave)=\"option.setInactive()\"\r\n >\r\n <span class=\"fui-autocomplete__option-text\">{{ option.getLabel() }}</span>\r\n @if (option._selected()) {\r\n <fui-icon name=\"check\" size=\"sm\" class=\"fui-autocomplete__option-check\"></fui-icon>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <div class=\"fui-autocomplete__no-options\">\r\n {{ resolvedNoOptionsText() }}\r\n </div>\r\n }\r\n </div>\r\n </div>\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-components-autocomplete.mjs","sources":["../../../lib/components/autocomplete/autocomplete.intl.ts","../../../lib/components/autocomplete/autocomplete.component.ts","../../../lib/components/autocomplete/autocomplete.component.html","../../../lib/components/autocomplete/raintonic-formaui-components-autocomplete.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiAutocompleteIntl extends FuiIntlBase {\r\n /** Placeholder text for the search input inside the panel. */\r\n searchPlaceholder = 'Search...';\r\n\r\n /** Aria label for the clear selection button. */\r\n clearSelectionAriaLabel = 'Clear selection';\r\n\r\n /** Text shown when the search filter has no matching options. */\r\n noResultsText = 'No results found';\r\n\r\n /** Announced via live region when panel opens, indicating how many results are available. */\r\n resultsAvailableText(count: number): string {\r\n return count === 1 ? '1 result available.' : `${count} results available.`;\r\n }\r\n}\r\n","import {\r\n AfterViewInit,\r\n booleanAttribute,\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n contentChildren,\r\n effect,\r\n ElementRef,\r\n inject,\r\n InjectionToken,\r\n input,\r\n InputSignal,\r\n OnDestroy,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n Signal,\r\n ViewChild,\r\n ViewEncapsulation,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl, ReactiveFormsModule } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\nimport {\r\n injectNgControl,\r\n FuiPopupOverlayDirective,\r\n FuiFormControlSyncDirective,\r\n} from '@raintonic/formaui/cdk/form-field';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { FuiFormFieldComponent, FuiPrefixDirective } from '@raintonic/formaui/components/form-field';\r\nimport { FuiInputDirective } from '@raintonic/formaui/components/input';\r\nimport {\r\n FUI_FORM_FIELD_CONTROL,\r\n FuiFormFieldControl,\r\n ErrorStateMatcher,\r\n syncMultiOptions,\r\n computeMultiDisplayValue,\r\n isEmpty,\r\n findInitialActiveOptionIndex,\r\n computeNextActiveOptionIndex,\r\n computePagedActiveOptionIndex,\r\n scrollOptionIntoView,\r\n announceMessage,\r\n computeActiveDescendant,\r\n getEnabledOptions,\r\n applyOptionSelection,\r\n noop,\r\n} from '@raintonic/formaui/core';\r\nimport { FUI_FORM_FIELD } from '@raintonic/formaui/components/form-field';\r\nimport { FuiOptionBase, FUI_OPTION } from '@raintonic/formaui/components/select';\r\nimport { FUI_SELECT, FuiSelectParent } from '@raintonic/formaui/components/select';\r\nimport { FuiAutocompleteIntl } from './autocomplete.intl';\r\n\r\n/**\r\n * Selection change event object emitted when the autocomplete's selection changes\r\n */\r\nexport interface FuiAutocompleteChange<T = unknown> {\r\n source: FuiAutocompleteComponent<T>;\r\n value: T | T[] | null;\r\n}\r\n\r\nexport const FUI_AUTOCOMPLETE = new InjectionToken<FuiAutocompleteComponent>('FUI_AUTOCOMPLETE');\r\n\r\n/**\r\n * # fui-autocomplete Component\r\n *\r\n * An autocomplete component that works inside fui-form-field.\r\n * Options are content-projected as `<fui-option>` children — same API as `<fui-select>`.\r\n * Search filtering is always enabled, CSS-hiding non-matching options.\r\n *\r\n * ## Features\r\n * - Content-projected `<fui-option>` children matching the `<fui-select>` API\r\n * - Built-in search filtering — CSS-hides non-matching options\r\n * - Single and multiple selection\r\n * - Full keyboard navigation\r\n * - Full Reactive Forms integration\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic Autocomplete\r\n * ```html\r\n * <fui-form-field>\r\n * <label>Framework</label>\r\n * <fui-autocomplete placeholder=\"Select a framework\" formControlName=\"framework\">\r\n * @for (fw of frameworks; track fw) {\r\n * <fui-option [value]=\"fw\">{{ fw.label }}</fui-option>\r\n * }\r\n * </fui-autocomplete>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### Multiple Selection\r\n * ```html\r\n * <fui-autocomplete [multiple]=\"true\" placeholder=\"Select tags\" formControlName=\"tags\">\r\n * @for (tag of tags; track tag) {\r\n * <fui-option [value]=\"tag\">{{ tag }}</fui-option>\r\n * }\r\n * </fui-autocomplete>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-autocomplete',\r\n standalone: true,\r\n imports: [ReactiveFormsModule, FuiIconComponent, FuiFormFieldComponent, FuiInputDirective, FuiPrefixDirective],\r\n templateUrl: './autocomplete.component.html',\r\n styleUrls: ['./autocomplete.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n hostDirectives: [\r\n {\r\n directive: FuiPopupOverlayDirective,\r\n inputs: ['positions', 'panelClass', 'backdropClass', 'scrollStrategy', 'minWidthFromTrigger'],\r\n outputs: ['openedChange', 'escapeKey'],\r\n },\r\n FuiFormControlSyncDirective,\r\n ],\r\n host: {\r\n class: 'fui-autocomplete',\r\n '[attr.id]': 'id',\r\n '[class.fui-autocomplete--open]': 'panelOpen()',\r\n '[class.fui-autocomplete--disabled]': 'disabled()',\r\n '[class.fui-autocomplete--focused]': 'focused()',\r\n '[class.fui-autocomplete--error]': 'errorState()',\r\n '[class.fui-autocomplete--readonly]': 'readonly()',\r\n '[class.fui-autocomplete--multiple]': 'multiple()',\r\n '[attr.aria-readonly]': 'readonly() ? \"true\" : null',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiAutocompleteComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiAutocompleteComponent,\r\n },\r\n {\r\n provide: FUI_AUTOCOMPLETE,\r\n useExisting: FuiAutocompleteComponent,\r\n },\r\n {\r\n provide: FUI_SELECT,\r\n useExisting: FuiAutocompleteComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiAutocompleteComponent<T = unknown>\r\n implements ControlValueAccessor, FuiFormFieldControl, FuiSelectParent, AfterViewInit, OnDestroy\r\n{\r\n static nextId = 0;\r\n readonly controlType = 'fui-autocomplete';\r\n\r\n // Injected dependencies\r\n private readonly _popup = inject(FuiPopupOverlayDirective);\r\n private readonly _formSync = inject(FuiFormControlSyncDirective);\r\n private readonly _parentFormField = inject(FUI_FORM_FIELD, { optional: true });\r\n readonly intl = inject(FuiAutocompleteIntl);\r\n\r\n // --- Inputs ---\r\n readonly placeholderInput = input('', { alias: 'placeholder' });\r\n readonly disabledInput = input(false, { alias: 'disabled', transform: booleanAttribute });\r\n readonly readonlyInput = input(false, { alias: 'readonly', transform: booleanAttribute });\r\n readonly multiple = input(false, { transform: booleanAttribute });\r\n\r\n /**\r\n * Comparison function for option values.\r\n * Defaults to strict equality (`===`). Override when options use object\r\n * values and you need to match by a property (e.g. comparing by `id`).\r\n */\r\n readonly compareWith: InputSignal<(o1: unknown, o2: unknown) => boolean> = input<\r\n (o1: unknown, o2: unknown) => boolean\r\n >((o1, o2) => o1 === o2);\r\n\r\n readonly errorStateMatcher = input<ErrorStateMatcher | null>(null);\r\n\r\n // --- Outputs ---\r\n readonly valueChange: OutputEmitterRef<T | T[] | null> = output<T | T[] | null>();\r\n readonly selectionChange: OutputEmitterRef<FuiAutocompleteChange<T>> = output<FuiAutocompleteChange<T>>();\r\n readonly openedChange: OutputEmitterRef<boolean> = output<boolean>();\r\n readonly searchChange: OutputEmitterRef<string> = output<string>();\r\n\r\n // --- Internal state ---\r\n private readonly _value: WritableSignal<unknown> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n private readonly _readOnly: WritableSignal<boolean> = signal(false);\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-autocomplete-${FuiAutocompleteComponent.nextId++}`;\r\n _ariaDescribedby: string | null = null;\r\n\r\n // Error state\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n readonly errorState = this._errorState;\r\n\r\n // Form control\r\n private readonly _ngControlRef = injectNgControl();\r\n get ngControl(): NgControl | null {\r\n return this._ngControlRef.ngControl;\r\n }\r\n\r\n // Computed interface properties\r\n readonly placeholder = computed(() => this.placeholderInput());\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n readonly required = this._required;\r\n readonly value = this._value;\r\n readonly focused = this._focused;\r\n\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\r\n readonly readonly = computed(() => this.readonlyInput() || this._readOnly());\r\n readonly empty = computed(() => isEmpty(this._value()));\r\n readonly id = this._uid;\r\n\r\n // --- View refs ---\r\n @ViewChild('trigger', { static: false }) trigger?: ElementRef<HTMLDivElement>;\r\n @ViewChild('panel', { static: true }) panel?: ElementRef<HTMLDivElement>;\r\n @ViewChild('searchInput', { static: false }) searchInput?: ElementRef<HTMLElement>;\r\n\r\n // --- Content-projected options ---\r\n readonly options = contentChildren(FUI_OPTION, { descendants: true });\r\n\r\n // --- Panel state ---\r\n readonly panelOpen = computed(() => this._popup.panelOpen());\r\n\r\n // --- Search ---\r\n readonly searchTerm: WritableSignal<string> = signal('');\r\n\r\n // --- Active option index ---\r\n readonly activeIndex: WritableSignal<number> = signal(-1);\r\n\r\n // --- Visible (not filtered-out) options — single source of truth for search filtering ---\r\n readonly _visibleOptions: Signal<readonly FuiOptionBase[]> = computed(() => {\r\n const term = this.searchTerm();\r\n const opts = this.options();\r\n if (!term.trim()) {\r\n return opts;\r\n }\r\n const lower = term.toLowerCase().trim();\r\n return opts.filter((o) => o.getLabel().toLowerCase().includes(lower));\r\n });\r\n\r\n readonly _visibleOptionCount: Signal<number> = computed(() => this._visibleOptions().length);\r\n\r\n // --- Live announcement ---\r\n readonly _liveAnnouncement: WritableSignal<string> = signal('');\r\n\r\n // --- ControlValueAccessor callbacks ---\r\n private _onChange = noop;\r\n private _onTouched = noop;\r\n\r\n // --- Computed ---\r\n readonly displayValue: Signal<string> = computed(() => computeMultiDisplayValue(this));\r\n\r\n constructor() {\r\n // Set valueAccessor after NgControl is resolved\r\n void Promise.resolve().then(() => {\r\n if (this._ngControlRef.ngControl) {\r\n this._ngControlRef.ngControl.valueAccessor = this;\r\n }\r\n });\r\n\r\n // State changes effect\r\n effect(() => {\r\n this.placeholderInput();\r\n this.readonly();\r\n this.disabledInput();\r\n this.multiple();\r\n this.errorStateMatcher();\r\n this._focused();\r\n this._disabled();\r\n this._value();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n this.stateChanges.next();\r\n });\r\n\r\n // Sync option states when value or options change\r\n effect(() => {\r\n syncMultiOptions(this);\r\n this.stateChanges.next();\r\n });\r\n\r\n // Sync DOM visibility to match _visibleOptions computed signal\r\n // One-way sync: computed signal is the source of truth, DOM is updated to match\r\n effect(() => {\r\n const term = this.searchTerm();\r\n const opts = this.options();\r\n const visible = this._visibleOptions();\r\n const visibleSet = new Set(visible);\r\n for (const opt of opts) {\r\n opt._getHostElement().style.display = visibleSet.has(opt) ? '' : 'none';\r\n }\r\n });\r\n\r\n // Announce visible results count when search term or panel state changes\r\n effect(() => {\r\n const term = this.searchTerm();\r\n const visible = this._visibleOptions();\r\n const isOpen = this._popup.panelOpen();\r\n // Only announce when the panel is open and search filtering is active\r\n if (isOpen && term.trim()) {\r\n this._announce(this.intl.resultsAvailableText(visible.length));\r\n }\r\n });\r\n\r\n // Focus management: move focus to search input when panel opens\r\n let _panelInitialized = false;\r\n effect(() => {\r\n const isOpen = this._popup.panelOpen();\r\n if (!_panelInitialized) {\r\n _panelInitialized = true;\r\n return;\r\n }\r\n if (isOpen) {\r\n queueMicrotask(() => {\r\n this.searchInput?.nativeElement.focus();\r\n });\r\n }\r\n });\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this._popup.setTrigger(this.trigger ?? null);\r\n this._popup.setPanel(this.panel ?? null);\r\n this._popup.panelClass.set(['fui-autocomplete-overlay-panel']);\r\n this._popup.backdropClass.set('fui-autocomplete-backdrop');\r\n this._popup.positions.set([\r\n {\r\n originX: 'start',\r\n originY: 'bottom',\r\n overlayX: 'start',\r\n overlayY: 'top',\r\n offsetY: 16,\r\n },\r\n ]);\r\n\r\n if (this._parentFormField) {\r\n this._popup.widthElement.set(this._parentFormField.getConnectedOverlayOrigin());\r\n }\r\n\r\n this._formSync.errorState.set(this._errorState);\r\n this._formSync.errorStateMatcher.set(this.errorStateMatcher());\r\n this._formSync.required.set(this._required);\r\n this._formSync.ngControlDisabled.set(this._ngControlDisabled);\r\n this._formSync.stateChanges.set(this.stateChanges);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stateChanges.complete();\r\n }\r\n\r\n // --- ControlValueAccessor ---\r\n writeValue(value: unknown): void {\r\n this._value.set(value ?? null);\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this._disabled.set(isDisabled);\r\n this.stateChanges.next();\r\n }\r\n\r\n // --- FuiFormFieldControl ---\r\n onContainerClick(_event: MouseEvent): void {\r\n if (this.disabled()) return;\r\n if (this.multiple() && this.panelOpen()) return;\r\n this.toggle();\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n }\r\n\r\n setReadOnly(readOnly: boolean): void {\r\n this._readOnly.set(readOnly);\r\n }\r\n\r\n // --- Public API ---\r\n\r\n /** Clears the current value. */\r\n clear(event: Event): void {\r\n event.stopPropagation();\r\n this._value.set(null);\r\n this._onChange(null);\r\n this.valueChange.emit(null);\r\n this.selectionChange.emit({ source: this, value: null });\r\n this.stateChanges.next();\r\n }\r\n\r\n focus(): void {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n\r\n blur(): void {\r\n this.trigger?.nativeElement.blur();\r\n }\r\n\r\n /** Opens the panel. */\r\n open(): void {\r\n if (this.disabled() || this.readonly() || this._popup.panelOpen()) return;\r\n this._focused.set(true);\r\n this.searchTerm.set('');\r\n this._setInitialActiveOption();\r\n this._popup.open();\r\n if (this._popup.panelOpen()) {\r\n this._scrollToActiveOption();\r\n this.openedChange.emit(true);\r\n // Announce how many results are available\r\n this._announce(this.intl.resultsAvailableText(this.options().length));\r\n }\r\n }\r\n\r\n /** Closes the panel. */\r\n close(restoreFocus = true): void {\r\n if (!this._popup.panelOpen()) return;\r\n this._focused.set(false);\r\n this.activeIndex.set(-1);\r\n this.searchTerm.set('');\r\n this._onTouched();\r\n this._popup.close();\r\n this.openedChange.emit(false);\r\n if (restoreFocus) {\r\n this.trigger?.nativeElement.focus();\r\n }\r\n }\r\n\r\n /** Toggles the panel. */\r\n toggle(): void {\r\n if (this.disabled() || this.readonly()) return;\r\n this._popup.toggle();\r\n }\r\n\r\n // --- Selection ---\r\n\r\n /**\r\n * Called by fui-option via FUI_SELECT._onOptionSelected.\r\n * Implements FuiSelectParent.\r\n */\r\n _onOptionSelected(option: FuiOptionBase): void {\r\n const result = applyOptionSelection(this, option);\r\n const newValue = result.newValue as T | T[] | null;\r\n\r\n this._value.set(newValue);\r\n this._onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n this.selectionChange.emit({ source: this, value: newValue });\r\n this.stateChanges.next();\r\n\r\n if (result.wasSelected) {\r\n this._announce(`${option.getLabel()} deselected`);\r\n } else {\r\n this._announce(`${option.getLabel()} selected`);\r\n }\r\n\r\n if (!this.multiple()) {\r\n this.close();\r\n }\r\n }\r\n\r\n // --- Search ---\r\n\r\n onSearchInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const term = target.value;\r\n this.searchTerm.set(term);\r\n this.searchChange.emit(term);\r\n\r\n // Reset active index to first visible enabled option\r\n const enabled = getEnabledOptions(this._visibleOptions());\r\n this.activeIndex.set(enabled.length > 0 ? 0 : -1);\r\n }\r\n\r\n // --- Keyboard Navigation ---\r\n\r\n /** Entry point for trigger keydown */\r\n _handleKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n if (!this.panelOpen()) {\r\n this._handleClosedKeydown(event);\r\n } else {\r\n this._handlePanelKeydown(event);\r\n }\r\n }\r\n\r\n private _handleClosedKeydown(event: KeyboardEvent): void {\r\n switch (event.key) {\r\n case 'Enter':\r\n case ' ':\r\n case 'ArrowDown':\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.open();\r\n break;\r\n }\r\n }\r\n\r\n /** Handle keydown inside the panel (search input or item list) */\r\n _handlePanelKeydown(event: KeyboardEvent): void {\r\n if (this.disabled()) return;\r\n\r\n const opts = this._getVisibleEnabledOptions();\r\n const activeIdx = this.activeIndex();\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(computeNextActiveOptionIndex(opts.length, activeIdx, 1));\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(computeNextActiveOptionIndex(opts.length, activeIdx, -1));\r\n break;\r\n case 'Home':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(0);\r\n break;\r\n case 'End':\r\n event.preventDefault();\r\n this._setActiveOptionIndex(opts.length - 1);\r\n break;\r\n case 'PageDown':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n this._setActiveOptionIndex(computePagedActiveOptionIndex(opts.length, activeIdx, 1));\r\n }\r\n break;\r\n case 'PageUp':\r\n event.preventDefault();\r\n if (opts.length > 0) {\r\n this._setActiveOptionIndex(computePagedActiveOptionIndex(opts.length, activeIdx, -1));\r\n }\r\n break;\r\n case 'Enter':\r\n event.preventDefault();\r\n if (activeIdx >= 0 && activeIdx < opts.length) {\r\n this._onOptionSelected(opts[activeIdx]);\r\n }\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.close();\r\n break;\r\n case 'Tab':\r\n this.close();\r\n break;\r\n }\r\n }\r\n\r\n private _setActiveOptionIndex(index: number): void {\r\n const opts = this._getVisibleEnabledOptions();\r\n if (index < 0 || index >= opts.length) return;\r\n\r\n // Deactivate all visible options\r\n this.options().forEach((opt) => {\r\n opt.setInactive();\r\n });\r\n\r\n const activeOption = opts[index];\r\n activeOption.setActive();\r\n this.activeIndex.set(index);\r\n scrollOptionIntoView(activeOption._getHostElement(), this.panel?.nativeElement, '.fui-autocomplete__options');\r\n\r\n // Announce active item\r\n const label = activeOption.getLabel();\r\n this._announce(`${label}, ${index + 1} of ${opts.length}`);\r\n }\r\n\r\n private _setInitialActiveOption(): void {\r\n const opts = this._getVisibleEnabledOptions();\r\n if (opts.length === 0) {\r\n this.activeIndex.set(-1);\r\n return;\r\n }\r\n\r\n const initialIndex = findInitialActiveOptionIndex(opts, this._value(), this.multiple(), this.compareWith());\r\n this._setActiveOptionIndex(initialIndex);\r\n }\r\n\r\n private _scrollToActiveOption(): void {\r\n const opts = this._getVisibleEnabledOptions();\r\n const activeIdx = this.activeIndex();\r\n if (activeIdx < 0 || activeIdx >= opts.length) return;\r\n scrollOptionIntoView(opts[activeIdx]._getHostElement(), this.panel?.nativeElement, '.fui-autocomplete__options');\r\n }\r\n\r\n /** Get visible (non-hidden) enabled options for keyboard navigation */\r\n private _getVisibleEnabledOptions(): FuiOptionBase[] {\r\n return getEnabledOptions(this._visibleOptions());\r\n }\r\n\r\n /** aria-activedescendant */\r\n _getActiveDescendant(): string | null {\r\n const opts = this._getVisibleEnabledOptions();\r\n return computeActiveDescendant(opts, this.activeIndex());\r\n }\r\n\r\n // --- Announcement ---\r\n\r\n private _announce(message: string): void {\r\n announceMessage(this._liveAnnouncement, message);\r\n }\r\n}\r\n","<!-- Trigger -->\r\n<div\r\n #trigger\r\n [id]=\"id\"\r\n class=\"fui-autocomplete__trigger\"\r\n [attr.tabindex]=\"disabled() ? -1 : 0\"\r\n role=\"combobox\"\r\n [attr.aria-haspopup]=\"'listbox'\"\r\n [attr.aria-expanded]=\"panelOpen()\"\r\n [attr.aria-disabled]=\"disabled()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n [attr.aria-required]=\"required()\"\r\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\r\n aria-autocomplete=\"list\"\r\n [attr.aria-activedescendant]=\"panelOpen() ? _getActiveDescendant() : null\"\r\n [attr.aria-controls]=\"panelOpen() ? id + '-panel' : null\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n>\r\n <span class=\"fui-autocomplete__value\">\r\n @if (empty()) {\r\n <span class=\"fui-autocomplete__placeholder\">{{ placeholder() }}</span>\r\n } @else {\r\n <span class=\"fui-autocomplete__value-text\">{{ displayValue() }}</span>\r\n }\r\n </span>\r\n\r\n @if (!readonly() && !disabled()) {\r\n @if (!empty()) {\r\n <button\r\n type=\"button\"\r\n class=\"fui-autocomplete__clear\"\r\n role=\"button\"\r\n [attr.aria-label]=\"intl.clearSelectionAriaLabel\"\r\n (click)=\"clear($event)\"\r\n >\r\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path\r\n d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n\r\n <span class=\"fui-autocomplete__arrow\" [class.fui-autocomplete__arrow--open]=\"panelOpen()\" aria-hidden=\"true\">\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </span>\r\n }\r\n</div>\r\n\r\n<!-- Live region for screen reader announcements -->\r\n<span class=\"fui-sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">{{ _liveAnnouncement() }}</span>\r\n\r\n<!-- Dropdown Panel (always rendered so #panel ViewChild is always available) -->\r\n<div #panel [hidden]=\"false\" [id]=\"id + '-panel'\" class=\"fui-autocomplete__panel\">\r\n <!-- Search Input -->\r\n <div class=\"fui-autocomplete__search-input\">\r\n <fui-form-field hideSubscript>\r\n <fui-icon fuiPrefix name=\"magnifying-glass\" size=\"sm\" />\r\n <input\r\n #searchInput\r\n fuiInput\r\n type=\"text\"\r\n [placeholder]=\"intl.searchPlaceholder\"\r\n [value]=\"searchTerm()\"\r\n autocomplete=\"off\"\r\n role=\"searchbox\"\r\n aria-label=\"Search\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"_handlePanelKeydown($event)\"\r\n />\r\n </fui-form-field>\r\n </div>\r\n\r\n <!-- Options List -->\r\n <div\r\n class=\"fui-autocomplete__options\"\r\n role=\"listbox\"\r\n [attr.aria-multiselectable]=\"multiple()\"\r\n [attr.aria-label]=\"placeholder()\"\r\n >\r\n <ng-content></ng-content>\r\n\r\n <!-- No results empty state when search has no matching options -->\r\n @if (searchTerm() && _visibleOptions().length === 0) {\r\n <div class=\"fui-autocomplete__no-results\" role=\"status\">\r\n {{ intl.noResultsText }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Panel Actions (e.g., Add new option, Refresh) -->\r\n <div class=\"fui-autocomplete__panel-actions\">\r\n <ng-content select=\"[fuiAutocompletePanelActions]\"></ng-content>\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,88 +1,63 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { FuiTooltipDirective } from '@raintonic/formaui/components/tooltip';
3
4
 
4
5
  /**
5
6
  * @component FuiAvatarComponent
6
7
  * @selector fui-avatar
7
- * @description Displays a user avatar with image, initials fallback, and configurable shape/size.
8
- * Automatically computes initials from name fields and generates a background color from an identity key.
8
+ * @description Displays a user avatar with initials-only fallback (no image tag).
9
+ * Shows computed initials from fullName with a tooltip on hover.
9
10
  *
10
- * @input size - Avatar size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' or a numeric pixel value. Default 'md'.
11
- * @input shape - Avatar shape: 'circle' | 'rounded' | 'square'. Default 'circle'.
12
- * @input src - Image URL or data URI for the avatar.
13
- * @input avatarUrl - Backward-compatible alias for src.
14
- * @input srcSet - HTML srcset attribute for responsive images.
15
- * @input sizesAttr - HTML sizes attribute for responsive images.
16
- * @input name - First name used to compute initials.
17
- * @input surname - Last name used to compute initials.
18
- * @input fullName - Full name (overrides name + surname for initials).
19
- * @input alt - Alt text for the image element.
20
- * @input identityKey - Key (e.g. email) used to deterministically pick a background color.
11
+ * @input size - Avatar size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' or a numeric pixel value. Default 'md'.
12
+ * @input fullName - Required. Full name used to compute initials and tooltip.
13
+ * @input initials - Optional override for the computed initials string.
14
+ * @input alt - Custom aria-label override. Defaults to "Avatar for {fullName}".
21
15
  *
22
16
  * @example
23
- * <fui-avatar [src]="user.photoUrl" [fullName]="user.displayName" size="lg"></fui-avatar>
17
+ * <fui-avatar fullName="Jane Doe" size="md"></fui-avatar>
24
18
  */
25
19
  class FuiAvatarComponent {
26
20
  // Inputs (signals)
27
21
  size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
28
- shape = input('circle', ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
29
- src = input(null, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ [])); // URL or data URI
30
- // Backward compatibility with previous API
31
- avatarUrl = input(null, ...(ngDevMode ? [{ debugName: "avatarUrl" }] : /* istanbul ignore next */ []));
32
- srcSet = input(null, ...(ngDevMode ? [{ debugName: "srcSet" }] : /* istanbul ignore next */ []));
33
- sizesAttr = input(null, ...(ngDevMode ? [{ debugName: "sizesAttr" }] : /* istanbul ignore next */ []));
34
- name = input(null, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
35
- surname = input(null, ...(ngDevMode ? [{ debugName: "surname" }] : /* istanbul ignore next */ []));
36
- fullName = input(null, ...(ngDevMode ? [{ debugName: "fullName" }] : /* istanbul ignore next */ []));
22
+ fullName = input.required(...(ngDevMode ? [{ debugName: "fullName" }] : /* istanbul ignore next */ []));
23
+ initials = input(...(ngDevMode ? [undefined, { debugName: "initials" }] : /* istanbul ignore next */ []));
37
24
  alt = input(null, ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
38
- identityKey = input(null, ...(ngDevMode ? [{ debugName: "identityKey" }] : /* istanbul ignore next */ [])); // e.g., email for color hashing
39
- // Local state
40
- imageFailed = signal(false, ...(ngDevMode ? [{ debugName: "imageFailed" }] : /* istanbul ignore next */ []));
41
25
  // Derived values
42
- normalizedName = computed(() => {
43
- const fn = (this.fullName() ?? `${this.name() ?? ''} ${this.surname() ?? ''}`).trim();
44
- return fn.replace(/\s+/g, ' ');
45
- }, ...(ngDevMode ? [{ debugName: "normalizedName" }] : /* istanbul ignore next */ []));
46
- initials = computed(() => {
47
- const parts = this.normalizedName().split(' ').filter(Boolean);
48
- if (parts.length === 0)
26
+ _initials = computed(() => {
27
+ const override = this.initials();
28
+ if (override)
29
+ return override;
30
+ const parts = this.fullName().split(' ').filter(Boolean);
31
+ const name = parts[0];
32
+ const surname = parts[1];
33
+ if (!name)
49
34
  return '?';
50
- if (parts.length === 1)
51
- return parts[0].slice(0, 2).toUpperCase();
52
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
53
- }, ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
35
+ if (!surname)
36
+ return name.slice(0, 2).toUpperCase();
37
+ return (name[0] + surname[0]).toUpperCase();
38
+ }, ...(ngDevMode ? [{ debugName: "_initials" }] : /* istanbul ignore next */ []));
54
39
  pixelSize = computed(() => {
55
40
  const s = this.size();
56
41
  if (typeof s === 'number')
57
42
  return s;
58
- return { xs: 16, sm: 24, md: 32, lg: 40, xl: 48 }[s] ?? 32;
43
+ return { xs: 24, sm: 32, md: 40, lg: 48, xl: 56, '2xl': 64 }[s];
59
44
  }, ...(ngDevMode ? [{ debugName: "pixelSize" }] : /* istanbul ignore next */ []));
60
- displayImage = computed(() => {
61
- if (this.imageFailed())
62
- return null;
63
- return this.src() ?? this.avatarUrl();
64
- }, ...(ngDevMode ? [{ debugName: "displayImage" }] : /* istanbul ignore next */ []));
65
- bgColor = computed(() => {
66
- const key = this.identityKey() ?? this.normalizedName() ?? this.initials();
67
- const palette = ['var(--fui-primary)'];
68
- let h = 0;
69
- for (let i = 0; i < key.length; i++)
70
- h = ((h << 5) - h + key.charCodeAt(i)) | 0;
71
- return palette[Math.abs(h) % palette.length];
72
- }, ...(ngDevMode ? [{ debugName: "bgColor" }] : /* istanbul ignore next */ []));
45
+ fontSize = computed(() => {
46
+ const s = this.size();
47
+ if (typeof s === 'number')
48
+ return s;
49
+ return { xs: 10, sm: 12, md: 14, lg: 16, xl: 20, '2xl': 24 }[s];
50
+ }, ...(ngDevMode ? [{ debugName: "fontSize" }] : /* istanbul ignore next */ []));
73
51
  ariaLabel = computed(() => {
74
- return this.alt() ?? (this.normalizedName() ? `Avatar for ${this.normalizedName()}` : 'User avatar');
52
+ return this.alt() ?? (this.fullName() ? `Avatar for ${this.fullName()}` : 'User avatar');
75
53
  }, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
76
- onImgError() {
77
- this.imageFailed.set(true);
78
- }
79
54
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
80
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiAvatarComponent, isStandalone: true, selector: "fui-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, avatarUrl: { classPropertyName: "avatarUrl", publicName: "avatarUrl", isSignal: true, isRequired: false, transformFunction: null }, srcSet: { classPropertyName: "srcSet", publicName: "srcSet", isSignal: true, isRequired: false, transformFunction: null }, sizesAttr: { classPropertyName: "sizesAttr", publicName: "sizesAttr", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, surname: { classPropertyName: "surname", publicName: "surname", isSignal: true, isRequired: false, transformFunction: null }, fullName: { classPropertyName: "fullName", publicName: "fullName", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, identityKey: { classPropertyName: "identityKey", publicName: "identityKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\r\n class=\"fui-avatar\"\r\n [style.--fui-avatar-size.px]=\"pixelSize()\"\r\n [class.fui-avatar--rounded]=\"shape() === 'rounded'\"\r\n [class.fui-avatar--square]=\"shape() === 'square'\"\r\n>\r\n @if (displayImage(); as img) {\r\n <img\r\n class=\"fui-avatar__img\"\r\n [src]=\"img\"\r\n [srcset]=\"srcSet() || null\"\r\n [sizes]=\"sizesAttr() || null\"\r\n [attr.alt]=\"ariaLabel()\"\r\n loading=\"lazy\"\r\n decoding=\"async\"\r\n referrerpolicy=\"no-referrer\"\r\n (error)=\"onImgError()\"\r\n />\r\n } @else {\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [style.background-color]=\"bgColor()\">\r\n {{ initials() }}\r\n </div>\r\n }\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\r\n", styles: [".fui-avatar{--fui-avatar-size: 32px;--fui-avatar-border-radius: var(--fui-border-radius-pill);--fui-avatar-border-color: var(--fui-border-color);--fui-avatar-font-size: var(--fui-font-size-02);--fui-avatar-font-weight: var(--fui-font-weight-semibold);contain:content;inline-size:var(--fui-avatar-size);block-size:var(--fui-avatar-size);position:relative;display:inline-flex;align-items:center;justify-content:center;border:var(--fui-border-width-sm) solid var(--fui-avatar-border-color);border-radius:var(--fui-avatar-border-radius);overflow:hidden;flex-shrink:0}.fui-avatar--rounded{border-radius:var(--fui-border-radius-sm)}.fui-avatar--square{border-radius:var(--fui-border-radius-none)}.fui-avatar__img{inline-size:100%;block-size:100%;object-fit:cover;border:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-avatar__initials{inline-size:100%;block-size:100%;display:grid;place-items:center;color:var(--fui-text-primary);font:var(--fui-avatar-font-weight) var(--fui-avatar-font-size)/1 var(--fui-font-family-sans);text-transform:uppercase}.fui-avatar ::ng-deep [avatar-badge]{position:absolute;inset-inline-end:-2px;inset-block-end:-2px;transform:translate(0)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
55
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.6", type: FuiAvatarComponent, isStandalone: true, selector: "fui-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullName: { classPropertyName: "fullName", publicName: "fullName", isSignal: true, isRequired: true, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fui-avatar\" [style.--fui-avatar-size.px]=\"pixelSize()\" [style.font-size.px]=\"fontSize()\">\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [fuiTooltip]=\"fullName()\">\r\n {{ _initials() }}\r\n </div>\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\r\n", styles: [":host{display:flex}.fui-avatar{--fui-avatar-size: 32px;--fui-avatar-border-radius: var(--fui-radius-pill);--fui-avatar-border-color: var(--fui-border-default);--fui-avatar-font-weight: var(--fui-weight-semibold);contain:content;inline-size:var(--fui-avatar-size);block-size:var(--fui-avatar-size);position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--fui-avatar-border-radius);overflow:hidden;flex-shrink:0}.fui-avatar__initials{inline-size:100%;block-size:100%;display:grid;place-items:center;color:var(--fui-text-primary);font-weight:var(--fui-weight-medium);text-transform:uppercase;background-color:var(--fui-primary-muted)}.fui-avatar ::ng-deep [avatar-badge]{position:absolute;inset-inline-end:-2px;inset-block-end:-2px;transform:translate(0)}\n"], dependencies: [{ kind: "directive", type: FuiTooltipDirective, selector: "[fuiTooltip]", inputs: ["fuiTooltip", "fuiTooltipPosition", "fuiTooltipSize", "fuiTooltipTrigger", "fuiTooltipShowDelay", "fuiTooltipHideDelay", "fuiTooltipDisabled", "fuiTooltipMaxWidth", "fuiTooltipOffset", "fuiTooltipArrow", "fuiTooltipShow"], exportAs: ["fuiTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
81
56
  }
82
57
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiAvatarComponent, decorators: [{
83
58
  type: Component,
84
- args: [{ selector: 'fui-avatar', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"fui-avatar\"\r\n [style.--fui-avatar-size.px]=\"pixelSize()\"\r\n [class.fui-avatar--rounded]=\"shape() === 'rounded'\"\r\n [class.fui-avatar--square]=\"shape() === 'square'\"\r\n>\r\n @if (displayImage(); as img) {\r\n <img\r\n class=\"fui-avatar__img\"\r\n [src]=\"img\"\r\n [srcset]=\"srcSet() || null\"\r\n [sizes]=\"sizesAttr() || null\"\r\n [attr.alt]=\"ariaLabel()\"\r\n loading=\"lazy\"\r\n decoding=\"async\"\r\n referrerpolicy=\"no-referrer\"\r\n (error)=\"onImgError()\"\r\n />\r\n } @else {\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [style.background-color]=\"bgColor()\">\r\n {{ initials() }}\r\n </div>\r\n }\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\r\n", styles: [".fui-avatar{--fui-avatar-size: 32px;--fui-avatar-border-radius: var(--fui-border-radius-pill);--fui-avatar-border-color: var(--fui-border-color);--fui-avatar-font-size: var(--fui-font-size-02);--fui-avatar-font-weight: var(--fui-font-weight-semibold);contain:content;inline-size:var(--fui-avatar-size);block-size:var(--fui-avatar-size);position:relative;display:inline-flex;align-items:center;justify-content:center;border:var(--fui-border-width-sm) solid var(--fui-avatar-border-color);border-radius:var(--fui-avatar-border-radius);overflow:hidden;flex-shrink:0}.fui-avatar--rounded{border-radius:var(--fui-border-radius-sm)}.fui-avatar--square{border-radius:var(--fui-border-radius-none)}.fui-avatar__img{inline-size:100%;block-size:100%;object-fit:cover;border:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-avatar__initials{inline-size:100%;block-size:100%;display:grid;place-items:center;color:var(--fui-text-primary);font:var(--fui-avatar-font-weight) var(--fui-avatar-font-size)/1 var(--fui-font-family-sans);text-transform:uppercase}.fui-avatar ::ng-deep [avatar-badge]{position:absolute;inset-inline-end:-2px;inset-block-end:-2px;transform:translate(0)}\n"] }]
85
- }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], avatarUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarUrl", required: false }] }], srcSet: [{ type: i0.Input, args: [{ isSignal: true, alias: "srcSet", required: false }] }], sizesAttr: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizesAttr", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], surname: [{ type: i0.Input, args: [{ isSignal: true, alias: "surname", required: false }] }], fullName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullName", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], identityKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "identityKey", required: false }] }] } });
59
+ args: [{ selector: 'fui-avatar', standalone: true, imports: [FuiTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"fui-avatar\" [style.--fui-avatar-size.px]=\"pixelSize()\" [style.font-size.px]=\"fontSize()\">\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [fuiTooltip]=\"fullName()\">\r\n {{ _initials() }}\r\n </div>\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\r\n", styles: [":host{display:flex}.fui-avatar{--fui-avatar-size: 32px;--fui-avatar-border-radius: var(--fui-radius-pill);--fui-avatar-border-color: var(--fui-border-default);--fui-avatar-font-weight: var(--fui-weight-semibold);contain:content;inline-size:var(--fui-avatar-size);block-size:var(--fui-avatar-size);position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--fui-avatar-border-radius);overflow:hidden;flex-shrink:0}.fui-avatar__initials{inline-size:100%;block-size:100%;display:grid;place-items:center;color:var(--fui-text-primary);font-weight:var(--fui-weight-medium);text-transform:uppercase;background-color:var(--fui-primary-muted)}.fui-avatar ::ng-deep [avatar-badge]{position:absolute;inset-inline-end:-2px;inset-block-end:-2px;transform:translate(0)}\n"] }]
60
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullName", required: true }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }] } });
86
61
 
87
62
  /**
88
63
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-avatar.mjs","sources":["../../../lib/components/avatar/avatar.component.ts","../../../lib/components/avatar/avatar.component.html","../../../lib/components/avatar/raintonic-formaui-components-avatar.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, Signal, signal } from '@angular/core';\r\n\r\nexport type FuiAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * @component FuiAvatarComponent\r\n * @selector fui-avatar\r\n * @description Displays a user avatar with image, initials fallback, and configurable shape/size.\r\n * Automatically computes initials from name fields and generates a background color from an identity key.\r\n *\r\n * @input size - Avatar size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' or a numeric pixel value. Default 'md'.\r\n * @input shape - Avatar shape: 'circle' | 'rounded' | 'square'. Default 'circle'.\r\n * @input src - Image URL or data URI for the avatar.\r\n * @input avatarUrl - Backward-compatible alias for src.\r\n * @input srcSet - HTML srcset attribute for responsive images.\r\n * @input sizesAttr - HTML sizes attribute for responsive images.\r\n * @input name - First name used to compute initials.\r\n * @input surname - Last name used to compute initials.\r\n * @input fullName - Full name (overrides name + surname for initials).\r\n * @input alt - Alt text for the image element.\r\n * @input identityKey - Key (e.g. email) used to deterministically pick a background color.\r\n *\r\n * @example\r\n * <fui-avatar [src]=\"user.photoUrl\" [fullName]=\"user.displayName\" size=\"lg\"></fui-avatar>\r\n */\r\n@Component({\r\n selector: 'fui-avatar',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './avatar.component.html',\r\n styleUrls: ['./avatar.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FuiAvatarComponent {\r\n // Inputs (signals)\r\n readonly size = input<FuiAvatarSize | number>('md');\r\n readonly shape = input<'circle' | 'rounded' | 'square'>('circle');\r\n readonly src = input<string | null>(null); // URL or data URI\r\n // Backward compatibility with previous API\r\n readonly avatarUrl = input<string | null>(null);\r\n readonly srcSet = input<string | null>(null);\r\n readonly sizesAttr = input<string | null>(null);\r\n readonly name = input<string | null>(null);\r\n readonly surname = input<string | null>(null);\r\n readonly fullName = input<string | null>(null);\r\n readonly alt = input<string | null>(null);\r\n readonly identityKey = input<string | null>(null); // e.g., email for color hashing\r\n\r\n // Local state\r\n private readonly imageFailed = signal(false);\r\n\r\n // Derived values\r\n readonly normalizedName: Signal<string> = computed(() => {\r\n const fn = (this.fullName() ?? `${this.name() ?? ''} ${this.surname() ?? ''}`).trim();\r\n return fn.replace(/\\s+/g, ' ');\r\n });\r\n\r\n readonly initials: Signal<string> = computed(() => {\r\n const parts = this.normalizedName().split(' ').filter(Boolean);\r\n if (parts.length === 0) return '?';\r\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\r\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\r\n });\r\n\r\n readonly pixelSize: Signal<number> = computed(() => {\r\n const s = this.size();\r\n if (typeof s === 'number') return s;\r\n return { xs: 16, sm: 24, md: 32, lg: 40, xl: 48 }[s] ?? 32;\r\n });\r\n\r\n readonly displayImage: Signal<string | null> = computed(() => {\r\n if (this.imageFailed()) return null;\r\n return this.src() ?? this.avatarUrl();\r\n });\r\n\r\n readonly bgColor: Signal<string> = computed(() => {\r\n const key = this.identityKey() ?? this.normalizedName() ?? this.initials();\r\n const palette = ['var(--fui-primary)'];\r\n let h = 0;\r\n for (let i = 0; i < key.length; i++) h = ((h << 5) - h + key.charCodeAt(i)) | 0;\r\n return palette[Math.abs(h) % palette.length];\r\n });\r\n\r\n readonly ariaLabel: Signal<string> = computed(() => {\r\n return this.alt() ?? (this.normalizedName() ? `Avatar for ${this.normalizedName()}` : 'User avatar');\r\n });\r\n\r\n onImgError(): void {\r\n this.imageFailed.set(true);\r\n }\r\n}\r\n","<div\r\n class=\"fui-avatar\"\r\n [style.--fui-avatar-size.px]=\"pixelSize()\"\r\n [class.fui-avatar--rounded]=\"shape() === 'rounded'\"\r\n [class.fui-avatar--square]=\"shape() === 'square'\"\r\n>\r\n @if (displayImage(); as img) {\r\n <img\r\n class=\"fui-avatar__img\"\r\n [src]=\"img\"\r\n [srcset]=\"srcSet() || null\"\r\n [sizes]=\"sizesAttr() || null\"\r\n [attr.alt]=\"ariaLabel()\"\r\n loading=\"lazy\"\r\n decoding=\"async\"\r\n referrerpolicy=\"no-referrer\"\r\n (error)=\"onImgError()\"\r\n />\r\n } @else {\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [style.background-color]=\"bgColor()\">\r\n {{ initials() }}\r\n </div>\r\n }\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\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-components-avatar.mjs","sources":["../../../lib/components/avatar/avatar.component.ts","../../../lib/components/avatar/avatar.component.html","../../../lib/components/avatar/raintonic-formaui-components-avatar.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, Signal } from '@angular/core';\r\nimport { FuiTooltipDirective } from '@raintonic/formaui/components/tooltip';\r\n\r\nexport type FuiAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\r\n\r\n/**\r\n * @component FuiAvatarComponent\r\n * @selector fui-avatar\r\n * @description Displays a user avatar with initials-only fallback (no image tag).\r\n * Shows computed initials from fullName with a tooltip on hover.\r\n *\r\n * @input size - Avatar size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' or a numeric pixel value. Default 'md'.\r\n * @input fullName - Required. Full name used to compute initials and tooltip.\r\n * @input initials - Optional override for the computed initials string.\r\n * @input alt - Custom aria-label override. Defaults to \"Avatar for {fullName}\".\r\n *\r\n * @example\r\n * <fui-avatar fullName=\"Jane Doe\" size=\"md\"></fui-avatar>\r\n */\r\n@Component({\r\n selector: 'fui-avatar',\r\n standalone: true,\r\n imports: [FuiTooltipDirective],\r\n templateUrl: './avatar.component.html',\r\n styleUrls: ['./avatar.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FuiAvatarComponent {\r\n // Inputs (signals)\r\n readonly size = input<FuiAvatarSize | number>('md');\r\n readonly fullName = input.required<string>();\r\n readonly initials = input<string | undefined>();\r\n readonly alt = input<string | null>(null);\r\n\r\n // Derived values\r\n\r\n readonly _initials: Signal<string> = computed(() => {\r\n const override = this.initials();\r\n if (override) return override;\r\n\r\n const parts = this.fullName().split(' ').filter(Boolean);\r\n const name = parts[0];\r\n const surname = parts[1];\r\n if (!name) return '?';\r\n if (!surname) return name.slice(0, 2).toUpperCase();\r\n return (name[0] + surname[0]).toUpperCase();\r\n });\r\n\r\n readonly pixelSize: Signal<number> = computed(() => {\r\n const s = this.size();\r\n if (typeof s === 'number') return s;\r\n return { xs: 24, sm: 32, md: 40, lg: 48, xl: 56, '2xl': 64 }[s];\r\n });\r\n\r\n readonly fontSize: Signal<number> = computed(() => {\r\n const s = this.size();\r\n if (typeof s === 'number') return s;\r\n return { xs: 10, sm: 12, md: 14, lg: 16, xl: 20, '2xl': 24 }[s];\r\n });\r\n\r\n readonly ariaLabel: Signal<string> = computed(() => {\r\n return this.alt() ?? (this.fullName() ? `Avatar for ${this.fullName()}` : 'User avatar');\r\n });\r\n}\r\n","<div class=\"fui-avatar\" [style.--fui-avatar-size.px]=\"pixelSize()\" [style.font-size.px]=\"fontSize()\">\r\n <div class=\"fui-avatar__initials\" role=\"img\" [attr.aria-label]=\"ariaLabel()\" [fuiTooltip]=\"fullName()\">\r\n {{ _initials() }}\r\n </div>\r\n\r\n <ng-content select=\"[avatar-badge]\"></ng-content>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -101,7 +101,7 @@ class FuiBadgeComponent {
101
101
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
102
102
  }
103
103
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
104
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiBadgeComponent, isStandalone: true, selector: "fui-badge", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "class": "computedClasses()", "style": "computedStyles()", "attr.aria-label": "ariaLabel() || null" } }, ngImport: i0, template: "<div class=\"fui-badge__content\">\r\n @if (icon()) {\r\n <fui-icon class=\"fui-badge__icon\" [name]=\"icon()!\" [size]=\"iconSize()\" aria-hidden=\"true\" />\r\n }\r\n <span class=\"fui-badge__label\">{{ label() }}</span>\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)}}:host.fui-badge{--fui-badge-bg: transparent;--fui-badge-color: inherit;--fui-badge-font-size: var(--fui-font-size-01);--fui-badge-font-weight: var(--fui-font-weight-medium);--fui-badge-border-radius: var(--fui-border-radius-pill);--fui-badge-gap: var(--fui-spacing-02);--fui-badge-height-sm: 1.25rem;--fui-badge-height-md: 1.5rem;--fui-badge-height-lg: 2rem;contain:content;display:inline-flex;align-items:center;justify-content:center;font-family:var(--fui-font-family-sans);font-size:var(--fui-badge-font-size);font-weight:var(--fui-badge-font-weight);border-radius:var(--fui-badge-border-radius);background-color:var(--fui-badge-bg);color:var(--fui-badge-color);white-space:nowrap;transition:all var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}:host.fui-badge .fui-badge__content{display:flex;align-items:center;gap:var(--fui-badge-gap)}:host.fui-badge .fui-badge__label{line-height:1}:host.fui-badge .fui-badge__icon{display:inline-flex;align-items:center;justify-content:center}:host.fui-badge--sm{height:var(--fui-badge-height-sm);padding:0 var(--fui-spacing-03);font-size:var(--fui-font-size-01)}:host.fui-badge--md{height:var(--fui-badge-height-md);padding:0 var(--fui-spacing-04);font-size:var(--fui-font-size-02)}:host.fui-badge--lg{height:var(--fui-badge-height-lg);padding:0 var(--fui-spacing-05);font-size:var(--fui-font-size-03)}:host.fui-badge--primary{--fui-badge-bg: var(--fui-primary-20);--fui-badge-color: var(--fui-primary)}:host.fui-badge--secondary{--fui-badge-bg: var(--fui-secondary-20);--fui-badge-color: var(--fui-secondary-80)}:host.fui-badge--success{--fui-badge-bg: var(--fui-success-20);--fui-badge-color: var(--fui-success-80)}:host.fui-badge--info{--fui-badge-bg: var(--fui-info-20);--fui-badge-color: var(--fui-info-80)}:host.fui-badge--warning{--fui-badge-bg: var(--fui-warning-20);--fui-badge-color: var(--fui-warning-80)}:host.fui-badge--error{--fui-badge-bg: var(--fui-danger-20);--fui-badge-color: var(--fui-danger-80)}:host.fui-badge--custom{--fui-badge-bg: transparent;--fui-badge-color: inherit}@media(prefers-reduced-motion:reduce){:host.fui-badge{transition:none}}\n"], dependencies: [{ kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
104
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiBadgeComponent, isStandalone: true, selector: "fui-badge", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "class": "computedClasses()", "style": "computedStyles()", "attr.aria-label": "ariaLabel() || null" } }, ngImport: i0, template: "<div class=\"fui-badge__content\">\r\n @if (icon()) {\r\n <fui-icon class=\"fui-badge__icon\" [name]=\"icon()!\" [size]=\"iconSize()\" aria-hidden=\"true\" />\r\n }\r\n <span class=\"fui-badge__label\">{{ label() }}</span>\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)}}:host.fui-badge{--fui-badge-bg: transparent;--fui-badge-color: inherit;--fui-badge-font-size: var(--fui-text-sm);--fui-badge-font-weight: var(--fui-weight-medium);--fui-badge-border-radius: var(--fui-radius-pill);--fui-badge-gap: var(--fui-spacing-2);--fui-badge-height-sm: 1.25rem;--fui-badge-height-md: 1.5rem;--fui-badge-height-lg: 2rem;contain:content;display:inline-flex;align-items:center;justify-content:center;font-family:var(--fui-font-sans);font-size:var(--fui-badge-font-size);font-weight:var(--fui-badge-font-weight);border-radius:var(--fui-badge-border-radius);background-color:var(--fui-badge-bg);color:var(--fui-badge-color);white-space:nowrap;transition-property:all;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}:host.fui-badge .fui-badge__content{display:flex;align-items:center;gap:var(--fui-badge-gap)}:host.fui-badge .fui-badge__label{line-height:1}:host.fui-badge .fui-badge__icon{display:inline-flex;align-items:center;justify-content:center}:host.fui-badge--sm{height:var(--fui-badge-height-sm);padding:0 var(--fui-spacing-4);font-size:var(--fui-text-sm)}:host.fui-badge--md{height:var(--fui-badge-height-md);padding:0 var(--fui-spacing-6);font-size:var(--fui-text-base)}:host.fui-badge--lg{height:var(--fui-badge-height-lg);padding:0 var(--fui-spacing-7);font-size:var(--fui-text-md)}:host.fui-badge--primary{--fui-badge-bg: var(--fui-primary-20);--fui-badge-color: var(--fui-brand-fg)}:host.fui-badge--secondary{--fui-badge-bg: var(--fui-neutral-20);--fui-badge-color: var(--fui-neutral-80)}:host.fui-badge--success{--fui-badge-bg: var(--fui-success-20);--fui-badge-color: var(--fui-success-80)}:host.fui-badge--info{--fui-badge-bg: var(--fui-info-20);--fui-badge-color: var(--fui-info-80)}:host.fui-badge--warning{--fui-badge-bg: var(--fui-warning-20);--fui-badge-color: var(--fui-warning-80)}:host.fui-badge--error{--fui-badge-bg: var(--fui-error-20);--fui-badge-color: var(--fui-error-80)}:host.fui-badge--custom{--fui-badge-bg: transparent;--fui-badge-color: inherit}@media(prefers-reduced-motion:reduce){:host.fui-badge{transition:none}}\n"], dependencies: [{ kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
105
105
  }
106
106
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiBadgeComponent, decorators: [{
107
107
  type: Component,
@@ -110,7 +110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
110
110
  '[style]': 'computedStyles()',
111
111
  role: 'status',
112
112
  '[attr.aria-label]': 'ariaLabel() || null',
113
- }, template: "<div class=\"fui-badge__content\">\r\n @if (icon()) {\r\n <fui-icon class=\"fui-badge__icon\" [name]=\"icon()!\" [size]=\"iconSize()\" aria-hidden=\"true\" />\r\n }\r\n <span class=\"fui-badge__label\">{{ label() }}</span>\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)}}:host.fui-badge{--fui-badge-bg: transparent;--fui-badge-color: inherit;--fui-badge-font-size: var(--fui-font-size-01);--fui-badge-font-weight: var(--fui-font-weight-medium);--fui-badge-border-radius: var(--fui-border-radius-pill);--fui-badge-gap: var(--fui-spacing-02);--fui-badge-height-sm: 1.25rem;--fui-badge-height-md: 1.5rem;--fui-badge-height-lg: 2rem;contain:content;display:inline-flex;align-items:center;justify-content:center;font-family:var(--fui-font-family-sans);font-size:var(--fui-badge-font-size);font-weight:var(--fui-badge-font-weight);border-radius:var(--fui-badge-border-radius);background-color:var(--fui-badge-bg);color:var(--fui-badge-color);white-space:nowrap;transition:all var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}:host.fui-badge .fui-badge__content{display:flex;align-items:center;gap:var(--fui-badge-gap)}:host.fui-badge .fui-badge__label{line-height:1}:host.fui-badge .fui-badge__icon{display:inline-flex;align-items:center;justify-content:center}:host.fui-badge--sm{height:var(--fui-badge-height-sm);padding:0 var(--fui-spacing-03);font-size:var(--fui-font-size-01)}:host.fui-badge--md{height:var(--fui-badge-height-md);padding:0 var(--fui-spacing-04);font-size:var(--fui-font-size-02)}:host.fui-badge--lg{height:var(--fui-badge-height-lg);padding:0 var(--fui-spacing-05);font-size:var(--fui-font-size-03)}:host.fui-badge--primary{--fui-badge-bg: var(--fui-primary-20);--fui-badge-color: var(--fui-primary)}:host.fui-badge--secondary{--fui-badge-bg: var(--fui-secondary-20);--fui-badge-color: var(--fui-secondary-80)}:host.fui-badge--success{--fui-badge-bg: var(--fui-success-20);--fui-badge-color: var(--fui-success-80)}:host.fui-badge--info{--fui-badge-bg: var(--fui-info-20);--fui-badge-color: var(--fui-info-80)}:host.fui-badge--warning{--fui-badge-bg: var(--fui-warning-20);--fui-badge-color: var(--fui-warning-80)}:host.fui-badge--error{--fui-badge-bg: var(--fui-danger-20);--fui-badge-color: var(--fui-danger-80)}:host.fui-badge--custom{--fui-badge-bg: transparent;--fui-badge-color: inherit}@media(prefers-reduced-motion:reduce){:host.fui-badge{transition:none}}\n"] }]
113
+ }, template: "<div class=\"fui-badge__content\">\r\n @if (icon()) {\r\n <fui-icon class=\"fui-badge__icon\" [name]=\"icon()!\" [size]=\"iconSize()\" aria-hidden=\"true\" />\r\n }\r\n <span class=\"fui-badge__label\">{{ label() }}</span>\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)}}:host.fui-badge{--fui-badge-bg: transparent;--fui-badge-color: inherit;--fui-badge-font-size: var(--fui-text-sm);--fui-badge-font-weight: var(--fui-weight-medium);--fui-badge-border-radius: var(--fui-radius-pill);--fui-badge-gap: var(--fui-spacing-2);--fui-badge-height-sm: 1.25rem;--fui-badge-height-md: 1.5rem;--fui-badge-height-lg: 2rem;contain:content;display:inline-flex;align-items:center;justify-content:center;font-family:var(--fui-font-sans);font-size:var(--fui-badge-font-size);font-weight:var(--fui-badge-font-weight);border-radius:var(--fui-badge-border-radius);background-color:var(--fui-badge-bg);color:var(--fui-badge-color);white-space:nowrap;transition-property:all;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}:host.fui-badge .fui-badge__content{display:flex;align-items:center;gap:var(--fui-badge-gap)}:host.fui-badge .fui-badge__label{line-height:1}:host.fui-badge .fui-badge__icon{display:inline-flex;align-items:center;justify-content:center}:host.fui-badge--sm{height:var(--fui-badge-height-sm);padding:0 var(--fui-spacing-4);font-size:var(--fui-text-sm)}:host.fui-badge--md{height:var(--fui-badge-height-md);padding:0 var(--fui-spacing-6);font-size:var(--fui-text-base)}:host.fui-badge--lg{height:var(--fui-badge-height-lg);padding:0 var(--fui-spacing-7);font-size:var(--fui-text-md)}:host.fui-badge--primary{--fui-badge-bg: var(--fui-primary-20);--fui-badge-color: var(--fui-brand-fg)}:host.fui-badge--secondary{--fui-badge-bg: var(--fui-neutral-20);--fui-badge-color: var(--fui-neutral-80)}:host.fui-badge--success{--fui-badge-bg: var(--fui-success-20);--fui-badge-color: var(--fui-success-80)}:host.fui-badge--info{--fui-badge-bg: var(--fui-info-20);--fui-badge-color: var(--fui-info-80)}:host.fui-badge--warning{--fui-badge-bg: var(--fui-warning-20);--fui-badge-color: var(--fui-warning-80)}:host.fui-badge--error{--fui-badge-bg: var(--fui-error-20);--fui-badge-color: var(--fui-error-80)}:host.fui-badge--custom{--fui-badge-bg: transparent;--fui-badge-color: inherit}@media(prefers-reduced-motion:reduce){:host.fui-badge{transition:none}}\n"] }]
114
114
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], customColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColor", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
115
115
 
116
116
  /**