@nanahoshi/mona-ui 0.1.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 (134) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
  3. package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
  4. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
  5. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
  6. package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
  7. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
  15. package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
  16. package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
  17. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
  18. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
  19. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
  20. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
  21. package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
  22. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
  23. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
  24. package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
  25. package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
  26. package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
  27. package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
  28. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
  29. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
  30. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
  31. package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
  32. package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
  33. package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
  34. package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
  36. package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
  37. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
  38. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
  39. package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
  40. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
  41. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
  42. package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
  43. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
  44. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
  45. package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
  46. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
  47. package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
  48. package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
  49. package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
  50. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
  51. package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
  52. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
  53. package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
  54. package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
  55. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
  56. package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
  57. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
  58. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
  59. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
  60. package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
  61. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
  62. package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
  63. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
  64. package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
  65. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
  66. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
  67. package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
  68. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
  69. package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
  70. package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
  71. package/package.json +289 -0
  72. package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
  73. package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
  74. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
  75. package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
  76. package/types/nanahoshi-mona-ui-button.d.ts +111 -0
  77. package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
  78. package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
  79. package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
  80. package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
  81. package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
  82. package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
  83. package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
  84. package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
  85. package/types/nanahoshi-mona-ui-common.d.ts +386 -0
  86. package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
  87. package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
  88. package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
  89. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
  90. package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
  91. package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
  92. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
  93. package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
  94. package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
  95. package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
  96. package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
  97. package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
  98. package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
  99. package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
  100. package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
  101. package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
  102. package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
  103. package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
  104. package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
  105. package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
  106. package/types/nanahoshi-mona-ui-list.d.ts +1 -0
  107. package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
  108. package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
  109. package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
  110. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
  111. package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
  112. package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
  113. package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
  114. package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
  115. package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
  116. package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
  117. package/types/nanahoshi-mona-ui-query.d.ts +89 -0
  118. package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
  119. package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
  120. package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
  121. package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
  122. package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
  123. package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
  124. package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
  125. package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
  126. package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
  127. package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
  128. package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
  129. package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
  130. package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
  131. package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
  132. package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
  133. package/types/nanahoshi-mona-ui-window.d.ts +295 -0
  134. package/types/nanahoshi-mona-ui.d.ts +2 -0
@@ -0,0 +1,1569 @@
1
+ import { NgTemplateOutlet, DatePipe } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, TemplateRef, Directive, computed, input, output, DestroyRef, ElementRef, signal, contentChild, linkedSignal, model, afterNextRender, effect, untracked, Component } from '@angular/core';
4
+ import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { LucideChevronLeft, LucideChevronRight } from '@lucide/angular';
6
+ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
7
+ import { PreventableEvent, TakeFirstPipe } from '@nanahoshi/mona-ui/common';
8
+ import { CalendarService } from '@nanahoshi/mona-ui/date-input';
9
+ import { createElementControlId, rxTimeout } from '@nanahoshi/mona-ui/internal';
10
+ import { ThemeService } from '@nanahoshi/mona-ui/theme';
11
+ import { any, exactly, Dictionary, lastOrDefault, range, index, select } from '@mirei/ts-collections';
12
+ import { DateTime } from 'luxon';
13
+ import { skip, fromEvent } from 'rxjs';
14
+ import { twMerge } from 'tailwind-merge';
15
+ import { cva } from 'class-variance-authority';
16
+
17
+ class CalendarDecadeCellTemplateDirective {
18
+ constructor() {
19
+ this.templateRef = inject(TemplateRef);
20
+ }
21
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarDecadeCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
22
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CalendarDecadeCellTemplateDirective, isStandalone: true, selector: "ng-template[monaCalendarDecadeCellTemplate]", ngImport: i0 }); }
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarDecadeCellTemplateDirective, decorators: [{
25
+ type: Directive,
26
+ args: [{
27
+ selector: "ng-template[monaCalendarDecadeCellTemplate]"
28
+ }]
29
+ }] });
30
+
31
+ class CalendarMonthCellTemplateDirective {
32
+ constructor() {
33
+ this.templateRef = inject(TemplateRef);
34
+ }
35
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarMonthCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
36
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CalendarMonthCellTemplateDirective, isStandalone: true, selector: "ng-template[monaCalendarMonthCellTemplate]", ngImport: i0 }); }
37
+ }
38
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarMonthCellTemplateDirective, decorators: [{
39
+ type: Directive,
40
+ args: [{
41
+ selector: "ng-template[monaCalendarMonthCellTemplate]"
42
+ }]
43
+ }] });
44
+
45
+ class CalendarYearCellTemplateDirective {
46
+ constructor() {
47
+ this.templateRef = inject(TemplateRef);
48
+ }
49
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarYearCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
50
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: CalendarYearCellTemplateDirective, isStandalone: true, selector: "ng-template[monaCalendarYearCellTemplate]", ngImport: i0 }); }
51
+ }
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarYearCellTemplateDirective, decorators: [{
53
+ type: Directive,
54
+ args: [{
55
+ selector: "ng-template[monaCalendarYearCellTemplate]"
56
+ }]
57
+ }] });
58
+
59
+ const calendarBaseVariants = cva(`
60
+ flex flex-col gap-2 p-2 min-w-64
61
+ bg-background text-foreground
62
+ border border-input-border
63
+ shadow-sm select-none
64
+ data-[invalid='true']:border-error
65
+ data-[invalid='true']:ring-2 data-[invalid='true']:ring-error/40
66
+ `, {
67
+ variants: {
68
+ disabled: {
69
+ true: "opacity-50 cursor-not-allowed pointer-events-none"
70
+ },
71
+ readonly: {
72
+ true: "pointer-events-none"
73
+ },
74
+ rounded: {
75
+ none: "rounded-none",
76
+ small: "rounded-sm",
77
+ medium: "rounded-md",
78
+ large: "rounded-lg",
79
+ full: "rounded-full"
80
+ }
81
+ }
82
+ });
83
+ const calendarHeaderVariants = cva(`
84
+ flex items-center justify-center
85
+ [&>button+button]:not-focus:border-s-0
86
+ [&>button:nth-of-type(2)]:flex-1
87
+ [&>button:nth-of-type(3)]:rounded-se-none
88
+ [&>button:nth-of-type(3)]:rounded-ee-none
89
+ [&>button:nth-of-type(4)]:rounded-ss-none
90
+ [&>button:nth-of-type(4)]:rounded-es-none
91
+ [&>button]:outline-none
92
+ `);
93
+ const calendarMonthViewDayVariants = cva(`
94
+ hover:bg-hover cursor-pointer
95
+ `, {
96
+ variants: {
97
+ disabled: {
98
+ true: "opacity-50 cursor-not-allowed pointer-events-none"
99
+ },
100
+ focused: {
101
+ true: "ring-1 ring-inset ring-primary/40 bg-accent outline-none"
102
+ },
103
+ outside: {
104
+ true: "opacity-50"
105
+ },
106
+ rangePreview: {
107
+ true: "bg-primary/20 hover:bg-primary/30"
108
+ },
109
+ rounded: {
110
+ none: "rounded-none",
111
+ small: "rounded-sm",
112
+ medium: "rounded-md",
113
+ large: "rounded-lg",
114
+ full: "rounded-full"
115
+ },
116
+ selected: {
117
+ true: "bg-primary text-primary-foreground hover:bg-primary-hover"
118
+ },
119
+ today: {
120
+ true: "font-bold text-primary"
121
+ }
122
+ },
123
+ compoundVariants: [
124
+ {
125
+ selected: true,
126
+ today: true,
127
+ class: "text-primary-foreground"
128
+ }
129
+ ],
130
+ defaultVariants: {
131
+ rounded: "medium"
132
+ }
133
+ });
134
+ const calendarMonthViewGridVariants = cva(`
135
+ grid gap-0.5
136
+ justify-center
137
+ [&>div]:h-full [&>div]:flex
138
+ [&>div]:items-center [&>div]:justify-center
139
+ [&>div]:aspect-square
140
+ `);
141
+ const calendarMonthViewGridHeaderVariants = cva(`
142
+ grid justify-center
143
+ gap-0.5 font-semibold text-sm
144
+ [&>div]:h-full [&>div]:flex
145
+ [&>div]:items-center [&>div]:justify-center
146
+ [&>div]:aspect-square
147
+ `);
148
+ const calendarYearViewGridVariants = cva(`
149
+ grid grid-cols-3 gap-0.5
150
+ justify-center
151
+ [&>div]:h-full [&>div]:flex
152
+ [&>div]:items-center [&>div]:justify-center
153
+ [&>div]:h-12
154
+ `);
155
+ const calendarYearViewCellVariants = cva(`
156
+ py-2 cursor-pointer
157
+ hover:bg-hover
158
+ active:bg-active
159
+ `, {
160
+ variants: {
161
+ focused: {
162
+ true: "ring-1 ring-inset ring-primary/40 bg-accent outline-none"
163
+ },
164
+ rounded: {
165
+ none: "rounded-none",
166
+ small: "rounded-sm",
167
+ medium: "rounded-md",
168
+ large: "rounded-lg",
169
+ full: "rounded-full"
170
+ }
171
+ }
172
+ });
173
+ const calendarDecadeViewGridVariants = cva(`
174
+ grid grid-cols-4 gap-0.5
175
+ justify-center
176
+ [&>div]:h-full [&>div]:flex
177
+ [&>div]:items-center [&>div]:justify-center
178
+ [&>div]:h-12
179
+ `);
180
+ const calendarDecadeViewCellVariants = cva(`
181
+ py-2 cursor-pointer
182
+ hover:bg-hover
183
+ active:bg-active
184
+ `, {
185
+ variants: {
186
+ focused: {
187
+ true: "ring-1 ring-inset ring-primary/40 bg-accent outline-none"
188
+ },
189
+ rounded: {
190
+ none: "rounded-none",
191
+ small: "rounded-sm",
192
+ medium: "rounded-md",
193
+ large: "rounded-lg",
194
+ full: "rounded-full"
195
+ }
196
+ }
197
+ });
198
+
199
+ const calendarBaseThemeVariants = (theme) => {
200
+ switch (theme) {
201
+ case "mona":
202
+ return calendarBaseVariants;
203
+ default:
204
+ return calendarBaseVariants;
205
+ }
206
+ };
207
+ const calendarHeaderThemeVariants = (theme) => {
208
+ switch (theme) {
209
+ case "mona":
210
+ return calendarHeaderVariants;
211
+ default:
212
+ return calendarHeaderVariants;
213
+ }
214
+ };
215
+ const calendarDecadeViewGridThemeVariants = (theme) => {
216
+ switch (theme) {
217
+ case "mona":
218
+ return calendarDecadeViewGridVariants;
219
+ default:
220
+ return calendarDecadeViewGridVariants;
221
+ }
222
+ };
223
+ const calendarDecadeViewCellThemeVariants = (theme) => {
224
+ switch (theme) {
225
+ case "mona":
226
+ return calendarDecadeViewCellVariants;
227
+ default:
228
+ return calendarDecadeViewCellVariants;
229
+ }
230
+ };
231
+ const calendarMonthViewDayThemeVariants = (theme) => {
232
+ switch (theme) {
233
+ case "mona":
234
+ return calendarMonthViewDayVariants;
235
+ default:
236
+ return calendarMonthViewDayVariants;
237
+ }
238
+ };
239
+ const calendarMonthViewGridThemeVariants = (theme) => {
240
+ switch (theme) {
241
+ case "mona":
242
+ return calendarMonthViewGridVariants;
243
+ default:
244
+ return calendarMonthViewGridVariants;
245
+ }
246
+ };
247
+ const calendarMonthViewGridHeaderThemeVariants = (theme) => {
248
+ switch (theme) {
249
+ case "mona":
250
+ return calendarMonthViewGridHeaderVariants;
251
+ default:
252
+ return calendarMonthViewGridHeaderVariants;
253
+ }
254
+ };
255
+ const calendarYearViewGridThemeVariants = (theme) => {
256
+ switch (theme) {
257
+ case "mona":
258
+ return calendarYearViewGridVariants;
259
+ default:
260
+ return calendarYearViewGridVariants;
261
+ }
262
+ };
263
+ const calendarYearViewCellThemeVariants = (theme) => {
264
+ switch (theme) {
265
+ case "mona":
266
+ return calendarYearViewCellVariants;
267
+ default:
268
+ return calendarYearViewCellVariants;
269
+ }
270
+ };
271
+
272
+ class DecadeYearDirective {
273
+ constructor() {
274
+ this.#themeService = inject(ThemeService);
275
+ this.ariaLabel = computed(() => `Year ${this.year()}`, /* @ts-ignore */
276
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
277
+ this.baseClass = computed(() => {
278
+ const theme = this.#themeService.theme();
279
+ const focused = this.focused();
280
+ const rounded = this.rounded();
281
+ return calendarDecadeViewCellThemeVariants(theme)({ focused, rounded });
282
+ }, /* @ts-ignore */
283
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
284
+ this.focused = computed(() => {
285
+ const navigatedYear = DateTime.fromJSDate(this.navigatedDate()).year;
286
+ return this.year() === navigatedYear;
287
+ }, /* @ts-ignore */
288
+ ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
289
+ this.isCurrent = computed(() => {
290
+ return this.year() === DateTime.now().year;
291
+ }, /* @ts-ignore */
292
+ ...(ngDevMode ? [{ debugName: "isCurrent" }] : /* istanbul ignore next */ []));
293
+ this.selected = computed(() => {
294
+ const selectedDate = this.selectedDate();
295
+ if (!selectedDate) {
296
+ return false;
297
+ }
298
+ return this.year() === DateTime.fromJSDate(selectedDate).year;
299
+ }, /* @ts-ignore */
300
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
301
+ this.navigatedDate = input.required(/* @ts-ignore */
302
+ ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
303
+ this.rounded = input.required(/* @ts-ignore */
304
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
305
+ this.selectedDate = input(null, /* @ts-ignore */
306
+ ...(ngDevMode ? [{ debugName: "selectedDate" }] : /* istanbul ignore next */ []));
307
+ this.year = input.required(/* @ts-ignore */
308
+ ...(ngDevMode ? [{ debugName: "year" }] : /* istanbul ignore next */ []));
309
+ }
310
+ #themeService;
311
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DecadeYearDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
312
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: DecadeYearDirective, isStandalone: true, selector: "[monaDecadeYear]", inputs: { navigatedDate: { classPropertyName: "navigatedDate", publicName: "navigatedDate", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: true, transformFunction: null }, selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, year: { classPropertyName: "year", publicName: "year", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "gridcell" }, properties: { "attr.tabindex": "focused() ? 0 : -1", "attr.aria-current": "isCurrent() ? 'true' : null", "attr.aria-label": "ariaLabel()", "attr.aria-selected": "selected() ? 'true' : null", "class": "baseClass()" } }, ngImport: i0 }); }
313
+ }
314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DecadeYearDirective, decorators: [{
315
+ type: Directive,
316
+ args: [{
317
+ selector: "[monaDecadeYear]",
318
+ host: {
319
+ "[attr.tabindex]": "focused() ? 0 : -1",
320
+ "[attr.aria-current]": "isCurrent() ? 'true' : null",
321
+ "[attr.aria-label]": "ariaLabel()",
322
+ "[attr.aria-selected]": "selected() ? 'true' : null",
323
+ "[class]": "baseClass()",
324
+ role: "gridcell"
325
+ }
326
+ }]
327
+ }], propDecorators: { navigatedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigatedDate", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: true }] }], selectedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDate", required: false }] }], year: [{ type: i0.Input, args: [{ isSignal: true, alias: "year", required: true }] }] } });
328
+
329
+ const compareDates = (date1, date2, operator) => {
330
+ if (!date1 || !date2) {
331
+ return false;
332
+ }
333
+ const valueDateParts = [date1.getFullYear(), date1.getMonth(), date1.getDate()];
334
+ const otherDateParts = [date2.getFullYear(), date2.getMonth(), date2.getDate()];
335
+ for (let i = 0; i < 3; i++) {
336
+ switch (operator) {
337
+ case "==":
338
+ if (valueDateParts[i] !== otherDateParts[i])
339
+ return false;
340
+ break;
341
+ case "!=":
342
+ if (valueDateParts[i] !== otherDateParts[i])
343
+ return true;
344
+ break;
345
+ case "<":
346
+ case "<=":
347
+ if (valueDateParts[i] < otherDateParts[i])
348
+ return true;
349
+ if (valueDateParts[i] > otherDateParts[i])
350
+ return false;
351
+ if (operator === "<=" && i === 2 && valueDateParts[i] === otherDateParts[i])
352
+ return true;
353
+ break;
354
+ case ">":
355
+ case ">=":
356
+ if (valueDateParts[i] > otherDateParts[i])
357
+ return true;
358
+ if (valueDateParts[i] < otherDateParts[i])
359
+ return false;
360
+ if (operator === ">=" && i === 2 && valueDateParts[i] === otherDateParts[i])
361
+ return true;
362
+ break;
363
+ default:
364
+ return false;
365
+ }
366
+ }
367
+ return operator === "==";
368
+ };
369
+
370
+ class MonthDayDirective {
371
+ constructor() {
372
+ this.#themeService = inject(ThemeService);
373
+ this.baseClass = computed(() => {
374
+ const theme = this.#themeService.theme();
375
+ const disabled = this.dayDisabled();
376
+ const focused = this.focused();
377
+ const outside = this.outside();
378
+ const rangePreview = this.rangePreviewed();
379
+ const rounded = this.rounded();
380
+ const selected = this.selected();
381
+ const today = this.isToday();
382
+ return calendarMonthViewDayThemeVariants(theme)({
383
+ disabled,
384
+ focused,
385
+ outside,
386
+ rangePreview,
387
+ rounded,
388
+ selected,
389
+ today
390
+ });
391
+ }, /* @ts-ignore */
392
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
393
+ this.dayDisabled = computed(() => {
394
+ const disabled = this.disabled();
395
+ const entry = this.entry();
396
+ const disabledDates = this.disabledDates();
397
+ const max = this.max();
398
+ const min = this.min();
399
+ let isDisabledByInput = false;
400
+ if (typeof disabledDates === "function") {
401
+ isDisabledByInput = disabledDates(entry.key);
402
+ }
403
+ else if (disabledDates) {
404
+ isDisabledByInput = any(disabledDates, d => compareDates(entry.key, d, "=="));
405
+ }
406
+ return disabled || isDisabledByInput || compareDates(entry.key, max, ">") || compareDates(entry.key, min, "<");
407
+ }, /* @ts-ignore */
408
+ ...(ngDevMode ? [{ debugName: "dayDisabled" }] : /* istanbul ignore next */ []));
409
+ this.focused = computed(() => {
410
+ const entry = this.entry();
411
+ const navigatedDate = this.navigatedDate();
412
+ return compareDates(entry.key, navigatedDate, "==");
413
+ }, /* @ts-ignore */
414
+ ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
415
+ this.isToday = computed(() => {
416
+ const entry = this.entry();
417
+ const today = new Date();
418
+ return compareDates(entry.key, today, "==");
419
+ }, /* @ts-ignore */
420
+ ...(ngDevMode ? [{ debugName: "isToday" }] : /* istanbul ignore next */ []));
421
+ this.outside = computed(() => {
422
+ const entry = this.entry();
423
+ const monthStart = this.monthBounds()[0];
424
+ const monthEnd = this.monthBounds()[1];
425
+ return compareDates(entry.key, monthStart, "<") || compareDates(entry.key, monthEnd, ">");
426
+ }, /* @ts-ignore */
427
+ ...(ngDevMode ? [{ debugName: "outside" }] : /* istanbul ignore next */ []));
428
+ this.rangePreviewed = computed(() => {
429
+ const entry = this.entry();
430
+ return !this.selected() && exactly(this.rangePreview(), 1, d => compareDates(entry.key, d, "=="));
431
+ }, /* @ts-ignore */
432
+ ...(ngDevMode ? [{ debugName: "rangePreviewed" }] : /* istanbul ignore next */ []));
433
+ this.selected = computed(() => {
434
+ const entry = this.entry();
435
+ const value = this.value();
436
+ if (Array.isArray(value)) {
437
+ return exactly(value, 1, d => compareDates(entry.key, d, "=="));
438
+ }
439
+ return compareDates(entry.key, value, "==");
440
+ }, /* @ts-ignore */
441
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
442
+ this.dayPointerEnter = output();
443
+ this.daySelect = output();
444
+ this.disabled = input.required(/* @ts-ignore */
445
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
446
+ this.disabledDates = input.required(/* @ts-ignore */
447
+ ...(ngDevMode ? [{ debugName: "disabledDates" }] : /* istanbul ignore next */ []));
448
+ this.entry = input.required(/* @ts-ignore */
449
+ ...(ngDevMode ? [{ debugName: "entry" }] : /* istanbul ignore next */ []));
450
+ this.max = input.required(/* @ts-ignore */
451
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
452
+ this.min = input.required(/* @ts-ignore */
453
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
454
+ this.monthBounds = input.required(/* @ts-ignore */
455
+ ...(ngDevMode ? [{ debugName: "monthBounds" }] : /* istanbul ignore next */ []));
456
+ this.navigatedDate = input.required(/* @ts-ignore */
457
+ ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
458
+ this.rangePreview = input.required(/* @ts-ignore */
459
+ ...(ngDevMode ? [{ debugName: "rangePreview" }] : /* istanbul ignore next */ []));
460
+ this.rounded = input.required(/* @ts-ignore */
461
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
462
+ this.value = input.required(/* @ts-ignore */
463
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
464
+ }
465
+ #themeService;
466
+ onClick(event) {
467
+ if (this.dayDisabled()) {
468
+ return;
469
+ }
470
+ event.preventDefault();
471
+ this.daySelect.emit({ date: this.entry().key, event });
472
+ }
473
+ onPointerEnter() {
474
+ if (this.dayDisabled()) {
475
+ return;
476
+ }
477
+ this.dayPointerEnter.emit(this.entry().key);
478
+ }
479
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MonthDayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
480
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: MonthDayDirective, isStandalone: true, selector: "[monaMonthDay]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: true, transformFunction: null }, entry: { classPropertyName: "entry", publicName: "entry", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: true, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: true, transformFunction: null }, monthBounds: { classPropertyName: "monthBounds", publicName: "monthBounds", isSignal: true, isRequired: true, transformFunction: null }, navigatedDate: { classPropertyName: "navigatedDate", publicName: "navigatedDate", isSignal: true, isRequired: true, transformFunction: null }, rangePreview: { classPropertyName: "rangePreview", publicName: "rangePreview", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dayPointerEnter: "dayPointerEnter", daySelect: "daySelect" }, host: { listeners: { "click": "onClick($event)", "pointerenter": "onPointerEnter()" }, properties: { "attr.tabindex": "focused() ? 0 : -1", "attr.aria-selected": "selected() ? 'true' : null", "attr.aria-current": "isToday() ? 'date' : null", "attr.aria-disabled": "dayDisabled() ? 'true' : null", "attr.data-range-preview": "rangePreviewed() ? 'true' : null", "class": "baseClass()" } }, ngImport: i0 }); }
481
+ }
482
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MonthDayDirective, decorators: [{
483
+ type: Directive,
484
+ args: [{
485
+ selector: "[monaMonthDay]",
486
+ host: {
487
+ "[attr.tabindex]": "focused() ? 0 : -1",
488
+ "[attr.aria-selected]": "selected() ? 'true' : null",
489
+ "[attr.aria-current]": "isToday() ? 'date' : null",
490
+ "[attr.aria-disabled]": "dayDisabled() ? 'true' : null",
491
+ "[attr.data-range-preview]": "rangePreviewed() ? 'true' : null",
492
+ "[class]": "baseClass()",
493
+ "(click)": "onClick($event)",
494
+ "(pointerenter)": "onPointerEnter()"
495
+ }
496
+ }]
497
+ }], propDecorators: { dayPointerEnter: [{ type: i0.Output, args: ["dayPointerEnter"] }], daySelect: [{ type: i0.Output, args: ["daySelect"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: true }] }], entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: true }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: true }] }], monthBounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthBounds", required: true }] }], navigatedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigatedDate", required: true }] }], rangePreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangePreview", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }] } });
498
+
499
+ class YearMonthDirective {
500
+ constructor() {
501
+ this.#themeService = inject(ThemeService);
502
+ this.ariaLabel = computed(() => {
503
+ const monthName = this.monthName();
504
+ return `${monthName} ${this.navigatedDate().getFullYear()}`;
505
+ }, /* @ts-ignore */
506
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
507
+ this.baseClass = computed(() => {
508
+ const theme = this.#themeService.theme();
509
+ const focused = this.focused();
510
+ const rounded = this.rounded();
511
+ return calendarYearViewCellThemeVariants(theme)({ focused, rounded });
512
+ }, /* @ts-ignore */
513
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
514
+ this.focused = computed(() => {
515
+ const navigatedMonth = DateTime.fromJSDate(this.navigatedDate()).month;
516
+ return this.month() === navigatedMonth;
517
+ }, /* @ts-ignore */
518
+ ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
519
+ this.isCurrent = computed(() => {
520
+ const now = DateTime.now();
521
+ const navDate = DateTime.fromJSDate(this.navigatedDate());
522
+ return this.month() === now.month && navDate.year === now.year;
523
+ }, /* @ts-ignore */
524
+ ...(ngDevMode ? [{ debugName: "isCurrent" }] : /* istanbul ignore next */ []));
525
+ this.selected = computed(() => {
526
+ const selectedDate = this.selectedDate();
527
+ if (!selectedDate) {
528
+ return false;
529
+ }
530
+ const navDate = DateTime.fromJSDate(this.navigatedDate());
531
+ const selDate = DateTime.fromJSDate(selectedDate);
532
+ return this.month() === selDate.month && navDate.year === selDate.year;
533
+ }, /* @ts-ignore */
534
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
535
+ this.month = input.required(/* @ts-ignore */
536
+ ...(ngDevMode ? [{ debugName: "month" }] : /* istanbul ignore next */ []));
537
+ this.monthName = input.required(/* @ts-ignore */
538
+ ...(ngDevMode ? [{ debugName: "monthName" }] : /* istanbul ignore next */ []));
539
+ this.navigatedDate = input.required(/* @ts-ignore */
540
+ ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
541
+ this.rounded = input.required(/* @ts-ignore */
542
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
543
+ this.selectedDate = input(/* @ts-ignore */
544
+ ...(ngDevMode ? [undefined, { debugName: "selectedDate" }] : /* istanbul ignore next */ []));
545
+ }
546
+ #themeService;
547
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: YearMonthDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
548
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: YearMonthDirective, isStandalone: true, selector: "[monaYearMonth]", inputs: { month: { classPropertyName: "month", publicName: "month", isSignal: true, isRequired: true, transformFunction: null }, monthName: { classPropertyName: "monthName", publicName: "monthName", isSignal: true, isRequired: true, transformFunction: null }, navigatedDate: { classPropertyName: "navigatedDate", publicName: "navigatedDate", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: true, transformFunction: null }, selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "gridcell" }, properties: { "attr.tabindex": "focused() ? 0 : -1", "attr.aria-current": "isCurrent() ? 'date' : null", "attr.aria-label": "ariaLabel()", "attr.aria-selected": "selected() ? 'true' : null", "class": "baseClass()" } }, ngImport: i0 }); }
549
+ }
550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: YearMonthDirective, decorators: [{
551
+ type: Directive,
552
+ args: [{
553
+ selector: "[monaYearMonth]",
554
+ host: {
555
+ "[attr.tabindex]": "focused() ? 0 : -1",
556
+ "[attr.aria-current]": "isCurrent() ? 'date' : null",
557
+ "[attr.aria-label]": "ariaLabel()",
558
+ "[attr.aria-selected]": "selected() ? 'true' : null",
559
+ "[class]": "baseClass()",
560
+ role: "gridcell"
561
+ }
562
+ }]
563
+ }], propDecorators: { month: [{ type: i0.Input, args: [{ isSignal: true, alias: "month", required: true }] }], monthName: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthName", required: true }] }], navigatedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigatedDate", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: true }] }], selectedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDate", required: false }] }] } });
564
+
565
+ class CalendarComponent {
566
+ #calendarService;
567
+ #destroyRef;
568
+ #hostElementRef;
569
+ #monthDict;
570
+ #outputValue;
571
+ #themeService;
572
+ constructor() {
573
+ this.#calendarService = inject(CalendarService, { optional: true });
574
+ this.#destroyRef = inject(DestroyRef);
575
+ this.#hostElementRef = inject(ElementRef);
576
+ this.#monthDict = computed(() => {
577
+ const day = this.navigatedDate();
578
+ const firstDayOfMonth = DateTime.fromJSDate(day).startOf("month");
579
+ const lastDayOfMonth = DateTime.fromJSDate(day).endOf("month");
580
+ const firstDayOfWeek = this.firstDay() === "monday" ? 1 : 0;
581
+ let firstDayOfCalendar;
582
+ const monthStartWeekday = firstDayOfMonth.weekday;
583
+ if (firstDayOfWeek === 0) {
584
+ const daysToSubtract = monthStartWeekday === 7 ? 0 : monthStartWeekday;
585
+ firstDayOfCalendar = firstDayOfMonth.minus({ days: daysToSubtract });
586
+ }
587
+ else {
588
+ firstDayOfCalendar = firstDayOfMonth.startOf("week");
589
+ }
590
+ let lastDayOfCalendar;
591
+ const monthEndWeekday = lastDayOfMonth.weekday;
592
+ if (firstDayOfWeek === 0) {
593
+ const daysToAdd = monthEndWeekday === 7 ? 6 : 6 - monthEndWeekday;
594
+ lastDayOfCalendar = lastDayOfMonth.plus({ days: daysToAdd });
595
+ }
596
+ else {
597
+ lastDayOfCalendar = lastDayOfMonth.endOf("week");
598
+ }
599
+ const dictionary = new Dictionary();
600
+ for (let i = firstDayOfCalendar; i <= lastDayOfCalendar; i = i.plus({ days: 1 })) {
601
+ dictionary.add(i.toJSDate(), i.day);
602
+ }
603
+ if (monthEndWeekday === 7) {
604
+ for (let i = 0; i < 7; i++) {
605
+ dictionary.add(lastDayOfMonth.plus({ days: i + 1 }).toJSDate(), lastDayOfMonth.plus({ days: i + 1 }).day);
606
+ }
607
+ }
608
+ return dictionary.toImmutableDictionary(e => e.key, e => e.value);
609
+ }, /* @ts-ignore */
610
+ ...(ngDevMode ? [{ debugName: "#monthDict" }] : /* istanbul ignore next */ []));
611
+ this.#outputValue = computed(() => {
612
+ const selection = this.selection();
613
+ const selectedDates = this.selectedDates();
614
+ if (selection === "single") {
615
+ return lastOrDefault(selectedDates);
616
+ }
617
+ else if (selection === "multiple") {
618
+ return selectedDates;
619
+ }
620
+ else if (selection === "range") {
621
+ if (selectedDates.length === 1) {
622
+ return [selectedDates[0], selectedDates[0]];
623
+ }
624
+ if (selectedDates.length > 1) {
625
+ return [selectedDates[0], selectedDates[selectedDates.length - 1]];
626
+ }
627
+ return [];
628
+ }
629
+ return [];
630
+ }, /* @ts-ignore */
631
+ ...(ngDevMode ? [{ debugName: "#outputValue" }] : /* istanbul ignore next */ []));
632
+ this.#themeService = inject(ThemeService);
633
+ this.ariaLabel = computed(() => {
634
+ const view = this.calendarView();
635
+ const navigatedDate = this.navigatedDate();
636
+ const date = DateTime.fromJSDate(navigatedDate);
637
+ switch (view) {
638
+ case "month":
639
+ return `Calendar, ${date.toFormat("MMMM yyyy")}`;
640
+ case "year":
641
+ return `Year view, ${date.toFormat("yyyy")}`;
642
+ case "decade":
643
+ return `Decade view, ${this.decadeStart()} - ${this.decadeEnd()}`;
644
+ }
645
+ }, /* @ts-ignore */
646
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
647
+ this.baseClass = computed(() => {
648
+ const theme = this.#themeService.theme();
649
+ const disabled = this.disabled();
650
+ const readonly = this.readonly();
651
+ const rounded = this.rounded() === "full" ? "large" : this.rounded();
652
+ const variantClass = calendarBaseThemeVariants(theme)({ disabled, readonly, rounded });
653
+ const userClass = this.userClass();
654
+ return twMerge(variantClass, userClass);
655
+ }, /* @ts-ignore */
656
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
657
+ this.calendarView = signal("month", /* @ts-ignore */
658
+ ...(ngDevMode ? [{ debugName: "calendarView" }] : /* istanbul ignore next */ []));
659
+ this.decadeCellTemplate = contentChild(CalendarDecadeCellTemplateDirective, /* @ts-ignore */
660
+ ...(ngDevMode ? [{ debugName: "decadeCellTemplate" }] : /* istanbul ignore next */ []));
661
+ this.decadeEnd = computed(() => {
662
+ return this.decadeStart() + 9;
663
+ }, /* @ts-ignore */
664
+ ...(ngDevMode ? [{ debugName: "decadeEnd" }] : /* istanbul ignore next */ []));
665
+ this.decadeGridClass = computed(() => {
666
+ const theme = this.#themeService.theme();
667
+ return calendarDecadeViewGridThemeVariants(theme)();
668
+ }, /* @ts-ignore */
669
+ ...(ngDevMode ? [{ debugName: "decadeGridClass" }] : /* istanbul ignore next */ []));
670
+ this.decadeStart = computed(() => {
671
+ const navigatedDate = this.navigatedDate();
672
+ const date = DateTime.fromJSDate(navigatedDate);
673
+ const year = date.year;
674
+ return year - (year % 10);
675
+ }, /* @ts-ignore */
676
+ ...(ngDevMode ? [{ debugName: "decadeStart" }] : /* istanbul ignore next */ []));
677
+ this.decadeYears = computed(() => {
678
+ const decadeStart = this.decadeStart();
679
+ return range(decadeStart, 10)
680
+ .chunk(4)
681
+ .select(e => e.toArray())
682
+ .toArray();
683
+ }, /* @ts-ignore */
684
+ ...(ngDevMode ? [{ debugName: "decadeYears" }] : /* istanbul ignore next */ []));
685
+ this.gridId = createElementControlId();
686
+ this.headerClass = computed(() => {
687
+ const theme = this.#themeService.theme();
688
+ return calendarHeaderThemeVariants(theme)({});
689
+ }, /* @ts-ignore */
690
+ ...(ngDevMode ? [{ debugName: "headerClass" }] : /* istanbul ignore next */ []));
691
+ this.invalidState = computed(() => this.invalid() || (this.required() && this.touched() && this.isEmptyValue()), /* @ts-ignore */
692
+ ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
693
+ this.monthBounds = computed(() => {
694
+ const navigatedDate = this.navigatedDate();
695
+ const firstDayOfMonth = DateTime.fromJSDate(navigatedDate).startOf("month");
696
+ const lastDayOfMonth = DateTime.fromJSDate(navigatedDate).endOf("month");
697
+ return { start: firstDayOfMonth.toJSDate(), end: lastDayOfMonth.toJSDate() };
698
+ }, /* @ts-ignore */
699
+ ...(ngDevMode ? [{ debugName: "monthBounds" }] : /* istanbul ignore next */ []));
700
+ this.monthCellTemplate = contentChild(CalendarMonthCellTemplateDirective, /* @ts-ignore */
701
+ ...(ngDevMode ? [{ debugName: "monthCellTemplate" }] : /* istanbul ignore next */ []));
702
+ this.monthDictChunked = computed(() => {
703
+ const dict = this.#monthDict();
704
+ return dict
705
+ .chunk(7)
706
+ .select(e => e.toImmutableDictionary(e => e.key, e => e.value))
707
+ .toImmutableSet();
708
+ }, /* @ts-ignore */
709
+ ...(ngDevMode ? [{ debugName: "monthDictChunked" }] : /* istanbul ignore next */ []));
710
+ this.monthGridClass = computed(() => {
711
+ const theme = this.#themeService.theme();
712
+ return calendarMonthViewGridThemeVariants(theme)();
713
+ }, /* @ts-ignore */
714
+ ...(ngDevMode ? [{ debugName: "monthGridClass" }] : /* istanbul ignore next */ []));
715
+ this.monthGridHeaderClass = computed(() => {
716
+ const theme = this.#themeService.theme();
717
+ return calendarMonthViewGridHeaderThemeVariants(theme)();
718
+ }, /* @ts-ignore */
719
+ ...(ngDevMode ? [{ debugName: "monthGridHeaderClass" }] : /* istanbul ignore next */ []));
720
+ this.months = computed(() => {
721
+ const names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
722
+ return index(names)
723
+ .chunk(3)
724
+ .select(e => e.select(m => [m[0] + 1, m[1]]).toImmutableSet())
725
+ .toImmutableSet();
726
+ }, /* @ts-ignore */
727
+ ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
728
+ this.navigatedDate = signal(new Date(), /* @ts-ignore */
729
+ ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
730
+ this.nextButtonLabel = computed(() => {
731
+ const view = this.calendarView();
732
+ switch (view) {
733
+ case "month":
734
+ return "Next month";
735
+ case "year":
736
+ return "Next year";
737
+ case "decade":
738
+ return "Next decade";
739
+ }
740
+ }, /* @ts-ignore */
741
+ ...(ngDevMode ? [{ debugName: "nextButtonLabel" }] : /* istanbul ignore next */ []));
742
+ this.prevButtonLabel = computed(() => {
743
+ const view = this.calendarView();
744
+ switch (view) {
745
+ case "month":
746
+ return "Previous month";
747
+ case "year":
748
+ return "Previous year";
749
+ case "decade":
750
+ return "Previous decade";
751
+ }
752
+ }, /* @ts-ignore */
753
+ ...(ngDevMode ? [{ debugName: "prevButtonLabel" }] : /* istanbul ignore next */ []));
754
+ this.pendingRangeStart = signal(null, /* @ts-ignore */
755
+ ...(ngDevMode ? [{ debugName: "pendingRangeStart" }] : /* istanbul ignore next */ []));
756
+ this.rangePreviewDate = signal(null, /* @ts-ignore */
757
+ ...(ngDevMode ? [{ debugName: "rangePreviewDate" }] : /* istanbul ignore next */ []));
758
+ this.rangePreviewDates = computed(() => {
759
+ if (this.selection() !== "range") {
760
+ return [];
761
+ }
762
+ const pendingRangeStart = this.pendingRangeStart();
763
+ if (!pendingRangeStart) {
764
+ return [];
765
+ }
766
+ return this.getInclusiveDateRange(pendingRangeStart, this.rangePreviewDate() ?? this.navigatedDate());
767
+ }, /* @ts-ignore */
768
+ ...(ngDevMode ? [{ debugName: "rangePreviewDates" }] : /* istanbul ignore next */ []));
769
+ this.selectedDates = linkedSignal(() => {
770
+ const v = this.value();
771
+ const selection = this.selection();
772
+ if (v == null) {
773
+ return [];
774
+ }
775
+ if (selection === "range" && Array.isArray(v) && v.length >= 2) {
776
+ const date1 = DateTime.fromJSDate(v[0]);
777
+ const date2 = DateTime.fromJSDate(v[v.length - 1]);
778
+ const startDate = date1 <= date2 ? date1 : date2;
779
+ const endDate = date1 <= date2 ? date2 : date1;
780
+ const totalDays = endDate.diff(startDate, "days").days + 1;
781
+ return range(0, totalDays)
782
+ .select(i => startDate.plus({ days: i }).toJSDate())
783
+ .toArray();
784
+ }
785
+ return Array.isArray(v) ? v : [v];
786
+ }, /* @ts-ignore */
787
+ ...(ngDevMode ? [{ debugName: "selectedDates" }] : /* istanbul ignore next */ []));
788
+ this.timezone = DateTime.local().zoneName ?? undefined;
789
+ this.todayButtonLabel = computed(() => {
790
+ const today = DateTime.now();
791
+ return `Go to today, ${today.toFormat("MMMM d, yyyy")}`;
792
+ }, /* @ts-ignore */
793
+ ...(ngDevMode ? [{ debugName: "todayButtonLabel" }] : /* istanbul ignore next */ []));
794
+ this.viewSwitchButtonLabel = computed(() => {
795
+ const view = this.calendarView();
796
+ const date = DateTime.fromJSDate(this.navigatedDate());
797
+ switch (view) {
798
+ case "month":
799
+ return `Switch to year view, currently ${date.toFormat("MMMM yyyy")}`;
800
+ case "year":
801
+ return `Switch to decade view, currently ${date.toFormat("yyyy")}`;
802
+ case "decade":
803
+ return `${this.decadeStart()} to ${this.decadeEnd()}`;
804
+ }
805
+ }, /* @ts-ignore */
806
+ ...(ngDevMode ? [{ debugName: "viewSwitchButtonLabel" }] : /* istanbul ignore next */ []));
807
+ this.weekdays = computed(() => {
808
+ const firstDayOfWeek = this.firstDay();
809
+ const days = [
810
+ { short: "Sun", full: "Sunday" },
811
+ { short: "Mon", full: "Monday" },
812
+ { short: "Tue", full: "Tuesday" },
813
+ { short: "Wed", full: "Wednesday" },
814
+ { short: "Thu", full: "Thursday" },
815
+ { short: "Fri", full: "Friday" },
816
+ { short: "Sat", full: "Saturday" }
817
+ ];
818
+ return firstDayOfWeek === "monday" ? [...days.slice(1), days[0]] : days;
819
+ }, /* @ts-ignore */
820
+ ...(ngDevMode ? [{ debugName: "weekdays" }] : /* istanbul ignore next */ []));
821
+ this.yearCellTemplate = contentChild(CalendarYearCellTemplateDirective, /* @ts-ignore */
822
+ ...(ngDevMode ? [{ debugName: "yearCellTemplate" }] : /* istanbul ignore next */ []));
823
+ this.yearGridClass = computed(() => {
824
+ const theme = this.#themeService.theme();
825
+ return calendarYearViewGridThemeVariants(theme)();
826
+ }, /* @ts-ignore */
827
+ ...(ngDevMode ? [{ debugName: "yearGridClass" }] : /* istanbul ignore next */ []));
828
+ /**
829
+ * @description Sets the disabled state of the calendar.
830
+ */
831
+ this.disabled = model(false, /* @ts-ignore */
832
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
833
+ /**
834
+ * @description Sets the disabled dates of the calendar.
835
+ * Accepts either an iterable of Date objects or a predicate function.
836
+ */
837
+ this.disabledDates = input(/* @ts-ignore */
838
+ ...(ngDevMode ? [undefined, { debugName: "disabledDates" }] : /* istanbul ignore next */ []));
839
+ /**
840
+ * @description Sets the first day of the week.
841
+ * @default "monday"
842
+ */
843
+ this.firstDay = input("monday", /* @ts-ignore */
844
+ ...(ngDevMode ? [{ debugName: "firstDay" }] : /* istanbul ignore next */ []));
845
+ /**
846
+ * @description Marks the calendar as invalid. When bound to a signal form field via `[formField]`,
847
+ * this is written by the `FormField` directive.
848
+ * @default false
849
+ */
850
+ this.invalid = input(false, /* @ts-ignore */
851
+ ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
852
+ /**
853
+ * @description Sets the maximum date that can be selected.
854
+ */
855
+ this.maxDate = input(/* @ts-ignore */
856
+ ...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
857
+ /**
858
+ * @description Sets the minimum date that can be selected.
859
+ */
860
+ this.minDate = input(/* @ts-ignore */
861
+ ...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
862
+ /**
863
+ * @description Sets the readonly state of the calendar.
864
+ * @default false
865
+ */
866
+ this.readonly = input(false, /* @ts-ignore */
867
+ ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
868
+ /**
869
+ * @description Sets the border radius of the calendar.
870
+ * @default "medium"
871
+ */
872
+ this.rounded = input("medium", /* @ts-ignore */
873
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
874
+ /**
875
+ * @description Sets the selection mode of the calendar.
876
+ * @default "single"
877
+ */
878
+ this.selection = input("single", /* @ts-ignore */
879
+ ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
880
+ /**
881
+ * @description Emitted when the calendar value is changed by user interaction.
882
+ * The `FormField` directive listens to this to mark the field as touched.
883
+ */
884
+ this.touch = output();
885
+ /**
886
+ * @description Sets whether the calendar is required. When bound to a signal form field via `[formField]`,
887
+ * this is written by the `FormField` directive.
888
+ * @default false
889
+ */
890
+ this.required = input(false, /* @ts-ignore */
891
+ ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
892
+ /**
893
+ * @description Sets the touched state of the calendar. When bound to a signal form field via `[formField]`,
894
+ * this is written by the `FormField` directive.
895
+ * @default false
896
+ */
897
+ this.touched = input(false, /* @ts-ignore */
898
+ ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
899
+ /**
900
+ * @description Adds custom CSS classes to the calendar host element.
901
+ */
902
+ this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
903
+ /**
904
+ * @description The current value of the calendar.
905
+ * @default null
906
+ */
907
+ this.value = model(null, /* @ts-ignore */
908
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
909
+ /**
910
+ * @description Enables the display of week numbers in the calendar.
911
+ * @default false
912
+ */
913
+ this.weekNumber = input(false, /* @ts-ignore */
914
+ ...(ngDevMode ? [{ debugName: "weekNumber" }] : /* istanbul ignore next */ []));
915
+ afterNextRender({
916
+ read: () => {
917
+ this.setupKeyboardNavigation();
918
+ this.focusActiveCell();
919
+ }
920
+ });
921
+ effect(() => {
922
+ const min = this.minDate();
923
+ const max = this.maxDate();
924
+ this.disabledDates();
925
+ untracked(() => {
926
+ const navigationDate = this.navigatedDate();
927
+ if (this.isDateDisabled(navigationDate)) {
928
+ const newDate = min ?? max;
929
+ if (newDate) {
930
+ this.navigatedDate.set(newDate);
931
+ }
932
+ }
933
+ });
934
+ });
935
+ effect(() => {
936
+ const v = this.value();
937
+ untracked(() => {
938
+ if (v != null) {
939
+ const lastDate = Array.isArray(v) ? (lastOrDefault(v) ?? DateTime.now().toJSDate()) : v;
940
+ this.navigatedDate.set(lastDate);
941
+ }
942
+ });
943
+ });
944
+ toObservable(this.calendarView)
945
+ .pipe(skip(1))
946
+ .subscribe(() => this.focusActiveCell());
947
+ }
948
+ onDayClick(date, event) {
949
+ event.preventDefault();
950
+ if (this.disabled() || this.readonly()) {
951
+ return;
952
+ }
953
+ const selection = this.selection();
954
+ if (selection === "single") {
955
+ this.handleSingleSelection(date);
956
+ }
957
+ else if (selection === "multiple") {
958
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
959
+ this.handleMultipleSelection(date, event.shiftKey);
960
+ }
961
+ else {
962
+ this.handleSingleSelection(date);
963
+ }
964
+ }
965
+ else if (selection === "range") {
966
+ this.handleRangeSelection(date);
967
+ this.navigatedDate.set(date);
968
+ }
969
+ this.focusActiveCell();
970
+ this.commitUserSelection();
971
+ }
972
+ onDayPointerEnter(date) {
973
+ if (this.disabled() || this.readonly() || this.selection() !== "range" || this.pendingRangeStart() == null) {
974
+ return;
975
+ }
976
+ this.rangePreviewDate.set(date);
977
+ }
978
+ onMonthClick(month) {
979
+ this.navigatedDate.set(DateTime.fromJSDate(this.navigatedDate()).set({ month }).toJSDate());
980
+ this.calendarView.set("month");
981
+ }
982
+ onMonthGridPointerLeave() {
983
+ this.rangePreviewDate.set(null);
984
+ }
985
+ onNavigationClick(direction) {
986
+ this.rangePreviewDate.set(null);
987
+ const date = DateTime.fromJSDate(this.navigatedDate());
988
+ let unit;
989
+ switch (this.calendarView()) {
990
+ case "month":
991
+ unit = { months: 1 };
992
+ break;
993
+ case "year":
994
+ unit = { years: 1 };
995
+ break;
996
+ case "decade":
997
+ unit = { years: 10 };
998
+ break;
999
+ }
1000
+ this.navigatedDate.set(direction === "prev" ? date.minus(unit).toJSDate() : date.plus(unit).toJSDate());
1001
+ }
1002
+ onTodayButtonClick() {
1003
+ if (this.disabled() || this.readonly()) {
1004
+ return;
1005
+ }
1006
+ const currentDate = DateTime.now();
1007
+ const navigatedDate = DateTime.fromJSDate(this.navigatedDate()).set({
1008
+ year: currentDate.year,
1009
+ month: currentDate.month,
1010
+ day: currentDate.day
1011
+ });
1012
+ this.clearPendingRange();
1013
+ this.navigatedDate.set(navigatedDate.toJSDate());
1014
+ this.setCurrentDate(navigatedDate.toJSDate());
1015
+ this.calendarView.set("month");
1016
+ this.commitUserSelection();
1017
+ }
1018
+ onViewChangeClick(view) {
1019
+ this.calendarView.set(view);
1020
+ }
1021
+ onYearClick(year) {
1022
+ this.navigatedDate.set(DateTime.fromJSDate(this.navigatedDate()).set({ year }).toJSDate());
1023
+ this.calendarView.set("year");
1024
+ }
1025
+ extendSelection(offset) {
1026
+ const currentDate = this.navigatedDate();
1027
+ const newDate = DateTime.fromJSDate(currentDate).plus({ days: offset }).toJSDate();
1028
+ if (this.isDateDisabled(newDate)) {
1029
+ return;
1030
+ }
1031
+ const currentSelection = this.selectedDates();
1032
+ const dateTime = DateTime.fromJSDate(newDate);
1033
+ const isAlreadySelected = currentSelection.some(d => DateTime.fromJSDate(d).hasSame(dateTime, "day"));
1034
+ if (!isAlreadySelected) {
1035
+ this.setCurrentDate([...currentSelection, newDate]);
1036
+ }
1037
+ this.navigatedDate.set(newDate);
1038
+ }
1039
+ clearPendingRange() {
1040
+ this.pendingRangeStart.set(null);
1041
+ this.rangePreviewDate.set(null);
1042
+ }
1043
+ commitUserSelection() {
1044
+ this.value.set(this.#outputValue());
1045
+ this.touch.emit();
1046
+ }
1047
+ focusActiveCell() {
1048
+ rxTimeout(this.#destroyRef, () => {
1049
+ const calendarView = this.calendarView();
1050
+ const selector = calendarView === "year"
1051
+ ? "[monaYearMonth]"
1052
+ : calendarView === "decade"
1053
+ ? "[monaDecadeYear]"
1054
+ : "[monaMonthDay]";
1055
+ const activeCell = this.#hostElementRef.nativeElement.querySelector(`${selector}[tabindex="0"]`);
1056
+ activeCell?.focus();
1057
+ });
1058
+ }
1059
+ getDateArray(date) {
1060
+ if (date == null) {
1061
+ return [];
1062
+ }
1063
+ return Array.isArray(date) ? date : [date];
1064
+ }
1065
+ getDatesForMultipleSelection(date) {
1066
+ const lastSelectedDate = lastOrDefault(this.selectedDates()) ?? this.navigatedDate();
1067
+ const startDate = lastSelectedDate < date ? lastSelectedDate : date;
1068
+ const endDate = this.navigatedDate() > date ? this.navigatedDate() : date;
1069
+ const totalDays = DateTime.fromJSDate(endDate).diff(DateTime.fromJSDate(startDate), "days").days + 1;
1070
+ return range(0, totalDays)
1071
+ .select(i => DateTime.fromJSDate(startDate).plus({ days: i }).toJSDate())
1072
+ .toArray();
1073
+ }
1074
+ getInclusiveDateRange(date1, date2) {
1075
+ const dateTime1 = DateTime.fromJSDate(date1);
1076
+ const dateTime2 = DateTime.fromJSDate(date2);
1077
+ const startDate = dateTime1 <= dateTime2 ? dateTime1 : dateTime2;
1078
+ const endDate = dateTime1 <= dateTime2 ? dateTime2 : dateTime1;
1079
+ const totalDays = endDate.diff(startDate, "days").days + 1;
1080
+ return range(0, totalDays)
1081
+ .select(i => startDate.plus({ days: i }).toJSDate())
1082
+ .toArray();
1083
+ }
1084
+ handleKeydown(event) {
1085
+ if (this.disabled()) {
1086
+ return;
1087
+ }
1088
+ const preventableEvent = new PreventableEvent("calendarKeydown", event);
1089
+ this.#calendarService?.keydown$.next(preventableEvent);
1090
+ if (preventableEvent.isDefaultPrevented()) {
1091
+ return;
1092
+ }
1093
+ const view = this.calendarView();
1094
+ const isCtrlOrCmd = event.ctrlKey || event.metaKey;
1095
+ const isShift = event.shiftKey;
1096
+ const selection = this.selection();
1097
+ if (!this.readonly() && selection === "multiple" && (isCtrlOrCmd || isShift)) {
1098
+ if (this.handleMultipleSelectionKeyboard(event, isCtrlOrCmd, isShift)) {
1099
+ this.commitUserSelection();
1100
+ this.focusActiveCell();
1101
+ return;
1102
+ }
1103
+ }
1104
+ let shouldFocusCell = false;
1105
+ switch (event.key) {
1106
+ case "ArrowUp":
1107
+ event.preventDefault();
1108
+ if (isCtrlOrCmd) {
1109
+ this.switchToUpperView();
1110
+ }
1111
+ else {
1112
+ this.navigateByWeeksOrRows(-1, view);
1113
+ }
1114
+ shouldFocusCell = true;
1115
+ break;
1116
+ case "ArrowDown":
1117
+ event.preventDefault();
1118
+ if (isCtrlOrCmd) {
1119
+ this.switchToLowerView();
1120
+ }
1121
+ else {
1122
+ this.navigateByWeeksOrRows(1, view);
1123
+ }
1124
+ shouldFocusCell = true;
1125
+ break;
1126
+ case "ArrowLeft":
1127
+ event.preventDefault();
1128
+ if (isCtrlOrCmd) {
1129
+ this.navigatePeriodKeyboard("prev");
1130
+ }
1131
+ else {
1132
+ this.navigateByDaysOrCells(-1, view);
1133
+ }
1134
+ shouldFocusCell = true;
1135
+ break;
1136
+ case "ArrowRight":
1137
+ event.preventDefault();
1138
+ if (isCtrlOrCmd) {
1139
+ this.navigatePeriodKeyboard("next");
1140
+ }
1141
+ else {
1142
+ this.navigateByDaysOrCells(1, view);
1143
+ }
1144
+ shouldFocusCell = true;
1145
+ break;
1146
+ case "Enter":
1147
+ case " ": {
1148
+ const target = event.target;
1149
+ if (target.tagName === "BUTTON" || target.closest("button")) {
1150
+ return;
1151
+ }
1152
+ event.preventDefault();
1153
+ const previousView = this.calendarView();
1154
+ if (this.readonly() && previousView === "month") {
1155
+ shouldFocusCell = true;
1156
+ break;
1157
+ }
1158
+ if (isCtrlOrCmd && selection === "multiple") {
1159
+ this.toggleFocusedDateInSelection();
1160
+ }
1161
+ else if (isShift && selection === "multiple") {
1162
+ this.selectRangeToFocused();
1163
+ }
1164
+ else {
1165
+ this.selectFocusedItem();
1166
+ }
1167
+ if (previousView === "month" && this.calendarView() === "month") {
1168
+ this.commitUserSelection();
1169
+ }
1170
+ shouldFocusCell = true;
1171
+ break;
1172
+ }
1173
+ case "Home":
1174
+ event.preventDefault();
1175
+ this.navigateToStart(view);
1176
+ shouldFocusCell = true;
1177
+ break;
1178
+ case "End":
1179
+ event.preventDefault();
1180
+ this.navigateToEnd(view);
1181
+ shouldFocusCell = true;
1182
+ break;
1183
+ case "PageUp":
1184
+ event.preventDefault();
1185
+ this.navigateByPeriod(-1, view);
1186
+ shouldFocusCell = true;
1187
+ break;
1188
+ case "PageDown":
1189
+ event.preventDefault();
1190
+ this.navigateByPeriod(1, view);
1191
+ shouldFocusCell = true;
1192
+ break;
1193
+ case "t":
1194
+ case "T":
1195
+ if (!isCtrlOrCmd && !isShift) {
1196
+ event.preventDefault();
1197
+ this.navigateToToday();
1198
+ shouldFocusCell = true;
1199
+ }
1200
+ break;
1201
+ case "Escape":
1202
+ event.preventDefault();
1203
+ return;
1204
+ }
1205
+ if (shouldFocusCell) {
1206
+ this.focusActiveCell();
1207
+ }
1208
+ }
1209
+ handleMultipleSelection(date, rangedSelection) {
1210
+ this.clearPendingRange();
1211
+ const value = this.selectedDates();
1212
+ if (value.length === 0) {
1213
+ this.setCurrentDate([date]);
1214
+ this.navigatedDate.set(date);
1215
+ return;
1216
+ }
1217
+ if (!rangedSelection) {
1218
+ const date1 = DateTime.fromJSDate(date);
1219
+ const valueList = this.getDateArray(value);
1220
+ const selectedDates = select(valueList, e => DateTime.fromJSDate(e));
1221
+ const alreadySelected = selectedDates.any(e => e.equals(date1));
1222
+ if (alreadySelected) {
1223
+ const newDates = selectedDates
1224
+ .where(e => !e.equals(date1))
1225
+ .select(e => e.toJSDate())
1226
+ .toArray();
1227
+ this.setCurrentDate(newDates);
1228
+ }
1229
+ else {
1230
+ this.setCurrentDate([...valueList, date]);
1231
+ }
1232
+ this.navigatedDate.set(date);
1233
+ }
1234
+ else {
1235
+ const selectedDates = this.getDatesForMultipleSelection(date);
1236
+ this.setCurrentDate(selectedDates);
1237
+ }
1238
+ }
1239
+ handleMultipleSelectionKeyboard(event, isCtrlOrCmd, isShift) {
1240
+ if (this.calendarView() !== "month") {
1241
+ return false;
1242
+ }
1243
+ if (isShift && !isCtrlOrCmd) {
1244
+ switch (event.key) {
1245
+ case "ArrowLeft":
1246
+ event.preventDefault();
1247
+ this.extendSelection(-1);
1248
+ return true;
1249
+ case "ArrowRight":
1250
+ event.preventDefault();
1251
+ this.extendSelection(1);
1252
+ return true;
1253
+ case "ArrowUp":
1254
+ event.preventDefault();
1255
+ this.extendSelection(-7);
1256
+ return true;
1257
+ case "ArrowDown":
1258
+ event.preventDefault();
1259
+ this.extendSelection(7);
1260
+ return true;
1261
+ }
1262
+ }
1263
+ return false;
1264
+ }
1265
+ handleRangeSelection(date) {
1266
+ const pendingRangeStart = this.pendingRangeStart();
1267
+ if (pendingRangeStart == null) {
1268
+ this.pendingRangeStart.set(date);
1269
+ this.rangePreviewDate.set(null);
1270
+ this.setCurrentDate([date]);
1271
+ return;
1272
+ }
1273
+ this.setCurrentDate(this.getInclusiveDateRange(pendingRangeStart, date));
1274
+ this.pendingRangeStart.set(null);
1275
+ this.rangePreviewDate.set(null);
1276
+ }
1277
+ handleSingleSelection(date) {
1278
+ this.clearPendingRange();
1279
+ const value = this.selectedDates();
1280
+ if (value.length > 0) {
1281
+ const date1 = DateTime.fromJSDate(date);
1282
+ const valueItem = lastOrDefault(value) ?? DateTime.now().toJSDate();
1283
+ const newDate = DateTime.fromJSDate(valueItem)
1284
+ .set({ day: date1.day, month: date1.month, year: date1.year })
1285
+ .toJSDate();
1286
+ this.navigatedDate.set(newDate);
1287
+ this.setCurrentDate(newDate);
1288
+ }
1289
+ else {
1290
+ this.navigatedDate.set(date);
1291
+ this.setCurrentDate(date);
1292
+ }
1293
+ }
1294
+ isDateDisabled(date) {
1295
+ const disabledDates = this.disabledDates();
1296
+ const max = this.maxDate();
1297
+ const min = this.minDate();
1298
+ let isDisabledByInput = false;
1299
+ if (typeof disabledDates === "function") {
1300
+ isDisabledByInput = disabledDates(date);
1301
+ }
1302
+ else if (disabledDates) {
1303
+ isDisabledByInput = any(disabledDates, d => compareDates(date, d, "=="));
1304
+ }
1305
+ return isDisabledByInput || compareDates(date, max, ">") || compareDates(date, min, "<");
1306
+ }
1307
+ isEmptyValue() {
1308
+ const value = this.value();
1309
+ return value == null || (Array.isArray(value) && value.length === 0);
1310
+ }
1311
+ navigateByDaysOrCells(offset, view) {
1312
+ const currentDate = this.navigatedDate();
1313
+ const dateTime = DateTime.fromJSDate(currentDate);
1314
+ let newDate;
1315
+ switch (view) {
1316
+ case "month":
1317
+ newDate = dateTime.plus({ days: offset }).toJSDate();
1318
+ break;
1319
+ case "year":
1320
+ newDate = dateTime.plus({ months: offset }).toJSDate();
1321
+ break;
1322
+ case "decade":
1323
+ newDate = dateTime.plus({ years: offset }).toJSDate();
1324
+ break;
1325
+ }
1326
+ if (view === "month" && this.isDateDisabled(newDate)) {
1327
+ return;
1328
+ }
1329
+ this.rangePreviewDate.set(null);
1330
+ this.navigatedDate.set(newDate);
1331
+ }
1332
+ navigateByPeriod(offset, view) {
1333
+ const currentDate = this.navigatedDate();
1334
+ const dateTime = DateTime.fromJSDate(currentDate);
1335
+ let newDate;
1336
+ switch (view) {
1337
+ case "month":
1338
+ newDate = dateTime.plus({ months: offset }).toJSDate();
1339
+ break;
1340
+ case "year":
1341
+ newDate = dateTime.plus({ years: offset }).toJSDate();
1342
+ break;
1343
+ case "decade":
1344
+ newDate = dateTime.plus({ years: offset * 10 }).toJSDate();
1345
+ break;
1346
+ }
1347
+ if (view === "month" && this.isDateDisabled(newDate)) {
1348
+ const direction = offset > 0 ? 1 : -1;
1349
+ const maxAttempts = 31;
1350
+ for (let i = 1; i <= maxAttempts; i++) {
1351
+ const adjustedDate = DateTime.fromJSDate(newDate)
1352
+ .plus({ days: direction * i })
1353
+ .toJSDate();
1354
+ if (!this.isDateDisabled(adjustedDate)) {
1355
+ newDate = adjustedDate;
1356
+ break;
1357
+ }
1358
+ }
1359
+ }
1360
+ this.rangePreviewDate.set(null);
1361
+ this.navigatedDate.set(newDate);
1362
+ }
1363
+ navigateByWeeksOrRows(offset, view) {
1364
+ const currentDate = this.navigatedDate();
1365
+ const dateTime = DateTime.fromJSDate(currentDate);
1366
+ let newDate;
1367
+ switch (view) {
1368
+ case "month":
1369
+ newDate = dateTime.plus({ weeks: offset }).toJSDate();
1370
+ break;
1371
+ case "year":
1372
+ newDate = dateTime.plus({ months: offset * 3 }).toJSDate();
1373
+ break;
1374
+ case "decade":
1375
+ newDate = dateTime.plus({ years: offset * 4 }).toJSDate();
1376
+ break;
1377
+ }
1378
+ if (view === "month" && this.isDateDisabled(newDate)) {
1379
+ return;
1380
+ }
1381
+ this.rangePreviewDate.set(null);
1382
+ this.navigatedDate.set(newDate);
1383
+ }
1384
+ navigatePeriodKeyboard(direction) {
1385
+ this.rangePreviewDate.set(null);
1386
+ this.onNavigationClick(direction);
1387
+ }
1388
+ navigateToEnd(view) {
1389
+ const currentDate = this.navigatedDate();
1390
+ const dateTime = DateTime.fromJSDate(currentDate);
1391
+ let newDate;
1392
+ switch (view) {
1393
+ case "month":
1394
+ newDate = dateTime.endOf("month").toJSDate();
1395
+ if (this.isDateDisabled(newDate)) {
1396
+ for (let i = newDate.getDate() - 1; i >= 1; i--) {
1397
+ const testDate = dateTime.set({ day: i }).toJSDate();
1398
+ if (!this.isDateDisabled(testDate)) {
1399
+ newDate = testDate;
1400
+ break;
1401
+ }
1402
+ }
1403
+ }
1404
+ break;
1405
+ case "year":
1406
+ newDate = dateTime.set({ month: 12 }).toJSDate();
1407
+ break;
1408
+ case "decade":
1409
+ const yearEnd = this.decadeEnd();
1410
+ newDate = dateTime.set({ year: yearEnd }).toJSDate();
1411
+ break;
1412
+ }
1413
+ this.rangePreviewDate.set(null);
1414
+ this.navigatedDate.set(newDate);
1415
+ }
1416
+ navigateToStart(view) {
1417
+ const currentDate = this.navigatedDate();
1418
+ const dateTime = DateTime.fromJSDate(currentDate);
1419
+ let newDate;
1420
+ switch (view) {
1421
+ case "month":
1422
+ newDate = dateTime.startOf("month").toJSDate();
1423
+ if (this.isDateDisabled(newDate)) {
1424
+ const daysInMonth = dateTime.daysInMonth ?? 31;
1425
+ for (let i = 2; i <= daysInMonth; i++) {
1426
+ const testDate = dateTime.set({ day: i }).toJSDate();
1427
+ if (!this.isDateDisabled(testDate)) {
1428
+ newDate = testDate;
1429
+ break;
1430
+ }
1431
+ }
1432
+ }
1433
+ break;
1434
+ case "year":
1435
+ newDate = dateTime.set({ month: 1 }).toJSDate();
1436
+ break;
1437
+ case "decade":
1438
+ const yearStart = this.decadeStart();
1439
+ newDate = dateTime.set({ year: yearStart }).toJSDate();
1440
+ break;
1441
+ }
1442
+ this.rangePreviewDate.set(null);
1443
+ this.navigatedDate.set(newDate);
1444
+ }
1445
+ navigateToToday() {
1446
+ const today = DateTime.now().toJSDate();
1447
+ if (this.isDateDisabled(today)) {
1448
+ return;
1449
+ }
1450
+ this.rangePreviewDate.set(null);
1451
+ this.navigatedDate.set(today);
1452
+ this.calendarView.set("month");
1453
+ }
1454
+ selectFocusedItem() {
1455
+ const view = this.calendarView();
1456
+ const currentDate = this.navigatedDate();
1457
+ switch (view) {
1458
+ case "month":
1459
+ if (!this.isDateDisabled(currentDate)) {
1460
+ const selection = this.selection();
1461
+ if (selection === "single") {
1462
+ this.handleSingleSelection(currentDate);
1463
+ }
1464
+ else if (selection === "multiple") {
1465
+ this.handleSingleSelection(currentDate);
1466
+ }
1467
+ else if (selection === "range") {
1468
+ this.handleRangeSelection(currentDate);
1469
+ }
1470
+ }
1471
+ break;
1472
+ case "year":
1473
+ this.calendarView.set("month");
1474
+ break;
1475
+ case "decade":
1476
+ this.calendarView.set("year");
1477
+ break;
1478
+ }
1479
+ }
1480
+ selectRangeToFocused() {
1481
+ const focusedDate = this.navigatedDate();
1482
+ if (this.isDateDisabled(focusedDate)) {
1483
+ return;
1484
+ }
1485
+ const selectedDates = this.getDatesForMultipleSelection(focusedDate);
1486
+ this.setCurrentDate(selectedDates);
1487
+ }
1488
+ setCurrentDate(date) {
1489
+ this.selectedDates.set(this.getDateArray(date));
1490
+ }
1491
+ setupKeyboardNavigation() {
1492
+ fromEvent(this.#hostElementRef.nativeElement, "keydown")
1493
+ .pipe(takeUntilDestroyed(this.#destroyRef))
1494
+ .subscribe(event => this.handleKeydown(event));
1495
+ }
1496
+ switchToLowerView() {
1497
+ const view = this.calendarView();
1498
+ switch (view) {
1499
+ case "decade":
1500
+ this.calendarView.set("year");
1501
+ break;
1502
+ case "year":
1503
+ this.calendarView.set("month");
1504
+ break;
1505
+ }
1506
+ }
1507
+ switchToUpperView() {
1508
+ const view = this.calendarView();
1509
+ switch (view) {
1510
+ case "month":
1511
+ this.calendarView.set("year");
1512
+ break;
1513
+ case "year":
1514
+ this.calendarView.set("decade");
1515
+ break;
1516
+ }
1517
+ }
1518
+ toggleFocusedDateInSelection() {
1519
+ const focusedDate = this.navigatedDate();
1520
+ if (this.isDateDisabled(focusedDate)) {
1521
+ return;
1522
+ }
1523
+ const currentSelection = this.selectedDates();
1524
+ const dateTime = DateTime.fromJSDate(focusedDate);
1525
+ const isAlreadySelected = currentSelection.some(d => DateTime.fromJSDate(d).hasSame(dateTime, "day"));
1526
+ if (isAlreadySelected) {
1527
+ const newSelection = currentSelection.filter(d => !DateTime.fromJSDate(d).hasSame(dateTime, "day"));
1528
+ this.setCurrentDate(newSelection);
1529
+ }
1530
+ else {
1531
+ this.setCurrentDate([...currentSelection, focusedDate]);
1532
+ }
1533
+ }
1534
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1535
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CalendarComponent, isStandalone: true, selector: "mona-calendar", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null }, firstDay: { classPropertyName: "firstDay", publicName: "firstDay", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, weekNumber: { classPropertyName: "weekNumber", publicName: "weekNumber", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", touch: "touch", value: "valueChange" }, host: { attributes: { "role": "application" }, properties: { "attr.aria-label": "ariaLabel()", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.data-invalid": "invalidState() || null", "attr.data-required": "required() || null", "attr.tabindex": "disabled() ? -1 : 0", "class": "baseClass()" } }, queries: [{ propertyName: "decadeCellTemplate", first: true, predicate: CalendarDecadeCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "monthCellTemplate", first: true, predicate: CalendarMonthCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "yearCellTemplate", first: true, predicate: CalendarYearCellTemplateDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"headerClass()\">\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"'small'\"\r\n (click)=\"onTodayButtonClick()\"\r\n [attr.aria-label]=\"todayButtonLabel()\">\r\n <span>Today</span>\r\n </button>\r\n @switch (calendarView()) {\r\n @case (\"month\") {\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n (click)=\"onViewChangeClick('year')\"\r\n [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\">{{\r\n navigatedDate() | date: \"MMMM yyyy\" : timezone\r\n }}</span>\r\n </button>\r\n }\r\n @case (\"year\") {\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n (click)=\"onViewChangeClick('decade')\"\r\n [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\">{{\r\n navigatedDate() | date: \"yyyy\" : timezone\r\n }}</span>\r\n </button>\r\n }\r\n @case (\"decade\") {\r\n <button monaButton look=\"ghost\" [rounded]=\"rounded()\" [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\"\r\n >{{ decadeStart() }} - {{ decadeEnd() }}</span\r\n >\r\n </button>\r\n }\r\n }\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [iconOnly]=\"true\"\r\n [size]=\"'small'\"\r\n (click)=\"onNavigationClick('prev')\"\r\n [attr.aria-label]=\"prevButtonLabel()\">\r\n <svg lucideChevronLeft></svg>\r\n </button>\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [iconOnly]=\"true\"\r\n [size]=\"'small'\"\r\n (click)=\"onNavigationClick('next')\"\r\n [attr.aria-label]=\"nextButtonLabel()\">\r\n <svg lucideChevronRight></svg>\r\n </button>\r\n</div>\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">{{ ariaLabel() }}</div>\r\n\r\n@if (calendarView() === \"month\") {\r\n @let columnCount = weekNumber() ? 8 : 7;\r\n <div [class]=\"monthGridHeaderClass()\" [style.grid-template-columns]=\"`repeat(${columnCount}, 32px)`\">\r\n @if (weekNumber()) {\r\n <div></div>\r\n }\r\n @for (day of weekdays(); track day.short) {\r\n <div>{{ day.short }}</div>\r\n }\r\n </div>\r\n <div\r\n [class]=\"monthGridClass()\"\r\n [attr.aria-labelledby]=\"gridId + '-heading'\"\r\n (pointerleave)=\"onMonthGridPointerLeave()\"\r\n [style.grid-template-columns]=\"`repeat(${columnCount}, 32px)`\">\r\n @for (row of monthDictChunked(); track $index) {\r\n @if (weekNumber()) {\r\n @let firstEntry = row | monaTakeFirst;\r\n @if (firstEntry) {\r\n @let week = firstEntry.key | date: \"w\";\r\n <div>{{ week }}</div>\r\n }\r\n }\r\n @for (entry of row; track entry.key) {\r\n <div\r\n (dayPointerEnter)=\"onDayPointerEnter($event)\"\r\n (daySelect)=\"onDayClick($event.date, $event.event)\"\r\n monaMonthDay\r\n [disabled]=\"disabled()\"\r\n [disabledDates]=\"disabledDates()\"\r\n [min]=\"minDate()\"\r\n [max]=\"maxDate()\"\r\n [monthBounds]=\"[monthBounds().start, monthBounds().end]\"\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rangePreview]=\"rangePreviewDates()\"\r\n [rounded]=\"rounded()\"\r\n [value]=\"selectedDates()\"\r\n [entry]=\"entry\">\r\n @if (monthCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: entry.value, date: entry.key }\"></ng-container>\r\n } @else {\r\n <span>{{ entry.value }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n} @else if (calendarView() === \"year\") {\r\n <div [class]=\"yearGridClass()\" [attr.aria-labelledby]=\"gridId + '-heading'\">\r\n @for (row of months(); track $index) {\r\n @for (monthItem of row; track monthItem) {\r\n <div\r\n (click)=\"onMonthClick(monthItem[0])\"\r\n monaYearMonth\r\n [month]=\"monthItem[0]\"\r\n [monthName]=\"monthItem[1]\"\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rounded]=\"rounded()\"\r\n [selectedDate]=\"selectedDates()[0]\">\r\n @if (yearCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: monthItem[0], text: monthItem[1] }\">\r\n </ng-container>\r\n } @else {\r\n <span>{{ monthItem[1] }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n} @else if (calendarView() === \"decade\") {\r\n <div [class]=\"decadeGridClass()\" [attr.aria-labelledby]=\"gridId + '-heading'\">\r\n @for (row of decadeYears(); track $index) {\r\n @for (year of row; track year) {\r\n <div\r\n (click)=\"onYearClick(year)\"\r\n monaDecadeYear\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rounded]=\"rounded()\"\r\n [year]=\"year\"\r\n [selectedDate]=\"selectedDates()[0]\">\r\n @if (decadeCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: year }\">\r\n </ng-container>\r\n } @else {\r\n <span>{{ year }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "directive", type: MonthDayDirective, selector: "[monaMonthDay]", inputs: ["disabled", "disabledDates", "entry", "max", "min", "monthBounds", "navigatedDate", "rangePreview", "rounded", "value"], outputs: ["dayPointerEnter", "daySelect"] }, { kind: "directive", type: DecadeYearDirective, selector: "[monaDecadeYear]", inputs: ["navigatedDate", "rounded", "selectedDate", "year"] }, { kind: "directive", type: YearMonthDirective, selector: "[monaYearMonth]", inputs: ["month", "monthName", "navigatedDate", "rounded", "selectedDate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: TakeFirstPipe, name: "monaTakeFirst" }] }); }
1536
+ }
1537
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CalendarComponent, decorators: [{
1538
+ type: Component,
1539
+ args: [{ selector: "mona-calendar", imports: [
1540
+ ButtonDirective,
1541
+ DatePipe,
1542
+ MonthDayDirective,
1543
+ DecadeYearDirective,
1544
+ YearMonthDirective,
1545
+ NgTemplateOutlet,
1546
+ TakeFirstPipe,
1547
+ LucideChevronLeft,
1548
+ LucideChevronRight
1549
+ ], host: {
1550
+ role: "application",
1551
+ "[attr.aria-label]": "ariaLabel()",
1552
+ "[attr.aria-invalid]": "invalidState() ? 'true' : null",
1553
+ "[attr.data-invalid]": "invalidState() || null",
1554
+ "[attr.data-required]": "required() || null",
1555
+ "[attr.tabindex]": "disabled() ? -1 : 0",
1556
+ "[class]": "baseClass()"
1557
+ }, template: "<div [class]=\"headerClass()\">\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"'small'\"\r\n (click)=\"onTodayButtonClick()\"\r\n [attr.aria-label]=\"todayButtonLabel()\">\r\n <span>Today</span>\r\n </button>\r\n @switch (calendarView()) {\r\n @case (\"month\") {\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n (click)=\"onViewChangeClick('year')\"\r\n [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\">{{\r\n navigatedDate() | date: \"MMMM yyyy\" : timezone\r\n }}</span>\r\n </button>\r\n }\r\n @case (\"year\") {\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n (click)=\"onViewChangeClick('decade')\"\r\n [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\">{{\r\n navigatedDate() | date: \"yyyy\" : timezone\r\n }}</span>\r\n </button>\r\n }\r\n @case (\"decade\") {\r\n <button monaButton look=\"ghost\" [rounded]=\"rounded()\" [attr.aria-label]=\"viewSwitchButtonLabel()\">\r\n <span class=\"text-primary font-semibold\" [id]=\"gridId + '-heading'\"\r\n >{{ decadeStart() }} - {{ decadeEnd() }}</span\r\n >\r\n </button>\r\n }\r\n }\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [iconOnly]=\"true\"\r\n [size]=\"'small'\"\r\n (click)=\"onNavigationClick('prev')\"\r\n [attr.aria-label]=\"prevButtonLabel()\">\r\n <svg lucideChevronLeft></svg>\r\n </button>\r\n <button\r\n monaButton\r\n look=\"ghost\"\r\n [rounded]=\"rounded()\"\r\n [iconOnly]=\"true\"\r\n [size]=\"'small'\"\r\n (click)=\"onNavigationClick('next')\"\r\n [attr.aria-label]=\"nextButtonLabel()\">\r\n <svg lucideChevronRight></svg>\r\n </button>\r\n</div>\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">{{ ariaLabel() }}</div>\r\n\r\n@if (calendarView() === \"month\") {\r\n @let columnCount = weekNumber() ? 8 : 7;\r\n <div [class]=\"monthGridHeaderClass()\" [style.grid-template-columns]=\"`repeat(${columnCount}, 32px)`\">\r\n @if (weekNumber()) {\r\n <div></div>\r\n }\r\n @for (day of weekdays(); track day.short) {\r\n <div>{{ day.short }}</div>\r\n }\r\n </div>\r\n <div\r\n [class]=\"monthGridClass()\"\r\n [attr.aria-labelledby]=\"gridId + '-heading'\"\r\n (pointerleave)=\"onMonthGridPointerLeave()\"\r\n [style.grid-template-columns]=\"`repeat(${columnCount}, 32px)`\">\r\n @for (row of monthDictChunked(); track $index) {\r\n @if (weekNumber()) {\r\n @let firstEntry = row | monaTakeFirst;\r\n @if (firstEntry) {\r\n @let week = firstEntry.key | date: \"w\";\r\n <div>{{ week }}</div>\r\n }\r\n }\r\n @for (entry of row; track entry.key) {\r\n <div\r\n (dayPointerEnter)=\"onDayPointerEnter($event)\"\r\n (daySelect)=\"onDayClick($event.date, $event.event)\"\r\n monaMonthDay\r\n [disabled]=\"disabled()\"\r\n [disabledDates]=\"disabledDates()\"\r\n [min]=\"minDate()\"\r\n [max]=\"maxDate()\"\r\n [monthBounds]=\"[monthBounds().start, monthBounds().end]\"\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rangePreview]=\"rangePreviewDates()\"\r\n [rounded]=\"rounded()\"\r\n [value]=\"selectedDates()\"\r\n [entry]=\"entry\">\r\n @if (monthCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: entry.value, date: entry.key }\"></ng-container>\r\n } @else {\r\n <span>{{ entry.value }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n} @else if (calendarView() === \"year\") {\r\n <div [class]=\"yearGridClass()\" [attr.aria-labelledby]=\"gridId + '-heading'\">\r\n @for (row of months(); track $index) {\r\n @for (monthItem of row; track monthItem) {\r\n <div\r\n (click)=\"onMonthClick(monthItem[0])\"\r\n monaYearMonth\r\n [month]=\"monthItem[0]\"\r\n [monthName]=\"monthItem[1]\"\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rounded]=\"rounded()\"\r\n [selectedDate]=\"selectedDates()[0]\">\r\n @if (yearCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: monthItem[0], text: monthItem[1] }\">\r\n </ng-container>\r\n } @else {\r\n <span>{{ monthItem[1] }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n} @else if (calendarView() === \"decade\") {\r\n <div [class]=\"decadeGridClass()\" [attr.aria-labelledby]=\"gridId + '-heading'\">\r\n @for (row of decadeYears(); track $index) {\r\n @for (year of row; track year) {\r\n <div\r\n (click)=\"onYearClick(year)\"\r\n monaDecadeYear\r\n [navigatedDate]=\"navigatedDate()\"\r\n [rounded]=\"rounded()\"\r\n [year]=\"year\"\r\n [selectedDate]=\"selectedDates()[0]\">\r\n @if (decadeCellTemplate()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\r\n [ngTemplateOutletContext]=\"{ $implicit: year }\">\r\n </ng-container>\r\n } @else {\r\n <span>{{ year }}</span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n}\r\n" }]
1558
+ }], ctorParameters: () => [], propDecorators: { decadeCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarDecadeCellTemplateDirective), { isSignal: true }] }], monthCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarMonthCellTemplateDirective), { isSignal: true }] }], yearCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarYearCellTemplateDirective), { isSignal: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: false }] }], firstDay: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDay", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], weekNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumber", required: false }] }] } });
1559
+
1560
+ /*
1561
+ * Public API Surface of @nanahoshi/mona-ui/calendar
1562
+ */
1563
+
1564
+ /**
1565
+ * Generated bundle index. Do not edit.
1566
+ */
1567
+
1568
+ export { CalendarComponent, CalendarDecadeCellTemplateDirective, CalendarMonthCellTemplateDirective, CalendarYearCellTemplateDirective };
1569
+ //# sourceMappingURL=nanahoshi-mona-ui-calendar.mjs.map