@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
package/kbd/README.md CHANGED
@@ -1,11 +1,297 @@
1
- # Kbd
1
+ # Kbd (`@egose/shadcn-theme-ng/kbd`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli).
3
+ Keyboard-keycap (`<kbd>`) styling for shortcut hints, ported from shadcn/ui `kbd`. There is no interactive primitive underneath — these are thin presentational directives that attach the shadcn keycap look (muted background, fixed `h-5` height, rounded, mono-adjacent `text-xs` label) plus a grouping row directive for multi-key chords such as `Ctrl + K`.
4
4
 
5
- ## Building
5
+ Ships as `@egose/shadcn-theme-ng/kbd` and `@egose/shadcn-theme-ng-tw/kbd` (tw: variant). See the [package README](../../README.md) for installation, peer dependencies, Tailwind setup, and testing. Do not publish this project directory independently.
6
6
 
7
- To build the library, run:
7
+ ## Installation
8
8
 
9
9
  ```bash
10
- ng build kbd
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
  ```
16
+
17
+ Peer dependencies are inherited from the package root (see [package README](../../README.md) — `@angular/core`, `@angular/common`, `@spartan-ng/brain`, `rxjs`, `@ng-icons/core`). This subpath itself declares `@angular/common`, `@angular/core`, `@spartan-ng/brain` as peers plus a `tslib` runtime dependency. No extra install step is needed beyond the package install above.
18
+
19
+ ## Imports
20
+
21
+ Real exported symbols (from `src/public-api.ts`):
22
+
23
+ ```ts
24
+ import {
25
+ HlmKbd, // directive: kbd[hlmKbd]
26
+ HlmKbdGroup, // directive: kbd[hlmKbdGroup]
27
+ HlmKbdImports, // readonly [HlmKbd, HlmKbdGroup]
28
+ HlmKbdModule, // NgModule wrapping HlmKbdImports
29
+ } from '@egose/shadcn-theme-ng/kbd';
30
+ ```
31
+
32
+ Standalone usage:
33
+
34
+ ```ts
35
+ import { Component } from '@angular/core';
36
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
37
+
38
+ @Component({
39
+ selector: 'app-demo',
40
+ standalone: true,
41
+ imports: [...HlmKbdImports],
42
+ template: `<kbd hlmKbd>⌘</kbd>`,
43
+ })
44
+ export class DemoComponent {}
45
+ ```
46
+
47
+ NgModule usage:
48
+
49
+ ```ts
50
+ import { NgModule } from '@angular/core';
51
+ import { HlmKbdModule } from '@egose/shadcn-theme-ng/kbd';
52
+
53
+ @NgModule({ imports: [HlmKbdModule] })
54
+ export class DemoModule {}
55
+ ```
56
+
57
+ For the `tw:` build, swap the specifier to `@egose/shadcn-theme-ng-tw/kbd`. Symbol names are identical.
58
+
59
+ ## Anatomy / Structure
60
+
61
+ ```html
62
+ <!-- Single key -->
63
+ <kbd hlmKbd>Ctrl</kbd>
64
+
65
+ <!-- Chord / sequence: outer kbd carries the group layout, inner kbds carry keycap styling -->
66
+ <kbd hlmKbdGroup>
67
+ <kbd hlmKbd>Ctrl</kbd>
68
+ <span>+</span>
69
+ <kbd hlmKbd>K</kbd>
70
+ </kbd hlmKbdGroup>
71
+ ```
72
+
73
+ | Class | Selector | Element | Role |
74
+ | ------------- | ------------------ | ------------ | ------------------------------------- |
75
+ | `HlmKbd` | `kbd[hlmKbd]` | `<kbd>` only | Single keycap |
76
+ | `HlmKbdGroup` | `kbd[hlmKbdGroup]` | `<kbd>` only | Inline-flex row that lays out a chord |
77
+
78
+ Both selectors require a native `<kbd>` host. Applying `hlmKbd` to a `<span>` or `<div>` will not match and no styles are applied. Both set a `data-slot` host attribute (`kbd` / `kbd-group`) used by downstream tooltip overrides.
79
+
80
+ ## API reference
81
+
82
+ Neither directive declares any `input()`, `output()`, method, or signal. They are pure styling directives: the constructor calls `classes(() => '…')` from `@egose/shadcn-theme-ng/utils`. All customization is via the host element itself (text content, `class`, `title`, `aria-*`).
83
+
84
+ | Selector | Inputs | Outputs | Notes |
85
+ | ------------------ | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
86
+ | `kbd[hlmKbd]` | — | — | `data-slot="kbd"`. Fixed keycap treatment: `h-5 w-fit min-w-5`, `rounded-sm`, `bg-muted text-muted-foreground`, `pointer-events-none select-none`, inline-flex centered. Includes `in-data-[slot=tooltip-content]` overrides so keys stay legible inside tooltips (light and dark). Icon sizing rule `[&_ng-icon:not([class*='text-'])]:text-[length:--spacing(3)]` normalizes bare `ng-icon` children. |
87
+ | `kbd[hlmKbdGroup]` | — | — | `data-slot="kbd-group"`. `inline-flex items-center gap-1`. Nest `HlmKbd` keycaps plus literal separators inside. |
88
+
89
+ ## Examples
90
+
91
+ ### 1. Basic single key
92
+
93
+ A lone keycap next to an action label.
94
+
95
+ ```ts
96
+ import { Component } from '@angular/core';
97
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
98
+
99
+ @Component({
100
+ selector: 'app-kbd-basic',
101
+ standalone: true,
102
+ imports: [...HlmKbdImports],
103
+ template: ` <p>Press <kbd hlmKbd>Enter</kbd> to submit.</p> `,
104
+ })
105
+ export class KbdBasicComponent {}
106
+ ```
107
+
108
+ ```html
109
+ <p>Press <kbd hlmKbd>Enter</kbd> to submit.</p>
110
+ ```
111
+
112
+ ### 2. Keyboard chord (Ctrl + K)
113
+
114
+ The canonical command-palette hint. The outer `kbd[hlmKbdGroup]` provides the row; inner keycaps provide the boxes.
115
+
116
+ ```ts
117
+ import { Component } from '@angular/core';
118
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
119
+
120
+ @Component({
121
+ selector: 'app-kbd-chord',
122
+ standalone: true,
123
+ imports: [...HlmKbdImports],
124
+ template: `
125
+ <div class="tw:flex tw:items-center tw:gap-2 tw:text-sm tw:text-muted-foreground">
126
+ <span>Search</span>
127
+ <kbd hlmKbdGroup>
128
+ <kbd hlmKbd>Ctrl</kbd>
129
+ <span>+</span>
130
+ <kbd hlmKbd>K</kbd>
131
+ </kbd>
132
+ </div>
133
+ `,
134
+ })
135
+ export class KbdChordComponent {}
136
+ ```
137
+
138
+ ```html
139
+ <div class="tw:flex tw:items-center tw:gap-2 tw:text-sm tw:text-muted-foreground">
140
+ <span>Search</span>
141
+ <kbd hlmKbdGroup>
142
+ <kbd hlmKbd>Ctrl</kbd>
143
+ <span>+</span>
144
+ <kbd hlmKbd>K</kbd>
145
+ </kbd>
146
+ </div>
147
+ ```
148
+
149
+ ### 3. macOS-style symbols and sequences
150
+
151
+ ```ts
152
+ import { Component } from '@angular/core';
153
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
154
+
155
+ @Component({
156
+ selector: 'app-kbd-symbols',
157
+ standalone: true,
158
+ imports: [...HlmKbdImports],
159
+ template: `
160
+ <ul class="tw:flex tw:flex-col tw:gap-2 tw:text-sm">
161
+ <li class="tw:flex tw:items-center tw:gap-2">
162
+ <span class="tw:w-32">Copy</span>
163
+ <kbd hlmKbdGroup><kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>C</kbd></kbd>
164
+ </li>
165
+ <li class="tw:flex tw:items-center tw:gap-2">
166
+ <span class="tw:w-32">Save</span>
167
+ <kbd hlmKbdGroup><kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>S</kbd></kbd>
168
+ </li>
169
+ <li class="tw:flex tw:items-center tw:gap-2">
170
+ <span class="tw:w-32">Close window</span>
171
+ <kbd hlmKbdGroup>
172
+ <kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>Shift</kbd><span>+</span><kbd hlmKbd>W</kbd>
173
+ </kbd>
174
+ </li>
175
+ </ul>
176
+ `,
177
+ })
178
+ export class KbdSymbolsComponent {}
179
+ ```
180
+
181
+ ### 4. Inside buttons, inputs, and menus
182
+
183
+ Keycaps are `pointer-events-none`, so they compose safely inside interactive parents.
184
+
185
+ ```ts
186
+ import { Component } from '@angular/core';
187
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
188
+ import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
189
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
190
+
191
+ @Component({
192
+ selector: 'app-kbd-composed',
193
+ standalone: true,
194
+ imports: [...HlmKbdImports, ...HlmButtonImports, HlmInput],
195
+ template: `
196
+ <div class="tw:flex tw:flex-col tw:gap-3 tw:max-w-sm">
197
+ <button hlmButton variant="secondary" appearance="outline" type="button">
198
+ <span>Command palette</span>
199
+ <kbd hlmKbdGroup class="tw:ml-auto">
200
+ <kbd hlmKbd>Ctrl</kbd>
201
+ <span>+</span>
202
+ <kbd hlmKbd>K</kbd>
203
+ </kbd>
204
+ </button>
205
+
206
+ <label class="tw:flex tw:flex-col tw:gap-1 tw:text-sm">
207
+ <span class="tw:flex tw:items-center tw:gap-2"> Search <kbd hlmKbd>/</kbd> </span>
208
+ <input hlmInput placeholder="Type here, or press / to focus" />
209
+ </label>
210
+ </div>
211
+ `,
212
+ })
213
+ export class KbdComposedComponent {}
214
+ ```
215
+
216
+ ### 5. Shortcut legend / settings table
217
+
218
+ ```ts
219
+ import { Component, signal } from '@angular/core';
220
+ import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
221
+
222
+ interface Shortcut {
223
+ action: string;
224
+ keys: string[];
225
+ }
226
+
227
+ @Component({
228
+ selector: 'app-kbd-legend',
229
+ standalone: true,
230
+ imports: [...HlmKbdImports],
231
+ template: `
232
+ <table class="tw:w-full tw:text-sm">
233
+ <tbody>
234
+ @for (s of shortcuts(); track s.action) {
235
+ <tr class="tw:border-b">
236
+ <td class="tw:py-2">{{ s.action }}</td>
237
+ <td class="tw:py-2 tw:text-right">
238
+ <kbd hlmKbdGroup class="tw:justify-end">
239
+ @for (k of s.keys; track k; let last = $last) {
240
+ <kbd hlmKbd>{{ k }}</kbd>
241
+ @if (!last) {
242
+ <span>+</span>
243
+ }
244
+ }
245
+ </kbd>
246
+ </td>
247
+ </tr>
248
+ }
249
+ </tbody>
250
+ </table>
251
+ `,
252
+ })
253
+ export class KbdLegendComponent {
254
+ readonly shortcuts = signal<Shortcut[]>([
255
+ { action: 'Undo', keys: ['Ctrl', 'Z'] },
256
+ { action: 'Redo', keys: ['Ctrl', 'Shift', 'Z'] },
257
+ { action: 'Toggle sidebar', keys: ['Ctrl', 'B'] },
258
+ ]);
259
+ }
260
+ ```
261
+
262
+ ### 6. NgModule consumer
263
+
264
+ ```ts
265
+ import { NgModule, Component } from '@angular/core';
266
+ import { HlmKbdModule } from '@egose/shadcn-theme-ng/kbd';
267
+
268
+ @Component({
269
+ selector: 'app-kbd-legacy',
270
+ template: `<kbd hlmKbd>Esc</kbd> to close.`,
271
+ })
272
+ export class KbdLegacyComponent {}
273
+
274
+ @NgModule({
275
+ declarations: [KbdLegacyComponent],
276
+ imports: [HlmKbdModule],
277
+ exports: [KbdLegacyComponent],
278
+ })
279
+ export class KbdLegacyModule {}
280
+ ```
281
+
282
+ ## Accessibility notes
283
+
284
+ - `<kbd>` is natively semantic ("keyboard input"). Keep the text content exactly what the user presses (`Ctrl`, not `Control` unless that is the label on the keyboard).
285
+ - For chords, screen readers linearize the group content; the `+` separators are announced. If verbosity matters, add an `aria-label` on the group (e.g. `aria-label="Control plus K"`) — plain HTML, no library input needed.
286
+ - Do not put interactive content inside a keycap: `HlmKbd` is `pointer-events-none` by design.
287
+ - `title`/`aria-keyshortcuts` belong on the _action_ that the shortcut triggers (e.g. the button), not on the `<kbd>` itself.
288
+
289
+ ## Theming / CSS variables
290
+
291
+ No component inputs. Styling keys off shadcn semantic tokens (`bg-muted`, `text-muted-foreground`, `bg-background` inside tooltip content) so dark mode and theme overrides flow through automatically. Add extra utilities via `class` on the host `<kbd>` (merged by the `classes()` helper).
292
+
293
+ ## Related subpaths
294
+
295
+ - `@egose/shadcn-theme-ng/tooltip` — keycaps render legibly inside tooltip content via the built-in `in-data-[slot=tooltip-content]` overrides.
296
+ - `@egose/shadcn-theme-ng/menu` (`HlmMenuShortcut`) — right-aligned shortcut column inside menus; use `kbd` keycaps inside it for key chords.
297
+ - `@egose/shadcn-theme-ng/button`, `@egose/shadcn-theme-ng/input` — common parents for inline shortcut hints.
@@ -6,10 +6,10 @@ class HlmKbd {
6
6
  constructor() {
7
7
  classes(() => "bg-muted text-muted-foreground in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 h-5 w-fit min-w-5 gap-1 rounded-sm px-1 font-sans text-xs font-medium [&_ng-icon:not([class*='text-'])]:text-[length:--spacing(3)] pointer-events-none inline-flex items-center justify-center select-none");
8
8
  }
9
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbd, deps: [], target: i0.ɵɵFactoryTarget.Directive });
10
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: HlmKbd, isStandalone: true, selector: "kbd[hlmKbd]", host: { attributes: { "data-slot": "kbd" } }, ngImport: i0 });
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbd, deps: [], target: i0.ɵɵFactoryTarget.Directive });
10
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmKbd, isStandalone: true, selector: "kbd[hlmKbd]", host: { attributes: { "data-slot": "kbd" } }, ngImport: i0 });
11
11
  }
12
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbd, decorators: [{
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbd, decorators: [{
13
13
  type: Directive,
14
14
  args: [{
15
15
  selector: 'kbd[hlmKbd]',
@@ -21,12 +21,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
21
21
 
22
22
  class HlmKbdGroup {
23
23
  constructor() {
24
- classes(() => 'gap-1 inline-flex items-center');
24
+ classes(() => "gap-1 inline-flex items-center");
25
25
  }
26
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
27
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: HlmKbdGroup, isStandalone: true, selector: "kbd[hlmKbdGroup]", host: { attributes: { "data-slot": "kbd-group" } }, ngImport: i0 });
26
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
27
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmKbdGroup, isStandalone: true, selector: "kbd[hlmKbdGroup]", host: { attributes: { "data-slot": "kbd-group" } }, ngImport: i0 });
28
28
  }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdGroup, decorators: [{
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdGroup, decorators: [{
30
30
  type: Directive,
31
31
  args: [{
32
32
  selector: 'kbd[hlmKbdGroup]',
@@ -41,11 +41,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
41
41
  */
42
42
  const HlmKbdImports = [HlmKbd, HlmKbdGroup];
43
43
  class HlmKbdModule {
44
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
45
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdModule, imports: [HlmKbd, HlmKbdGroup], exports: [HlmKbd, HlmKbdGroup] });
46
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdModule });
44
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
45
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdModule, imports: [HlmKbd, HlmKbdGroup], exports: [HlmKbd, HlmKbdGroup] });
46
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdModule });
47
47
  }
48
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmKbdModule, decorators: [{
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmKbdModule, decorators: [{
49
49
  type: NgModule,
50
50
  args: [{
51
51
  imports: [...HlmKbdImports],
@@ -58,4 +58,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
58
58
  */
59
59
 
60
60
  export { HlmKbd, HlmKbdGroup, HlmKbdImports, HlmKbdModule };
61
- //# sourceMappingURL=kbd.mjs.map
61
+
package/label/README.md CHANGED
@@ -1,64 +1,273 @@
1
- # Label
1
+ # Label (`@egose/shadcn-theme-ng/label`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.2.0.
3
+ Form-field label ported from shadcn/ui `label` (Radix Label equivalent). A thin directive wrapper around the spartan-ng `BrnLabel` brain primitive: it forwards label semantics/association (`id`, `for`) to `BrnLabel` via host directives and adds the shadcn label treatment (small medium-weight text plus disabled-state dimming that reacts to `peer`/`group`/`has-[[disabled]]` context).
4
4
 
5
- ## Code scaffolding
5
+ Ships as `@egose/shadcn-theme-ng/label` and `@egose/shadcn-theme-ng-tw/label` (tw: variant). See the [package README](../../README.md) for installation, peer dependencies, Tailwind setup, and testing. 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
+ Peer dependencies are inherited from the package root (see [package README](../../README.md)). This subpath itself declares `@angular/common`, `@angular/core`, `@spartan-ng/brain` as peers plus a `tslib` runtime dependency. No extra install step is needed beyond the package install above.
14
18
 
15
- ```bash
16
- ng generate --help
19
+ ## Imports
20
+
21
+ Real exported symbols (from `src/public-api.ts`):
22
+
23
+ ```ts
24
+ import {
25
+ HlmLabel, // directive: [hlmLabel]
26
+ HlmLabelImports, // readonly [HlmLabel]
27
+ HlmLabelModule, // NgModule wrapping HlmLabelImports
28
+ } from '@egose/shadcn-theme-ng/label';
17
29
  ```
18
30
 
19
- ## Building
31
+ Standalone usage:
20
32
 
21
- To build the library, run:
33
+ ```ts
34
+ import { Component } from '@angular/core';
35
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
22
36
 
23
- ```bash
24
- ng build label
37
+ @Component({
38
+ selector: 'app-demo',
39
+ standalone: true,
40
+ imports: [...HlmLabelImports],
41
+ template: `<label hlmLabel for="email">Email</label>`,
42
+ })
43
+ export class DemoComponent {}
25
44
  ```
26
45
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
46
+ NgModule usage:
28
47
 
29
- ### Publishing the Library
48
+ ```ts
49
+ import { NgModule } from '@angular/core';
50
+ import { HlmLabelModule } from '@egose/shadcn-theme-ng/label';
30
51
 
31
- Once the project is built, you can publish your library by following these steps:
52
+ @NgModule({ imports: [HlmLabelModule] })
53
+ export class DemoModule {}
54
+ ```
32
55
 
33
- 1. Navigate to the `dist` directory:
56
+ For the `tw:` build, swap the specifier to `@egose/shadcn-theme-ng-tw/label`. Symbol names are identical.
34
57
 
35
- ```bash
36
- cd dist/label
37
- ```
58
+ ## Anatomy / Structure
38
59
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
60
+ ```html
61
+ <label hlmLabel for="email">Email address</label>
62
+ <input hlmInput id="email" type="email" />
43
63
 
44
- ## Running unit tests
64
+ <!-- extra classes merge via class input -->
65
+ <label hlmLabel for="bio" class="tw:mb-2">Bio</label>
66
+ ```
45
67
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
68
+ | Class | Selector | Element | Role |
69
+ | ---------- | ------------ | -------------------------------------- | --------------------------------- |
70
+ | `HlmLabel` | `[hlmLabel]` | any labelable host, normally `<label>` | Accessible label + shadcn styling |
47
71
 
48
- ```bash
49
- ng test
72
+ `HlmLabel` declares `hostDirectives: [{ directive: BrnLabel, inputs: ['id', 'for'] }]`, so the `id` and `for` bindings you write on the host are forwarded to the brain directive that owns label association.
73
+
74
+ ## API reference
75
+
76
+ ### `HlmLabel` (`[hlmLabel]`)
77
+
78
+ | Member | Kind | Type / Default | Notes |
79
+ | --------------------- | ------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
80
+ | `id` | input (via `BrnLabel` host directive) | `string` | Forwarded to `BrnLabel`. Rarely set on the label itself. |
81
+ | `for` | input (via `BrnLabel` host directive) | `string` | Forwarded to `BrnLabel`. Associates the label with the control whose `id` matches. |
82
+ | `userClass` (`class`) | input | `ClassValue`, default `''` | Extra Tailwind/classes merged after the base label classes via `hlm()`. |
83
+ | `_computedClass` | protected computed | `string` | Base: `flex select-none items-center gap-2 text-sm font-medium leading-none` plus disabled dimming: `peer-disabled:cursor-not-allowed peer-disabled:opacity-50`, `has-[[disabled]]:cursor-not-allowed has-[[disabled]]:opacity-50`, `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50`, `peer-data-[disabled]:cursor-not-allowed peer-data-[disabled]:opacity-50`. |
84
+
85
+ No outputs, methods, or signals beyond the inputs above.
86
+
87
+ ## Examples
88
+
89
+ ### 1. Basic label + input
90
+
91
+ ```ts
92
+ import { Component } from '@angular/core';
93
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
94
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
95
+
96
+ @Component({
97
+ selector: 'app-label-basic',
98
+ standalone: true,
99
+ imports: [...HlmLabelImports, HlmInput],
100
+ template: `
101
+ <div class="tw:grid tw:gap-1.5">
102
+ <label hlmLabel for="email">Email</label>
103
+ <input hlmInput id="email" type="email" placeholder="you@example.com" />
104
+ </div>
105
+ `,
106
+ })
107
+ export class LabelBasicComponent {}
50
108
  ```
51
109
 
52
- ## Running end-to-end tests
110
+ ```html
111
+ <div class="tw:grid tw:gap-1.5">
112
+ <label hlmLabel for="email">Email</label>
113
+ <input hlmInput id="email" type="email" placeholder="you@example.com" />
114
+ </div>
115
+ ```
53
116
 
54
- For end-to-end (e2e) testing, run:
117
+ ### 2. Required marker and hint text
55
118
 
56
- ```bash
57
- ng e2e
119
+ ```ts
120
+ import { Component } from '@angular/core';
121
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
122
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
123
+
124
+ @Component({
125
+ selector: 'app-label-required',
126
+ standalone: true,
127
+ imports: [...HlmLabelImports, HlmInput],
128
+ template: `
129
+ <div class="tw:grid tw:gap-1.5">
130
+ <label hlmLabel for="username">
131
+ Username
132
+ <span aria-hidden="true" class="tw:text-destructive">*</span>
133
+ <span class="tw:sr-only">(required)</span>
134
+ </label>
135
+ <input hlmInput id="username" required minlength="3" placeholder="ada_lovelace" />
136
+ <p class="tw:text-xs tw:text-muted-foreground">Lowercase letters, numbers, underscores.</p>
137
+ </div>
138
+ `,
139
+ })
140
+ export class LabelRequiredComponent {}
141
+ ```
142
+
143
+ ### 3. Template-driven form
144
+
145
+ ```ts
146
+ import { Component } from '@angular/core';
147
+ import { FormsModule } from '@angular/forms';
148
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
149
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
150
+
151
+ @Component({
152
+ selector: 'app-label-template-driven',
153
+ standalone: true,
154
+ imports: [FormsModule, ...HlmLabelImports, HlmInput],
155
+ template: `
156
+ <form #f="ngForm" class="tw:grid tw:gap-4">
157
+ <div class="tw:grid tw:gap-1.5">
158
+ <label hlmLabel for="displayName">Display name</label>
159
+ <input hlmInput id="displayName" name="displayName" [(ngModel)]="name" required />
160
+ </div>
161
+ <p class="tw:text-sm tw:text-muted-foreground">Hello, {{ name || 'stranger' }}.</p>
162
+ </form>
163
+ `,
164
+ })
165
+ export class LabelTemplateDrivenComponent {
166
+ name = '';
167
+ }
58
168
  ```
59
169
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
170
+ ### 4. Reactive form with disabled state
171
+
172
+ The label dims automatically when the associated control is a disabled `peer` (or inside a disabled group) thanks to the built-in `peer-disabled:` / `group-data-[disabled=true]:` rules.
173
+
174
+ ```ts
175
+ import { Component } from '@angular/core';
176
+ import { ReactiveFormsModule, FormControl, FormGroup } from '@angular/forms';
177
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
178
+ import { HlmInput } from '@egose/shadcn-theme-ng/input';
179
+
180
+ @Component({
181
+ selector: 'app-label-reactive',
182
+ standalone: true,
183
+ imports: [ReactiveFormsModule, ...HlmLabelImports, HlmInput],
184
+ template: `
185
+ <form [formGroup]="form" class="tw:grid tw:gap-4">
186
+ <div class="tw:grid tw:gap-1.5">
187
+ <label hlmLabel for="company">Company</label>
188
+ <input hlmInput id="company" class="tw:peer" formControlName="company" />
189
+ </div>
190
+ <label class="tw:flex tw:items-center tw:gap-2 tw:text-sm">
191
+ <input type="checkbox" (change)="toggleDisabled()" />
192
+ Disable company field
193
+ </label>
194
+ </form>
195
+ `,
196
+ })
197
+ export class LabelReactiveComponent {
198
+ readonly form = new FormGroup({
199
+ company: new FormControl({ value: 'Acme', disabled: false }),
200
+ });
201
+
202
+ toggleDisabled(): void {
203
+ const control = this.form.controls.company;
204
+ control.disabled ? control.enable() : control.disable();
205
+ }
206
+ }
207
+ ```
208
+
209
+ > Add `class="tw:peer"` to the input so the label's `peer-disabled:` rule can observe it. Without the `peer` class the label still dims via the `has-[[disabled]]` fallback when the control is nested in the same wrapper.
210
+
211
+ ### 5. Checkbox / switch labels and custom spacing
212
+
213
+ ```ts
214
+ import { Component } from '@angular/core';
215
+ import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
216
+ import { HlmCheckbox } from '@egose/shadcn-theme-ng/checkbox';
217
+ import { HlmSwitch } from '@egose/shadcn-theme-ng/switch';
218
+
219
+ @Component({
220
+ selector: 'app-label-checks',
221
+ standalone: true,
222
+ imports: [...HlmLabelImports, HlmCheckbox, HlmSwitch],
223
+ template: `
224
+ <div class="tw:flex tw:flex-col tw:gap-4">
225
+ <div class="tw:flex tw:items-center tw:gap-2">
226
+ <hlm-checkbox id="marketing" />
227
+ <label hlmLabel for="marketing" class="tw:cursor-pointer">Email me product news</label>
228
+ </div>
229
+ <div class="tw:flex tw:items-center tw:gap-2">
230
+ <hlm-switch id="notifications" />
231
+ <label hlmLabel for="notifications">Push notifications</label>
232
+ </div>
233
+ </div>
234
+ `,
235
+ })
236
+ export class LabelChecksComponent {}
237
+ ```
238
+
239
+ ### 6. NgModule consumer
240
+
241
+ ```ts
242
+ import { NgModule, Component } from '@angular/core';
243
+ import { HlmLabelModule } from '@egose/shadcn-theme-ng/label';
244
+
245
+ @Component({
246
+ selector: 'app-label-legacy',
247
+ template: `<label hlmLabel for="city">City</label>`,
248
+ })
249
+ export class LabelLegacyComponent {}
250
+
251
+ @NgModule({
252
+ declarations: [LabelLegacyComponent],
253
+ imports: [HlmLabelModule],
254
+ exports: [LabelLegacyComponent],
255
+ })
256
+ export class LabelLegacyModule {}
257
+ ```
258
+
259
+ ## Accessibility notes
260
+
261
+ - Always pair `for` with the control's `id` (or nest the control inside the `<label>`). The `for` binding is forwarded to `BrnLabel`, which owns the association semantics.
262
+ - Keep label text visible and concise; use `aria-hidden` + `sr-only` for decorative markers like `*` (see example 2).
263
+ - Do not use `placeholder` as a label substitute — the shadcn label treatment assumes a real `<label>` element.
264
+ - The disabled dimming is visual only; disable the control itself (`disabled` attribute / `FormControl.disable()`) so assistive tech reports the state.
265
+
266
+ ## Theming / CSS variables
267
+
268
+ No theming inputs. The label inherits `text-sm font-medium` and theme tokens automatically; pass extra utilities via `class` (merged by `hlm()` after the base classes, so yours win on conflict).
61
269
 
62
- ## Additional Resources
270
+ ## Related subpaths
63
271
 
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.
272
+ - `@egose/shadcn-theme-ng/input`, `@egose/shadcn-theme-ng/textarea`, `@egose/shadcn-theme-ng/checkbox`, `@egose/shadcn-theme-ng/switch` — controls that `for`/`id` pairs target.
273
+ - `@egose/shadcn-theme-ng/form-field`, `@egose/shadcn-theme-ng/form-field-simple` — higher-level field wrappers that compose labels with errors and hints.