@egose/shadcn-theme-ng 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 (237) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +27 -39
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +47 -47
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +47 -47
  8. package/aspect-ratio/README.md +272 -5
  9. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  10. package/autocomplete/README.md +473 -34
  11. package/autocomplete/fesm2022/autocomplete.mjs +53 -71
  12. package/avatar/README.md +357 -5
  13. package/avatar/fesm2022/avatar.mjs +32 -32
  14. package/badge/README.md +289 -34
  15. package/badge/fesm2022/badge.mjs +57 -57
  16. package/basic-alert/README.md +324 -34
  17. package/basic-alert/fesm2022/basic-alert.mjs +6 -18
  18. package/breadcrumb/README.md +406 -5
  19. package/breadcrumb/fesm2022/breadcrumb.mjs +33 -39
  20. package/button/README.md +453 -34
  21. package/button/fesm2022/button.mjs +147 -219
  22. package/button/types/button.d.ts +7 -10
  23. package/button-group/README.md +318 -5
  24. package/button-group/fesm2022/button-group.mjs +20 -20
  25. package/calendar/README.md +328 -34
  26. package/calendar/fesm2022/calendar.mjs +29 -743
  27. package/card/README.md +331 -5
  28. package/card/fesm2022/card.mjs +33 -33
  29. package/carousel/README.md +333 -5
  30. package/carousel/fesm2022/carousel.mjs +39 -78
  31. package/checkbox/README.md +291 -34
  32. package/checkbox/fesm2022/checkbox.mjs +20 -58
  33. package/checkbox/types/checkbox.d.ts +5 -4
  34. package/collapsible/README.md +332 -5
  35. package/collapsible/fesm2022/collapsible.mjs +15 -15
  36. package/combobox/README.md +507 -5
  37. package/combobox/fesm2022/combobox.mjs +91 -224
  38. package/command/README.md +435 -5
  39. package/command/fesm2022/command.mjs +49 -109
  40. package/confirmation-dialog/README.md +272 -34
  41. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +15 -40
  42. package/confirmation-dialog/types/confirmation-dialog.d.ts +8 -4
  43. package/context-menu/README.md +366 -5
  44. package/context-menu/fesm2022/context-menu.mjs +9 -9
  45. package/date-picker/README.md +436 -34
  46. package/date-picker/fesm2022/date-picker.mjs +64 -267
  47. package/date-picker/types/date-picker.d.ts +7 -3
  48. package/dialog/README.md +419 -34
  49. package/dialog/fesm2022/dialog.mjs +45 -71
  50. package/drawer/README.md +395 -5
  51. package/drawer/fesm2022/drawer.mjs +44 -54
  52. package/dropdown-menu/README.md +417 -5
  53. package/dropdown-menu/fesm2022/dropdown-menu.mjs +82 -70
  54. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  55. package/empty/README.md +329 -5
  56. package/empty/fesm2022/empty.mjs +30 -30
  57. package/field/README.md +385 -5
  58. package/field/fesm2022/field.mjs +56 -72
  59. package/form-checkbox/README.md +283 -34
  60. package/form-checkbox/fesm2022/form-checkbox.mjs +25 -85
  61. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  62. package/form-date-picker/README.md +293 -34
  63. package/form-date-picker/fesm2022/form-date-picker.mjs +31 -84
  64. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  65. package/form-field/README.md +327 -34
  66. package/form-field/fesm2022/form-field.mjs +33 -19
  67. package/form-field/types/form-field.d.ts +28 -20
  68. package/form-field-simple/README.md +311 -34
  69. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  70. package/form-searchable-multiselect/README.md +332 -34
  71. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +31 -91
  72. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +7 -1
  73. package/form-select/README.md +321 -34
  74. package/form-select/fesm2022/form-select.mjs +32 -149
  75. package/form-select/types/form-select.d.ts +7 -1
  76. package/form-text-input/README.md +342 -34
  77. package/form-text-input/fesm2022/form-text-input.mjs +35 -149
  78. package/form-text-input/types/form-text-input.d.ts +9 -12
  79. package/form-textarea/README.md +318 -34
  80. package/form-textarea/fesm2022/form-textarea.mjs +34 -109
  81. package/form-textarea/types/form-textarea.d.ts +8 -1
  82. package/hover-card/README.md +256 -5
  83. package/hover-card/fesm2022/hover-card.mjs +19 -19
  84. package/icon/README.md +210 -34
  85. package/icon/fesm2022/icon.mjs +8 -8
  86. package/input/README.md +240 -34
  87. package/input/fesm2022/input.mjs +17 -12
  88. package/input/types/input.d.ts +2 -1
  89. package/input-group/README.md +335 -5
  90. package/input-group/fesm2022/input-group.mjs +34 -34
  91. package/input-otp/README.md +375 -5
  92. package/input-otp/fesm2022/input-otp.mjs +26 -26
  93. package/item/README.md +385 -5
  94. package/item/fesm2022/item.mjs +53 -53
  95. package/kbd/README.md +291 -5
  96. package/kbd/fesm2022/kbd.mjs +12 -12
  97. package/label/README.md +243 -34
  98. package/label/fesm2022/label.mjs +10 -10
  99. package/label/types/label.d.ts +1 -1
  100. package/layout-simple/README.md +174 -44
  101. package/layout-simple/fesm2022/layout-simple.mjs +508 -603
  102. package/layout-simple/types/layout-simple.d.ts +179 -128
  103. package/menu/README.md +418 -0
  104. package/menu/fesm2022/menu.mjs +455 -0
  105. package/menu/package.json +24 -0
  106. package/menu/types/menu.d.ts +137 -0
  107. package/menubar/README.md +343 -5
  108. package/menubar/fesm2022/menubar.mjs +13 -13
  109. package/native-select/README.md +323 -5
  110. package/native-select/fesm2022/native-select.mjs +19 -19
  111. package/navigation-menu/README.md +369 -5
  112. package/navigation-menu/fesm2022/navigation-menu.mjs +35 -47
  113. package/package.json +183 -154
  114. package/pagination/README.md +388 -5
  115. package/pagination/fesm2022/pagination.mjs +45 -331
  116. package/popover/README.md +302 -34
  117. package/popover/fesm2022/popover.mjs +30 -30
  118. package/progress/README.md +311 -5
  119. package/progress/fesm2022/progress.mjs +13 -13
  120. package/radio-group/README.md +335 -34
  121. package/radio-group/fesm2022/radio-group.mjs +26 -19
  122. package/radio-group/types/radio-group.d.ts +1 -1
  123. package/resizable/README.md +269 -5
  124. package/resizable/fesm2022/resizable.mjs +18 -26
  125. package/scroll-area/README.md +233 -5
  126. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  127. package/searchable-multiselect/README.md +294 -34
  128. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +28 -117
  129. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  130. package/select/README.md +408 -34
  131. package/select/fesm2022/select.mjs +71 -111
  132. package/select/types/select.d.ts +3 -1
  133. package/separator/README.md +193 -34
  134. package/separator/fesm2022/separator.mjs +9 -9
  135. package/separator/types/separator.d.ts +1 -1
  136. package/sheet/README.md +282 -34
  137. package/sheet/fesm2022/sheet.mjs +41 -53
  138. package/sidebar/README.md +457 -5
  139. package/sidebar/fesm2022/sidebar.mjs +125 -227
  140. package/skeleton/README.md +217 -5
  141. package/skeleton/fesm2022/skeleton.mjs +9 -9
  142. package/slider/README.md +273 -5
  143. package/slider/fesm2022/slider.mjs +10 -80
  144. package/sonner/README.md +317 -34
  145. package/sonner/fesm2022/sonner.mjs +13 -13
  146. package/spinner/README.md +255 -34
  147. package/spinner/fesm2022/spinner.mjs +11 -11
  148. package/switch/README.md +281 -34
  149. package/switch/fesm2022/switch.mjs +13 -15
  150. package/table/README.md +423 -5
  151. package/table/fesm2022/table.mjs +41 -41
  152. package/tabs/README.md +382 -34
  153. package/tabs/fesm2022/tabs.mjs +35 -111
  154. package/textarea/README.md +282 -5
  155. package/textarea/fesm2022/textarea.mjs +9 -9
  156. package/toggle/README.md +270 -5
  157. package/toggle/fesm2022/toggle.mjs +13 -13
  158. package/toggle-group/README.md +340 -5
  159. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  160. package/toggle-group/types/toggle-group.d.ts +13 -7
  161. package/tooltip/README.md +240 -34
  162. package/tooltip/fesm2022/tooltip.mjs +14 -14
  163. package/typography/README.md +271 -5
  164. package/typography/fesm2022/typography.mjs +53 -53
  165. package/typography/types/typography.d.ts +19 -19
  166. package/utils/README.md +274 -34
  167. package/utils/fesm2022/utils.mjs +68 -44
  168. package/accordion/fesm2022/accordion.mjs.map +0 -1
  169. package/alert/fesm2022/alert.mjs.map +0 -1
  170. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  171. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  172. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  173. package/avatar/fesm2022/avatar.mjs.map +0 -1
  174. package/badge/fesm2022/badge.mjs.map +0 -1
  175. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  176. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  177. package/button/fesm2022/button.mjs.map +0 -1
  178. package/button-group/fesm2022/button-group.mjs.map +0 -1
  179. package/calendar/fesm2022/calendar.mjs.map +0 -1
  180. package/card/fesm2022/card.mjs.map +0 -1
  181. package/carousel/fesm2022/carousel.mjs.map +0 -1
  182. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  183. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  184. package/combobox/fesm2022/combobox.mjs.map +0 -1
  185. package/command/fesm2022/command.mjs.map +0 -1
  186. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  187. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  188. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  189. package/dialog/fesm2022/dialog.mjs.map +0 -1
  190. package/drawer/fesm2022/drawer.mjs.map +0 -1
  191. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  192. package/empty/fesm2022/empty.mjs.map +0 -1
  193. package/field/fesm2022/field.mjs.map +0 -1
  194. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  195. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  196. package/form-field/fesm2022/form-field.mjs.map +0 -1
  197. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  198. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  199. package/form-select/fesm2022/form-select.mjs.map +0 -1
  200. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  201. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  202. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  203. package/icon/fesm2022/icon.mjs.map +0 -1
  204. package/input/fesm2022/input.mjs.map +0 -1
  205. package/input-group/fesm2022/input-group.mjs.map +0 -1
  206. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  207. package/item/fesm2022/item.mjs.map +0 -1
  208. package/kbd/fesm2022/kbd.mjs.map +0 -1
  209. package/label/fesm2022/label.mjs.map +0 -1
  210. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  211. package/menubar/fesm2022/menubar.mjs.map +0 -1
  212. package/native-select/fesm2022/native-select.mjs.map +0 -1
  213. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  214. package/pagination/fesm2022/pagination.mjs.map +0 -1
  215. package/popover/fesm2022/popover.mjs.map +0 -1
  216. package/progress/fesm2022/progress.mjs.map +0 -1
  217. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  218. package/resizable/fesm2022/resizable.mjs.map +0 -1
  219. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  220. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  221. package/select/fesm2022/select.mjs.map +0 -1
  222. package/separator/fesm2022/separator.mjs.map +0 -1
  223. package/sheet/fesm2022/sheet.mjs.map +0 -1
  224. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  225. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  226. package/slider/fesm2022/slider.mjs.map +0 -1
  227. package/sonner/fesm2022/sonner.mjs.map +0 -1
  228. package/spinner/fesm2022/spinner.mjs.map +0 -1
  229. package/switch/fesm2022/switch.mjs.map +0 -1
  230. package/table/fesm2022/table.mjs.map +0 -1
  231. package/tabs/fesm2022/tabs.mjs.map +0 -1
  232. package/textarea/fesm2022/textarea.mjs.map +0 -1
  233. package/toggle/fesm2022/toggle.mjs.map +0 -1
  234. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  235. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  236. package/typography/fesm2022/typography.mjs.map +0 -1
  237. package/utils/fesm2022/utils.mjs.map +0 -1
@@ -1,64 +1,365 @@
1
- # RadioGroup
1
+ # Radio Group (`@egose/shadcn-theme-ng/radio-group`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.2.0.
3
+ A shadcn/ui-style **Radio Group** for Angular — a set of mutually exclusive options where exactly one can be selected. This is the Angular equivalent of shadcn/ui `RadioGroup` / `RadioGroupItem`.
4
4
 
5
- ## Code scaffolding
5
+ The primitives come from **spartan-ng/brain** (`BrnRadioGroup`, `BrnRadio`, `BrnFieldControlDescribedBy`): keyboard navigation (arrow keys), roving tabindex, and form integration are handled by `BrnRadioGroup`/`BrnRadio`, while this package adds the shadcn look (grid layout, circular indicator, focus ring, error styling).
6
6
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
7
+ > **Ships as:** `@egose/shadcn-theme-ng/radio-group` and `@egose/shadcn-theme-ng-tw/radio-group` (the `tw:`-prefixed Tailwind variant — same API, class strings prefixed with `tw:`).
8
+ > See the [package README](../../README.md) for installation, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
9
+
10
+ ## Installation
8
11
 
9
12
  ```bash
10
- ng generate component component-name
13
+ # Plain Tailwind (no prefix)
14
+ npm install @egose/shadcn-theme-ng
15
+
16
+ # Or the tw:-prefixed variant
17
+ npm install @egose/shadcn-theme-ng-tw
11
18
  ```
12
19
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
20
+ Import from the subpath (not the package root):
14
21
 
15
- ```bash
16
- ng generate --help
22
+ ```ts
23
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
24
+ // tw variant:
25
+ // import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng-tw/radio-group';
17
26
  ```
18
27
 
19
- ## Building
28
+ Peer dependencies (see [package README](../../README.md) for versions): `@angular/core`, `@angular/common`, `@spartan-ng/brain`. `@angular/cdk` is required transitively by `HlmRadio` (boolean coercion).
20
29
 
21
- To build the library, run:
30
+ ## Imports
22
31
 
23
- ```bash
24
- ng build radio-group
32
+ Real exported symbols (from `src/public-api.ts`):
33
+
34
+ | Symbol | Kind | Description |
35
+ | ---------------------- | ------------- | ----------------------------------------------------------------- |
36
+ | `HlmRadioGroup` | Directive | Group container; forwards `BrnRadioGroup` |
37
+ | `HlmRadio` | Component | Single radio item (`hlm-radio`), wraps `BrnRadio` |
38
+ | `HlmRadioIndicator` | Component | Circular visual indicator dot |
39
+ | `HlmRadioGroupImports` | `const` array | `[HlmRadioGroup, HlmRadio, HlmRadioIndicator]` standalone imports |
40
+ | `HlmRadioGroupModule` | `NgModule` | NgModule wrapper re-exporting the three above |
41
+
42
+ Standalone usage:
43
+
44
+ ```ts
45
+ import { Component } from '@angular/core';
46
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
47
+
48
+ @Component({
49
+ selector: 'app-demo',
50
+ standalone: true,
51
+ imports: [HlmRadioGroupImports],
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 usage:
28
58
 
29
- ### Publishing the Library
59
+ ```ts
60
+ import { NgModule } from '@angular/core';
61
+ import { HlmRadioGroupModule } from '@egose/shadcn-theme-ng/radio-group';
30
62
 
31
- Once the project is built, you can publish your library by following these steps:
63
+ @NgModule({ imports: [HlmRadioGroupModule] })
64
+ export class DemoModule {}
65
+ ```
66
+
67
+ You can also import the pieces individually (`import { HlmRadioGroup, HlmRadio, HlmRadioIndicator } from '...'`).
32
68
 
33
- 1. Navigate to the `dist` directory:
69
+ ## Anatomy / Structure
34
70
 
35
- ```bash
36
- cd dist/radio-group
37
- ```
71
+ ```html
72
+ <!-- Attribute form on a div -->
73
+ <div hlmRadioGroup name="plan" [value]="plan()" (valueChange)="plan.set($event)">
74
+ <hlm-radio value="free" inputId="plan-free">
75
+ <hlm-radio-indicator />
76
+ Free
77
+ </hlm-radio>
38
78
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
79
+ <hlm-radio value="pro" inputId="plan-pro">
80
+ <hlm-radio-indicator />
81
+ Pro
82
+ </hlm-radio>
83
+ </div>
43
84
 
44
- ## Running unit tests
85
+ <!-- Element form also works -->
86
+ <hlm-radio-group name="plan">
87
+ <hlm-radio value="free"><hlm-radio-indicator />Free</hlm-radio>
88
+ </hlm-radio-group>
89
+ ```
45
90
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
91
+ Real selectors:
47
92
 
48
- ```bash
49
- ng test
93
+ | Selector | Class | Notes |
94
+ | ------------------------------------ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
95
+ | `[hlmRadioGroup]`, `hlm-radio-group` | `HlmRadioGroup` | Group host; `data-slot="radio-group"` |
96
+ | `hlm-radio` | `HlmRadio<T>` | Item host; `data-slot="radio-group-item"`; projects `[target],[indicator],hlm-radio-indicator` into the indicator slot, everything else as label content |
97
+ | `hlm-radio-indicator` | `HlmRadioIndicator` | Visual dot; `data-slot="radio-group-indicator"` |
98
+
99
+ ## API reference
100
+
101
+ ### HlmRadioGroup (directive)
102
+
103
+ Thin directive wrapper over `BrnRadioGroup` (plus `BrnFieldControlDescribedBy` for form-field `aria-describedby` wiring). Own inputs:
104
+
105
+ | Input | Type | Default | Description |
106
+ | --------------------- | ------------ | ------- | -------------------------------------------- |
107
+ | `class` (`userClass`) | `ClassValue` | `''` | Extra classes appended to `tw:grid tw:gap-3` |
108
+
109
+ Forwarded `BrnRadioGroup` host-directive bindings:
110
+
111
+ | Binding | Kind | Description |
112
+ | ------------- | ------ | ---------------------------------------- |
113
+ | `name` | input | Radio group name (native input grouping) |
114
+ | `value` | input | Currently selected value |
115
+ | `disabled` | input | Disables the whole group |
116
+ | `required` | input | Marks the group as required |
117
+ | `valueChange` | output | Emits the newly selected value |
118
+
119
+ The host also reflects form state as attributes: `aria-invalid`/`data-invalid` when the bound control is invalid, plus `data-dirty` and `data-touched`.
120
+
121
+ ### HlmRadio\<T\> (component)
122
+
123
+ | Input | Type | Default | Description |
124
+ | -------------------------------------- | --------------------- | ------------ | -------------------------------------------------------------------------------------------------- |
125
+ | `value` | `T` | **required** | The value this item represents |
126
+ | `inputId` | `string \| undefined` | `undefined` | `id` placed on the underlying `brn-radio` element; also used to find an associated `<label [for]>` |
127
+ | `aria-label` (`ariaLabel`) | `string \| undefined` | `undefined` | Accessible name when there is no visible label |
128
+ | `aria-labelledby` (`ariaLabelledby`) | `string \| undefined` | `undefined` | Id(s) of labelling element(s) |
129
+ | `aria-describedby` (`ariaDescribedby`) | `string \| undefined` | `undefined` | Id(s) of describing element(s) |
130
+ | `required` | `boolean` | `false` | Native required flag (boolean-coerced) |
131
+ | `disabled` | `boolean` | `false` | Disables this item (boolean-coerced); mirrors `data-disabled` onto an associated `<label>` |
132
+ | `class` (`userClass`) | `ClassValue` | `''` | Extra classes |
133
+
134
+ | Output | Type | Description |
135
+ | -------- | ------------------- | ---------------------------------------------- |
136
+ | `change` | `BrnRadioChange<T>` | Emitted when this item's checked state changes |
137
+
138
+ Label association detail: on init the component looks for `closest('label')`, falling back to `document.querySelector('label[for=inputId]')`, and mirrors `data-disabled="true"/"false"` onto that label so label styling follows the disabled state. IDs containing special characters (e.g. quotes/brackets) are matched safely via `htmlFor` comparison, not a CSS selector.
139
+
140
+ ### HlmRadioIndicator (component)
141
+
142
+ No inputs/outputs. Renders the styled outer circle; the inner dot fills via `group-data-[checked=true]` when the parent `brn-radio` reports checked. Always place it inside `hlm-radio` (it matches the `hlm-radio-indicator` content slot).
143
+
144
+ ## Examples
145
+
146
+ ### 1. Basic usage
147
+
148
+ ```ts
149
+ import { Component, signal } from '@angular/core';
150
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
151
+
152
+ @Component({
153
+ selector: 'app-basic-radio',
154
+ standalone: true,
155
+ imports: [HlmRadioGroupImports],
156
+ template: `
157
+ <div hlmRadioGroup name="fruit" [value]="fruit()" (valueChange)="fruit.set($event)">
158
+ <hlm-radio value="apple" inputId="fruit-apple">
159
+ <hlm-radio-indicator />
160
+ Apple
161
+ </hlm-radio>
162
+ <hlm-radio value="banana" inputId="fruit-banana">
163
+ <hlm-radio-indicator />
164
+ Banana
165
+ </hlm-radio>
166
+ <hlm-radio value="orange" inputId="fruit-orange">
167
+ <hlm-radio-indicator />
168
+ Orange
169
+ </hlm-radio>
170
+ </div>
171
+ <p>Selected: {{ fruit() }}</p>
172
+ `,
173
+ })
174
+ export class BasicRadioComponent {
175
+ readonly fruit = signal('apple');
176
+ }
50
177
  ```
51
178
 
52
- ## Running end-to-end tests
179
+ ### 2. Element selector form + external labels
53
180
 
54
- For end-to-end (e2e) testing, run:
181
+ `hlm-radio-group` works as an element, and labels can live outside the item via `for`/`inputId`:
55
182
 
56
- ```bash
57
- ng e2e
183
+ ```ts
184
+ import { Component, signal } from '@angular/core';
185
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
186
+
187
+ @Component({
188
+ selector: 'app-labelled-radio',
189
+ standalone: true,
190
+ imports: [HlmRadioGroupImports],
191
+ template: `
192
+ <hlm-radio-group name="contact">
193
+ <label for="c-email">Email me</label>
194
+ <hlm-radio value="email" inputId="c-email"><hlm-radio-indicator /></hlm-radio>
195
+
196
+ <label for="c-sms">Text me</label>
197
+ <hlm-radio value="sms" inputId="c-sms"><hlm-radio-indicator /></hlm-radio>
198
+ </hlm-radio-group>
199
+ `,
200
+ })
201
+ export class LabelledRadioComponent {}
202
+ ```
203
+
204
+ Wrapping the item in a `<label>` also works — the item finds it with `closest('label')`:
205
+
206
+ ```html
207
+ <hlm-radio-group name="contact">
208
+ <label>
209
+ <hlm-radio value="email"><hlm-radio-indicator /></hlm-radio>
210
+ Email me
211
+ </label>
212
+ </hlm-radio-group>
213
+ ```
214
+
215
+ ### 3. Reactive forms
216
+
217
+ `BrnRadioGroup` is a `ControlValueAccessor`, so `formControlName`/`formControl` bind on the group host:
218
+
219
+ ```ts
220
+ import { Component } from '@angular/core';
221
+ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
222
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
223
+
224
+ @Component({
225
+ selector: 'app-reactive-radio',
226
+ standalone: true,
227
+ imports: [HlmRadioGroupImports, ReactiveFormsModule],
228
+ template: `
229
+ <form [formGroup]="form" (ngSubmit)="submit()">
230
+ <div hlmRadioGroup formControlName="plan">
231
+ <hlm-radio value="hobby"><hlm-radio-indicator />Hobby</hlm-radio>
232
+ <hlm-radio value="pro"><hlm-radio-indicator />Pro</hlm-radio>
233
+ <hlm-radio value="enterprise"><hlm-radio-indicator />Enterprise</hlm-radio>
234
+ </div>
235
+ @if (form.controls.plan.invalid && form.controls.plan.touched) {
236
+ <p class="tw:text-destructive tw:text-sm">Please pick a plan.</p>
237
+ }
238
+ <button type="submit">Continue</button>
239
+ </form>
240
+ `,
241
+ })
242
+ export class ReactiveRadioComponent {
243
+ readonly form = new FormGroup({
244
+ plan: new FormControl<string | null>(null, Validators.required),
245
+ });
246
+
247
+ submit(): void {
248
+ this.form.markAllAsTouched();
249
+ console.log(this.form.value);
250
+ }
251
+ }
252
+ ```
253
+
254
+ When the control is invalid + touched, the group automatically gets `data-invalid="true"` (and destructive text styling) via the forwarded control state — no manual class juggling needed.
255
+
256
+ ### 4. Disabled states (group vs item)
257
+
258
+ ```ts
259
+ import { Component, signal } from '@angular/core';
260
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
261
+
262
+ @Component({
263
+ selector: 'app-disabled-radio',
264
+ standalone: true,
265
+ imports: [HlmRadioGroupImports],
266
+ template: `
267
+ <!-- Whole group disabled -->
268
+ <div hlmRadioGroup name="a" value="one" disabled>
269
+ <hlm-radio value="one"><hlm-radio-indicator />One</hlm-radio>
270
+ <hlm-radio value="two"><hlm-radio-indicator />Two</hlm-radio>
271
+ </div>
272
+
273
+ <!-- Single item disabled; its <label> gets data-disabled="true" -->
274
+ <div hlmRadioGroup name="b" [value]="choice()" (valueChange)="choice.set($event)">
275
+ <label for="b-one">One (soon unavailable)</label>
276
+ <hlm-radio value="one" inputId="b-one" disabled><hlm-radio-indicator /></hlm-radio>
277
+ <label for="b-two">Two</label>
278
+ <hlm-radio value="two" inputId="b-two"><hlm-radio-indicator /></hlm-radio>
279
+ </div>
280
+ `,
281
+ })
282
+ export class DisabledRadioComponent {
283
+ readonly choice = signal('two');
284
+ }
58
285
  ```
59
286
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
287
+ ### 5. Per-item change events + typed values
288
+
289
+ `HlmRadio` is generic — `value` can be any type, and `change` emits `BrnRadioChange<T>`:
290
+
291
+ ```ts
292
+ import { Component, signal } from '@angular/core';
293
+ import { HlmRadioGroupImports } from '@egose/shadcn-theme-ng/radio-group';
294
+ import type { BrnRadioChange } from '@spartan-ng/brain/radio-group';
295
+
296
+ interface Tier {
297
+ id: string;
298
+ price: number;
299
+ }
300
+
301
+ @Component({
302
+ selector: 'app-typed-radio',
303
+ standalone: true,
304
+ imports: [HlmRadioGroupImports],
305
+ template: `
306
+ <div hlmRadioGroup name="tier" (valueChange)="onGroupChange($event)">
307
+ @for (tier of tiers; track tier.id) {
308
+ <hlm-radio [value]="tier" (change)="onItemChange($event)">
309
+ <hlm-radio-indicator />
310
+ {{ tier.id }} — ${{ tier.price }}/mo
311
+ </hlm-radio>
312
+ }
313
+ </div>
314
+ `,
315
+ })
316
+ export class TypedRadioComponent {
317
+ readonly tiers: Tier[] = [
318
+ { id: 'starter', price: 0 },
319
+ { id: 'growth', price: 29 },
320
+ ];
321
+
322
+ onGroupChange(value: Tier): void {
323
+ console.log('group selected:', value.id);
324
+ }
325
+
326
+ onItemChange(event: BrnRadioChange<Tier>): void {
327
+ console.log('item checked:', event.value.id, event.checked);
328
+ }
329
+ }
330
+ ```
331
+
332
+ ### 6. Custom indicator content (target slot)
333
+
334
+ Anything projected with `[target]` or `[indicator]` goes into the indicator slot instead of the default label position:
335
+
336
+ ```html
337
+ <div hlmRadioGroup name="layout">
338
+ <hlm-radio value="grid">
339
+ <span target class="tw:flex tw:items-center tw:gap-2">
340
+ <hlm-radio-indicator />
341
+ <strong>Grid</strong>
342
+ </span>
343
+ <span class="tw:text-muted-foreground tw:text-sm">Cards in a grid</span>
344
+ </hlm-radio>
345
+ </div>
346
+ ```
347
+
348
+ ## Accessibility notes
349
+
350
+ - The group uses the native `radiogroup` semantics from `BrnRadioGroup`, including arrow-key navigation and roving tabindex — keep all `hlm-radio` items inside one group container.
351
+ - Always provide `name` so assistive tech (and native form serialization) treats the items as one group.
352
+ - Prefer visible text content inside `hlm-radio`; use `aria-label`/`aria-labelledby` only when the item has no visible label.
353
+ - Disabled items expose `data-disabled` (and the native disabled state on the inner input) and are skipped in keyboard navigation.
354
+ - Invalid form state is announced via `aria-invalid="true"` on the group host.
355
+
356
+ ## Theming / CSS variables
357
+
358
+ Styling is class-driven (no component-specific CSS variables). Override via the `class` input on any of the three pieces; the indicator's checked dot keys off `group-data-[checked=true]`, and the group invalid state off `data-[invalid=true]`.
61
359
 
62
- ## Additional Resources
360
+ ## Related subpaths
63
361
 
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.
362
+ - `@egose/shadcn-theme-ng/label` — labelling radio items and form rows
363
+ - `@egose/shadcn-theme-ng/field` / `form-field` — form rows, descriptions, and error text wired via `BrnFieldControlDescribedBy`
364
+ - `@egose/shadcn-theme-ng/checkbox` — multi-select counterpart
365
+ - `@egose/shadcn-theme-ng/form-field-simple` — lightweight wrapper for reactive-form controls
@@ -24,7 +24,7 @@ class HlmRadio {
24
24
  _errorStateClass = computed(() => (this._groupSpartanInvalid() ? 'text-destructive' : ''), /* @ts-ignore */
25
25
  ...(ngDevMode ? [{ debugName: "_errorStateClass" }] : /* istanbul ignore next */ []));
26
26
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
27
- _computedClass = computed(() => hlm('group relative flex items-center gap-x-3', 'data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50', this.userClass(), this._errorStateClass()), /* @ts-ignore */
27
+ _computedClass = computed(() => hlm("group relative flex items-center gap-x-3", "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50", this.userClass(), this._errorStateClass()), /* @ts-ignore */
28
28
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
29
29
  /** Used to set the id on the underlying brn element. */
30
30
  inputId = input(undefined, /* @ts-ignore */
@@ -54,15 +54,18 @@ class HlmRadio {
54
54
  const isDisabled = this.disabled();
55
55
  if (!this._elementRef.nativeElement || !this._isBrowser)
56
56
  return;
57
+ const inputId = this.inputId();
57
58
  const labelElement = this._elementRef.nativeElement.closest('label') ??
58
- this._document.querySelector(`label[for="${this.inputId()}"]`);
59
+ (inputId
60
+ ? Array.from(this._document.getElementsByTagName('label')).find((label) => label.htmlFor === inputId)
61
+ : undefined);
59
62
  if (!labelElement)
60
63
  return;
61
64
  this._renderer.setAttribute(labelElement, 'data-disabled', isDisabled ? 'true' : 'false');
62
65
  });
63
66
  }
64
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
65
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: HlmRadio, isStandalone: true, selector: "hlm-radio", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { attributes: { "data-slot": "radio-group-item" }, properties: { "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.data-disabled": "disabled() ? \"\" : null" } }, ngImport: i0, template: `
67
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
68
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: HlmRadio, isStandalone: true, selector: "hlm-radio", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { attributes: { "data-slot": "radio-group-item" }, properties: { "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.data-disabled": "disabled() ? \"\" : null" } }, ngImport: i0, template: `
66
69
  <brn-radio
67
70
  [id]="inputId()"
68
71
  [class]="_computedClass()"
@@ -84,7 +87,7 @@ class HlmRadio {
84
87
  </brn-radio>
85
88
  `, isInline: true, dependencies: [{ kind: "component", type: BrnRadio, selector: "brn-radio", inputs: ["disabled", "id", "aria-label", "aria-labelledby", "aria-describedby", "value", "inputStyles", "required"], outputs: ["change"], exportAs: ["brnRadio"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
86
89
  }
87
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadio, decorators: [{
90
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadio, decorators: [{
88
91
  type: Component,
89
92
  args: [{
90
93
  selector: 'hlm-radio',
@@ -133,12 +136,16 @@ class HlmRadioGroup {
133
136
  _errorState = computed(() => this._brnRadioGroup.controlState?.()?.spartanInvalid, /* @ts-ignore */
134
137
  ...(ngDevMode ? [{ debugName: "_errorState" }] : /* istanbul ignore next */ []));
135
138
  constructor() {
136
- classes(() => ['grid gap-3', this.userClass(), this._errorState() ? 'data-[invalid=true]:text-destructive' : '']);
139
+ classes(() => [
140
+ "grid gap-3",
141
+ this.userClass(),
142
+ this._errorState() ? "data-[invalid=true]:text-destructive" : '',
143
+ ]);
137
144
  }
138
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
139
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: HlmRadioGroup, isStandalone: true, selector: "[hlmRadioGroup],hlm-radio-group", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "radio-group" }, properties: { "attr.aria-invalid": "_ariaInvalid() ? \"true\" : null", "attr.data-invalid": "_ariaInvalid() ? \"true\" : null", "attr.data-dirty": "_dirty() ? \"true\" : null", "attr.data-touched": "_touched() ? \"true\" : null" } }, hostDirectives: [{ directive: i1.BrnRadioGroup, inputs: ["name", "name", "value", "value", "disabled", "disabled", "required", "required"], outputs: ["valueChange", "valueChange"] }, { directive: i2.BrnFieldControlDescribedBy }], ngImport: i0 });
145
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
146
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmRadioGroup, isStandalone: true, selector: "[hlmRadioGroup],hlm-radio-group", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "radio-group" }, properties: { "attr.aria-invalid": "_ariaInvalid() ? \"true\" : null", "attr.data-invalid": "_ariaInvalid() ? \"true\" : null", "attr.data-dirty": "_dirty() ? \"true\" : null", "attr.data-touched": "_touched() ? \"true\" : null" } }, hostDirectives: [{ directive: i1.BrnRadioGroup, inputs: ["name", "name", "value", "value", "disabled", "disabled", "required", "required"], outputs: ["valueChange", "valueChange"] }, { directive: i2.BrnFieldControlDescribedBy }], ngImport: i0 });
140
147
  }
141
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroup, decorators: [{
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroup, decorators: [{
142
149
  type: Directive,
143
150
  args: [{
144
151
  selector: '[hlmRadioGroup],hlm-radio-group',
@@ -162,12 +169,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
162
169
 
163
170
  class HlmRadioIndicator {
164
171
  constructor() {
165
- classes(() => 'border-input text-primary group-has-[:focus-visible]:border-ring group-has-[:focus-visible]:ring-ring/50 dark:bg-input/30 group-data=[disabled=true]:cursor-not-allowed group-data=[disabled=true]:opacity-50 relative flex aspect-square size-4 shrink-0 items-center justify-center rounded-full border shadow-xs transition-[color,box-shadow] outline-none group-has-[:focus-visible]:ring-[3px]');
172
+ classes(() => "border-input text-primary group-has-[:focus-visible]:border-ring group-has-[:focus-visible]:ring-ring/50 dark:bg-input/30 group-data-[disabled=true]:cursor-not-allowed group-data-[disabled=true]:opacity-50 relative flex aspect-square size-4 shrink-0 items-center justify-center rounded-full border shadow-xs transition-[color,box-shadow] outline-none group-has-[:focus-visible]:ring-[3px]");
166
173
  }
167
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioIndicator, deps: [], target: i0.ɵɵFactoryTarget.Component });
168
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: HlmRadioIndicator, isStandalone: true, selector: "hlm-radio-indicator", host: { attributes: { "data-slot": "radio-group-indicator" } }, ngImport: i0, template: ` <div class="group-data-[checked=true]:bg-primary size-2 rounded-full bg-transparent"></div> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioIndicator, deps: [], target: i0.ɵɵFactoryTarget.Component });
175
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.3", type: HlmRadioIndicator, isStandalone: true, selector: "hlm-radio-indicator", host: { attributes: { "data-slot": "radio-group-indicator" } }, ngImport: i0, template: " <div class=\"group-data-[checked=true]:bg-primary size-2 rounded-full bg-transparent\"></div> ", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
169
176
  }
170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioIndicator, decorators: [{
177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioIndicator, decorators: [{
171
178
  type: Component,
172
179
  args: [{
173
180
  selector: 'hlm-radio-indicator',
@@ -175,7 +182,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
175
182
  host: {
176
183
  'data-slot': 'radio-group-indicator',
177
184
  },
178
- template: ` <div class="group-data-[checked=true]:bg-primary size-2 rounded-full bg-transparent"></div> `,
185
+ template: " <div class=\"group-data-[checked=true]:bg-primary size-2 rounded-full bg-transparent\"></div> ",
179
186
  }]
180
187
  }], ctorParameters: () => [] });
181
188
 
@@ -184,11 +191,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
184
191
  */
185
192
  const HlmRadioGroupImports = [HlmRadioGroup, HlmRadio, HlmRadioIndicator];
186
193
  class HlmRadioGroupModule {
187
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
188
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroupModule, imports: [HlmRadioGroup, HlmRadio, HlmRadioIndicator], exports: [HlmRadioGroup, HlmRadio, HlmRadioIndicator] });
189
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroupModule, imports: [HlmRadio] });
194
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
195
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroupModule, imports: [HlmRadioGroup, HlmRadio, HlmRadioIndicator], exports: [HlmRadioGroup, HlmRadio, HlmRadioIndicator] });
196
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroupModule, imports: [HlmRadio] });
190
197
  }
191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmRadioGroupModule, decorators: [{
198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmRadioGroupModule, decorators: [{
192
199
  type: NgModule,
193
200
  args: [{
194
201
  imports: [...HlmRadioGroupImports],
@@ -201,4 +208,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
201
208
  */
202
209
 
203
210
  export { HlmRadio, HlmRadioGroup, HlmRadioGroupImports, HlmRadioGroupModule, HlmRadioIndicator };
204
- //# sourceMappingURL=radio-group.mjs.map
211
+
@@ -15,7 +15,7 @@ declare class HlmRadio<T = unknown> {
15
15
  protected readonly _touched: _angular_core.Signal<boolean | undefined>;
16
16
  protected readonly _dirty: _angular_core.Signal<boolean | undefined>;
17
17
  protected readonly _groupSpartanInvalid: _angular_core.Signal<boolean | undefined>;
18
- protected readonly _errorStateClass: _angular_core.Signal<"text-destructive" | "">;
18
+ protected readonly _errorStateClass: _angular_core.Signal<"" | "text-destructive">;
19
19
  readonly userClass: _angular_core.InputSignal<ClassValue>;
20
20
  protected readonly _computedClass: _angular_core.Signal<string>;
21
21
  /** Used to set the id on the underlying brn element. */