@egose/shadcn-theme-ng-tw 0.0.28 → 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 (244) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +20 -20
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +18 -18
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
  8. package/alert-dialog/types/alert-dialog.d.ts +1 -1
  9. package/aspect-ratio/README.md +272 -5
  10. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  11. package/autocomplete/README.md +473 -34
  12. package/autocomplete/fesm2022/autocomplete.mjs +54 -54
  13. package/autocomplete/types/autocomplete.d.ts +1 -1
  14. package/avatar/README.md +357 -5
  15. package/avatar/fesm2022/avatar.mjs +32 -32
  16. package/badge/README.md +289 -34
  17. package/badge/fesm2022/badge.mjs +4 -4
  18. package/basic-alert/README.md +324 -34
  19. package/basic-alert/fesm2022/basic-alert.mjs +4 -4
  20. package/basic-alert/types/basic-alert.d.ts +1 -1
  21. package/breadcrumb/README.md +406 -5
  22. package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
  23. package/button/README.md +453 -34
  24. package/button/fesm2022/button.mjs +96 -118
  25. package/button/types/button.d.ts +7 -10
  26. package/button-group/README.md +318 -5
  27. package/button-group/fesm2022/button-group.mjs +20 -20
  28. package/calendar/README.md +328 -34
  29. package/calendar/fesm2022/calendar.mjs +154 -154
  30. package/card/README.md +331 -5
  31. package/card/fesm2022/card.mjs +33 -33
  32. package/carousel/README.md +333 -5
  33. package/carousel/fesm2022/carousel.mjs +47 -44
  34. package/carousel/types/carousel.d.ts +1 -1
  35. package/checkbox/README.md +291 -34
  36. package/checkbox/fesm2022/checkbox.mjs +22 -20
  37. package/checkbox/types/checkbox.d.ts +5 -4
  38. package/collapsible/README.md +332 -5
  39. package/collapsible/fesm2022/collapsible.mjs +15 -15
  40. package/combobox/README.md +507 -5
  41. package/combobox/fesm2022/combobox.mjs +95 -92
  42. package/combobox/types/combobox.d.ts +1 -1
  43. package/command/README.md +435 -5
  44. package/command/fesm2022/command.mjs +56 -56
  45. package/confirmation-dialog/README.md +272 -34
  46. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
  47. package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
  48. package/context-menu/README.md +366 -5
  49. package/context-menu/fesm2022/context-menu.mjs +9 -9
  50. package/date-picker/README.md +436 -34
  51. package/date-picker/fesm2022/date-picker.mjs +79 -68
  52. package/date-picker/types/date-picker.d.ts +8 -4
  53. package/dialog/README.md +419 -34
  54. package/dialog/fesm2022/dialog.mjs +48 -48
  55. package/drawer/README.md +395 -5
  56. package/drawer/fesm2022/drawer.mjs +45 -45
  57. package/dropdown-menu/README.md +417 -5
  58. package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
  59. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  60. package/empty/README.md +329 -5
  61. package/empty/fesm2022/empty.mjs +31 -31
  62. package/field/README.md +385 -5
  63. package/field/fesm2022/field.mjs +59 -59
  64. package/field/types/field.d.ts +1 -1
  65. package/form-checkbox/README.md +283 -34
  66. package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
  67. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  68. package/form-date-picker/README.md +293 -34
  69. package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
  70. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  71. package/form-field/README.md +327 -34
  72. package/form-field/fesm2022/form-field.mjs +30 -16
  73. package/form-field/types/form-field.d.ts +28 -20
  74. package/form-field-simple/README.md +311 -34
  75. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  76. package/form-searchable-multiselect/README.md +332 -34
  77. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
  78. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
  79. package/form-select/README.md +321 -34
  80. package/form-select/fesm2022/form-select.mjs +62 -29
  81. package/form-select/types/form-select.d.ts +7 -1
  82. package/form-text-input/README.md +342 -34
  83. package/form-text-input/fesm2022/form-text-input.mjs +43 -55
  84. package/form-text-input/types/form-text-input.d.ts +9 -12
  85. package/form-textarea/README.md +318 -34
  86. package/form-textarea/fesm2022/form-textarea.mjs +42 -23
  87. package/form-textarea/types/form-textarea.d.ts +8 -1
  88. package/hover-card/README.md +256 -5
  89. package/hover-card/fesm2022/hover-card.mjs +19 -19
  90. package/icon/README.md +210 -34
  91. package/icon/fesm2022/icon.mjs +8 -8
  92. package/input/README.md +240 -34
  93. package/input/fesm2022/input.mjs +17 -12
  94. package/input/types/input.d.ts +2 -1
  95. package/input-group/README.md +335 -5
  96. package/input-group/fesm2022/input-group.mjs +37 -37
  97. package/input-group/types/input-group.d.ts +3 -3
  98. package/input-otp/README.md +375 -5
  99. package/input-otp/fesm2022/input-otp.mjs +27 -27
  100. package/item/README.md +385 -5
  101. package/item/fesm2022/item.mjs +54 -54
  102. package/kbd/README.md +291 -5
  103. package/kbd/fesm2022/kbd.mjs +13 -13
  104. package/label/README.md +243 -34
  105. package/label/fesm2022/label.mjs +9 -9
  106. package/label/types/label.d.ts +1 -1
  107. package/layout-simple/README.md +174 -44
  108. package/layout-simple/fesm2022/layout-simple.mjs +917 -398
  109. package/layout-simple/types/layout-simple.d.ts +180 -129
  110. package/menu/README.md +418 -0
  111. package/menu/fesm2022/menu.mjs +461 -0
  112. package/menu/package.json +24 -0
  113. package/menu/types/menu.d.ts +137 -0
  114. package/menubar/README.md +343 -5
  115. package/menubar/fesm2022/menubar.mjs +13 -13
  116. package/native-select/README.md +323 -5
  117. package/native-select/fesm2022/native-select.mjs +19 -19
  118. package/navigation-menu/README.md +369 -5
  119. package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
  120. package/package.json +183 -154
  121. package/pagination/README.md +388 -5
  122. package/pagination/fesm2022/pagination.mjs +63 -63
  123. package/popover/README.md +302 -34
  124. package/popover/fesm2022/popover.mjs +30 -30
  125. package/progress/README.md +311 -5
  126. package/progress/fesm2022/progress.mjs +13 -13
  127. package/radio-group/README.md +335 -34
  128. package/radio-group/fesm2022/radio-group.mjs +26 -19
  129. package/resizable/README.md +269 -5
  130. package/resizable/fesm2022/resizable.mjs +19 -19
  131. package/scroll-area/README.md +233 -5
  132. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  133. package/searchable-multiselect/README.md +294 -34
  134. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
  135. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  136. package/select/README.md +408 -34
  137. package/select/fesm2022/select.mjs +80 -72
  138. package/select/types/select.d.ts +3 -1
  139. package/separator/README.md +193 -34
  140. package/separator/fesm2022/separator.mjs +9 -9
  141. package/separator/types/separator.d.ts +1 -1
  142. package/sheet/README.md +282 -34
  143. package/sheet/fesm2022/sheet.mjs +30 -30
  144. package/sidebar/README.md +457 -5
  145. package/sidebar/fesm2022/sidebar.mjs +136 -134
  146. package/sidebar/types/sidebar.d.ts +3 -3
  147. package/skeleton/README.md +217 -5
  148. package/skeleton/fesm2022/skeleton.mjs +9 -9
  149. package/slider/README.md +273 -5
  150. package/slider/fesm2022/slider.mjs +29 -25
  151. package/sonner/README.md +317 -34
  152. package/sonner/fesm2022/sonner.mjs +9 -9
  153. package/spinner/README.md +255 -34
  154. package/spinner/fesm2022/spinner.mjs +8 -8
  155. package/switch/README.md +281 -34
  156. package/switch/fesm2022/switch.mjs +12 -14
  157. package/table/README.md +423 -5
  158. package/table/fesm2022/table.mjs +41 -41
  159. package/tabs/README.md +382 -34
  160. package/tabs/fesm2022/tabs.mjs +48 -38
  161. package/textarea/README.md +282 -5
  162. package/textarea/fesm2022/textarea.mjs +9 -9
  163. package/toggle/README.md +270 -5
  164. package/toggle/fesm2022/toggle.mjs +14 -14
  165. package/toggle-group/README.md +340 -5
  166. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  167. package/toggle-group/types/toggle-group.d.ts +13 -7
  168. package/tooltip/README.md +240 -34
  169. package/tooltip/fesm2022/tooltip.mjs +14 -14
  170. package/typography/README.md +271 -5
  171. package/typography/fesm2022/typography.mjs +53 -53
  172. package/typography/types/typography.d.ts +12 -12
  173. package/utils/README.md +274 -34
  174. package/utils/fesm2022/utils.mjs +68 -44
  175. package/accordion/fesm2022/accordion.mjs.map +0 -1
  176. package/alert/fesm2022/alert.mjs.map +0 -1
  177. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  178. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  179. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  180. package/avatar/fesm2022/avatar.mjs.map +0 -1
  181. package/badge/fesm2022/badge.mjs.map +0 -1
  182. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  183. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  184. package/button/fesm2022/button.mjs.map +0 -1
  185. package/button-group/fesm2022/button-group.mjs.map +0 -1
  186. package/calendar/fesm2022/calendar.mjs.map +0 -1
  187. package/card/fesm2022/card.mjs.map +0 -1
  188. package/carousel/fesm2022/carousel.mjs.map +0 -1
  189. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  190. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  191. package/combobox/fesm2022/combobox.mjs.map +0 -1
  192. package/command/fesm2022/command.mjs.map +0 -1
  193. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  194. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  195. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  196. package/dialog/fesm2022/dialog.mjs.map +0 -1
  197. package/drawer/fesm2022/drawer.mjs.map +0 -1
  198. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  199. package/empty/fesm2022/empty.mjs.map +0 -1
  200. package/field/fesm2022/field.mjs.map +0 -1
  201. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  202. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  203. package/form-field/fesm2022/form-field.mjs.map +0 -1
  204. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  205. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  206. package/form-select/fesm2022/form-select.mjs.map +0 -1
  207. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  208. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  209. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  210. package/icon/fesm2022/icon.mjs.map +0 -1
  211. package/input/fesm2022/input.mjs.map +0 -1
  212. package/input-group/fesm2022/input-group.mjs.map +0 -1
  213. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  214. package/item/fesm2022/item.mjs.map +0 -1
  215. package/kbd/fesm2022/kbd.mjs.map +0 -1
  216. package/label/fesm2022/label.mjs.map +0 -1
  217. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  218. package/menubar/fesm2022/menubar.mjs.map +0 -1
  219. package/native-select/fesm2022/native-select.mjs.map +0 -1
  220. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  221. package/pagination/fesm2022/pagination.mjs.map +0 -1
  222. package/popover/fesm2022/popover.mjs.map +0 -1
  223. package/progress/fesm2022/progress.mjs.map +0 -1
  224. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  225. package/resizable/fesm2022/resizable.mjs.map +0 -1
  226. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  227. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  228. package/select/fesm2022/select.mjs.map +0 -1
  229. package/separator/fesm2022/separator.mjs.map +0 -1
  230. package/sheet/fesm2022/sheet.mjs.map +0 -1
  231. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  232. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  233. package/slider/fesm2022/slider.mjs.map +0 -1
  234. package/sonner/fesm2022/sonner.mjs.map +0 -1
  235. package/spinner/fesm2022/spinner.mjs.map +0 -1
  236. package/switch/fesm2022/switch.mjs.map +0 -1
  237. package/table/fesm2022/table.mjs.map +0 -1
  238. package/tabs/fesm2022/tabs.mjs.map +0 -1
  239. package/textarea/fesm2022/textarea.mjs.map +0 -1
  240. package/toggle/fesm2022/toggle.mjs.map +0 -1
  241. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  242. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  243. package/typography/fesm2022/typography.mjs.map +0 -1
  244. package/utils/fesm2022/utils.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, computed, Directive, contentChild, contentChildren, effect, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
2
+ import { input, computed, Directive, contentChild, contentChildren, effect, ChangeDetectionStrategy, Component, inject, APP_ID, Injectable, NgModule } from '@angular/core';
3
3
  import { hlm } from '@egose/shadcn-theme-ng-tw/utils';
4
4
  import { FormGroupDirective, ControlContainer } from '@angular/forms';
5
5
  import * as i1 from '@spartan-ng/brain/field';
@@ -9,10 +9,10 @@ class HlmError {
9
9
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
10
10
  _computedClass = computed(() => hlm('tw:text-destructive tw:block tw:text-sm tw:font-medium', this.userClass()), /* @ts-ignore */
11
11
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
12
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmError, deps: [], target: i0.ɵɵFactoryTarget.Directive });
13
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: HlmError, isStandalone: true, selector: "hlm-error", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
12
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmError, deps: [], target: i0.ɵɵFactoryTarget.Directive });
13
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmError, isStandalone: true, selector: "hlm-error", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
14
14
  }
15
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmError, decorators: [{
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmError, decorators: [{
16
16
  type: Directive,
17
17
  args: [{
18
18
  selector: 'hlm-error',
@@ -43,8 +43,8 @@ class HlmFormField {
43
43
  }
44
44
  });
45
45
  }
46
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmFormField, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: HlmFormField, isStandalone: true, selector: "hlm-form-field", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], queries: [{ propertyName: "control", first: true, predicate: BrnFieldControl, descendants: true, isSignal: true }, { propertyName: "errorChildren", predicate: HlmError, isSignal: true }], hostDirectives: [{ directive: i1.BrnField }], ngImport: i0, template: `
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormField, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: HlmFormField, isStandalone: true, selector: "hlm-form-field", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], queries: [{ propertyName: "control", first: true, predicate: BrnFieldControl, descendants: true, isSignal: true }, { propertyName: "errorChildren", predicate: HlmError, isSignal: true }], hostDirectives: [{ directive: i1.BrnField }], ngImport: i0, template: `
48
48
  <ng-content />
49
49
 
50
50
  @switch (_hasDisplayedMessage()) {
@@ -57,7 +57,7 @@ class HlmFormField {
57
57
  }
58
58
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
59
59
  }
60
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmFormField, decorators: [{
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormField, decorators: [{
61
61
  type: Component,
62
62
  args: [{
63
63
  selector: 'hlm-form-field',
@@ -86,10 +86,10 @@ class HlmHint {
86
86
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
87
87
  _computedClass = computed(() => hlm('tw:text-muted-foreground tw:block tw:text-sm', this.userClass()), /* @ts-ignore */
88
88
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
89
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmHint, deps: [], target: i0.ɵɵFactoryTarget.Directive });
90
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: HlmHint, isStandalone: true, selector: "hlm-hint", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
89
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHint, deps: [], target: i0.ɵɵFactoryTarget.Directive });
90
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmHint, isStandalone: true, selector: "hlm-hint", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
91
91
  }
92
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmHint, decorators: [{
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmHint, decorators: [{
93
93
  type: Directive,
94
94
  args: [{
95
95
  selector: 'hlm-hint',
@@ -99,16 +99,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
99
99
  }]
100
100
  }], propDecorators: { userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
101
101
 
102
+ class HlmFormIdGenerator {
103
+ appId = inject(APP_ID);
104
+ nextId = 0;
105
+ generate(prefix) {
106
+ return `${prefix}-${this.appId}-${this.nextId++}`;
107
+ }
108
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormIdGenerator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
109
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormIdGenerator, providedIn: 'root' });
110
+ }
111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormIdGenerator, decorators: [{
112
+ type: Injectable,
113
+ args: [{ providedIn: 'root' }]
114
+ }] });
115
+
102
116
  /*
103
117
  * Public API Surface of form-field
104
118
  */
105
119
  const HlmFormFieldImports = [HlmFormField, HlmError, HlmHint];
106
120
  class HlmFormFieldModule {
107
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmFormFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
108
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmFormFieldModule, imports: [HlmFormField, HlmError, HlmHint], exports: [HlmFormField, HlmError, HlmHint] });
109
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmFormFieldModule });
121
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
122
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmFormFieldModule, imports: [HlmFormField, HlmError, HlmHint], exports: [HlmFormField, HlmError, HlmHint] });
123
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormFieldModule });
110
124
  }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmFormFieldModule, decorators: [{
125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmFormFieldModule, decorators: [{
112
126
  type: NgModule,
113
127
  args: [{
114
128
  imports: [...HlmFormFieldImports],
@@ -120,5 +134,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
120
134
  * Generated bundle index. Do not edit.
121
135
  */
122
136
 
123
- export { HlmError, HlmFormField, HlmFormFieldImports, HlmFormFieldModule, HlmHint };
124
- //# sourceMappingURL=form-field.mjs.map
137
+ export { HlmError, HlmFormField, HlmFormFieldImports, HlmFormFieldModule, HlmFormIdGenerator, HlmHint };
138
+
@@ -1,38 +1,46 @@
1
- import * as _angular_core from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
2
  import { ClassValue } from 'clsx';
3
3
  import * as i1 from '@spartan-ng/brain/field';
4
4
  import { BrnFieldControl } from '@spartan-ng/brain/field';
5
5
 
6
6
  declare class HlmError {
7
- readonly userClass: _angular_core.InputSignal<ClassValue>;
8
- protected readonly _computedClass: _angular_core.Signal<string>;
9
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmError, never>;
10
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HlmError, "hlm-error", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
7
+ readonly userClass: i0.InputSignal<ClassValue>;
8
+ protected readonly _computedClass: i0.Signal<string>;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<HlmError, never>;
10
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HlmError, "hlm-error", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
11
11
  }
12
12
 
13
13
  declare class HlmFormField {
14
- readonly userClass: _angular_core.InputSignal<ClassValue>;
15
- protected readonly _computedClass: _angular_core.Signal<string>;
16
- readonly control: _angular_core.Signal<BrnFieldControl | undefined>;
17
- readonly errorChildren: _angular_core.Signal<readonly HlmError[]>;
18
- protected readonly _hasDisplayedMessage: _angular_core.Signal<"error" | "hint">;
14
+ readonly userClass: i0.InputSignal<ClassValue>;
15
+ protected readonly _computedClass: i0.Signal<string>;
16
+ readonly control: i0.Signal<BrnFieldControl | undefined>;
17
+ readonly errorChildren: i0.Signal<readonly HlmError[]>;
18
+ protected readonly _hasDisplayedMessage: i0.Signal<"error" | "hint">;
19
19
  constructor();
20
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmFormField, never>;
21
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<HlmFormField, "hlm-form-field", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, ["control", "errorChildren"], ["*", "hlm-error", "hlm-hint"], true, [{ directive: typeof i1.BrnField; inputs: {}; outputs: {}; }]>;
20
+ static ɵfac: i0.ɵɵFactoryDeclaration<HlmFormField, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<HlmFormField, "hlm-form-field", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, ["control", "errorChildren"], ["*", "hlm-error", "hlm-hint"], true, [{ directive: typeof i1.BrnField; inputs: {}; outputs: {}; }]>;
22
22
  }
23
23
 
24
24
  declare class HlmHint {
25
- readonly userClass: _angular_core.InputSignal<ClassValue>;
26
- protected readonly _computedClass: _angular_core.Signal<string>;
27
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmHint, never>;
28
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HlmHint, "hlm-hint", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
25
+ readonly userClass: i0.InputSignal<ClassValue>;
26
+ protected readonly _computedClass: i0.Signal<string>;
27
+ static ɵfac: i0.ɵɵFactoryDeclaration<HlmHint, never>;
28
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HlmHint, "hlm-hint", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
29
+ }
30
+
31
+ declare class HlmFormIdGenerator {
32
+ private readonly appId;
33
+ private nextId;
34
+ generate(prefix: string): string;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<HlmFormIdGenerator, never>;
36
+ static ɵprov: i0.ɵɵInjectableDeclaration<HlmFormIdGenerator>;
29
37
  }
30
38
 
31
39
  declare const HlmFormFieldImports: (typeof HlmError | typeof HlmFormField | typeof HlmHint)[];
32
40
  declare class HlmFormFieldModule {
33
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmFormFieldModule, never>;
34
- static ɵmod: _angular_core.ɵɵNgModuleDeclaration<HlmFormFieldModule, never, [typeof HlmFormField, typeof HlmError, typeof HlmHint], [typeof HlmFormField, typeof HlmError, typeof HlmHint]>;
35
- static ɵinj: _angular_core.ɵɵInjectorDeclaration<HlmFormFieldModule>;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<HlmFormFieldModule, never>;
42
+ static ɵmod: i0.ɵɵNgModuleDeclaration<HlmFormFieldModule, never, [typeof HlmFormField, typeof HlmError, typeof HlmHint], [typeof HlmFormField, typeof HlmError, typeof HlmHint]>;
43
+ static ɵinj: i0.ɵɵInjectorDeclaration<HlmFormFieldModule>;
36
44
  }
37
45
 
38
- export { HlmError, HlmFormField, HlmFormFieldImports, HlmFormFieldModule, HlmHint };
46
+ export { HlmError, HlmFormField, HlmFormFieldImports, HlmFormFieldModule, HlmFormIdGenerator, HlmHint };
@@ -1,64 +1,341 @@
1
- # FormFieldSimple
1
+ # Form Field Simple (`@egose/shadcn-theme-ng/form-field-simple`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
3
+ A minimal reactive-form wrapper: `eg-form-field` projects your control and shows either the projected `hlm-error` or `hlm-hint` based on the control's touched/dirty error state. A lighter alternative to `hlm-form-field` with no brain dependency.
4
4
 
5
- ## Code scaffolding
5
+ The Angular implementation is a standalone component with no headless primitive: it grabs the
6
+ projected `FormControlName` via `contentChild`, subscribes to its `statusChanges`, and exposes
7
+ `hasError` / `firstErrorKey` computed signals. Template logic is `@if (hasError())` → project
8
+ `hlm-error`, else project `hlm-hint`. It must live inside a `FormGroupDirective` (`[formGroup]`
9
+ parent) and provides `ControlContainer → FormGroupDirective` so `formControlName` resolves.
6
10
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
11
+ > **Ships as:** `@egose/shadcn-theme-ng/form-field-simple` and `@egose/shadcn-theme-ng-tw/form-field-simple`
12
+ > (the `tw:`-prefixed Tailwind variant). Both expose the identical TypeScript surface; only the
13
+ > emitted Tailwind class strings differ. See the [package README](../../README.md) for install
14
+ > steps, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
15
+
16
+ ## Installation
8
17
 
9
18
  ```bash
10
- ng generate component component-name
19
+ # Plain Tailwind (no prefix)
20
+ npm install @egose/shadcn-theme-ng
21
+
22
+ # tw:-prefixed Tailwind variant
23
+ npm install @egose/shadcn-theme-ng-tw
11
24
  ```
12
25
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
26
+ Peer dependencies (Angular, `@spartan-ng/brain`, `@ng-icons/*`, `rxjs`, …) are documented in the
27
+ [package README](../../README.md#peer-dependencies). This subpath has no extra runtime component
28
+ dependencies beyond `@egose/shadcn-theme-ng/utils`.
14
29
 
15
- ```bash
16
- ng generate --help
30
+ ## Imports
31
+
32
+ Exported from the subpath root (`projects/form-field-simple/src/public-api.ts`). Note: this subpath
33
+ exports a single standalone component — there is no `*Imports` array or `*Module`:
34
+
35
+ ```ts
36
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
37
+ // tw variant: replace with '@egose/shadcn-theme-ng-tw/form-field-simple'
17
38
  ```
18
39
 
19
- ## Building
40
+ Standalone usage:
20
41
 
21
- To build the library, run:
42
+ ```ts
43
+ import { Component } from '@angular/core';
44
+ import { ReactiveFormsModule } from '@angular/forms';
45
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
46
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
22
47
 
23
- ```bash
24
- ng build form-field-simple
48
+ @Component({
49
+ selector: 'app-demo',
50
+ standalone: true,
51
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint],
52
+ template: `...`,
53
+ })
54
+ export class DemoComponent {}
25
55
  ```
26
56
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
57
+ NgModule-based consumer: add `EgFormField` (and `ReactiveFormsModule`) to the module's `imports`.
28
58
 
29
- ### Publishing the Library
59
+ `ControlValueAccessor` behavior: `eg-form-field` is not a form control and implements no
60
+ `ControlValueAccessor` — the projected control (e.g. `input[formControlName]`, `hlm-checkbox`,
61
+ `hlm-select`) owns the value. The wrapper only observes `FormControlName.control.errors`,
62
+ `touched`, and `dirty` to decide which message to project.
30
63
 
31
- Once the project is built, you can publish your library by following these steps:
64
+ ## Anatomy / Structure
32
65
 
33
- 1. Navigate to the `dist` directory:
66
+ ```html
67
+ <form [formGroup]="form">
68
+ <eg-form-field>
69
+ <label hlmLabel for="email">Email</label>
70
+ <input hlmInput id="email" formControlName="email" />
71
+ <hlm-hint>We'll never share your email.</hlm-hint>
72
+ <hlm-error>Email is required.</hlm-error>
73
+ </eg-form-field>
74
+ </form>
75
+ ```
34
76
 
35
- ```bash
36
- cd dist/form-field-simple
37
- ```
77
+ Selector (from source): `eg-form-field` (standalone component).
38
78
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
79
+ Template (from source):
43
80
 
44
- ## Running unit tests
81
+ ```html
82
+ <ng-content></ng-content>
45
83
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
84
+ @if (hasError()) {
85
+ <ng-content select="hlm-error"></ng-content>
86
+ } @else {
87
+ <ng-content select="hlm-hint"></ng-content>
88
+ }
89
+ ```
47
90
 
48
- ```bash
49
- ng test
91
+ ## API reference
92
+
93
+ ### `EgFormField` — `eg-form-field`
94
+
95
+ | Input | Type | Default | Description |
96
+ | ------- | ------------ | ------- | ----------------------------------- |
97
+ | `class` | `ClassValue` | `''` | Extra host classes (base is empty). |
98
+
99
+ | Member | Type | Description |
100
+ | --------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
101
+ | `control` | `contentChild(FormControlName)` | The projected form-control directive. No control → `hasError` is always `false` (hint shows). |
102
+ | `form` | `FormGroup` | Parent group from injected `FormGroupDirective`. |
103
+ | `hasError` | `computed boolean` | `true` when `control.errors` is non-empty and the control is `touched` or `dirty` (subscribes to `statusChanges`). |
104
+ | `firstErrorKey` | `computed string \| null` | First key of `control.errors` (e.g. `'required'`), or `null`. Useful for per-key messages. |
105
+
106
+ Lifecycle: subscribes to `statusChanges` in `ngAfterContentInit`, unsubscribes in `ngOnDestroy`.
107
+
108
+ ## Examples
109
+
110
+ ### 1. Basic input with hint/error
111
+
112
+ ```ts
113
+ import { Component, inject } from '@angular/core';
114
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
115
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
116
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
117
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
118
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
119
+
120
+ @Component({
121
+ selector: 'app-simple-basic',
122
+ standalone: true,
123
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmLabel, HlmInput],
124
+ template: `
125
+ <form [formGroup]="form">
126
+ <eg-form-field>
127
+ <label hlmLabel for="name">Name</label>
128
+ <input hlmInput id="name" formControlName="name" placeholder="Ada" />
129
+ <hlm-hint>Your public display name.</hlm-hint>
130
+ <hlm-error>Name is required.</hlm-error>
131
+ </eg-form-field>
132
+ </form>
133
+ `,
134
+ })
135
+ export class SimpleBasicComponent {
136
+ private readonly fb = inject(FormBuilder);
137
+ readonly form = this.fb.group({ name: ['', Validators.required] });
138
+ }
50
139
  ```
51
140
 
52
- ## Running end-to-end tests
141
+ ### 2. Per-validator messages with `firstErrorKey`
53
142
 
54
- For end-to-end (e2e) testing, run:
143
+ ```ts
144
+ import { Component, inject, viewChild } from '@angular/core';
145
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
146
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
147
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
148
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
149
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
55
150
 
56
- ```bash
57
- ng e2e
151
+ @Component({
152
+ selector: 'app-per-key',
153
+ standalone: true,
154
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmLabel, HlmInput],
155
+ template: `
156
+ <form [formGroup]="form">
157
+ <eg-form-field #wrapper>
158
+ <label hlmLabel for="email">Email</label>
159
+ <input hlmInput id="email" type="email" formControlName="email" />
160
+ <hlm-hint>We'll send the receipt here.</hlm-hint>
161
+ <hlm-error>
162
+ @if (wrapper.firstErrorKey() === 'required') {
163
+ Email is required.
164
+ } @else if (wrapper.firstErrorKey() === 'email') {
165
+ Enter a valid email address.
166
+ } @else {
167
+ This field is invalid.
168
+ }
169
+ </hlm-error>
170
+ </eg-form-field>
171
+ </form>
172
+ `,
173
+ })
174
+ export class PerKeyComponent {
175
+ private readonly fb = inject(FormBuilder);
176
+ readonly field = viewChild(EgFormField);
177
+ readonly form = this.fb.group({ email: ['', [Validators.required, Validators.email]] });
178
+ }
58
179
  ```
59
180
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
181
+ ### 3. Template-driven-style submit gating
182
+
183
+ ```ts
184
+ import { Component, inject } from '@angular/core';
185
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
186
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
187
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
188
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
189
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
190
+
191
+ @Component({
192
+ selector: 'app-submit-gate',
193
+ standalone: true,
194
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmLabel, HlmInput],
195
+ template: `
196
+ <form [formGroup]="form" (ngSubmit)="submit()">
197
+ <eg-form-field>
198
+ <label hlmLabel for="password">Password</label>
199
+ <input hlmInput id="password" type="password" formControlName="password" />
200
+ <hlm-hint>At least 8 characters.</hlm-hint>
201
+ <hlm-error>Password must be at least 8 characters.</hlm-error>
202
+ </eg-form-field>
203
+ <button type="submit">Sign in</button>
204
+ </form>
205
+ `,
206
+ })
207
+ export class SubmitGateComponent {
208
+ private readonly fb = inject(FormBuilder);
209
+ readonly form = this.fb.group({ password: ['', [Validators.required, Validators.minLength(8)]] });
210
+ submit() {
211
+ this.form.markAllAsTouched();
212
+ if (this.form.valid) console.log('signing in…');
213
+ }
214
+ }
215
+ ```
216
+
217
+ ### 4. Checkbox row (used by `eg-form-checkbox` internally)
218
+
219
+ ```ts
220
+ import { Component, inject } from '@angular/core';
221
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
222
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
223
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
224
+ import { HlmCheckbox } from '@egose/shadcn-theme-ng/checkbox';
225
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
226
+
227
+ @Component({
228
+ selector: 'app-simple-check',
229
+ standalone: true,
230
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmCheckbox, HlmLabel],
231
+ template: `
232
+ <form [formGroup]="form">
233
+ <eg-form-field>
234
+ <div class="tw:flex tw:items-center tw:gap-2">
235
+ <hlm-checkbox id="tos" formControlName="tos" />
236
+ <label hlmLabel for="tos">I agree to the terms</label>
237
+ </div>
238
+ <hlm-hint>You can withdraw consent anytime.</hlm-hint>
239
+ <hlm-error>You must agree to continue.</hlm-error>
240
+ </eg-form-field>
241
+ </form>
242
+ `,
243
+ })
244
+ export class SimpleCheckComponent {
245
+ private readonly fb = inject(FormBuilder);
246
+ readonly form = this.fb.group({ tos: [false, Validators.requiredTrue] });
247
+ }
248
+ ```
249
+
250
+ ### 5. Select + async options
251
+
252
+ ```ts
253
+ import { Component, inject, signal } from '@angular/core';
254
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
255
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
256
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
257
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
258
+ import { HlmSelectImports } from '@egose/shadcn-theme-ng/select';
259
+
260
+ @Component({
261
+ selector: 'app-simple-select',
262
+ standalone: true,
263
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmLabel, ...HlmSelectImports],
264
+ template: `
265
+ <form [formGroup]="form">
266
+ <eg-form-field>
267
+ <label hlmLabel>Country</label>
268
+ <hlm-select formControlName="country" placeholder="Select a country">
269
+ <hlm-select-content>
270
+ @if (!countries().length) {
271
+ <hlm-select-item value="" disabled>Loading…</hlm-select-item>
272
+ }
273
+ @for (c of countries(); track c) {
274
+ <hlm-select-item [value]="c">{{ c }}</hlm-select-item>
275
+ }
276
+ </hlm-select-content>
277
+ </hlm-select>
278
+ <hlm-hint>Used for shipping estimates.</hlm-hint>
279
+ <hlm-error>Pick a country.</hlm-error>
280
+ </eg-form-field>
281
+ </form>
282
+ `,
283
+ })
284
+ export class SimpleSelectComponent {
285
+ private readonly fb = inject(FormBuilder);
286
+ readonly form = this.fb.group({ country: ['', Validators.required] });
287
+ readonly countries = signal<string[]>([]);
288
+ constructor() {
289
+ setTimeout(() => this.countries.set(['Germany', 'France', 'Japan']), 500);
290
+ }
291
+ }
292
+ ```
293
+
294
+ ### 6. Custom host styling + textarea
295
+
296
+ ```ts
297
+ import { Component, inject } from '@angular/core';
298
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
299
+ import { EgFormField } from '@egose/shadcn-theme-ng/form-field-simple';
300
+ import { HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
301
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
302
+ import { HlmTextarea } from '@egose/shadcn-theme-ng/textarea';
303
+
304
+ @Component({
305
+ selector: 'app-simple-area',
306
+ standalone: true,
307
+ imports: [ReactiveFormsModule, EgFormField, HlmError, HlmHint, HlmLabel, HlmTextarea],
308
+ template: `
309
+ <form [formGroup]="form">
310
+ <eg-form-field class="tw:rounded-lg tw:border tw:p-4">
311
+ <label hlmLabel for="notes">Notes</label>
312
+ <textarea hlmTextarea id="notes" formControlName="notes" rows="3"></textarea>
313
+ <hlm-hint>Optional context for the reviewer.</hlm-hint>
314
+ <hlm-error>Notes are required for this step.</hlm-error>
315
+ </eg-form-field>
316
+ </form>
317
+ `,
318
+ })
319
+ export class SimpleAreaComponent {
320
+ private readonly fb = inject(FormBuilder);
321
+ readonly form = this.fb.group({ notes: ['', Validators.required] });
322
+ }
323
+ ```
324
+
325
+ ## Accessibility notes
326
+
327
+ - Errors only appear after the control is `touched` or `dirty`, so screen-reader users are not spammed on load; call `markAllAsTouched()` on submit to reveal outstanding errors.
328
+ - The wrapper adds no label itself — always include a `<label>` (or `aria-label`) so the field has an accessible name.
329
+ - Only one of `hlm-error` / `hlm-hint` is in the DOM at a time, keeping `aria-describedby` targets unambiguous when you wire ids.
330
+ - `firstErrorKey` lets you render a single assertive message per failure instead of stacking multiple errors.
331
+
332
+ ## Theming / CSS variables
333
+
334
+ No component-specific CSS variables and no base host classes — layout comes from your content plus `class`. Pair with `hlm-error` / `hlm-hint` styling from `@egose/shadcn-theme-ng/form-field`.
61
335
 
62
- ## Additional Resources
336
+ ## Related subpaths
63
337
 
64
- For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
338
+ - `@egose/shadcn-theme-ng/form-field` — `hlm-form-field` with brain `BrnField` state (stricter, throws without a field control).
339
+ - `@egose/shadcn-theme-ng/form-checkbox` — ready-made checkbox row built on `eg-form-field`.
340
+ - `@egose/shadcn-theme-ng/label` — `HlmLabel` for field labels.
341
+ - `@egose/shadcn-theme-ng/input`, `.../textarea`, `.../select` — controls to project inside the wrapper.
@@ -43,8 +43,8 @@ class EgFormField {
43
43
  return Object.keys(ctrlDir.control.errors)[0] ?? null;
44
44
  }, /* @ts-ignore */
45
45
  ...(ngDevMode ? [{ debugName: "firstErrorKey" }] : /* istanbul ignore next */ []));
46
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: EgFormField, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: EgFormField, isStandalone: true, selector: "eg-form-field", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], queries: [{ propertyName: "control", first: true, predicate: FormControlName, descendants: true, isSignal: true }], ngImport: i0, template: `
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormField, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormField, isStandalone: true, selector: "eg-form-field", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], queries: [{ propertyName: "control", first: true, predicate: FormControlName, descendants: true, isSignal: true }], ngImport: i0, template: `
48
48
  <ng-content></ng-content>
49
49
 
50
50
  @if (hasError()) {
@@ -54,7 +54,7 @@ class EgFormField {
54
54
  }
55
55
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
56
56
  }
57
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: EgFormField, decorators: [{
57
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormField, decorators: [{
58
58
  type: Component,
59
59
  args: [{
60
60
  selector: 'eg-form-field',
@@ -84,4 +84,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
84
84
  */
85
85
 
86
86
  export { EgFormField };
87
- //# sourceMappingURL=form-field-simple.mjs.map
87
+