@vadem/ui 0.0.0-stage → 0.0.1

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 (289) hide show
  1. package/LICENSE-lucide.txt +43 -0
  2. package/README.md +19 -2
  3. package/fesm2022/vadem-ui-accordion.mjs +139 -0
  4. package/fesm2022/vadem-ui-accordion.mjs.map +1 -0
  5. package/fesm2022/vadem-ui-active-filters.mjs +355 -0
  6. package/fesm2022/vadem-ui-active-filters.mjs.map +1 -0
  7. package/fesm2022/vadem-ui-alert-dialog.mjs +433 -0
  8. package/fesm2022/vadem-ui-alert-dialog.mjs.map +1 -0
  9. package/fesm2022/vadem-ui-alert.mjs +266 -0
  10. package/fesm2022/vadem-ui-alert.mjs.map +1 -0
  11. package/fesm2022/vadem-ui-autocomplete.mjs +715 -0
  12. package/fesm2022/vadem-ui-autocomplete.mjs.map +1 -0
  13. package/fesm2022/vadem-ui-avatar.mjs +219 -0
  14. package/fesm2022/vadem-ui-avatar.mjs.map +1 -0
  15. package/fesm2022/vadem-ui-badge.mjs +86 -0
  16. package/fesm2022/vadem-ui-badge.mjs.map +1 -0
  17. package/fesm2022/vadem-ui-breadcrumbs.mjs +61 -0
  18. package/fesm2022/vadem-ui-breadcrumbs.mjs.map +1 -0
  19. package/fesm2022/vadem-ui-button.mjs +220 -0
  20. package/fesm2022/vadem-ui-button.mjs.map +1 -0
  21. package/fesm2022/vadem-ui-calendar.mjs +1314 -0
  22. package/fesm2022/vadem-ui-calendar.mjs.map +1 -0
  23. package/fesm2022/vadem-ui-card.mjs +271 -0
  24. package/fesm2022/vadem-ui-card.mjs.map +1 -0
  25. package/fesm2022/vadem-ui-character-count.mjs +269 -0
  26. package/fesm2022/vadem-ui-character-count.mjs.map +1 -0
  27. package/fesm2022/vadem-ui-chart.mjs +1984 -0
  28. package/fesm2022/vadem-ui-chart.mjs.map +1 -0
  29. package/fesm2022/vadem-ui-checkbox.mjs +67 -0
  30. package/fesm2022/vadem-ui-checkbox.mjs.map +1 -0
  31. package/fesm2022/vadem-ui-color-picker.mjs +815 -0
  32. package/fesm2022/vadem-ui-color-picker.mjs.map +1 -0
  33. package/fesm2022/vadem-ui-command.mjs +735 -0
  34. package/fesm2022/vadem-ui-command.mjs.map +1 -0
  35. package/fesm2022/vadem-ui-copy-button.mjs +375 -0
  36. package/fesm2022/vadem-ui-copy-button.mjs.map +1 -0
  37. package/fesm2022/vadem-ui-date-range-picker.mjs +1011 -0
  38. package/fesm2022/vadem-ui-date-range-picker.mjs.map +1 -0
  39. package/fesm2022/vadem-ui-description-list.mjs +59 -0
  40. package/fesm2022/vadem-ui-description-list.mjs.map +1 -0
  41. package/fesm2022/vadem-ui-dialog.mjs +587 -0
  42. package/fesm2022/vadem-ui-dialog.mjs.map +1 -0
  43. package/fesm2022/vadem-ui-dropzone.mjs +176 -0
  44. package/fesm2022/vadem-ui-dropzone.mjs.map +1 -0
  45. package/fesm2022/vadem-ui-editable-text.mjs +641 -0
  46. package/fesm2022/vadem-ui-editable-text.mjs.map +1 -0
  47. package/fesm2022/vadem-ui-empty-state.mjs +175 -0
  48. package/fesm2022/vadem-ui-empty-state.mjs.map +1 -0
  49. package/fesm2022/vadem-ui-expandable-text.mjs +244 -0
  50. package/fesm2022/vadem-ui-expandable-text.mjs.map +1 -0
  51. package/fesm2022/vadem-ui-field.mjs +583 -0
  52. package/fesm2022/vadem-ui-field.mjs.map +1 -0
  53. package/fesm2022/vadem-ui-file-preview.mjs +532 -0
  54. package/fesm2022/vadem-ui-file-preview.mjs.map +1 -0
  55. package/fesm2022/vadem-ui-file-size.mjs +83 -0
  56. package/fesm2022/vadem-ui-file-size.mjs.map +1 -0
  57. package/fesm2022/vadem-ui-form-error-summary.mjs +201 -0
  58. package/fesm2022/vadem-ui-form-error-summary.mjs.map +1 -0
  59. package/fesm2022/vadem-ui-icon.mjs +303 -0
  60. package/fesm2022/vadem-ui-icon.mjs.map +1 -0
  61. package/fesm2022/vadem-ui-input.mjs +120 -0
  62. package/fesm2022/vadem-ui-input.mjs.map +1 -0
  63. package/fesm2022/vadem-ui-kbd.mjs +286 -0
  64. package/fesm2022/vadem-ui-kbd.mjs.map +1 -0
  65. package/fesm2022/vadem-ui-keyboard.mjs +105 -0
  66. package/fesm2022/vadem-ui-keyboard.mjs.map +1 -0
  67. package/fesm2022/vadem-ui-locale.mjs +443 -0
  68. package/fesm2022/vadem-ui-locale.mjs.map +1 -0
  69. package/fesm2022/vadem-ui-menu.mjs +637 -0
  70. package/fesm2022/vadem-ui-menu.mjs.map +1 -0
  71. package/fesm2022/vadem-ui-navigation-list.mjs +130 -0
  72. package/fesm2022/vadem-ui-navigation-list.mjs.map +1 -0
  73. package/fesm2022/vadem-ui-number-input.mjs +264 -0
  74. package/fesm2022/vadem-ui-number-input.mjs.map +1 -0
  75. package/fesm2022/vadem-ui-otp-input.mjs +86 -0
  76. package/fesm2022/vadem-ui-otp-input.mjs.map +1 -0
  77. package/fesm2022/vadem-ui-pagination.mjs +353 -0
  78. package/fesm2022/vadem-ui-pagination.mjs.map +1 -0
  79. package/fesm2022/vadem-ui-password-input.mjs +213 -0
  80. package/fesm2022/vadem-ui-password-input.mjs.map +1 -0
  81. package/fesm2022/vadem-ui-popover.mjs +178 -0
  82. package/fesm2022/vadem-ui-popover.mjs.map +1 -0
  83. package/fesm2022/vadem-ui-progress.mjs +331 -0
  84. package/fesm2022/vadem-ui-progress.mjs.map +1 -0
  85. package/fesm2022/vadem-ui-radio.mjs +39 -0
  86. package/fesm2022/vadem-ui-radio.mjs.map +1 -0
  87. package/fesm2022/vadem-ui-range-slider.mjs +561 -0
  88. package/fesm2022/vadem-ui-range-slider.mjs.map +1 -0
  89. package/fesm2022/vadem-ui-rating.mjs +404 -0
  90. package/fesm2022/vadem-ui-rating.mjs.map +1 -0
  91. package/fesm2022/vadem-ui-relative-time.mjs +217 -0
  92. package/fesm2022/vadem-ui-relative-time.mjs.map +1 -0
  93. package/fesm2022/vadem-ui-reorder-list.mjs +601 -0
  94. package/fesm2022/vadem-ui-reorder-list.mjs.map +1 -0
  95. package/fesm2022/vadem-ui-scroll-area.mjs +65 -0
  96. package/fesm2022/vadem-ui-scroll-area.mjs.map +1 -0
  97. package/fesm2022/vadem-ui-search-input.mjs +307 -0
  98. package/fesm2022/vadem-ui-search-input.mjs.map +1 -0
  99. package/fesm2022/vadem-ui-segmented.mjs +297 -0
  100. package/fesm2022/vadem-ui-segmented.mjs.map +1 -0
  101. package/fesm2022/vadem-ui-select.mjs +1462 -0
  102. package/fesm2022/vadem-ui-select.mjs.map +1 -0
  103. package/fesm2022/vadem-ui-sidebar.mjs +493 -0
  104. package/fesm2022/vadem-ui-sidebar.mjs.map +1 -0
  105. package/fesm2022/vadem-ui-skeleton.mjs +106 -0
  106. package/fesm2022/vadem-ui-skeleton.mjs.map +1 -0
  107. package/fesm2022/vadem-ui-slider.mjs +60 -0
  108. package/fesm2022/vadem-ui-slider.mjs.map +1 -0
  109. package/fesm2022/vadem-ui-splitter.mjs +438 -0
  110. package/fesm2022/vadem-ui-splitter.mjs.map +1 -0
  111. package/fesm2022/vadem-ui-stat.mjs +369 -0
  112. package/fesm2022/vadem-ui-stat.mjs.map +1 -0
  113. package/fesm2022/vadem-ui-stepper.mjs +483 -0
  114. package/fesm2022/vadem-ui-stepper.mjs.map +1 -0
  115. package/fesm2022/vadem-ui-switch.mjs +45 -0
  116. package/fesm2022/vadem-ui-switch.mjs.map +1 -0
  117. package/fesm2022/vadem-ui-table.mjs +593 -0
  118. package/fesm2022/vadem-ui-table.mjs.map +1 -0
  119. package/fesm2022/vadem-ui-tabs.mjs +405 -0
  120. package/fesm2022/vadem-ui-tabs.mjs.map +1 -0
  121. package/fesm2022/vadem-ui-tag-input.mjs +685 -0
  122. package/fesm2022/vadem-ui-tag-input.mjs.map +1 -0
  123. package/fesm2022/vadem-ui-text-highlight.mjs +126 -0
  124. package/fesm2022/vadem-ui-text-highlight.mjs.map +1 -0
  125. package/fesm2022/vadem-ui-time-input.mjs +430 -0
  126. package/fesm2022/vadem-ui-time-input.mjs.map +1 -0
  127. package/fesm2022/vadem-ui-timeline.mjs +313 -0
  128. package/fesm2022/vadem-ui-timeline.mjs.map +1 -0
  129. package/fesm2022/vadem-ui-toast.mjs +397 -0
  130. package/fesm2022/vadem-ui-toast.mjs.map +1 -0
  131. package/fesm2022/vadem-ui-toolbar.mjs +396 -0
  132. package/fesm2022/vadem-ui-toolbar.mjs.map +1 -0
  133. package/fesm2022/vadem-ui-tooltip.mjs +218 -0
  134. package/fesm2022/vadem-ui-tooltip.mjs.map +1 -0
  135. package/fesm2022/vadem-ui-tree.mjs +551 -0
  136. package/fesm2022/vadem-ui-tree.mjs.map +1 -0
  137. package/fesm2022/vadem-ui-upload-list.mjs +408 -0
  138. package/fesm2022/vadem-ui-upload-list.mjs.map +1 -0
  139. package/fesm2022/vadem-ui.mjs +4 -0
  140. package/fesm2022/vadem-ui.mjs.map +1 -0
  141. package/fonts/jetbrains-mono/OFL.txt +93 -0
  142. package/fonts/jetbrains-mono/jetbrains-mono-cyrillic.woff2 +0 -0
  143. package/fonts/jetbrains-mono/jetbrains-mono-latin.woff2 +0 -0
  144. package/fonts/manrope/OFL.txt +93 -0
  145. package/fonts/manrope/manrope-cyrillic.woff2 +0 -0
  146. package/fonts/manrope/manrope-latin.woff2 +0 -0
  147. package/package.json +306 -3
  148. package/styles/base.css +160 -0
  149. package/styles/components/accordion.css +130 -0
  150. package/styles/components/active-filters.css +42 -0
  151. package/styles/components/alert-dialog.css +34 -0
  152. package/styles/components/alert.css +159 -0
  153. package/styles/components/autocomplete.css +97 -0
  154. package/styles/components/avatar.css +90 -0
  155. package/styles/components/badge.css +91 -0
  156. package/styles/components/breadcrumbs.css +94 -0
  157. package/styles/components/button.css +174 -0
  158. package/styles/components/calendar.css +186 -0
  159. package/styles/components/card.css +206 -0
  160. package/styles/components/character-count.css +41 -0
  161. package/styles/components/chart.css +308 -0
  162. package/styles/components/checkbox.css +115 -0
  163. package/styles/components/color-picker.css +158 -0
  164. package/styles/components/command.css +175 -0
  165. package/styles/components/copy-button.css +58 -0
  166. package/styles/components/date-range-picker.css +153 -0
  167. package/styles/components/description-list.css +69 -0
  168. package/styles/components/dialog.css +334 -0
  169. package/styles/components/dropzone.css +89 -0
  170. package/styles/components/editable-text.css +58 -0
  171. package/styles/components/empty-state.css +72 -0
  172. package/styles/components/expandable-text.css +24 -0
  173. package/styles/components/field.css +148 -0
  174. package/styles/components/file-preview.css +65 -0
  175. package/styles/components/form-error-summary.css +71 -0
  176. package/styles/components/icon.css +38 -0
  177. package/styles/components/index.css +80 -0
  178. package/styles/components/input.css +171 -0
  179. package/styles/components/kbd.css +42 -0
  180. package/styles/components/menu.css +168 -0
  181. package/styles/components/multi-select.css +156 -0
  182. package/styles/components/navigation-list.css +147 -0
  183. package/styles/components/number-input.css +33 -0
  184. package/styles/components/otp-input.css +26 -0
  185. package/styles/components/pagination.css +127 -0
  186. package/styles/components/password-input.css +20 -0
  187. package/styles/components/popover.css +93 -0
  188. package/styles/components/progress-ring.css +112 -0
  189. package/styles/components/progress.css +162 -0
  190. package/styles/components/radio.css +117 -0
  191. package/styles/components/range-slider.css +158 -0
  192. package/styles/components/rating.css +100 -0
  193. package/styles/components/reorder-list.css +143 -0
  194. package/styles/components/scroll-area.css +39 -0
  195. package/styles/components/search-input.css +25 -0
  196. package/styles/components/segmented.css +136 -0
  197. package/styles/components/select.css +257 -0
  198. package/styles/components/sidebar.css +105 -0
  199. package/styles/components/skeleton.css +83 -0
  200. package/styles/components/slider.css +132 -0
  201. package/styles/components/splitter.css +83 -0
  202. package/styles/components/stat.css +62 -0
  203. package/styles/components/stepper.css +236 -0
  204. package/styles/components/switch.css +107 -0
  205. package/styles/components/table.css +195 -0
  206. package/styles/components/tabs.css +198 -0
  207. package/styles/components/tag-input.css +138 -0
  208. package/styles/components/text-highlight.css +22 -0
  209. package/styles/components/time-input.css +96 -0
  210. package/styles/components/timeline.css +182 -0
  211. package/styles/components/toast.css +146 -0
  212. package/styles/components/toolbar.css +72 -0
  213. package/styles/components/tooltip.css +93 -0
  214. package/styles/components/tree.css +88 -0
  215. package/styles/components/upload-list.css +113 -0
  216. package/styles/fonts.css +67 -0
  217. package/styles/index.css +14 -0
  218. package/styles/reset.css +57 -0
  219. package/styles/tokens/primitives.css +364 -0
  220. package/styles/tokens/semantic.css +233 -0
  221. package/types/vadem-ui-accordion.d.ts +43 -0
  222. package/types/vadem-ui-active-filters.d.ts +73 -0
  223. package/types/vadem-ui-alert-dialog.d.ts +87 -0
  224. package/types/vadem-ui-alert.d.ts +64 -0
  225. package/types/vadem-ui-autocomplete.d.ts +156 -0
  226. package/types/vadem-ui-avatar.d.ts +59 -0
  227. package/types/vadem-ui-badge.d.ts +25 -0
  228. package/types/vadem-ui-breadcrumbs.d.ts +22 -0
  229. package/types/vadem-ui-button.d.ts +52 -0
  230. package/types/vadem-ui-calendar.d.ts +327 -0
  231. package/types/vadem-ui-card.d.ts +58 -0
  232. package/types/vadem-ui-character-count.d.ts +71 -0
  233. package/types/vadem-ui-chart.d.ts +452 -0
  234. package/types/vadem-ui-checkbox.d.ts +20 -0
  235. package/types/vadem-ui-color-picker.d.ts +171 -0
  236. package/types/vadem-ui-command.d.ts +145 -0
  237. package/types/vadem-ui-copy-button.d.ts +90 -0
  238. package/types/vadem-ui-date-range-picker.d.ts +216 -0
  239. package/types/vadem-ui-description-list.d.ts +15 -0
  240. package/types/vadem-ui-dialog.d.ts +174 -0
  241. package/types/vadem-ui-dropzone.d.ts +73 -0
  242. package/types/vadem-ui-editable-text.d.ts +141 -0
  243. package/types/vadem-ui-empty-state.d.ts +34 -0
  244. package/types/vadem-ui-expandable-text.d.ts +52 -0
  245. package/types/vadem-ui-field.d.ts +180 -0
  246. package/types/vadem-ui-file-preview.d.ts +108 -0
  247. package/types/vadem-ui-file-size.d.ts +18 -0
  248. package/types/vadem-ui-form-error-summary.d.ts +46 -0
  249. package/types/vadem-ui-icon.d.ts +152 -0
  250. package/types/vadem-ui-input.d.ts +31 -0
  251. package/types/vadem-ui-kbd.d.ts +66 -0
  252. package/types/vadem-ui-keyboard.d.ts +61 -0
  253. package/types/vadem-ui-locale.d.ts +241 -0
  254. package/types/vadem-ui-menu.d.ts +132 -0
  255. package/types/vadem-ui-navigation-list.d.ts +28 -0
  256. package/types/vadem-ui-number-input.d.ts +39 -0
  257. package/types/vadem-ui-otp-input.d.ts +15 -0
  258. package/types/vadem-ui-pagination.d.ts +96 -0
  259. package/types/vadem-ui-password-input.d.ts +36 -0
  260. package/types/vadem-ui-popover.d.ts +48 -0
  261. package/types/vadem-ui-progress.d.ts +95 -0
  262. package/types/vadem-ui-radio.d.ts +11 -0
  263. package/types/vadem-ui-range-slider.d.ts +136 -0
  264. package/types/vadem-ui-rating.d.ts +95 -0
  265. package/types/vadem-ui-relative-time.d.ts +58 -0
  266. package/types/vadem-ui-reorder-list.d.ts +120 -0
  267. package/types/vadem-ui-scroll-area.d.ts +13 -0
  268. package/types/vadem-ui-search-input.d.ts +58 -0
  269. package/types/vadem-ui-segmented.d.ts +76 -0
  270. package/types/vadem-ui-select.d.ts +303 -0
  271. package/types/vadem-ui-sidebar.d.ts +70 -0
  272. package/types/vadem-ui-skeleton.d.ts +28 -0
  273. package/types/vadem-ui-slider.d.ts +17 -0
  274. package/types/vadem-ui-splitter.d.ts +99 -0
  275. package/types/vadem-ui-stat.d.ts +101 -0
  276. package/types/vadem-ui-stepper.d.ts +108 -0
  277. package/types/vadem-ui-switch.d.ts +10 -0
  278. package/types/vadem-ui-table.d.ts +172 -0
  279. package/types/vadem-ui-tabs.d.ts +101 -0
  280. package/types/vadem-ui-tag-input.d.ts +170 -0
  281. package/types/vadem-ui-text-highlight.d.ts +27 -0
  282. package/types/vadem-ui-time-input.d.ts +47 -0
  283. package/types/vadem-ui-timeline.d.ts +54 -0
  284. package/types/vadem-ui-toast.d.ts +104 -0
  285. package/types/vadem-ui-toolbar.d.ts +80 -0
  286. package/types/vadem-ui-tooltip.d.ts +71 -0
  287. package/types/vadem-ui-tree.d.ts +123 -0
  288. package/types/vadem-ui-upload-list.d.ts +70 -0
  289. package/types/vadem-ui.d.ts +1 -0
@@ -0,0 +1,583 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, InjectionToken, ViewEncapsulation, booleanAttribute, computed, inject, input, signal } from "@angular/core";
3
+ import { VdIcon } from "@vadem/ui/icon";
4
+ import { NgControl, Validators } from "@angular/forms";
5
+ import { FormField } from "@angular/forms/signals";
6
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
7
+ var VdChoice = class VdChoice {
8
+ static ɵfac = i0.ɵɵngDeclareFactory({
9
+ minVersion: "12.0.0",
10
+ version: "22.2.1",
11
+ ngImport: i0,
12
+ type: VdChoice,
13
+ deps: [],
14
+ target: i0.ɵɵFactoryTarget.Directive
15
+ });
16
+ static ɵdir = i0.ɵɵngDeclareDirective({
17
+ minVersion: "14.0.0",
18
+ version: "22.2.1",
19
+ type: VdChoice,
20
+ isStandalone: true,
21
+ selector: "label[vdChoice]",
22
+ host: { classAttribute: "vd-choice" },
23
+ ngImport: i0
24
+ });
25
+ };
26
+ i0.ɵɵngDeclareClassMetadata({
27
+ minVersion: "12.0.0",
28
+ version: "22.2.1",
29
+ ngImport: i0,
30
+ type: VdChoice,
31
+ decorators: [{
32
+ type: Directive,
33
+ args: [{
34
+ selector: "label[vdChoice]",
35
+ host: { class: "vd-choice" }
36
+ }]
37
+ }]
38
+ });
39
+ const VD_FIELD = new InjectionToken("VD_FIELD");
40
+ let nextId = 0;
41
+ function vdUniqueId(prefix) {
42
+ return `${prefix}-${nextId++}`;
43
+ }
44
+ var VdField = class VdField {
45
+ label = input(...ngDevMode ? [void 0, { debugName: "label" }] : /* istanbul ignore next */ []);
46
+ hint = input(...ngDevMode ? [void 0, { debugName: "hint" }] : /* istanbul ignore next */ []);
47
+ descriptionIds = input(...ngDevMode ? [void 0, { debugName: "descriptionIds" }] : /* istanbul ignore next */ []);
48
+ error = input(...ngDevMode ? [void 0, { debugName: "error" }] : /* istanbul ignore next */ []);
49
+ control = signal(null, ...ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []);
50
+ hintId = vdUniqueId("vd-field-hint");
51
+ errorId = vdUniqueId("vd-field-error");
52
+ showError = computed(() => !!this.error() && !!this.control()?.invalid(), ...ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []);
53
+ describedBy = computed(() => {
54
+ const ids = [this.showError() ? this.errorId : this.hint() ? this.hintId : "", this.descriptionIds() ?? ""].join(" ").split(/\s+/).filter(Boolean);
55
+ return [...new Set(ids)].join(" ") || null;
56
+ }, ...ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []);
57
+ register(control) {
58
+ this.control.set(control);
59
+ }
60
+ unregister(control) {
61
+ if (this.control() === control) this.control.set(null);
62
+ }
63
+ static ɵfac = i0.ɵɵngDeclareFactory({
64
+ minVersion: "12.0.0",
65
+ version: "22.2.1",
66
+ ngImport: i0,
67
+ type: VdField,
68
+ deps: [],
69
+ target: i0.ɵɵFactoryTarget.Component
70
+ });
71
+ static ɵcmp = i0.ɵɵngDeclareComponent({
72
+ minVersion: "17.0.0",
73
+ version: "22.2.1",
74
+ type: VdField,
75
+ isStandalone: true,
76
+ selector: "vd-field",
77
+ inputs: {
78
+ label: {
79
+ classPropertyName: "label",
80
+ publicName: "label",
81
+ isSignal: true,
82
+ isRequired: false,
83
+ transformFunction: null
84
+ },
85
+ hint: {
86
+ classPropertyName: "hint",
87
+ publicName: "hint",
88
+ isSignal: true,
89
+ isRequired: false,
90
+ transformFunction: null
91
+ },
92
+ descriptionIds: {
93
+ classPropertyName: "descriptionIds",
94
+ publicName: "descriptionIds",
95
+ isSignal: true,
96
+ isRequired: false,
97
+ transformFunction: null
98
+ },
99
+ error: {
100
+ classPropertyName: "error",
101
+ publicName: "error",
102
+ isSignal: true,
103
+ isRequired: false,
104
+ transformFunction: null
105
+ }
106
+ },
107
+ host: {
108
+ properties: {
109
+ "attr.data-invalid": "showError() ? \"\" : null",
110
+ "attr.data-disabled": "control()?.disabled() ? \"\" : null"
111
+ },
112
+ classAttribute: "vd-field"
113
+ },
114
+ providers: [{
115
+ provide: VD_FIELD,
116
+ useExisting: VdField
117
+ }],
118
+ ngImport: i0,
119
+ template: `
120
+ @if (label()) {
121
+ <label class="vd-field__label" [attr.for]="control()?.id()">
122
+ {{ label() }}
123
+ @if (control()?.required()) {
124
+ <span class="vd-field__required" aria-hidden="true">*</span>
125
+ }
126
+ </label>
127
+ }
128
+ <ng-content />
129
+ @if (showError()) {
130
+ <p class="vd-field__error" [id]="errorId">
131
+ <vd-icon name="alert-circle" />
132
+ <span>{{ error() }}</span>
133
+ </p>
134
+ } @else if (hint()) {
135
+ <p class="vd-field__hint" [id]="hintId">{{ hint() }}</p>
136
+ }
137
+ `,
138
+ isInline: true,
139
+ dependencies: [{
140
+ kind: "component",
141
+ type: VdIcon,
142
+ selector: "vd-icon",
143
+ inputs: ["name", "label"]
144
+ }],
145
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
146
+ encapsulation: i0.ViewEncapsulation.None
147
+ });
148
+ };
149
+ i0.ɵɵngDeclareClassMetadata({
150
+ minVersion: "12.0.0",
151
+ version: "22.2.1",
152
+ ngImport: i0,
153
+ type: VdField,
154
+ decorators: [{
155
+ type: Component,
156
+ args: [{
157
+ selector: "vd-field",
158
+ imports: [VdIcon],
159
+ template: `
160
+ @if (label()) {
161
+ <label class="vd-field__label" [attr.for]="control()?.id()">
162
+ {{ label() }}
163
+ @if (control()?.required()) {
164
+ <span class="vd-field__required" aria-hidden="true">*</span>
165
+ }
166
+ </label>
167
+ }
168
+ <ng-content />
169
+ @if (showError()) {
170
+ <p class="vd-field__error" [id]="errorId">
171
+ <vd-icon name="alert-circle" />
172
+ <span>{{ error() }}</span>
173
+ </p>
174
+ } @else if (hint()) {
175
+ <p class="vd-field__hint" [id]="hintId">{{ hint() }}</p>
176
+ }
177
+ `,
178
+ host: {
179
+ class: "vd-field",
180
+ "[attr.data-invalid]": "showError() ? \"\" : null",
181
+ "[attr.data-disabled]": "control()?.disabled() ? \"\" : null"
182
+ },
183
+ providers: [{
184
+ provide: VD_FIELD,
185
+ useExisting: VdField
186
+ }],
187
+ changeDetection: ChangeDetectionStrategy.OnPush,
188
+ encapsulation: ViewEncapsulation.None
189
+ }]
190
+ }],
191
+ propDecorators: {
192
+ label: [{
193
+ type: i0.Input,
194
+ args: [{
195
+ isSignal: true,
196
+ alias: "label",
197
+ required: false
198
+ }]
199
+ }],
200
+ hint: [{
201
+ type: i0.Input,
202
+ args: [{
203
+ isSignal: true,
204
+ alias: "hint",
205
+ required: false
206
+ }]
207
+ }],
208
+ descriptionIds: [{
209
+ type: i0.Input,
210
+ args: [{
211
+ isSignal: true,
212
+ alias: "descriptionIds",
213
+ required: false
214
+ }]
215
+ }],
216
+ error: [{
217
+ type: i0.Input,
218
+ args: [{
219
+ isSignal: true,
220
+ alias: "error",
221
+ required: false
222
+ }]
223
+ }]
224
+ }
225
+ });
226
+ var VdFieldset = class VdFieldset {
227
+ legend = input(...ngDevMode ? [void 0, { debugName: "legend" }] : /* istanbul ignore next */ []);
228
+ hint = input(...ngDevMode ? [void 0, { debugName: "hint" }] : /* istanbul ignore next */ []);
229
+ error = input(...ngDevMode ? [void 0, { debugName: "error" }] : /* istanbul ignore next */ []);
230
+ orientation = input("vertical", ...ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []);
231
+ controls = signal([], ...ngDevMode ? [{ debugName: "controls" }] : /* istanbul ignore next */ []);
232
+ hintId = vdUniqueId("vd-fieldset-hint");
233
+ errorId = vdUniqueId("vd-fieldset-error");
234
+ required = computed(() => this.controls().some((c) => c.required()), ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
235
+ showError = computed(() => !!this.error() && this.controls().some((c) => c.invalid()), ...ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []);
236
+ groupDescribedBy = computed(() => [this.hint() ? this.hintId : null, this.showError() ? this.errorId : null].filter(Boolean).join(" ") || null, ...ngDevMode ? [{ debugName: "groupDescribedBy" }] : /* istanbul ignore next */ []);
237
+ describedBy = signal(null).asReadonly();
238
+ register(control) {
239
+ this.controls.update((list) => [...list, control]);
240
+ }
241
+ unregister(control) {
242
+ this.controls.update((list) => list.filter((c) => c !== control));
243
+ }
244
+ static ɵfac = i0.ɵɵngDeclareFactory({
245
+ minVersion: "12.0.0",
246
+ version: "22.2.1",
247
+ ngImport: i0,
248
+ type: VdFieldset,
249
+ deps: [],
250
+ target: i0.ɵɵFactoryTarget.Component
251
+ });
252
+ static ɵcmp = i0.ɵɵngDeclareComponent({
253
+ minVersion: "17.0.0",
254
+ version: "22.2.1",
255
+ type: VdFieldset,
256
+ isStandalone: true,
257
+ selector: "fieldset[vdFieldset]",
258
+ inputs: {
259
+ legend: {
260
+ classPropertyName: "legend",
261
+ publicName: "legend",
262
+ isSignal: true,
263
+ isRequired: false,
264
+ transformFunction: null
265
+ },
266
+ hint: {
267
+ classPropertyName: "hint",
268
+ publicName: "hint",
269
+ isSignal: true,
270
+ isRequired: false,
271
+ transformFunction: null
272
+ },
273
+ error: {
274
+ classPropertyName: "error",
275
+ publicName: "error",
276
+ isSignal: true,
277
+ isRequired: false,
278
+ transformFunction: null
279
+ },
280
+ orientation: {
281
+ classPropertyName: "orientation",
282
+ publicName: "orientation",
283
+ isSignal: true,
284
+ isRequired: false,
285
+ transformFunction: null
286
+ }
287
+ },
288
+ host: {
289
+ properties: {
290
+ "attr.data-orientation": "orientation()",
291
+ "attr.data-invalid": "showError() ? \"\" : null",
292
+ "attr.aria-describedby": "groupDescribedBy()"
293
+ },
294
+ classAttribute: "vd-fieldset"
295
+ },
296
+ providers: [{
297
+ provide: VD_FIELD,
298
+ useExisting: VdFieldset
299
+ }],
300
+ ngImport: i0,
301
+ template: `
302
+ @if (legend()) {
303
+ <legend class="vd-fieldset__legend">
304
+ {{ legend() }}
305
+ @if (required()) {
306
+ <span class="vd-field__required" aria-hidden="true">*</span>
307
+ }
308
+ </legend>
309
+ }
310
+ @if (hint()) {
311
+ <p class="vd-field__hint" [id]="hintId">{{ hint() }}</p>
312
+ }
313
+ @if (showError()) {
314
+ <p class="vd-field__error" [id]="errorId">
315
+ <vd-icon name="alert-circle" />
316
+ <span>{{ error() }}</span>
317
+ </p>
318
+ }
319
+ <div class="vd-fieldset__options"><ng-content /></div>
320
+ `,
321
+ isInline: true,
322
+ dependencies: [{
323
+ kind: "component",
324
+ type: VdIcon,
325
+ selector: "vd-icon",
326
+ inputs: ["name", "label"]
327
+ }],
328
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
329
+ encapsulation: i0.ViewEncapsulation.None
330
+ });
331
+ };
332
+ i0.ɵɵngDeclareClassMetadata({
333
+ minVersion: "12.0.0",
334
+ version: "22.2.1",
335
+ ngImport: i0,
336
+ type: VdFieldset,
337
+ decorators: [{
338
+ type: Component,
339
+ args: [{
340
+ selector: "fieldset[vdFieldset]",
341
+ imports: [VdIcon],
342
+ template: `
343
+ @if (legend()) {
344
+ <legend class="vd-fieldset__legend">
345
+ {{ legend() }}
346
+ @if (required()) {
347
+ <span class="vd-field__required" aria-hidden="true">*</span>
348
+ }
349
+ </legend>
350
+ }
351
+ @if (hint()) {
352
+ <p class="vd-field__hint" [id]="hintId">{{ hint() }}</p>
353
+ }
354
+ @if (showError()) {
355
+ <p class="vd-field__error" [id]="errorId">
356
+ <vd-icon name="alert-circle" />
357
+ <span>{{ error() }}</span>
358
+ </p>
359
+ }
360
+ <div class="vd-fieldset__options"><ng-content /></div>
361
+ `,
362
+ host: {
363
+ class: "vd-fieldset",
364
+ "[attr.data-orientation]": "orientation()",
365
+ "[attr.data-invalid]": "showError() ? \"\" : null",
366
+ "[attr.aria-describedby]": "groupDescribedBy()"
367
+ },
368
+ providers: [{
369
+ provide: VD_FIELD,
370
+ useExisting: VdFieldset
371
+ }],
372
+ changeDetection: ChangeDetectionStrategy.OnPush,
373
+ encapsulation: ViewEncapsulation.None
374
+ }]
375
+ }],
376
+ propDecorators: {
377
+ legend: [{
378
+ type: i0.Input,
379
+ args: [{
380
+ isSignal: true,
381
+ alias: "legend",
382
+ required: false
383
+ }]
384
+ }],
385
+ hint: [{
386
+ type: i0.Input,
387
+ args: [{
388
+ isSignal: true,
389
+ alias: "hint",
390
+ required: false
391
+ }]
392
+ }],
393
+ error: [{
394
+ type: i0.Input,
395
+ args: [{
396
+ isSignal: true,
397
+ alias: "error",
398
+ required: false
399
+ }]
400
+ }],
401
+ orientation: [{
402
+ type: i0.Input,
403
+ args: [{
404
+ isSignal: true,
405
+ alias: "orientation",
406
+ required: false
407
+ }]
408
+ }]
409
+ }
410
+ });
411
+ const EMPTY = {
412
+ invalid: false,
413
+ touched: false,
414
+ disabled: false,
415
+ required: false
416
+ };
417
+ function vdNgControlState(ngControl, destroyRef) {
418
+ const control = ngControl?.control;
419
+ const state = signal(EMPTY, ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
420
+ if (!control?.events) return state;
421
+ const sync = () => state.set({
422
+ invalid: control.invalid,
423
+ touched: control.touched,
424
+ disabled: control.disabled,
425
+ required: control.hasValidator(Validators.required) || control.hasValidator(Validators.requiredTrue)
426
+ });
427
+ sync();
428
+ control.events.pipe(takeUntilDestroyed(destroyRef)).subscribe(sync);
429
+ return state;
430
+ }
431
+ var VdFieldControlBase = class VdFieldControlBase {
432
+ invalid = input(false, {
433
+ ...ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {},
434
+ transform: booleanAttribute
435
+ });
436
+ touched = input(void 0, ...ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []);
437
+ required = input(false, {
438
+ ...ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {},
439
+ transform: booleanAttribute
440
+ });
441
+ id = input(vdUniqueId("vd-control"), ...ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []);
442
+ field = inject(VD_FIELD, { optional: true });
443
+ ngControl = inject(NgControl, {
444
+ self: true,
445
+ optional: true
446
+ });
447
+ formField = inject(FormField, {
448
+ self: true,
449
+ optional: true
450
+ });
451
+ destroyRef = inject(DestroyRef);
452
+ ngSource = signal(null, ...ngDevMode ? [{ debugName: "ngSource" }] : /* istanbul ignore next */ []);
453
+ ngState = computed(() => this.ngSource()?.() ?? {
454
+ invalid: false,
455
+ touched: false,
456
+ disabled: false,
457
+ required: false
458
+ }, ...ngDevMode ? [{ debugName: "ngState" }] : /* istanbul ignore next */ []);
459
+ showInvalid = computed(() => {
460
+ if (this.invalid() && this.touched() !== false) return true;
461
+ const ng = this.ngState();
462
+ return ng.invalid && ng.touched;
463
+ }, ...ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []);
464
+ fieldControl = {
465
+ id: this.id,
466
+ invalid: this.showInvalid,
467
+ required: computed(() => this.required() || this.ngState().required || !!this.formField?.state().required()),
468
+ disabled: computed(() => this.ngState().disabled || !!this.formField?.state().disabled())
469
+ };
470
+ constructor() {
471
+ this.field?.register(this.fieldControl);
472
+ this.destroyRef.onDestroy(() => this.field?.unregister(this.fieldControl));
473
+ }
474
+ ngOnInit() {
475
+ if (!this.formField) this.ngSource.set(vdNgControlState(this.ngControl, this.destroyRef));
476
+ }
477
+ static ɵfac = i0.ɵɵngDeclareFactory({
478
+ minVersion: "12.0.0",
479
+ version: "22.2.1",
480
+ ngImport: i0,
481
+ type: VdFieldControlBase,
482
+ deps: [],
483
+ target: i0.ɵɵFactoryTarget.Directive
484
+ });
485
+ static ɵdir = i0.ɵɵngDeclareDirective({
486
+ minVersion: "17.1.0",
487
+ version: "22.2.1",
488
+ type: VdFieldControlBase,
489
+ isStandalone: true,
490
+ inputs: {
491
+ invalid: {
492
+ classPropertyName: "invalid",
493
+ publicName: "invalid",
494
+ isSignal: true,
495
+ isRequired: false,
496
+ transformFunction: null
497
+ },
498
+ touched: {
499
+ classPropertyName: "touched",
500
+ publicName: "touched",
501
+ isSignal: true,
502
+ isRequired: false,
503
+ transformFunction: null
504
+ },
505
+ required: {
506
+ classPropertyName: "required",
507
+ publicName: "required",
508
+ isSignal: true,
509
+ isRequired: false,
510
+ transformFunction: null
511
+ },
512
+ id: {
513
+ classPropertyName: "id",
514
+ publicName: "id",
515
+ isSignal: true,
516
+ isRequired: false,
517
+ transformFunction: null
518
+ }
519
+ },
520
+ host: { properties: {
521
+ "id": "id()",
522
+ "attr.data-invalid": "showInvalid() ? \"\" : null",
523
+ "attr.aria-invalid": "showInvalid() ? \"true\" : null",
524
+ "attr.aria-describedby": "field?.describedBy() ?? null",
525
+ "attr.required": "required() ? \"\" : null"
526
+ } },
527
+ ngImport: i0
528
+ });
529
+ };
530
+ i0.ɵɵngDeclareClassMetadata({
531
+ minVersion: "12.0.0",
532
+ version: "22.2.1",
533
+ ngImport: i0,
534
+ type: VdFieldControlBase,
535
+ decorators: [{
536
+ type: Directive,
537
+ args: [{ host: {
538
+ "[id]": "id()",
539
+ "[attr.data-invalid]": "showInvalid() ? \"\" : null",
540
+ "[attr.aria-invalid]": "showInvalid() ? \"true\" : null",
541
+ "[attr.aria-describedby]": "field?.describedBy() ?? null",
542
+ "[attr.required]": "required() ? \"\" : null"
543
+ } }]
544
+ }],
545
+ ctorParameters: () => [],
546
+ propDecorators: {
547
+ invalid: [{
548
+ type: i0.Input,
549
+ args: [{
550
+ isSignal: true,
551
+ alias: "invalid",
552
+ required: false
553
+ }]
554
+ }],
555
+ touched: [{
556
+ type: i0.Input,
557
+ args: [{
558
+ isSignal: true,
559
+ alias: "touched",
560
+ required: false
561
+ }]
562
+ }],
563
+ required: [{
564
+ type: i0.Input,
565
+ args: [{
566
+ isSignal: true,
567
+ alias: "required",
568
+ required: false
569
+ }]
570
+ }],
571
+ id: [{
572
+ type: i0.Input,
573
+ args: [{
574
+ isSignal: true,
575
+ alias: "id",
576
+ required: false
577
+ }]
578
+ }]
579
+ }
580
+ });
581
+ export { VD_FIELD, VdChoice, VdField, VdFieldControlBase, VdFieldset, vdNgControlState, vdUniqueId };
582
+
583
+ //# sourceMappingURL=vadem-ui-field.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vadem-ui-field.mjs","names":[],"sources":["../../../projects/ui/field/src/choice.ts","../../../projects/ui/field/src/field-control.ts","../../../projects/ui/field/src/field.ts","../../../projects/ui/field/src/fieldset.ts","../../../projects/ui/field/src/ng-control-state.ts","../../../projects/ui/field/src/field-control-base.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Label that wraps a checkbox, switch or radio and its text. The whole label is the hit area;\n * the text is the control's accessible name. Spec: specs/checkbox.md\n */\n@Directive({\n selector: 'label[vdChoice]',\n host: { class: 'vd-choice' },\n})\nexport class VdChoice {}\n","import { InjectionToken, Signal } from '@angular/core';\n\n/** What a form control exposes to its surrounding `vd-field`. */\nexport interface VdFieldControl {\n readonly id: Signal<string>;\n readonly invalid: Signal<boolean>;\n readonly required: Signal<boolean>;\n readonly disabled: Signal<boolean>;\n}\n\n/** What `vd-field` exposes to the control inside it. */\nexport interface VdFieldContext {\n /** Space-separated ids for `aria-describedby` (hint or error), or null. */\n readonly describedBy: Signal<string | null>;\n register(control: VdFieldControl): void;\n unregister(control: VdFieldControl): void;\n}\n\nexport const VD_FIELD = new InjectionToken<VdFieldContext>('VD_FIELD');\n\nlet nextId = 0;\n/** Deterministic per-app id. Same creation order on server and client keeps hydration stable. */\nexport function vdUniqueId(prefix: string): string {\n return `${prefix}-${nextId++}`;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\n/**\n * Label, hint and error around one form control. Wires `for`, `aria-describedby`,\n * and the required marker automatically. Spec: specs/field.md\n */\n@Component({\n selector: 'vd-field',\n imports: [VdIcon],\n template: `\n @if (label()) {\n <label class=\"vd-field__label\" [attr.for]=\"control()?.id()\">\n {{ label() }}\n @if (control()?.required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n <ng-content />\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n } @else if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n `,\n host: {\n class: 'vd-field',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.data-disabled]': 'control()?.disabled() ? \"\" : null',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdField }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdField implements VdFieldContext {\n readonly label = input<string>();\n readonly hint = input<string>();\n /** Additional descriptive IDs, e.g. a character counter; retained beside hint/error. */\n readonly descriptionIds = input<string>();\n /** Message shown while the control is invalid. Replaces the hint. */\n readonly error = input<string>();\n\n protected readonly control = signal<VdFieldControl | null>(null);\n protected readonly hintId = vdUniqueId('vd-field-hint');\n protected readonly errorId = vdUniqueId('vd-field-error');\n\n protected readonly showError = computed(() => !!this.error() && !!this.control()?.invalid());\n\n readonly describedBy = computed(() => {\n const primary = this.showError() ? this.errorId : this.hint() ? this.hintId : '';\n const ids = [primary, this.descriptionIds() ?? ''].join(' ').split(/\\s+/).filter(Boolean);\n return [...new Set(ids)].join(' ') || null;\n });\n\n register(control: VdFieldControl): void {\n this.control.set(control);\n }\n\n unregister(control: VdFieldControl): void {\n if (this.control() === control) this.control.set(null);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\nexport type VdFieldsetOrientation = 'vertical' | 'horizontal';\n\n/**\n * Legend, hint and error around a group of choices (radios, checkboxes). The group is named by\n * the legend; hint and error describe the fieldset itself, so they are announced once when the\n * group is entered, not on every option. Spec: specs/field.md\n */\n@Component({\n // Attribute selector: the native fieldset keeps its group semantics.\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'fieldset[vdFieldset]',\n imports: [VdIcon],\n template: `\n @if (legend()) {\n <legend class=\"vd-fieldset__legend\">\n {{ legend() }}\n @if (required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </legend>\n }\n @if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n }\n <div class=\"vd-fieldset__options\"><ng-content /></div>\n `,\n host: {\n class: 'vd-fieldset',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.aria-describedby]': 'groupDescribedBy()',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdFieldset }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdFieldset implements VdFieldContext {\n readonly legend = input<string>();\n readonly hint = input<string>();\n /** Shown while any control in the group is displayed invalid. */\n readonly error = input<string>();\n readonly orientation = input<VdFieldsetOrientation>('vertical');\n\n protected readonly controls = signal<readonly VdFieldControl[]>([]);\n protected readonly hintId = vdUniqueId('vd-fieldset-hint');\n protected readonly errorId = vdUniqueId('vd-fieldset-error');\n\n protected readonly required = computed(() => this.controls().some((c) => c.required()));\n protected readonly showError = computed(\n () => !!this.error() && this.controls().some((c) => c.invalid()),\n );\n protected readonly groupDescribedBy = computed(\n () =>\n [this.hint() ? this.hintId : null, this.showError() ? this.errorId : null]\n .filter(Boolean)\n .join(' ') || null,\n );\n\n /** Controls aren't described individually: the fieldset carries the description. */\n readonly describedBy = signal<string | null>(null).asReadonly();\n\n register(control: VdFieldControl): void {\n this.controls.update((list) => [...list, control]);\n }\n\n unregister(control: VdFieldControl): void {\n this.controls.update((list) => list.filter((c) => c !== control));\n }\n}\n","import { DestroyRef, Signal, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgControl, Validators } from '@angular/forms';\n\nexport interface VdNgControlState {\n invalid: boolean;\n touched: boolean;\n disabled: boolean;\n required: boolean;\n}\n\nconst EMPTY: VdNgControlState = {\n invalid: false,\n touched: false,\n disabled: false,\n required: false,\n};\n\n/**\n * Mirrors a Reactive/Template forms control into a signal (NgControl isn't signal-based).\n * Call once the control is resolved (ngOnInit or later). Returns a static empty state when\n * there's no control or it's a Signal Forms shim without `events`.\n */\nexport function vdNgControlState(\n ngControl: NgControl | null,\n destroyRef: DestroyRef,\n): Signal<VdNgControlState> {\n const control = ngControl?.control;\n const state = signal(EMPTY);\n if (!control?.events) return state;\n const sync = () =>\n state.set({\n invalid: control.invalid,\n touched: control.touched,\n disabled: control.disabled,\n required:\n control.hasValidator(Validators.required) || control.hasValidator(Validators.requiredTrue),\n });\n sync();\n control.events.pipe(takeUntilDestroyed(destroyRef)).subscribe(sync);\n return state;\n}\n","import {\n DestroyRef,\n Directive,\n OnInit,\n Signal,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { FormField } from '@angular/forms/signals';\nimport { VD_FIELD, VdFieldControl, vdUniqueId } from './field-control';\nimport { VdNgControlState, vdNgControlState } from './ng-control-state';\n\n/**\n * Shared behavior for controls on native form elements (input, checkbox, switch):\n * displayed validity from Reactive/Template forms or Signal Forms, `vd-field` registration,\n * and the ARIA/data attributes that go with it. Not part of the styling contract.\n */\n@Directive({\n host: {\n '[id]': 'id()',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.aria-invalid]': 'showInvalid() ? \"true\" : null',\n '[attr.aria-describedby]': 'field?.describedBy() ?? null',\n '[attr.required]': 'required() ? \"\" : null',\n },\n})\nexport abstract class VdFieldControlBase implements OnInit {\n /** Invalid state (e.g. a server error). Reactive/Template form validity is detected on its own. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /**\n * Optional gate for `invalid`: when explicitly false the error isn't shown yet. Signal Forms\n * binds `invalid`, `touched` and `required` here automatically (FormUiControl contract).\n */\n readonly touched = input<boolean | undefined>(undefined);\n readonly required = input(false, { transform: booleanAttribute });\n readonly id = input(vdUniqueId('vd-control'));\n\n protected readonly field = inject(VD_FIELD, { optional: true });\n private readonly ngControl = inject(NgControl, { self: true, optional: true });\n private readonly formField = inject(FormField, { self: true, optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n /** Mirrored Reactive/Template forms state; set once the control is resolved (ngOnInit). */\n private readonly ngSource = signal<Signal<VdNgControlState> | null>(null);\n private readonly ngState = computed(\n () =>\n this.ngSource()?.() ?? { invalid: false, touched: false, disabled: false, required: false },\n );\n\n /** Invalid as displayed: forced, or form-invalid after the user has touched the control. */\n readonly showInvalid = computed(() => {\n if (this.invalid() && this.touched() !== false) return true;\n const ng = this.ngState();\n return ng.invalid && ng.touched;\n });\n\n private readonly fieldControl: VdFieldControl = {\n id: this.id,\n invalid: this.showInvalid,\n required: computed(\n () => this.required() || this.ngState().required || !!this.formField?.state().required(),\n ),\n disabled: computed(() => this.ngState().disabled || !!this.formField?.state().disabled()),\n };\n\n constructor() {\n this.field?.register(this.fieldControl);\n this.destroyRef.onDestroy(() => this.field?.unregister(this.fieldControl));\n }\n\n ngOnInit(): void {\n // NgControl resolves its control only after init. Signal Forms provides an NgControl shim\n // too; its state arrives through the inputs instead.\n if (!this.formField) this.ngSource.set(vdNgControlState(this.ngControl, this.destroyRef));\n }\n}\n"],"mappings":"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"}