@yuuvis/client-components 3.0.0-beta.21.1

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 (47) hide show
  1. package/README.md +3 -0
  2. package/autocomplete/README.md +3 -0
  3. package/common/README.md +3 -0
  4. package/datepicker/README.md +3 -0
  5. package/fesm2022/yuuvis-client-components-autocomplete.mjs +236 -0
  6. package/fesm2022/yuuvis-client-components-autocomplete.mjs.map +1 -0
  7. package/fesm2022/yuuvis-client-components-common.mjs +1724 -0
  8. package/fesm2022/yuuvis-client-components-common.mjs.map +1 -0
  9. package/fesm2022/yuuvis-client-components-datepicker.mjs +456 -0
  10. package/fesm2022/yuuvis-client-components-datepicker.mjs.map +1 -0
  11. package/fesm2022/yuuvis-client-components-list.mjs +666 -0
  12. package/fesm2022/yuuvis-client-components-list.mjs.map +1 -0
  13. package/fesm2022/yuuvis-client-components-master-details.mjs +136 -0
  14. package/fesm2022/yuuvis-client-components-master-details.mjs.map +1 -0
  15. package/fesm2022/yuuvis-client-components-overflow-hidden.mjs +109 -0
  16. package/fesm2022/yuuvis-client-components-overflow-hidden.mjs.map +1 -0
  17. package/fesm2022/yuuvis-client-components-overflow-menu.mjs +171 -0
  18. package/fesm2022/yuuvis-client-components-overflow-menu.mjs.map +1 -0
  19. package/fesm2022/yuuvis-client-components-popout.mjs +240 -0
  20. package/fesm2022/yuuvis-client-components-popout.mjs.map +1 -0
  21. package/fesm2022/yuuvis-client-components-split-view.mjs +317 -0
  22. package/fesm2022/yuuvis-client-components-split-view.mjs.map +1 -0
  23. package/fesm2022/yuuvis-client-components-widget-grid.mjs +933 -0
  24. package/fesm2022/yuuvis-client-components-widget-grid.mjs.map +1 -0
  25. package/fesm2022/yuuvis-client-components.mjs +18 -0
  26. package/fesm2022/yuuvis-client-components.mjs.map +1 -0
  27. package/lib/assets/i18n/de.json +56 -0
  28. package/lib/assets/i18n/en.json +56 -0
  29. package/list/README.md +3 -0
  30. package/master-details/README.md +3 -0
  31. package/overflow-hidden/README.md +3 -0
  32. package/overflow-menu/README.md +3 -0
  33. package/package.json +67 -0
  34. package/popout/README.md +3 -0
  35. package/split-view/README.md +3 -0
  36. package/types/yuuvis-client-components-autocomplete.d.ts +89 -0
  37. package/types/yuuvis-client-components-common.d.ts +536 -0
  38. package/types/yuuvis-client-components-datepicker.d.ts +94 -0
  39. package/types/yuuvis-client-components-list.d.ts +380 -0
  40. package/types/yuuvis-client-components-master-details.d.ts +69 -0
  41. package/types/yuuvis-client-components-overflow-hidden.d.ts +72 -0
  42. package/types/yuuvis-client-components-overflow-menu.d.ts +89 -0
  43. package/types/yuuvis-client-components-popout.d.ts +106 -0
  44. package/types/yuuvis-client-components-split-view.d.ts +197 -0
  45. package/types/yuuvis-client-components-widget-grid.d.ts +299 -0
  46. package/types/yuuvis-client-components.d.ts +8 -0
  47. package/widget-grid/README.md +48 -0
@@ -0,0 +1,456 @@
1
+ import * as i0 from '@angular/core';
2
+ import { NgModule, inject, LOCALE_ID, Injectable, ElementRef, ChangeDetectorRef, input, output, signal, computed, effect, Component, viewChild, forwardRef } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
5
+ import { MatIcon } from '@angular/material/icon';
6
+ import { YmtIconButtonDirective } from '@yuuvis/material';
7
+
8
+ class DatepickerModule {
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: DatepickerModule, imports: [CommonModule] });
11
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerModule, imports: [CommonModule] });
12
+ }
13
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerModule, decorators: [{
14
+ type: NgModule,
15
+ args: [{
16
+ imports: [CommonModule]
17
+ }]
18
+ }] });
19
+
20
+ class DatepickerLocaleService {
21
+ angularLocale = inject(LOCALE_ID);
22
+ resolvedLocale;
23
+ constructor() {
24
+ this.resolvedLocale = 'de';
25
+ // this.angularLocale !== 'en-US'
26
+ // ? this.angularLocale
27
+ // : typeof navigator !== 'undefined'
28
+ // ? navigator.language
29
+ // : 'en-US';
30
+ }
31
+ getWeekdayHeaders() {
32
+ const firstDay = this.getFirstDayOfWeek();
33
+ const narrowFmt = new Intl.DateTimeFormat(this.resolvedLocale, { weekday: 'narrow' });
34
+ const longFmt = new Intl.DateTimeFormat(this.resolvedLocale, { weekday: 'long' });
35
+ // Jan 1, 2024 is a Monday (ISO weekday 1)
36
+ const refMonday = new Date(2024, 0, 1);
37
+ const days = [];
38
+ for (let i = 0; i < 7; i++) {
39
+ const dayOffset = (firstDay - 1 + i) % 7;
40
+ const date = new Date(refMonday);
41
+ date.setDate(refMonday.getDate() + dayOffset);
42
+ days.push({
43
+ narrow: narrowFmt.format(date),
44
+ long: longFmt.format(date),
45
+ });
46
+ }
47
+ return days;
48
+ }
49
+ /** Returns first day of week: 1=Monday ... 7=Sunday */
50
+ getFirstDayOfWeek() {
51
+ try {
52
+ const locale = new Intl.Locale(this.resolvedLocale);
53
+ if (typeof locale.getWeekInfo === 'function') {
54
+ return locale.getWeekInfo().firstDay;
55
+ }
56
+ if ('weekInfo' in locale && locale.weekInfo) {
57
+ return locale.weekInfo.firstDay;
58
+ }
59
+ }
60
+ catch {
61
+ // fallback below
62
+ }
63
+ return this.getFirstDayFallback(this.resolvedLocale);
64
+ }
65
+ getFirstDayFallback(locale) {
66
+ const sundayFirst = ['en-US', 'en-CA', 'ja', 'ko', 'zh', 'he', 'ar'];
67
+ const lang = locale.split('-')[0];
68
+ if (sundayFirst.includes(locale) || sundayFirst.includes(lang)) {
69
+ return 7; // Sunday
70
+ }
71
+ return 1; // Monday
72
+ }
73
+ getMonthYearLabel(date) {
74
+ return new Intl.DateTimeFormat(this.resolvedLocale, {
75
+ month: 'long',
76
+ year: 'numeric',
77
+ }).format(date);
78
+ }
79
+ getFullDateLabel(date) {
80
+ return new Intl.DateTimeFormat(this.resolvedLocale, {
81
+ dateStyle: 'full',
82
+ }).format(date);
83
+ }
84
+ formatDateForInput(date) {
85
+ return new Intl.DateTimeFormat(this.resolvedLocale, {
86
+ dateStyle: 'short',
87
+ }).format(date);
88
+ }
89
+ getDateFormatPlaceholder() {
90
+ const ref = new Date(2033, 11, 25); // Dec 25, 2033
91
+ const formatted = this.formatDateForInput(ref);
92
+ return formatted
93
+ .replace('25', 'DD')
94
+ .replace('12', 'MM')
95
+ .replace('2033', 'YYYY')
96
+ .replace('33', 'YY');
97
+ }
98
+ parseDateFromInput(raw) {
99
+ if (!raw.trim())
100
+ return null;
101
+ // Try native Date parsing first
102
+ const native = new Date(raw);
103
+ if (!isNaN(native.getTime()) && native.getFullYear() > 1000) {
104
+ return this.normalizeDate(native);
105
+ }
106
+ return this.parseLocaleDate(raw);
107
+ }
108
+ parseLocaleDate(raw) {
109
+ const parts = raw.split(/[\/\-\.]/).map((p) => parseInt(p, 10));
110
+ if (parts.length !== 3 || parts.some(isNaN))
111
+ return null;
112
+ // Determine order by formatting a known reference date
113
+ const ref = new Date(2033, 11, 25); // Dec 25, 2033
114
+ const formatted = this.formatDateForInput(ref);
115
+ const refParts = formatted.split(/[\/\-\.]/).map((p) => parseInt(p, 10));
116
+ const monthIdx = refParts.findIndex((p) => p === 12);
117
+ const dayIdx = refParts.findIndex((p) => p === 25);
118
+ const yearIdx = refParts.findIndex((p) => p === 2033 || p === 33);
119
+ if (monthIdx === -1 || dayIdx === -1 || yearIdx === -1)
120
+ return null;
121
+ let year = parts[yearIdx];
122
+ const month = parts[monthIdx];
123
+ const day = parts[dayIdx];
124
+ if (year < 100)
125
+ year += 2000;
126
+ if (month < 1 || month > 12 || day < 1 || day > 31)
127
+ return null;
128
+ const result = new Date(year, month - 1, day);
129
+ // Validate no date rollover
130
+ if (result.getMonth() !== month - 1 || result.getDate() !== day)
131
+ return null;
132
+ return result;
133
+ }
134
+ normalizeDate(date) {
135
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
136
+ }
137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
138
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerLocaleService, providedIn: 'root' });
139
+ }
140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerLocaleService, decorators: [{
141
+ type: Injectable,
142
+ args: [{ providedIn: 'root' }]
143
+ }], ctorParameters: () => [] });
144
+
145
+ let nextId$1 = 0;
146
+ class CalendarComponent {
147
+ localeService = inject(DatepickerLocaleService);
148
+ elementRef = inject(ElementRef);
149
+ cdr = inject(ChangeDetectorRef);
150
+ selectedDate = input(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : /* istanbul ignore next */ []));
151
+ initialFocusDate = input(new Date(), ...(ngDevMode ? [{ debugName: "initialFocusDate" }] : /* istanbul ignore next */ []));
152
+ min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
153
+ dateSelected = output();
154
+ closeRequested = output();
155
+ gridLabelId = `app-calendar-label-${nextId$1++}`;
156
+ focusedDate = signal(new Date(), ...(ngDevMode ? [{ debugName: "focusedDate" }] : /* istanbul ignore next */ []));
157
+ weekdayHeaders = this.localeService.getWeekdayHeaders();
158
+ monthYearLabel = computed(() => this.localeService.getMonthYearLabel(this.focusedDate()), ...(ngDevMode ? [{ debugName: "monthYearLabel" }] : /* istanbul ignore next */ []));
159
+ weeks = computed(() => this.generateWeeks(), ...(ngDevMode ? [{ debugName: "weeks" }] : /* istanbul ignore next */ []));
160
+ constructor() {
161
+ effect(() => {
162
+ const initial = this.initialFocusDate();
163
+ this.focusedDate.set(new Date(initial.getFullYear(), initial.getMonth(), initial.getDate()));
164
+ });
165
+ }
166
+ focusActiveCell() {
167
+ this.cdr.detectChanges();
168
+ const cell = this.elementRef.nativeElement.querySelector('td[tabindex="0"]');
169
+ cell?.focus();
170
+ }
171
+ selectDate(day) {
172
+ if (day.isDisabled)
173
+ return;
174
+ if (day.isOutsideMonth) {
175
+ this.focusedDate.set(day.date);
176
+ return;
177
+ }
178
+ this.dateSelected.emit(day.date);
179
+ }
180
+ navigateMonth(delta) {
181
+ const current = this.focusedDate();
182
+ this.focusedDate.set(new Date(current.getFullYear(), current.getMonth() + delta, 1));
183
+ this.focusActiveCell();
184
+ }
185
+ navigateYear(delta) {
186
+ const current = this.focusedDate();
187
+ this.focusedDate.set(new Date(current.getFullYear() + delta, current.getMonth(), 1));
188
+ this.focusActiveCell();
189
+ }
190
+ onGridKeydown(event) {
191
+ const current = this.focusedDate();
192
+ let handled = true;
193
+ switch (event.key) {
194
+ case 'ArrowRight':
195
+ this.moveFocusClamped(this.addDays(current, 1));
196
+ break;
197
+ case 'ArrowLeft':
198
+ this.moveFocusClamped(this.addDays(current, -1));
199
+ break;
200
+ case 'ArrowDown':
201
+ this.moveFocusClamped(this.addDays(current, 7));
202
+ break;
203
+ case 'ArrowUp':
204
+ this.moveFocusClamped(this.addDays(current, -7));
205
+ break;
206
+ case 'Home':
207
+ this.moveFocusClamped(this.startOfWeek(current));
208
+ break;
209
+ case 'End':
210
+ this.moveFocusClamped(this.endOfWeek(current));
211
+ break;
212
+ case 'PageDown':
213
+ event.shiftKey ? this.moveFocusYear(1) : this.moveFocusMonth(1);
214
+ break;
215
+ case 'PageUp':
216
+ event.shiftKey ? this.moveFocusYear(-1) : this.moveFocusMonth(-1);
217
+ break;
218
+ case 'Enter':
219
+ case ' ':
220
+ if (!this.isBeforeMin(this.focusedDate())) {
221
+ this.dateSelected.emit(this.focusedDate());
222
+ }
223
+ break;
224
+ default:
225
+ handled = false;
226
+ }
227
+ if (handled) {
228
+ event.preventDefault();
229
+ this.focusActiveCell();
230
+ }
231
+ }
232
+ generateWeeks() {
233
+ const focused = this.focusedDate();
234
+ const year = focused.getFullYear();
235
+ const month = focused.getMonth();
236
+ const selected = this.selectedDate();
237
+ const minDate = this.min();
238
+ const firstDayOfWeek = this.localeService.getFirstDayOfWeek();
239
+ const firstOfMonth = new Date(year, month, 1);
240
+ const firstOfMonthDow = firstOfMonth.getDay();
241
+ const firstOfMonthIso = firstOfMonthDow === 0 ? 7 : firstOfMonthDow;
242
+ let offset = firstOfMonthIso - firstDayOfWeek;
243
+ if (offset < 0)
244
+ offset += 7;
245
+ const gridStart = new Date(year, month, 1 - offset);
246
+ const today = new Date();
247
+ today.setHours(0, 0, 0, 0);
248
+ const minNorm = minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()).getTime() : null;
249
+ const weeks = [];
250
+ for (let w = 0; w < 6; w++) {
251
+ const week = [];
252
+ for (let d = 0; d < 7; d++) {
253
+ const cellDate = new Date(gridStart);
254
+ cellDate.setDate(gridStart.getDate() + w * 7 + d);
255
+ const disabled = minNorm !== null && cellDate.getTime() < minNorm;
256
+ week.push({
257
+ date: cellDate,
258
+ dayNumber: cellDate.getDate(),
259
+ dateIso: this.toIsoString(cellDate),
260
+ isToday: cellDate.getTime() === today.getTime(),
261
+ isSelected: this.isSameDay(cellDate, selected),
262
+ isOutsideMonth: cellDate.getMonth() !== month,
263
+ isDisabled: disabled,
264
+ isFocusTarget: this.isSameDay(cellDate, focused),
265
+ fullLabel: this.localeService.getFullDateLabel(cellDate)
266
+ });
267
+ }
268
+ weeks.push(week);
269
+ }
270
+ return weeks;
271
+ }
272
+ isBeforeMin(date) {
273
+ const minDate = this.min();
274
+ if (!minDate)
275
+ return false;
276
+ const minNorm = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
277
+ return date.getTime() < minNorm.getTime();
278
+ }
279
+ moveFocusClamped(target) {
280
+ if (this.isBeforeMin(target))
281
+ return;
282
+ this.focusedDate.set(target);
283
+ }
284
+ addDays(date, days) {
285
+ const result = new Date(date);
286
+ result.setDate(result.getDate() + days);
287
+ return result;
288
+ }
289
+ startOfWeek(date) {
290
+ const firstDay = this.localeService.getFirstDayOfWeek();
291
+ const dow = date.getDay();
292
+ const isoDay = dow === 0 ? 7 : dow;
293
+ let diff = isoDay - firstDay;
294
+ if (diff < 0)
295
+ diff += 7;
296
+ return this.addDays(date, -diff);
297
+ }
298
+ endOfWeek(date) {
299
+ return this.addDays(this.startOfWeek(date), 6);
300
+ }
301
+ moveFocusMonth(delta) {
302
+ const current = this.focusedDate();
303
+ const targetMonth = current.getMonth() + delta;
304
+ const maxDay = new Date(current.getFullYear(), targetMonth + 1, 0).getDate();
305
+ const clampedDay = Math.min(current.getDate(), maxDay);
306
+ const target = new Date(current.getFullYear(), targetMonth, clampedDay);
307
+ this.moveFocusClamped(target);
308
+ }
309
+ moveFocusYear(delta) {
310
+ const current = this.focusedDate();
311
+ const targetYear = current.getFullYear() + delta;
312
+ const maxDay = new Date(targetYear, current.getMonth() + 1, 0).getDate();
313
+ const clampedDay = Math.min(current.getDate(), maxDay);
314
+ const target = new Date(targetYear, current.getMonth(), clampedDay);
315
+ this.moveFocusClamped(target);
316
+ }
317
+ isSameDay(a, b) {
318
+ if (!b)
319
+ return false;
320
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
321
+ }
322
+ toIsoString(date) {
323
+ const y = date.getFullYear();
324
+ const m = String(date.getMonth() + 1).padStart(2, '0');
325
+ const d = String(date.getDate()).padStart(2, '0');
326
+ return `${y}-${m}-${d}`;
327
+ }
328
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
329
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CalendarComponent, isStandalone: true, selector: "yuv-calendar", inputs: { selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, initialFocusDate: { classPropertyName: "initialFocusDate", publicName: "initialFocusDate", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateSelected: "dateSelected", closeRequested: "closeRequested" }, ngImport: i0, template: "<div class=\"app-calendar-header\">\n <button\n type=\"button\"\n aria-label=\"Previous Year\"\n (click)=\"navigateYear(-1)\"\n class=\"app-calendar-nav-btn\"\n >&laquo;</button>\n <button\n type=\"button\"\n aria-label=\"Previous Month\"\n (click)=\"navigateMonth(-1)\"\n class=\"app-calendar-nav-btn\"\n >&lsaquo;</button>\n <h2\n [id]=\"gridLabelId\"\n aria-live=\"polite\"\n class=\"app-calendar-title\"\n >{{ monthYearLabel() }}</h2>\n <button\n type=\"button\"\n aria-label=\"Next Month\"\n (click)=\"navigateMonth(1)\"\n class=\"app-calendar-nav-btn\"\n >&rsaquo;</button>\n <button\n type=\"button\"\n aria-label=\"Next Year\"\n (click)=\"navigateYear(1)\"\n class=\"app-calendar-nav-btn\"\n >&raquo;</button>\n</div>\n\n<table\n role=\"grid\"\n [attr.aria-labelledby]=\"gridLabelId\"\n (keydown)=\"onGridKeydown($event)\"\n>\n <thead>\n <tr>\n @for (day of weekdayHeaders; track day.long) {\n <th scope=\"col\" [abbr]=\"day.long\">{{ day.narrow }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (week of weeks(); track $index) {\n <tr>\n @for (day of week; track day.dateIso) {\n <td\n role=\"gridcell\"\n [attr.tabindex]=\"day.isFocusTarget ? 0 : -1\"\n [attr.aria-selected]=\"day.isSelected || null\"\n [attr.aria-disabled]=\"day.isDisabled || day.isOutsideMonth || null\"\n [attr.aria-label]=\"day.fullLabel\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.outside-month]=\"day.isOutsideMonth\"\n [class.disabled]=\"day.isDisabled\"\n (click)=\"selectDate(day)\"\n >{{ day.dayNumber }}</td>\n }\n </tr>\n }\n </tbody>\n</table>\n", styles: [":host{display:block;font-family:system-ui,-apple-system,sans-serif}.app-calendar-header{display:flex;align-items:center;justify-content:space-between;gap:4px;margin-bottom:8px}.app-calendar-title{font-size:1rem;font-weight:600;margin:0;text-align:center;flex:1;white-space:nowrap}.app-calendar-nav-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:4px;background:none;font-size:1.1rem;cursor:pointer;color:inherit}.app-calendar-nav-btn:hover{background-color:#0000000f}.app-calendar-nav-btn:focus-visible{outline:2px solid #0066cc;outline-offset:-2px}table{border-collapse:collapse;width:100%;table-layout:fixed}th{padding:4px;font-size:.75rem;font-weight:600;text-align:center;color:#555;-webkit-user-select:none;user-select:none}td{padding:0;text-align:center;font-size:.875rem;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:4px;position:relative;width:36px;height:36px;line-height:36px}td:hover:not(.outside-month):not(.disabled){background-color:#0000000f}td:focus-visible{outline:2px solid #0066cc;outline-offset:-2px;z-index:1}td.today{font-weight:700;border:1px solid currentColor}td.selected{background-color:#06c;color:#fff;font-weight:600}td.selected:hover{background-color:#0052a3}td.outside-month{color:#aaa;cursor:default}td.disabled{color:#ccc;cursor:not-allowed;text-decoration:line-through}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"] });
330
+ }
331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CalendarComponent, decorators: [{
332
+ type: Component,
333
+ args: [{ selector: 'yuv-calendar', standalone: true, template: "<div class=\"app-calendar-header\">\n <button\n type=\"button\"\n aria-label=\"Previous Year\"\n (click)=\"navigateYear(-1)\"\n class=\"app-calendar-nav-btn\"\n >&laquo;</button>\n <button\n type=\"button\"\n aria-label=\"Previous Month\"\n (click)=\"navigateMonth(-1)\"\n class=\"app-calendar-nav-btn\"\n >&lsaquo;</button>\n <h2\n [id]=\"gridLabelId\"\n aria-live=\"polite\"\n class=\"app-calendar-title\"\n >{{ monthYearLabel() }}</h2>\n <button\n type=\"button\"\n aria-label=\"Next Month\"\n (click)=\"navigateMonth(1)\"\n class=\"app-calendar-nav-btn\"\n >&rsaquo;</button>\n <button\n type=\"button\"\n aria-label=\"Next Year\"\n (click)=\"navigateYear(1)\"\n class=\"app-calendar-nav-btn\"\n >&raquo;</button>\n</div>\n\n<table\n role=\"grid\"\n [attr.aria-labelledby]=\"gridLabelId\"\n (keydown)=\"onGridKeydown($event)\"\n>\n <thead>\n <tr>\n @for (day of weekdayHeaders; track day.long) {\n <th scope=\"col\" [abbr]=\"day.long\">{{ day.narrow }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (week of weeks(); track $index) {\n <tr>\n @for (day of week; track day.dateIso) {\n <td\n role=\"gridcell\"\n [attr.tabindex]=\"day.isFocusTarget ? 0 : -1\"\n [attr.aria-selected]=\"day.isSelected || null\"\n [attr.aria-disabled]=\"day.isDisabled || day.isOutsideMonth || null\"\n [attr.aria-label]=\"day.fullLabel\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.outside-month]=\"day.isOutsideMonth\"\n [class.disabled]=\"day.isDisabled\"\n (click)=\"selectDate(day)\"\n >{{ day.dayNumber }}</td>\n }\n </tr>\n }\n </tbody>\n</table>\n", styles: [":host{display:block;font-family:system-ui,-apple-system,sans-serif}.app-calendar-header{display:flex;align-items:center;justify-content:space-between;gap:4px;margin-bottom:8px}.app-calendar-title{font-size:1rem;font-weight:600;margin:0;text-align:center;flex:1;white-space:nowrap}.app-calendar-nav-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:4px;background:none;font-size:1.1rem;cursor:pointer;color:inherit}.app-calendar-nav-btn:hover{background-color:#0000000f}.app-calendar-nav-btn:focus-visible{outline:2px solid #0066cc;outline-offset:-2px}table{border-collapse:collapse;width:100%;table-layout:fixed}th{padding:4px;font-size:.75rem;font-weight:600;text-align:center;color:#555;-webkit-user-select:none;user-select:none}td{padding:0;text-align:center;font-size:.875rem;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:4px;position:relative;width:36px;height:36px;line-height:36px}td:hover:not(.outside-month):not(.disabled){background-color:#0000000f}td:focus-visible{outline:2px solid #0066cc;outline-offset:-2px;z-index:1}td.today{font-weight:700;border:1px solid currentColor}td.selected{background-color:#06c;color:#fff;font-weight:600}td.selected:hover{background-color:#0052a3}td.outside-month{color:#aaa;cursor:default}td.disabled{color:#ccc;cursor:not-allowed;text-decoration:line-through}@media(prefers-reduced-motion:reduce){*{transition:none!important}}\n"] }]
334
+ }], ctorParameters: () => [], propDecorators: { selectedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDate", required: false }] }], initialFocusDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFocusDate", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
335
+
336
+ let nextId = 0;
337
+ class DatepickerComponent {
338
+ localeService = inject(DatepickerLocaleService);
339
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
340
+ min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
341
+ selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : /* istanbul ignore next */ []));
342
+ inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : /* istanbul ignore next */ []));
343
+ disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
344
+ uid = nextId++;
345
+ inputId = `app-datepicker-input-${this.uid}`;
346
+ descriptionId = `app-datepicker-desc-${this.uid}`;
347
+ calendarDialog = viewChild.required('calendarDialog');
348
+ triggerButton = viewChild.required('triggerButton');
349
+ calendarRef = viewChild.required(CalendarComponent);
350
+ dateFormatPlaceholder = this.localeService.getDateFormatPlaceholder();
351
+ chooseButtonAriaLabel = computed(() => {
352
+ const date = this.selectedDate();
353
+ if (!date)
354
+ return 'Choose Date';
355
+ return `Change Date, ${this.localeService.getFullDateLabel(date)}`;
356
+ }, ...(ngDevMode ? [{ debugName: "chooseButtonAriaLabel" }] : /* istanbul ignore next */ []));
357
+ initialFocusDate = computed(() => this.selectedDate() ?? new Date(), ...(ngDevMode ? [{ debugName: "initialFocusDate" }] : /* istanbul ignore next */ []));
358
+ onChange = () => { };
359
+ onTouched = () => { };
360
+ writeValue(value) {
361
+ this.selectedDate.set(value);
362
+ this.inputValue.set(value ? this.localeService.formatDateForInput(value) : '');
363
+ }
364
+ registerOnChange(fn) {
365
+ this.onChange = fn;
366
+ }
367
+ registerOnTouched(fn) {
368
+ this.onTouched = fn;
369
+ }
370
+ setDisabledState(isDisabled) {
371
+ this.disabled.set(isDisabled);
372
+ }
373
+ validate(_control) {
374
+ const raw = this.inputValue();
375
+ if (raw && !this.selectedDate()) {
376
+ return { datepickerParse: { value: raw } };
377
+ }
378
+ const date = this.selectedDate();
379
+ const minDate = this.min();
380
+ if (date && minDate) {
381
+ const minNorm = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
382
+ if (date.getTime() < minNorm.getTime()) {
383
+ return { datepickerMin: { min: minDate, actual: date } };
384
+ }
385
+ }
386
+ return null;
387
+ }
388
+ onManualInput(event) {
389
+ const raw = event.target.value;
390
+ this.inputValue.set(raw);
391
+ const parsed = this.localeService.parseDateFromInput(raw);
392
+ this.selectedDate.set(parsed);
393
+ this.onChange(parsed);
394
+ }
395
+ toggleDialog() {
396
+ const dialog = this.calendarDialog().nativeElement;
397
+ if (dialog.open) {
398
+ dialog.close();
399
+ }
400
+ else {
401
+ dialog.showModal();
402
+ // Wait one tick for dialog to be visible, then focus the active cell
403
+ setTimeout(() => this.calendarRef().focusActiveCell());
404
+ }
405
+ }
406
+ onDateSelected(date) {
407
+ this.selectedDate.set(date);
408
+ this.inputValue.set(this.localeService.formatDateForInput(date));
409
+ this.onChange(date);
410
+ this.calendarDialog().nativeElement.close();
411
+ }
412
+ onDialogClose() {
413
+ this.onTouched();
414
+ this.triggerButton().nativeElement.focus();
415
+ }
416
+ onDialogBackdropClick(event) {
417
+ if (event.target === this.calendarDialog().nativeElement) {
418
+ this.calendarDialog().nativeElement.close();
419
+ }
420
+ }
421
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
422
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.9", type: DatepickerComponent, isStandalone: true, selector: "yuv-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
423
+ {
424
+ provide: NG_VALUE_ACCESSOR,
425
+ useExisting: forwardRef(() => DatepickerComponent),
426
+ multi: true
427
+ },
428
+ {
429
+ provide: NG_VALIDATORS,
430
+ useExisting: forwardRef(() => DatepickerComponent),
431
+ multi: true
432
+ }
433
+ ], viewQueries: [{ propertyName: "calendarDialog", first: true, predicate: ["calendarDialog"], descendants: true, isSignal: true }, { propertyName: "triggerButton", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }, { propertyName: "calendarRef", first: true, predicate: CalendarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"app-datepicker-field\">\n <label [for]=\"inputId\">{{ label() }}</label>\n <div class=\"app-datepicker-input-group\">\n <input\n [id]=\"inputId\"\n type=\"text\"\n [attr.aria-describedby]=\"descriptionId\"\n [placeholder]=\"dateFormatPlaceholder\"\n [value]=\"inputValue()\"\n [disabled]=\"disabled()\"\n (input)=\"onManualInput($event)\"\n (blur)=\"onTouched()\"\n autocomplete=\"off\"\n />\n <button\n #triggerButton\n ymtIconButton\n icon-button-size=\"small\"\n type=\"button\"\n [attr.aria-label]=\"chooseButtonAriaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleDialog()\"\n >\n <mat-icon>calendar_today</mat-icon>\n </button>\n </div>\n <span [id]=\"descriptionId\" class=\"sr-only\"> Date format: {{ dateFormatPlaceholder }} </span>\n</div>\n\n<dialog\n #calendarDialog\n aria-label=\"Choose Date\"\n aria-modal=\"true\"\n class=\"app-datepicker-dialog\"\n (close)=\"onDialogClose()\"\n (click)=\"onDialogBackdropClick($event)\"\n>\n <yuv-calendar\n [selectedDate]=\"selectedDate()\"\n [initialFocusDate]=\"initialFocusDate()\"\n [min]=\"min()\"\n (dateSelected)=\"onDateSelected($event)\"\n />\n</dialog>\n", styles: [":host{display:block}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.app-datepicker-field{display:flex;flex-direction:column;gap:4px}label{font-size:.875rem;font-weight:600;color:#333}.app-datepicker-input-group{display:flex;align-items:stretch;border:1px solid #999;border-radius:4px;overflow:hidden;background:#fff}.app-datepicker-input-group:focus-within{outline:2px solid #0066cc;outline-offset:-1px}.app-datepicker-input-group input{flex:1;padding:8px 10px;border:none;font-size:.9375rem;outline:none;min-width:0;background:transparent;color:inherit}.app-datepicker-input-group input::placeholder{color:#999}.app-datepicker-input-group input:disabled{opacity:.5;cursor:not-allowed}.app-datepicker-input-group button{display:inline-flex;align-items:center;justify-content:center;width:40px;padding:0;border:none;border-left:1px solid #999;background:#f5f5f5;cursor:pointer;color:#333}.app-datepicker-input-group button:hover:not(:disabled){background:#e5e5e5}.app-datepicker-input-group button:focus-visible{outline:2px solid #0066cc;outline-offset:-2px}.app-datepicker-input-group button:disabled{opacity:.5;cursor:not-allowed}.app-datepicker-dialog{padding:16px;border:1px solid #ccc;border-radius:8px;box-shadow:0 8px 24px #00000026;max-width:320px}.app-datepicker-dialog::backdrop{background-color:#00000040}.app-datepicker-dialog{opacity:0;transform:scale(.95);transition:opacity .15s ease,transform .15s ease,display .15s ease allow-discrete,overlay .15s ease allow-discrete}.app-datepicker-dialog[open]{opacity:1;transform:scale(1)}@starting-style{.app-datepicker-dialog[open]{opacity:0;transform:scale(.95)}}.app-datepicker-dialog::backdrop{transition:background-color .15s ease,display .15s ease allow-discrete,overlay .15s ease allow-discrete}@starting-style{.app-datepicker-dialog[open]::backdrop{background-color:#0000}}@media(prefers-reduced-motion:reduce){.app-datepicker-dialog,.app-datepicker-dialog::backdrop{transition:none}}\n"], dependencies: [{ kind: "component", type: CalendarComponent, selector: "yuv-calendar", inputs: ["selectedDate", "initialFocusDate", "min"], outputs: ["dateSelected", "closeRequested"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
434
+ }
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatepickerComponent, decorators: [{
436
+ type: Component,
437
+ args: [{ selector: 'yuv-datepicker', standalone: true, imports: [CalendarComponent, YmtIconButtonDirective, MatIcon], providers: [
438
+ {
439
+ provide: NG_VALUE_ACCESSOR,
440
+ useExisting: forwardRef(() => DatepickerComponent),
441
+ multi: true
442
+ },
443
+ {
444
+ provide: NG_VALIDATORS,
445
+ useExisting: forwardRef(() => DatepickerComponent),
446
+ multi: true
447
+ }
448
+ ], template: "<div class=\"app-datepicker-field\">\n <label [for]=\"inputId\">{{ label() }}</label>\n <div class=\"app-datepicker-input-group\">\n <input\n [id]=\"inputId\"\n type=\"text\"\n [attr.aria-describedby]=\"descriptionId\"\n [placeholder]=\"dateFormatPlaceholder\"\n [value]=\"inputValue()\"\n [disabled]=\"disabled()\"\n (input)=\"onManualInput($event)\"\n (blur)=\"onTouched()\"\n autocomplete=\"off\"\n />\n <button\n #triggerButton\n ymtIconButton\n icon-button-size=\"small\"\n type=\"button\"\n [attr.aria-label]=\"chooseButtonAriaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleDialog()\"\n >\n <mat-icon>calendar_today</mat-icon>\n </button>\n </div>\n <span [id]=\"descriptionId\" class=\"sr-only\"> Date format: {{ dateFormatPlaceholder }} </span>\n</div>\n\n<dialog\n #calendarDialog\n aria-label=\"Choose Date\"\n aria-modal=\"true\"\n class=\"app-datepicker-dialog\"\n (close)=\"onDialogClose()\"\n (click)=\"onDialogBackdropClick($event)\"\n>\n <yuv-calendar\n [selectedDate]=\"selectedDate()\"\n [initialFocusDate]=\"initialFocusDate()\"\n [min]=\"min()\"\n (dateSelected)=\"onDateSelected($event)\"\n />\n</dialog>\n", styles: [":host{display:block}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.app-datepicker-field{display:flex;flex-direction:column;gap:4px}label{font-size:.875rem;font-weight:600;color:#333}.app-datepicker-input-group{display:flex;align-items:stretch;border:1px solid #999;border-radius:4px;overflow:hidden;background:#fff}.app-datepicker-input-group:focus-within{outline:2px solid #0066cc;outline-offset:-1px}.app-datepicker-input-group input{flex:1;padding:8px 10px;border:none;font-size:.9375rem;outline:none;min-width:0;background:transparent;color:inherit}.app-datepicker-input-group input::placeholder{color:#999}.app-datepicker-input-group input:disabled{opacity:.5;cursor:not-allowed}.app-datepicker-input-group button{display:inline-flex;align-items:center;justify-content:center;width:40px;padding:0;border:none;border-left:1px solid #999;background:#f5f5f5;cursor:pointer;color:#333}.app-datepicker-input-group button:hover:not(:disabled){background:#e5e5e5}.app-datepicker-input-group button:focus-visible{outline:2px solid #0066cc;outline-offset:-2px}.app-datepicker-input-group button:disabled{opacity:.5;cursor:not-allowed}.app-datepicker-dialog{padding:16px;border:1px solid #ccc;border-radius:8px;box-shadow:0 8px 24px #00000026;max-width:320px}.app-datepicker-dialog::backdrop{background-color:#00000040}.app-datepicker-dialog{opacity:0;transform:scale(.95);transition:opacity .15s ease,transform .15s ease,display .15s ease allow-discrete,overlay .15s ease allow-discrete}.app-datepicker-dialog[open]{opacity:1;transform:scale(1)}@starting-style{.app-datepicker-dialog[open]{opacity:0;transform:scale(.95)}}.app-datepicker-dialog::backdrop{transition:background-color .15s ease,display .15s ease allow-discrete,overlay .15s ease allow-discrete}@starting-style{.app-datepicker-dialog[open]::backdrop{background-color:#0000}}@media(prefers-reduced-motion:reduce){.app-datepicker-dialog,.app-datepicker-dialog::backdrop{transition:none}}\n"] }]
449
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], calendarDialog: [{ type: i0.ViewChild, args: ['calendarDialog', { isSignal: true }] }], triggerButton: [{ type: i0.ViewChild, args: ['triggerButton', { isSignal: true }] }], calendarRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CalendarComponent), { isSignal: true }] }] } });
450
+
451
+ /**
452
+ * Generated bundle index. Do not edit.
453
+ */
454
+
455
+ export { DatepickerComponent, DatepickerModule };
456
+ //# sourceMappingURL=yuuvis-client-components-datepicker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuuvis-client-components-datepicker.mjs","sources":["../../../../../libs/yuuvis/client-components/datepicker/src/lib/datepicker.module.ts","../../../../../libs/yuuvis/client-components/datepicker/src/lib/datepicker-locale.service.ts","../../../../../libs/yuuvis/client-components/datepicker/src/lib/calendar/calendar.component.ts","../../../../../libs/yuuvis/client-components/datepicker/src/lib/calendar/calendar.component.html","../../../../../libs/yuuvis/client-components/datepicker/src/lib/datepicker.component.ts","../../../../../libs/yuuvis/client-components/datepicker/src/lib/datepicker.component.html","../../../../../libs/yuuvis/client-components/datepicker/src/yuuvis-client-components-datepicker.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule]\n})\nexport class DatepickerModule {}\n","import { inject, Injectable, LOCALE_ID } from '@angular/core';\nimport { WeekdayHeader } from './datepicker.models';\n\n@Injectable({ providedIn: 'root' })\nexport class DatepickerLocaleService {\n private readonly angularLocale = inject(LOCALE_ID);\n readonly resolvedLocale: string;\n\n constructor() {\n this.resolvedLocale = 'de'\n // this.angularLocale !== 'en-US'\n // ? this.angularLocale\n // : typeof navigator !== 'undefined'\n // ? navigator.language\n // : 'en-US';\n }\n\n getWeekdayHeaders(): WeekdayHeader[] {\n const firstDay = this.getFirstDayOfWeek();\n const narrowFmt = new Intl.DateTimeFormat(this.resolvedLocale, { weekday: 'narrow' });\n const longFmt = new Intl.DateTimeFormat(this.resolvedLocale, { weekday: 'long' });\n\n // Jan 1, 2024 is a Monday (ISO weekday 1)\n const refMonday = new Date(2024, 0, 1);\n const days: WeekdayHeader[] = [];\n\n for (let i = 0; i < 7; i++) {\n const dayOffset = (firstDay - 1 + i) % 7;\n const date = new Date(refMonday);\n date.setDate(refMonday.getDate() + dayOffset);\n days.push({\n narrow: narrowFmt.format(date),\n long: longFmt.format(date),\n });\n }\n return days;\n }\n\n /** Returns first day of week: 1=Monday ... 7=Sunday */\n getFirstDayOfWeek(): number {\n try {\n const locale = new Intl.Locale(this.resolvedLocale);\n if (typeof (locale as any).getWeekInfo === 'function') {\n return (locale as any).getWeekInfo().firstDay;\n }\n if ('weekInfo' in locale && (locale as any).weekInfo) {\n return (locale as any).weekInfo.firstDay;\n }\n } catch {\n // fallback below\n }\n return this.getFirstDayFallback(this.resolvedLocale);\n }\n\n private getFirstDayFallback(locale: string): number {\n const sundayFirst = ['en-US', 'en-CA', 'ja', 'ko', 'zh', 'he', 'ar'];\n const lang = locale.split('-')[0];\n if (sundayFirst.includes(locale) || sundayFirst.includes(lang)) {\n return 7; // Sunday\n }\n return 1; // Monday\n }\n\n getMonthYearLabel(date: Date): string {\n return new Intl.DateTimeFormat(this.resolvedLocale, {\n month: 'long',\n year: 'numeric',\n }).format(date);\n }\n\n getFullDateLabel(date: Date): string {\n return new Intl.DateTimeFormat(this.resolvedLocale, {\n dateStyle: 'full',\n }).format(date);\n }\n\n formatDateForInput(date: Date): string {\n return new Intl.DateTimeFormat(this.resolvedLocale, {\n dateStyle: 'short',\n }).format(date);\n }\n\n getDateFormatPlaceholder(): string {\n const ref = new Date(2033, 11, 25); // Dec 25, 2033\n const formatted = this.formatDateForInput(ref);\n return formatted\n .replace('25', 'DD')\n .replace('12', 'MM')\n .replace('2033', 'YYYY')\n .replace('33', 'YY');\n }\n\n parseDateFromInput(raw: string): Date | null {\n if (!raw.trim()) return null;\n\n // Try native Date parsing first\n const native = new Date(raw);\n if (!isNaN(native.getTime()) && native.getFullYear() > 1000) {\n return this.normalizeDate(native);\n }\n\n return this.parseLocaleDate(raw);\n }\n\n private parseLocaleDate(raw: string): Date | null {\n const parts = raw.split(/[\\/\\-\\.]/).map((p) => parseInt(p, 10));\n if (parts.length !== 3 || parts.some(isNaN)) return null;\n\n // Determine order by formatting a known reference date\n const ref = new Date(2033, 11, 25); // Dec 25, 2033\n const formatted = this.formatDateForInput(ref);\n const refParts = formatted.split(/[\\/\\-\\.]/).map((p) => parseInt(p, 10));\n\n const monthIdx = refParts.findIndex((p) => p === 12);\n const dayIdx = refParts.findIndex((p) => p === 25);\n const yearIdx = refParts.findIndex((p) => p === 2033 || p === 33);\n\n if (monthIdx === -1 || dayIdx === -1 || yearIdx === -1) return null;\n\n let year = parts[yearIdx];\n const month = parts[monthIdx];\n const day = parts[dayIdx];\n\n if (year < 100) year += 2000;\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\n\n const result = new Date(year, month - 1, day);\n // Validate no date rollover\n if (result.getMonth() !== month - 1 || result.getDate() !== day) return null;\n return result;\n }\n\n private normalizeDate(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n }\n}\n","import {\n ChangeDetectorRef,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { DatepickerLocaleService } from './../datepicker-locale.service';\nimport { CalendarDay, WeekdayHeader } from './../datepicker.models';\n\nlet nextId = 0;\n\n@Component({\n selector: 'yuv-calendar',\n standalone: true,\n templateUrl: './calendar.component.html',\n styleUrl: './calendar.component.scss'\n})\nexport class CalendarComponent {\n private readonly localeService = inject(DatepickerLocaleService);\n private readonly elementRef = inject(ElementRef);\n private readonly cdr = inject(ChangeDetectorRef);\n\n readonly selectedDate = input<Date | null>(null);\n readonly initialFocusDate = input<Date>(new Date());\n readonly min = input<Date | null>(null);\n\n readonly dateSelected = output<Date>();\n readonly closeRequested = output<void>();\n\n protected readonly gridLabelId = `app-calendar-label-${nextId++}`;\n protected readonly focusedDate = signal<Date>(new Date());\n\n protected readonly weekdayHeaders: WeekdayHeader[] = this.localeService.getWeekdayHeaders();\n\n protected readonly monthYearLabel = computed(() => this.localeService.getMonthYearLabel(this.focusedDate()));\n\n protected readonly weeks = computed(() => this.generateWeeks());\n\n constructor() {\n effect(() => {\n const initial = this.initialFocusDate();\n this.focusedDate.set(new Date(initial.getFullYear(), initial.getMonth(), initial.getDate()));\n });\n }\n\n focusActiveCell(): void {\n this.cdr.detectChanges();\n const cell = this.elementRef.nativeElement.querySelector('td[tabindex=\"0\"]') as HTMLElement | null;\n cell?.focus();\n }\n\n protected selectDate(day: CalendarDay): void {\n if (day.isDisabled) return;\n if (day.isOutsideMonth) {\n this.focusedDate.set(day.date);\n return;\n }\n this.dateSelected.emit(day.date);\n }\n\n protected navigateMonth(delta: number): void {\n const current = this.focusedDate();\n this.focusedDate.set(new Date(current.getFullYear(), current.getMonth() + delta, 1));\n this.focusActiveCell();\n }\n\n protected navigateYear(delta: number): void {\n const current = this.focusedDate();\n this.focusedDate.set(new Date(current.getFullYear() + delta, current.getMonth(), 1));\n this.focusActiveCell();\n }\n\n protected onGridKeydown(event: KeyboardEvent): void {\n const current = this.focusedDate();\n let handled = true;\n\n switch (event.key) {\n case 'ArrowRight':\n this.moveFocusClamped(this.addDays(current, 1));\n break;\n case 'ArrowLeft':\n this.moveFocusClamped(this.addDays(current, -1));\n break;\n case 'ArrowDown':\n this.moveFocusClamped(this.addDays(current, 7));\n break;\n case 'ArrowUp':\n this.moveFocusClamped(this.addDays(current, -7));\n break;\n case 'Home':\n this.moveFocusClamped(this.startOfWeek(current));\n break;\n case 'End':\n this.moveFocusClamped(this.endOfWeek(current));\n break;\n case 'PageDown':\n event.shiftKey ? this.moveFocusYear(1) : this.moveFocusMonth(1);\n break;\n case 'PageUp':\n event.shiftKey ? this.moveFocusYear(-1) : this.moveFocusMonth(-1);\n break;\n case 'Enter':\n case ' ':\n if (!this.isBeforeMin(this.focusedDate())) {\n this.dateSelected.emit(this.focusedDate());\n }\n break;\n default:\n handled = false;\n }\n\n if (handled) {\n event.preventDefault();\n this.focusActiveCell();\n }\n }\n\n private generateWeeks(): CalendarDay[][] {\n const focused = this.focusedDate();\n const year = focused.getFullYear();\n const month = focused.getMonth();\n const selected = this.selectedDate();\n const minDate = this.min();\n\n const firstDayOfWeek = this.localeService.getFirstDayOfWeek();\n const firstOfMonth = new Date(year, month, 1);\n const firstOfMonthDow = firstOfMonth.getDay();\n const firstOfMonthIso = firstOfMonthDow === 0 ? 7 : firstOfMonthDow;\n\n let offset = firstOfMonthIso - firstDayOfWeek;\n if (offset < 0) offset += 7;\n\n const gridStart = new Date(year, month, 1 - offset);\n\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const minNorm = minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()).getTime() : null;\n\n const weeks: CalendarDay[][] = [];\n for (let w = 0; w < 6; w++) {\n const week: CalendarDay[] = [];\n for (let d = 0; d < 7; d++) {\n const cellDate = new Date(gridStart);\n cellDate.setDate(gridStart.getDate() + w * 7 + d);\n\n const disabled = minNorm !== null && cellDate.getTime() < minNorm;\n\n week.push({\n date: cellDate,\n dayNumber: cellDate.getDate(),\n dateIso: this.toIsoString(cellDate),\n isToday: cellDate.getTime() === today.getTime(),\n isSelected: this.isSameDay(cellDate, selected),\n isOutsideMonth: cellDate.getMonth() !== month,\n isDisabled: disabled,\n isFocusTarget: this.isSameDay(cellDate, focused),\n fullLabel: this.localeService.getFullDateLabel(cellDate)\n });\n }\n weeks.push(week);\n }\n return weeks;\n }\n\n private isBeforeMin(date: Date): boolean {\n const minDate = this.min();\n if (!minDate) return false;\n const minNorm = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());\n return date.getTime() < minNorm.getTime();\n }\n\n private moveFocusClamped(target: Date): void {\n if (this.isBeforeMin(target)) return;\n this.focusedDate.set(target);\n }\n\n private addDays(date: Date, days: number): Date {\n const result = new Date(date);\n result.setDate(result.getDate() + days);\n return result;\n }\n\n private startOfWeek(date: Date): Date {\n const firstDay = this.localeService.getFirstDayOfWeek();\n const dow = date.getDay();\n const isoDay = dow === 0 ? 7 : dow;\n let diff = isoDay - firstDay;\n if (diff < 0) diff += 7;\n return this.addDays(date, -diff);\n }\n\n private endOfWeek(date: Date): Date {\n return this.addDays(this.startOfWeek(date), 6);\n }\n\n private moveFocusMonth(delta: number): void {\n const current = this.focusedDate();\n const targetMonth = current.getMonth() + delta;\n const maxDay = new Date(current.getFullYear(), targetMonth + 1, 0).getDate();\n const clampedDay = Math.min(current.getDate(), maxDay);\n const target = new Date(current.getFullYear(), targetMonth, clampedDay);\n this.moveFocusClamped(target);\n }\n\n private moveFocusYear(delta: number): void {\n const current = this.focusedDate();\n const targetYear = current.getFullYear() + delta;\n const maxDay = new Date(targetYear, current.getMonth() + 1, 0).getDate();\n const clampedDay = Math.min(current.getDate(), maxDay);\n const target = new Date(targetYear, current.getMonth(), clampedDay);\n this.moveFocusClamped(target);\n }\n\n private isSameDay(a: Date, b: Date | null): boolean {\n if (!b) return false;\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n }\n\n private toIsoString(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n }\n}\n","<div class=\"app-calendar-header\">\n <button\n type=\"button\"\n aria-label=\"Previous Year\"\n (click)=\"navigateYear(-1)\"\n class=\"app-calendar-nav-btn\"\n >&laquo;</button>\n <button\n type=\"button\"\n aria-label=\"Previous Month\"\n (click)=\"navigateMonth(-1)\"\n class=\"app-calendar-nav-btn\"\n >&lsaquo;</button>\n <h2\n [id]=\"gridLabelId\"\n aria-live=\"polite\"\n class=\"app-calendar-title\"\n >{{ monthYearLabel() }}</h2>\n <button\n type=\"button\"\n aria-label=\"Next Month\"\n (click)=\"navigateMonth(1)\"\n class=\"app-calendar-nav-btn\"\n >&rsaquo;</button>\n <button\n type=\"button\"\n aria-label=\"Next Year\"\n (click)=\"navigateYear(1)\"\n class=\"app-calendar-nav-btn\"\n >&raquo;</button>\n</div>\n\n<table\n role=\"grid\"\n [attr.aria-labelledby]=\"gridLabelId\"\n (keydown)=\"onGridKeydown($event)\"\n>\n <thead>\n <tr>\n @for (day of weekdayHeaders; track day.long) {\n <th scope=\"col\" [abbr]=\"day.long\">{{ day.narrow }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (week of weeks(); track $index) {\n <tr>\n @for (day of week; track day.dateIso) {\n <td\n role=\"gridcell\"\n [attr.tabindex]=\"day.isFocusTarget ? 0 : -1\"\n [attr.aria-selected]=\"day.isSelected || null\"\n [attr.aria-disabled]=\"day.isDisabled || day.isOutsideMonth || null\"\n [attr.aria-label]=\"day.fullLabel\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.outside-month]=\"day.isOutsideMonth\"\n [class.disabled]=\"day.isDisabled\"\n (click)=\"selectDate(day)\"\n >{{ day.dayNumber }}</td>\n }\n </tr>\n }\n </tbody>\n</table>\n","import { Component, computed, ElementRef, forwardRef, inject, input, signal, viewChild } from '@angular/core';\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator\n} from '@angular/forms';\nimport { MatIcon } from '@angular/material/icon';\nimport { YmtIconButtonDirective } from '@yuuvis/material';\nimport { CalendarComponent } from './calendar/calendar.component';\nimport { DatepickerLocaleService } from './datepicker-locale.service';\n\nlet nextId = 0;\n\n@Component({\n selector: 'yuv-datepicker',\n standalone: true,\n imports: [CalendarComponent, YmtIconButtonDirective, MatIcon],\n templateUrl: './datepicker.component.html',\n styleUrl: './datepicker.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DatepickerComponent),\n multi: true\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => DatepickerComponent),\n multi: true\n }\n ]\n})\nexport class DatepickerComponent implements ControlValueAccessor, Validator {\n private readonly localeService = inject(DatepickerLocaleService);\n\n readonly label = input.required<string>();\n readonly min = input<Date | null>(null);\n\n protected readonly selectedDate = signal<Date | null>(null);\n protected readonly inputValue = signal<string>('');\n protected readonly disabled = signal<boolean>(false);\n\n private readonly uid = nextId++;\n protected readonly inputId = `app-datepicker-input-${this.uid}`;\n protected readonly descriptionId = `app-datepicker-desc-${this.uid}`;\n\n protected readonly calendarDialog = viewChild.required<ElementRef<HTMLDialogElement>>('calendarDialog');\n protected readonly triggerButton = viewChild.required<ElementRef<HTMLButtonElement>>('triggerButton');\n protected readonly calendarRef = viewChild.required(CalendarComponent);\n\n protected readonly dateFormatPlaceholder = this.localeService.getDateFormatPlaceholder();\n\n protected readonly chooseButtonAriaLabel = computed(() => {\n const date = this.selectedDate();\n if (!date) return 'Choose Date';\n return `Change Date, ${this.localeService.getFullDateLabel(date)}`;\n });\n\n protected readonly initialFocusDate = computed(() => this.selectedDate() ?? new Date());\n\n private onChange: (value: Date | null) => void = () => {};\n protected onTouched: () => void = () => {};\n\n writeValue(value: Date | null): void {\n this.selectedDate.set(value);\n this.inputValue.set(value ? this.localeService.formatDateForInput(value) : '');\n }\n\n registerOnChange(fn: (value: Date | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n }\n\n validate(_control: AbstractControl): ValidationErrors | null {\n const raw = this.inputValue();\n if (raw && !this.selectedDate()) {\n return { datepickerParse: { value: raw } };\n }\n const date = this.selectedDate();\n const minDate = this.min();\n if (date && minDate) {\n const minNorm = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());\n if (date.getTime() < minNorm.getTime()) {\n return { datepickerMin: { min: minDate, actual: date } };\n }\n }\n return null;\n }\n\n protected onManualInput(event: Event): void {\n const raw = (event.target as HTMLInputElement).value;\n this.inputValue.set(raw);\n const parsed = this.localeService.parseDateFromInput(raw);\n this.selectedDate.set(parsed);\n this.onChange(parsed);\n }\n\n protected toggleDialog(): void {\n const dialog = this.calendarDialog().nativeElement;\n if (dialog.open) {\n dialog.close();\n } else {\n dialog.showModal();\n // Wait one tick for dialog to be visible, then focus the active cell\n setTimeout(() => this.calendarRef().focusActiveCell());\n }\n }\n\n protected onDateSelected(date: Date): void {\n this.selectedDate.set(date);\n this.inputValue.set(this.localeService.formatDateForInput(date));\n this.onChange(date);\n this.calendarDialog().nativeElement.close();\n }\n\n protected onDialogClose(): void {\n this.onTouched();\n this.triggerButton().nativeElement.focus();\n }\n\n protected onDialogBackdropClick(event: MouseEvent): void {\n if (event.target === this.calendarDialog().nativeElement) {\n this.calendarDialog().nativeElement.close();\n }\n }\n}\n","<div class=\"app-datepicker-field\">\n <label [for]=\"inputId\">{{ label() }}</label>\n <div class=\"app-datepicker-input-group\">\n <input\n [id]=\"inputId\"\n type=\"text\"\n [attr.aria-describedby]=\"descriptionId\"\n [placeholder]=\"dateFormatPlaceholder\"\n [value]=\"inputValue()\"\n [disabled]=\"disabled()\"\n (input)=\"onManualInput($event)\"\n (blur)=\"onTouched()\"\n autocomplete=\"off\"\n />\n <button\n #triggerButton\n ymtIconButton\n icon-button-size=\"small\"\n type=\"button\"\n [attr.aria-label]=\"chooseButtonAriaLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"toggleDialog()\"\n >\n <mat-icon>calendar_today</mat-icon>\n </button>\n </div>\n <span [id]=\"descriptionId\" class=\"sr-only\"> Date format: {{ dateFormatPlaceholder }} </span>\n</div>\n\n<dialog\n #calendarDialog\n aria-label=\"Choose Date\"\n aria-modal=\"true\"\n class=\"app-datepicker-dialog\"\n (close)=\"onDialogClose()\"\n (click)=\"onDialogBackdropClick($event)\"\n>\n <yuv-calendar\n [selectedDate]=\"selectedDate()\"\n [initialFocusDate]=\"initialFocusDate()\"\n [min]=\"min()\"\n (dateSelected)=\"onDateSelected($event)\"\n />\n</dialog>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["nextId"],"mappings":"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"}