@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,64 +1,466 @@
1
- # DatePicker
1
+ # Date Picker (`@egose/shadcn-theme-ng/date-picker`)
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
3
+ A shadcn/ui-style date picker for Angular: a popover-anchored calendar with a text-input or button trigger, single-date, multi-date, range, and month/year modes. Equivalent to shadcn/ui `Calendar` + `Popover` composed as a date picker.
4
4
 
5
- ## Code scaffolding
5
+ The Angular implementation is a styling + composition layer over headless primitives: [`BrnDatePicker*` / `BrnDateInput` from `@spartan-ng/brain/date-picker`](https://www.spartan-ng.com/), `BrnPopover` from `@spartan-ng/brain/popover`, `BrnFieldControl` / `provideBrnLabelable` from `@spartan-ng/brain/field`, and the styled `HlmCalendar` / `HlmCalendarMulti` / `HlmCalendarRange` / `HlmMonthYearCalendar` from `@egose/shadcn-theme-ng/calendar` plus `HlmPopoverImports` and `HlmInputGroup` styling. All four picker roots are `ControlValueAccessor`s, so they bind directly to `formControlName` / `ngModel`.
6
6
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
7
+ > **Ships as:** `@egose/shadcn-theme-ng/date-picker` and `@egose/shadcn-theme-ng-tw/date-picker`
8
+ > (the `tw:`-prefixed Tailwind variant). Both expose the identical TypeScript surface; only the
9
+ > emitted Tailwind class strings differ. See the [package README](../../README.md) for install
10
+ > steps, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
11
+
12
+ ## Installation
8
13
 
9
14
  ```bash
10
- ng generate component component-name
15
+ # Plain Tailwind (no prefix)
16
+ npm install @egose/shadcn-theme-ng
17
+
18
+ # tw:-prefixed Tailwind variant
19
+ npm install @egose/shadcn-theme-ng-tw
11
20
  ```
12
21
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
22
+ Peer dependencies (Angular, `@spartan-ng/brain`, `@ng-icons/*`, `rxjs`, …) are documented in the
23
+ [package README](../../README.md#peer-dependencies). This subpath additionally relies at runtime on
24
+ `@egose/shadcn-theme-ng/calendar`, `@egose/shadcn-theme-ng/popover`,
25
+ `@egose/shadcn-theme-ng/input-group`, `@egose/shadcn-theme-ng/button`, and `@ng-icons/lucide`.
14
26
 
15
- ```bash
16
- ng generate --help
27
+ ## Imports
28
+
29
+ All symbols are exported from the subpath root (`projects/date-picker/src/public-api.ts`):
30
+
31
+ ```ts
32
+ import {
33
+ HlmDatePicker,
34
+ HlmDatePickerMulti,
35
+ HlmDateRangePicker,
36
+ HlmMonthYearPicker,
37
+ HlmDatePickerInput,
38
+ HlmDateMultiInput,
39
+ HlmDateRangeInput,
40
+ HlmMonthYearInput,
41
+ HlmDatePickerTrigger,
42
+ HlmDatePickerAnchor,
43
+ HlmDatePickerImports,
44
+ HlmDatePickerModule,
45
+ provideHlmDatePickerConfig,
46
+ injectHlmDatePickerConfig,
47
+ provideHlmDatePickerMultiConfig,
48
+ injectHlmDatePickerMultiConfig,
49
+ provideHlmDateRangePickerConfig,
50
+ injectHlmDateRangePickerConfig,
51
+ provideHlmMonthYearPickerConfig,
52
+ injectHlmMonthYearPickerConfig,
53
+ } from '@egose/shadcn-theme-ng/date-picker';
54
+ // tw variant: replace with '@egose/shadcn-theme-ng-tw/date-picker'
17
55
  ```
18
56
 
19
- ## Building
57
+ Standalone component — spread the `*Imports` array:
20
58
 
21
- To build the library, run:
59
+ ```ts
60
+ import { Component } from '@angular/core';
61
+ import { HlmDatePickerImports } from '@egose/shadcn-theme-ng/date-picker';
22
62
 
23
- ```bash
24
- ng build date-picker
63
+ @Component({
64
+ selector: 'app-demo',
65
+ standalone: true,
66
+ imports: [...HlmDatePickerImports],
67
+ template: `...`,
68
+ })
69
+ export class DemoComponent {}
25
70
  ```
26
71
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
72
+ NgModule-based consumer — import the module:
73
+
74
+ ```ts
75
+ import { NgModule } from '@angular/core';
76
+ import { HlmDatePickerModule } from '@egose/shadcn-theme-ng/date-picker';
28
77
 
29
- ### Publishing the Library
78
+ @NgModule({ imports: [HlmDatePickerModule] })
79
+ export class DemoModule {}
80
+ ```
30
81
 
31
- Once the project is built, you can publish your library by following these steps:
82
+ ## Anatomy / Structure
32
83
 
33
- 1. Navigate to the `dist` directory:
84
+ ```html
85
+ <!-- single date: button trigger -->
86
+ <hlm-date-picker>
87
+ <hlm-date-picker-trigger>Pick a date</hlm-date-picker-trigger>
88
+ </hlm-date-picker>
34
89
 
35
- ```bash
36
- cd dist/date-picker
37
- ```
90
+ <!-- single date: text input trigger -->
91
+ <hlm-date-picker>
92
+ <hlm-date-picker-input placeholder="Pick a date" />
93
+ </hlm-date-picker>
38
94
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
95
+ <!-- multi date -->
96
+ <hlm-date-picker-multi [maxSelection]="3">
97
+ <hlm-date-multi-input placeholder="Pick dates" />
98
+ </hlm-date-picker-multi>
43
99
 
44
- ## Running unit tests
100
+ <!-- range -->
101
+ <hlm-date-range-picker>
102
+ <hlm-date-range-input placeholder="Pick a range" />
103
+ </hlm-date-range-picker>
45
104
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
105
+ <!-- month/year -->
106
+ <hlm-month-year-picker>
107
+ <hlm-month-year-input placeholder="MM/YYYY" />
108
+ </hlm-month-year-picker>
47
109
 
48
- ```bash
49
- ng test
110
+ <!-- optional header/footer projection slots -->
111
+ <hlm-date-picker>
112
+ <hlm-date-picker-input placeholder="Pick a date" />
113
+ <div hlmDatePickerHeader>Custom header</div>
114
+ <div hlmDatePickerFooter>Custom footer</div>
115
+ </hlm-date-picker>
116
+
117
+ <!-- external anchor -->
118
+ <input hlmDatePickerAnchor [hlmDatePickerAnchorFor]="popoverRef" />
50
119
  ```
51
120
 
52
- ## Running end-to-end tests
121
+ Real selectors (from source):
53
122
 
54
- For end-to-end (e2e) testing, run:
123
+ | Class | Selector | Kind |
124
+ | ---------------------- | ------------------------- | --------------------------------------------------- |
125
+ | `HlmDatePicker` | `hlm-date-picker` | Component (CVA) |
126
+ | `HlmDatePickerMulti` | `hlm-date-picker-multi` | Component (CVA) |
127
+ | `HlmDateRangePicker` | `hlm-date-range-picker` | Component (CVA) |
128
+ | `HlmMonthYearPicker` | `hlm-month-year-picker` | Component (CVA) |
129
+ | `HlmDatePickerInput` | `hlm-date-picker-input` | Component (trigger, extends `BrnDateInput<T>`) |
130
+ | `HlmDateMultiInput` | `hlm-date-multi-input` | Component (trigger, extends `BrnDateInput<T[]>`) |
131
+ | `HlmDateRangeInput` | `hlm-date-range-input` | Component (trigger, extends `BrnDateInput<[T, T]>`) |
132
+ | `HlmMonthYearInput` | `hlm-month-year-input` | Component (trigger, extends `BrnDateInput<T>`) |
133
+ | `HlmDatePickerTrigger` | `hlm-date-picker-trigger` | Component (button trigger) |
134
+ | `HlmDatePickerAnchor` | `[hlmDatePickerAnchor]` | Directive |
55
135
 
56
- ```bash
57
- ng e2e
136
+ ## API reference
137
+
138
+ ### `HlmDatePicker` — `hlm-date-picker`
139
+
140
+ Single-date picker. Generic `<T>` (usually `Date`). Implements `BrnDatePickerBase<T>` + `ControlValueAccessor`, hosts `BrnFieldControl`.
141
+
142
+ | Input | Type | Default | Description |
143
+ | -------------------- | ---------------------------------------------------------------- | ----------------------- | ------------------------------------------------------- |
144
+ | `captionLayout` | `'dropdown' \| 'label' \| 'dropdown-months' \| 'dropdown-years'` | `'label'` | Calendar caption navigation mode. |
145
+ | `min` | `T` | — | Minimum selectable date. |
146
+ | `max` | `T` | — | Maximum selectable date. |
147
+ | `disabled` | `boolean` | `false` | Disables the picker. |
148
+ | `wrapperDisabled` | `boolean` | `false` | Interaction lock that does not write to a form control. |
149
+ | `date` | `T` | — | Controlled selected value. |
150
+ | `defaultFocusedDate` | `T` | — | Month the calendar opens on when nothing is selected. |
151
+ | `autoCloseOnSelect` | `boolean` | config (`false`) | Close the popover when a date is picked. |
152
+ | `formatDate` | `(date: T) => string` | config (`toDateString`) | Display format for the trigger. |
153
+ | `transformDate` | `(date: T) => T` | config (identity) | Normalizes every value entering the model. |
154
+
155
+ | Output | Type | Description |
156
+ | ------------ | ----------- | ------------------------------------------- |
157
+ | `dateChange` | `T \| null` | Emitted on select / `updateDate` / `reset`. |
158
+
159
+ | Signal / method | Description |
160
+ | ---------------------------------------------------------------------- | ------------------------------------------------------------- |
161
+ | `formattedDate` | Formatted current date (readonly signal). |
162
+ | `hasDate` | Whether a date is selected. |
163
+ | `value` | Raw current value (`T \| null`), used by inputs. |
164
+ | `disabledState` | Combined disabled signal. |
165
+ | `labelableId` | Trigger id for labelling. |
166
+ | `popover` | Required `BrnPopover` view child. |
167
+ | `updateDate(value: T \| null)` | Commit a date without closing the popover (typed-input path). |
168
+ | `open() / close() / reset()` | Programmatic popover control + clear. |
169
+ | `touched()` | Marks as touched. |
170
+ | `writeValue / registerOnChange / registerOnTouched / setDisabledState` | `ControlValueAccessor` contract. |
171
+
172
+ Content slots: default (trigger), `[hlmDatePickerHeader]`, `[hlmDatePickerFooter]`.
173
+
174
+ ### `HlmDatePickerMulti` — `hlm-date-picker-multi`
175
+
176
+ Multi-date variant. Model is `T[]`.
177
+
178
+ | Input | Type | Default | Description |
179
+ | ------------------------------- | ------------------------ | ---------------------------- | ------------------------------------- |
180
+ | `captionLayout` | same as above | `'label'` | Caption mode. |
181
+ | `min` / `max` | `T` | — | Date bounds. |
182
+ | `minSelection` / `maxSelection` | `number` | — | Selection-count bounds. |
183
+ | `disabled` | `boolean` | `false` | Disables the picker. |
184
+ | `date` | `T[]` | — | Controlled value. |
185
+ | `autoCloseOnMaxSelection` | `boolean` | config (`false`) | Close when `maxSelection` is reached. |
186
+ | `formatDates` | `(dates: T[]) => string` | config (join `toDateString`) | Trigger display. |
187
+ | `transformDates` | `(dates: T[]) => T[]` | config (identity) | Model normalization. |
188
+
189
+ | Output | Type |
190
+ | ------------ | ----- |
191
+ | `dateChange` | `T[]` |
192
+
193
+ Methods: `updateDate(value: T[] \| null)`, `open()`, `close()`, `reset()` (emits `[]`), plus CVA methods and `formattedDate` / `hasDate` / `value` / `disabledState` signals.
194
+
195
+ ### `HlmDateRangePicker` — `hlm-date-range-picker`
196
+
197
+ Range variant. Model is `[T, T] | null`.
198
+
199
+ | Input | Type | Default | Description |
200
+ | ------------------------- | ------------------------------------------- | --------------------- | ---------------------------------- |
201
+ | `captionLayout` | same | `'label'` | Caption mode. |
202
+ | `min` / `max` | `T` | — | Bounds. |
203
+ | `disabled` | `boolean` | `false` | Disables. |
204
+ | `date` | `[T, T]` | — | Controlled range. |
205
+ | `autoCloseOnEndSelection` | `boolean` | config (`false`) | Close once the end date is picked. |
206
+ | `formatDates` | `(dates: [T \| null, T \| null]) => string` | config (join `' - '`) | Trigger display. |
207
+ | `transformDates` | `(dates: [T, T]) => [T, T]` | config (identity) | Normalization. |
208
+
209
+ | Output | Type |
210
+ | ------------ | ---------------- |
211
+ | `dateChange` | `[T, T] \| null` |
212
+
213
+ Methods: `updateDate(value: [T, T] \| null)` (pass `null` to clear), `open()`, `close()`, `reset()`, CVA methods.
214
+
215
+ ### `HlmMonthYearPicker` — `hlm-month-year-picker`
216
+
217
+ Month/year variant (renders `hlm-month-year-calendar`). Same single-date API as `HlmDatePicker` except it has no `wrapperDisabled` input and defaults `formatDate` / `formatInputDate` to `MM/YYYY`:
218
+
219
+ | Input | Type | Default |
220
+ | ------------------------------ | --------- | ----------------------------- |
221
+ | `min` / `max` | `T` | — |
222
+ | `disabled` | `boolean` | `false` |
223
+ | `date` / `defaultFocusedDate` | `T` | — |
224
+ | `autoCloseOnSelect` | `boolean` | config (`false`) |
225
+ | `formatDate` / `transformDate` | functions | config (`MM/YYYY` / identity) |
226
+
227
+ Outputs/methods mirror `HlmDatePicker` (`dateChange: T | null`, `updateDate`, `open`, `close`, `reset`).
228
+
229
+ ### Trigger inputs (`HlmDatePickerInput`)
230
+
231
+ `HlmDatePickerInput<T>`, `HlmDateMultiInput<T>`, `HlmDateRangeInput<T>`, `HlmMonthYearInput<T>` extend `BrnDateInput` (inheriting `placeholder`, `inputId`, disabled/invalid wiring, clear-button and calendar-button behavior) and add:
232
+
233
+ | Input | Type | Default | Notes |
234
+ | -------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------- |
235
+ | `parseDate` | `(value: string) => T \| null` (or `T[] \| null` / `[T,T] \| null` per variant) | from matching `provideHlm*Config` | Return `null` for invalid text; picker clears while text is preserved. |
236
+ | `formatInputDate` / `formatInputDates` | `(date) => string` | from config | Edit format shown while focused. |
237
+ | `ariaLabel` / `ariaDescribedby` | `string` | — | Only on `HlmDatePickerInput`. |
238
+
239
+ ### `HlmDatePickerTrigger` — `hlm-date-picker-trigger`
240
+
241
+ Button trigger showing the formatted date or projected placeholder.
242
+
243
+ | Input | Type | Default | Description |
244
+ | -------------- | --------------------------- | --------------------- | -------------------------------------------------- |
245
+ | `buttonId` | `string` | `hlm-date-picker-<n>` | Button id; also used as `triggerId` for labelling. |
246
+ | `forceInvalid` | `boolean` | `false` | Forces invalid styling. |
247
+ | `variant` | `ButtonVariants['variant']` | `'outline'` | `hlmBtn` variant. |
248
+ | `showTrigger` | `boolean` | `true` | Show the chevron-down icon. |
249
+ | `class` | `ClassValue` | `''` | Extra classes. |
250
+
251
+ ### `HlmDatePickerAnchor` — `[hlmDatePickerAnchor]`
252
+
253
+ | Input | Type | Description |
254
+ | -------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------ |
255
+ | `hlmDatePickerAnchorFor` (alias; underlying `hlmDatePickerAnchorForInput`) | `BrnPopover \| undefined` | Popover whose origin is set to the host element. |
256
+
257
+ ### Config tokens
258
+
259
+ | Symbol | Description |
260
+ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
261
+ | `HlmDatePickerConfig<T>` | `{ autoCloseOnSelect, formatDate, formatInputDate, transformDate, parseDate }`. Default parse: `new Date(value)`, `null` when invalid. |
262
+ | `provideHlmDatePickerConfig<T>(partial)` / `injectHlmDatePickerConfig<T>()` | Provide / read the single-date config. |
263
+ | `HlmDatePickerMultiConfig<T>` | `{ autoCloseOnMaxSelection, formatDates, formatInputDates, transformDates, parseDate }`. Default multi parse: comma-separated `DD/MM/YYYY`. |
264
+ | `provideHlmDatePickerMultiConfig` / `injectHlmDatePickerMultiConfig` | Multi config DI. |
265
+ | `HlmDateRangePickerConfig<T>` | `{ autoCloseOnEndSelection, formatDates, formatInputDates, transformDates, parseDate }`. Default range parse: `"a - b"` via `new Date(part)`. |
266
+ | `provideHlmDateRangePickerConfig` / `injectHlmDateRangePickerConfig` | Range config DI. |
267
+ | `HlmMonthYearPickerConfig<T>` | `{ autoCloseOnSelect, formatDate, formatInputDate, transformDate, parseDate }`. Default parse: `MM/YYYY`. |
268
+ | `provideHlmMonthYearPickerConfig` / `injectHlmMonthYearPickerConfig` | Month/year config DI. |
269
+
270
+ ## Examples
271
+
272
+ ### 1. Basic single date with text input
273
+
274
+ ```ts
275
+ import { Component, signal } from '@angular/core';
276
+ import { HlmDatePickerImports } from '@egose/shadcn-theme-ng/date-picker';
277
+
278
+ @Component({
279
+ selector: 'app-basic',
280
+ standalone: true,
281
+ imports: [...HlmDatePickerImports],
282
+ template: `
283
+ <hlm-date-picker (dateChange)="date.set($event)">
284
+ <hlm-date-picker-input placeholder="Pick a date" />
285
+ </hlm-date-picker>
286
+ <p>Selected: {{ date()?.toDateString() ?? 'none' }}</p>
287
+ `,
288
+ })
289
+ export class BasicComponent {
290
+ readonly date = signal<Date | null>(null);
291
+ }
292
+ ```
293
+
294
+ ### 2. Button trigger with min/max and dropdown caption
295
+
296
+ ```ts
297
+ import { Component, signal } from '@angular/core';
298
+ import { HlmDatePickerImports } from '@egose/shadcn-theme-ng/date-picker';
299
+
300
+ @Component({
301
+ selector: 'app-button-trigger',
302
+ standalone: true,
303
+ imports: [...HlmDatePickerImports],
304
+ template: `
305
+ <hlm-date-picker captionLayout="dropdown" [min]="min" [max]="max" autoCloseOnSelect (dateChange)="date.set($event)">
306
+ <hlm-date-picker-trigger>Pick a date</hlm-date-picker-trigger>
307
+ </hlm-date-picker>
308
+ `,
309
+ })
310
+ export class ButtonTriggerComponent {
311
+ readonly date = signal<Date | null>(null);
312
+ readonly min = new Date(2025, 0, 1);
313
+ readonly max = new Date(2026, 11, 31);
314
+ }
315
+ ```
316
+
317
+ ### 3. Reactive form binding + validation
318
+
319
+ ```ts
320
+ import { Component, inject } from '@angular/core';
321
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
322
+ import { HlmDatePickerImports } from '@egose/shadcn-theme-ng/date-picker';
323
+ import { HlmFormFieldImports } from '@egose/shadcn-theme-ng/form-field';
324
+ import { HlmLabel } from '@egose/shadcn-theme-ng/label';
325
+
326
+ @Component({
327
+ selector: 'app-reactive',
328
+ standalone: true,
329
+ imports: [ReactiveFormsModule, HlmLabel, ...HlmDatePickerImports, ...HlmFormFieldImports],
330
+ template: `
331
+ <form [formGroup]="form" (ngSubmit)="save()">
332
+ <hlm-form-field>
333
+ <label hlmLabel for="dob">Date of birth</label>
334
+ <hlm-date-picker formControlName="dob">
335
+ <hlm-date-picker-input inputId="dob" placeholder="YYYY-MM-DD" />
336
+ </hlm-date-picker>
337
+ <hlm-error>Birth date is required.</hlm-error>
338
+ </hlm-form-field>
339
+ <button type="submit" [disabled]="form.invalid">Save</button>
340
+ </form>
341
+ `,
342
+ })
343
+ export class ReactiveComponent {
344
+ private readonly fb = inject(FormBuilder);
345
+ readonly form = this.fb.group({ dob: [null as Date | null, Validators.required] });
346
+ save() {
347
+ console.log(this.form.value.dob);
348
+ }
349
+ }
350
+ ```
351
+
352
+ ### 4. Multi-date with max selection + custom formatting
353
+
354
+ ```ts
355
+ import { Component, signal } from '@angular/core';
356
+ import { HlmDatePickerImports } from '@egose/shadcn-theme-ng/date-picker';
357
+
358
+ @Component({
359
+ selector: 'app-multi',
360
+ standalone: true,
361
+ imports: [...HlmDatePickerImports],
362
+ template: `
363
+ <hlm-date-picker-multi
364
+ [maxSelection]="3"
365
+ autoCloseOnMaxSelection
366
+ [formatDates]="format"
367
+ (dateChange)="dates.set($event)"
368
+ >
369
+ <hlm-date-multi-input placeholder="Pick up to 3 dates (DD/MM/YYYY, …)" />
370
+ </hlm-date-picker-multi>
371
+ <p>{{ dates().length }} selected</p>
372
+ `,
373
+ })
374
+ export class MultiComponent {
375
+ readonly dates = signal<Date[]>([]);
376
+ readonly format = (dates: Date[]) => dates.map((d) => d.toLocaleDateString()).join(' · ');
377
+ }
378
+ ```
379
+
380
+ ### 5. Range picker with programmatic control and footer
381
+
382
+ ```ts
383
+ import { Component, signal, viewChild } from '@angular/core';
384
+ import { HlmDatePickerImports, HlmDateRangePicker } from '@egose/shadcn-theme-ng/date-picker';
385
+ import { HlmButton } from '@egose/shadcn-theme-ng/button';
386
+
387
+ @Component({
388
+ selector: 'app-range',
389
+ standalone: true,
390
+ imports: [...HlmDatePickerImports, HlmButton],
391
+ template: `
392
+ <hlm-date-range-picker #range autoCloseOnEndSelection (dateChange)="onRange($event)">
393
+ <hlm-date-range-input placeholder="Start - End" />
394
+ <div hlmDatePickerFooter class="tw:flex tw:justify-end tw:gap-2 tw:p-2">
395
+ <button hlmBtn variant="ghost" size="sm" type="button" (click)="range.reset()">Clear</button>
396
+ <button hlmBtn variant="outline" size="sm" type="button" (click)="range.close()">Done</button>
397
+ </div>
398
+ </hlm-date-range-picker>
399
+ <div class="tw:flex tw:gap-2">
400
+ <button hlmBtn type="button" variant="outline" (click)="range.open()">Open</button>
401
+ </div>
402
+ `,
403
+ })
404
+ export class RangeComponent {
405
+ readonly picker = viewChild.required(HlmDateRangePicker);
406
+ onRange(value: [Date, Date] | null) {
407
+ console.log('range', value);
408
+ }
409
+ }
58
410
  ```
59
411
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
412
+ ### 6. Month/year picker + global config (local-midnight normalization)
413
+
414
+ ```ts
415
+ import { Component, signal } from '@angular/core';
416
+ import { HlmDatePickerImports, provideHlmDatePickerConfig } from '@egose/shadcn-theme-ng/date-picker';
417
+
418
+ @Component({
419
+ selector: 'app-month-config',
420
+ standalone: true,
421
+ imports: [...HlmDatePickerImports],
422
+ providers: [
423
+ provideHlmDatePickerConfig<Date>({
424
+ autoCloseOnSelect: true,
425
+ // Normalize every model value to local midnight.
426
+ transformDate: (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate()),
427
+ parseDate: (value: string) => {
428
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
429
+ if (!m) return null;
430
+ const d = new Date(+m[1], +m[2] - 1, +m[3]);
431
+ return isNaN(d.getTime()) ? null : d;
432
+ },
433
+ }),
434
+ ],
435
+ template: `
436
+ <hlm-month-year-picker (dateChange)="month.set($event)">
437
+ <hlm-month-year-input placeholder="MM/YYYY" />
438
+ </hlm-month-year-picker>
439
+
440
+ <hlm-date-picker [date]="month()" (dateChange)="month.set($event)">
441
+ <hlm-date-picker-input placeholder="Pick a date" />
442
+ </hlm-date-picker>
443
+ `,
444
+ })
445
+ export class MonthConfigComponent {
446
+ readonly month = signal<Date | null>(null);
447
+ }
448
+ ```
449
+
450
+ ## Accessibility notes
451
+
452
+ - The text inputs render a native `<input>` with `hlmInputGroupInput`, forwarding `inputId`, `placeholder`, `aria-label` / `aria-describedby` (single input), and disabled/invalid states — always pair with a visible `<label>` or `ariaLabel`.
453
+ - The button trigger wires `brnFieldControlDescribedBy`, `aria-invalid`, and `data-touched` / `data-dirty` attributes from the surrounding field control.
454
+ - Arrow-down opens the calendar, enter commits typed text, and closing the popover marks the control touched (driving `touched`-gated error display).
455
+ - The calendar and popover primitives handle roving focus, escape-to-close, and outside-click dismissal; the clear and calendar icon buttons expose `aria-label`s from the brain input (`clearAriaLabel`, `calendarAriaLabel`).
456
+
457
+ ## Theming / CSS variables
458
+
459
+ No component-specific CSS variables. Style via the `class` input on `hlm-date-picker-trigger` / overlays, the `[hlmDatePickerHeader]` / `[hlmDatePickerFooter]` slots, and the global shadcn theme tokens (`--popover`, `--muted`, `--accent`, …). The popover content uses `tw:w-fit tw:p-0` and the calendar `tw:rounded-none tw:border-0` by default.
61
460
 
62
- ## Additional Resources
461
+ ## Related subpaths
63
462
 
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.
463
+ - `@egose/shadcn-theme-ng/calendar` — `HlmCalendar`, `HlmCalendarMulti`, `HlmCalendarRange`, `HlmMonthYearCalendar` rendered inside the popover.
464
+ - `@egose/shadcn-theme-ng/popover` — `HlmPopoverImports` positioning and portal.
465
+ - `@egose/shadcn-theme-ng/form-field` — `hlm-form-field` / `hlm-error` / `hlm-hint` wrappers for labelled, validated pickers.
466
+ - `@egose/shadcn-theme-ng/form-date-picker` — `eg-form-date-picker`, a ready-made labelled reactive-form wrapper around this picker.