@egose/shadcn-theme-ng-tw 0.0.28 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +20 -20
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +18 -18
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
  8. package/alert-dialog/types/alert-dialog.d.ts +1 -1
  9. package/aspect-ratio/README.md +272 -5
  10. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  11. package/autocomplete/README.md +473 -34
  12. package/autocomplete/fesm2022/autocomplete.mjs +54 -54
  13. package/autocomplete/types/autocomplete.d.ts +1 -1
  14. package/avatar/README.md +357 -5
  15. package/avatar/fesm2022/avatar.mjs +32 -32
  16. package/badge/README.md +289 -34
  17. package/badge/fesm2022/badge.mjs +4 -4
  18. package/basic-alert/README.md +324 -34
  19. package/basic-alert/fesm2022/basic-alert.mjs +4 -4
  20. package/basic-alert/types/basic-alert.d.ts +1 -1
  21. package/breadcrumb/README.md +406 -5
  22. package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
  23. package/button/README.md +453 -34
  24. package/button/fesm2022/button.mjs +96 -118
  25. package/button/types/button.d.ts +7 -10
  26. package/button-group/README.md +318 -5
  27. package/button-group/fesm2022/button-group.mjs +20 -20
  28. package/calendar/README.md +328 -34
  29. package/calendar/fesm2022/calendar.mjs +154 -154
  30. package/card/README.md +331 -5
  31. package/card/fesm2022/card.mjs +33 -33
  32. package/carousel/README.md +333 -5
  33. package/carousel/fesm2022/carousel.mjs +47 -44
  34. package/carousel/types/carousel.d.ts +1 -1
  35. package/checkbox/README.md +291 -34
  36. package/checkbox/fesm2022/checkbox.mjs +22 -20
  37. package/checkbox/types/checkbox.d.ts +5 -4
  38. package/collapsible/README.md +332 -5
  39. package/collapsible/fesm2022/collapsible.mjs +15 -15
  40. package/combobox/README.md +507 -5
  41. package/combobox/fesm2022/combobox.mjs +95 -92
  42. package/combobox/types/combobox.d.ts +1 -1
  43. package/command/README.md +435 -5
  44. package/command/fesm2022/command.mjs +56 -56
  45. package/confirmation-dialog/README.md +272 -34
  46. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
  47. package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
  48. package/context-menu/README.md +366 -5
  49. package/context-menu/fesm2022/context-menu.mjs +9 -9
  50. package/date-picker/README.md +436 -34
  51. package/date-picker/fesm2022/date-picker.mjs +79 -68
  52. package/date-picker/types/date-picker.d.ts +8 -4
  53. package/dialog/README.md +419 -34
  54. package/dialog/fesm2022/dialog.mjs +48 -48
  55. package/drawer/README.md +395 -5
  56. package/drawer/fesm2022/drawer.mjs +45 -45
  57. package/dropdown-menu/README.md +417 -5
  58. package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
  59. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  60. package/empty/README.md +329 -5
  61. package/empty/fesm2022/empty.mjs +31 -31
  62. package/field/README.md +385 -5
  63. package/field/fesm2022/field.mjs +59 -59
  64. package/field/types/field.d.ts +1 -1
  65. package/form-checkbox/README.md +283 -34
  66. package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
  67. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  68. package/form-date-picker/README.md +293 -34
  69. package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
  70. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  71. package/form-field/README.md +327 -34
  72. package/form-field/fesm2022/form-field.mjs +30 -16
  73. package/form-field/types/form-field.d.ts +28 -20
  74. package/form-field-simple/README.md +311 -34
  75. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  76. package/form-searchable-multiselect/README.md +332 -34
  77. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
  78. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
  79. package/form-select/README.md +321 -34
  80. package/form-select/fesm2022/form-select.mjs +62 -29
  81. package/form-select/types/form-select.d.ts +7 -1
  82. package/form-text-input/README.md +342 -34
  83. package/form-text-input/fesm2022/form-text-input.mjs +43 -55
  84. package/form-text-input/types/form-text-input.d.ts +9 -12
  85. package/form-textarea/README.md +318 -34
  86. package/form-textarea/fesm2022/form-textarea.mjs +42 -23
  87. package/form-textarea/types/form-textarea.d.ts +8 -1
  88. package/hover-card/README.md +256 -5
  89. package/hover-card/fesm2022/hover-card.mjs +19 -19
  90. package/icon/README.md +210 -34
  91. package/icon/fesm2022/icon.mjs +8 -8
  92. package/input/README.md +240 -34
  93. package/input/fesm2022/input.mjs +17 -12
  94. package/input/types/input.d.ts +2 -1
  95. package/input-group/README.md +335 -5
  96. package/input-group/fesm2022/input-group.mjs +37 -37
  97. package/input-group/types/input-group.d.ts +3 -3
  98. package/input-otp/README.md +375 -5
  99. package/input-otp/fesm2022/input-otp.mjs +27 -27
  100. package/item/README.md +385 -5
  101. package/item/fesm2022/item.mjs +54 -54
  102. package/kbd/README.md +291 -5
  103. package/kbd/fesm2022/kbd.mjs +13 -13
  104. package/label/README.md +243 -34
  105. package/label/fesm2022/label.mjs +9 -9
  106. package/label/types/label.d.ts +1 -1
  107. package/layout-simple/README.md +174 -44
  108. package/layout-simple/fesm2022/layout-simple.mjs +917 -398
  109. package/layout-simple/types/layout-simple.d.ts +180 -129
  110. package/menu/README.md +418 -0
  111. package/menu/fesm2022/menu.mjs +461 -0
  112. package/menu/package.json +24 -0
  113. package/menu/types/menu.d.ts +137 -0
  114. package/menubar/README.md +343 -5
  115. package/menubar/fesm2022/menubar.mjs +13 -13
  116. package/native-select/README.md +323 -5
  117. package/native-select/fesm2022/native-select.mjs +19 -19
  118. package/navigation-menu/README.md +369 -5
  119. package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
  120. package/package.json +183 -154
  121. package/pagination/README.md +388 -5
  122. package/pagination/fesm2022/pagination.mjs +63 -63
  123. package/popover/README.md +302 -34
  124. package/popover/fesm2022/popover.mjs +30 -30
  125. package/progress/README.md +311 -5
  126. package/progress/fesm2022/progress.mjs +13 -13
  127. package/radio-group/README.md +335 -34
  128. package/radio-group/fesm2022/radio-group.mjs +26 -19
  129. package/resizable/README.md +269 -5
  130. package/resizable/fesm2022/resizable.mjs +19 -19
  131. package/scroll-area/README.md +233 -5
  132. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  133. package/searchable-multiselect/README.md +294 -34
  134. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
  135. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  136. package/select/README.md +408 -34
  137. package/select/fesm2022/select.mjs +80 -72
  138. package/select/types/select.d.ts +3 -1
  139. package/separator/README.md +193 -34
  140. package/separator/fesm2022/separator.mjs +9 -9
  141. package/separator/types/separator.d.ts +1 -1
  142. package/sheet/README.md +282 -34
  143. package/sheet/fesm2022/sheet.mjs +30 -30
  144. package/sidebar/README.md +457 -5
  145. package/sidebar/fesm2022/sidebar.mjs +136 -134
  146. package/sidebar/types/sidebar.d.ts +3 -3
  147. package/skeleton/README.md +217 -5
  148. package/skeleton/fesm2022/skeleton.mjs +9 -9
  149. package/slider/README.md +273 -5
  150. package/slider/fesm2022/slider.mjs +29 -25
  151. package/sonner/README.md +317 -34
  152. package/sonner/fesm2022/sonner.mjs +9 -9
  153. package/spinner/README.md +255 -34
  154. package/spinner/fesm2022/spinner.mjs +8 -8
  155. package/switch/README.md +281 -34
  156. package/switch/fesm2022/switch.mjs +12 -14
  157. package/table/README.md +423 -5
  158. package/table/fesm2022/table.mjs +41 -41
  159. package/tabs/README.md +382 -34
  160. package/tabs/fesm2022/tabs.mjs +48 -38
  161. package/textarea/README.md +282 -5
  162. package/textarea/fesm2022/textarea.mjs +9 -9
  163. package/toggle/README.md +270 -5
  164. package/toggle/fesm2022/toggle.mjs +14 -14
  165. package/toggle-group/README.md +340 -5
  166. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  167. package/toggle-group/types/toggle-group.d.ts +13 -7
  168. package/tooltip/README.md +240 -34
  169. package/tooltip/fesm2022/tooltip.mjs +14 -14
  170. package/typography/README.md +271 -5
  171. package/typography/fesm2022/typography.mjs +53 -53
  172. package/typography/types/typography.d.ts +12 -12
  173. package/utils/README.md +274 -34
  174. package/utils/fesm2022/utils.mjs +68 -44
  175. package/accordion/fesm2022/accordion.mjs.map +0 -1
  176. package/alert/fesm2022/alert.mjs.map +0 -1
  177. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  178. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  179. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  180. package/avatar/fesm2022/avatar.mjs.map +0 -1
  181. package/badge/fesm2022/badge.mjs.map +0 -1
  182. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  183. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  184. package/button/fesm2022/button.mjs.map +0 -1
  185. package/button-group/fesm2022/button-group.mjs.map +0 -1
  186. package/calendar/fesm2022/calendar.mjs.map +0 -1
  187. package/card/fesm2022/card.mjs.map +0 -1
  188. package/carousel/fesm2022/carousel.mjs.map +0 -1
  189. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  190. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  191. package/combobox/fesm2022/combobox.mjs.map +0 -1
  192. package/command/fesm2022/command.mjs.map +0 -1
  193. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  194. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  195. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  196. package/dialog/fesm2022/dialog.mjs.map +0 -1
  197. package/drawer/fesm2022/drawer.mjs.map +0 -1
  198. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  199. package/empty/fesm2022/empty.mjs.map +0 -1
  200. package/field/fesm2022/field.mjs.map +0 -1
  201. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  202. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  203. package/form-field/fesm2022/form-field.mjs.map +0 -1
  204. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  205. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  206. package/form-select/fesm2022/form-select.mjs.map +0 -1
  207. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  208. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  209. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  210. package/icon/fesm2022/icon.mjs.map +0 -1
  211. package/input/fesm2022/input.mjs.map +0 -1
  212. package/input-group/fesm2022/input-group.mjs.map +0 -1
  213. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  214. package/item/fesm2022/item.mjs.map +0 -1
  215. package/kbd/fesm2022/kbd.mjs.map +0 -1
  216. package/label/fesm2022/label.mjs.map +0 -1
  217. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  218. package/menubar/fesm2022/menubar.mjs.map +0 -1
  219. package/native-select/fesm2022/native-select.mjs.map +0 -1
  220. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  221. package/pagination/fesm2022/pagination.mjs.map +0 -1
  222. package/popover/fesm2022/popover.mjs.map +0 -1
  223. package/progress/fesm2022/progress.mjs.map +0 -1
  224. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  225. package/resizable/fesm2022/resizable.mjs.map +0 -1
  226. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  227. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  228. package/select/fesm2022/select.mjs.map +0 -1
  229. package/separator/fesm2022/separator.mjs.map +0 -1
  230. package/sheet/fesm2022/sheet.mjs.map +0 -1
  231. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  232. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  233. package/slider/fesm2022/slider.mjs.map +0 -1
  234. package/sonner/fesm2022/sonner.mjs.map +0 -1
  235. package/spinner/fesm2022/spinner.mjs.map +0 -1
  236. package/switch/fesm2022/switch.mjs.map +0 -1
  237. package/table/fesm2022/table.mjs.map +0 -1
  238. package/tabs/fesm2022/tabs.mjs.map +0 -1
  239. package/textarea/fesm2022/textarea.mjs.map +0 -1
  240. package/toggle/fesm2022/toggle.mjs.map +0 -1
  241. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  242. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  243. package/typography/fesm2022/typography.mjs.map +0 -1
  244. package/utils/fesm2022/utils.mjs.map +0 -1
package/switch/README.md CHANGED
@@ -1,64 +1,311 @@
1
- # Switch
1
+ # Switch (`@egose/shadcn-theme-ng/switch`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.2.0.
3
+ A toggle switch, equivalent to [shadcn/ui Switch](https://ui.shadcn.com/docs/components/switch). This subpath ships `HlmSwitch` — a shadcn-styled `ControlValueAccessor` component wrapping spartan-ng's `BrnSwitch`/`BrnSwitchThumb` primitives — plus the `HlmSwitchThumb` styling directive for advanced use. Supports template-driven forms, reactive forms, and two-way `[(checked)]` binding out of the box.
4
4
 
5
- ## Code scaffolding
5
+ > **Ships as:** `@egose/shadcn-theme-ng/switch` and `@egose/shadcn-theme-ng-tw/switch` (the `tw:`-prefixed Tailwind variant). See the [package README](../../README.md) for install steps, peer dependencies, Tailwind setup, and testing/release guidance. Do not publish this project directory independently.
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
+ `@spartan-ng/brain` arrives transitively; `FormsModule`/`ReactiveFormsModule` come from your app when you need form bindings. See the [package README](../../README.md) for the full peer-dependency table.
14
18
 
15
- ```bash
16
- ng generate --help
19
+ ## Imports
20
+
21
+ All public symbols are re-exported from `projects/switch/src/public-api.ts`:
22
+
23
+ ```ts
24
+ import { HlmSwitch, HlmSwitchThumb, HlmSwitchImports, HlmSwitchModule } from '@egose/shadcn-theme-ng/switch';
25
+ // tw variant:
26
+ // import { HlmSwitch, HlmSwitchThumb, HlmSwitchImports, HlmSwitchModule } from '@egose/shadcn-theme-ng-tw/switch';
17
27
  ```
18
28
 
19
- ## Building
29
+ Standalone-component usage (preferred):
20
30
 
21
- To build the library, run:
31
+ ```ts
32
+ import { Component } from '@angular/core';
33
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
22
34
 
23
- ```bash
24
- ng build switch
35
+ @Component({
36
+ selector: 'app-demo',
37
+ standalone: true,
38
+ imports: [...HlmSwitchImports],
39
+ template: `<hlm-switch />`,
40
+ })
41
+ export class DemoComponent {}
25
42
  ```
26
43
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
44
+ NgModule usage:
28
45
 
29
- ### Publishing the Library
46
+ ```ts
47
+ import { NgModule } from '@angular/core';
48
+ import { HlmSwitchModule } from '@egose/shadcn-theme-ng/switch';
30
49
 
31
- Once the project is built, you can publish your library by following these steps:
50
+ @NgModule({ imports: [HlmSwitchModule] })
51
+ export class FeatureModule {}
52
+ ```
32
53
 
33
- 1. Navigate to the `dist` directory:
54
+ | Symbol | Kind | Description |
55
+ | ------------------ | -------------------- | --------------------------------------------------------------- |
56
+ | `HlmSwitch` | Standalone component | `<hlm-switch>` — styled switch with `ControlValueAccessor`. |
57
+ | `HlmSwitchThumb` | Directive | Thumb styling for custom `brn-switch` compositions (see below). |
58
+ | `HlmSwitchImports` | `const` array | `[HlmSwitch, HlmSwitchThumb]` — spread into `imports: [...]`. |
59
+ | `HlmSwitchModule` | NgModule | Imports + re-exports both for NgModule consumers. |
34
60
 
35
- ```bash
36
- cd dist/switch
37
- ```
61
+ ## Anatomy / Structure
38
62
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
63
+ ```html
64
+ <!-- basic -->
65
+ <hlm-switch />
43
66
 
44
- ## Running unit tests
67
+ <!-- with label (always associate a visible label) -->
68
+ <div class="flex items-center gap-2">
69
+ <hlm-switch id="airplane" />
70
+ <label hlmLabel for="airplane">Airplane mode</label>
71
+ </div>
45
72
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
73
+ <!-- two-way binding + change output -->
74
+ <hlm-switch [(checked)]="enabled" (changed)="onChanged($event)" />
47
75
 
48
- ```bash
49
- ng test
76
+ <!-- disabled -->
77
+ <hlm-switch [disabled]="true" />
50
78
  ```
51
79
 
52
- ## Running end-to-end tests
80
+ The component renders an inner `<brn-switch>` + `<brn-switch-thumb hlm>` pair. The outer `<hlm-switch>` host uses `class="contents"` and nulls its own `id`/`aria-*` attributes — set `id`, `aria-label`, `aria-labelledby`, `aria-describedby` as inputs and they are forwarded to the inner `brn-switch`.
53
81
 
54
- For end-to-end (e2e) testing, run:
82
+ ## API reference
55
83
 
56
- ```bash
57
- ng e2e
84
+ ### `HlmSwitch` — selector `hlm-switch` (component, `ControlValueAccessor`)
85
+
86
+ | Input | Type | Default | Description |
87
+ | ------------------ | ------------------------------------------- | ------- | ---------------------------------------------------------------------- |
88
+ | `checked` | `model<boolean>` (two-way bindable) | `false` | Checked state. Supports `[(checked)]`. |
89
+ | `disabled` | `boolean` (coerced with `booleanAttribute`) | `false` | Disabled state (also set via `setDisabledState` from forms). |
90
+ | `id` | `string \| null` | `null` | Forwarded to the inner `<brn-switch>` `id` (pairs with `<label for>`). |
91
+ | `aria-label` | `string \| null` (alias `ariaLabel`) | `null` | Forwarded `aria-label`. |
92
+ | `aria-labelledby` | `string \| null` (alias `ariaLabelledby`) | `null` | Forwarded `aria-labelledby`. |
93
+ | `aria-describedby` | `string \| null` (alias `ariaDescribedby`) | `null` | Forwarded `aria-describedby` (e.g. hint text id). |
94
+ | `class` | `ClassValue` (aliased input `userClass`) | `''` | Extra classes merged onto the inner `brn-switch` track. |
95
+
96
+ | Output | Type | Description |
97
+ | --------- | --------- | ----------------------------------------- |
98
+ | `changed` | `boolean` | Emits whenever the checked state changes. |
99
+
100
+ `ControlValueAccessor` methods (used by Angular forms, not called directly): `writeValue(value: boolean)`, `registerOnChange(fn)`, `registerOnTouched(fn)`, `setDisabledState(isDisabled: boolean)`. Also exports `EG_SWITCH_VALUE_ACCESSOR` (`NG_VALUE_ACCESSOR` provider).
101
+
102
+ ### `HlmSwitchThumb` — selector `brn-switch-thumb[hlm], [hlmSwitchThumb]` (directive)
103
+
104
+ Thin styling directive for hand-built `brn-switch` compositions. Only one input:
105
+
106
+ | Input | Type | Default | Description |
107
+ | ------- | ------------ | ------- | -------------------------------------------- |
108
+ | `class` | `ClassValue` | `''` | Extra classes merged onto the thumb element. |
109
+
110
+ You rarely need this — `<hlm-switch>` already includes `<brn-switch-thumb hlm />` internally.
111
+
112
+ ## Examples
113
+
114
+ ### 1. Basic usage with label
115
+
116
+ ```ts
117
+ // demo-basic.component.ts
118
+ import { Component } from '@angular/core';
119
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
120
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
121
+
122
+ @Component({
123
+ selector: 'demo-basic',
124
+ standalone: true,
125
+ imports: [...HlmSwitchImports, HlmLabel],
126
+ template: `
127
+ <div class="flex items-center gap-2">
128
+ <hlm-switch id="airplane" />
129
+ <label hlmLabel for="airplane">Airplane mode</label>
130
+ </div>
131
+ `,
132
+ })
133
+ export class DemoBasic {}
134
+ ```
135
+
136
+ ### 2. Two-way binding + `changed` output
137
+
138
+ ```ts
139
+ // demo-bound.component.ts
140
+ import { Component, signal } from '@angular/core';
141
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
142
+
143
+ @Component({
144
+ selector: 'demo-bound',
145
+ standalone: true,
146
+ imports: [...HlmSwitchImports],
147
+ template: `
148
+ <hlm-switch [(checked)]="enabled" (changed)="log($event)" aria-label="Enable notifications" />
149
+ <p class="text-sm text-muted-foreground">Notifications {{ enabled() ? 'on' : 'off' }}</p>
150
+ `,
151
+ })
152
+ export class DemoBound {
153
+ readonly enabled = signal(true);
154
+
155
+ log(v: boolean) {
156
+ console.log('switch changed:', v);
157
+ }
158
+ }
159
+ ```
160
+
161
+ ### 3. Reactive forms (`formControl`)
162
+
163
+ `HlmSwitch` implements `ControlValueAccessor`, so `formControl` / `formControlName` work directly.
164
+
165
+ ```ts
166
+ // demo-reactive.component.ts
167
+ import { Component } from '@angular/core';
168
+ import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
169
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
170
+
171
+ @Component({
172
+ selector: 'demo-reactive',
173
+ standalone: true,
174
+ imports: [...HlmSwitchImports, ReactiveFormsModule],
175
+ template: `
176
+ <form [formGroup]="form" class="flex items-center gap-2">
177
+ <hlm-switch formControlName="marketing" id="marketing" />
178
+ <label for="marketing">Marketing emails</label>
179
+ </form>
180
+ <p class="text-sm">Value: {{ form.value | json }}</p>
181
+ `,
182
+ })
183
+ export class DemoReactive {
184
+ readonly form = new FormGroup({ marketing: new FormControl(false) });
185
+ }
58
186
  ```
59
187
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
188
+ ### 4. Template-driven forms (`ngModel`)
189
+
190
+ ```ts
191
+ // demo-template.component.ts
192
+ import { Component } from '@angular/core';
193
+ import { FormsModule } from '@angular/forms';
194
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
195
+
196
+ @Component({
197
+ selector: 'demo-template',
198
+ standalone: true,
199
+ imports: [...HlmSwitchImports, FormsModule],
200
+ template: `
201
+ <hlm-switch [(ngModel)]="dark" name="dark" aria-label="Dark mode" />
202
+ <p class="text-sm">Dark mode {{ dark ? 'on' : 'off' }}</p>
203
+ `,
204
+ })
205
+ export class DemoTemplate {
206
+ dark = false;
207
+ }
208
+ ```
209
+
210
+ ### 5. Disabled / loading states
211
+
212
+ ```ts
213
+ // demo-states.component.ts
214
+ import { Component, signal } from '@angular/core';
215
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
216
+
217
+ @Component({
218
+ selector: 'demo-states',
219
+ standalone: true,
220
+ imports: [...HlmSwitchImports],
221
+ template: `
222
+ <div class="flex flex-col gap-3">
223
+ <div class="flex items-center gap-2">
224
+ <hlm-switch [checked]="true" [disabled]="true" />
225
+ <span class="text-sm">On, disabled</span>
226
+ </div>
227
+ <div class="flex items-center gap-2">
228
+ <hlm-switch [checked]="false" [disabled]="true" />
229
+ <span class="text-sm">Off, disabled</span>
230
+ </div>
231
+ <div class="flex items-center gap-2">
232
+ <hlm-switch [disabled]="saving()" aria-label="Sync" />
233
+ <span class="text-sm">{{ saving() ? 'Saving…' : 'Sync enabled' }}</span>
234
+ </div>
235
+ </div>
236
+ `,
237
+ })
238
+ export class DemoStates {
239
+ readonly saving = signal(true);
240
+ }
241
+ ```
242
+
243
+ > Disabled switches render `cursor-not-allowed` + `opacity-50` automatically via `data-[disabled=true]` styles.
244
+
245
+ ### 6. Advanced: settings list + custom thumb composition
246
+
247
+ Settings-list pattern with descriptions wired via `aria-describedby`:
248
+
249
+ ```ts
250
+ // demo-settings.component.ts
251
+ import { Component, signal } from '@angular/core';
252
+ import { HlmSwitchImports } from '@egose/shadcn-theme-ng/switch';
253
+
254
+ @Component({
255
+ selector: 'demo-settings',
256
+ standalone: true,
257
+ imports: [...HlmSwitchImports],
258
+ template: `
259
+ <div class="flex items-center justify-between gap-4 rounded-lg border p-4">
260
+ <div>
261
+ <p class="text-sm font-medium">Two-factor authentication</p>
262
+ <p id="tfa-hint" class="text-sm text-muted-foreground">Require a code at sign-in.</p>
263
+ </div>
264
+ <hlm-switch [(checked)]="tfa" aria-describedby="tfa-hint" aria-label="Two-factor authentication" />
265
+ </div>
266
+ `,
267
+ })
268
+ export class DemoSettings {
269
+ readonly tfa = signal(false);
270
+ }
271
+ ```
272
+
273
+ Custom composition with `HlmSwitchThumb` directly on a `brn-switch` (rare — only when you need full control of the track):
274
+
275
+ ```ts
276
+ // demo-custom.component.ts
277
+ import { Component } from '@angular/core';
278
+ import { BrnSwitch, BrnSwitchThumb } from '@spartan-ng/brain/switch';
279
+ import { HlmSwitchThumb } from '@egose/shadcn-theme-ng/switch';
280
+
281
+ @Component({
282
+ selector: 'demo-custom',
283
+ standalone: true,
284
+ imports: [BrnSwitch, BrnSwitchThumb, HlmSwitchThumb],
285
+ template: `
286
+ <brn-switch class="my-track-classes">
287
+ <brn-switch-thumb hlm class="my-thumb-overrides" />
288
+ </brn-switch>
289
+ `,
290
+ })
291
+ export class DemoCustom {}
292
+ ```
293
+
294
+ ## Accessibility notes
295
+
296
+ - A switch must always have an accessible name: pair it with a visible `<label>` (via matching `id`/`for`), or set `aria-label` / `aria-labelledby`.
297
+ - Use `aria-describedby` to associate hint text, as in the settings example above.
298
+ - The inner `brn-switch` handles `role="switch"`, `aria-checked`, and keyboard interaction (Space/Enter); do not add your own key handlers.
299
+ - Disabled switches are exposed as `aria-disabled`/`data-[disabled=true]` — keep them focusable-visible but non-interactive, and explain _why_ they are disabled in nearby text when it is not obvious.
300
+ - Prefer switches for immediate-effect on/off settings; use a checkbox for multi-select or form-submission choices.
301
+
302
+ ## Theming / CSS variables
303
+
304
+ The track uses theme tokens (`data-[state=checked]:bg-primary`, `bg-input`, `border-ring`, `ring-ring/50`) and the thumb uses `bg-background` / dark-mode `bg-foreground` / `bg-primary-foreground` shifts. Both follow your shadcn CSS-variable theme. Pass `class` to append/override track utilities (merged with `hlm()`).
61
305
 
62
- ## Additional Resources
306
+ ## Related subpaths
63
307
 
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.
308
+ - `@egose/shadcn-theme-ng/label` — accessible labels for switches.
309
+ - `@egose/shadcn-theme-ng/checkbox` — alternative boolean control for forms.
310
+ - `@egose/shadcn-theme-ng/form-checkbox` — labeled checkbox+description field pattern.
311
+ - `@egose/shadcn-theme-ng/toggle` — press-state button (vs. a switch track).
@@ -8,10 +8,10 @@ class HlmSwitchThumb {
8
8
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
9
9
  _computedClass = computed(() => hlm('tw:bg-background tw:dark:group-data-[state=unchecked]:bg-foreground tw:dark:group-data-[state=checked]:bg-primary-foreground tw:pointer-events-none tw:block tw:size-4 tw:rounded-full tw:ring-0 tw:transition-transform tw:data-[state=unchecked]:translate-x-0 tw:group-data-[state=checked]:translate-x-[calc(100%-2px)]', this.userClass()), /* @ts-ignore */
10
10
  ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
11
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchThumb, deps: [], target: i0.ɵɵFactoryTarget.Directive });
12
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: HlmSwitchThumb, isStandalone: true, selector: "brn-switch-thumb[hlm],[hlmSwitchThumb]", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchThumb, deps: [], target: i0.ɵɵFactoryTarget.Directive });
12
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmSwitchThumb, isStandalone: true, selector: "brn-switch-thumb[hlm],[hlmSwitchThumb]", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "_computedClass()" } }, ngImport: i0 });
13
13
  }
14
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchThumb, decorators: [{
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchThumb, decorators: [{
15
15
  type: Directive,
16
16
  args: [{
17
17
  selector: 'brn-switch-thumb[hlm],[hlmSwitchThumb]',
@@ -69,12 +69,11 @@ class HlmSwitch {
69
69
  setDisabledState(isDisabled) {
70
70
  this._disabled.set(isDisabled);
71
71
  }
72
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitch, deps: [], target: i0.ɵɵFactoryTarget.Component });
73
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: HlmSwitch, isStandalone: true, selector: "hlm-switch", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", 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 } }, outputs: { checked: "checkedChange", changed: "changed" }, host: { properties: { "attr.id": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" }, classAttribute: "contents" }, providers: [EG_SWITCH_VALUE_ACCESSOR], ngImport: i0, template: `
72
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitch, deps: [], target: i0.ɵɵFactoryTarget.Component });
73
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.3", type: HlmSwitch, isStandalone: true, selector: "hlm-switch", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", 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 } }, outputs: { checked: "checkedChange", changed: "changed" }, host: { properties: { "attr.id": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" }, classAttribute: "contents" }, providers: [EG_SWITCH_VALUE_ACCESSOR], ngImport: i0, template: `
74
74
  <brn-switch
75
75
  [class]="_computedClass()"
76
76
  [checked]="checked()"
77
- @ts-ignore
78
77
  (changed)="handleChange($event)"
79
78
  (touched)="_onTouched?.()"
80
79
  [disabled]="_disabled()"
@@ -87,13 +86,13 @@ class HlmSwitch {
87
86
  </brn-switch>
88
87
  `, isInline: true, dependencies: [{ kind: "component", type: BrnSwitchThumb, selector: "brn-switch-thumb" }, { kind: "component", type: BrnSwitch, selector: "brn-switch", inputs: ["checked", "id", "name", "class", "hostStyles", "size", "aria-label", "aria-labelledby", "aria-describedby", "required", "disabled", "tabIndex"], outputs: ["checkedChange", "touched"] }, { kind: "directive", type: HlmSwitchThumb, selector: "brn-switch-thumb[hlm],[hlmSwitchThumb]", inputs: ["class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
89
88
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitch, decorators: [{
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitch, decorators: [{
91
90
  type: Component,
92
91
  args: [{
93
92
  selector: 'hlm-switch',
94
93
  imports: [BrnSwitchThumb, BrnSwitch, HlmSwitchThumb],
95
94
  host: {
96
- class: 'contents',
95
+ class: "tw:contents",
97
96
  '[attr.id]': 'null',
98
97
  '[attr.aria-label]': 'null',
99
98
  '[attr.aria-labelledby]': 'null',
@@ -104,7 +103,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
104
103
  <brn-switch
105
104
  [class]="_computedClass()"
106
105
  [checked]="checked()"
107
- @ts-ignore
108
106
  (changed)="handleChange($event)"
109
107
  (touched)="_onTouched?.()"
110
108
  [disabled]="_disabled()"
@@ -126,11 +124,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
126
124
  */
127
125
  const HlmSwitchImports = [HlmSwitch, HlmSwitchThumb];
128
126
  class HlmSwitchModule {
129
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
130
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchModule, imports: [HlmSwitch, HlmSwitchThumb], exports: [HlmSwitch, HlmSwitchThumb] });
131
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchModule, imports: [HlmSwitch] });
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
128
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchModule, imports: [HlmSwitch, HlmSwitchThumb], exports: [HlmSwitch, HlmSwitchThumb] });
129
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchModule, imports: [HlmSwitch] });
132
130
  }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSwitchModule, decorators: [{
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSwitchModule, decorators: [{
134
132
  type: NgModule,
135
133
  args: [{
136
134
  imports: [...HlmSwitchImports],
@@ -143,4 +141,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
143
141
  */
144
142
 
145
143
  export { EG_SWITCH_VALUE_ACCESSOR, HlmSwitch, HlmSwitchImports, HlmSwitchModule, HlmSwitchThumb };
146
- //# sourceMappingURL=switch.mjs.map
144
+