@raintonic/formaui 0.2.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 (240) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +145 -0
  3. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs +806 -0
  4. package/fesm2022/raintonic-formaui-cdk-drag-drop.mjs.map +1 -0
  5. package/fesm2022/raintonic-formaui-cdk-form-field.mjs +86 -0
  6. package/fesm2022/raintonic-formaui-cdk-form-field.mjs.map +1 -0
  7. package/fesm2022/raintonic-formaui-cdk-overlay.mjs +1757 -0
  8. package/fesm2022/raintonic-formaui-cdk-overlay.mjs.map +1 -0
  9. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs +287 -0
  10. package/fesm2022/raintonic-formaui-cdk-virtual-scroll.mjs.map +1 -0
  11. package/fesm2022/raintonic-formaui-components-accordion.mjs +217 -0
  12. package/fesm2022/raintonic-formaui-components-accordion.mjs.map +1 -0
  13. package/fesm2022/raintonic-formaui-components-alert.mjs +161 -0
  14. package/fesm2022/raintonic-formaui-components-alert.mjs.map +1 -0
  15. package/fesm2022/raintonic-formaui-components-autocomplete.mjs +726 -0
  16. package/fesm2022/raintonic-formaui-components-autocomplete.mjs.map +1 -0
  17. package/fesm2022/raintonic-formaui-components-avatar.mjs +92 -0
  18. package/fesm2022/raintonic-formaui-components-avatar.mjs.map +1 -0
  19. package/fesm2022/raintonic-formaui-components-badge.mjs +107 -0
  20. package/fesm2022/raintonic-formaui-components-badge.mjs.map +1 -0
  21. package/fesm2022/raintonic-formaui-components-big-menu.mjs +68 -0
  22. package/fesm2022/raintonic-formaui-components-big-menu.mjs.map +1 -0
  23. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs +55 -0
  24. package/fesm2022/raintonic-formaui-components-breadcrumb.mjs.map +1 -0
  25. package/fesm2022/raintonic-formaui-components-button-group.mjs +103 -0
  26. package/fesm2022/raintonic-formaui-components-button-group.mjs.map +1 -0
  27. package/fesm2022/raintonic-formaui-components-button.mjs +241 -0
  28. package/fesm2022/raintonic-formaui-components-button.mjs.map +1 -0
  29. package/fesm2022/raintonic-formaui-components-card.mjs +270 -0
  30. package/fesm2022/raintonic-formaui-components-card.mjs.map +1 -0
  31. package/fesm2022/raintonic-formaui-components-checkbox.mjs +295 -0
  32. package/fesm2022/raintonic-formaui-components-checkbox.mjs.map +1 -0
  33. package/fesm2022/raintonic-formaui-components-data-table.mjs +631 -0
  34. package/fesm2022/raintonic-formaui-components-data-table.mjs.map +1 -0
  35. package/fesm2022/raintonic-formaui-components-date-picker.mjs +1331 -0
  36. package/fesm2022/raintonic-formaui-components-date-picker.mjs.map +1 -0
  37. package/fesm2022/raintonic-formaui-components-divider.mjs +41 -0
  38. package/fesm2022/raintonic-formaui-components-divider.mjs.map +1 -0
  39. package/fesm2022/raintonic-formaui-components-drawer.mjs +190 -0
  40. package/fesm2022/raintonic-formaui-components-drawer.mjs.map +1 -0
  41. package/fesm2022/raintonic-formaui-components-dynamic-form.mjs +266 -0
  42. package/fesm2022/raintonic-formaui-components-dynamic-form.mjs.map +1 -0
  43. package/fesm2022/raintonic-formaui-components-empty-state.mjs +33 -0
  44. package/fesm2022/raintonic-formaui-components-empty-state.mjs.map +1 -0
  45. package/fesm2022/raintonic-formaui-components-file-upload.mjs +246 -0
  46. package/fesm2022/raintonic-formaui-components-file-upload.mjs.map +1 -0
  47. package/fesm2022/raintonic-formaui-components-form-field.mjs +482 -0
  48. package/fesm2022/raintonic-formaui-components-form-field.mjs.map +1 -0
  49. package/fesm2022/raintonic-formaui-components-icon.mjs +117 -0
  50. package/fesm2022/raintonic-formaui-components-icon.mjs.map +1 -0
  51. package/fesm2022/raintonic-formaui-components-input.mjs +327 -0
  52. package/fesm2022/raintonic-formaui-components-input.mjs.map +1 -0
  53. package/fesm2022/raintonic-formaui-components-list.mjs +149 -0
  54. package/fesm2022/raintonic-formaui-components-list.mjs.map +1 -0
  55. package/fesm2022/raintonic-formaui-components-menu.mjs +896 -0
  56. package/fesm2022/raintonic-formaui-components-menu.mjs.map +1 -0
  57. package/fesm2022/raintonic-formaui-components-number-input.mjs +345 -0
  58. package/fesm2022/raintonic-formaui-components-number-input.mjs.map +1 -0
  59. package/fesm2022/raintonic-formaui-components-paginator.mjs +139 -0
  60. package/fesm2022/raintonic-formaui-components-paginator.mjs.map +1 -0
  61. package/fesm2022/raintonic-formaui-components-password-input.mjs +306 -0
  62. package/fesm2022/raintonic-formaui-components-password-input.mjs.map +1 -0
  63. package/fesm2022/raintonic-formaui-components-popover.mjs +451 -0
  64. package/fesm2022/raintonic-formaui-components-popover.mjs.map +1 -0
  65. package/fesm2022/raintonic-formaui-components-progressbar.mjs +148 -0
  66. package/fesm2022/raintonic-formaui-components-progressbar.mjs.map +1 -0
  67. package/fesm2022/raintonic-formaui-components-radio.mjs +260 -0
  68. package/fesm2022/raintonic-formaui-components-radio.mjs.map +1 -0
  69. package/fesm2022/raintonic-formaui-components-select.mjs +1011 -0
  70. package/fesm2022/raintonic-formaui-components-select.mjs.map +1 -0
  71. package/fesm2022/raintonic-formaui-components-side-panel.mjs +150 -0
  72. package/fesm2022/raintonic-formaui-components-side-panel.mjs.map +1 -0
  73. package/fesm2022/raintonic-formaui-components-sidebar.mjs +257 -0
  74. package/fesm2022/raintonic-formaui-components-sidebar.mjs.map +1 -0
  75. package/fesm2022/raintonic-formaui-components-skeleton.mjs +50 -0
  76. package/fesm2022/raintonic-formaui-components-skeleton.mjs.map +1 -0
  77. package/fesm2022/raintonic-formaui-components-slider.mjs +347 -0
  78. package/fesm2022/raintonic-formaui-components-slider.mjs.map +1 -0
  79. package/fesm2022/raintonic-formaui-components-spinner.mjs +63 -0
  80. package/fesm2022/raintonic-formaui-components-spinner.mjs.map +1 -0
  81. package/fesm2022/raintonic-formaui-components-stepper.mjs +317 -0
  82. package/fesm2022/raintonic-formaui-components-stepper.mjs.map +1 -0
  83. package/fesm2022/raintonic-formaui-components-tab.mjs +197 -0
  84. package/fesm2022/raintonic-formaui-components-tab.mjs.map +1 -0
  85. package/fesm2022/raintonic-formaui-components-tag.mjs +78 -0
  86. package/fesm2022/raintonic-formaui-components-tag.mjs.map +1 -0
  87. package/fesm2022/raintonic-formaui-components-time-picker.mjs +644 -0
  88. package/fesm2022/raintonic-formaui-components-time-picker.mjs.map +1 -0
  89. package/fesm2022/raintonic-formaui-components-toggle.mjs +171 -0
  90. package/fesm2022/raintonic-formaui-components-toggle.mjs.map +1 -0
  91. package/fesm2022/raintonic-formaui-components-toolbar.mjs +140 -0
  92. package/fesm2022/raintonic-formaui-components-toolbar.mjs.map +1 -0
  93. package/fesm2022/raintonic-formaui-components-tooltip.mjs +555 -0
  94. package/fesm2022/raintonic-formaui-components-tooltip.mjs.map +1 -0
  95. package/fesm2022/raintonic-formaui-components-tree-select.mjs +314 -0
  96. package/fesm2022/raintonic-formaui-components-tree-select.mjs.map +1 -0
  97. package/fesm2022/raintonic-formaui-components-tree-table.mjs +103 -0
  98. package/fesm2022/raintonic-formaui-components-tree-table.mjs.map +1 -0
  99. package/fesm2022/raintonic-formaui-components-tree.mjs +430 -0
  100. package/fesm2022/raintonic-formaui-components-tree.mjs.map +1 -0
  101. package/fesm2022/raintonic-formaui-core.mjs +62 -0
  102. package/fesm2022/raintonic-formaui-core.mjs.map +1 -0
  103. package/fesm2022/raintonic-formaui-services-dialog.mjs +798 -0
  104. package/fesm2022/raintonic-formaui-services-dialog.mjs.map +1 -0
  105. package/fesm2022/raintonic-formaui-services-notification.mjs +391 -0
  106. package/fesm2022/raintonic-formaui-services-notification.mjs.map +1 -0
  107. package/fesm2022/raintonic-formaui-services-theme.mjs +248 -0
  108. package/fesm2022/raintonic-formaui-services-theme.mjs.map +1 -0
  109. package/fesm2022/raintonic-formaui-test-utils.mjs +66 -0
  110. package/fesm2022/raintonic-formaui-test-utils.mjs.map +1 -0
  111. package/fesm2022/raintonic-formaui.mjs +15 -0
  112. package/fesm2022/raintonic-formaui.mjs.map +1 -0
  113. package/llms-full.txt +1627 -0
  114. package/llms.txt +60 -0
  115. package/package.json +251 -0
  116. package/styles/_fonts-entry.scss +3 -0
  117. package/styles/fonts/dm-mono-400-latin.woff2 +0 -0
  118. package/styles/fonts/inter-tight-latin-italic.woff2 +0 -0
  119. package/styles/fonts/inter-tight-latin.woff2 +0 -0
  120. package/styles/index.scss +127 -0
  121. package/styles/partials/_constants.scss +29 -0
  122. package/styles/partials/_fonts.scss +36 -0
  123. package/styles/partials/_grid.scss +171 -0
  124. package/styles/partials/_mixins.scss +145 -0
  125. package/styles/partials/_motion.scss +252 -0
  126. package/styles/partials/_theme.scss +275 -0
  127. package/styles/partials/_typography.scss +112 -0
  128. package/styles/partials/_utilities.scss +480 -0
  129. package/styles/partials/themes/_dark.scss +254 -0
  130. package/styles/partials/themes/_light.scss +254 -0
  131. package/types/raintonic-formaui-cdk-drag-drop.d.ts +196 -0
  132. package/types/raintonic-formaui-cdk-drag-drop.d.ts.map +1 -0
  133. package/types/raintonic-formaui-cdk-form-field.d.ts +62 -0
  134. package/types/raintonic-formaui-cdk-form-field.d.ts.map +1 -0
  135. package/types/raintonic-formaui-cdk-overlay.d.ts +843 -0
  136. package/types/raintonic-formaui-cdk-overlay.d.ts.map +1 -0
  137. package/types/raintonic-formaui-cdk-virtual-scroll.d.ts +112 -0
  138. package/types/raintonic-formaui-cdk-virtual-scroll.d.ts.map +1 -0
  139. package/types/raintonic-formaui-components-accordion.d.ts +124 -0
  140. package/types/raintonic-formaui-components-accordion.d.ts.map +1 -0
  141. package/types/raintonic-formaui-components-alert.d.ts +143 -0
  142. package/types/raintonic-formaui-components-alert.d.ts.map +1 -0
  143. package/types/raintonic-formaui-components-autocomplete.d.ts +193 -0
  144. package/types/raintonic-formaui-components-autocomplete.d.ts.map +1 -0
  145. package/types/raintonic-formaui-components-avatar.d.ts +52 -0
  146. package/types/raintonic-formaui-components-avatar.d.ts.map +1 -0
  147. package/types/raintonic-formaui-components-badge.d.ts +47 -0
  148. package/types/raintonic-formaui-components-badge.d.ts.map +1 -0
  149. package/types/raintonic-formaui-components-big-menu.d.ts +62 -0
  150. package/types/raintonic-formaui-components-big-menu.d.ts.map +1 -0
  151. package/types/raintonic-formaui-components-breadcrumb.d.ts +26 -0
  152. package/types/raintonic-formaui-components-breadcrumb.d.ts.map +1 -0
  153. package/types/raintonic-formaui-components-button-group.d.ts +61 -0
  154. package/types/raintonic-formaui-components-button-group.d.ts.map +1 -0
  155. package/types/raintonic-formaui-components-button.d.ts +116 -0
  156. package/types/raintonic-formaui-components-button.d.ts.map +1 -0
  157. package/types/raintonic-formaui-components-card.d.ts +191 -0
  158. package/types/raintonic-formaui-components-card.d.ts.map +1 -0
  159. package/types/raintonic-formaui-components-checkbox.d.ts +132 -0
  160. package/types/raintonic-formaui-components-checkbox.d.ts.map +1 -0
  161. package/types/raintonic-formaui-components-data-table.d.ts +368 -0
  162. package/types/raintonic-formaui-components-data-table.d.ts.map +1 -0
  163. package/types/raintonic-formaui-components-date-picker.d.ts +341 -0
  164. package/types/raintonic-formaui-components-date-picker.d.ts.map +1 -0
  165. package/types/raintonic-formaui-components-divider.d.ts +21 -0
  166. package/types/raintonic-formaui-components-divider.d.ts.map +1 -0
  167. package/types/raintonic-formaui-components-drawer.d.ts +48 -0
  168. package/types/raintonic-formaui-components-drawer.d.ts.map +1 -0
  169. package/types/raintonic-formaui-components-dynamic-form.d.ts +412 -0
  170. package/types/raintonic-formaui-components-dynamic-form.d.ts.map +1 -0
  171. package/types/raintonic-formaui-components-empty-state.d.ts +14 -0
  172. package/types/raintonic-formaui-components-empty-state.d.ts.map +1 -0
  173. package/types/raintonic-formaui-components-file-upload.d.ts +77 -0
  174. package/types/raintonic-formaui-components-file-upload.d.ts.map +1 -0
  175. package/types/raintonic-formaui-components-form-field.d.ts +271 -0
  176. package/types/raintonic-formaui-components-form-field.d.ts.map +1 -0
  177. package/types/raintonic-formaui-components-icon.d.ts +61 -0
  178. package/types/raintonic-formaui-components-icon.d.ts.map +1 -0
  179. package/types/raintonic-formaui-components-input.d.ts +149 -0
  180. package/types/raintonic-formaui-components-input.d.ts.map +1 -0
  181. package/types/raintonic-formaui-components-list.d.ts +48 -0
  182. package/types/raintonic-formaui-components-list.d.ts.map +1 -0
  183. package/types/raintonic-formaui-components-menu.d.ts +403 -0
  184. package/types/raintonic-formaui-components-menu.d.ts.map +1 -0
  185. package/types/raintonic-formaui-components-number-input.d.ts +127 -0
  186. package/types/raintonic-formaui-components-number-input.d.ts.map +1 -0
  187. package/types/raintonic-formaui-components-paginator.d.ts +37 -0
  188. package/types/raintonic-formaui-components-paginator.d.ts.map +1 -0
  189. package/types/raintonic-formaui-components-password-input.d.ts +111 -0
  190. package/types/raintonic-formaui-components-password-input.d.ts.map +1 -0
  191. package/types/raintonic-formaui-components-popover.d.ts +131 -0
  192. package/types/raintonic-formaui-components-popover.d.ts.map +1 -0
  193. package/types/raintonic-formaui-components-progressbar.d.ts +111 -0
  194. package/types/raintonic-formaui-components-progressbar.d.ts.map +1 -0
  195. package/types/raintonic-formaui-components-radio.d.ts +95 -0
  196. package/types/raintonic-formaui-components-radio.d.ts.map +1 -0
  197. package/types/raintonic-formaui-components-select.d.ts +307 -0
  198. package/types/raintonic-formaui-components-select.d.ts.map +1 -0
  199. package/types/raintonic-formaui-components-side-panel.d.ts +51 -0
  200. package/types/raintonic-formaui-components-side-panel.d.ts.map +1 -0
  201. package/types/raintonic-formaui-components-sidebar.d.ts +174 -0
  202. package/types/raintonic-formaui-components-sidebar.d.ts.map +1 -0
  203. package/types/raintonic-formaui-components-skeleton.d.ts +20 -0
  204. package/types/raintonic-formaui-components-skeleton.d.ts.map +1 -0
  205. package/types/raintonic-formaui-components-slider.d.ts +108 -0
  206. package/types/raintonic-formaui-components-slider.d.ts.map +1 -0
  207. package/types/raintonic-formaui-components-spinner.d.ts +42 -0
  208. package/types/raintonic-formaui-components-spinner.d.ts.map +1 -0
  209. package/types/raintonic-formaui-components-stepper.d.ts +126 -0
  210. package/types/raintonic-formaui-components-stepper.d.ts.map +1 -0
  211. package/types/raintonic-formaui-components-tab.d.ts +96 -0
  212. package/types/raintonic-formaui-components-tab.d.ts.map +1 -0
  213. package/types/raintonic-formaui-components-tag.d.ts +34 -0
  214. package/types/raintonic-formaui-components-tag.d.ts.map +1 -0
  215. package/types/raintonic-formaui-components-time-picker.d.ts +172 -0
  216. package/types/raintonic-formaui-components-time-picker.d.ts.map +1 -0
  217. package/types/raintonic-formaui-components-toggle.d.ts +70 -0
  218. package/types/raintonic-formaui-components-toggle.d.ts.map +1 -0
  219. package/types/raintonic-formaui-components-toolbar.d.ts +128 -0
  220. package/types/raintonic-formaui-components-toolbar.d.ts.map +1 -0
  221. package/types/raintonic-formaui-components-tooltip.d.ts +268 -0
  222. package/types/raintonic-formaui-components-tooltip.d.ts.map +1 -0
  223. package/types/raintonic-formaui-components-tree-select.d.ts +80 -0
  224. package/types/raintonic-formaui-components-tree-select.d.ts.map +1 -0
  225. package/types/raintonic-formaui-components-tree-table.d.ts +90 -0
  226. package/types/raintonic-formaui-components-tree-table.d.ts.map +1 -0
  227. package/types/raintonic-formaui-components-tree.d.ts +104 -0
  228. package/types/raintonic-formaui-components-tree.d.ts.map +1 -0
  229. package/types/raintonic-formaui-core.d.ts +115 -0
  230. package/types/raintonic-formaui-core.d.ts.map +1 -0
  231. package/types/raintonic-formaui-services-dialog.d.ts +451 -0
  232. package/types/raintonic-formaui-services-dialog.d.ts.map +1 -0
  233. package/types/raintonic-formaui-services-notification.d.ts +221 -0
  234. package/types/raintonic-formaui-services-notification.d.ts.map +1 -0
  235. package/types/raintonic-formaui-services-theme.d.ts +126 -0
  236. package/types/raintonic-formaui-services-theme.d.ts.map +1 -0
  237. package/types/raintonic-formaui-test-utils.d.ts +24 -0
  238. package/types/raintonic-formaui-test-utils.d.ts.map +1 -0
  239. package/types/raintonic-formaui.d.ts +4 -0
  240. package/types/raintonic-formaui.d.ts.map +1 -0
@@ -0,0 +1,117 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, input, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { DOCUMENT } from '@angular/common';
4
+
5
+ const FUI_ICON_DEFAULT_CONFIG = {
6
+ cdnBase: 'https://unpkg.com/@phosphor-icons/web@2.1.2/src',
7
+ };
8
+ const FUI_ICON_CONFIG = new InjectionToken('FUI_ICON_CONFIG', {
9
+ providedIn: 'root',
10
+ factory: () => FUI_ICON_DEFAULT_CONFIG,
11
+ });
12
+
13
+ /**
14
+ * # FuiIcon Component
15
+ *
16
+ * A wrapper component for Phosphor Icons with consistent sizing and styling.
17
+ * Provides easy access to the complete Phosphor Icons library with theme integration.
18
+ *
19
+ * ## Usage
20
+ *
21
+ * ### Basic Icon
22
+ * ```html
23
+ * <fui-icon name="heart"></fui-icon>
24
+ * ```
25
+ */
26
+ class FuiIconComponent {
27
+ // Track which phosphor icon weights have been loaded
28
+ static _loadedWeights = new Set();
29
+ _config = inject(FUI_ICON_CONFIG);
30
+ _document = inject(DOCUMENT);
31
+ // Inputs using new signal-based API
32
+ name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
33
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
34
+ weight = input('regular', ...(ngDevMode ? [{ debugName: "weight" }] : /* istanbul ignore next */ []));
35
+ color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : /* istanbul ignore next */ []));
36
+ ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
37
+ spin = input(false, ...(ngDevMode ? [{ debugName: "spin" }] : /* istanbul ignore next */ []));
38
+ pulse = input(false, ...(ngDevMode ? [{ debugName: "pulse" }] : /* istanbul ignore next */ []));
39
+ // Computed properties
40
+ computedClasses = computed(() => {
41
+ const classes = ['fui-icon', `fui-icon--${this.size()}`, `fui-icon--${this.weight()}`, this.iconClass()];
42
+ if (this.spin()) {
43
+ classes.push('fui-icon--spin');
44
+ }
45
+ if (this.pulse()) {
46
+ classes.push('fui-icon--pulse');
47
+ }
48
+ return classes.join(' ');
49
+ }, ...(ngDevMode ? [{ debugName: "computedClasses" }] : /* istanbul ignore next */ []));
50
+ iconClass = computed(() => {
51
+ const weight = this.weight();
52
+ const weightSuffix = weight === 'regular' ? '' : `-${weight}`;
53
+ return `ph${weightSuffix} ph-${this.name()}`;
54
+ }, ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
55
+ constructor() {
56
+ // Watch for weight changes and load the corresponding CSS
57
+ effect(() => {
58
+ const weight = this.weight();
59
+ this._loadPhosphorWeight(weight);
60
+ });
61
+ }
62
+ /**
63
+ * Dynamically loads the CSS for a specific Phosphor Icons weight from CDN
64
+ * @param weight The icon weight to load
65
+ */
66
+ _loadPhosphorWeight(weight) {
67
+ if (this._config.disableAutoLoad) {
68
+ return;
69
+ }
70
+ // Skip if already loaded
71
+ if (FuiIconComponent._loadedWeights.has(weight)) {
72
+ return;
73
+ }
74
+ // Check if CSS link already exists in DOM
75
+ const linkId = `phosphor-icons-${weight}`;
76
+ if (this._document.getElementById(linkId)) {
77
+ FuiIconComponent._loadedWeights.add(weight);
78
+ return;
79
+ }
80
+ // Create and append the link element
81
+ const link = this._document.createElement('link');
82
+ link.id = linkId;
83
+ link.rel = 'stylesheet';
84
+ link.href = `${this._config.cdnBase}/${weight}/style.css`;
85
+ link.crossOrigin = 'anonymous';
86
+ const integrityHash = this._config.integrity?.[weight];
87
+ if (integrityHash) {
88
+ link.integrity = integrityHash;
89
+ }
90
+ link.onerror = () => {
91
+ console.warn(`[FormaUI] Failed to load Phosphor Icons weight "${weight}" from CDN.`);
92
+ FuiIconComponent._loadedWeights.delete(weight);
93
+ };
94
+ this._document.head.appendChild(link);
95
+ FuiIconComponent._loadedWeights.add(weight);
96
+ }
97
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
98
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.6", type: FuiIconComponent, isStandalone: true, selector: "fui-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, spin: { classPropertyName: "spin", publicName: "spin", isSignal: true, isRequired: false, transformFunction: null }, pulse: { classPropertyName: "pulse", publicName: "pulse", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "img" }, properties: { "class": "computedClasses()", "style.color": "color() || null", "attr.aria-label": "ariaLabel() || null", "attr.aria-hidden": "ariaLabel() ? null : \"true\"" }, classAttribute: "fui-icon" }, ngImport: i0, template: '', isInline: true, 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)}::ng-deep .fui-icon{--fui-icon-color: currentColor;--fui-icon-default-size: 1em;contain:content;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:var(--fui-icon-color);transition:color var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms;width:var(--fui-icon-default-size);height:var(--fui-icon-default-size)}::ng-deep .fui-icon--sm{font-size:var(--fui-icon-size-sm);width:var(--fui-icon-size-sm);height:var(--fui-icon-size-sm)}::ng-deep .fui-icon--md{font-size:var(--fui-icon-size-md);width:var(--fui-icon-size-md);height:var(--fui-icon-size-md)}::ng-deep .fui-icon--lg{font-size:var(--fui-icon-size-lg);width:var(--fui-icon-size-lg);height:var(--fui-icon-size-lg)}::ng-deep .fui-icon--xl{font-size:var(--fui-icon-size-xl);width:var(--fui-icon-size-xl);height:var(--fui-icon-size-xl)}::ng-deep .fui-icon--spin{animation:fui-spin var(--fui-icon-spin-duration, var(--fui-duration-slow-02)) var(--fui-icon-spin-timing, linear) infinite}::ng-deep .fui-icon--pulse{animation:fui-pulse var(--fui-icon-pulse-duration, var(--fui-duration-slow-01)) var(--fui-icon-pulse-timing, var(--fui-ease-expressive)) infinite}@media(prefers-reduced-motion:reduce){::ng-deep .fui-icon--spin,::ng-deep .fui-icon--pulse{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
99
+ }
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiIconComponent, decorators: [{
101
+ type: Component,
102
+ args: [{ selector: 'fui-icon', template: '', changeDetection: ChangeDetectionStrategy.OnPush, host: {
103
+ class: 'fui-icon',
104
+ '[class]': 'computedClasses()',
105
+ '[style.color]': 'color() || null',
106
+ role: 'img',
107
+ '[attr.aria-label]': 'ariaLabel() || null',
108
+ '[attr.aria-hidden]': 'ariaLabel() ? null : "true"',
109
+ }, 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)}::ng-deep .fui-icon{--fui-icon-color: currentColor;--fui-icon-default-size: 1em;contain:content;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:var(--fui-icon-color);transition:color var(--fui-duration-fast-02) var(--fui-ease-standard) 0ms;width:var(--fui-icon-default-size);height:var(--fui-icon-default-size)}::ng-deep .fui-icon--sm{font-size:var(--fui-icon-size-sm);width:var(--fui-icon-size-sm);height:var(--fui-icon-size-sm)}::ng-deep .fui-icon--md{font-size:var(--fui-icon-size-md);width:var(--fui-icon-size-md);height:var(--fui-icon-size-md)}::ng-deep .fui-icon--lg{font-size:var(--fui-icon-size-lg);width:var(--fui-icon-size-lg);height:var(--fui-icon-size-lg)}::ng-deep .fui-icon--xl{font-size:var(--fui-icon-size-xl);width:var(--fui-icon-size-xl);height:var(--fui-icon-size-xl)}::ng-deep .fui-icon--spin{animation:fui-spin var(--fui-icon-spin-duration, var(--fui-duration-slow-02)) var(--fui-icon-spin-timing, linear) infinite}::ng-deep .fui-icon--pulse{animation:fui-pulse var(--fui-icon-pulse-duration, var(--fui-duration-slow-01)) var(--fui-icon-pulse-timing, var(--fui-ease-expressive)) infinite}@media(prefers-reduced-motion:reduce){::ng-deep .fui-icon--spin,::ng-deep .fui-icon--pulse{animation:none}}\n"] }]
110
+ }], ctorParameters: () => [], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], weight: [{ type: i0.Input, args: [{ isSignal: true, alias: "weight", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], spin: [{ type: i0.Input, args: [{ isSignal: true, alias: "spin", required: false }] }], pulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "pulse", required: false }] }] } });
111
+
112
+ /**
113
+ * Generated bundle index. Do not edit.
114
+ */
115
+
116
+ export { FUI_ICON_CONFIG, FUI_ICON_DEFAULT_CONFIG, FuiIconComponent };
117
+ //# sourceMappingURL=raintonic-formaui-components-icon.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raintonic-formaui-components-icon.mjs","sources":["../../../lib/components/icon/icon-config.ts","../../../lib/components/icon/icon.component.ts","../../../lib/components/icon/raintonic-formaui-components-icon.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { FuiIconWeight } from './icon.component';\n\nexport interface FuiIconConfig {\n /** Base URL for the Phosphor Icons CDN */\n cdnBase: string;\n /** SRI hashes per weight. If provided, integrity attribute is added to link elements */\n integrity?: Partial<Record<FuiIconWeight, string>>;\n /** If true, disables automatic CDN loading. Consumer must load icon CSS manually. */\n disableAutoLoad?: boolean;\n}\n\nexport const FUI_ICON_DEFAULT_CONFIG: FuiIconConfig = {\n cdnBase: 'https://unpkg.com/@phosphor-icons/web@2.1.2/src',\n};\n\nexport const FUI_ICON_CONFIG = new InjectionToken<FuiIconConfig>('FUI_ICON_CONFIG', {\n providedIn: 'root',\n factory: () => FUI_ICON_DEFAULT_CONFIG,\n});\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n InputSignal,\n Signal,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { FUI_ICON_CONFIG, FuiIconConfig } from './icon-config';\n\n/**\n * Available icon sizes following Carbon Design System\n */\nexport type FuiIconSize = 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Available icon weights\n */\nexport type FuiIconWeight = 'thin' | 'light' | 'regular' | 'bold' | 'fill';\n\n/**\n * # FuiIcon Component\n *\n * A wrapper component for Phosphor Icons with consistent sizing and styling.\n * Provides easy access to the complete Phosphor Icons library with theme integration.\n *\n * ## Usage\n *\n * ### Basic Icon\n * ```html\n * <fui-icon name=\"heart\"></fui-icon>\n * ```\n */\n@Component({\n selector: 'fui-icon',\n template: '',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'fui-icon',\n '[class]': 'computedClasses()',\n '[style.color]': 'color() || null',\n role: 'img',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-hidden]': 'ariaLabel() ? null : \"true\"',\n },\n})\nexport class FuiIconComponent {\n // Track which phosphor icon weights have been loaded\n private static readonly _loadedWeights = new Set<FuiIconWeight>();\n\n private readonly _config = inject(FUI_ICON_CONFIG);\n private readonly _document = inject(DOCUMENT);\n\n // Inputs using new signal-based API\n name: InputSignal<string> = input.required<string>();\n size: InputSignal<FuiIconSize> = input<FuiIconSize>('md');\n weight: InputSignal<FuiIconWeight> = input<FuiIconWeight>('regular');\n color: InputSignal<string | undefined> = input<string>();\n ariaLabel: InputSignal<string | undefined> = input<string>();\n spin: InputSignal<boolean> = input(false);\n pulse: InputSignal<boolean> = input(false);\n\n // Computed properties\n readonly computedClasses: Signal<string> = computed(() => {\n const classes: string[] = ['fui-icon', `fui-icon--${this.size()}`, `fui-icon--${this.weight()}`, this.iconClass()];\n\n if (this.spin()) {\n classes.push('fui-icon--spin');\n }\n\n if (this.pulse()) {\n classes.push('fui-icon--pulse');\n }\n\n return classes.join(' ');\n });\n\n readonly iconClass: Signal<string> = computed(() => {\n const weight: FuiIconWeight = this.weight();\n const weightSuffix: string = weight === 'regular' ? '' : `-${weight}`;\n return `ph${weightSuffix} ph-${this.name()}`;\n });\n\n constructor() {\n // Watch for weight changes and load the corresponding CSS\n effect(() => {\n const weight = this.weight();\n this._loadPhosphorWeight(weight);\n });\n }\n\n /**\n * Dynamically loads the CSS for a specific Phosphor Icons weight from CDN\n * @param weight The icon weight to load\n */\n private _loadPhosphorWeight(weight: FuiIconWeight): void {\n if (this._config.disableAutoLoad) {\n return;\n }\n\n // Skip if already loaded\n if (FuiIconComponent._loadedWeights.has(weight)) {\n return;\n }\n\n // Check if CSS link already exists in DOM\n const linkId = `phosphor-icons-${weight}`;\n if (this._document.getElementById(linkId)) {\n FuiIconComponent._loadedWeights.add(weight);\n return;\n }\n\n // Create and append the link element\n const link = this._document.createElement('link');\n link.id = linkId;\n link.rel = 'stylesheet';\n link.href = `${this._config.cdnBase}/${weight}/style.css`;\n link.crossOrigin = 'anonymous';\n\n const integrityHash = this._config.integrity?.[weight];\n if (integrityHash) {\n link.integrity = integrityHash;\n }\n\n link.onerror = (): void => {\n console.warn(`[FormaUI] Failed to load Phosphor Icons weight \"${weight}\" from CDN.`);\n FuiIconComponent._loadedWeights.delete(weight);\n };\n\n this._document.head.appendChild(link);\n FuiIconComponent._loadedWeights.add(weight);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, signal, computed, output, inject, ElementRef, effect, HostListener, Directive } from '@angular/core';
3
+ import { NgForm, FormGroupDirective, NG_VALUE_ACCESSOR } from '@angular/forms';
4
+ import { Subject } from 'rxjs';
5
+ import { DefaultErrorStateMatcher, FUI_FORM_FIELD_CONTROL } from '@raintonic/formaui/core';
6
+ import { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';
7
+
8
+ /**
9
+ * # FuiInput Directive
10
+ *
11
+ * An input directive that integrates seamlessly with fui-form-field and Angular Forms.
12
+ * Follows Angular Material patterns with Carbon Design System styling.
13
+ *
14
+ * ## Features
15
+ * - Full integration with fui-form-field
16
+ * - Reactive Forms and Template-driven Forms support
17
+ * - Multiple input types support
18
+ * - Error state handling with customizable error messages
19
+ * - Accessibility features (ARIA attributes, labels)
20
+ * - Smooth animations and transitions
21
+ * - Theme-aware styling
22
+ *
23
+ * ## Usage
24
+ *
25
+ * ### Basic Input with Form Field
26
+ * ```html
27
+ * <fui-form-field>
28
+ * <fui-label>Email</fui-label>
29
+ * <input fuiInput type="email" placeholder="Enter your email">
30
+ * </fui-form-field>
31
+ * ```
32
+ *
33
+ * ### With Reactive Forms
34
+ * ```html
35
+ * <fui-form-field>
36
+ * <fui-label>Username</fui-label>
37
+ * <input fuiInput formControlName="username">
38
+ * <fui-error *ngIf="form.get('username')?.hasError('required')">
39
+ * Username is required
40
+ * </fui-error>
41
+ * </fui-form-field>
42
+ * ```
43
+ *
44
+ * ### Password Input with Toggle
45
+ * ```html
46
+ * <fui-form-field>
47
+ * <fui-label>Password</fui-label>
48
+ * <input fuiInput [type]="showPassword ? 'text' : 'password'">
49
+ * <button fuiSuffix fuiButton variant="ghost" (click)="togglePassword()">
50
+ * <fui-icon [name]="showPassword ? 'eye-slash' : 'eye'"></fui-icon>
51
+ * </button>
52
+ * </fui-form-field>
53
+ * ```
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * import { FuiInputDirective } from '@raintonic/formaui/components/input';
58
+ * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';
59
+ *
60
+ * @Component({
61
+ * standalone: true,
62
+ * imports: [FuiInputDirective, FuiFormFieldComponent, ReactiveFormsModule],
63
+ * template: `
64
+ * <form [formGroup]="form">
65
+ * <fui-form-field>
66
+ * <fui-label>Email</fui-label>
67
+ * <input fuiInput type="email" formControlName="email">
68
+ * <fui-error *ngIf="emailControl?.invalid && emailControl?.touched">
69
+ * Please enter a valid email
70
+ * </fui-error>
71
+ * </fui-form-field>
72
+ * </form>
73
+ * `
74
+ * })
75
+ * export class MyFormComponent {
76
+ * form = this.fb.group({
77
+ * email: ['', [Validators.required, Validators.email]]
78
+ * });
79
+ *
80
+ * get emailControl() {
81
+ * return this.form.get('email');
82
+ * }
83
+ * }
84
+ * ```
85
+ */
86
+ class FuiInputDirective {
87
+ // Static properties
88
+ static nextId = 0;
89
+ controlType = 'fui-input';
90
+ // Inputs
91
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
92
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
93
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
94
+ // Validation/constraint inputs (pass-through to native attributes)
95
+ maxlength = input(null, ...(ngDevMode ? [{ debugName: "maxlength" }] : /* istanbul ignore next */ []));
96
+ minlength = input(null, ...(ngDevMode ? [{ debugName: "minlength" }] : /* istanbul ignore next */ []));
97
+ pattern = input(null, ...(ngDevMode ? [{ debugName: "pattern" }] : /* istanbul ignore next */ []));
98
+ // Interface implementation
99
+ required = signal(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
100
+ errorStateMatcher = input(null, ...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
101
+ disabledInput = input(false, ...(ngDevMode ? [{ debugName: "disabledInput" }] : /* istanbul ignore next */ []));
102
+ disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
103
+ // Outputs
104
+ valueChange = output();
105
+ // Internal state
106
+ _focused = signal(false, ...(ngDevMode ? [{ debugName: "_focused" }] : /* istanbul ignore next */ []));
107
+ focused = this._focused;
108
+ stateChanges = new Subject();
109
+ _value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
110
+ value = this._value;
111
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
112
+ _ngControlDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_ngControlDisabled" }] : /* istanbul ignore next */ []));
113
+ _uid = `fui-input-${FuiInputDirective.nextId++}`;
114
+ _ariaDescribedby = null;
115
+ // Error state
116
+ _errorState = signal(false, ...(ngDevMode ? [{ debugName: "_errorState" }] : /* istanbul ignore next */ []));
117
+ errorState = this._errorState;
118
+ // Form control references
119
+ _parentForm = inject(NgForm, { optional: true });
120
+ _parentFormGroup = inject(FormGroupDirective, { optional: true });
121
+ _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);
122
+ // Element reference
123
+ _elementRef = inject(ElementRef);
124
+ // Computed properties
125
+ empty = computed(() => {
126
+ const v = this._value();
127
+ return !v || v.length === 0;
128
+ }, ...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
129
+ id = this._uid;
130
+ // ControlValueAccessor callbacks
131
+ _onChange = () => {
132
+ /* noop */
133
+ };
134
+ _onTouched = () => {
135
+ /* noop */
136
+ };
137
+ _ngControlRef = injectNgControl();
138
+ get ngControl() {
139
+ return this._ngControlRef.ngControl;
140
+ }
141
+ constructor() {
142
+ // Set valueAccessor after NgControl is resolved
143
+ void Promise.resolve().then(() => {
144
+ if (this._ngControlRef.ngControl) {
145
+ this._ngControlRef.ngControl.valueAccessor = this;
146
+ }
147
+ });
148
+ // Effect to emit state changes
149
+ effect(() => {
150
+ // Track all reactive inputs and internal signals
151
+ this.type();
152
+ this.placeholder();
153
+ this.readonly();
154
+ this.maxlength();
155
+ this.minlength();
156
+ this.pattern();
157
+ this.disabledInput();
158
+ this.errorStateMatcher();
159
+ this._focused();
160
+ this._value();
161
+ this._disabled();
162
+ this._ngControlDisabled();
163
+ this.required();
164
+ this._errorState();
165
+ // Emit state change
166
+ this.stateChanges.next();
167
+ });
168
+ }
169
+ ngDoCheck() {
170
+ if (this.ngControl) {
171
+ updateErrorState(this.ngControl, this._errorState, this.errorStateMatcher(), this._defaultErrorStateMatcher, this._parentForm, this._parentFormGroup, this.stateChanges);
172
+ syncRequiredState(this.ngControl, this.required, this.stateChanges);
173
+ syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);
174
+ }
175
+ }
176
+ ngOnDestroy() {
177
+ this.stateChanges.complete();
178
+ }
179
+ // ControlValueAccessor implementation
180
+ writeValue(value) {
181
+ const v = value ?? '';
182
+ this._value.set(v);
183
+ // Update the DOM element's value to reflect the new value
184
+ this._elementRef.nativeElement.value = v;
185
+ this.stateChanges.next();
186
+ }
187
+ registerOnChange(fn) {
188
+ this._onChange = fn;
189
+ }
190
+ registerOnTouched(fn) {
191
+ this._onTouched = fn;
192
+ }
193
+ setDisabledState(isDisabled) {
194
+ this._disabled.set(isDisabled);
195
+ this.stateChanges.next();
196
+ }
197
+ onContainerClick(_event) {
198
+ if (!this._focused()) {
199
+ this._elementRef.nativeElement.focus();
200
+ }
201
+ }
202
+ setDescribedByIds(ids) {
203
+ this._ariaDescribedby = ids.length ? ids.join(' ') : null;
204
+ }
205
+ // Event handlers
206
+ onInput(event) {
207
+ const target = event.target;
208
+ const newValue = target.value;
209
+ if (newValue !== this._value()) {
210
+ this._value.set(newValue);
211
+ this._onChange(newValue);
212
+ this.valueChange.emit(newValue);
213
+ this.stateChanges.next();
214
+ }
215
+ }
216
+ onChange(event) {
217
+ // Handle change event for select elements
218
+ if (this.isSelect()) {
219
+ const target = event.target;
220
+ const newValue = target.value;
221
+ if (newValue !== this._value()) {
222
+ this._value.set(newValue);
223
+ this._onChange(newValue);
224
+ this.valueChange.emit(newValue);
225
+ this.stateChanges.next();
226
+ }
227
+ }
228
+ }
229
+ onFocus() {
230
+ if (!this._focused()) {
231
+ this._focused.set(true);
232
+ this.stateChanges.next();
233
+ }
234
+ }
235
+ onBlur() {
236
+ if (this._focused()) {
237
+ this._focused.set(false);
238
+ this._onTouched();
239
+ this.stateChanges.next();
240
+ }
241
+ }
242
+ // Public API
243
+ focus() {
244
+ this._elementRef.nativeElement.focus();
245
+ }
246
+ blur() {
247
+ this._elementRef.nativeElement.blur();
248
+ }
249
+ /**
250
+ * Check if the element is a select element
251
+ */
252
+ isSelect() {
253
+ return this._elementRef.nativeElement.tagName.toLowerCase() === 'select';
254
+ }
255
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
256
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.6", type: FuiInputDirective, isStandalone: true, selector: "input[fuiInput], textarea[fuiInput], select[fuiInput]", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, minlength: { classPropertyName: "minlength", publicName: "minlength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabledInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "input": "onInput($event)", "change": "onChange($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "class.fui-input--select": "isSelect()", "class.fui-input--disabled": "disabled()", "class.fui-input--readonly": "readonly()", "class.fui-input--error": "errorState()", "attr.id": "id", "attr.type": "type()", "attr.placeholder": "placeholder()", "attr.disabled": "disabled() ? \"\" : null", "attr.readonly": "readonly() ? \"\" : null", "attr.required": "required() ? \"\" : null", "attr.maxlength": "maxlength()", "attr.minlength": "minlength()", "attr.pattern": "pattern()", "attr.aria-invalid": "errorState() ? \"true\" : null", "attr.aria-required": "required() ? \"true\" : null", "attr.aria-describedby": "_ariaDescribedby", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-readonly": "readonly() ? \"true\" : null" }, classAttribute: "fui-input" }, providers: [
257
+ {
258
+ provide: NG_VALUE_ACCESSOR,
259
+ useExisting: FuiInputDirective,
260
+ multi: true,
261
+ },
262
+ {
263
+ provide: FUI_FORM_FIELD_CONTROL,
264
+ useExisting: FuiInputDirective,
265
+ },
266
+ ], ngImport: i0 });
267
+ }
268
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: FuiInputDirective, decorators: [{
269
+ type: Directive,
270
+ args: [{
271
+ selector: 'input[fuiInput], textarea[fuiInput], select[fuiInput]',
272
+ standalone: true,
273
+ host: {
274
+ class: 'fui-input',
275
+ '[class.fui-input--select]': 'isSelect()',
276
+ '[class.fui-input--disabled]': 'disabled()',
277
+ '[class.fui-input--readonly]': 'readonly()',
278
+ '[class.fui-input--error]': 'errorState()',
279
+ '[attr.id]': 'id',
280
+ '[attr.type]': 'type()',
281
+ '[attr.placeholder]': 'placeholder()',
282
+ '[attr.disabled]': 'disabled() ? "" : null',
283
+ '[attr.readonly]': 'readonly() ? "" : null',
284
+ '[attr.required]': 'required() ? "" : null',
285
+ // constraints
286
+ '[attr.maxlength]': 'maxlength()',
287
+ '[attr.minlength]': 'minlength()',
288
+ '[attr.pattern]': 'pattern()',
289
+ // ARIA
290
+ '[attr.aria-invalid]': 'errorState() ? "true" : null',
291
+ '[attr.aria-required]': 'required() ? "true" : null',
292
+ '[attr.aria-describedby]': '_ariaDescribedby',
293
+ '[attr.aria-disabled]': 'disabled() ? "true" : null',
294
+ '[attr.aria-readonly]': 'readonly() ? "true" : null',
295
+ },
296
+ providers: [
297
+ {
298
+ provide: NG_VALUE_ACCESSOR,
299
+ useExisting: FuiInputDirective,
300
+ multi: true,
301
+ },
302
+ {
303
+ provide: FUI_FORM_FIELD_CONTROL,
304
+ useExisting: FuiInputDirective,
305
+ },
306
+ ],
307
+ }]
308
+ }], ctorParameters: () => [], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], minlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minlength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledInput", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onInput: [{
309
+ type: HostListener,
310
+ args: ['input', ['$event']]
311
+ }], onChange: [{
312
+ type: HostListener,
313
+ args: ['change', ['$event']]
314
+ }], onFocus: [{
315
+ type: HostListener,
316
+ args: ['focus']
317
+ }], onBlur: [{
318
+ type: HostListener,
319
+ args: ['blur']
320
+ }] } });
321
+
322
+ /**
323
+ * Generated bundle index. Do not edit.
324
+ */
325
+
326
+ export { FuiInputDirective };
327
+ //# sourceMappingURL=raintonic-formaui-components-input.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raintonic-formaui-components-input.mjs","sources":["../../../lib/components/input/input.directive.ts","../../../lib/components/input/raintonic-formaui-components-input.ts"],"sourcesContent":["import {\n computed,\n Directive,\n DoCheck,\n effect,\n ElementRef,\n HostListener,\n inject,\n input,\n InputSignal,\n OnDestroy,\n output,\n OutputEmitterRef,\n signal,\n WritableSignal,\n} from '@angular/core';\n\nimport { ControlValueAccessor, FormGroupDirective, NG_VALUE_ACCESSOR, NgControl, NgForm } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { FUI_FORM_FIELD_CONTROL, FuiFormFieldControl } from '@raintonic/formaui/core';\nimport { DefaultErrorStateMatcher, ErrorStateMatcher } from '@raintonic/formaui/core';\nimport { injectNgControl, updateErrorState, syncRequiredState, syncNgControlDisabled } from '@raintonic/formaui/cdk/form-field';\n\n/**\n * Available input types\n */\nexport type FuiInputType =\n | 'text'\n | 'email'\n | 'password'\n | 'number'\n | 'tel'\n | 'url'\n | 'search'\n | 'date'\n | 'time'\n | 'datetime-local';\n\n/**\n * # FuiInput Directive\n *\n * An input directive that integrates seamlessly with fui-form-field and Angular Forms.\n * Follows Angular Material patterns with Carbon Design System styling.\n *\n * ## Features\n * - Full integration with fui-form-field\n * - Reactive Forms and Template-driven Forms support\n * - Multiple input types support\n * - Error state handling with customizable error messages\n * - Accessibility features (ARIA attributes, labels)\n * - Smooth animations and transitions\n * - Theme-aware styling\n *\n * ## Usage\n *\n * ### Basic Input with Form Field\n * ```html\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\" placeholder=\"Enter your email\">\n * </fui-form-field>\n * ```\n *\n * ### With Reactive Forms\n * ```html\n * <fui-form-field>\n * <fui-label>Username</fui-label>\n * <input fuiInput formControlName=\"username\">\n * <fui-error *ngIf=\"form.get('username')?.hasError('required')\">\n * Username is required\n * </fui-error>\n * </fui-form-field>\n * ```\n *\n * ### Password Input with Toggle\n * ```html\n * <fui-form-field>\n * <fui-label>Password</fui-label>\n * <input fuiInput [type]=\"showPassword ? 'text' : 'password'\">\n * <button fuiSuffix fuiButton variant=\"ghost\" (click)=\"togglePassword()\">\n * <fui-icon [name]=\"showPassword ? 'eye-slash' : 'eye'\"></fui-icon>\n * </button>\n * </fui-form-field>\n * ```\n *\n * @example\n * ```typescript\n * import { FuiInputDirective } from '@raintonic/formaui/components/input';\n * import { FuiFormFieldComponent } from '@raintonic/formaui/components/form-field';\n *\n * @Component({\n * standalone: true,\n * imports: [FuiInputDirective, FuiFormFieldComponent, ReactiveFormsModule],\n * template: `\n * <form [formGroup]=\"form\">\n * <fui-form-field>\n * <fui-label>Email</fui-label>\n * <input fuiInput type=\"email\" formControlName=\"email\">\n * <fui-error *ngIf=\"emailControl?.invalid && emailControl?.touched\">\n * Please enter a valid email\n * </fui-error>\n * </fui-form-field>\n * </form>\n * `\n * })\n * export class MyFormComponent {\n * form = this.fb.group({\n * email: ['', [Validators.required, Validators.email]]\n * });\n *\n * get emailControl() {\n * return this.form.get('email');\n * }\n * }\n * ```\n */\n@Directive({\n selector: 'input[fuiInput], textarea[fuiInput], select[fuiInput]',\n standalone: true,\n host: {\n class: 'fui-input',\n '[class.fui-input--select]': 'isSelect()',\n '[class.fui-input--disabled]': 'disabled()',\n '[class.fui-input--readonly]': 'readonly()',\n '[class.fui-input--error]': 'errorState()',\n '[attr.id]': 'id',\n '[attr.type]': 'type()',\n '[attr.placeholder]': 'placeholder()',\n '[attr.disabled]': 'disabled() ? \"\" : null',\n '[attr.readonly]': 'readonly() ? \"\" : null',\n '[attr.required]': 'required() ? \"\" : null',\n // constraints\n '[attr.maxlength]': 'maxlength()',\n '[attr.minlength]': 'minlength()',\n '[attr.pattern]': 'pattern()',\n // ARIA\n '[attr.aria-invalid]': 'errorState() ? \"true\" : null',\n '[attr.aria-required]': 'required() ? \"true\" : null',\n '[attr.aria-describedby]': '_ariaDescribedby',\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n '[attr.aria-readonly]': 'readonly() ? \"true\" : null',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: FuiInputDirective,\n multi: true,\n },\n {\n provide: FUI_FORM_FIELD_CONTROL,\n useExisting: FuiInputDirective,\n },\n ],\n})\nexport class FuiInputDirective implements ControlValueAccessor, FuiFormFieldControl<string>, DoCheck, OnDestroy {\n // Static properties\n static nextId = 0;\n readonly controlType = 'fui-input';\n\n // Inputs\n type: InputSignal<FuiInputType> = input<FuiInputType>('text');\n placeholder: InputSignal<string> = input('');\n\n readonly: InputSignal<boolean> = input(false);\n\n // Validation/constraint inputs (pass-through to native attributes)\n maxlength: InputSignal<number | null> = input<number | null>(null);\n minlength: InputSignal<number | null> = input<number | null>(null);\n pattern: InputSignal<string | null> = input<string | null>(null);\n\n // Interface implementation\n required: WritableSignal<boolean> = signal(false);\n\n errorStateMatcher: InputSignal<ErrorStateMatcher | null> = input<ErrorStateMatcher | null>(null);\n readonly disabledInput: InputSignal<boolean> = input(false);\n readonly disabled = computed(() => this._disabled() || this.disabledInput() || this._ngControlDisabled());\n\n // Outputs\n readonly valueChange: OutputEmitterRef<string> = output<string>();\n\n // Internal state\n private readonly _focused: WritableSignal<boolean> = signal(false);\n readonly focused = this._focused;\n readonly stateChanges = new Subject<void>();\n\n private readonly _value: WritableSignal<string> = signal('');\n readonly value = this._value;\n private readonly _disabled: WritableSignal<boolean> = signal(false);\n private readonly _ngControlDisabled: WritableSignal<boolean> = signal(false);\n private _uid = `fui-input-${FuiInputDirective.nextId++}`;\n _ariaDescribedby: string | null = null;\n\n // Error state\n private readonly _errorState: WritableSignal<boolean> = signal(false);\n readonly errorState = this._errorState;\n\n // Form control references\n private _parentForm = inject(NgForm, { optional: true });\n private _parentFormGroup = inject(FormGroupDirective, { optional: true });\n private _defaultErrorStateMatcher = inject(DefaultErrorStateMatcher);\n\n // Element reference\n private readonly _elementRef: ElementRef<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> =\n inject(ElementRef);\n\n // Computed properties\n readonly empty = computed(() => {\n const v = this._value();\n return !v || v.length === 0;\n });\n readonly id = this._uid;\n\n // ControlValueAccessor callbacks\n private _onChange: (value: string) => void = () => {\n /* noop */\n };\n private _onTouched: () => void = () => {\n /* noop */\n };\n\n private readonly _ngControlRef = injectNgControl();\n\n get ngControl(): NgControl | null {\n return this._ngControlRef.ngControl;\n }\n\n constructor() {\n // Set valueAccessor after NgControl is resolved\n void Promise.resolve().then(() => {\n if (this._ngControlRef.ngControl) {\n this._ngControlRef.ngControl.valueAccessor = this;\n }\n });\n\n // Effect to emit state changes\n effect(() => {\n // Track all reactive inputs and internal signals\n this.type();\n this.placeholder();\n this.readonly();\n this.maxlength();\n this.minlength();\n this.pattern();\n this.disabledInput();\n this.errorStateMatcher();\n this._focused();\n this._value();\n this._disabled();\n this._ngControlDisabled();\n this.required();\n this._errorState();\n\n // Emit state change\n this.stateChanges.next();\n });\n }\n\n ngDoCheck(): void {\n if (this.ngControl) {\n updateErrorState(\n this.ngControl,\n this._errorState,\n this.errorStateMatcher(),\n this._defaultErrorStateMatcher,\n this._parentForm,\n this._parentFormGroup,\n this.stateChanges,\n );\n syncRequiredState(this.ngControl, this.required, this.stateChanges);\n syncNgControlDisabled(this.ngControl, this._ngControlDisabled, this.stateChanges);\n }\n }\n\n ngOnDestroy(): void {\n this.stateChanges.complete();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n const v = value ?? '';\n this._value.set(v);\n // Update the DOM element's value to reflect the new value\n this._elementRef.nativeElement.value = v;\n this.stateChanges.next();\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled.set(isDisabled);\n this.stateChanges.next();\n }\n\n onContainerClick(_event: MouseEvent): void {\n if (!this._focused()) {\n this._elementRef.nativeElement.focus();\n }\n }\n\n setDescribedByIds(ids: string[]): void {\n this._ariaDescribedby = ids.length ? ids.join(' ') : null;\n }\n\n // Event handlers\n @HostListener('input', ['$event'])\n onInput(event: Event): void {\n const target = event.target as HTMLInputElement;\n const newValue = target.value;\n if (newValue !== this._value()) {\n this._value.set(newValue);\n this._onChange(newValue);\n this.valueChange.emit(newValue);\n this.stateChanges.next();\n }\n }\n\n @HostListener('change', ['$event'])\n onChange(event: Event): void {\n // Handle change event for select elements\n if (this.isSelect()) {\n const target = event.target as HTMLSelectElement;\n const newValue = target.value;\n if (newValue !== this._value()) {\n this._value.set(newValue);\n this._onChange(newValue);\n this.valueChange.emit(newValue);\n this.stateChanges.next();\n }\n }\n }\n\n @HostListener('focus')\n onFocus(): void {\n if (!this._focused()) {\n this._focused.set(true);\n this.stateChanges.next();\n }\n }\n\n @HostListener('blur')\n onBlur(): void {\n if (this._focused()) {\n this._focused.set(false);\n this._onTouched();\n this.stateChanges.next();\n }\n }\n\n // Public API\n focus(): void {\n this._elementRef.nativeElement.focus();\n }\n\n blur(): void {\n this._elementRef.nativeElement.blur();\n }\n\n /**\n * Check if the element is a select element\n */\n isSelect(): boolean {\n return this._elementRef.nativeElement.tagName.toLowerCase() === 'select';\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}