@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,10 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, ChangeDetectorRef, input, booleanAttribute, output, signal, computed, viewChild, effect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { Injectable, inject, ChangeDetectorRef, input, booleanAttribute, output, signal, computed, viewChild, effect, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
4
  import { NgForm, FormGroupDirective, NG_VALUE_ACCESSOR } from '@angular/forms';
5
5
  import { Subject } from 'rxjs';
6
6
  import { FuiIntlBase, DefaultErrorStateMatcher, FUI_FORM_FIELD_CONTROL } from '@raintonic/formaui/core';
7
7
  import { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';
8
+ import { FuiInputDirective } from '@raintonic/formaui/components/input';
8
9
  import { FuiIconComponent } from '@raintonic/formaui/components/icon';
9
10
 
10
11
  class FuiNumberInputIntl extends FuiIntlBase {
@@ -66,7 +67,8 @@ class FuiNumberInputComponent {
66
67
  placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
67
68
  disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
68
69
  transform: booleanAttribute });
69
- readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
70
+ readOnlyInput = input(false, { ...(ngDevMode ? { debugName: "readOnlyInput" } : /* istanbul ignore next */ {}), alias: 'readonly',
71
+ transform: booleanAttribute });
70
72
  showButtons = input(true, { ...(ngDevMode ? { debugName: "showButtons" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
71
73
  buttonLayout = input('horizontal', ...(ngDevMode ? [{ debugName: "buttonLayout" }] : /* istanbul ignore next */ []));
72
74
  errorStateMatcher = input(null, ...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
@@ -85,6 +87,7 @@ class FuiNumberInputComponent {
85
87
  errorState = this._errorState.asReadonly();
86
88
  required = this._required.asReadonly();
87
89
  disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
90
+ readonly = computed(() => this.readOnlyInput(), ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
88
91
  // Computed
89
92
  empty = computed(() => this._value() === null, ...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
90
93
  _isAtMin = computed(() => {
@@ -116,6 +119,8 @@ class FuiNumberInputComponent {
116
119
  }
117
120
  // ViewChild for input element
118
121
  inputElement = viewChild('inputElement', ...(ngDevMode ? [{ debugName: "inputElement" }] : /* istanbul ignore next */ []));
122
+ // ViewChild for fuiInput directive — delegates readonly/disabled/aria/state to it
123
+ _fuiInput;
119
124
  // ControlValueAccessor callbacks
120
125
  _onChange = () => {
121
126
  /* noop */
@@ -129,7 +134,9 @@ class FuiNumberInputComponent {
129
134
  this._ngControlRef.ngControl.valueAccessor = this;
130
135
  }
131
136
  });
132
- this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });
137
+ this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => {
138
+ this._cdr.markForCheck();
139
+ });
133
140
  // Effect to emit state changes
134
141
  effect(() => {
135
142
  this.min();
@@ -138,7 +145,7 @@ class FuiNumberInputComponent {
138
145
  this.precision();
139
146
  this.placeholder();
140
147
  this.disabledInput();
141
- this.readonly();
148
+ this.readOnlyInput();
142
149
  this.showButtons();
143
150
  this.buttonLayout();
144
151
  this.errorStateMatcher();
@@ -186,9 +193,7 @@ class FuiNumberInputComponent {
186
193
  }
187
194
  setDescribedByIds(ids) {
188
195
  this._ariaDescribedby = ids.length ? ids.join(' ') : null;
189
- }
190
- setReadOnly(_readOnly) {
191
- // Handled via input signal, but required by interface
196
+ this._fuiInput?.setDescribedByIds(ids);
192
197
  }
193
198
  // Public API
194
199
  focus() {
@@ -315,7 +320,7 @@ class FuiNumberInputComponent {
315
320
  return parsed;
316
321
  }
317
322
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
318
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiNumberInputComponent, isStandalone: true, selector: "fui-number-input", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, precision: { classPropertyName: "precision", publicName: "precision", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null }, buttonLayout: { classPropertyName: "buttonLayout", publicName: "buttonLayout", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.fui-number-input--disabled": "disabled()", "class.fui-number-input--readonly": "readonly()", "class.fui-number-input--focused": "focused()", "class.fui-number-input--error": "errorState()", "class.fui-number-input--has-buttons": "showButtons()", "class.fui-number-input--horizontal": "buttonLayout() === \"horizontal\"", "class.fui-number-input--vertical": "buttonLayout() === \"vertical\"", "attr.id": "id" }, classAttribute: "fui-number-input" }, providers: [
323
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiNumberInputComponent, isStandalone: true, selector: "fui-number-input", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, precision: { classPropertyName: "precision", publicName: "precision", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnlyInput: { classPropertyName: "readOnlyInput", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null }, buttonLayout: { classPropertyName: "buttonLayout", publicName: "buttonLayout", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.fui-number-input--disabled": "disabled()", "class.fui-number-input--readonly": "readonly()", "class.fui-number-input--focused": "focused()", "class.fui-number-input--error": "errorState()", "class.fui-number-input--has-buttons": "showButtons()", "class.fui-number-input--horizontal": "buttonLayout() === \"horizontal\"", "class.fui-number-input--vertical": "buttonLayout() === \"vertical\"", "attr.id": "id" }, classAttribute: "fui-number-input" }, providers: [
319
324
  {
320
325
  provide: NG_VALUE_ACCESSOR,
321
326
  useExisting: FuiNumberInputComponent,
@@ -325,11 +330,11 @@ class FuiNumberInputComponent {
325
330
  provide: FUI_FORM_FIELD_CONTROL,
326
331
  useExisting: FuiNumberInputComponent,
327
332
  },
328
- ], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fui-number-input__wrapper\">\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n [attr.readonly]=\"readonly() ? '' : null\"\r\n [attr.aria-valuenow]=\"value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-required]=\"required() ? 'true' : null\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (showButtons() && buttonLayout() === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-number-input{display:block;margin:0 -.6rem}.fui-number-input__wrapper{display:flex;flex-direction:row;align-items:stretch}.fui-number-input__input{flex:1 1 auto;min-width:0;border:none;outline:none;background:transparent;font-family:var(--fui-font-family-sans);font-size:var(--fui-font-size-02);font-weight:var(--fui-font-weight-regular);line-height:var(--fui-line-height-02);letter-spacing:var(--fui-letter-spacing-normal);color:var(--fui-text-primary);width:100%;box-sizing:border-box;padding:0 .5rem;text-align:left;transition:color var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-number-input__input::-webkit-outer-spin-button,.fui-number-input__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.fui-number-input__input{-moz-appearance:textfield}.fui-number-input__input::placeholder{color:var(--fui-text-disabled);opacity:1}.fui-number-input__input:focus{outline:none}.fui-number-input__input:focus-visible{outline:none}.fui-number-input__input:disabled{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary);cursor:not-allowed}.fui-number-input__input[readonly]{cursor:default}.fui-number-input__btn{background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;outline:none}.fui-number-input__btn:focus-visible{outline:2px solid var(--fui-primary);outline-offset:2px}.fui-number-input__btn{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:2rem;height:auto;border:none;margin:-.6rem 0;padding:0 .5rem;background:transparent;color:var(--fui-text-secondary);transition:color,background-color,opacity var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-number-input__btn:hover:not(:disabled){color:var(--fui-primary);background-color:var(--fui-primary-10)}.fui-number-input__btn:active:not(:disabled){color:var(--fui-primary-80);background-color:var(--fui-primary-20)}.fui-number-input__btn:disabled{opacity:.4;cursor:not-allowed}.fui-number-input__btn--decrement{border-right:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-number-input__btn--increment{border-left:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-number-input__btn-stack{display:flex;flex-direction:column;border-left:var(--fui-border-width-sm) solid var(--fui-border-color);margin:-.5rem 0}.fui-number-input__btn-stack .fui-number-input__btn{flex:1 1 50%;width:1.75rem;border-left:none;border-right:none;margin:0}.fui-number-input__btn-stack .fui-number-input__btn--increment{border-bottom:var(--fui-border-width-sm) solid var(--fui-border-color);border-left:none}.fui-number-input__btn-stack .fui-number-input__btn--decrement{border-right:none}.fui-number-input--disabled .fui-number-input__input{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary)}\n"], dependencies: [{ kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
333
+ ], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }, { propertyName: "_fuiInput", first: true, predicate: ["inputElement"], descendants: true, read: FuiInputDirective }], ngImport: i0, template: "@let _disabled = disabled();\r\n@let _readonly = readonly();\r\n@let __isAtMin = _isAtMin();\r\n@let __isAtMax = _isAtMax();\r\n@let _placeholder = placeholder();\r\n@let _value = value();\r\n@let _min = min();\r\n@let _max = max();\r\n@let _showButtons = showButtons();\r\n@let btnLayout = buttonLayout();\r\n\r\n<div class=\"fui-number-input__wrapper\">\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n fuiInput\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [placeholder]=\"_placeholder\"\r\n [disabled]=\"_disabled\"\r\n [readonly]=\"_readonly\"\r\n [attr.aria-valuenow]=\"_value\"\r\n [attr.aria-valuemin]=\"_min\"\r\n [attr.aria-valuemax]=\"_max\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (_showButtons && btnLayout === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-number-input{display:block}.fui-number-input__wrapper{display:flex;flex-direction:row;align-items:stretch}.fui-number-input__input{flex:1 1 auto;min-width:0;border:none;outline:none;background:transparent;font-family:var(--fui-font-sans);font-size:var(--fui-text-base);font-weight:var(--fui-weight-regular);line-height:var(--fui-leading-normal);letter-spacing:var(--fui-tracking-normal);color:var(--fui-text-primary);width:100%;box-sizing:border-box;padding:0 .5rem;text-align:left;transition-property:color;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-number-input__input::-webkit-outer-spin-button,.fui-number-input__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.fui-number-input__input{-moz-appearance:textfield}.fui-number-input__input::placeholder{color:var(--fui-text-disabled);opacity:1}.fui-number-input__input:focus{outline:none}.fui-number-input__input:focus-visible{outline:none}.fui-number-input__input:disabled{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary);cursor:not-allowed}.fui-number-input__input[readonly]{cursor:default}.fui-number-input__btn{background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;outline:none}.fui-number-input__btn:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-number-input__btn{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:2rem;height:auto;border:none;margin:-.6rem 0;background:transparent;color:var(--fui-text-secondary);transition-property:color,background-color,opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-number-input__btn:hover:not(:disabled){color:var(--fui-brand-fg);background-color:var(--fui-primary-10)}.fui-number-input__btn:active:not(:disabled){color:var(--fui-primary-80);background-color:var(--fui-primary-20)}.fui-number-input__btn:disabled{cursor:not-allowed}.fui-number-input__btn--decrement{border-right:var(--fui-border-width-sm) solid var(--fui-border-default);padding:0 0 0 .25rem}.fui-number-input__btn--decrement fui-icon{margin-left:-.25rem}.fui-number-input__btn--increment{border-left:var(--fui-border-width-sm) solid var(--fui-border-default);padding:0 .25rem 0 0}.fui-number-input__btn--increment fui-icon{margin-right:-.25rem}.fui-number-input__btn-stack{display:flex;flex-direction:column;border-left:var(--fui-border-width-sm) solid var(--fui-border-default);margin:-.5rem 0}.fui-number-input__btn-stack .fui-number-input__btn{flex:1 1 50%;width:1.75rem;border-left:none;border-right:none;margin:0;padding:0}.fui-number-input__btn-stack .fui-number-input__btn fui-icon{margin:0}.fui-number-input__btn-stack .fui-number-input__btn--increment{border-bottom:var(--fui-border-width-sm) solid var(--fui-border-default);border-left:none}.fui-number-input__btn-stack .fui-number-input__btn--decrement{border-right:none}.fui-number-input--disabled .fui-number-input__input{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary)}.fui-number-input--disabled .fui-number-input__btn fui-icon{color:var(--fui-text-disabled)}\n"], dependencies: [{ kind: "directive", type: FuiInputDirective, selector: "input[fuiInput], textarea[fuiInput], select[fuiInput]", inputs: ["type", "placeholder", "readonly", "maxlength", "minlength", "pattern", "errorStateMatcher", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
329
334
  }
330
335
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiNumberInputComponent, decorators: [{
331
336
  type: Component,
332
- args: [{ selector: 'fui-number-input', standalone: true, imports: [FuiIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
337
+ args: [{ selector: 'fui-number-input', standalone: true, imports: [FuiInputDirective, FuiIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
333
338
  class: 'fui-number-input',
334
339
  '[class.fui-number-input--disabled]': 'disabled()',
335
340
  '[class.fui-number-input--readonly]': 'readonly()',
@@ -349,8 +354,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
349
354
  provide: FUI_FORM_FIELD_CONTROL,
350
355
  useExisting: FuiNumberInputComponent,
351
356
  },
352
- ], template: "<div class=\"fui-number-input__wrapper\">\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n [attr.readonly]=\"readonly() ? '' : null\"\r\n [attr.aria-valuenow]=\"value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-required]=\"required() ? 'true' : null\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (showButtons() && buttonLayout() === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-number-input{display:block;margin:0 -.6rem}.fui-number-input__wrapper{display:flex;flex-direction:row;align-items:stretch}.fui-number-input__input{flex:1 1 auto;min-width:0;border:none;outline:none;background:transparent;font-family:var(--fui-font-family-sans);font-size:var(--fui-font-size-02);font-weight:var(--fui-font-weight-regular);line-height:var(--fui-line-height-02);letter-spacing:var(--fui-letter-spacing-normal);color:var(--fui-text-primary);width:100%;box-sizing:border-box;padding:0 .5rem;text-align:left;transition:color var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-number-input__input::-webkit-outer-spin-button,.fui-number-input__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.fui-number-input__input{-moz-appearance:textfield}.fui-number-input__input::placeholder{color:var(--fui-text-disabled);opacity:1}.fui-number-input__input:focus{outline:none}.fui-number-input__input:focus-visible{outline:none}.fui-number-input__input:disabled{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary);cursor:not-allowed}.fui-number-input__input[readonly]{cursor:default}.fui-number-input__btn{background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;outline:none}.fui-number-input__btn:focus-visible{outline:2px solid var(--fui-primary);outline-offset:2px}.fui-number-input__btn{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:2rem;height:auto;border:none;margin:-.6rem 0;padding:0 .5rem;background:transparent;color:var(--fui-text-secondary);transition:color,background-color,opacity var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-number-input__btn:hover:not(:disabled){color:var(--fui-primary);background-color:var(--fui-primary-10)}.fui-number-input__btn:active:not(:disabled){color:var(--fui-primary-80);background-color:var(--fui-primary-20)}.fui-number-input__btn:disabled{opacity:.4;cursor:not-allowed}.fui-number-input__btn--decrement{border-right:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-number-input__btn--increment{border-left:var(--fui-border-width-sm) solid var(--fui-border-color)}.fui-number-input__btn-stack{display:flex;flex-direction:column;border-left:var(--fui-border-width-sm) solid var(--fui-border-color);margin:-.5rem 0}.fui-number-input__btn-stack .fui-number-input__btn{flex:1 1 50%;width:1.75rem;border-left:none;border-right:none;margin:0}.fui-number-input__btn-stack .fui-number-input__btn--increment{border-bottom:var(--fui-border-width-sm) solid var(--fui-border-color);border-left:none}.fui-number-input__btn-stack .fui-number-input__btn--decrement{border-right:none}.fui-number-input--disabled .fui-number-input__input{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary)}\n"] }]
353
- }], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], precision: [{ type: i0.Input, args: [{ isSignal: true, alias: "precision", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], buttonLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLayout", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], inputElement: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }] } });
357
+ ], template: "@let _disabled = disabled();\r\n@let _readonly = readonly();\r\n@let __isAtMin = _isAtMin();\r\n@let __isAtMax = _isAtMax();\r\n@let _placeholder = placeholder();\r\n@let _value = value();\r\n@let _min = min();\r\n@let _max = max();\r\n@let _showButtons = showButtons();\r\n@let btnLayout = buttonLayout();\r\n\r\n<div class=\"fui-number-input__wrapper\">\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n fuiInput\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [placeholder]=\"_placeholder\"\r\n [disabled]=\"_disabled\"\r\n [readonly]=\"_readonly\"\r\n [attr.aria-valuenow]=\"_value\"\r\n [attr.aria-valuemin]=\"_min\"\r\n [attr.aria-valuemax]=\"_max\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (_showButtons && btnLayout === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-number-input{display:block}.fui-number-input__wrapper{display:flex;flex-direction:row;align-items:stretch}.fui-number-input__input{flex:1 1 auto;min-width:0;border:none;outline:none;background:transparent;font-family:var(--fui-font-sans);font-size:var(--fui-text-base);font-weight:var(--fui-weight-regular);line-height:var(--fui-leading-normal);letter-spacing:var(--fui-tracking-normal);color:var(--fui-text-primary);width:100%;box-sizing:border-box;padding:0 .5rem;text-align:left;transition-property:color;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-number-input__input::-webkit-outer-spin-button,.fui-number-input__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.fui-number-input__input{-moz-appearance:textfield}.fui-number-input__input::placeholder{color:var(--fui-text-disabled);opacity:1}.fui-number-input__input:focus{outline:none}.fui-number-input__input:focus-visible{outline:none}.fui-number-input__input:disabled{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary);cursor:not-allowed}.fui-number-input__input[readonly]{cursor:default}.fui-number-input__btn{background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;outline:none}.fui-number-input__btn:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-number-input__btn{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:2rem;height:auto;border:none;margin:-.6rem 0;background:transparent;color:var(--fui-text-secondary);transition-property:color,background-color,opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-number-input__btn:hover:not(:disabled){color:var(--fui-brand-fg);background-color:var(--fui-primary-10)}.fui-number-input__btn:active:not(:disabled){color:var(--fui-primary-80);background-color:var(--fui-primary-20)}.fui-number-input__btn:disabled{cursor:not-allowed}.fui-number-input__btn--decrement{border-right:var(--fui-border-width-sm) solid var(--fui-border-default);padding:0 0 0 .25rem}.fui-number-input__btn--decrement fui-icon{margin-left:-.25rem}.fui-number-input__btn--increment{border-left:var(--fui-border-width-sm) solid var(--fui-border-default);padding:0 .25rem 0 0}.fui-number-input__btn--increment fui-icon{margin-right:-.25rem}.fui-number-input__btn-stack{display:flex;flex-direction:column;border-left:var(--fui-border-width-sm) solid var(--fui-border-default);margin:-.5rem 0}.fui-number-input__btn-stack .fui-number-input__btn{flex:1 1 50%;width:1.75rem;border-left:none;border-right:none;margin:0;padding:0}.fui-number-input__btn-stack .fui-number-input__btn fui-icon{margin:0}.fui-number-input__btn-stack .fui-number-input__btn--increment{border-bottom:var(--fui-border-width-sm) solid var(--fui-border-default);border-left:none}.fui-number-input__btn-stack .fui-number-input__btn--decrement{border-right:none}.fui-number-input--disabled .fui-number-input__input{color:var(--fui-text-secondary);-webkit-text-fill-color:var(--fui-text-secondary)}.fui-number-input--disabled .fui-number-input__btn fui-icon{color:var(--fui-text-disabled)}\n"] }]
358
+ }], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], precision: [{ type: i0.Input, args: [{ isSignal: true, alias: "precision", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnlyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], buttonLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLayout", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], inputElement: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }], _fuiInput: [{
359
+ type: ViewChild,
360
+ args: ['inputElement', { read: FuiInputDirective, static: false }]
361
+ }] } });
354
362
 
355
363
  /**
356
364
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-number-input.mjs","sources":["../../../lib/components/number-input/number-input.intl.ts","../../../lib/components/number-input/number-input.component.ts","../../../lib/components/number-input/number-input.component.html","../../../lib/components/number-input/raintonic-formaui-components-number-input.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiNumberInputIntl extends FuiIntlBase {\r\n increaseAriaLabel = 'Increase value';\r\n decreaseAriaLabel = 'Decrease value';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n computed,\r\n signal,\r\n viewChild,\r\n ElementRef,\r\n WritableSignal,\r\n Signal,\r\n OnDestroy,\r\n DoCheck,\r\n inject,\r\n effect,\r\n booleanAttribute,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl, FormGroupDirective, NgForm } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { NumberInputButtonLayout } from './number-input.types';\r\nimport { FuiNumberInputIntl } from './number-input.intl';\r\n\r\n/**\r\n * # NumberInput Component\r\n *\r\n * A numeric input component with increment/decrement buttons,\r\n * full Angular Reactive Forms support, and FormField integration.\r\n *\r\n * ## Features\r\n * - Full Reactive Forms integration (ControlValueAccessor)\r\n * - FuiFormFieldControl integration for fui-form-field\r\n * - Increment/decrement buttons (horizontal or vertical layout)\r\n * - Min/max clamping and step support\r\n * - Configurable decimal precision\r\n * - Keyboard support (ArrowUp/ArrowDown)\r\n * - Error state handling\r\n * - Accessibility (ARIA spinbutton role)\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Quantity</fui-label>\r\n * <fui-number-input formControlName=\"quantity\" [min]=\"0\" [max]=\"100\" [step]=\"1\"></fui-number-input>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With vertical buttons\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Price</fui-label>\r\n * <fui-number-input formControlName=\"price\" [step]=\"0.01\" [precision]=\"2\" buttonLayout=\"vertical\"></fui-number-input>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-number-input',\r\n standalone: true,\r\n imports: [FuiIconComponent],\r\n templateUrl: './number-input.component.html',\r\n styleUrls: ['./number-input.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-number-input',\r\n '[class.fui-number-input--disabled]': 'disabled()',\r\n '[class.fui-number-input--readonly]': 'readonly()',\r\n '[class.fui-number-input--focused]': 'focused()',\r\n '[class.fui-number-input--error]': 'errorState()',\r\n '[class.fui-number-input--has-buttons]': 'showButtons()',\r\n '[class.fui-number-input--horizontal]': 'buttonLayout() === \"horizontal\"',\r\n '[class.fui-number-input--vertical]': 'buttonLayout() === \"vertical\"',\r\n '[attr.id]': 'id',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiNumberInputComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiNumberInputComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiNumberInputComponent implements ControlValueAccessor, FuiFormFieldControl<number>, DoCheck, OnDestroy {\r\n readonly intl = inject(FuiNumberInputIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-number-input';\r\n\r\n // Inputs\r\n readonly min = input<number | null>(null);\r\n readonly max = input<number | null>(null);\r\n readonly step = input(1);\r\n readonly precision = input<number | null>(null);\r\n readonly placeholder = input('');\r\n readonly disabledInput = input<boolean, unknown>(false, {\r\n alias: 'disabled',\r\n transform: booleanAttribute,\r\n });\r\n readonly readonly = input<boolean, unknown>(false, {\r\n transform: booleanAttribute,\r\n });\r\n readonly showButtons = input<boolean, unknown>(true, {\r\n transform: booleanAttribute,\r\n });\r\n readonly buttonLayout = input<NumberInputButtonLayout>('horizontal');\r\n readonly errorStateMatcher = input<ErrorStateMatcher | null>(null);\r\n\r\n // Outputs\r\n readonly valueChange = output<number | null>();\r\n\r\n // Internal state\r\n private readonly _value: WritableSignal<number | null> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n\r\n // Public signals\r\n readonly value: Signal<number | null> = this._value.asReadonly();\r\n readonly focused: Signal<boolean> = this._focused.asReadonly();\r\n readonly errorState: Signal<boolean> = this._errorState.asReadonly();\r\n readonly required: Signal<boolean> = this._required.asReadonly();\r\n readonly disabled: Signal<boolean> = computed(\r\n () => this._disabled() || this.disabledInput() || this._ngControlDisabled(),\r\n );\r\n\r\n // Computed\r\n readonly empty = computed(() => this._value() === null);\r\n\r\n readonly _isAtMin = computed(() => {\r\n const val = this._value();\r\n const minVal = this.min();\r\n if (val === null || minVal === null) return false;\r\n return val <= minVal;\r\n });\r\n\r\n readonly _isAtMax = computed(() => {\r\n const val = this._value();\r\n const maxVal = this.max();\r\n if (val === null || maxVal === null) return false;\r\n return val >= maxVal;\r\n });\r\n\r\n // State changes subject for form field compatibility\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-number-input-${FuiNumberInputComponent.nextId++}`;\r\n readonly id = this._uid;\r\n _ariaDescribedby: string | null = null;\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 // ViewChild for input element\r\n readonly inputElement = viewChild<ElementRef<HTMLInputElement>>('inputElement');\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: number | null) => void = () => {\r\n /* noop */\r\n };\r\n private _onTouched: () => void = () => {\r\n /* noop */\r\n };\r\n\r\n constructor() {\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 this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n this.min();\r\n this.max();\r\n this.step();\r\n this.precision();\r\n this.placeholder();\r\n this.disabledInput();\r\n this.readonly();\r\n this.showButtons();\r\n this.buttonLayout();\r\n this.errorStateMatcher();\r\n this._value();\r\n this._focused();\r\n this._disabled();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n\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 }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: number | null): void {\r\n const v = value ?? null;\r\n this._value.set(v);\r\n this._syncInputElement();\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: number | null) => 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._focused()) {\r\n this.focus();\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 // Handled via input signal, but required by interface\r\n }\r\n\r\n // Public API\r\n focus(): void {\r\n this.inputElement()?.nativeElement.focus();\r\n }\r\n\r\n increment(): void {\r\n if (this.disabled() || this.readonly()) return;\r\n const current = this._value() ?? 0;\r\n const newVal = this._clamp(this._roundToPrecision(current + this.step()));\r\n this._setValue(newVal);\r\n }\r\n\r\n decrement(): void {\r\n if (this.disabled() || this.readonly()) return;\r\n const current = this._value() ?? 0;\r\n const newVal = this._clamp(this._roundToPrecision(current - this.step()));\r\n this._setValue(newVal);\r\n }\r\n\r\n // Event handlers\r\n onInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const raw = target.value;\r\n const parsed = this._parseInputValue(raw);\r\n this._value.set(parsed);\r\n this._onChange(parsed);\r\n this.valueChange.emit(parsed);\r\n this.stateChanges.next();\r\n }\r\n\r\n onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n this.increment();\r\n } else if (event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n this.decrement();\r\n }\r\n }\r\n\r\n onFocus(): void {\r\n if (!this._focused()) {\r\n this._focused.set(true);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n onBlur(): void {\r\n if (this._focused()) {\r\n this._focused.set(false);\r\n this._onTouched();\r\n\r\n // On blur, clamp and format the value\r\n const current = this._value();\r\n if (current !== null) {\r\n const clamped = this._clamp(this._roundToPrecision(current));\r\n if (clamped !== current) {\r\n this._setValue(clamped);\r\n } else {\r\n // Re-sync the display to ensure formatting\r\n this._syncInputElement();\r\n }\r\n }\r\n\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n // Internal methods\r\n private _setValue(val: number | null): void {\r\n this._value.set(val);\r\n this._syncInputElement();\r\n this._onChange(val);\r\n this.valueChange.emit(val);\r\n this.stateChanges.next();\r\n }\r\n\r\n private _syncInputElement(): void {\r\n const el = this.inputElement()?.nativeElement;\r\n if (!el) return;\r\n const v = this._value();\r\n el.value = v !== null ? this._formatValue(v) : '';\r\n }\r\n\r\n private _formatValue(val: number): string {\r\n const p = this._getEffectivePrecision();\r\n if (p !== null) {\r\n return val.toFixed(p);\r\n }\r\n return String(val);\r\n }\r\n\r\n private _getEffectivePrecision(): number | null {\r\n const p = this.precision();\r\n if (p !== null) return p;\r\n // Auto-detect from step\r\n const s = this.step();\r\n const str = String(s);\r\n const dotIndex = str.indexOf('.');\r\n if (dotIndex === -1) return null;\r\n return str.length - dotIndex - 1;\r\n }\r\n\r\n _clamp(val: number): number {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n let result = val;\r\n if (minVal !== null && result < minVal) result = minVal;\r\n if (maxVal !== null && result > maxVal) result = maxVal;\r\n return result;\r\n }\r\n\r\n _roundToPrecision(val: number): number {\r\n const p = this._getEffectivePrecision();\r\n if (p === null) return val;\r\n // Use Number.toFixed to avoid floating point precision issues (e.g. 1.005 * 100 = 100.49999...)\r\n return parseFloat(val.toFixed(p));\r\n }\r\n\r\n _parseInputValue(raw: string): number | null {\r\n if (!raw || raw.trim() === '') return null;\r\n // Allow minus sign, digits, and decimal point\r\n const cleaned = raw.replace(/[^0-9.-]/g, '');\r\n const parsed = parseFloat(cleaned);\r\n if (isNaN(parsed)) return null;\r\n return parsed;\r\n }\r\n}\r\n","<div class=\"fui-number-input__wrapper\">\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [attr.placeholder]=\"placeholder()\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n [attr.readonly]=\"readonly() ? '' : null\"\r\n [attr.aria-valuenow]=\"value()\"\r\n [attr.aria-valuemin]=\"min()\"\r\n [attr.aria-valuemax]=\"max()\"\r\n [attr.aria-invalid]=\"errorState()\"\r\n [attr.aria-required]=\"required() ? 'true' : null\"\r\n [attr.aria-describedby]=\"_ariaDescribedby\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (showButtons() && buttonLayout() === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (showButtons() && buttonLayout() === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"disabled() || readonly() || _isAtMax()\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"disabled() || readonly() || _isAtMin()\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\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-number-input.mjs","sources":["../../../lib/components/number-input/number-input.intl.ts","../../../lib/components/number-input/number-input.component.ts","../../../lib/components/number-input/number-input.component.html","../../../lib/components/number-input/raintonic-formaui-components-number-input.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiNumberInputIntl extends FuiIntlBase {\r\n increaseAriaLabel = 'Increase value';\r\n decreaseAriaLabel = 'Decrease value';\r\n}\r\n","import {\r\n Component,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ViewEncapsulation,\r\n input,\r\n output,\r\n computed,\r\n signal,\r\n viewChild,\r\n ViewChild,\r\n ElementRef,\r\n WritableSignal,\r\n Signal,\r\n OnDestroy,\r\n DoCheck,\r\n inject,\r\n effect,\r\n booleanAttribute,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl, FormGroupDirective, NgForm } from '@angular/forms';\r\nimport { Subject } from 'rxjs';\r\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\r\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\r\nimport {\r\n injectNgControl,\r\n updateErrorState,\r\n syncRequiredState,\r\n syncNgControlDisabled,\r\n} from '@raintonic/formaui/cdk/form-field';\r\nimport { FuiInputDirective } from '@raintonic/formaui/components/input';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\nimport { NumberInputButtonLayout } from './number-input.types';\r\nimport { FuiNumberInputIntl } from './number-input.intl';\r\n\r\n/**\r\n * # NumberInput Component\r\n *\r\n * A numeric input component with increment/decrement buttons,\r\n * full Angular Reactive Forms support, and FormField integration.\r\n *\r\n * ## Features\r\n * - Full Reactive Forms integration (ControlValueAccessor)\r\n * - FuiFormFieldControl integration for fui-form-field\r\n * - Increment/decrement buttons (horizontal or vertical layout)\r\n * - Min/max clamping and step support\r\n * - Configurable decimal precision\r\n * - Keyboard support (ArrowUp/ArrowDown)\r\n * - Error state handling\r\n * - Accessibility (ARIA spinbutton role)\r\n *\r\n * ## Usage\r\n *\r\n * ### Basic\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Quantity</fui-label>\r\n * <fui-number-input formControlName=\"quantity\" [min]=\"0\" [max]=\"100\" [step]=\"1\"></fui-number-input>\r\n * </fui-form-field>\r\n * ```\r\n *\r\n * ### With vertical buttons\r\n * ```html\r\n * <fui-form-field>\r\n * <fui-label>Price</fui-label>\r\n * <fui-number-input formControlName=\"price\" [step]=\"0.01\" [precision]=\"2\" buttonLayout=\"vertical\"></fui-number-input>\r\n * </fui-form-field>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'fui-number-input',\r\n standalone: true,\r\n imports: [FuiInputDirective, FuiIconComponent],\r\n templateUrl: './number-input.component.html',\r\n styleUrls: ['./number-input.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.None,\r\n host: {\r\n class: 'fui-number-input',\r\n '[class.fui-number-input--disabled]': 'disabled()',\r\n '[class.fui-number-input--readonly]': 'readonly()',\r\n '[class.fui-number-input--focused]': 'focused()',\r\n '[class.fui-number-input--error]': 'errorState()',\r\n '[class.fui-number-input--has-buttons]': 'showButtons()',\r\n '[class.fui-number-input--horizontal]': 'buttonLayout() === \"horizontal\"',\r\n '[class.fui-number-input--vertical]': 'buttonLayout() === \"vertical\"',\r\n '[attr.id]': 'id',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: FuiNumberInputComponent,\r\n multi: true,\r\n },\r\n {\r\n provide: FUI_FORM_FIELD_CONTROL,\r\n useExisting: FuiNumberInputComponent,\r\n },\r\n ],\r\n})\r\nexport class FuiNumberInputComponent implements ControlValueAccessor, FuiFormFieldControl<number>, DoCheck, OnDestroy {\r\n readonly intl = inject(FuiNumberInputIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n // Static properties\r\n static nextId = 0;\r\n readonly controlType = 'fui-number-input';\r\n\r\n // Inputs\r\n readonly min = input<number | null>(null);\r\n readonly max = input<number | null>(null);\r\n readonly step = input(1);\r\n readonly precision = input<number | null>(null);\r\n readonly placeholder = input('');\r\n readonly disabledInput = input<boolean, unknown>(false, {\r\n alias: 'disabled',\r\n transform: booleanAttribute,\r\n });\r\n readonly readOnlyInput = input<boolean, unknown>(false, {\r\n alias: 'readonly',\r\n transform: booleanAttribute,\r\n });\r\n readonly showButtons = input<boolean, unknown>(true, {\r\n transform: booleanAttribute,\r\n });\r\n readonly buttonLayout = input<NumberInputButtonLayout>('horizontal');\r\n readonly errorStateMatcher = input<ErrorStateMatcher | null>(null);\r\n\r\n // Outputs\r\n readonly valueChange = output<number | null>();\r\n\r\n // Internal state\r\n private readonly _value: WritableSignal<number | null> = signal(null);\r\n private readonly _focused: WritableSignal<boolean> = signal(false);\r\n private readonly _disabled: WritableSignal<boolean> = signal(false);\r\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\r\n private readonly _errorState: WritableSignal<boolean> = signal(false);\r\n private readonly _required: WritableSignal<boolean> = signal(false);\r\n\r\n // Public signals\r\n readonly value: Signal<number | null> = this._value.asReadonly();\r\n readonly focused: Signal<boolean> = this._focused.asReadonly();\r\n readonly errorState: Signal<boolean> = this._errorState.asReadonly();\r\n readonly required: Signal<boolean> = this._required.asReadonly();\r\n readonly disabled: Signal<boolean> = computed(\r\n () => this._disabled() || this.disabledInput() || this._ngControlDisabled(),\r\n );\r\n readonly readonly: Signal<boolean> = computed(() => this.readOnlyInput());\r\n\r\n // Computed\r\n readonly empty = computed(() => this._value() === null);\r\n\r\n readonly _isAtMin = computed(() => {\r\n const val = this._value();\r\n const minVal = this.min();\r\n if (val === null || minVal === null) return false;\r\n return val <= minVal;\r\n });\r\n\r\n readonly _isAtMax = computed(() => {\r\n const val = this._value();\r\n const maxVal = this.max();\r\n if (val === null || maxVal === null) return false;\r\n return val >= maxVal;\r\n });\r\n\r\n // State changes subject for form field compatibility\r\n readonly stateChanges = new Subject<void>();\r\n private _uid = `fui-number-input-${FuiNumberInputComponent.nextId++}`;\r\n readonly id = this._uid;\r\n _ariaDescribedby: string | null = null;\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 // ViewChild for input element\r\n readonly inputElement = viewChild<ElementRef<HTMLInputElement>>('inputElement');\r\n\r\n // ViewChild for fuiInput directive — delegates readonly/disabled/aria/state to it\r\n @ViewChild('inputElement', { read: FuiInputDirective, static: false }) _fuiInput?: FuiInputDirective;\r\n\r\n // ControlValueAccessor callbacks\r\n private _onChange: (value: number | null) => void = () => {\r\n /* noop */\r\n };\r\n private _onTouched: () => void = () => {\r\n /* noop */\r\n };\r\n\r\n constructor() {\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 this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => {\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Effect to emit state changes\r\n effect(() => {\r\n this.min();\r\n this.max();\r\n this.step();\r\n this.precision();\r\n this.placeholder();\r\n this.disabledInput();\r\n this.readOnlyInput();\r\n this.showButtons();\r\n this.buttonLayout();\r\n this.errorStateMatcher();\r\n this._value();\r\n this._focused();\r\n this._disabled();\r\n this._ngControlDisabled();\r\n this._required();\r\n this._errorState();\r\n\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 }\r\n\r\n // ControlValueAccessor implementation\r\n writeValue(value: number | null): void {\r\n const v = value ?? null;\r\n this._value.set(v);\r\n this._syncInputElement();\r\n this.stateChanges.next();\r\n }\r\n\r\n registerOnChange(fn: (value: number | null) => 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._focused()) {\r\n this.focus();\r\n }\r\n }\r\n\r\n setDescribedByIds(ids: string[]): void {\r\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\r\n this._fuiInput?.setDescribedByIds(ids);\r\n }\r\n\r\n // Public API\r\n focus(): void {\r\n this.inputElement()?.nativeElement.focus();\r\n }\r\n\r\n increment(): void {\r\n if (this.disabled() || this.readonly()) return;\r\n const current = this._value() ?? 0;\r\n const newVal = this._clamp(this._roundToPrecision(current + this.step()));\r\n this._setValue(newVal);\r\n }\r\n\r\n decrement(): void {\r\n if (this.disabled() || this.readonly()) return;\r\n const current = this._value() ?? 0;\r\n const newVal = this._clamp(this._roundToPrecision(current - this.step()));\r\n this._setValue(newVal);\r\n }\r\n\r\n // Event handlers\r\n onInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const raw = target.value;\r\n const parsed = this._parseInputValue(raw);\r\n this._value.set(parsed);\r\n this._onChange(parsed);\r\n this.valueChange.emit(parsed);\r\n this.stateChanges.next();\r\n }\r\n\r\n onKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n this.increment();\r\n } else if (event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n this.decrement();\r\n }\r\n }\r\n\r\n onFocus(): void {\r\n if (!this._focused()) {\r\n this._focused.set(true);\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n onBlur(): void {\r\n if (this._focused()) {\r\n this._focused.set(false);\r\n this._onTouched();\r\n\r\n // On blur, clamp and format the value\r\n const current = this._value();\r\n if (current !== null) {\r\n const clamped = this._clamp(this._roundToPrecision(current));\r\n if (clamped !== current) {\r\n this._setValue(clamped);\r\n } else {\r\n // Re-sync the display to ensure formatting\r\n this._syncInputElement();\r\n }\r\n }\r\n\r\n this.stateChanges.next();\r\n }\r\n }\r\n\r\n // Internal methods\r\n private _setValue(val: number | null): void {\r\n this._value.set(val);\r\n this._syncInputElement();\r\n this._onChange(val);\r\n this.valueChange.emit(val);\r\n this.stateChanges.next();\r\n }\r\n\r\n private _syncInputElement(): void {\r\n const el = this.inputElement()?.nativeElement;\r\n if (!el) return;\r\n const v = this._value();\r\n el.value = v !== null ? this._formatValue(v) : '';\r\n }\r\n\r\n private _formatValue(val: number): string {\r\n const p = this._getEffectivePrecision();\r\n if (p !== null) {\r\n return val.toFixed(p);\r\n }\r\n return String(val);\r\n }\r\n\r\n private _getEffectivePrecision(): number | null {\r\n const p = this.precision();\r\n if (p !== null) return p;\r\n // Auto-detect from step\r\n const s = this.step();\r\n const str = String(s);\r\n const dotIndex = str.indexOf('.');\r\n if (dotIndex === -1) return null;\r\n return str.length - dotIndex - 1;\r\n }\r\n\r\n _clamp(val: number): number {\r\n const minVal = this.min();\r\n const maxVal = this.max();\r\n let result = val;\r\n if (minVal !== null && result < minVal) result = minVal;\r\n if (maxVal !== null && result > maxVal) result = maxVal;\r\n return result;\r\n }\r\n\r\n _roundToPrecision(val: number): number {\r\n const p = this._getEffectivePrecision();\r\n if (p === null) return val;\r\n // Use Number.toFixed to avoid floating point precision issues (e.g. 1.005 * 100 = 100.49999...)\r\n return parseFloat(val.toFixed(p));\r\n }\r\n\r\n _parseInputValue(raw: string): number | null {\r\n if (!raw || raw.trim() === '') return null;\r\n // Allow minus sign, digits, and decimal point\r\n const cleaned = raw.replace(/[^0-9.-]/g, '');\r\n const parsed = parseFloat(cleaned);\r\n if (isNaN(parsed)) return null;\r\n return parsed;\r\n }\r\n}\r\n","@let _disabled = disabled();\r\n@let _readonly = readonly();\r\n@let __isAtMin = _isAtMin();\r\n@let __isAtMax = _isAtMax();\r\n@let _placeholder = placeholder();\r\n@let _value = value();\r\n@let _min = min();\r\n@let _max = max();\r\n@let _showButtons = showButtons();\r\n@let btnLayout = buttonLayout();\r\n\r\n<div class=\"fui-number-input__wrapper\">\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"minus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n\r\n <input\r\n #inputElement\r\n fuiInput\r\n class=\"fui-number-input__input\"\r\n type=\"text\"\r\n inputmode=\"decimal\"\r\n [placeholder]=\"_placeholder\"\r\n [disabled]=\"_disabled\"\r\n [readonly]=\"_readonly\"\r\n [attr.aria-valuenow]=\"_value\"\r\n [attr.aria-valuemin]=\"_min\"\r\n [attr.aria-valuemax]=\"_max\"\r\n role=\"spinbutton\"\r\n (input)=\"onInput($event)\"\r\n (keydown)=\"onKeydown($event)\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n />\r\n\r\n @if (_showButtons && btnLayout === 'horizontal') {\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"plus\" size=\"sm\"></fui-icon>\r\n </button>\r\n }\r\n @if (_showButtons && btnLayout === 'vertical') {\r\n <div class=\"fui-number-input__btn-stack\">\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--increment\"\r\n [disabled]=\"_disabled || _readonly || __isAtMax\"\r\n (click)=\"increment()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.increaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-up\" size=\"sm\"></fui-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"fui-number-input__btn fui-number-input__btn--decrement\"\r\n [disabled]=\"_disabled || _readonly || __isAtMin\"\r\n (click)=\"decrement()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n [attr.aria-label]=\"intl.decreaseAriaLabel\"\r\n tabindex=\"-1\"\r\n >\r\n <fui-icon name=\"caret-down\" size=\"sm\"></fui-icon>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -139,13 +139,13 @@ class FuiPaginatorComponent {
139
139
  return typeof page === 'number';
140
140
  }
141
141
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiPaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiPaginatorComponent, isStandalone: true, selector: "fui-paginator", inputs: { numberOfItems: { classPropertyName: "numberOfItems", publicName: "numberOfItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: true, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSelected: "pageSelected" }, host: { classAttribute: "fui-paginator" }, viewQueries: [{ propertyName: "_pageAnnouncer", first: true, predicate: ["pageAnnouncer"], descendants: true }], ngImport: i0, template: "<div class=\"fui-paginator\">\r\n\r\n\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track page) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-paginator{--fui-paginator-bg: transparent;--fui-paginator-button-size: 2.5rem;--fui-paginator-font-size: var(--fui-font-size-sm);--fui-paginator-border-radius: var(--fui-border-radius-sm);--fui-paginator-gap: var(--fui-spacing-02);--fui-paginator-active-bg: var(--fui-primary);--fui-paginator-active-color: var(--fui-primary-text);--fui-paginator-active-hover-bg: var(--fui-primary-hover);--fui-paginator-hover-bg: var(--fui-primary-20)}.fui-paginator__container{display:flex;align-items:center;justify-content:center;gap:var(--fui-spacing-02);background-color:var(--fui-paginator-bg);flex-wrap:wrap}.fui-paginator__nav-button{flex-shrink:0;min-width:auto;padding:var(--fui-spacing-02)}.fui-paginator__nav-button:disabled{cursor:not-allowed;opacity:var(--fui-opacity-disabled)}.fui-paginator__page-buttons{display:flex;align-items:center;gap:var(--fui-spacing-01);flex-wrap:wrap;justify-content:center}.fui-paginator__page-button{min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);padding:0;border-radius:var(--fui-paginator-border-radius);font-weight:500;font-size:var(--fui-paginator-font-size)}.fui-paginator__page-button:not(:disabled){cursor:pointer}.fui-paginator__page-button:not(:disabled):hover{background-color:var(--fui-paginator-hover-bg)}.fui-paginator__page-button:disabled{cursor:not-allowed}.fui-paginator__page-button[aria-current=page]{background-color:var(--fui-paginator-active-bg);color:var(--fui-paginator-active-color);font-weight:600}.fui-paginator__page-button[aria-current=page]:hover{background-color:var(--fui-paginator-active-hover-bg)}.fui-paginator__page-button{transition:all var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-paginator__page-button:focus-visible{outline:2px solid var(--fui-primary);outline-offset:2px}.fui-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);color:var(--fui-text-secondary);font-weight:500;font-size:var(--fui-font-size-sm);-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: FuiButtonDirective, selector: "button[fuiButton], a[fuiButton]", inputs: ["variant", "size", "disabled", "fullWidth", "loading", "iconOnly", "aria-label", "type"] }, { kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }] });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: FuiPaginatorComponent, isStandalone: true, selector: "fui-paginator", inputs: { numberOfItems: { classPropertyName: "numberOfItems", publicName: "numberOfItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: true, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSelected: "pageSelected" }, host: { classAttribute: "fui-paginator" }, viewQueries: [{ propertyName: "_pageAnnouncer", first: true, predicate: ["pageAnnouncer"], descendants: true }], ngImport: i0, template: "<div class=\"fui-paginator\">\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track $index) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-paginator{--fui-paginator-bg: transparent;--fui-paginator-button-size: 2.5rem;--fui-paginator-font-size: var(--fui-text-base);--fui-paginator-border-radius: var(--fui-radius-sm);--fui-paginator-gap: var(--fui-spacing-2);--fui-paginator-active-bg: var(--fui-primary-bg);--fui-paginator-active-color: var(--fui-text-on-fill);--fui-paginator-active-hover-bg: var(--fui-primary-bg-hover);--fui-paginator-hover-bg: var(--fui-primary-20)}.fui-paginator__container{display:flex;align-items:center;justify-content:center;gap:var(--fui-spacing-2);background-color:var(--fui-paginator-bg);flex-wrap:wrap}.fui-paginator__nav-button{flex-shrink:0;min-width:auto;padding:var(--fui-spacing-2)}.fui-paginator__nav-button:disabled{cursor:not-allowed;opacity:var(--fui-state-disabled-opacity)}.fui-paginator__page-buttons{display:flex;align-items:center;gap:var(--fui-spacing-1);flex-wrap:wrap;justify-content:center}.fui-paginator__page-button{min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);padding:0;border-radius:var(--fui-paginator-border-radius);font-weight:500;font-size:var(--fui-paginator-font-size)}.fui-paginator__page-button:not(:disabled){cursor:pointer}.fui-paginator__page-button:not(:disabled):hover{background-color:var(--fui-paginator-hover-bg)}.fui-paginator__page-button:disabled{cursor:not-allowed}.fui-paginator__page-button[aria-current=page]{background-color:var(--fui-paginator-active-bg);color:var(--fui-paginator-active-color);font-weight:600}.fui-paginator__page-button[aria-current=page]:hover{background-color:var(--fui-paginator-active-hover-bg)}.fui-paginator__page-button{transition-property:all;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-paginator__page-button:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);color:var(--fui-text-secondary);font-weight:500;font-size:var(--fui-text-base);-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: FuiButtonDirective, selector: "button[fuiButton], a[fuiButton]", inputs: ["variant", "size", "disabled", "fullWidth", "loading", "iconOnly", "aria-label", "type"] }, { kind: "component", type: FuiIconComponent, selector: "fui-icon", inputs: ["name", "size", "weight", "color", "ariaLabel", "spin", "pulse"] }] });
143
143
  }
144
144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiPaginatorComponent, decorators: [{
145
145
  type: Component,
146
146
  args: [{ selector: 'fui-paginator', standalone: true, imports: [FuiButtonDirective, FuiIconComponent], host: {
147
147
  class: 'fui-paginator',
148
- }, template: "<div class=\"fui-paginator\">\r\n\r\n\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track page) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition:opacity var(--fui-duration-fast-02) var(--fui-ease-entrance) 0ms}.fui-motion-fade-out{transition:opacity var(--fui-duration-fast-01) var(--fui-ease-exit) 0ms}.fui-motion-slide-in-bottom{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition:transform var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition:transform,opacity var(--fui-duration-moderate-01) var(--fui-ease-entrance) 0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-moderate-01) var(--fui-ease-entrance)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-paginator{--fui-paginator-bg: transparent;--fui-paginator-button-size: 2.5rem;--fui-paginator-font-size: var(--fui-font-size-sm);--fui-paginator-border-radius: var(--fui-border-radius-sm);--fui-paginator-gap: var(--fui-spacing-02);--fui-paginator-active-bg: var(--fui-primary);--fui-paginator-active-color: var(--fui-primary-text);--fui-paginator-active-hover-bg: var(--fui-primary-hover);--fui-paginator-hover-bg: var(--fui-primary-20)}.fui-paginator__container{display:flex;align-items:center;justify-content:center;gap:var(--fui-spacing-02);background-color:var(--fui-paginator-bg);flex-wrap:wrap}.fui-paginator__nav-button{flex-shrink:0;min-width:auto;padding:var(--fui-spacing-02)}.fui-paginator__nav-button:disabled{cursor:not-allowed;opacity:var(--fui-opacity-disabled)}.fui-paginator__page-buttons{display:flex;align-items:center;gap:var(--fui-spacing-01);flex-wrap:wrap;justify-content:center}.fui-paginator__page-button{min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);padding:0;border-radius:var(--fui-paginator-border-radius);font-weight:500;font-size:var(--fui-paginator-font-size)}.fui-paginator__page-button:not(:disabled){cursor:pointer}.fui-paginator__page-button:not(:disabled):hover{background-color:var(--fui-paginator-hover-bg)}.fui-paginator__page-button:disabled{cursor:not-allowed}.fui-paginator__page-button[aria-current=page]{background-color:var(--fui-paginator-active-bg);color:var(--fui-paginator-active-color);font-weight:600}.fui-paginator__page-button[aria-current=page]:hover{background-color:var(--fui-paginator-active-hover-bg)}.fui-paginator__page-button{transition:all var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms}.fui-paginator__page-button:focus-visible{outline:2px solid var(--fui-primary);outline-offset:2px}.fui-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);color:var(--fui-text-secondary);font-weight:500;font-size:var(--fui-font-size-sm);-webkit-user-select:none;user-select:none}\n"] }]
148
+ }, template: "<div class=\"fui-paginator\">\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track $index) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n", styles: ["@keyframes fui-skeleton-pulse{0%{opacity:1}50%{opacity:.4}to{opacity:1}}@keyframes fui-spin{to{transform:rotate(360deg)}}@keyframes fui-shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-2px)}20%,40%,60%,80%{transform:translate(2px)}}.fui-motion-fade-in{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-out);transition-delay:0ms}.fui-motion-fade-out{transition-property:opacity;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in);transition-delay:0ms}.fui-motion-slide-in-bottom{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-bottom.fui-motion-entering{transform:translateY(1rem)}.fui-motion-slide-in-top{transition-property:transform;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:translateY(0)}.fui-motion-slide-in-top.fui-motion-entering{transform:translateY(-1rem)}.fui-motion-scale-in{transition-property:transform,opacity;transition-duration:var(--fui-duration-base);transition-timing-function:var(--fui-ease-out);transition-delay:0ms;transform:scale(1);opacity:1}.fui-motion-scale-in.fui-motion-entering{transform:scale(.95);opacity:0}.fui-no-motion{transition:none!important;animation:none!important}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@keyframes fui-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.05)}to{transform:scale(1);opacity:1}}@keyframes fui-slide-in{0%{transform:translate(120%)}to{transform:translate(0)}}.fui-slide-in{animation:fui-slide-in var(--fui-duration-base) var(--fui-ease-out)}@keyframes fui-popover-enter{0%{opacity:0;transform:translateY(-14px)}60%{opacity:1}to{opacity:1;transform:translateY(0)}}.fui-paginator{--fui-paginator-bg: transparent;--fui-paginator-button-size: 2.5rem;--fui-paginator-font-size: var(--fui-text-base);--fui-paginator-border-radius: var(--fui-radius-sm);--fui-paginator-gap: var(--fui-spacing-2);--fui-paginator-active-bg: var(--fui-primary-bg);--fui-paginator-active-color: var(--fui-text-on-fill);--fui-paginator-active-hover-bg: var(--fui-primary-bg-hover);--fui-paginator-hover-bg: var(--fui-primary-20)}.fui-paginator__container{display:flex;align-items:center;justify-content:center;gap:var(--fui-spacing-2);background-color:var(--fui-paginator-bg);flex-wrap:wrap}.fui-paginator__nav-button{flex-shrink:0;min-width:auto;padding:var(--fui-spacing-2)}.fui-paginator__nav-button:disabled{cursor:not-allowed;opacity:var(--fui-state-disabled-opacity)}.fui-paginator__page-buttons{display:flex;align-items:center;gap:var(--fui-spacing-1);flex-wrap:wrap;justify-content:center}.fui-paginator__page-button{min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);padding:0;border-radius:var(--fui-paginator-border-radius);font-weight:500;font-size:var(--fui-paginator-font-size)}.fui-paginator__page-button:not(:disabled){cursor:pointer}.fui-paginator__page-button:not(:disabled):hover{background-color:var(--fui-paginator-hover-bg)}.fui-paginator__page-button:disabled{cursor:not-allowed}.fui-paginator__page-button[aria-current=page]{background-color:var(--fui-paginator-active-bg);color:var(--fui-paginator-active-color);font-weight:600}.fui-paginator__page-button[aria-current=page]:hover{background-color:var(--fui-paginator-active-hover-bg)}.fui-paginator__page-button{transition-property:all;transition-duration:var(--fui-duration-fast);transition-timing-function:var(--fui-ease-in-out);transition-delay:0ms}.fui-paginator__page-button:focus-visible{outline:2px solid var(--fui-primary-10)}.fui-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--fui-paginator-button-size);height:var(--fui-paginator-button-size);color:var(--fui-text-secondary);font-weight:500;font-size:var(--fui-text-base);-webkit-user-select:none;user-select:none}\n"] }]
149
149
  }], ctorParameters: () => [], propDecorators: { numberOfItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "numberOfItems", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: true }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }], pageSelected: [{ type: i0.Output, args: ["pageSelected"] }], _pageAnnouncer: [{
150
150
  type: ViewChild,
151
151
  args: ['pageAnnouncer']
@@ -1 +1 @@
1
- {"version":3,"file":"raintonic-formaui-components-paginator.mjs","sources":["../../../lib/components/paginator/paginator.intl.ts","../../../lib/components/paginator/paginator.component.ts","../../../lib/components/paginator/paginator.component.html","../../../lib/components/paginator/raintonic-formaui-components-paginator.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiPaginatorIntl extends FuiIntlBase {\r\n rootAriaLabel = 'Pagination';\r\n prevPageAriaLabel = 'Go to previous page';\r\n nextPageAriaLabel = 'Go to next page';\r\n pageAriaLabel(page: number, total: number): string {\r\n return `Page ${page} of ${total}`;\r\n }\r\n}\r\n","import { ChangeDetectorRef, Component, computed, effect, ElementRef, inject, input, output, signal, ViewChild } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\n\r\nimport { FuiPaginatorIntl } from './paginator.intl';\r\n\r\n/**\r\n * # Paginator Component\r\n *\r\n * A pagination component that handles navigation through pages with:\r\n * - Previous/Next navigation buttons (disabled at boundaries)\r\n * - Page number buttons (at least 4 visible)\r\n * - Ellipsis (...) for remaining pages when there are more than 4 pages\r\n * - Emits page selection via output signal\r\n * - Keyboard support for accessibility\r\n */\r\n@Component({\r\n selector: 'fui-paginator',\r\n standalone: true,\r\n imports: [FuiButtonDirective, FuiIconComponent],\r\n templateUrl: './paginator.component.html',\r\n styleUrl: './paginator.component.scss',\r\n host: {\r\n class: 'fui-paginator',\r\n },\r\n})\r\nexport class FuiPaginatorComponent {\r\n // Input properties\r\n readonly numberOfItems = input.required<number>();\r\n readonly pageSize = input.required<number>();\r\n readonly currentPage = input(1);\r\n\r\n // Internal state\r\n private readonly _currentPage = signal(1);\r\n\r\n // Output events\r\n readonly pageSelected = output<number>();\r\n\r\n @ViewChild('pageAnnouncer') private _pageAnnouncer?: ElementRef<HTMLElement>;\r\n\r\n readonly intl = inject(FuiPaginatorIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n // Computed properties\r\n readonly totalPages = computed(() => {\r\n const total = this.numberOfItems();\r\n const size = this.pageSize();\r\n\r\n return Math.ceil(total / size);\r\n });\r\n\r\n readonly isFirstPage = computed(() => this._currentPage() === 1);\r\n readonly isLastPage = computed(() => this._currentPage() === this.totalPages());\r\n\r\n readonly pageNumbers = computed(() => {\r\n const currentPage = this._currentPage();\r\n const total = this.totalPages();\r\n\r\n if (total <= 4) {\r\n // Show all pages if 4 or fewer\r\n return Array.from({ length: total }, (_, i) => i + 1);\r\n }\r\n\r\n // Show at least 4 buttons with ellipsis for remaining pages\r\n const pages: (number | string)[] = [];\r\n\r\n // Always include first page\r\n pages.push(1);\r\n\r\n // Determine the range around current page\r\n let start = Math.max(2, currentPage - 1);\r\n let end = Math.min(total - 1, currentPage + 1);\r\n\r\n // Ensure we show at least 4 page buttons (including first and last)\r\n if (end - start < 2) {\r\n if (start === 2) {\r\n end = Math.min(total - 1, start + 2);\r\n } else {\r\n start = Math.max(2, end - 2);\r\n }\r\n }\r\n\r\n // Add ellipsis and pages\r\n if (start > 2) {\r\n pages.push('...');\r\n }\r\n\r\n for (let i = start; i <= end; i++) {\r\n pages.push(i);\r\n }\r\n\r\n if (end < total - 1) {\r\n pages.push('...');\r\n }\r\n\r\n // Always include last page\r\n pages.push(total);\r\n\r\n return pages;\r\n });\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n\r\n // Sync currentPage input to internal state\r\n effect(() => {\r\n const page = this.currentPage();\r\n this._currentPage.set(page);\r\n });\r\n\r\n // Reset to first page when numberOfItems or pageSize change\r\n effect(() => {\r\n this.numberOfItems();\r\n this.pageSize();\r\n this._currentPage.set(1);\r\n });\r\n }\r\n\r\n onPageClick(page: number | string): void {\r\n if (typeof page === 'number') {\r\n this._currentPage.set(page);\r\n this.pageSelected.emit(page);\r\n this._announce(this.intl.pageAriaLabel(page, this.totalPages()));\r\n }\r\n }\r\n\r\n onPreviousClick(): void {\r\n if (!this.isFirstPage()) {\r\n const newPage = this._currentPage() - 1;\r\n this._currentPage.set(newPage);\r\n this.pageSelected.emit(newPage);\r\n this._announce(this.intl.pageAriaLabel(newPage, this.totalPages()));\r\n }\r\n }\r\n\r\n onNextClick(): void {\r\n if (!this.isLastPage()) {\r\n const newPage = this._currentPage() + 1;\r\n this._currentPage.set(newPage);\r\n this.pageSelected.emit(newPage);\r\n this._announce(this.intl.pageAriaLabel(newPage, this.totalPages()));\r\n }\r\n }\r\n\r\n private _announce(message: string): void {\r\n if (this._pageAnnouncer?.nativeElement) {\r\n this._pageAnnouncer.nativeElement.textContent = message;\r\n }\r\n }\r\n\r\n getCurrentPage(): number {\r\n return this._currentPage();\r\n }\r\n\r\n isPageActive(page: number | string): boolean {\r\n return typeof page === 'number' && page === this._currentPage();\r\n }\r\n\r\n isPageClickable(page: number | string): boolean {\r\n return typeof page === 'number';\r\n }\r\n}\r\n","<div class=\"fui-paginator\">\r\n\r\n\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track page) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;AAIM,MAAO,gBAAiB,SAAQ,WAAW,CAAA;IAC/C,aAAa,GAAG,YAAY;IAC5B,iBAAiB,GAAG,qBAAqB;IACzC,iBAAiB,GAAG,iBAAiB;IACrC,aAAa,CAAC,IAAY,EAAE,KAAa,EAAA;AACvC,QAAA,OAAO,CAAA,KAAA,EAAQ,IAAI,CAAA,IAAA,EAAO,KAAK,EAAE;IACnC;uGANW,gBAAgB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA;;2FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACKlC;;;;;;;;;AASG;MAWU,qBAAqB,CAAA;;AAEvB,IAAA,aAAa,GAAG,KAAK,CAAC,QAAQ,mFAAU;AACxC,IAAA,QAAQ,GAAG,KAAK,CAAC,QAAQ,8EAAU;AACnC,IAAA,WAAW,GAAG,KAAK,CAAC,CAAC,kFAAC;;AAGd,IAAA,YAAY,GAAG,MAAM,CAAC,CAAC,mFAAC;;IAGhC,YAAY,GAAG,MAAM,EAAU;AAEJ,IAAA,cAAc;AAEzC,IAAA,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACvB,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;;AAGxC,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;AAClC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;QAE5B,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;AAChC,IAAA,CAAC,iFAAC;AAEO,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,kFAAC;AACvD,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,CAAC,UAAU,EAAE,iFAAC;AAEtE,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AACnC,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE;AACvC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE;AAE/B,QAAA,IAAI,KAAK,IAAI,CAAC,EAAE;;YAEd,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvD;;QAGA,MAAM,KAAK,GAAwB,EAAE;;AAGrC,QAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;;AAGb,QAAA,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC;AACxC,QAAA,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC;;AAG9C,QAAA,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE;AACnB,YAAA,IAAI,KAAK,KAAK,CAAC,EAAE;AACf,gBAAA,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;YACtC;iBAAO;gBACL,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;YAC9B;QACF;;AAGA,QAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACb,YAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACnB;AAEA,QAAA,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;AACjC,YAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACf;AAEA,QAAA,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE;AACnB,YAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACnB;;AAGA,QAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AAEjB,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,kFAAC;AAEF,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAK,EAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;;QAG3F,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7B,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,QAAQ,EAAE;AACf,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1B,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,WAAW,CAAC,IAAqB,EAAA;AAC/B,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC5B,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAC3B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAClE;IACF;IAEA,eAAe,GAAA;AACb,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC;AACvC,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;AAC/B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE;IACF;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC;AACvC,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;AAC/B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE;IACF;AAEQ,IAAA,SAAS,CAAC,OAAe,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE;YACtC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,WAAW,GAAG,OAAO;QACzD;IACF;IAEA,cAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,YAAY,EAAE;IAC5B;AAEA,IAAA,YAAY,CAAC,IAAqB,EAAA;QAChC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,YAAY,EAAE;IACjE;AAEA,IAAA,eAAe,CAAC,IAAqB,EAAA;AACnC,QAAA,OAAO,OAAO,IAAI,KAAK,QAAQ;IACjC;uGAtIW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,eAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,eAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC5BlC,olEAgEA,EAAA,MAAA,EAAA,CAAA,ouHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED3CY,kBAAkB,+KAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAOnC,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAVjC,SAAS;+BACE,eAAe,EAAA,UAAA,EACb,IAAI,EAAA,OAAA,EACP,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAAA,IAAA,EAGzC;AACJ,wBAAA,KAAK,EAAE,eAAe;AACvB,qBAAA,EAAA,QAAA,EAAA,olEAAA,EAAA,MAAA,EAAA,CAAA,ouHAAA,CAAA,EAAA;;sBAcA,SAAS;uBAAC,eAAe;;;AExC5B;;AAEG;;;;"}
1
+ {"version":3,"file":"raintonic-formaui-components-paginator.mjs","sources":["../../../lib/components/paginator/paginator.intl.ts","../../../lib/components/paginator/paginator.component.ts","../../../lib/components/paginator/paginator.component.html","../../../lib/components/paginator/raintonic-formaui-components-paginator.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { FuiIntlBase } from '@raintonic/formaui/core';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FuiPaginatorIntl extends FuiIntlBase {\r\n rootAriaLabel = 'Pagination';\r\n prevPageAriaLabel = 'Go to previous page';\r\n nextPageAriaLabel = 'Go to next page';\r\n pageAriaLabel(page: number, total: number): string {\r\n return `Page ${page} of ${total}`;\r\n }\r\n}\r\n","import { ChangeDetectorRef, Component, computed, effect, ElementRef, inject, input, output, signal, ViewChild } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\n\r\nimport { FuiButtonDirective } from '@raintonic/formaui/components/button';\r\nimport { FuiIconComponent } from '@raintonic/formaui/components/icon';\r\n\r\nimport { FuiPaginatorIntl } from './paginator.intl';\r\n\r\n/**\r\n * # Paginator Component\r\n *\r\n * A pagination component that handles navigation through pages with:\r\n * - Previous/Next navigation buttons (disabled at boundaries)\r\n * - Page number buttons (at least 4 visible)\r\n * - Ellipsis (...) for remaining pages when there are more than 4 pages\r\n * - Emits page selection via output signal\r\n * - Keyboard support for accessibility\r\n */\r\n@Component({\r\n selector: 'fui-paginator',\r\n standalone: true,\r\n imports: [FuiButtonDirective, FuiIconComponent],\r\n templateUrl: './paginator.component.html',\r\n styleUrl: './paginator.component.scss',\r\n host: {\r\n class: 'fui-paginator',\r\n },\r\n})\r\nexport class FuiPaginatorComponent {\r\n // Input properties\r\n readonly numberOfItems = input.required<number>();\r\n readonly pageSize = input.required<number>();\r\n readonly currentPage = input(1);\r\n\r\n // Internal state\r\n private readonly _currentPage = signal(1);\r\n\r\n // Output events\r\n readonly pageSelected = output<number>();\r\n\r\n @ViewChild('pageAnnouncer') private _pageAnnouncer?: ElementRef<HTMLElement>;\r\n\r\n readonly intl = inject(FuiPaginatorIntl);\r\n private readonly _cdr = inject(ChangeDetectorRef);\r\n\r\n // Computed properties\r\n readonly totalPages = computed(() => {\r\n const total = this.numberOfItems();\r\n const size = this.pageSize();\r\n\r\n return Math.ceil(total / size);\r\n });\r\n\r\n readonly isFirstPage = computed(() => this._currentPage() === 1);\r\n readonly isLastPage = computed(() => this._currentPage() === this.totalPages());\r\n\r\n readonly pageNumbers = computed(() => {\r\n const currentPage = this._currentPage();\r\n const total = this.totalPages();\r\n\r\n if (total <= 4) {\r\n // Show all pages if 4 or fewer\r\n return Array.from({ length: total }, (_, i) => i + 1);\r\n }\r\n\r\n // Show at least 4 buttons with ellipsis for remaining pages\r\n const pages: (number | string)[] = [];\r\n\r\n // Always include first page\r\n pages.push(1);\r\n\r\n // Determine the range around current page\r\n let start = Math.max(2, currentPage - 1);\r\n let end = Math.min(total - 1, currentPage + 1);\r\n\r\n // Ensure we show at least 4 page buttons (including first and last)\r\n if (end - start < 2) {\r\n if (start === 2) {\r\n end = Math.min(total - 1, start + 2);\r\n } else {\r\n start = Math.max(2, end - 2);\r\n }\r\n }\r\n\r\n // Add ellipsis and pages\r\n if (start > 2) {\r\n pages.push('...');\r\n }\r\n\r\n for (let i = start; i <= end; i++) {\r\n pages.push(i);\r\n }\r\n\r\n if (end < total - 1) {\r\n pages.push('...');\r\n }\r\n\r\n // Always include last page\r\n pages.push(total);\r\n\r\n return pages;\r\n });\r\n\r\n constructor() {\r\n this.intl.changes.pipe(takeUntilDestroyed()).subscribe(() => { this._cdr.markForCheck(); });\r\n\r\n // Sync currentPage input to internal state\r\n effect(() => {\r\n const page = this.currentPage();\r\n this._currentPage.set(page);\r\n });\r\n\r\n // Reset to first page when numberOfItems or pageSize change\r\n effect(() => {\r\n this.numberOfItems();\r\n this.pageSize();\r\n this._currentPage.set(1);\r\n });\r\n }\r\n\r\n onPageClick(page: number | string): void {\r\n if (typeof page === 'number') {\r\n this._currentPage.set(page);\r\n this.pageSelected.emit(page);\r\n this._announce(this.intl.pageAriaLabel(page, this.totalPages()));\r\n }\r\n }\r\n\r\n onPreviousClick(): void {\r\n if (!this.isFirstPage()) {\r\n const newPage = this._currentPage() - 1;\r\n this._currentPage.set(newPage);\r\n this.pageSelected.emit(newPage);\r\n this._announce(this.intl.pageAriaLabel(newPage, this.totalPages()));\r\n }\r\n }\r\n\r\n onNextClick(): void {\r\n if (!this.isLastPage()) {\r\n const newPage = this._currentPage() + 1;\r\n this._currentPage.set(newPage);\r\n this.pageSelected.emit(newPage);\r\n this._announce(this.intl.pageAriaLabel(newPage, this.totalPages()));\r\n }\r\n }\r\n\r\n private _announce(message: string): void {\r\n if (this._pageAnnouncer?.nativeElement) {\r\n this._pageAnnouncer.nativeElement.textContent = message;\r\n }\r\n }\r\n\r\n getCurrentPage(): number {\r\n return this._currentPage();\r\n }\r\n\r\n isPageActive(page: number | string): boolean {\r\n return typeof page === 'number' && page === this._currentPage();\r\n }\r\n\r\n isPageClickable(page: number | string): boolean {\r\n return typeof page === 'number';\r\n }\r\n}\r\n","<div class=\"fui-paginator\">\r\n <nav role=\"navigation\" [attr.aria-label]=\"intl.rootAriaLabel\" class=\"fui-paginator__container\">\r\n <!-- Live region for page change announcements -->\r\n <div class=\"fui-sr-only\" aria-live=\"polite\" aria-atomic=\"true\" #pageAnnouncer></div>\r\n\r\n <!-- Previous Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isFirstPage()\"\r\n [attr.aria-disabled]=\"isFirstPage()\"\r\n (click)=\"onPreviousClick()\"\r\n [aria-label]=\"intl.prevPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-left\" size=\"md\"></fui-icon>\r\n </button>\r\n\r\n <!-- Page Numbers -->\r\n <div class=\"fui-paginator__page-buttons\">\r\n @for (page of pageNumbers(); track $index) {\r\n @if (typeof page === 'string') {\r\n <!-- Ellipsis -->\r\n <span class=\"fui-paginator__ellipsis\" aria-hidden=\"true\">\r\n {{ page }}\r\n </span>\r\n } @else {\r\n <!-- Page Number Button -->\r\n <button\r\n fuiButton\r\n [variant]=\"isPageActive(page) ? 'primary' : 'tertiary'\"\r\n size=\"md\"\r\n [disabled]=\"false\"\r\n (click)=\"onPageClick(page)\"\r\n [attr.aria-current]=\"isPageActive(page) ? 'page' : null\"\r\n [aria-label]=\"intl.pageAriaLabel(page, totalPages())\"\r\n class=\"fui-paginator__page-button\"\r\n >\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Next Button -->\r\n <button\r\n fuiButton\r\n variant=\"secondary\"\r\n size=\"md\"\r\n iconOnly\r\n [disabled]=\"isLastPage()\"\r\n [attr.aria-disabled]=\"isLastPage()\"\r\n (click)=\"onNextClick()\"\r\n [aria-label]=\"intl.nextPageAriaLabel\"\r\n class=\"fui-paginator__nav-button\"\r\n >\r\n <fui-icon name=\"caret-right\" size=\"md\"></fui-icon>\r\n </button>\r\n </nav>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}