@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,321 @@
1
- # Checkbox
1
+ # Checkbox (`@egose/shadcn-theme-ng/checkbox`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
3
+ A shadcn/ui-style checkbox — the Angular port of shadcn/ui `Checkbox`. A single standalone `hlm-checkbox` component wraps `BrnCheckbox` from `@spartan-ng/brain/checkbox`, renders the `lucideCheck` icon when checked, and fully implements `ControlValueAccessor`, so it works with `[(checked)]`, `[(ngModel)]`, and reactive `FormControl`s. Supports the tri-state `boolean | 'indeterminate'` model, separate `disabled` (form-aware) vs `wrapperDisabled` (visual-only) locks, and a `changed` output.
4
4
 
5
- ## Code scaffolding
5
+ Ships as `@egose/shadcn-theme-ng/checkbox` and `@egose/shadcn-theme-ng-tw/checkbox` (the `tw:`-prefixed variant). See the [package README](../../README.md) for install, peer dependencies, and Tailwind setup. Do not publish this project directory independently — it is consumed via the published subpath only.
6
6
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
7
+ ## Installation
8
8
 
9
9
  ```bash
10
- ng generate component component-name
10
+ # Plain Tailwind (no prefix):
11
+ npm install @egose/shadcn-theme-ng
12
+
13
+ # Or the tw:-prefixed variant:
14
+ npm install @egose/shadcn-theme-ng-tw
11
15
  ```
12
16
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
17
+ Peers are listed in the [package README](../../README.md). This subpath declares `@angular/common` and `@angular/core` as peers (see `projects/checkbox/package.json`); `FormsModule`/`ReactiveFormsModule` come from your app when you use form bindings.
14
18
 
15
- ```bash
16
- ng generate --help
19
+ ## Imports
20
+
21
+ ```ts
22
+ import {
23
+ HlmCheckbox,
24
+ HlmCheckboxImports,
25
+ HlmCheckboxModule,
26
+ HLM_CHECKBOX_VALUE_ACCESSOR,
27
+ } from '@egose/shadcn-theme-ng/checkbox';
28
+ // tw variant:
29
+ // import { ... } from '@egose/shadcn-theme-ng-tw/checkbox';
17
30
  ```
18
31
 
19
- ## Building
32
+ Standalone:
20
33
 
21
- To build the library, run:
34
+ ```ts
35
+ import { Component } from '@angular/core';
36
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
22
37
 
23
- ```bash
24
- ng build checkbox
38
+ @Component({
39
+ selector: 'app-demo',
40
+ standalone: true,
41
+ imports: [...HlmCheckboxImports],
42
+ template: `<hlm-checkbox />`,
43
+ })
44
+ export class DemoComponent {}
45
+ ```
46
+
47
+ NgModule:
48
+
49
+ ```ts
50
+ import { NgModule } from '@angular/core';
51
+ import { HlmCheckboxModule } from '@egose/shadcn-theme-ng/checkbox';
52
+
53
+ @NgModule({ imports: [HlmCheckboxModule] })
54
+ export class DemoModule {}
25
55
  ```
26
56
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
57
+ ## Anatomy / Structure
28
58
 
29
- ### Publishing the Library
59
+ ```html
60
+ <!-- Two-way model binding -->
61
+ <hlm-checkbox [(checked)]="accept" aria-label="Accept terms" />
30
62
 
31
- Once the project is built, you can publish your library by following these steps:
63
+ <!-- With visible label -->
64
+ <div class="flex items-center gap-2">
65
+ <hlm-checkbox id="marketing" [(checked)]="marketing" />
66
+ <label for="marketing">Email me product updates</label>
67
+ </div>
32
68
 
33
- 1. Navigate to the `dist` directory:
69
+ <!-- Reactive form -->
70
+ <hlm-checkbox formControlName="accept" />
34
71
 
35
- ```bash
36
- cd dist/checkbox
37
- ```
72
+ <!-- Template-driven -->
73
+ <hlm-checkbox name="accept" [(ngModel)]="accept" />
74
+ ```
38
75
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
76
+ Real selector: `hlm-checkbox` (element only). The host renders `class="contents peer"` so sibling label/description selectors (`peer-*`) keep working; `id` / `aria-*` attributes are nulled on the host and forwarded to the inner `brn-checkbox` instead. Set a visible label with a native `<label for>` — the component does not render label text itself.
43
77
 
44
- ## Running unit tests
78
+ ## API reference
45
79
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
80
+ ### `HlmCheckbox` (`hlm-checkbox`)
47
81
 
48
- ```bash
49
- ng test
82
+ | Input | Type | Default | Description |
83
+ | -------------------------------------- | ----------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
84
+ | `checked` | `model<boolean \| 'indeterminate'>` | `false` | Checked state. Two-way bindable (`[(checked)]`). `'indeterminate'` renders the checked icon; clicking it resolves to `true`. |
85
+ | `class` (`userClass`) | `ClassValue` | `''` | Extra classes merged into the box. |
86
+ | `id` | `string \| null` | `null` | Forwarded to inner `brn-checkbox`. Pair with `<label for>`. |
87
+ | `aria-label` (`ariaLabel`) | `string \| null` | `null` | Forwarded aria-label. |
88
+ | `aria-labelledby` (`ariaLabelledby`) | `string \| null` | `null` | Forwarded aria-labelledby. |
89
+ | `aria-describedby` (`ariaDescribedby`) | `string \| null` | `null` | Forwarded aria-describedby. |
90
+ | `name` | `string \| null` | `null` | Forwarded `name`. |
91
+ | `required` | `boolean` | `false` | Forwarded `required` (boolean-coerced). |
92
+ | `disabled` | `boolean` | `false` | Visual + interaction lock (boolean-coerced). Clicks are ignored. |
93
+ | `wrapperDisabled` | `boolean` | `false` | Additional visual/interaction lock that does **not** write to a reactive form control (unlike `setDisabledState`). Useful for preview-only states. |
94
+
95
+ | Signal | Type | Description |
96
+ | --------------- | ----------------- | ------------------------------------------------------------------------------------------------------------ |
97
+ | `disabledState` | `Signal<boolean>` | `disabled() \|\| wrapperDisabled() \|\| formDisabled()` — the effective lock. Host reflects `data-disabled`. |
98
+
99
+ | Output | Payload | Description |
100
+ | --------- | --------- | -------------------------------------------------------------------------------------------------------------- |
101
+ | `changed` | `boolean` | Emitted on user toggle with the new boolean (`!previous`). Note: toggling from `'indeterminate'` emits `true`. |
102
+
103
+ ControlValueAccessor: `writeValue(value)`, `registerOnChange`, `registerOnTouched`, `setDisabledState(isDisabled)` (writes `formDisabled`, hence `disabledState`). `HLM_CHECKBOX_VALUE_ACCESSOR` (`NG_VALUE_ACCESSOR`, `forwardRef(HlmCheckbox)`, `multi: true`) is provided on the component.
104
+
105
+ ## Examples
106
+
107
+ ### 1. Basic with label
108
+
109
+ ```ts
110
+ import { Component, signal } from '@angular/core';
111
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
112
+
113
+ @Component({
114
+ selector: 'app-basic-checkbox',
115
+ standalone: true,
116
+ imports: [...HlmCheckboxImports],
117
+ template: `
118
+ <div class="flex items-center gap-2">
119
+ <hlm-checkbox id="terms" [(checked)]="accept" />
120
+ <label for="terms" class="text-sm">Accept terms and conditions</label>
121
+ </div>
122
+ <p class="mt-2 text-sm">Value: {{ accept() }}</p>
123
+ `,
124
+ })
125
+ export class BasicCheckboxComponent {
126
+ readonly accept = signal<boolean | 'indeterminate'>(false);
127
+ }
50
128
  ```
51
129
 
52
- ## Running end-to-end tests
130
+ ### 2. Reactive form with validation
53
131
 
54
- For end-to-end (e2e) testing, run:
132
+ `hlm-checkbox` is a `ControlValueAccessor` — `formControlName` just works, including `disable()`.
55
133
 
56
- ```bash
57
- ng e2e
134
+ ```ts
135
+ import { Component } from '@angular/core';
136
+ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
137
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
138
+
139
+ @Component({
140
+ selector: 'app-reactive-checkbox',
141
+ standalone: true,
142
+ imports: [ReactiveFormsModule, ...HlmCheckboxImports],
143
+ template: `
144
+ <form [formGroup]="form" (ngSubmit)="submit()" class="space-y-3">
145
+ <div class="flex items-center gap-2">
146
+ <hlm-checkbox id="accept" formControlName="accept" />
147
+ <label for="accept" class="text-sm">I agree to the privacy policy</label>
148
+ </div>
149
+ @if (form.controls.accept.touched && form.controls.accept.invalid) {
150
+ <p class="text-destructive text-sm">You must accept to continue.</p>
151
+ }
152
+ <button type="submit" [disabled]="form.invalid">Continue</button>
153
+ <button type="button" (click)="form.controls.accept.disable()">Disable via form</button>
154
+ </form>
155
+ `,
156
+ })
157
+ export class ReactiveCheckboxComponent {
158
+ readonly form = new FormGroup({
159
+ accept: new FormControl(false, { validators: Validators.requiredTrue, nonNullable: true }),
160
+ });
161
+ submit() {
162
+ console.log(this.form.getRawValue());
163
+ }
164
+ }
58
165
  ```
59
166
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
167
+ ### 3. Template-driven (`ngModel`)
168
+
169
+ ```ts
170
+ import { Component } from '@angular/core';
171
+ import { FormsModule } from '@angular/forms';
172
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
173
+
174
+ @Component({
175
+ selector: 'app-ngmodel-checkbox',
176
+ standalone: true,
177
+ imports: [FormsModule, ...HlmCheckboxImports],
178
+ template: `
179
+ <div class="flex items-center gap-2">
180
+ <hlm-checkbox id="news" name="news" [(ngModel)]="subscribed" aria-label="Subscribe to newsletter" />
181
+ <label for="news" class="text-sm">Subscribe to newsletter</label>
182
+ </div>
183
+ `,
184
+ })
185
+ export class NgModelCheckboxComponent {
186
+ subscribed = true;
187
+ }
188
+ ```
189
+
190
+ ### 4. Indeterminate + select-all pattern
191
+
192
+ Parent shows `'indeterminate'` when some (not all) children are checked — the classic bulk-select header.
193
+
194
+ ```ts
195
+ import { Component, computed, signal } from '@angular/core';
196
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
197
+
198
+ @Component({
199
+ selector: 'app-select-all',
200
+ standalone: true,
201
+ imports: [...HlmCheckboxImports],
202
+ template: `
203
+ <div class="flex items-center gap-2 border-b pb-2">
204
+ <hlm-checkbox id="all" [checked]="parentState()" (changed)="toggleAll($event)" aria-label="Select all files" />
205
+ <label for="all" class="text-sm font-medium">Select all</label>
206
+ </div>
207
+ @for (f of files(); track f.id) {
208
+ <div class="flex items-center gap-2 py-1">
209
+ <hlm-checkbox [id]="f.id" [checked]="f.done" (changed)="toggleOne(f.id, $event)" />
210
+ <label [for]="f.id" class="text-sm">{{ f.name }}</label>
211
+ </div>
212
+ }
213
+ `,
214
+ })
215
+ export class SelectAllComponent {
216
+ readonly files = signal([
217
+ { id: 'f1', name: 'invoice.pdf', done: true },
218
+ { id: 'f2', name: 'photo.png', done: false },
219
+ { id: 'f3', name: 'notes.md', done: false },
220
+ ]);
221
+ readonly parentState = computed<boolean | 'indeterminate'>(() => {
222
+ const all = this.files();
223
+ if (all.every((f) => f.done)) return true;
224
+ if (all.some((f) => f.done)) return 'indeterminate';
225
+ return false;
226
+ });
227
+ toggleAll(next: boolean) {
228
+ this.files.update((fs) => fs.map((f) => ({ ...f, done: next })));
229
+ }
230
+ toggleOne(id: string, next: boolean) {
231
+ this.files.update((fs) => fs.map((f) => (f.id === id ? { ...f, done: next } : f)));
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### 5. Disabled / wrapper-disabled / required states
237
+
238
+ ```ts
239
+ import { Component, signal } from '@angular/core';
240
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
241
+
242
+ @Component({
243
+ selector: 'app-states-checkbox',
244
+ standalone: true,
245
+ imports: [...HlmCheckboxImports],
246
+ template: `
247
+ <div class="space-y-2">
248
+ <div class="flex items-center gap-2">
249
+ <hlm-checkbox id="d1" [disabled]="true" aria-label="Disabled unchecked" />
250
+ <label for="d1" class="text-sm opacity-70">Disabled (unchecked)</label>
251
+ </div>
252
+ <div class="flex items-center gap-2">
253
+ <hlm-checkbox id="d2" [checked]="true" [disabled]="true" aria-label="Disabled checked" />
254
+ <label for="d2" class="text-sm opacity-70">Disabled (checked)</label>
255
+ </div>
256
+ <div class="flex items-center gap-2">
257
+ <hlm-checkbox id="w1" [wrapperDisabled]="preview()" aria-label="Preview lock" />
258
+ <label for="w1" class="text-sm">Preview lock (visual only — form value untouched)</label>
259
+ </div>
260
+ <div class="flex items-center gap-2">
261
+ <hlm-checkbox id="r1" [(checked)]="v" [required]="true" aria-label="Required" />
262
+ <label for="r1" class="text-sm">Required</label>
263
+ </div>
264
+ </div>
265
+ `,
266
+ })
267
+ export class StatesCheckboxComponent {
268
+ readonly preview = signal(true);
269
+ v = false;
270
+ }
271
+ ```
272
+
273
+ ### 6. Listening to `changed` + custom styling
274
+
275
+ ```ts
276
+ import { Component } from '@angular/core';
277
+ import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
278
+
279
+ @Component({
280
+ selector: 'app-changed-checkbox',
281
+ standalone: true,
282
+ imports: [...HlmCheckboxImports],
283
+ template: `
284
+ <div class="flex items-center gap-2">
285
+ <hlm-checkbox
286
+ id="audit"
287
+ class="data-[state=checked]:border-emerald-600 data-[state=checked]:bg-emerald-600"
288
+ aria-label="Enable audit log"
289
+ (changed)="onChanged($event)"
290
+ />
291
+ <label for="audit" class="text-sm">Enable audit log</label>
292
+ </div>
293
+ <p class="mt-1 text-sm">Last event: {{ lastChanged === null ? 'none' : lastChanged }}</p>
294
+ `,
295
+ })
296
+ export class ChangedCheckboxComponent {
297
+ lastChanged: boolean | null = null;
298
+ onChanged(next: boolean) {
299
+ this.lastChanged = next;
300
+ console.log('checkbox changed →', next);
301
+ }
302
+ }
303
+ ```
304
+
305
+ ## Accessibility notes
306
+
307
+ - The component renders a native-checkbox-equivalent `brn-checkbox` with `aria-label`/`labelledby`/`describedby` forwarding — always provide one: visible `<label for>` preferred, `aria-label` for icon-only rows.
308
+ - `disabledState` adds `data-disabled`, `cursor-not-allowed`, and `opacity-50`; disabled boxes are skipped correctly because clicks early-return.
309
+ - The check glyph is decorative (`lucideCheck` icon, no text) — state is exposed via `data-[state]` / native semantics, not the icon.
310
+ - Tri-state: `'indeterminate'` is a visual/model state, not `aria-checked="mixed"` — if you need mixed semantics for a tree, add `aria-checked` handling at your own level and test with a screen reader.
311
+
312
+ ## Theming / CSS variables
313
+
314
+ No component-specific CSS variables. The box uses `border-input`, `data-[state=checked]:bg-primary` / `text-primary-foreground`, `focus-visible:ring-ring/50`, `aria-invalid:border-destructive`, `size-4 rounded-[4px]`. Invalid-form styling integrates via `aria-invalid` ring tokens. Pass `class` to extend (merged with `hlm()`).
61
315
 
62
- ## Additional Resources
316
+ ## Related subpaths
63
317
 
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.
318
+ - `@egose/shadcn-theme-ng/form-checkbox` — labeled + described + validated field composition.
319
+ - `@egose/shadcn-theme-ng/label` — accessible labels for the `for`/`id` pair.
320
+ - `@egose/shadcn-theme-ng/field` — form layout rows that host checkboxes.
321
+ - `@egose/shadcn-theme-ng/icon` — `HlmIcon` sizing used by the inner check glyph.
@@ -14,7 +14,7 @@ const HLM_CHECKBOX_VALUE_ACCESSOR = {
14
14
  };
15
15
  class HlmCheckbox {
16
16
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
17
- _computedClass = computed(() => hlm('border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shadow-xs peer size-4 shrink-0 cursor-default rounded-[4px] border outline-none transition-shadow focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', this.userClass(), this._state().disabled() ? 'cursor-not-allowed opacity-50' : ''), /* @ts-ignore */
17
+ _computedClass = computed(() => hlm("border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shadow-xs peer size-4 shrink-0 cursor-default rounded-[4px] border outline-none transition-shadow focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50", this.userClass(), this.disabledState() ? "cursor-not-allowed opacity-50" : ''), /* @ts-ignore */
18
18
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
19
19
  /** Used to set the id on the underlying brn element. */
20
20
  id = input(null, /* @ts-ignore */
@@ -35,15 +35,17 @@ class HlmCheckbox {
35
35
  required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
36
36
  /** Whether the checkbox is disabled. */
37
37
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
38
- _state = computed(() => ({
39
- disabled: signal(this.disabled()),
40
- }), /* @ts-ignore */
41
- ...(ngDevMode ? [{ debugName: "_state" }] : /* istanbul ignore next */ []));
38
+ /** Additional visual/interaction lock that does not write to a reactive form control. */
39
+ wrapperDisabled = input(false, { ...(ngDevMode ? { debugName: "wrapperDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
40
+ formDisabled = signal(false, /* @ts-ignore */
41
+ ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
42
+ disabledState = computed(() => this.disabled() || this.wrapperDisabled() || this.formDisabled(), /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
42
44
  changed = output();
43
45
  _onChange;
44
46
  _onTouched;
45
47
  _handleChange() {
46
- if (this._state().disabled())
48
+ if (this.disabledState())
47
49
  return;
48
50
  const previousChecked = this.checked();
49
51
  this.checked.set(previousChecked === 'indeterminate' ? true : !previousChecked);
@@ -61,81 +63,41 @@ class HlmCheckbox {
61
63
  this._onTouched = fn;
62
64
  }
63
65
  setDisabledState(isDisabled) {
64
- this._state().disabled.set(isDisabled);
66
+ this.formDisabled.set(isDisabled);
65
67
  }
66
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
67
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: HlmCheckbox, isStandalone: true, selector: "hlm-checkbox", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", 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 }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, 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: { checked: "checkedChange", changed: "changed" }, host: { properties: { "attr.id": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.data-disabled": "_state().disabled() ? \"\" : null" }, classAttribute: "contents peer" }, providers: [HLM_CHECKBOX_VALUE_ACCESSOR], ngImport: i0, template: `
68
- <brn-checkbox
69
- [id]="id()"
70
- [name]="name()"
71
- [class]="_computedClass()"
72
- [checked]="checked()"
73
- [disabled]="_state().disabled()"
74
- [required]="required()"
75
- [aria-label]="ariaLabel()"
76
- [aria-labelledby]="ariaLabelledby()"
77
- [aria-describedby]="ariaDescribedby()"
78
- (changed)="_handleChange()"
79
- (touched)="_onTouched?.()"
80
- >
81
- @if (checked()) {
82
- <span class="flex items-center justify-center text-current transition-none">
83
- <ng-icon hlm size="14px" name="lucideCheck" />
84
- </span>
85
- }
86
- </brn-checkbox>
87
- `, isInline: true, dependencies: [{ kind: "component", type: BrnCheckbox, selector: "brn-checkbox", inputs: ["checked", "indeterminate", "id", "name", "class", "hostStyles", "aria-label", "aria-labelledby", "aria-describedby", "required", "disabled", "forceInvalid"], outputs: ["checkedChange", "indeterminateChange", "touched"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: HlmIcon, selector: "ng-icon[hlm]", inputs: ["size"] }], viewProviders: [provideIcons({ lucideCheck })], changeDetection: i0.ChangeDetectionStrategy.OnPush });
68
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
69
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: HlmCheckbox, isStandalone: true, selector: "hlm-checkbox", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", 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 }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, wrapperDisabled: { classPropertyName: "wrapperDisabled", publicName: "wrapperDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", changed: "changed" }, host: { properties: { "attr.id": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.data-disabled": "disabledState() ? \"\" : null" }, classAttribute: "contents peer" }, providers: [HLM_CHECKBOX_VALUE_ACCESSOR], ngImport: i0, template: "\n <brn-checkbox\n [id]=\"id()\"\n [name]=\"name()\"\n [class]=\"_computedClass()\"\n [checked]=\"checked()\"\n [disabled]=\"disabledState()\"\n [required]=\"required()\"\n [aria-label]=\"ariaLabel()\"\n [aria-labelledby]=\"ariaLabelledby()\"\n [aria-describedby]=\"ariaDescribedby()\"\n (changed)=\"_handleChange()\"\n (touched)=\"_onTouched?.()\"\n >\n @if (checked()) {\n <span class=\"flex items-center justify-center text-current transition-none\">\n <ng-icon hlm size=\"14px\" name=\"lucideCheck\" />\n </span>\n }\n </brn-checkbox>\n ", isInline: true, dependencies: [{ kind: "component", type: BrnCheckbox, selector: "brn-checkbox", inputs: ["checked", "indeterminate", "id", "name", "class", "hostStyles", "aria-label", "aria-labelledby", "aria-describedby", "required", "disabled", "forceInvalid"], outputs: ["checkedChange", "indeterminateChange", "touched"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: HlmIcon, selector: "ng-icon[hlm]", inputs: ["size"] }], viewProviders: [provideIcons({ lucideCheck })], changeDetection: i0.ChangeDetectionStrategy.OnPush });
88
70
  }
89
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckbox, decorators: [{
71
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckbox, decorators: [{
90
72
  type: Component,
91
73
  args: [{
92
74
  selector: 'hlm-checkbox',
93
75
  imports: [BrnCheckbox, NgIcon, HlmIcon],
94
- template: `
95
- <brn-checkbox
96
- [id]="id()"
97
- [name]="name()"
98
- [class]="_computedClass()"
99
- [checked]="checked()"
100
- [disabled]="_state().disabled()"
101
- [required]="required()"
102
- [aria-label]="ariaLabel()"
103
- [aria-labelledby]="ariaLabelledby()"
104
- [aria-describedby]="ariaDescribedby()"
105
- (changed)="_handleChange()"
106
- (touched)="_onTouched?.()"
107
- >
108
- @if (checked()) {
109
- <span class="flex items-center justify-center text-current transition-none">
110
- <ng-icon hlm size="14px" name="lucideCheck" />
111
- </span>
112
- }
113
- </brn-checkbox>
114
- `,
76
+ template: "\n <brn-checkbox\n [id]=\"id()\"\n [name]=\"name()\"\n [class]=\"_computedClass()\"\n [checked]=\"checked()\"\n [disabled]=\"disabledState()\"\n [required]=\"required()\"\n [aria-label]=\"ariaLabel()\"\n [aria-labelledby]=\"ariaLabelledby()\"\n [aria-describedby]=\"ariaDescribedby()\"\n (changed)=\"_handleChange()\"\n (touched)=\"_onTouched?.()\"\n >\n @if (checked()) {\n <span class=\"flex items-center justify-center text-current transition-none\">\n <ng-icon hlm size=\"14px\" name=\"lucideCheck\" />\n </span>\n }\n </brn-checkbox>\n ",
115
77
  host: {
116
78
  class: 'contents peer',
117
79
  '[attr.id]': 'null',
118
80
  '[attr.aria-label]': 'null',
119
81
  '[attr.aria-labelledby]': 'null',
120
82
  '[attr.aria-describedby]': 'null',
121
- '[attr.data-disabled]': '_state().disabled() ? "" : null',
83
+ '[attr.data-disabled]': 'disabledState() ? "" : null',
122
84
  },
123
85
  providers: [HLM_CHECKBOX_VALUE_ACCESSOR],
124
86
  viewProviders: [provideIcons({ lucideCheck })],
125
87
  changeDetection: ChangeDetectionStrategy.OnPush,
126
88
  }]
127
- }], propDecorators: { userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
89
+ }], propDecorators: { userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], wrapperDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperDisabled", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
128
90
 
129
91
  /*
130
92
  * Public API Surface of checkbox
131
93
  */
132
94
  const HlmCheckboxImports = [HlmCheckbox];
133
95
  class HlmCheckboxModule {
134
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
135
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckboxModule, imports: [HlmCheckbox], exports: [HlmCheckbox] });
136
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckboxModule, imports: [HlmCheckboxImports] });
96
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
97
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckboxModule, imports: [HlmCheckbox], exports: [HlmCheckbox] });
98
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckboxModule, imports: [HlmCheckboxImports] });
137
99
  }
138
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmCheckboxModule, decorators: [{
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmCheckboxModule, decorators: [{
139
101
  type: NgModule,
140
102
  args: [{
141
103
  imports: [...HlmCheckboxImports],
@@ -148,4 +110,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
148
110
  */
149
111
 
150
112
  export { HLM_CHECKBOX_VALUE_ACCESSOR, HlmCheckbox, HlmCheckboxImports, HlmCheckboxModule };
151
- //# sourceMappingURL=checkbox.mjs.map
113
+
@@ -28,9 +28,10 @@ declare class HlmCheckbox implements ControlValueAccessor {
28
28
  readonly required: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
29
29
  /** Whether the checkbox is disabled. */
30
30
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
31
- protected readonly _state: _angular_core.Signal<{
32
- disabled: _angular_core.WritableSignal<boolean>;
33
- }>;
31
+ /** Additional visual/interaction lock that does not write to a reactive form control. */
32
+ readonly wrapperDisabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
33
+ private readonly formDisabled;
34
+ readonly disabledState: _angular_core.Signal<boolean>;
34
35
  readonly changed: _angular_core.OutputEmitterRef<boolean>;
35
36
  protected _onChange?: ChangeFn<CheckboxValue>;
36
37
  protected _onTouched?: TouchFn;
@@ -41,7 +42,7 @@ declare class HlmCheckbox implements ControlValueAccessor {
41
42
  registerOnTouched(fn: TouchFn): void;
42
43
  setDisabledState(isDisabled: boolean): void;
43
44
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmCheckbox, never>;
44
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<HlmCheckbox, "hlm-checkbox", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "changed": "changed"; }, never, never, true, never>;
45
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<HlmCheckbox, "hlm-checkbox", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "wrapperDisabled": { "alias": "wrapperDisabled"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "changed": "changed"; }, never, never, true, never>;
45
46
  }
46
47
  type CheckboxValue = boolean | 'indeterminate';
47
48