@egose/shadcn-theme-ng-tw 0.1.0 → 0.3.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 (165) hide show
  1. package/README.md +2 -2
  2. package/accordion/README.md +405 -2
  3. package/alert/README.md +372 -2
  4. package/alert/fesm2022/alert.mjs +1 -1
  5. package/alert-dialog/README.md +471 -5
  6. package/aspect-ratio/README.md +272 -5
  7. package/autocomplete/README.md +502 -2
  8. package/autocomplete/fesm2022/autocomplete.mjs +1 -1
  9. package/avatar/README.md +357 -5
  10. package/badge/README.md +318 -2
  11. package/basic-alert/README.md +353 -2
  12. package/breadcrumb/README.md +406 -5
  13. package/button/README.md +482 -2
  14. package/button/fesm2022/button.mjs +85 -107
  15. package/button/types/button.d.ts +5 -8
  16. package/button-group/README.md +318 -5
  17. package/button-group/fesm2022/button-group.mjs +1 -1
  18. package/calendar/README.md +357 -2
  19. package/card/README.md +331 -5
  20. package/carousel/README.md +333 -5
  21. package/carousel/fesm2022/carousel.mjs +4 -1
  22. package/checkbox/README.md +320 -2
  23. package/checkbox/fesm2022/checkbox.mjs +6 -7
  24. package/checkbox/types/checkbox.d.ts +1 -1
  25. package/collapsible/README.md +332 -5
  26. package/combobox/README.md +507 -5
  27. package/combobox/fesm2022/combobox.mjs +5 -2
  28. package/command/README.md +435 -5
  29. package/confirmation-dialog/README.md +301 -2
  30. package/context-menu/README.md +366 -5
  31. package/date-picker/README.md +469 -2
  32. package/date-picker/fesm2022/date-picker.mjs +150 -32
  33. package/date-picker/types/date-picker.d.ts +102 -9
  34. package/dialog/README.md +448 -2
  35. package/drawer/README.md +395 -5
  36. package/dropdown-menu/README.md +417 -5
  37. package/empty/README.md +329 -5
  38. package/field/README.md +385 -5
  39. package/form-autocomplete/README.md +177 -0
  40. package/form-autocomplete/fesm2022/form-autocomplete.mjs +211 -0
  41. package/form-autocomplete/package.json +24 -0
  42. package/form-autocomplete/types/form-autocomplete.d.ts +61 -0
  43. package/form-checkbox/README.md +322 -2
  44. package/form-checkbox/fesm2022/form-checkbox.mjs +22 -9
  45. package/form-checkbox/types/form-checkbox.d.ts +23 -4
  46. package/form-combobox/README.md +202 -0
  47. package/form-combobox/fesm2022/form-combobox.mjs +273 -0
  48. package/form-combobox/package.json +24 -0
  49. package/form-combobox/types/form-combobox.d.ts +73 -0
  50. package/form-date-picker/README.md +348 -2
  51. package/form-date-picker/fesm2022/form-date-picker.mjs +60 -16
  52. package/form-date-picker/types/form-date-picker.d.ts +17 -1
  53. package/form-date-picker-multi/README.md +191 -0
  54. package/form-date-picker-multi/fesm2022/form-date-picker-multi.mjs +239 -0
  55. package/form-date-picker-multi/package.json +24 -0
  56. package/form-date-picker-multi/types/form-date-picker-multi.d.ts +58 -0
  57. package/form-date-range-picker/README.md +253 -0
  58. package/form-date-range-picker/fesm2022/form-date-range-picker.mjs +236 -0
  59. package/form-date-range-picker/package.json +24 -0
  60. package/form-date-range-picker/types/form-date-range-picker.d.ts +55 -0
  61. package/form-field/README.md +356 -2
  62. package/form-field-simple/README.md +340 -2
  63. package/form-input-otp/README.md +194 -0
  64. package/form-input-otp/fesm2022/form-input-otp.mjs +194 -0
  65. package/form-input-otp/package.json +24 -0
  66. package/form-input-otp/types/form-input-otp.d.ts +58 -0
  67. package/form-month-year-picker/README.md +188 -0
  68. package/form-month-year-picker/fesm2022/form-month-year-picker.mjs +229 -0
  69. package/form-month-year-picker/package.json +24 -0
  70. package/form-month-year-picker/types/form-month-year-picker.d.ts +53 -0
  71. package/form-native-select/README.md +205 -0
  72. package/form-native-select/fesm2022/form-native-select.mjs +187 -0
  73. package/form-native-select/package.json +24 -0
  74. package/form-native-select/types/form-native-select.d.ts +57 -0
  75. package/form-phone-input/README.md +188 -0
  76. package/form-phone-input/fesm2022/form-phone-input.mjs +203 -0
  77. package/form-phone-input/package.json +24 -0
  78. package/form-phone-input/types/form-phone-input.d.ts +58 -0
  79. package/form-radio-group/README.md +198 -0
  80. package/form-radio-group/fesm2022/form-radio-group.mjs +211 -0
  81. package/form-radio-group/package.json +24 -0
  82. package/form-radio-group/types/form-radio-group.d.ts +63 -0
  83. package/form-searchable-multiselect/README.md +371 -2
  84. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +19 -10
  85. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +18 -1
  86. package/form-select/README.md +360 -2
  87. package/form-select/fesm2022/form-select.mjs +24 -15
  88. package/form-select/types/form-select.d.ts +18 -1
  89. package/form-slider/README.md +182 -0
  90. package/form-slider/fesm2022/form-slider.mjs +186 -0
  91. package/form-slider/package.json +24 -0
  92. package/form-slider/types/form-slider.d.ts +60 -0
  93. package/form-switch/README.md +173 -0
  94. package/form-switch/fesm2022/form-switch.mjs +178 -0
  95. package/form-switch/package.json +24 -0
  96. package/form-switch/types/form-switch.d.ts +50 -0
  97. package/form-text-input/README.md +381 -2
  98. package/form-text-input/fesm2022/form-text-input.mjs +19 -10
  99. package/form-text-input/types/form-text-input.d.ts +18 -1
  100. package/form-textarea/README.md +357 -2
  101. package/form-textarea/fesm2022/form-textarea.mjs +19 -10
  102. package/form-textarea/types/form-textarea.d.ts +18 -1
  103. package/form-toggle/README.md +186 -0
  104. package/form-toggle/fesm2022/form-toggle.mjs +241 -0
  105. package/form-toggle/package.json +24 -0
  106. package/form-toggle/types/form-toggle.d.ts +82 -0
  107. package/form-toggle-group/README.md +176 -0
  108. package/form-toggle-group/fesm2022/form-toggle-group.mjs +216 -0
  109. package/form-toggle-group/package.json +24 -0
  110. package/form-toggle-group/types/form-toggle-group.d.ts +65 -0
  111. package/hover-card/README.md +256 -5
  112. package/icon/README.md +239 -2
  113. package/input/README.md +269 -2
  114. package/input-group/README.md +335 -5
  115. package/input-group/fesm2022/input-group.mjs +23 -13
  116. package/input-group/types/input-group.d.ts +4 -1
  117. package/input-otp/README.md +375 -5
  118. package/item/README.md +385 -5
  119. package/item/fesm2022/item.mjs +3 -3
  120. package/kbd/README.md +291 -5
  121. package/label/README.md +272 -2
  122. package/layout-simple/README.md +193 -2
  123. package/layout-simple/fesm2022/layout-simple.mjs +877 -409
  124. package/layout-simple/types/layout-simple.d.ts +174 -137
  125. package/menu/README.md +417 -2
  126. package/menubar/README.md +343 -5
  127. package/native-select/README.md +323 -5
  128. package/native-select/fesm2022/native-select.mjs +18 -6
  129. package/native-select/types/native-select.d.ts +7 -2
  130. package/navigation-menu/README.md +369 -5
  131. package/package.json +57 -1
  132. package/pagination/README.md +388 -5
  133. package/phone-input/README.md +114 -0
  134. package/phone-input/fesm2022/phone-input.mjs +191 -0
  135. package/phone-input/package.json +24 -0
  136. package/phone-input/types/phone-input.d.ts +67 -0
  137. package/popover/README.md +331 -2
  138. package/progress/README.md +311 -5
  139. package/radio-group/README.md +364 -2
  140. package/radio-group/fesm2022/radio-group.mjs +5 -1
  141. package/resizable/README.md +269 -5
  142. package/scroll-area/README.md +233 -5
  143. package/searchable-multiselect/README.md +323 -2
  144. package/select/README.md +437 -2
  145. package/separator/README.md +222 -2
  146. package/sheet/README.md +311 -2
  147. package/sheet/fesm2022/sheet.mjs +1 -1
  148. package/sidebar/README.md +457 -5
  149. package/skeleton/README.md +217 -5
  150. package/slider/README.md +273 -5
  151. package/slider/fesm2022/slider.mjs +17 -13
  152. package/sonner/README.md +346 -2
  153. package/spinner/README.md +284 -2
  154. package/switch/README.md +310 -2
  155. package/switch/fesm2022/switch.mjs +7 -5
  156. package/switch/types/switch.d.ts +2 -1
  157. package/table/README.md +423 -5
  158. package/tabs/README.md +411 -2
  159. package/tabs/fesm2022/tabs.mjs +12 -2
  160. package/textarea/README.md +282 -5
  161. package/toggle/README.md +270 -5
  162. package/toggle-group/README.md +340 -5
  163. package/tooltip/README.md +269 -2
  164. package/typography/README.md +271 -5
  165. package/utils/README.md +303 -2
@@ -1,3 +1,358 @@
1
- # Calendar Subpath
1
+ # Calendar (`@egose/shadcn-theme-ng/calendar`)
2
2
 
3
- This project ships only as `@egose/shadcn-theme-ng/calendar` or `@egose/shadcn-theme-ng-tw/calendar`. See the [package README](../../README.md) for installation, compatibility, Tailwind variant, test, and release guidance. Do not publish this project directory independently.
3
+ A shadcn/ui-style calendar month grid for single-date, multi-date, range, and month/year picking — the Angular port of shadcn/ui `Calendar`. Four standalone components share one visual language (ghost icon day cells, `--cell-size`/`--cell-radius` tokens, optional month/year dropdown caption): `hlm-calendar` (single date), `hlm-calendar-multi` (multi-select), `hlm-calendar-range` (start/end range), and `hlm-month-year-calendar` (year→month stepping). Behavior comes from `@spartan-ng/brain/calendar` host directives (`BrnCalendar`, `BrnCalendarMulti`, `BrnCalendarRange`, `BrnMonthYearCalendar`) plus `@spartan-ng/brain/date-time` adapters and i18n; the header dropdowns are composed from this repo's own `hlm-select` subpath.
4
+
5
+ Ships as `@egose/shadcn-theme-ng/calendar` and `@egose/shadcn-theme-ng-tw/calendar` (the `tw:`-prefixed variant). See the [package README](../../README.md) for install, peer dependencies, and Tailwind setup. Do not publish this project directory independently — it is consumed via the published subpath only.
6
+
7
+ ## Installation
8
+
9
+ ```bash
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
15
+ ```
16
+
17
+ Peers are listed in the [package README](../../README.md). This subpath declares `@angular/common` and `@angular/core` as peers (see `projects/calendar/package.json`); at runtime it also imports `@egose/shadcn-theme-ng/button` and `@egose/shadcn-theme-ng/select`, so install the whole package, not the directory.
18
+
19
+ ## Imports
20
+
21
+ ```ts
22
+ import {
23
+ HlmCalendar,
24
+ HlmCalendarMulti,
25
+ HlmCalendarRange,
26
+ HlmMonthYearCalendar,
27
+ HlmCalendarImports,
28
+ HlmCalendarModule,
29
+ } from '@egose/shadcn-theme-ng/calendar';
30
+ // tw variant:
31
+ // import { ... } from '@egose/shadcn-theme-ng-tw/calendar';
32
+ ```
33
+
34
+ Standalone:
35
+
36
+ ```ts
37
+ import { Component } from '@angular/core';
38
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
39
+
40
+ @Component({
41
+ selector: 'app-demo',
42
+ standalone: true,
43
+ imports: [...HlmCalendarImports],
44
+ template: `<hlm-calendar />`,
45
+ })
46
+ export class DemoComponent {}
47
+ ```
48
+
49
+ NgModule:
50
+
51
+ ```ts
52
+ import { NgModule } from '@angular/core';
53
+ import { HlmCalendarModule } from '@egose/shadcn-theme-ng/calendar';
54
+
55
+ @NgModule({ imports: [HlmCalendarModule] })
56
+ export class DemoModule {}
57
+ ```
58
+
59
+ > Requires a date adapter provider from `@spartan-ng/brain/date-time` (e.g. native-JS-date adapter) and, for localized names, the calendar i18n provider — see the examples below.
60
+
61
+ ## Anatomy / Structure
62
+
63
+ ```html
64
+ <!-- Single date -->
65
+ <hlm-calendar
66
+ captionLayout="dropdown"
67
+ [date]="selected"
68
+ [min]="minDate"
69
+ [max]="maxDate"
70
+ [disabled]="isDisabled"
71
+ [weekStartsOn]="1"
72
+ (dateChange)="selected = $event"
73
+ />
74
+
75
+ <!-- Multi date -->
76
+ <hlm-calendar-multi [date]="[d1, d2]" [minSelection]="1" [maxSelection]="5" (dateChange)="dates = $event" />
77
+
78
+ <!-- Range -->
79
+ <hlm-calendar-range
80
+ [startDate]="start"
81
+ [endDate]="end"
82
+ (startDateChange)="start = $event"
83
+ (endDateChange)="end = $event"
84
+ />
85
+
86
+ <!-- Month/year stepper -->
87
+ <hlm-month-year-calendar [date]="picked" view="month" (dateChange)="picked = $event" />
88
+ ```
89
+
90
+ Real selectors: `hlm-calendar`, `hlm-calendar-multi`, `hlm-calendar-range`, `hlm-month-year-calendar` (element selectors only). Internally each template composes `brnCalendarPreviousButton` / `brnCalendarNextButton` / `brnCalendarHeader` / `brnCalendarGrid` / `brnCalendarCellButton` structural directives and `brnCalendarMonthSelect` / `brnCalendarYearSelect` selects; you do not write those yourself.
91
+
92
+ ## API reference
93
+
94
+ All date types are generic `<T>` (whatever your date adapter uses — usually native `Date`).
95
+
96
+ ### `HlmCalendar` (`hlm-calendar`)
97
+
98
+ | Input (own) | Type | Default | Description |
99
+ | --------------- | ---------------------------------------------------------------- | --------- | -------------------------------------------------------------- |
100
+ | `captionLayout` | `'dropdown' \| 'label' \| 'dropdown-months' \| 'dropdown-years'` | `'label'` | Header mode: plain label vs month/year `hlm-select` dropdowns. |
101
+
102
+ | Brain input (via `BrnCalendar`) | Description |
103
+ | ------------------------------- | ------------------------------------------------------------- |
104
+ | `min` | Minimum selectable date. |
105
+ | `max` | Maximum selectable date. |
106
+ | `disabled` | Disables the whole calendar. |
107
+ | `date` | Currently selected date. |
108
+ | `dateDisabled` | Predicate `(date: T) => boolean` disabling individual days. |
109
+ | `weekStartsOn` | First weekday (`0` = Sunday … `6` = Saturday). |
110
+ | `highlightDays` | Dates/dots predicate for the `data-[highlighted]` dot marker. |
111
+ | `defaultFocusedDate` | Initially focused date when `date` is unset. |
112
+
113
+ | Output | Payload | Description |
114
+ | ------------ | ----------------------------------------- | --------------------------------------- |
115
+ | `dateChange` | `T \| null/undefined` (adapter-dependent) | Emitted on day click / keyboard select. |
116
+
117
+ ### `HlmCalendarMulti` (`hlm-calendar-multi`)
118
+
119
+ Own `captionLayout` input identical to above. Brain inputs via `BrnCalendarMulti`: `min`, `max`, `minSelection`, `maxSelection`, `disabled`, `date` (array), `dateDisabled`, `weekStartsOn`, `highlightDays`, `defaultFocusedDate`. Output: `dateChange` (selected-dates array).
120
+
121
+ ### `HlmCalendarRange` (`hlm-calendar-range`)
122
+
123
+ Own `captionLayout` input identical to above. Brain inputs via `BrnCalendarRange`: `min`, `max`, `disabled`, `startDate`, `endDate`, `dateDisabled`, `weekStartsOn`, `highlightDays`, `defaultFocusedDate`. Outputs: `startDateChange`, `endDateChange`.
124
+
125
+ ### `HlmMonthYearCalendar` (`hlm-month-year-calendar`)
126
+
127
+ No `captionLayout`. Brain inputs via `BrnMonthYearCalendar`: `min`, `max`, `disabled`, `date`, `defaultFocusedDate`, `view` (`'month' | 'year'`). Output: `dateChange`. The header button (`brnMonthYearCalendarHeader`) toggles year↔month views; the grid renders `brnMonthYearCalendarYearButton` / `brnMonthYearCalendarMonthButton` cells.
128
+
129
+ ## Examples
130
+
131
+ ### 1. Basic single-date calendar (two-way style)
132
+
133
+ ```ts
134
+ import { Component, signal } from '@angular/core';
135
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
136
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
137
+
138
+ @Component({
139
+ selector: 'app-basic-calendar',
140
+ standalone: true,
141
+ imports: [...HlmCalendarImports],
142
+ providers: [provideNativeDateAdapter()],
143
+ template: `
144
+ <hlm-calendar [date]="date()" (dateChange)="date.set($event)" />
145
+ <p class="mt-2 text-sm">Picked: {{ date()?.toDateString() ?? 'none' }}</p>
146
+ `,
147
+ })
148
+ export class BasicCalendarComponent {
149
+ readonly date = signal<Date | undefined>(new Date());
150
+ }
151
+ ```
152
+
153
+ ### 2. Caption variants (dropdown navigation)
154
+
155
+ All three single/multi/range calendars accept `captionLayout`.
156
+
157
+ ```ts
158
+ import { Component, signal } from '@angular/core';
159
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
160
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
161
+
162
+ @Component({
163
+ selector: 'app-caption-layouts',
164
+ standalone: true,
165
+ imports: [...HlmCalendarImports],
166
+ providers: [provideNativeDateAdapter()],
167
+ template: `
168
+ <div class="flex flex-wrap gap-6">
169
+ <div>
170
+ <h3 class="mb-2 text-sm font-medium">dropdown</h3>
171
+ <hlm-calendar captionLayout="dropdown" [date]="a()" (dateChange)="a.set($event)" />
172
+ </div>
173
+ <div>
174
+ <h3 class="mb-2 text-sm font-medium">dropdown-months</h3>
175
+ <hlm-calendar captionLayout="dropdown-months" [date]="b()" (dateChange)="b.set($event)" />
176
+ </div>
177
+ <div>
178
+ <h3 class="mb-2 text-sm font-medium">dropdown-years</h3>
179
+ <hlm-calendar captionLayout="dropdown-years" [date]="c()" (dateChange)="c.set($event)" />
180
+ </div>
181
+ <div>
182
+ <h3 class="mb-2 text-sm font-medium">label (default)</h3>
183
+ <hlm-calendar captionLayout="label" [date]="d()" (dateChange)="d.set($event)" />
184
+ </div>
185
+ </div>
186
+ `,
187
+ })
188
+ export class CaptionLayoutsComponent {
189
+ readonly a = signal<Date | undefined>(new Date());
190
+ readonly b = signal<Date | undefined>(new Date());
191
+ readonly c = signal<Date | undefined>(new Date());
192
+ readonly d = signal<Date | undefined>(new Date());
193
+ }
194
+ ```
195
+
196
+ ### 3. Min/max, disabled dates, week start, highlight dots
197
+
198
+ ```ts
199
+ import { Component, signal } from '@angular/core';
200
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
201
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
202
+
203
+ @Component({
204
+ selector: 'app-constrained-calendar',
205
+ standalone: true,
206
+ imports: [...HlmCalendarImports],
207
+ providers: [provideNativeDateAdapter()],
208
+ template: `
209
+ <hlm-calendar
210
+ [date]="date()"
211
+ [min]="min"
212
+ [max]="max"
213
+ [dateDisabled]="isWeekend"
214
+ [weekStartsOn]="1"
215
+ [highlightDays]="isPayday"
216
+ (dateChange)="date.set($event)"
217
+ />
218
+ `,
219
+ })
220
+ export class ConstrainedCalendarComponent {
221
+ readonly date = signal<Date | undefined>(new Date());
222
+ readonly min = new Date(2026, 0, 1);
223
+ readonly max = new Date(2026, 11, 31);
224
+
225
+ // Disable weekends:
226
+ readonly isWeekend = (d: Date) => d.getDay() === 0 || d.getDay() === 6;
227
+ // Red dot under the 15th of any month:
228
+ readonly isPayday = (d: Date) => d.getDate() === 15;
229
+ }
230
+ ```
231
+
232
+ ### 4. Multi-date selection with selection limits
233
+
234
+ ```ts
235
+ import { Component, signal } from '@angular/core';
236
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
237
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
238
+
239
+ @Component({
240
+ selector: 'app-multi-calendar',
241
+ standalone: true,
242
+ imports: [...HlmCalendarImports],
243
+ providers: [provideNativeDateAdapter()],
244
+ template: `
245
+ <hlm-calendar-multi
246
+ captionLayout="dropdown"
247
+ [date]="dates()"
248
+ [minSelection]="1"
249
+ [maxSelection]="3"
250
+ (dateChange)="dates.set($event ?? [])"
251
+ />
252
+ <p class="mt-2 text-sm">{{ dates().length }} / 3 selected</p>
253
+ <ul class="text-sm">
254
+ @for (d of dates(); track d.getTime()) {
255
+ <li>{{ d.toDateString() }}</li>
256
+ }
257
+ </ul>
258
+ `,
259
+ })
260
+ export class MultiCalendarComponent {
261
+ readonly dates = signal<Date[]>([new Date()]);
262
+ }
263
+ ```
264
+
265
+ ### 5. Date range with reactive-form-friendly signals
266
+
267
+ ```ts
268
+ import { Component, computed, signal } from '@angular/core';
269
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
270
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
271
+
272
+ @Component({
273
+ selector: 'app-range-calendar',
274
+ standalone: true,
275
+ imports: [...HlmCalendarImports],
276
+ providers: [provideNativeDateAdapter()],
277
+ template: `
278
+ <hlm-calendar-range
279
+ [startDate]="start()"
280
+ [endDate]="end()"
281
+ [disabled]="locked()"
282
+ (startDateChange)="start.set($event)"
283
+ (endDateChange)="end.set($event)"
284
+ />
285
+ <p class="mt-2 text-sm">{{ summary() }}</p>
286
+ <button type="button" (click)="locked.set(!locked())">
287
+ {{ locked() ? 'Unlock' : 'Lock' }}
288
+ </button>
289
+ <button type="button" (click)="clear()">Clear</button>
290
+ `,
291
+ })
292
+ export class RangeCalendarComponent {
293
+ readonly start = signal<Date | undefined>(new Date(2026, 8, 1));
294
+ readonly end = signal<Date | undefined>(new Date(2026, 8, 7));
295
+ readonly locked = signal(false);
296
+ readonly summary = computed(() =>
297
+ this.start() && this.end()
298
+ ? `${this.start()!.toDateString()} → ${this.end()!.toDateString()}`
299
+ : 'Pick a start and end date',
300
+ );
301
+ clear() {
302
+ this.start.set(undefined);
303
+ this.end.set(undefined);
304
+ }
305
+ }
306
+ ```
307
+
308
+ ### 6. Month/year picker + composition inside card/popover
309
+
310
+ `hlm-month-year-calendar` steps through year grids then month grids — ideal for expiry / birth-month fields. Calendars are transparent inside `card-content` / `popover-content` slots by design (`in-data-[slot=...]:bg-transparent`).
311
+
312
+ ```ts
313
+ import { Component, signal } from '@angular/core';
314
+ import { HlmCalendarImports } from '@egose/shadcn-theme-ng/calendar';
315
+ import { HlmCardImports } from '@egose/shadcn-theme-ng/card';
316
+ import { provideNativeDateAdapter } from '@spartan-ng/brain/date-time';
317
+
318
+ @Component({
319
+ selector: 'app-card-calendar',
320
+ standalone: true,
321
+ imports: [...HlmCalendarImports, ...HlmCardImports],
322
+ providers: [provideNativeDateAdapter()],
323
+ template: `
324
+ <div hlmCard class="w-80">
325
+ <div hlmCardHeader>
326
+ <h3 hlmCardTitle>Expiry month</h3>
327
+ <p hlmCardDescription>Month/year only — no day grid.</p>
328
+ </div>
329
+ <div hlmCardContent>
330
+ <hlm-month-year-calendar view="year" [date]="picked()" (dateChange)="picked.set($event)" />
331
+ <p class="mt-2 text-sm">Value: {{ picked()?.toDateString() ?? 'none' }}</p>
332
+ </div>
333
+ </div>
334
+ `,
335
+ })
336
+ export class CardCalendarComponent {
337
+ readonly picked = signal<Date | undefined>(undefined);
338
+ }
339
+ ```
340
+
341
+ ## Accessibility notes
342
+
343
+ - Day grids use a real `<table>` with `brnCalendarGrid`, weekday `<th scope="col">` headers (`aria-hidden` visual row plus `aria-label` weekday names), and `role="rowgroup"` body — screen readers announce weeks correctly.
344
+ - Prev/next month buttons expose chevron icons with ghost-button styling and `aria-disabled` states; keep them focusable and do not hide them with CSS.
345
+ - Keyboard: arrows move the focused day (brain directive), Enter/Space selects. The `data-[focused=true]` ring (`group-data-[focused=true]/day`) is the visible focus indicator — do not remove it.
346
+ - `hlm-carousel`-style `aria-roledescription` is not used here; the calendar relies on native table semantics plus dialog/popover labeling when composed — always label the surrounding popover/dialog title.
347
+
348
+ ## Theming / CSS variables
349
+
350
+ - `--cell-size` (default `--spacing(8)`) and `--cell-radius` (default `var(--radius-md)`) control day-cell geometry; override per instance: `<hlm-calendar class="[--cell-size:--spacing(10)]">`.
351
+ - Selected/range/today/highlight states are `data-*` driven (`data-[selected-single]`, `data-[range-start/middle/end]`, `data-[today]`, `data-[highlighted]`, `data-[outside]`) using `bg-primary`, `bg-muted`, and `bg-destructive` dot tokens — they follow the app theme automatically.
352
+
353
+ ## Related subpaths
354
+
355
+ - `@egose/shadcn-theme-ng/button` — `hlmBtn` prev/next buttons and day-cell `buttonVariants`.
356
+ - `@egose/shadcn-theme-ng/select` — month/year dropdown caption selects.
357
+ - `@egose/shadcn-theme-ng/card` / `popover` — common calendar hosts (transparent-slot styling built in).
358
+ - `@egose/shadcn-theme-ng/date-picker` — input + popover composition that emits `Date` via `dateChange`.