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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/README.md +130 -13
  2. package/accordion/README.md +376 -34
  3. package/accordion/fesm2022/accordion.mjs +20 -20
  4. package/alert/README.md +343 -34
  5. package/alert/fesm2022/alert.mjs +18 -18
  6. package/alert-dialog/README.md +471 -5
  7. package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
  8. package/alert-dialog/types/alert-dialog.d.ts +1 -1
  9. package/aspect-ratio/README.md +272 -5
  10. package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
  11. package/autocomplete/README.md +473 -34
  12. package/autocomplete/fesm2022/autocomplete.mjs +54 -54
  13. package/autocomplete/types/autocomplete.d.ts +1 -1
  14. package/avatar/README.md +357 -5
  15. package/avatar/fesm2022/avatar.mjs +32 -32
  16. package/badge/README.md +289 -34
  17. package/badge/fesm2022/badge.mjs +4 -4
  18. package/basic-alert/README.md +324 -34
  19. package/basic-alert/fesm2022/basic-alert.mjs +4 -4
  20. package/basic-alert/types/basic-alert.d.ts +1 -1
  21. package/breadcrumb/README.md +406 -5
  22. package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
  23. package/button/README.md +453 -34
  24. package/button/fesm2022/button.mjs +96 -118
  25. package/button/types/button.d.ts +7 -10
  26. package/button-group/README.md +318 -5
  27. package/button-group/fesm2022/button-group.mjs +20 -20
  28. package/calendar/README.md +328 -34
  29. package/calendar/fesm2022/calendar.mjs +154 -154
  30. package/card/README.md +331 -5
  31. package/card/fesm2022/card.mjs +33 -33
  32. package/carousel/README.md +333 -5
  33. package/carousel/fesm2022/carousel.mjs +47 -44
  34. package/carousel/types/carousel.d.ts +1 -1
  35. package/checkbox/README.md +291 -34
  36. package/checkbox/fesm2022/checkbox.mjs +22 -20
  37. package/checkbox/types/checkbox.d.ts +5 -4
  38. package/collapsible/README.md +332 -5
  39. package/collapsible/fesm2022/collapsible.mjs +15 -15
  40. package/combobox/README.md +507 -5
  41. package/combobox/fesm2022/combobox.mjs +95 -92
  42. package/combobox/types/combobox.d.ts +1 -1
  43. package/command/README.md +435 -5
  44. package/command/fesm2022/command.mjs +56 -56
  45. package/confirmation-dialog/README.md +272 -34
  46. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
  47. package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
  48. package/context-menu/README.md +366 -5
  49. package/context-menu/fesm2022/context-menu.mjs +9 -9
  50. package/date-picker/README.md +436 -34
  51. package/date-picker/fesm2022/date-picker.mjs +79 -68
  52. package/date-picker/types/date-picker.d.ts +8 -4
  53. package/dialog/README.md +419 -34
  54. package/dialog/fesm2022/dialog.mjs +48 -48
  55. package/drawer/README.md +395 -5
  56. package/drawer/fesm2022/drawer.mjs +45 -45
  57. package/dropdown-menu/README.md +417 -5
  58. package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
  59. package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
  60. package/empty/README.md +329 -5
  61. package/empty/fesm2022/empty.mjs +31 -31
  62. package/field/README.md +385 -5
  63. package/field/fesm2022/field.mjs +59 -59
  64. package/field/types/field.d.ts +1 -1
  65. package/form-checkbox/README.md +283 -34
  66. package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
  67. package/form-checkbox/types/form-checkbox.d.ts +7 -1
  68. package/form-date-picker/README.md +293 -34
  69. package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
  70. package/form-date-picker/types/form-date-picker.d.ts +7 -1
  71. package/form-field/README.md +327 -34
  72. package/form-field/fesm2022/form-field.mjs +30 -16
  73. package/form-field/types/form-field.d.ts +28 -20
  74. package/form-field-simple/README.md +311 -34
  75. package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
  76. package/form-searchable-multiselect/README.md +332 -34
  77. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
  78. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
  79. package/form-select/README.md +321 -34
  80. package/form-select/fesm2022/form-select.mjs +62 -29
  81. package/form-select/types/form-select.d.ts +7 -1
  82. package/form-text-input/README.md +342 -34
  83. package/form-text-input/fesm2022/form-text-input.mjs +43 -55
  84. package/form-text-input/types/form-text-input.d.ts +9 -12
  85. package/form-textarea/README.md +318 -34
  86. package/form-textarea/fesm2022/form-textarea.mjs +42 -23
  87. package/form-textarea/types/form-textarea.d.ts +8 -1
  88. package/hover-card/README.md +256 -5
  89. package/hover-card/fesm2022/hover-card.mjs +19 -19
  90. package/icon/README.md +210 -34
  91. package/icon/fesm2022/icon.mjs +8 -8
  92. package/input/README.md +240 -34
  93. package/input/fesm2022/input.mjs +17 -12
  94. package/input/types/input.d.ts +2 -1
  95. package/input-group/README.md +335 -5
  96. package/input-group/fesm2022/input-group.mjs +37 -37
  97. package/input-group/types/input-group.d.ts +3 -3
  98. package/input-otp/README.md +375 -5
  99. package/input-otp/fesm2022/input-otp.mjs +27 -27
  100. package/item/README.md +385 -5
  101. package/item/fesm2022/item.mjs +54 -54
  102. package/kbd/README.md +291 -5
  103. package/kbd/fesm2022/kbd.mjs +13 -13
  104. package/label/README.md +243 -34
  105. package/label/fesm2022/label.mjs +9 -9
  106. package/label/types/label.d.ts +1 -1
  107. package/layout-simple/README.md +174 -44
  108. package/layout-simple/fesm2022/layout-simple.mjs +917 -398
  109. package/layout-simple/types/layout-simple.d.ts +180 -129
  110. package/menu/README.md +418 -0
  111. package/menu/fesm2022/menu.mjs +461 -0
  112. package/menu/package.json +24 -0
  113. package/menu/types/menu.d.ts +137 -0
  114. package/menubar/README.md +343 -5
  115. package/menubar/fesm2022/menubar.mjs +13 -13
  116. package/native-select/README.md +323 -5
  117. package/native-select/fesm2022/native-select.mjs +19 -19
  118. package/navigation-menu/README.md +369 -5
  119. package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
  120. package/package.json +183 -154
  121. package/pagination/README.md +388 -5
  122. package/pagination/fesm2022/pagination.mjs +63 -63
  123. package/popover/README.md +302 -34
  124. package/popover/fesm2022/popover.mjs +30 -30
  125. package/progress/README.md +311 -5
  126. package/progress/fesm2022/progress.mjs +13 -13
  127. package/radio-group/README.md +335 -34
  128. package/radio-group/fesm2022/radio-group.mjs +26 -19
  129. package/resizable/README.md +269 -5
  130. package/resizable/fesm2022/resizable.mjs +19 -19
  131. package/scroll-area/README.md +233 -5
  132. package/scroll-area/fesm2022/scroll-area.mjs +9 -9
  133. package/searchable-multiselect/README.md +294 -34
  134. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
  135. package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
  136. package/select/README.md +408 -34
  137. package/select/fesm2022/select.mjs +80 -72
  138. package/select/types/select.d.ts +3 -1
  139. package/separator/README.md +193 -34
  140. package/separator/fesm2022/separator.mjs +9 -9
  141. package/separator/types/separator.d.ts +1 -1
  142. package/sheet/README.md +282 -34
  143. package/sheet/fesm2022/sheet.mjs +30 -30
  144. package/sidebar/README.md +457 -5
  145. package/sidebar/fesm2022/sidebar.mjs +136 -134
  146. package/sidebar/types/sidebar.d.ts +3 -3
  147. package/skeleton/README.md +217 -5
  148. package/skeleton/fesm2022/skeleton.mjs +9 -9
  149. package/slider/README.md +273 -5
  150. package/slider/fesm2022/slider.mjs +29 -25
  151. package/sonner/README.md +317 -34
  152. package/sonner/fesm2022/sonner.mjs +9 -9
  153. package/spinner/README.md +255 -34
  154. package/spinner/fesm2022/spinner.mjs +8 -8
  155. package/switch/README.md +281 -34
  156. package/switch/fesm2022/switch.mjs +12 -14
  157. package/table/README.md +423 -5
  158. package/table/fesm2022/table.mjs +41 -41
  159. package/tabs/README.md +382 -34
  160. package/tabs/fesm2022/tabs.mjs +48 -38
  161. package/textarea/README.md +282 -5
  162. package/textarea/fesm2022/textarea.mjs +9 -9
  163. package/toggle/README.md +270 -5
  164. package/toggle/fesm2022/toggle.mjs +14 -14
  165. package/toggle-group/README.md +340 -5
  166. package/toggle-group/fesm2022/toggle-group.mjs +13 -13
  167. package/toggle-group/types/toggle-group.d.ts +13 -7
  168. package/tooltip/README.md +240 -34
  169. package/tooltip/fesm2022/tooltip.mjs +14 -14
  170. package/typography/README.md +271 -5
  171. package/typography/fesm2022/typography.mjs +53 -53
  172. package/typography/types/typography.d.ts +12 -12
  173. package/utils/README.md +274 -34
  174. package/utils/fesm2022/utils.mjs +68 -44
  175. package/accordion/fesm2022/accordion.mjs.map +0 -1
  176. package/alert/fesm2022/alert.mjs.map +0 -1
  177. package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
  178. package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
  179. package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
  180. package/avatar/fesm2022/avatar.mjs.map +0 -1
  181. package/badge/fesm2022/badge.mjs.map +0 -1
  182. package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
  183. package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
  184. package/button/fesm2022/button.mjs.map +0 -1
  185. package/button-group/fesm2022/button-group.mjs.map +0 -1
  186. package/calendar/fesm2022/calendar.mjs.map +0 -1
  187. package/card/fesm2022/card.mjs.map +0 -1
  188. package/carousel/fesm2022/carousel.mjs.map +0 -1
  189. package/checkbox/fesm2022/checkbox.mjs.map +0 -1
  190. package/collapsible/fesm2022/collapsible.mjs.map +0 -1
  191. package/combobox/fesm2022/combobox.mjs.map +0 -1
  192. package/command/fesm2022/command.mjs.map +0 -1
  193. package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
  194. package/context-menu/fesm2022/context-menu.mjs.map +0 -1
  195. package/date-picker/fesm2022/date-picker.mjs.map +0 -1
  196. package/dialog/fesm2022/dialog.mjs.map +0 -1
  197. package/drawer/fesm2022/drawer.mjs.map +0 -1
  198. package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
  199. package/empty/fesm2022/empty.mjs.map +0 -1
  200. package/field/fesm2022/field.mjs.map +0 -1
  201. package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
  202. package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
  203. package/form-field/fesm2022/form-field.mjs.map +0 -1
  204. package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
  205. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
  206. package/form-select/fesm2022/form-select.mjs.map +0 -1
  207. package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
  208. package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
  209. package/hover-card/fesm2022/hover-card.mjs.map +0 -1
  210. package/icon/fesm2022/icon.mjs.map +0 -1
  211. package/input/fesm2022/input.mjs.map +0 -1
  212. package/input-group/fesm2022/input-group.mjs.map +0 -1
  213. package/input-otp/fesm2022/input-otp.mjs.map +0 -1
  214. package/item/fesm2022/item.mjs.map +0 -1
  215. package/kbd/fesm2022/kbd.mjs.map +0 -1
  216. package/label/fesm2022/label.mjs.map +0 -1
  217. package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
  218. package/menubar/fesm2022/menubar.mjs.map +0 -1
  219. package/native-select/fesm2022/native-select.mjs.map +0 -1
  220. package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
  221. package/pagination/fesm2022/pagination.mjs.map +0 -1
  222. package/popover/fesm2022/popover.mjs.map +0 -1
  223. package/progress/fesm2022/progress.mjs.map +0 -1
  224. package/radio-group/fesm2022/radio-group.mjs.map +0 -1
  225. package/resizable/fesm2022/resizable.mjs.map +0 -1
  226. package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
  227. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
  228. package/select/fesm2022/select.mjs.map +0 -1
  229. package/separator/fesm2022/separator.mjs.map +0 -1
  230. package/sheet/fesm2022/sheet.mjs.map +0 -1
  231. package/sidebar/fesm2022/sidebar.mjs.map +0 -1
  232. package/skeleton/fesm2022/skeleton.mjs.map +0 -1
  233. package/slider/fesm2022/slider.mjs.map +0 -1
  234. package/sonner/fesm2022/sonner.mjs.map +0 -1
  235. package/spinner/fesm2022/spinner.mjs.map +0 -1
  236. package/switch/fesm2022/switch.mjs.map +0 -1
  237. package/table/fesm2022/table.mjs.map +0 -1
  238. package/tabs/fesm2022/tabs.mjs.map +0 -1
  239. package/textarea/fesm2022/textarea.mjs.map +0 -1
  240. package/toggle/fesm2022/toggle.mjs.map +0 -1
  241. package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
  242. package/tooltip/fesm2022/tooltip.mjs.map +0 -1
  243. package/typography/fesm2022/typography.mjs.map +0 -1
  244. package/utils/fesm2022/utils.mjs.map +0 -1
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Signal, ValueProvider } from '@angular/core';
3
3
  import { ClassValue } from 'clsx';
4
- import * as i1 from '@egose/shadcn-theme-ng/input';
4
+ import * as i1 from '@egose/shadcn-theme-ng-tw/input';
5
5
  import { BooleanInput } from '@angular/cdk/coercion';
6
6
  import * as i1$1 from '@spartan-ng/brain/tooltip';
7
- import * as i1$2 from '@egose/shadcn-theme-ng/separator';
8
- import * as i1$3 from '@egose/shadcn-theme-ng/button';
7
+ import * as i1$2 from '@egose/shadcn-theme-ng-tw/separator';
8
+ import * as i1$3 from '@egose/shadcn-theme-ng-tw/button';
9
9
 
10
10
  type SidebarVariant = 'sidebar' | 'floating' | 'inset';
11
11
  declare class HlmSidebarService {
@@ -1,11 +1,223 @@
1
- # Skeleton
1
+ # Skeleton (`@egose/shadcn-theme-ng/skeleton`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli).
3
+ A shadcn/ui-style **Skeleton** — a pulsing placeholder block shown while content loads. This is the Angular equivalent of shadcn/ui `Skeleton`.
4
4
 
5
- ## Building
5
+ It has **no behavior and no primitive underneath**: a single thin directive (`[hlmSkeleton]` / `hlm-skeleton`) that paints any host element with the muted pulse styling (`bg-muted`, rounded, `motion-safe:animate-pulse`). Size it with your own utilities.
6
6
 
7
- To build the library, run:
7
+ > **Ships as:** `@egose/shadcn-theme-ng/skeleton` and `@egose/shadcn-theme-ng-tw/skeleton` (the `tw:`-prefixed Tailwind variant — same API, class strings prefixed with `tw:`).
8
+ > See the [package README](../../README.md) for installation, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
9
+
10
+ ## Installation
8
11
 
9
12
  ```bash
10
- ng build skeleton
13
+ # Plain Tailwind (no prefix)
14
+ npm install @egose/shadcn-theme-ng
15
+
16
+ # Or the tw:-prefixed variant
17
+ npm install @egose/shadcn-theme-ng-tw
18
+ ```
19
+
20
+ ```ts
21
+ import { HlmSkeletonImports } from '@egose/shadcn-theme-ng/skeleton';
22
+ // tw variant:
23
+ // import { HlmSkeletonImports } from '@egose/shadcn-theme-ng-tw/skeleton';
24
+ ```
25
+
26
+ Peer dependencies (see [package README](../../README.md) for versions): `@angular/core`, `@angular/common`, `@spartan-ng/brain` (declared peer; the directive itself uses none of its APIs).
27
+
28
+ ## Imports
29
+
30
+ Real exported symbols (from `src/public-api.ts`):
31
+
32
+ | Symbol | Kind | Description |
33
+ | -------------------- | ------------- | -------------------------------------------------------------- |
34
+ | `HlmSkeleton` | Directive | The placeholder styling; selector `[hlmSkeleton],hlm-skeleton` |
35
+ | `HlmSkeletonImports` | `const` array | `[HlmSkeleton]` standalone imports |
36
+ | `HlmSkeletonModule` | `NgModule` | NgModule wrapper re-exporting `HlmSkeleton` |
37
+
38
+ Standalone usage:
39
+
40
+ ```ts
41
+ import { Component } from '@angular/core';
42
+ import { HlmSkeletonImports } from '@egose/shadcn-theme-ng/skeleton';
43
+
44
+ @Component({
45
+ selector: 'app-demo',
46
+ standalone: true,
47
+ imports: [HlmSkeletonImports],
48
+ template: `<hlm-skeleton class="tw:h-12 tw:w-full" />`,
49
+ })
50
+ export class DemoComponent {}
51
+ ```
52
+
53
+ NgModule usage:
54
+
55
+ ```ts
56
+ import { NgModule } from '@angular/core';
57
+ import { HlmSkeletonModule } from '@egose/shadcn-theme-ng/skeleton';
58
+
59
+ @NgModule({ imports: [HlmSkeletonModule] })
60
+ export class DemoModule {}
61
+ ```
62
+
63
+ ## Anatomy / Structure
64
+
65
+ ```html
66
+ <!-- Element form -->
67
+ <hlm-skeleton class="tw:h-4 tw:w-48" />
68
+
69
+ <!-- Attribute form on any element -->
70
+ <div hlmSkeleton class="tw:h-24 tw:w-full"></div>
71
+ ```
72
+
73
+ Real selectors:
74
+
75
+ | Selector | Class | Notes |
76
+ | ---------------------------- | ------------- | -------------------------------------------------------------------------------------- |
77
+ | `[hlmSkeleton],hlm-skeleton` | `HlmSkeleton` | `data-slot="skeleton"`; `block`, `rounded-md`, `bg-muted`, `motion-safe:animate-pulse` |
78
+
79
+ The directive declares **no inputs, outputs, or methods**. All sizing/spacing comes from classes you add.
80
+
81
+ ## API reference
82
+
83
+ `HlmSkeleton` has no API surface beyond its selector — it only applies styling classes to its host. There are no inputs (use the `class` attribute directly), no outputs, and no methods.
84
+
85
+ ## Examples
86
+
87
+ ### 1. Basic placeholders
88
+
89
+ ```html
90
+ <hlm-skeleton class="tw:h-4 tw:w-48" />
91
+ <hlm-skeleton class="tw:h-8 tw:w-full" />
92
+ <div hlmSkeleton class="tw:size-12 tw:rounded-full"></div>
93
+ ```
94
+
95
+ ### 2. Card loading state
96
+
97
+ ```ts
98
+ import { Component, signal } from '@angular/core';
99
+ import { HlmSkeletonImports } from '@egose/shadcn-theme-ng/skeleton';
100
+
101
+ @Component({
102
+ selector: 'app-card-loading',
103
+ standalone: true,
104
+ imports: [HlmSkeletonImports],
105
+ template: `
106
+ @if (loading()) {
107
+ <div class="tw:flex tw:items-center tw:gap-4">
108
+ <div hlmSkeleton class="tw:size-12 tw:rounded-full"></div>
109
+ <div class="tw:space-y-2">
110
+ <hlm-skeleton class="tw:h-4 tw:w-48" />
111
+ <hlm-skeleton class="tw:h-4 tw:w-32" />
112
+ </div>
113
+ </div>
114
+ } @else {
115
+ <div class="tw:flex tw:items-center tw:gap-4">
116
+ <img [src]="user().avatar" alt="" class="tw:size-12 tw:rounded-full" />
117
+ <div>
118
+ <p>{{ user().name }}</p>
119
+ <p class="tw:text-muted-foreground tw:text-sm">{{ user().email }}</p>
120
+ </div>
121
+ </div>
122
+ }
123
+ `,
124
+ })
125
+ export class CardLoadingComponent {
126
+ readonly loading = signal(true);
127
+ readonly user = signal({ name: 'Ada', email: 'ada@example.com', avatar: '/avatar.png' });
128
+ }
129
+ ```
130
+
131
+ Match skeleton sizes to the real content sizes to avoid layout shift when data arrives.
132
+
133
+ ### 3. List / table rows
134
+
135
+ ```html
136
+ <ul class="tw:space-y-2">
137
+ @for (i of [1, 2, 3, 4, 5]; track i) {
138
+ <li class="tw:flex tw:items-center tw:gap-3">
139
+ <div hlmSkeleton class="tw:size-8 tw:rounded-md"></div>
140
+ <hlm-skeleton class="tw:h-4 tw:flex-1" />
141
+ <hlm-skeleton class="tw:h-4 tw:w-16" />
142
+ </li>
143
+ }
144
+ </ul>
145
+ ```
146
+
147
+ ### 4. Async data with `resource`
148
+
149
+ ```ts
150
+ import { Component, resource } from '@angular/core';
151
+ import { HlmSkeletonImports } from '@egose/shadcn-theme-ng/skeleton';
152
+
153
+ @Component({
154
+ selector: 'app-async-profile',
155
+ standalone: true,
156
+ imports: [HlmSkeletonImports],
157
+ template: `
158
+ @if (profile.isLoading()) {
159
+ <div class="tw:space-y-3">
160
+ <hlm-skeleton class="tw:h-6 tw:w-1/3" />
161
+ <hlm-skeleton class="tw:h-4 tw:w-full" />
162
+ <hlm-skeleton class="tw:h-4 tw:w-2/3" />
163
+ </div>
164
+ } @else if (profile.error()) {
165
+ <p class="tw:text-destructive tw:text-sm">Failed to load profile.</p>
166
+ } @else {
167
+ <h2>{{ profile.value()?.name }}</h2>
168
+ <p>{{ profile.value()?.bio }}</p>
169
+ }
170
+ `,
171
+ })
172
+ export class AsyncProfileComponent {
173
+ readonly profile = resource({
174
+ loader: async () => {
175
+ const res = await fetch('/api/profile');
176
+ return (await res.json()) as { name: string; bio: string };
177
+ },
178
+ });
179
+ }
11
180
  ```
181
+
182
+ ### 5. Form skeleton
183
+
184
+ ```html
185
+ <form aria-busy="true" aria-label="Loading form">
186
+ <div class="tw:grid tw:gap-4">
187
+ <hlm-skeleton class="tw:h-4 tw:w-24" />
188
+ <hlm-skeleton class="tw:h-9 tw:w-full" />
189
+ <hlm-skeleton class="tw:h-4 tw:w-24" />
190
+ <hlm-skeleton class="tw:h-20 tw:w-full" />
191
+ <hlm-skeleton class="tw:h-9 tw:w-28" />
192
+ </div>
193
+ </form>
194
+ ```
195
+
196
+ ### 6. Sidebar menu skeletons (composition)
197
+
198
+ The `sidebar` subpath reuses this directive in `HlmSidebarMenuSkeleton` — but you can also compose manually:
199
+
200
+ ```html
201
+ <div hlmSidebarContent>
202
+ <hlm-skeleton class="tw:mb-2 tw:h-8 tw:w-full" />
203
+ <hlm-skeleton class="tw:mb-2 tw:h-8 tw:w-full" />
204
+ <hlm-skeleton class="tw:h-8 tw:w-3/4" />
205
+ </div>
206
+ ```
207
+
208
+ ## Accessibility notes
209
+
210
+ - Skeletons are visual placeholders: hide them from assistive tech (`aria-hidden="true"` on the skeleton container) and expose a single loading status instead (`role="status"` + `aria-busy="true"` on the loading region, or an `aria-live` announcement).
211
+ - The pulse animation is gated behind `motion-safe:` — users with reduced-motion preferences see a static block. Do not add your own infinite animations on top.
212
+ - Keep skeleton geometry close to the final content so focus order and scroll position don't jump when content swaps in; move focus deliberately (e.g. to an error message) on load failure.
213
+
214
+ ## Theming / CSS variables
215
+
216
+ One token: `bg-muted` block color (follows light/dark theme). Shape via border-radius utilities, motion via the built-in `motion-safe:animate-pulse`.
217
+
218
+ ## Related subpaths
219
+
220
+ - `@egose/shadcn-theme-ng/sidebar` — `HlmSidebarMenuSkeleton` composes this directive for nav loading states
221
+ - `@egose/shadcn-theme-ng/card` — containers commonly filled with skeleton rows while loading
222
+ - `@egose/shadcn-theme-ng/table` — tables that show skeleton rows during fetches
223
+ - `@egose/shadcn-theme-ng/spinner` — determinate/indeterminate activity indicator alternative
@@ -4,12 +4,12 @@ import { classes } from '@egose/shadcn-theme-ng-tw/utils';
4
4
 
5
5
  class HlmSkeleton {
6
6
  constructor() {
7
- classes(() => 'bg-muted rounded-md block motion-safe:animate-pulse');
7
+ classes(() => 'tw:bg-muted tw:rounded-md tw:block tw:motion-safe:animate-pulse');
8
8
  }
9
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
10
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: HlmSkeleton, isStandalone: true, selector: "[hlmSkeleton],hlm-skeleton", host: { attributes: { "data-slot": "skeleton" } }, ngImport: i0 });
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
10
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmSkeleton, isStandalone: true, selector: "[hlmSkeleton],hlm-skeleton", host: { attributes: { "data-slot": "skeleton" } }, ngImport: i0 });
11
11
  }
12
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeleton, decorators: [{
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeleton, decorators: [{
13
13
  type: Directive,
14
14
  args: [{
15
15
  selector: '[hlmSkeleton],hlm-skeleton',
@@ -24,11 +24,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
24
24
  */
25
25
  const HlmSkeletonImports = [HlmSkeleton];
26
26
  class HlmSkeletonModule {
27
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeletonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
28
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeletonModule, imports: [HlmSkeleton], exports: [HlmSkeleton] });
29
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeletonModule });
27
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeletonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
28
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeletonModule, imports: [HlmSkeleton], exports: [HlmSkeleton] });
29
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeletonModule });
30
30
  }
31
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: HlmSkeletonModule, decorators: [{
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmSkeletonModule, decorators: [{
32
32
  type: NgModule,
33
33
  args: [{
34
34
  imports: [...HlmSkeletonImports],
@@ -41,4 +41,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
41
41
  */
42
42
 
43
43
  export { HlmSkeleton, HlmSkeletonImports, HlmSkeletonModule };
44
- //# sourceMappingURL=skeleton.mjs.map
44
+
package/slider/README.md CHANGED
@@ -1,11 +1,279 @@
1
- # Slider
1
+ # Slider (`@egose/shadcn-theme-ng/slider`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli).
3
+ A shadcn/ui-style **Slider** — a draggable track with one or more thumbs for picking numeric value(s). This is the Angular equivalent of shadcn/ui `Slider`.
4
4
 
5
- ## Building
5
+ Behavior comes from **spartan-ng/brain** (`BrnSlider` + `BrnSliderImports`: track/range/thumb/tick structural pieces, keyboard support, min/max/step, multi-thumb, orientation, ticks formatting). This package is the shadcn skin: a `hlm-slider` (or `brn-slider [hlm]`) component that forwards the full brain slider API via host directives and renders the muted track, primary range fill, circular thumbs, and optional tick labels.
6
6
 
7
- To build the library, run:
7
+ > **Ships as:** `@egose/shadcn-theme-ng/slider` and `@egose/shadcn-theme-ng-tw/slider` (the `tw:`-prefixed Tailwind variant — same API, class strings prefixed with `tw:`).
8
+ > See the [package README](../../README.md) for installation, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
9
+
10
+ ## Installation
8
11
 
9
12
  ```bash
10
- ng build slider
13
+ # Plain Tailwind (no prefix)
14
+ npm install @egose/shadcn-theme-ng
15
+
16
+ # Or the tw:-prefixed variant
17
+ npm install @egose/shadcn-theme-ng-tw
18
+ ```
19
+
20
+ ```ts
21
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
22
+ // tw variant:
23
+ // import { HlmSliderImports } from '@egose/shadcn-theme-ng-tw/slider';
24
+ ```
25
+
26
+ Peer dependencies (see [package README](../../README.md) for versions): `@angular/core`, `@angular/common`, `@spartan-ng/brain`.
27
+
28
+ ## Imports
29
+
30
+ Real exported symbols (from `src/public-api.ts`):
31
+
32
+ | Symbol | Kind | Description |
33
+ | ------------------ | ------------- | ------------------------------------------------------------------------- |
34
+ | `HlmSlider` | Component | The slider; selector `hlm-slider, brn-slider [hlm]`; forwards `BrnSlider` |
35
+ | `HlmSliderImports` | `const` array | `[HlmSlider]` standalone imports |
36
+ | `HlmSliderModule` | `NgModule` | NgModule wrapper re-exporting `HlmSlider` |
37
+
38
+ Standalone usage:
39
+
40
+ ```ts
41
+ import { Component } from '@angular/core';
42
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
43
+
44
+ @Component({
45
+ selector: 'app-demo',
46
+ standalone: true,
47
+ imports: [HlmSliderImports],
48
+ template: `<hlm-slider [value]="[50]" />`,
49
+ })
50
+ export class DemoComponent {}
51
+ ```
52
+
53
+ NgModule usage:
54
+
55
+ ```ts
56
+ import { NgModule } from '@angular/core';
57
+ import { HlmSliderModule } from '@egose/shadcn-theme-ng/slider';
58
+
59
+ @NgModule({ imports: [HlmSliderModule] })
60
+ export class DemoModule {}
11
61
  ```
62
+
63
+ ## Anatomy / Structure
64
+
65
+ You only write the host element — track, range, thumbs, and ticks render from the component template:
66
+
67
+ ```html
68
+ <!-- Single value -->
69
+ <hlm-slider [value]="[50]" [min]="0" [max]="100" (valueChange)="volume.set($event)" />
70
+
71
+ <!-- Range (two thumbs) -->
72
+ <hlm-slider [value]="[20, 80]" [min]="0" [max]="100" />
73
+
74
+ <!-- Attribute form on an element inside a brain slider host -->
75
+ <brn-slider [value]="[30]">
76
+ <div hlm></div>
77
+ </brn-slider>
78
+ ```
79
+
80
+ Real selectors:
81
+
82
+ | Selector | Class | Notes |
83
+ | -------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
84
+ | `hlm-slider`, `brn-slider [hlm]` | `HlmSlider` | Renders `brnSliderTrack` > `brnSliderRange`, one `brnSliderThumb` per `thumbIndexes()`, and optional `*brnSliderTick` labels (`hlm` goes on an element inside `brn-slider`) |
85
+
86
+ ## API reference
87
+
88
+ ### HlmSlider (component)
89
+
90
+ Thin wrapper — no own inputs. All bindings are forwarded to the `BrnSlider` host directive:
91
+
92
+ | Binding | Kind | Description |
93
+ | ----------------------- | ------ | ----------------------------------------------------------------------------------- |
94
+ | `id` | input | Slider id |
95
+ | `value` | input | Thumb values as array (e.g. `[50]`, `[20, 80]`); use `[(value)]` or `(valueChange)` |
96
+ | `disabled` | input | Disables interaction (dims + `pointer-events-none`) |
97
+ | `min` | input | Minimum value |
98
+ | `max` | input | Maximum value |
99
+ | `step` | input | Step increment |
100
+ | `minStepsBetweenThumbs` | input | Minimum gap (in steps) between thumbs |
101
+ | `inverted` | input | Flip the axis direction |
102
+ | `orientation` | input | `'horizontal' \| 'vertical'` |
103
+ | `showTicks` | input | Render tick labels under/beside the track |
104
+ | `maxTicks` | input | Cap on rendered tick count |
105
+ | `tickLabelInterval` | input | Label every Nth tick |
106
+ | `formatTick` | input | `(tick: number) => string` label formatter |
107
+ | `draggableRange` | input | Allow dragging the range fill between thumbs |
108
+ | `draggableRangeOnly` | input | Only the range (not thumbs) is draggable |
109
+ | `aria-label` | input | Accessible name |
110
+ | `aria-labelledby` | input | Id(s) of labelling element(s) |
111
+ | `valueChange` | output | Emits the new value array on change |
112
+
113
+ Vertical mode needs height from you (`tw:h-40` on the host pulls in `data-vertical:min-h-40` styling); horizontal is full-width by default.
114
+
115
+ ## Examples
116
+
117
+ ### 1. Basic single slider
118
+
119
+ ```ts
120
+ import { Component, signal } from '@angular/core';
121
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
122
+
123
+ @Component({
124
+ selector: 'app-basic-slider',
125
+ standalone: true,
126
+ imports: [HlmSliderImports],
127
+ template: `
128
+ <label id="vol-label" class="tw:mb-2 tw:block tw:text-sm">Volume: {{ volume()[0] }}</label>
129
+ <hlm-slider
130
+ aria-labelledby="vol-label"
131
+ [min]="0"
132
+ [max]="100"
133
+ [step]="1"
134
+ [value]="volume()"
135
+ (valueChange)="volume.set($event)"
136
+ />
137
+ `,
138
+ })
139
+ export class BasicSliderComponent {
140
+ readonly volume = signal<number[]>([50]);
141
+ }
142
+ ```
143
+
144
+ ### 2. Range slider (two thumbs)
145
+
146
+ ```ts
147
+ import { Component, signal } from '@angular/core';
148
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
149
+
150
+ @Component({
151
+ selector: 'app-range-slider',
152
+ standalone: true,
153
+ imports: [HlmSliderImports],
154
+ template: `
155
+ <hlm-slider
156
+ aria-label="Price range"
157
+ [min]="0"
158
+ [max]="500"
159
+ [step]="10"
160
+ [minStepsBetweenThumbs]="1"
161
+ [(value)]="range"
162
+ />
163
+ <p class="tw:mt-2 tw:text-sm">Between ${{ range()[0] }} and ${{ range()[1] }}</p>
164
+ `,
165
+ })
166
+ export class RangeSliderComponent {
167
+ readonly range = signal<number[]>([50, 300]);
168
+ }
169
+ ```
170
+
171
+ ### 3. Reactive forms
172
+
173
+ `BrnSlider` is a `ControlValueAccessor` — bind `formControlName` directly on the host:
174
+
175
+ ```ts
176
+ import { Component } from '@angular/core';
177
+ import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
178
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
179
+
180
+ @Component({
181
+ selector: 'app-form-slider',
182
+ standalone: true,
183
+ imports: [HlmSliderImports, ReactiveFormsModule],
184
+ template: `
185
+ <form [formGroup]="form">
186
+ <label for="brightness" class="tw:mb-2 tw:block tw:text-sm">Brightness</label>
187
+ <hlm-slider id="brightness" formControlName="brightness" [min]="0" [max]="100" />
188
+ <button type="button" (click)="form.controls.brightness.setValue([100])">Max</button>
189
+ </form>
190
+ `,
191
+ })
192
+ export class FormSliderComponent {
193
+ readonly form = new FormGroup({
194
+ brightness: new FormControl<number[]>([70]),
195
+ });
196
+ }
197
+ ```
198
+
199
+ ### 4. Disabled + tick labels
200
+
201
+ ```ts
202
+ import { Component, signal } from '@angular/core';
203
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
204
+
205
+ @Component({
206
+ selector: 'app-ticks-slider',
207
+ standalone: true,
208
+ imports: [HlmSliderImports],
209
+ template: `
210
+ <hlm-slider
211
+ aria-label="Quality"
212
+ [min]="0"
213
+ [max]="100"
214
+ [step]="10"
215
+ showTicks
216
+ [maxTicks]="6"
217
+ [tickLabelInterval]="2"
218
+ [formatTick]="format"
219
+ [(value)]="quality"
220
+ />
221
+
222
+ <hlm-slider class="tw:mt-6" aria-label="Locked setting" [value]="[40]" disabled />
223
+ `,
224
+ })
225
+ export class TicksSliderComponent {
226
+ readonly quality = signal<number[]>([60]);
227
+ readonly format = (tick: number): string => `${tick}%`;
228
+ }
229
+ ```
230
+
231
+ ### 5. Vertical + inverted
232
+
233
+ ```html
234
+ <div class="tw:flex tw:gap-8">
235
+ <hlm-slider class="tw:h-48" aria-label="Balance" orientation="vertical" [min]="0" [max]="100" [(value)]="balance" />
236
+
237
+ <hlm-slider aria-label="Inverted level" inverted [min]="0" [max]="100" [(value)]="level" />
238
+ </div>
239
+ ```
240
+
241
+ Vertical sliders size along the block axis — always give the host an explicit height (e.g. `tw:h-48`).
242
+
243
+ ### 6. Draggable range (select a window, move it whole)
244
+
245
+ ```ts
246
+ import { Component, signal } from '@angular/core';
247
+ import { HlmSliderImports } from '@egose/shadcn-theme-ng/slider';
248
+
249
+ @Component({
250
+ selector: 'app-window-slider',
251
+ standalone: true,
252
+ imports: [HlmSliderImports],
253
+ template: `
254
+ <hlm-slider aria-label="Visible window" [min]="0" [max]="24" [step]="1" draggableRange [(value)]="window" />
255
+ <p class="tw:mt-2 tw:text-sm">Showing hours {{ window()[0] }}–{{ window()[1] }}</p>
256
+ `,
257
+ })
258
+ export class WindowSliderComponent {
259
+ readonly window = signal<number[]>([8, 17]);
260
+ }
261
+ ```
262
+
263
+ ## Accessibility notes
264
+
265
+ - Always name the slider: `aria-label` for standalone use or `aria-labelledby` pointing at a visible label. Without a name, screen-reader users get an anonymous slider.
266
+ - Thumbs are keyboard-operable (arrows/Home/End, per brain) — keep the host focusable (default) and never wrap thumbs in extra focus stops.
267
+ - `disabled` removes interaction and dims the control; for temporarily-unavailable-but-explainable states, prefer keeping it enabled with a described constraint instead.
268
+ - Tick labels are visual annotations; don't rely on them as the only value readout — mirror the current value in text (as in examples 1–2) or an `aria-valuetext` equivalent where the primitive supports it.
269
+
270
+ ## Theming / CSS variables
271
+
272
+ Class-driven (`bg-muted` track, `bg-primary` range, white thumbs with primary border and focus rings). No component-specific CSS variables; density follows the default `size-4` thumbs.
273
+
274
+ ## Related subpaths
275
+
276
+ - `@egose/shadcn-theme-ng/label` — visible labels referenced via `aria-labelledby`
277
+ - `@egose/shadcn-theme-ng/field` / `form-field` — form rows pairing labels, sliders, and hints/errors
278
+ - `@egose/shadcn-theme-ng/progress` — read-only fill-bar counterpart
279
+ - `@egose/shadcn-theme-ng/input` — precise numeric entry to pair with coarse slider input