@lifecorner/angular-ui-kit 3.28.0 → 3.29.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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { ChangeDetectionStrategy, Component, DOCUMENT, computed, forwardRef, inject, input, linkedSignal, output, signal, viewChild } from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DOCUMENT, Injector, afterNextRender, computed, forwardRef, inject, input, linkedSignal, output, signal, viewChild } from "@angular/core";
3
3
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
4
4
  import * as i1 from "@angular/cdk/overlay";
5
5
  import { OverlayModule } from "@angular/cdk/overlay";
@@ -31,6 +31,11 @@ var DatepickerComponent = class DatepickerComponent {
31
31
  nextMonthAriaLabel = input("Next month", ...ngDevMode ? [{ debugName: "nextMonthAriaLabel" }] : /* istanbul ignore next */ []);
32
32
  todayLabel = input("Today", ...ngDevMode ? [{ debugName: "todayLabel" }] : /* istanbul ignore next */ []);
33
33
  selectedAriaLabel = input("selected", ...ngDevMode ? [{ debugName: "selectedAriaLabel" }] : /* istanbul ignore next */ []);
34
+ granularity = input("day", ...ngDevMode ? [{ debugName: "granularity" }] : /* istanbul ignore next */ []);
35
+ previousYearAriaLabel = input("Previous year", ...ngDevMode ? [{ debugName: "previousYearAriaLabel" }] : /* istanbul ignore next */ []);
36
+ nextYearAriaLabel = input("Next year", ...ngDevMode ? [{ debugName: "nextYearAriaLabel" }] : /* istanbul ignore next */ []);
37
+ monthDialogAriaLabel = input("Choose month", ...ngDevMode ? [{ debugName: "monthDialogAriaLabel" }] : /* istanbul ignore next */ []);
38
+ currentMonthLabel = input("This month", ...ngDevMode ? [{ debugName: "currentMonthLabel" }] : /* istanbul ignore next */ []);
34
39
  dateChange = output();
35
40
  opened = output();
36
41
  closed = output();
@@ -40,10 +45,12 @@ var DatepickerComponent = class DatepickerComponent {
40
45
  currentYear = signal((/* @__PURE__ */ new Date()).getFullYear(), ...ngDevMode ? [{ debugName: "currentYear" }] : /* istanbul ignore next */ []);
41
46
  formDisabled = signal(false, ...ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []);
42
47
  isDisabled = computed(() => this.disabled() || this.formDisabled(), ...ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []);
48
+ isMonthMode = computed(() => this.granularity() === "month", ...ngDevMode ? [{ debugName: "isMonthMode" }] : /* istanbul ignore next */ []);
43
49
  formattedDate = computed(() => {
44
50
  const date = this.selectedDate();
45
51
  if (!date) return "";
46
- return this.formatDate(date, this.format());
52
+ const shown = this.isMonthMode() ? new Date(date.getFullYear(), date.getMonth(), 1) : date;
53
+ return this.formatDate(shown, this.format());
47
54
  }, ...ngDevMode ? [{ debugName: "formattedDate" }] : /* istanbul ignore next */ []);
48
55
  inputValue = linkedSignal(() => this.formattedDate(), ...ngDevMode ? [{ debugName: "inputValue" }] : /* istanbul ignore next */ []);
49
56
  weekDays = [
@@ -79,6 +86,34 @@ var DatepickerComponent = class DatepickerComponent {
79
86
  const names = locale ? Array.from({ length: 7 }, (_, d) => new Date(2023, 0, 1 + d).toLocaleDateString(locale, { weekday: "short" }).replace(/\.$/, "")) : this.weekDays;
80
87
  return Array.from({ length: 7 }, (_, i) => names[(first + i) % 7]);
81
88
  }, ...ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []);
89
+ headerTitle = computed(() => this.isMonthMode() ? String(this.currentYear()) : `${this.currentMonthName()} ${this.currentYear()}`, ...ngDevMode ? [{ debugName: "headerTitle" }] : /* istanbul ignore next */ []);
90
+ monthCells = computed(() => {
91
+ const year = this.currentYear();
92
+ const locale = this.locale();
93
+ const selected = this.selectedDate();
94
+ const today = /* @__PURE__ */ new Date();
95
+ return Array.from({ length: 12 }, (_, month) => {
96
+ const first = new Date(year, month, 1);
97
+ return {
98
+ month,
99
+ name: locale ? first.toLocaleDateString(locale, { month: "long" }) : this.monthNames[month],
100
+ label: first.toLocaleDateString(locale || "en-US", {
101
+ month: "long",
102
+ year: "numeric"
103
+ }),
104
+ selected: !!selected && selected.getFullYear() === year && selected.getMonth() === month,
105
+ current: today.getFullYear() === year && today.getMonth() === month,
106
+ disabled: this.isMonthDisabled(year, month)
107
+ };
108
+ });
109
+ }, ...ngDevMode ? [{ debugName: "monthCells" }] : /* istanbul ignore next */ []);
110
+ monthRows = computed(() => [
111
+ 0,
112
+ 3,
113
+ 6,
114
+ 9
115
+ ].map((i) => this.monthCells().slice(i, i + 3)), ...ngDevMode ? [{ debugName: "monthRows" }] : /* istanbul ignore next */ []);
116
+ monthTabStop = linkedSignal(() => this.defaultMonthTabStop(), ...ngDevMode ? [{ debugName: "monthTabStop" }] : /* istanbul ignore next */ []);
82
117
  gridStart = computed(() => {
83
118
  const day = Math.trunc(Number(this.firstDayOfWeek()));
84
119
  return Number.isFinite(day) ? (day % 7 + 7) % 7 : 0;
@@ -100,6 +135,7 @@ var DatepickerComponent = class DatepickerComponent {
100
135
  return classes.join(" ");
101
136
  }, ...ngDevMode ? [{ debugName: "datepickerClasses" }] : /* istanbul ignore next */ []);
102
137
  document = inject(DOCUMENT);
138
+ injector = inject(Injector);
103
139
  onChange = () => {};
104
140
  onTouched = () => {};
105
141
  toggle() {
@@ -112,6 +148,7 @@ var DatepickerComponent = class DatepickerComponent {
112
148
  this.isOpen.set(true);
113
149
  const date = this.selectedDate();
114
150
  if (date) this.showMonthOf(date);
151
+ if (this.isMonthMode()) this.monthTabStop.set(this.defaultMonthTabStop());
115
152
  this.opened.emit();
116
153
  }
117
154
  close() {
@@ -193,6 +230,65 @@ var DatepickerComponent = class DatepickerComponent {
193
230
  goToToday() {
194
231
  this.showMonthOf(/* @__PURE__ */ new Date());
195
232
  }
233
+ previousYear() {
234
+ this.currentYear.update((year) => year - 1);
235
+ }
236
+ nextYear() {
237
+ this.currentYear.update((year) => year + 1);
238
+ }
239
+ showCurrentYear() {
240
+ this.currentYear.set((/* @__PURE__ */ new Date()).getFullYear());
241
+ }
242
+ selectMonth(month) {
243
+ const year = this.currentYear();
244
+ if (this.isDisabled() || this.readonly() || this.isMonthDisabled(year, month)) return;
245
+ this.commitDate(new Date(year, month, 1));
246
+ this.close();
247
+ }
248
+ onMonthKeydown(event, month) {
249
+ const year = this.currentYear();
250
+ const at = year * 12 + month;
251
+ let target;
252
+ switch (event.key) {
253
+ case "ArrowLeft":
254
+ target = this.nextEnabledMonth(at, -1);
255
+ break;
256
+ case "ArrowRight":
257
+ target = this.nextEnabledMonth(at, 1);
258
+ break;
259
+ case "ArrowUp":
260
+ target = this.nextEnabledMonth(at, -3);
261
+ break;
262
+ case "ArrowDown":
263
+ target = this.nextEnabledMonth(at, 3);
264
+ break;
265
+ case "PageUp":
266
+ target = this.nearestEnabledMonth(year - 1, month);
267
+ break;
268
+ case "PageDown":
269
+ target = this.nearestEnabledMonth(year + 1, month);
270
+ break;
271
+ case "Home":
272
+ target = this.edgeEnabledMonth(year, 1);
273
+ break;
274
+ case "End":
275
+ target = this.edgeEnabledMonth(year, -1);
276
+ break;
277
+ case "Enter":
278
+ case " ":
279
+ event.preventDefault();
280
+ this.selectMonth(month);
281
+ return;
282
+ case "Escape":
283
+ event.preventDefault();
284
+ event.stopPropagation();
285
+ this.close();
286
+ return;
287
+ default: return;
288
+ }
289
+ event.preventDefault();
290
+ if (target !== null) this.moveMonthFocus(target);
291
+ }
196
292
  onInputChange(value) {
197
293
  this.inputValue.set(value);
198
294
  if (value.trim() === "") {
@@ -200,7 +296,7 @@ var DatepickerComponent = class DatepickerComponent {
200
296
  return;
201
297
  }
202
298
  const date = this.parseDate(value, this.format());
203
- if (date && !this.isDateDisabled(date) && !this.isSelectedDate(date)) {
299
+ if (date && !this.isUnavailable(date) && !this.isSameSelection(date)) {
204
300
  this.commitDate(date);
205
301
  this.showMonthOf(date);
206
302
  }
@@ -210,9 +306,14 @@ var DatepickerComponent = class DatepickerComponent {
210
306
  if (!this.isOpen() && (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ")) {
211
307
  this.open();
212
308
  event.preventDefault();
309
+ if (this.isMonthMode()) afterNextRender(() => this.focusMonthCell(this.monthTabStop()), { injector: this.injector });
213
310
  return;
214
311
  }
215
312
  if (!this.isOpen()) return;
313
+ if (this.isMonthMode()) {
314
+ this.onMonthFieldKeyDown(event);
315
+ return;
316
+ }
216
317
  const editing = this.inputValue() !== this.formattedDate();
217
318
  const currentDate = this.selectedDate() || /* @__PURE__ */ new Date();
218
319
  let newDate = null;
@@ -284,6 +385,75 @@ var DatepickerComponent = class DatepickerComponent {
284
385
  isCurrentMonth(date) {
285
386
  return date.getMonth() === this.currentMonth() && date.getFullYear() === this.currentYear();
286
387
  }
388
+ defaultMonthTabStop() {
389
+ const cells = this.monthCells().filter((c) => !c.disabled);
390
+ return (cells.find((c) => c.selected) ?? cells.find((c) => c.current) ?? cells[0])?.month ?? -1;
391
+ }
392
+ onMonthFieldKeyDown(event) {
393
+ switch (event.key) {
394
+ case "ArrowDown":
395
+ event.preventDefault();
396
+ this.focusMonthCell(this.monthTabStop());
397
+ break;
398
+ case "Escape":
399
+ this.close();
400
+ event.preventDefault();
401
+ event.stopPropagation();
402
+ break;
403
+ case "Enter":
404
+ event.preventDefault();
405
+ if (this.selectedDate()) this.close();
406
+ }
407
+ }
408
+ isMonthDisabled(year, month) {
409
+ const min = this.minDate();
410
+ if (min && new Date(year, month + 1, 0).getTime() < this.startOfDay(min)) return true;
411
+ const max = this.maxDate();
412
+ if (max && new Date(year, month, 1).getTime() > this.startOfDay(max)) return true;
413
+ return this.disabledDates().some((d) => d.getFullYear() === year && d.getMonth() === month);
414
+ }
415
+ isUnavailable(date) {
416
+ return this.isMonthMode() ? this.isMonthDisabled(date.getFullYear(), date.getMonth()) : this.isDateDisabled(date);
417
+ }
418
+ isSameSelection(date) {
419
+ if (!this.isMonthMode()) return this.isSelectedDate(date);
420
+ const selected = this.selectedDate();
421
+ return !!selected && selected.getFullYear() === date.getFullYear() && selected.getMonth() === date.getMonth();
422
+ }
423
+ monthAt(index) {
424
+ return {
425
+ year: Math.floor(index / 12),
426
+ month: (index % 12 + 12) % 12
427
+ };
428
+ }
429
+ nextEnabledMonth(index, step) {
430
+ for (let i = 1; i * Math.abs(step) <= 120; i++) {
431
+ const { year, month } = this.monthAt(index + step * i);
432
+ if (!this.isMonthDisabled(year, month)) return index + step * i;
433
+ }
434
+ return null;
435
+ }
436
+ nearestEnabledMonth(year, month) {
437
+ for (let d = 0; d < 12; d++) for (const m of d === 0 ? [month] : [month - d, month + d]) if (m >= 0 && m < 12 && !this.isMonthDisabled(year, m)) return year * 12 + m;
438
+ return null;
439
+ }
440
+ edgeEnabledMonth(year, dir) {
441
+ for (let i = 0; i < 12; i++) {
442
+ const month = dir === 1 ? i : 11 - i;
443
+ if (!this.isMonthDisabled(year, month)) return year * 12 + month;
444
+ }
445
+ return null;
446
+ }
447
+ moveMonthFocus(index) {
448
+ const { year, month } = this.monthAt(index);
449
+ if (year !== this.currentYear()) this.currentYear.set(year);
450
+ this.monthTabStop.set(month);
451
+ this.focusMonthCell(month);
452
+ }
453
+ focusMonthCell(month) {
454
+ if (month < 0) return;
455
+ this.calendarPanel()?.nativeElement.querySelectorAll(".lc-datepicker-month")[month]?.focus();
456
+ }
287
457
  commitDate(date) {
288
458
  this.selectedDate.set(date);
289
459
  this.inputValue.set(this.formatDate(date, this.format()));
@@ -313,16 +483,18 @@ var DatepickerComponent = class DatepickerComponent {
313
483
  }
314
484
  parseDate(value, format) {
315
485
  if (value.length !== format.length) return null;
486
+ const monthMode = this.isMonthMode();
316
487
  const yearIndex = format.indexOf("YYYY");
317
488
  const monthIndex = format.indexOf("MM");
318
489
  const dayIndex = format.indexOf("DD");
319
- if (yearIndex < 0 || monthIndex < 0 || dayIndex < 0) return null;
490
+ if (yearIndex < 0 || monthIndex < 0 || dayIndex < 0 && !monthMode) return null;
320
491
  const yearText = value.substring(yearIndex, yearIndex + 4);
321
492
  const monthText = value.substring(monthIndex, monthIndex + 2);
322
- const dayText = value.substring(dayIndex, dayIndex + 2);
493
+ const dayText = dayIndex < 0 ? "01" : value.substring(dayIndex, dayIndex + 2);
323
494
  if (!/^\d{4}$/.test(yearText) || !/^\d{2}$/.test(monthText) || !/^\d{2}$/.test(dayText)) return null;
324
495
  const date = new Date(Number(yearText), Number(monthText) - 1, Number(dayText));
325
- return this.formatDate(date, format) === value ? date : null;
496
+ if (this.formatDate(date, format) !== value) return null;
497
+ return monthMode ? new Date(date.getFullYear(), date.getMonth(), 1) : date;
326
498
  }
327
499
  getInputValue(event) {
328
500
  return event.target.value;
@@ -502,6 +674,41 @@ var DatepickerComponent = class DatepickerComponent {
502
674
  isSignal: true,
503
675
  isRequired: false,
504
676
  transformFunction: null
677
+ },
678
+ granularity: {
679
+ classPropertyName: "granularity",
680
+ publicName: "granularity",
681
+ isSignal: true,
682
+ isRequired: false,
683
+ transformFunction: null
684
+ },
685
+ previousYearAriaLabel: {
686
+ classPropertyName: "previousYearAriaLabel",
687
+ publicName: "previousYearAriaLabel",
688
+ isSignal: true,
689
+ isRequired: false,
690
+ transformFunction: null
691
+ },
692
+ nextYearAriaLabel: {
693
+ classPropertyName: "nextYearAriaLabel",
694
+ publicName: "nextYearAriaLabel",
695
+ isSignal: true,
696
+ isRequired: false,
697
+ transformFunction: null
698
+ },
699
+ monthDialogAriaLabel: {
700
+ classPropertyName: "monthDialogAriaLabel",
701
+ publicName: "monthDialogAriaLabel",
702
+ isSignal: true,
703
+ isRequired: false,
704
+ transformFunction: null
705
+ },
706
+ currentMonthLabel: {
707
+ classPropertyName: "currentMonthLabel",
708
+ publicName: "currentMonthLabel",
709
+ isSignal: true,
710
+ isRequired: false,
711
+ transformFunction: null
505
712
  }
506
713
  },
507
714
  outputs: {
@@ -528,8 +735,8 @@ var DatepickerComponent = class DatepickerComponent {
528
735
  isSignal: true
529
736
  }],
530
737
  ngImport: i0,
531
- template: "<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"dialogAriaLabel()\"\n >\n <!-- Calendar Header -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"previousMonth()\"\n [attr.aria-label]=\"previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\">\n {{ currentMonthName() }} {{ currentYear() }}\n </div>\n \n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"nextMonth()\"\n [attr.aria-label]=\"nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"goToToday()\"\n >\n {{ todayLabel() }}\n </button>\n </div>\n\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n",
532
- styles: [".lc-datepicker-wrapper{display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%;position:relative}.lc-datepicker-input-wrapper{position:relative;width:100%}.lc-datepicker{width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background-color:var(--color-surface);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease);cursor:text}.lc-datepicker::placeholder{color:var(--color-text-secondary)}.lc-datepicker:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){border-color:var(--color-text-secondary)}.lc-datepicker:focus{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.lc-datepicker:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.lc-datepicker[readonly]{background-color:var(--color-surface-muted);cursor:default}.lc-datepicker.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--error:focus{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--xs{height:var(--size-interactive-xs-height);padding:var(--size-interactive-xs-padding);padding-right:var(--spacing-10);font-size:var(--size-interactive-xs-font-size)}.lc-datepicker.lc-datepicker--sm{height:var(--size-interactive-sm-height);padding:var(--size-interactive-sm-padding);padding-right:var(--spacing-12);font-size:var(--size-interactive-sm-font-size)}.lc-datepicker.lc-datepicker--md{height:var(--size-interactive-md-height);padding:var(--size-interactive-md-padding);padding-right:var(--spacing-14);font-size:var(--size-interactive-md-font-size)}.lc-datepicker.lc-datepicker--lg{height:var(--size-interactive-lg-height);padding:var(--size-interactive-lg-padding);padding-right:var(--spacing-16);font-size:var(--size-interactive-lg-font-size)}.lc-datepicker.lc-datepicker--filled{background-color:var(--color-surface-sunken);border-color:var(--color-field-border)}.lc-datepicker.lc-datepicker--filled:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-datepicker.lc-datepicker--filled:focus{background-color:var(--color-surface);border-color:var(--color-primary-500)}.lc-datepicker.lc-datepicker--filled:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border)}.lc-datepicker.lc-datepicker--filled.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker-icons{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--spacing-1);pointer-events:none}.lc-datepicker-calendar-icon{width:1.25rem;height:1.25rem;color:var(--color-text-secondary)}.lc-datepicker-clear{pointer-events:auto;display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:none;border:none;border-radius:var(--border-radius-sm);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-clear:hover{color:var(--color-text-primary);background-color:var(--color-surface-hover)}.lc-datepicker-clear:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-clear svg{width:1rem;height:1rem}.lc-datepicker-calendar{position:absolute;z-index:1000;margin-top:var(--spacing-1);padding:var(--lc-density-padding-md, var(--spacing-4));background-color:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);box-shadow:var(--elevation-3);min-width:280px;opacity:0;transform:translateY(-8px);transition:all var(--animation-duration-base) var(--animation-timing-ease);pointer-events:none}.lc-datepicker-calendar.lc-datepicker-calendar--open{opacity:1;transform:translateY(0);pointer-events:auto}.lc-datepicker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--spacing-4)}.lc-datepicker-month-year{font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);color:var(--color-text-primary)}.lc-datepicker-nav-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--border-radius-md);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-nav-button:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-datepicker-nav-button:active{background-color:var(--color-surface-sunken)}.lc-datepicker-nav-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-nav-button svg{width:1.25rem;height:1.25rem}.lc-datepicker-quick-actions{display:flex;justify-content:center;margin-bottom:var(--spacing-3)}.lc-datepicker-today-button{padding:var(--spacing-1) var(--spacing-3);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-primary-600);background:none;border:1px solid var(--color-primary-200);border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-today-button:hover{background-color:var(--color-primary-50);border-color:var(--color-primary-300)}.lc-datepicker-today-button:active{background-color:var(--color-primary-100)}.lc-datepicker-today-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1);margin-bottom:var(--spacing-2)}.lc-datepicker-weekday{font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);color:var(--color-text-secondary);text-align:center;padding:var(--spacing-1)}.lc-datepicker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1)}.lc-datepicker-day{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);color:var(--color-text-primary);background:none;border:none;border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-day:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-datepicker-day.lc-datepicker-day--other-month{color:var(--color-text-tertiary)}.lc-datepicker-day.lc-datepicker-day--today{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-day.lc-datepicker-day--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill)}.lc-datepicker-day.lc-datepicker-day--selected:hover{background-color:var(--color-primary-fill-hover)}.lc-datepicker-day.lc-datepicker-day--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-day.lc-datepicker-day--disabled:hover{background:none}.lc-datepicker-day:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-datepicker__error{font-size:var(--font-size-xs);color:var(--color-error-600);margin-top:var(--spacing-1)}.lc-datepicker__helper{font-size:var(--font-size-xs);color:var(--color-text-secondary);margin-top:var(--spacing-1)}\n"],
738
+ template: "<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [class.lc-datepicker-calendar--month]=\"isMonthMode()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"isMonthMode() ? monthDialogAriaLabel() : dialogAriaLabel()\"\n >\n <!-- Calendar Header (month mode, 3.29: the year and year buttons) -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? previousYear() : previousMonth()\"\n [attr.aria-label]=\"isMonthMode() ? previousYearAriaLabel() : previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\" [attr.id]=\"isMonthMode() ? inputId + '-year' : null\">\n {{ headerTitle() }}\n </div>\n\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? nextYear() : nextMonth()\"\n [attr.aria-label]=\"isMonthMode() ? nextYearAriaLabel() : nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"isMonthMode() ? showCurrentYear() : goToToday()\"\n >\n {{ isMonthMode() ? currentMonthLabel() : todayLabel() }}\n </button>\n </div>\n\n @if (isMonthMode()) {\n <!-- Month grid (3.29): APG grid, one roving tab stop, named by the year title -->\n <div class=\"lc-datepicker-months\" role=\"grid\" [attr.aria-labelledby]=\"inputId + '-year'\">\n @for (row of monthRows(); track $index) {\n <div class=\"lc-datepicker-month-row\" role=\"row\">\n @for (cell of row; track cell.month) {\n <div\n role=\"gridcell\"\n class=\"lc-datepicker-month\"\n [class.lc-datepicker-month--current]=\"cell.current\"\n [class.lc-datepicker-month--selected]=\"cell.selected\"\n [class.lc-datepicker-month--disabled]=\"cell.disabled\"\n [attr.tabindex]=\"cell.month === monthTabStop() ? 0 : -1\"\n [attr.aria-selected]=\"cell.selected ? 'true' : null\"\n [attr.aria-current]=\"cell.current ? 'date' : null\"\n [attr.aria-disabled]=\"cell.disabled ? 'true' : null\"\n [attr.aria-label]=\"cell.label\"\n (click)=\"selectMonth(cell.month)\"\n (keydown)=\"onMonthKeydown($event, cell.month)\"\n >{{ cell.name }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n",
739
+ styles: [".lc-datepicker-wrapper{display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%;position:relative}.lc-datepicker-input-wrapper{position:relative;width:100%}.lc-datepicker{width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background-color:var(--color-surface);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease);cursor:text}.lc-datepicker::placeholder{color:var(--color-text-secondary)}.lc-datepicker:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){border-color:var(--color-text-secondary)}.lc-datepicker:focus{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.lc-datepicker:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.lc-datepicker[readonly]{background-color:var(--color-surface-muted);cursor:default}.lc-datepicker.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--error:focus{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--xs{height:var(--size-interactive-xs-height);padding:var(--size-interactive-xs-padding);padding-right:var(--spacing-10);font-size:var(--size-interactive-xs-font-size)}.lc-datepicker.lc-datepicker--sm{height:var(--size-interactive-sm-height);padding:var(--size-interactive-sm-padding);padding-right:var(--spacing-12);font-size:var(--size-interactive-sm-font-size)}.lc-datepicker.lc-datepicker--md{height:var(--size-interactive-md-height);padding:var(--size-interactive-md-padding);padding-right:var(--spacing-14);font-size:var(--size-interactive-md-font-size)}.lc-datepicker.lc-datepicker--lg{height:var(--size-interactive-lg-height);padding:var(--size-interactive-lg-padding);padding-right:var(--spacing-16);font-size:var(--size-interactive-lg-font-size)}.lc-datepicker.lc-datepicker--filled{background-color:var(--color-surface-sunken);border-color:var(--color-field-border)}.lc-datepicker.lc-datepicker--filled:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-datepicker.lc-datepicker--filled:focus{background-color:var(--color-surface);border-color:var(--color-primary-500)}.lc-datepicker.lc-datepicker--filled:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border)}.lc-datepicker.lc-datepicker--filled.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker-icons{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--spacing-1);pointer-events:none}.lc-datepicker-calendar-icon{width:1.25rem;height:1.25rem;color:var(--color-text-secondary)}.lc-datepicker-clear{pointer-events:auto;display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:none;border:none;border-radius:var(--border-radius-sm);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-clear:hover{color:var(--color-text-primary);background-color:var(--color-surface-hover)}.lc-datepicker-clear:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-clear svg{width:1rem;height:1rem}.lc-datepicker-calendar{position:absolute;z-index:1000;margin-top:var(--spacing-1);padding:var(--lc-density-padding-md, var(--spacing-4));background-color:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);box-shadow:var(--elevation-3);min-width:280px;opacity:0;transform:translateY(-8px);transition:all var(--animation-duration-base) var(--animation-timing-ease);pointer-events:none}.lc-datepicker-calendar.lc-datepicker-calendar--open{opacity:1;transform:translateY(0);pointer-events:auto}.lc-datepicker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--spacing-4)}.lc-datepicker-month-year{font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);color:var(--color-text-primary)}.lc-datepicker-nav-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--border-radius-md);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-nav-button:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-datepicker-nav-button:active{background-color:var(--color-surface-sunken)}.lc-datepicker-nav-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-nav-button svg{width:1.25rem;height:1.25rem}.lc-datepicker-quick-actions{display:flex;justify-content:center;margin-bottom:var(--spacing-3)}.lc-datepicker-today-button{padding:var(--spacing-1) var(--spacing-3);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-primary-600);background:none;border:1px solid var(--color-primary-200);border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-today-button:hover{background-color:var(--color-primary-50);border-color:var(--color-primary-300)}.lc-datepicker-today-button:active{background-color:var(--color-primary-100)}.lc-datepicker-today-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1);margin-bottom:var(--spacing-2)}.lc-datepicker-weekday{font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);color:var(--color-text-secondary);text-align:center;padding:var(--spacing-1)}.lc-datepicker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1)}.lc-datepicker-day{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);color:var(--color-text-primary);background:none;border:none;border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-day:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-datepicker-day.lc-datepicker-day--other-month{color:var(--color-text-tertiary)}.lc-datepicker-day.lc-datepicker-day--today{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-day.lc-datepicker-day--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill)}.lc-datepicker-day.lc-datepicker-day--selected:hover{background-color:var(--color-primary-fill-hover)}.lc-datepicker-day.lc-datepicker-day--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-day.lc-datepicker-day--disabled:hover{background:none}.lc-datepicker-day:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-datepicker-calendar--month .lc-datepicker-nav-button{width:2.75rem;height:2.75rem}.lc-datepicker-calendar--month .lc-datepicker-today-button{min-height:2.75rem}.lc-datepicker-months{display:flex;flex-direction:column;gap:var(--spacing-2);inline-size:17.25rem;max-inline-size:calc(100vw - 4.125rem)}.lc-datepicker-month-row{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-2)}.lc-datepicker-month{display:flex;align-items:center;justify-content:center;min-height:2.75rem;padding:0 var(--spacing-1);font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);text-align:center;overflow-wrap:anywhere;hyphens:auto;color:var(--color-text-primary);border-radius:var(--border-radius-md);cursor:pointer}.lc-datepicker-month:hover:not(.lc-datepicker-month--disabled):not(.lc-datepicker-month--selected){background-color:var(--color-surface-hover)}.lc-datepicker-month.lc-datepicker-month--current{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-month.lc-datepicker-month--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill);box-shadow:inset 0 0 0 2px var(--color-primary-500)}.lc-datepicker-month.lc-datepicker-month--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-month:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}@media(forced-colors:active){.lc-datepicker-month:focus-visible{outline-color:Highlight}.lc-datepicker-month.lc-datepicker-month--selected{forced-color-adjust:none;background-color:Highlight;color:HighlightText}.lc-datepicker-month.lc-datepicker-month--current{text-decoration:underline}.lc-datepicker-month.lc-datepicker-month--disabled{color:GrayText}}.lc-datepicker__error{font-size:var(--font-size-xs);color:var(--color-error-600);margin-top:var(--spacing-1)}.lc-datepicker__helper{font-size:var(--font-size-xs);color:var(--color-text-secondary);margin-top:var(--spacing-1)}\n"],
533
740
  dependencies: [{
534
741
  kind: "ngmodule",
535
742
  type: OverlayModule
@@ -594,8 +801,8 @@ i0.ɵɵngDeclareClassMetadata({
594
801
  useExisting: forwardRef(() => DatepickerComponent),
595
802
  multi: true
596
803
  }],
597
- template: "<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"dialogAriaLabel()\"\n >\n <!-- Calendar Header -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"previousMonth()\"\n [attr.aria-label]=\"previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\">\n {{ currentMonthName() }} {{ currentYear() }}\n </div>\n \n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"nextMonth()\"\n [attr.aria-label]=\"nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"goToToday()\"\n >\n {{ todayLabel() }}\n </button>\n </div>\n\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n",
598
- styles: [".lc-datepicker-wrapper{display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%;position:relative}.lc-datepicker-input-wrapper{position:relative;width:100%}.lc-datepicker{width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background-color:var(--color-surface);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease);cursor:text}.lc-datepicker::placeholder{color:var(--color-text-secondary)}.lc-datepicker:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){border-color:var(--color-text-secondary)}.lc-datepicker:focus{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.lc-datepicker:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.lc-datepicker[readonly]{background-color:var(--color-surface-muted);cursor:default}.lc-datepicker.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--error:focus{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--xs{height:var(--size-interactive-xs-height);padding:var(--size-interactive-xs-padding);padding-right:var(--spacing-10);font-size:var(--size-interactive-xs-font-size)}.lc-datepicker.lc-datepicker--sm{height:var(--size-interactive-sm-height);padding:var(--size-interactive-sm-padding);padding-right:var(--spacing-12);font-size:var(--size-interactive-sm-font-size)}.lc-datepicker.lc-datepicker--md{height:var(--size-interactive-md-height);padding:var(--size-interactive-md-padding);padding-right:var(--spacing-14);font-size:var(--size-interactive-md-font-size)}.lc-datepicker.lc-datepicker--lg{height:var(--size-interactive-lg-height);padding:var(--size-interactive-lg-padding);padding-right:var(--spacing-16);font-size:var(--size-interactive-lg-font-size)}.lc-datepicker.lc-datepicker--filled{background-color:var(--color-surface-sunken);border-color:var(--color-field-border)}.lc-datepicker.lc-datepicker--filled:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-datepicker.lc-datepicker--filled:focus{background-color:var(--color-surface);border-color:var(--color-primary-500)}.lc-datepicker.lc-datepicker--filled:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border)}.lc-datepicker.lc-datepicker--filled.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker-icons{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--spacing-1);pointer-events:none}.lc-datepicker-calendar-icon{width:1.25rem;height:1.25rem;color:var(--color-text-secondary)}.lc-datepicker-clear{pointer-events:auto;display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:none;border:none;border-radius:var(--border-radius-sm);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-clear:hover{color:var(--color-text-primary);background-color:var(--color-surface-hover)}.lc-datepicker-clear:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-clear svg{width:1rem;height:1rem}.lc-datepicker-calendar{position:absolute;z-index:1000;margin-top:var(--spacing-1);padding:var(--lc-density-padding-md, var(--spacing-4));background-color:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);box-shadow:var(--elevation-3);min-width:280px;opacity:0;transform:translateY(-8px);transition:all var(--animation-duration-base) var(--animation-timing-ease);pointer-events:none}.lc-datepicker-calendar.lc-datepicker-calendar--open{opacity:1;transform:translateY(0);pointer-events:auto}.lc-datepicker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--spacing-4)}.lc-datepicker-month-year{font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);color:var(--color-text-primary)}.lc-datepicker-nav-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--border-radius-md);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-nav-button:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-datepicker-nav-button:active{background-color:var(--color-surface-sunken)}.lc-datepicker-nav-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-nav-button svg{width:1.25rem;height:1.25rem}.lc-datepicker-quick-actions{display:flex;justify-content:center;margin-bottom:var(--spacing-3)}.lc-datepicker-today-button{padding:var(--spacing-1) var(--spacing-3);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-primary-600);background:none;border:1px solid var(--color-primary-200);border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-today-button:hover{background-color:var(--color-primary-50);border-color:var(--color-primary-300)}.lc-datepicker-today-button:active{background-color:var(--color-primary-100)}.lc-datepicker-today-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1);margin-bottom:var(--spacing-2)}.lc-datepicker-weekday{font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);color:var(--color-text-secondary);text-align:center;padding:var(--spacing-1)}.lc-datepicker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1)}.lc-datepicker-day{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);color:var(--color-text-primary);background:none;border:none;border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-day:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-datepicker-day.lc-datepicker-day--other-month{color:var(--color-text-tertiary)}.lc-datepicker-day.lc-datepicker-day--today{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-day.lc-datepicker-day--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill)}.lc-datepicker-day.lc-datepicker-day--selected:hover{background-color:var(--color-primary-fill-hover)}.lc-datepicker-day.lc-datepicker-day--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-day.lc-datepicker-day--disabled:hover{background:none}.lc-datepicker-day:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-datepicker__error{font-size:var(--font-size-xs);color:var(--color-error-600);margin-top:var(--spacing-1)}.lc-datepicker__helper{font-size:var(--font-size-xs);color:var(--color-text-secondary);margin-top:var(--spacing-1)}\n"]
804
+ template: "<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [class.lc-datepicker-calendar--month]=\"isMonthMode()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"isMonthMode() ? monthDialogAriaLabel() : dialogAriaLabel()\"\n >\n <!-- Calendar Header (month mode, 3.29: the year and year buttons) -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? previousYear() : previousMonth()\"\n [attr.aria-label]=\"isMonthMode() ? previousYearAriaLabel() : previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\" [attr.id]=\"isMonthMode() ? inputId + '-year' : null\">\n {{ headerTitle() }}\n </div>\n\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? nextYear() : nextMonth()\"\n [attr.aria-label]=\"isMonthMode() ? nextYearAriaLabel() : nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"isMonthMode() ? showCurrentYear() : goToToday()\"\n >\n {{ isMonthMode() ? currentMonthLabel() : todayLabel() }}\n </button>\n </div>\n\n @if (isMonthMode()) {\n <!-- Month grid (3.29): APG grid, one roving tab stop, named by the year title -->\n <div class=\"lc-datepicker-months\" role=\"grid\" [attr.aria-labelledby]=\"inputId + '-year'\">\n @for (row of monthRows(); track $index) {\n <div class=\"lc-datepicker-month-row\" role=\"row\">\n @for (cell of row; track cell.month) {\n <div\n role=\"gridcell\"\n class=\"lc-datepicker-month\"\n [class.lc-datepicker-month--current]=\"cell.current\"\n [class.lc-datepicker-month--selected]=\"cell.selected\"\n [class.lc-datepicker-month--disabled]=\"cell.disabled\"\n [attr.tabindex]=\"cell.month === monthTabStop() ? 0 : -1\"\n [attr.aria-selected]=\"cell.selected ? 'true' : null\"\n [attr.aria-current]=\"cell.current ? 'date' : null\"\n [attr.aria-disabled]=\"cell.disabled ? 'true' : null\"\n [attr.aria-label]=\"cell.label\"\n (click)=\"selectMonth(cell.month)\"\n (keydown)=\"onMonthKeydown($event, cell.month)\"\n >{{ cell.name }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n",
805
+ styles: [".lc-datepicker-wrapper{display:flex;flex-direction:column;gap:var(--lc-density-gap-xs, var(--spacing-1));width:100%;position:relative}.lc-datepicker-input-wrapper{position:relative;width:100%}.lc-datepicker{width:100%;font-family:var(--font-family-sans);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);color:var(--color-text-primary);background-color:var(--color-surface);border:1px solid var(--color-field-border);border-radius:var(--border-radius-md);transition:all var(--animation-duration-base) var(--animation-timing-ease);cursor:text}.lc-datepicker::placeholder{color:var(--color-text-secondary)}.lc-datepicker:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){border-color:var(--color-text-secondary)}.lc-datepicker:focus{outline:2px solid var(--color-primary-500);outline-offset:0px;border-color:var(--color-primary-500)}.lc-datepicker:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border);cursor:not-allowed;opacity:.6}.lc-datepicker[readonly]{background-color:var(--color-surface-muted);cursor:default}.lc-datepicker.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--error:focus{outline-color:var(--color-error-600);border-color:var(--color-error-600)}.lc-datepicker.lc-datepicker--xs{height:var(--size-interactive-xs-height);padding:var(--size-interactive-xs-padding);padding-right:var(--spacing-10);font-size:var(--size-interactive-xs-font-size)}.lc-datepicker.lc-datepicker--sm{height:var(--size-interactive-sm-height);padding:var(--size-interactive-sm-padding);padding-right:var(--spacing-12);font-size:var(--size-interactive-sm-font-size)}.lc-datepicker.lc-datepicker--md{height:var(--size-interactive-md-height);padding:var(--size-interactive-md-padding);padding-right:var(--spacing-14);font-size:var(--size-interactive-md-font-size)}.lc-datepicker.lc-datepicker--lg{height:var(--size-interactive-lg-height);padding:var(--size-interactive-lg-padding);padding-right:var(--spacing-16);font-size:var(--size-interactive-lg-font-size)}.lc-datepicker.lc-datepicker--filled{background-color:var(--color-surface-sunken);border-color:var(--color-field-border)}.lc-datepicker.lc-datepicker--filled:hover:not(:disabled):not([readonly]):not(.lc-datepicker--error):not(:focus){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-datepicker.lc-datepicker--filled:focus{background-color:var(--color-surface);border-color:var(--color-primary-500)}.lc-datepicker.lc-datepicker--filled:disabled{background-color:var(--color-surface-muted);border-color:var(--color-border)}.lc-datepicker.lc-datepicker--filled.lc-datepicker--error{border-color:var(--color-error-600)}.lc-datepicker-icons{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--spacing-1);pointer-events:none}.lc-datepicker-calendar-icon{width:1.25rem;height:1.25rem;color:var(--color-text-secondary)}.lc-datepicker-clear{pointer-events:auto;display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:none;border:none;border-radius:var(--border-radius-sm);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-clear:hover{color:var(--color-text-primary);background-color:var(--color-surface-hover)}.lc-datepicker-clear:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-clear svg{width:1rem;height:1rem}.lc-datepicker-calendar{position:absolute;z-index:1000;margin-top:var(--spacing-1);padding:var(--lc-density-padding-md, var(--spacing-4));background-color:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);box-shadow:var(--elevation-3);min-width:280px;opacity:0;transform:translateY(-8px);transition:all var(--animation-duration-base) var(--animation-timing-ease);pointer-events:none}.lc-datepicker-calendar.lc-datepicker-calendar--open{opacity:1;transform:translateY(0);pointer-events:auto}.lc-datepicker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--spacing-4)}.lc-datepicker-month-year{font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);color:var(--color-text-primary)}.lc-datepicker-nav-button{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;background:none;border:none;border-radius:var(--border-radius-md);color:var(--color-text-secondary);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-nav-button:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-datepicker-nav-button:active{background-color:var(--color-surface-sunken)}.lc-datepicker-nav-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-nav-button svg{width:1.25rem;height:1.25rem}.lc-datepicker-quick-actions{display:flex;justify-content:center;margin-bottom:var(--spacing-3)}.lc-datepicker-today-button{padding:var(--spacing-1) var(--spacing-3);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-primary-600);background:none;border:1px solid var(--color-primary-200);border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-today-button:hover{background-color:var(--color-primary-50);border-color:var(--color-primary-300)}.lc-datepicker-today-button:active{background-color:var(--color-primary-100)}.lc-datepicker-today-button:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:1px}.lc-datepicker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1);margin-bottom:var(--spacing-2)}.lc-datepicker-weekday{font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);color:var(--color-text-secondary);text-align:center;padding:var(--spacing-1)}.lc-datepicker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--spacing-1)}.lc-datepicker-day{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);color:var(--color-text-primary);background:none;border:none;border-radius:var(--border-radius-md);cursor:pointer;transition:all var(--animation-duration-fast) var(--animation-timing-ease)}.lc-datepicker-day:hover:not(:disabled){background-color:var(--color-surface-hover)}.lc-datepicker-day.lc-datepicker-day--other-month{color:var(--color-text-tertiary)}.lc-datepicker-day.lc-datepicker-day--today{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-day.lc-datepicker-day--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill)}.lc-datepicker-day.lc-datepicker-day--selected:hover{background-color:var(--color-primary-fill-hover)}.lc-datepicker-day.lc-datepicker-day--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-day.lc-datepicker-day--disabled:hover{background:none}.lc-datepicker-day:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-datepicker-calendar--month .lc-datepicker-nav-button{width:2.75rem;height:2.75rem}.lc-datepicker-calendar--month .lc-datepicker-today-button{min-height:2.75rem}.lc-datepicker-months{display:flex;flex-direction:column;gap:var(--spacing-2);inline-size:17.25rem;max-inline-size:calc(100vw - 4.125rem)}.lc-datepicker-month-row{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-2)}.lc-datepicker-month{display:flex;align-items:center;justify-content:center;min-height:2.75rem;padding:0 var(--spacing-1);font-size:var(--font-size-sm);font-weight:var(--font-weight-regular);line-height:var(--line-height-normal);text-align:center;overflow-wrap:anywhere;hyphens:auto;color:var(--color-text-primary);border-radius:var(--border-radius-md);cursor:pointer}.lc-datepicker-month:hover:not(.lc-datepicker-month--disabled):not(.lc-datepicker-month--selected){background-color:var(--color-surface-hover)}.lc-datepicker-month.lc-datepicker-month--current{font-weight:var(--font-weight-semibold);color:var(--color-primary-600);background-color:var(--color-primary-50)}.lc-datepicker-month.lc-datepicker-month--selected{font-weight:var(--font-weight-semibold);color:var(--color-on-primary);background-color:var(--color-primary-fill);box-shadow:inset 0 0 0 2px var(--color-primary-500)}.lc-datepicker-month.lc-datepicker-month--disabled{color:var(--color-text-disabled);cursor:not-allowed;opacity:.5}.lc-datepicker-month:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}@media(forced-colors:active){.lc-datepicker-month:focus-visible{outline-color:Highlight}.lc-datepicker-month.lc-datepicker-month--selected{forced-color-adjust:none;background-color:Highlight;color:HighlightText}.lc-datepicker-month.lc-datepicker-month--current{text-decoration:underline}.lc-datepicker-month.lc-datepicker-month--disabled{color:GrayText}}.lc-datepicker__error{font-size:var(--font-size-xs);color:var(--color-error-600);margin-top:var(--spacing-1)}.lc-datepicker__helper{font-size:var(--font-size-xs);color:var(--color-text-secondary);margin-top:var(--spacing-1)}\n"]
599
806
  }]
600
807
  }],
601
808
  propDecorators: {
@@ -791,6 +998,46 @@ i0.ɵɵngDeclareClassMetadata({
791
998
  required: false
792
999
  }]
793
1000
  }],
1001
+ granularity: [{
1002
+ type: i0.Input,
1003
+ args: [{
1004
+ isSignal: true,
1005
+ alias: "granularity",
1006
+ required: false
1007
+ }]
1008
+ }],
1009
+ previousYearAriaLabel: [{
1010
+ type: i0.Input,
1011
+ args: [{
1012
+ isSignal: true,
1013
+ alias: "previousYearAriaLabel",
1014
+ required: false
1015
+ }]
1016
+ }],
1017
+ nextYearAriaLabel: [{
1018
+ type: i0.Input,
1019
+ args: [{
1020
+ isSignal: true,
1021
+ alias: "nextYearAriaLabel",
1022
+ required: false
1023
+ }]
1024
+ }],
1025
+ monthDialogAriaLabel: [{
1026
+ type: i0.Input,
1027
+ args: [{
1028
+ isSignal: true,
1029
+ alias: "monthDialogAriaLabel",
1030
+ required: false
1031
+ }]
1032
+ }],
1033
+ currentMonthLabel: [{
1034
+ type: i0.Input,
1035
+ args: [{
1036
+ isSignal: true,
1037
+ alias: "currentMonthLabel",
1038
+ required: false
1039
+ }]
1040
+ }],
794
1041
  dateChange: [{
795
1042
  type: i0.Output,
796
1043
  args: ["dateChange"]