@cocoar/ui-components 0.1.0-beta.122 → 0.1.0-beta.126

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.
@@ -643,7 +643,9 @@ function transformStepperButtons(value) {
643
643
  class CoarNumberInputComponent extends CoarControlValueAccessor {
644
644
  destroyRef = inject(DestroyRef);
645
645
  localizationService = inject(CoarLocalizationService, { optional: true });
646
- currentLanguage = toSignal(this.localizationService?.languageChanged$ ?? of(navigator.language));
646
+ currentLanguage = toSignal(this.localizationService?.languageState.value$ ?? of(navigator.language), {
647
+ initialValue: this.localizationService?.languageState.value ?? navigator.language,
648
+ });
647
649
  maskitoInstance;
648
650
  /** Label text displayed above the input */
649
651
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
@@ -841,9 +843,7 @@ class CoarNumberInputComponent extends CoarControlValueAccessor {
841
843
  return null;
842
844
  const format = this.resolveNumberFormat();
843
845
  // Remove thousand separators first (before converting decimal)
844
- const withoutThousands = format.thousand
845
- ? str.replace(new RegExp(`\\${format.thousand}`, 'g'), '')
846
- : str;
846
+ const withoutThousands = format.thousand ? str.replace(new RegExp(`\\${format.thousand}`, 'g'), '') : str;
847
847
  // Replace locale-specific decimal separator with period for parseFloat
848
848
  const normalized = withoutThousands.replace(format.decimal, '.');
849
849
  const parsed = parseFloat(normalized);
@@ -3990,22 +3990,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
3990
3990
  }, styles: [":host{display:block}.coar-table-wrapper{overflow-x:auto;border:1px solid var(--coar-border-neutral-tertiary);border-radius:var(--coar-radius-xs);background:var(--coar-background-neutral-primary)}.coar-table{width:100%;border-collapse:collapse;font-family:var(--coar-body-base-family);font-size:.875rem;line-height:1.5}.coar-table ::ng-deep thead{background:var(--coar-background-neutral-secondary)}.coar-table ::ng-deep th{padding:.75rem 1rem;text-align:left;font-weight:600;font-size:.8125rem;color:var(--coar-text-neutral-primary);border-bottom:1px solid var(--coar-border-neutral-tertiary);white-space:nowrap;text-transform:uppercase;letter-spacing:.025em}.coar-table ::ng-deep tbody tr:nth-child(odd){background:var(--coar-background-neutral-primary)}.coar-table ::ng-deep tbody tr:nth-child(2n){background:var(--coar-background-neutral-secondary)}.coar-table ::ng-deep td{padding:.75rem 1rem;text-align:left;color:var(--coar-text-neutral-secondary);vertical-align:top}.coar-table ::ng-deep code{font-family:Consolas,Monaco,Courier New,monospace;font-size:.8125rem;color:var(--coar-text-accent-secondary);white-space:nowrap}:host(.coar-table--plain) .coar-table ::ng-deep tbody tr:nth-child(odd),:host(.coar-table--plain) .coar-table ::ng-deep tbody tr:nth-child(2n){background:var(--coar-background-neutral-primary)}:host(.coar-table--plain) .coar-table ::ng-deep td{border-bottom:1px solid var(--coar-border-neutral-tertiary)}:host(.coar-table--plain) .coar-table ::ng-deep tbody tr:last-child td{border-bottom:none}:host(.coar-table--bordered) .coar-table-wrapper{border:none}:host(.coar-table--bordered) .coar-table ::ng-deep th,:host(.coar-table--bordered) .coar-table ::ng-deep td{border:1px solid var(--coar-border-neutral-tertiary)}:host(.coar-table--bordered) .coar-table ::ng-deep tbody tr:nth-child(odd),:host(.coar-table--bordered) .coar-table ::ng-deep tbody tr:nth-child(2n){background:var(--coar-background-neutral-primary)}:host(.coar-table--compact) .coar-table ::ng-deep th,:host(.coar-table--compact) .coar-table ::ng-deep td{padding:.5rem .75rem;font-size:.8125rem}:host(.coar-table--hover) .coar-table ::ng-deep tbody tr:hover{background:var(--coar-background-neutral-secondary)}.coar-table ::ng-deep .text-right{text-align:right}.coar-table ::ng-deep .text-center{text-align:center}.coar-table ::ng-deep .nowrap{white-space:nowrap}.coar-table ::ng-deep .prop-name code{color:var(--coar-text-accent-primary);font-weight:500}.coar-table ::ng-deep .type{color:var(--coar-text-neutral-tertiary)}.coar-table ::ng-deep .default{color:var(--coar-text-neutral-tertiary)}.coar-table ::ng-deep .required-badge{display:inline-block;margin-left:.5rem;padding:.125rem .375rem;font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--coar-text-semantic-warning-bold);background:var(--coar-background-semantic-warning-subtle);border-radius:var(--coar-radius-xxs);vertical-align:middle}\n"] }]
3991
3991
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }] } });
3992
3992
 
3993
- /**
3994
- * Generate localized weekday names using Intl.DateTimeFormat.
3995
- * Uses a reference week (Jan 2024 starts on Monday) for consistent day mapping.
3996
- */
3997
- function getLocalizedWeekdays(locale, firstDayOfWeek) {
3993
+ function coarDetectDateFormatPatternFromIntl(locale) {
3994
+ try {
3995
+ const formatter = new Intl.DateTimeFormat(locale);
3996
+ const parts = formatter.formatToParts(new Date(2024, 0, 15));
3997
+ const dayIndex = parts.findIndex((p) => p.type === 'day');
3998
+ const monthIndex = parts.findIndex((p) => p.type === 'month');
3999
+ const yearIndex = parts.findIndex((p) => p.type === 'year');
4000
+ if (dayIndex === -1 || monthIndex === -1 || yearIndex === -1) {
4001
+ return null;
4002
+ }
4003
+ if (dayIndex < monthIndex && monthIndex < yearIndex)
4004
+ return 'dd.mm.yyyy';
4005
+ if (monthIndex < dayIndex && dayIndex < yearIndex)
4006
+ return 'mm/dd/yyyy';
4007
+ if (yearIndex < monthIndex && monthIndex < dayIndex)
4008
+ return 'yyyy-mm-dd';
4009
+ return null;
4010
+ }
4011
+ catch {
4012
+ return null;
4013
+ }
4014
+ }
4015
+ function coarGetDateSeparatorForPattern(pattern) {
4016
+ if (pattern.includes('.'))
4017
+ return '.';
4018
+ if (pattern.includes('/'))
4019
+ return '/';
4020
+ return '-';
4021
+ }
4022
+ function coarGetLocalizedWeekdays(locale, firstDayOfWeek) {
3998
4023
  const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short' });
3999
- // Jan 1, 2024 is a Monday - use this as reference for day mapping
4024
+ // Jan 1, 2024 is a Monday - use this as reference for day mapping.
4000
4025
  const weekdays = [];
4001
4026
  for (let i = 0; i < 7; i++) {
4002
- // Start from Monday (Jan 1) and go through the week
4003
4027
  const date = new Date(2024, 0, 1 + i);
4004
4028
  weekdays.push(formatter.format(date));
4005
4029
  }
4006
- // weekdays is now [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
4030
+ // weekdays is now [Mon, Tue, Wed, Thu, Fri, Sat, Sun].
4007
4031
  if (firstDayOfWeek === 7) {
4008
- // Rotate to start with Sunday
4009
4032
  const sunday = weekdays.pop();
4010
4033
  if (sunday) {
4011
4034
  weekdays.unshift(sunday);
@@ -4013,6 +4036,370 @@ function getLocalizedWeekdays(locale, firstDayOfWeek) {
4013
4036
  }
4014
4037
  return weekdays;
4015
4038
  }
4039
+ function coarFormatPlainDate(date, pattern) {
4040
+ const sep = coarGetDateSeparatorForPattern(pattern);
4041
+ const day = String(date.day).padStart(2, '0');
4042
+ const month = String(date.month).padStart(2, '0');
4043
+ const year = String(date.year);
4044
+ switch (pattern) {
4045
+ case 'dd.mm.yyyy':
4046
+ case 'dd/mm/yyyy':
4047
+ return `${day}${sep}${month}${sep}${year}`;
4048
+ case 'mm/dd/yyyy':
4049
+ return `${month}${sep}${day}${sep}${year}`;
4050
+ case 'yyyy-mm-dd':
4051
+ return `${year}${sep}${month}${sep}${day}`;
4052
+ default:
4053
+ return `${day}${sep}${month}${sep}${year}`;
4054
+ }
4055
+ }
4056
+ function coarParsePlainDateFromInput(text, pattern, constraints) {
4057
+ if (!text)
4058
+ return null;
4059
+ const sep = coarGetDateSeparatorForPattern(pattern);
4060
+ const parts = text.split(sep);
4061
+ if (parts.length !== 3)
4062
+ return null;
4063
+ if (parts.some((p) => p.length === 0 || !/^\d+$/.test(p)))
4064
+ return null;
4065
+ let year;
4066
+ let month;
4067
+ let day;
4068
+ try {
4069
+ switch (pattern) {
4070
+ case 'dd.mm.yyyy':
4071
+ case 'dd/mm/yyyy':
4072
+ day = parseInt(parts[0], 10);
4073
+ month = parseInt(parts[1], 10);
4074
+ year = parseInt(parts[2], 10);
4075
+ break;
4076
+ case 'mm/dd/yyyy':
4077
+ month = parseInt(parts[0], 10);
4078
+ day = parseInt(parts[1], 10);
4079
+ year = parseInt(parts[2], 10);
4080
+ break;
4081
+ case 'yyyy-mm-dd':
4082
+ year = parseInt(parts[0], 10);
4083
+ month = parseInt(parts[1], 10);
4084
+ day = parseInt(parts[2], 10);
4085
+ break;
4086
+ default:
4087
+ return null;
4088
+ }
4089
+ if (year < 1 || month < 1 || month > 12 || day < 1 || day > 31) {
4090
+ return null;
4091
+ }
4092
+ const date = Temporal.PlainDate.from({ year, month, day });
4093
+ const minDate = constraints?.min ?? null;
4094
+ const maxDate = constraints?.max ?? null;
4095
+ if (minDate && Temporal.PlainDate.compare(date, minDate) < 0) {
4096
+ return null;
4097
+ }
4098
+ if (maxDate && Temporal.PlainDate.compare(date, maxDate) > 0) {
4099
+ return null;
4100
+ }
4101
+ return date;
4102
+ }
4103
+ catch {
4104
+ return null;
4105
+ }
4106
+ }
4107
+ function coarTemporalPlainDateToDate(date) {
4108
+ return new Date(date.year, date.month - 1, date.day);
4109
+ }
4110
+ function coarCalculateIsoWeekNumber(date) {
4111
+ const jsDate = coarTemporalPlainDateToDate(date);
4112
+ const dayOfWeek = jsDate.getDay() || 7;
4113
+ jsDate.setDate(jsDate.getDate() + 4 - dayOfWeek);
4114
+ const yearStart = new Date(jsDate.getFullYear(), 0, 1);
4115
+ return Math.ceil(((jsDate.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
4116
+ }
4117
+ function coarClampPlainDate(date, constraints) {
4118
+ const minDate = constraints?.min ?? null;
4119
+ const maxDate = constraints?.max ?? null;
4120
+ if (minDate && Temporal.PlainDate.compare(date, minDate) < 0) {
4121
+ return minDate;
4122
+ }
4123
+ if (maxDate && Temporal.PlainDate.compare(date, maxDate) > 0) {
4124
+ return maxDate;
4125
+ }
4126
+ return date;
4127
+ }
4128
+ /**
4129
+ * Returns a fixed 6x7 calendar grid (42 cells) for the given month.
4130
+ * Includes leading/trailing days from adjacent months to fill the grid.
4131
+ */
4132
+ function coarGetCalendarGridDates(viewMonth, firstDayOfWeek) {
4133
+ const firstDay = viewMonth.toPlainDate({ day: 1 });
4134
+ const daysInMonth = viewMonth.daysInMonth;
4135
+ const startDayOfWeek = firstDay.dayOfWeek; // Temporal: 1=Mon ... 7=Sun
4136
+ let daysFromPrevMonth;
4137
+ if (firstDayOfWeek === 1) {
4138
+ // Monday first: Monday=0, Tuesday=1, ..., Sunday=6
4139
+ daysFromPrevMonth = (startDayOfWeek - 1 + 7) % 7;
4140
+ }
4141
+ else {
4142
+ // Sunday first: Sunday=0, Monday=1, ..., Saturday=6
4143
+ // Temporal uses: Sunday=7, so we convert via modulo
4144
+ daysFromPrevMonth = startDayOfWeek % 7;
4145
+ }
4146
+ const cells = [];
4147
+ if (daysFromPrevMonth > 0) {
4148
+ const prevMonth = viewMonth.subtract({ months: 1 });
4149
+ const prevMonthDays = prevMonth.daysInMonth;
4150
+ for (let i = daysFromPrevMonth - 1; i >= 0; i--) {
4151
+ const day = prevMonth.toPlainDate({ day: prevMonthDays - i });
4152
+ cells.push({ date: day, isOutsideMonth: true });
4153
+ }
4154
+ }
4155
+ for (let d = 1; d <= daysInMonth; d++) {
4156
+ const day = viewMonth.toPlainDate({ day: d });
4157
+ cells.push({ date: day, isOutsideMonth: false });
4158
+ }
4159
+ const remainingDays = 42 - cells.length;
4160
+ const nextMonth = viewMonth.add({ months: 1 });
4161
+ for (let d = 1; d <= remainingDays; d++) {
4162
+ const day = nextMonth.toPlainDate({ day: d });
4163
+ cells.push({ date: day, isOutsideMonth: true });
4164
+ }
4165
+ return cells;
4166
+ }
4167
+
4168
+ class CoarMiniCalendarComponent {
4169
+ /** Current selected date (two-way bindable with [(value)]) */
4170
+ value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
4171
+ valueChange = output();
4172
+ /** Minimum selectable date */
4173
+ min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : []));
4174
+ /** Maximum selectable date */
4175
+ max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : []));
4176
+ /** Locale identifier for calendar month/week labels */
4177
+ locale = input(navigator.language, ...(ngDevMode ? [{ debugName: "locale" }] : []));
4178
+ /** Date format configuration (pattern and first day of week) */
4179
+ dateFormatConfig = input(...(ngDevMode ? [undefined, { debugName: "dateFormatConfig" }] : []));
4180
+ /** Whether to show a "Today" button */
4181
+ showTodayButton = input(true, { ...(ngDevMode ? { debugName: "showTodayButton" } : {}), transform: booleanAttribute });
4182
+ /** Whether to show week numbers */
4183
+ showWeekNumbers = input(false, { ...(ngDevMode ? { debugName: "showWeekNumbers" } : {}), transform: booleanAttribute });
4184
+ /** Whether to highlight weekend days (Saturday/Sunday) with a subtle background */
4185
+ highlightWeekends = input(false, { ...(ngDevMode ? { debugName: "highlightWeekends" } : {}), transform: booleanAttribute });
4186
+ /** Date markers for highlighting special dates (holidays, events, etc.) */
4187
+ markers = input([], ...(ngDevMode ? [{ debugName: "markers" }] : []));
4188
+ /** Maximum number of lines shown in the marker popover (including "+N" line). */
4189
+ markerPopoverMaxLines = 5;
4190
+ /** Visible markers before switching to "+N other events". */
4191
+ markerPopoverVisibleMarkers = 4;
4192
+ today = Temporal.Now.plainDateISO();
4193
+ /** Currently viewed month/year in the calendar */
4194
+ viewDate = signal(this.today.toPlainYearMonth(), ...(ngDevMode ? [{ debugName: "viewDate" }] : []));
4195
+ /** Focused date in the calendar (for keyboard navigation) */
4196
+ focusedDate = signal(null, ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
4197
+ effectiveDateFormat = computed(() => {
4198
+ const directConfig = this.dateFormatConfig();
4199
+ if (directConfig)
4200
+ return directConfig;
4201
+ const detectedPattern = coarDetectDateFormatPatternFromIntl(this.locale());
4202
+ return { pattern: detectedPattern ?? 'dd.mm.yyyy', firstDayOfWeek: 1 };
4203
+ }, ...(ngDevMode ? [{ debugName: "effectiveDateFormat" }] : []));
4204
+ firstDayOfWeek = computed(() => this.effectiveDateFormat().firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
4205
+ daysOfWeek = computed(() => coarGetLocalizedWeekdays(this.locale(), this.firstDayOfWeek()), ...(ngDevMode ? [{ debugName: "daysOfWeek" }] : []));
4206
+ calendarDays = computed(() => {
4207
+ const viewMonth = this.viewDate();
4208
+ const grid = coarGetCalendarGridDates(viewMonth, this.firstDayOfWeek());
4209
+ return grid.map((cell) => this.createCalendarDay(cell.date, cell.isOutsideMonth));
4210
+ }, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
4211
+ viewMonth = computed(() => {
4212
+ const viewMonth = this.viewDate();
4213
+ const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'long' });
4214
+ const jsDate = new Date(viewMonth.year, viewMonth.month - 1, 1);
4215
+ return formatter.format(jsDate);
4216
+ }, ...(ngDevMode ? [{ debugName: "viewMonth" }] : []));
4217
+ viewYear = computed(() => this.viewDate().year, ...(ngDevMode ? [{ debugName: "viewYear" }] : []));
4218
+ weekNumbers = computed(() => {
4219
+ const days = this.calendarDays();
4220
+ const weeks = [];
4221
+ for (let i = 0; i < 6; i++) {
4222
+ const firstDayOfWeek = days[i * 7];
4223
+ if (firstDayOfWeek) {
4224
+ const weekNum = firstDayOfWeek.date.weekOfYear ?? coarCalculateIsoWeekNumber(firstDayOfWeek.date);
4225
+ weeks.push(weekNum);
4226
+ }
4227
+ }
4228
+ return weeks;
4229
+ }, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : []));
4230
+ constructor() {
4231
+ // Keep the view month in sync when a value is provided/changed.
4232
+ effect(() => {
4233
+ const val = this.value();
4234
+ if (!val)
4235
+ return;
4236
+ this.viewDate.set(val.toPlainYearMonth());
4237
+ // Set a sensible default focus when a value arrives.
4238
+ if (!this.focusedDate()) {
4239
+ this.focusedDate.set(val);
4240
+ }
4241
+ });
4242
+ // Default focus when no value is set.
4243
+ effect(() => {
4244
+ if (this.value())
4245
+ return;
4246
+ if (this.focusedDate())
4247
+ return;
4248
+ this.focusedDate.set(this.today);
4249
+ });
4250
+ }
4251
+ previousMonth() {
4252
+ this.viewDate.update((d) => d.subtract({ months: 1 }));
4253
+ }
4254
+ nextMonth() {
4255
+ this.viewDate.update((d) => d.add({ months: 1 }));
4256
+ }
4257
+ previousYear() {
4258
+ this.viewDate.update((d) => d.subtract({ years: 1 }));
4259
+ }
4260
+ nextYear() {
4261
+ this.viewDate.update((d) => d.add({ years: 1 }));
4262
+ }
4263
+ goToToday() {
4264
+ this.viewDate.set(this.today.toPlainYearMonth());
4265
+ this.focusedDate.set(this.today);
4266
+ }
4267
+ selectDate(date) {
4268
+ if (this.isDateDisabled(date))
4269
+ return;
4270
+ this.value.set(date);
4271
+ this.valueChange.emit(date);
4272
+ this.focusedDate.set(date);
4273
+ }
4274
+ onKeydown(event) {
4275
+ switch (event.key) {
4276
+ case 'Enter':
4277
+ case ' ': {
4278
+ event.preventDefault();
4279
+ const focused = this.focusedDate();
4280
+ if (focused) {
4281
+ this.selectDate(focused);
4282
+ }
4283
+ break;
4284
+ }
4285
+ case 'ArrowLeft':
4286
+ event.preventDefault();
4287
+ this.moveFocus(-1, 'day');
4288
+ break;
4289
+ case 'ArrowRight':
4290
+ event.preventDefault();
4291
+ this.moveFocus(1, 'day');
4292
+ break;
4293
+ case 'ArrowUp':
4294
+ event.preventDefault();
4295
+ this.moveFocus(-7, 'day');
4296
+ break;
4297
+ case 'ArrowDown':
4298
+ event.preventDefault();
4299
+ this.moveFocus(7, 'day');
4300
+ break;
4301
+ case 'PageUp':
4302
+ event.preventDefault();
4303
+ if (event.shiftKey) {
4304
+ this.moveFocus(-1, 'year');
4305
+ }
4306
+ else {
4307
+ this.moveFocus(-1, 'month');
4308
+ }
4309
+ break;
4310
+ case 'PageDown':
4311
+ event.preventDefault();
4312
+ if (event.shiftKey) {
4313
+ this.moveFocus(1, 'year');
4314
+ }
4315
+ else {
4316
+ this.moveFocus(1, 'month');
4317
+ }
4318
+ break;
4319
+ case 'Home':
4320
+ event.preventDefault();
4321
+ this.goToToday();
4322
+ break;
4323
+ }
4324
+ }
4325
+ getVisibleMarkers(markers) {
4326
+ if (markers.length <= this.markerPopoverMaxLines) {
4327
+ return markers;
4328
+ }
4329
+ return markers.slice(0, this.markerPopoverVisibleMarkers);
4330
+ }
4331
+ getHiddenMarkerCount(markers) {
4332
+ if (markers.length <= this.markerPopoverMaxLines) {
4333
+ return 0;
4334
+ }
4335
+ return Math.max(0, markers.length - this.markerPopoverVisibleMarkers);
4336
+ }
4337
+ getMarkersForDate(date) {
4338
+ const markers = this.markers();
4339
+ const matches = [];
4340
+ for (const marker of markers) {
4341
+ const start = marker.startDate;
4342
+ const end = marker.endDate ?? marker.startDate;
4343
+ if (Temporal.PlainDate.compare(date, start) >= 0 &&
4344
+ Temporal.PlainDate.compare(date, end) <= 0) {
4345
+ matches.push(marker);
4346
+ }
4347
+ }
4348
+ return matches;
4349
+ }
4350
+ isDateDisabled(date) {
4351
+ const minDate = this.min();
4352
+ const maxDate = this.max();
4353
+ if (minDate && Temporal.PlainDate.compare(date, minDate) < 0)
4354
+ return true;
4355
+ if (maxDate && Temporal.PlainDate.compare(date, maxDate) > 0)
4356
+ return true;
4357
+ return false;
4358
+ }
4359
+ moveFocus(amount, unit) {
4360
+ const current = this.focusedDate() ?? this.value() ?? this.today;
4361
+ let newDate;
4362
+ switch (unit) {
4363
+ case 'day':
4364
+ newDate = current.add({ days: amount });
4365
+ break;
4366
+ case 'month':
4367
+ newDate = current.add({ months: amount });
4368
+ break;
4369
+ case 'year':
4370
+ newDate = current.add({ years: amount });
4371
+ break;
4372
+ }
4373
+ newDate = coarClampPlainDate(newDate, { min: this.min(), max: this.max() });
4374
+ this.focusedDate.set(newDate);
4375
+ this.viewDate.set(newDate.toPlainYearMonth());
4376
+ }
4377
+ createCalendarDay(date, isOutsideMonth) {
4378
+ const selected = this.value();
4379
+ const focused = this.focusedDate();
4380
+ const dayOfWeek = date.dayOfWeek;
4381
+ const markers = this.getMarkersForDate(date);
4382
+ return {
4383
+ date,
4384
+ day: date.day,
4385
+ isOutsideMonth,
4386
+ isToday: Temporal.PlainDate.compare(date, this.today) === 0,
4387
+ isSelected: selected ? Temporal.PlainDate.compare(date, selected) === 0 : false,
4388
+ isFocused: focused ? Temporal.PlainDate.compare(date, focused) === 0 : false,
4389
+ isDisabled: this.isDateDisabled(date),
4390
+ isWeekend: dayOfWeek === 6 || dayOfWeek === 7,
4391
+ markers,
4392
+ markerCssClass: markers[0]?.cssClass ?? null,
4393
+ };
4394
+ }
4395
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CoarMiniCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4396
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CoarMiniCalendarComponent, isStandalone: true, selector: "coar-mini-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, dateFormatConfig: { classPropertyName: "dateFormatConfig", publicName: "dateFormatConfig", isSignal: true, isRequired: false, transformFunction: null }, showTodayButton: { classPropertyName: "showTodayButton", publicName: "showTodayButton", isSignal: true, isRequired: false, transformFunction: null }, showWeekNumbers: { classPropertyName: "showWeekNumbers", publicName: "showWeekNumbers", isSignal: true, isRequired: false, transformFunction: null }, highlightWeekends: { classPropertyName: "highlightWeekends", publicName: "highlightWeekends", isSignal: true, isRequired: false, transformFunction: null }, markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange" }, providers: [CoarPopoverGroupService], ngImport: i0, template: "<div class=\"coar-mini-calendar\" role=\"application\" (keydown)=\"onKeydown($event)\">\n <div class=\"coar-mini-calendar-header\">\n <button type=\"button\" class=\"coar-mini-calendar-nav\" aria-label=\"Previous year\" (click)=\"previousYear()\">\n <coar-icon name=\"chevrons-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-mini-calendar-nav\" aria-label=\"Previous month\" (click)=\"previousMonth()\">\n <coar-icon name=\"chevron-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n\n <span class=\"coar-mini-calendar-month-year\">\n <span class=\"coar-mini-calendar-month\">{{ viewMonth() }}</span>\n <span class=\"coar-mini-calendar-year\">{{ viewYear() }}</span>\n </span>\n\n <button type=\"button\" class=\"coar-mini-calendar-nav coar-mini-calendar-nav--next\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <coar-icon name=\"chevron-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-mini-calendar-nav coar-mini-calendar-nav--next\" aria-label=\"Next year\" (click)=\"nextYear()\">\n <coar-icon name=\"chevrons-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <div class=\"coar-mini-calendar-weekdays\" [class.coar-mini-calendar-weekdays--with-weeks]=\"showWeekNumbers()\">\n @if (showWeekNumbers()) {\n <span class=\"coar-mini-calendar-week-spacer\"></span>\n }\n @for (day of daysOfWeek(); track day) {\n <span class=\"coar-mini-calendar-weekday\">{{ day }}</span>\n }\n </div>\n\n <div class=\"coar-mini-calendar-grid\" [class.coar-mini-calendar-grid--with-weeks]=\"showWeekNumbers()\" role=\"grid\">\n @for (day of calendarDays(); track day.date.toString(); let i = $index) {\n @if (showWeekNumbers() && i % 7 === 0) {\n <span class=\"coar-mini-calendar-week-number\">{{ weekNumbers()[i / 7] }}</span>\n }\n\n <coar-popover [disabled]=\"day.isDisabled || day.markers.length === 0\" [openOnClick]=\"true\" [openOnHover]=\"true\" [interactive]=\"false\">\n <button\n coarPopoverTrigger\n type=\"button\"\n class=\"coar-mini-calendar-day\"\n [class.coar-mini-calendar-day--outside]=\"day.isOutsideMonth\"\n [class.coar-mini-calendar-day--today]=\"day.isToday\"\n [class.coar-mini-calendar-day--selected]=\"day.isSelected\"\n [class.coar-mini-calendar-day--focused]=\"day.isFocused\"\n [class.coar-mini-calendar-day--disabled]=\"day.isDisabled\"\n [class.coar-mini-calendar-day--weekend]=\"highlightWeekends() && day.isWeekend\"\n [class.coar-mini-calendar-day--marked]=\"day.markers.length > 0\"\n [class]=\"day.markerCssClass\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDate(day.date)\"\n >\n {{ day.day }}\n </button>\n\n @if (day.markers.length > 0) {\n <div coarPopoverContent class=\"coar-mini-calendar-marker-popover\">\n <div class=\"coar-mini-calendar-marker-popover__list\">\n @for (marker of getVisibleMarkers(day.markers); track marker.description) {\n <div class=\"coar-mini-calendar-marker-popover__item\">\n {{ marker.description }}\n </div>\n }\n\n @if (getHiddenMarkerCount(day.markers) > 0) {\n <div class=\"coar-mini-calendar-marker-popover__more\">+{{ getHiddenMarkerCount(day.markers) }} other events</div>\n }\n </div>\n </div>\n }\n </coar-popover>\n }\n </div>\n\n @if (showTodayButton()) {\n <div class=\"coar-mini-calendar-footer\">\n <button type=\"button\" class=\"coar-mini-calendar-today\" (click)=\"selectDate(today)\">Today</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.coar-mini-calendar{padding:var(--coar-spacing-m);min-width:280px;background:var(--coar-background-neutral-primary)}.coar-mini-calendar-header{display:flex;align-items:center;justify-content:space-between;gap:var(--coar-spacing-xs);margin-bottom:var(--coar-spacing-m)}.coar-mini-calendar-nav{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;border-radius:var(--coar-radius-xs);transition:background-color .15s ease,color .15s ease}.coar-mini-calendar-nav:hover{background:var(--coar-background-neutral-secondary);color:var(--coar-icon-neutral-primary)}.coar-mini-calendar-month-year{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);line-height:1.2}.coar-mini-calendar-month{font-size:var(--coar-body-base-size);font-weight:var(--coar-body-base-weight)}.coar-mini-calendar-year{font-size:var(--coar-body-sm-size);font-weight:var(--coar-body-sm-weight);color:var(--coar-text-neutral-secondary)}.coar-mini-calendar-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:var(--coar-spacing-xs)}.coar-mini-calendar-weekdays--with-weeks{grid-template-columns:32px repeat(7,1fr)}.coar-mini-calendar-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-secondary);text-transform:uppercase}.coar-mini-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.coar-mini-calendar-grid--with-weeks{position:relative;grid-template-columns:32px repeat(7,1fr)}.coar-mini-calendar-grid--with-weeks:before{content:\"\";position:absolute;left:30px;top:0;bottom:0;width:1px;background:var(--coar-border-neutral-secondary);opacity:.15}.coar-mini-calendar-week-number{display:flex;align-items:center;justify-content:center;min-height:32px;font-family:var(--coar-body-caption-family);font-size:10px;color:var(--coar-text-neutral-tertiary);opacity:.6}.coar-mini-calendar-day{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:1;min-height:32px;padding:2px;border:none;border-radius:0;background:transparent;background-clip:content-box;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);cursor:pointer;outline:none;transition:background-color .15s ease,color .15s ease}.coar-mini-calendar-day:hover:not(:disabled):not(.coar-mini-calendar-day--selected){background:var(--coar-background-neutral-secondary)}.coar-mini-calendar-day--outside{color:var(--coar-text-neutral-tertiary);opacity:.5}.coar-mini-calendar-day--today:not(.coar-mini-calendar-day--selected){font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);background:var(--coar-background-accent-tertiary)}.coar-mini-calendar-day--selected{background:var(--coar-background-accent-primary);color:var(--coar-text-on-bold);font-weight:var(--coar-body-small-bold-weight)}.coar-mini-calendar-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-mini-calendar-day--focused:not(.coar-mini-calendar-day--selected){outline:2px solid var(--coar-border-accent-primary);outline-offset:-2px}.coar-mini-calendar-day--disabled{color:var(--coar-text-neutral-disabled);cursor:not-allowed}.coar-mini-calendar-day--disabled:hover{background:transparent}.coar-mini-calendar-day--weekend{background:var(--coar-background-neutral-secondary)}.coar-mini-calendar-day--weekend:hover:not(:disabled):not(.coar-mini-calendar-day--selected){background:var(--coar-background-neutral-tertiary)}.coar-mini-calendar-day--weekend.coar-mini-calendar-day--selected{background:var(--coar-background-accent-primary)}.coar-mini-calendar-day--weekend.coar-mini-calendar-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-mini-calendar-day--marked{position:relative}.coar-mini-calendar-day--marked:after{content:\"\";position:absolute;top:2px;left:2px;right:2px;height:3px;border-radius:1px;background:var(--coar-border-semantic-info-subtle);pointer-events:none}.coar-mini-calendar-day--marked.coar-mini-calendar-day--selected:after{background:var(--coar-text-on-bold)}.coar-mini-calendar-marker-popover__list{display:flex;flex-direction:column;gap:var(--coar-spacing-xs)}.coar-mini-calendar-marker-popover__item{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);line-height:1.3}.coar-mini-calendar-marker-popover__more{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-secondary);line-height:1.3}.coar-mini-calendar-footer{display:flex;justify-content:center;margin-top:var(--coar-spacing-m);padding-top:var(--coar-spacing-m);border-top:1px solid var(--coar-border-neutral-tertiary)}.coar-mini-calendar-today{padding:var(--coar-spacing-xs) var(--coar-spacing-m);border:none;border-radius:var(--coar-radius-xs);background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);cursor:pointer;transition:background-color .15s ease}.coar-mini-calendar-today:hover{background:var(--coar-background-accent-tertiary)}\n"], dependencies: [{ kind: "component", type: CoarIconComponent, selector: "coar-icon", inputs: ["name", "source", "size", "rotate", "rotateTransition", "spin", "color", "label"] }, { kind: "component", type: CoarPopoverComponent, selector: "coar-popover", inputs: ["disabled", "openOnHover", "openOnClick", "interactive", "fallbackToBestFit", "clampToViewport"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4397
+ }
4398
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CoarMiniCalendarComponent, decorators: [{
4399
+ type: Component,
4400
+ args: [{ selector: 'coar-mini-calendar', standalone: true, imports: [CoarIconComponent, CoarPopoverComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [CoarPopoverGroupService], template: "<div class=\"coar-mini-calendar\" role=\"application\" (keydown)=\"onKeydown($event)\">\n <div class=\"coar-mini-calendar-header\">\n <button type=\"button\" class=\"coar-mini-calendar-nav\" aria-label=\"Previous year\" (click)=\"previousYear()\">\n <coar-icon name=\"chevrons-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-mini-calendar-nav\" aria-label=\"Previous month\" (click)=\"previousMonth()\">\n <coar-icon name=\"chevron-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n\n <span class=\"coar-mini-calendar-month-year\">\n <span class=\"coar-mini-calendar-month\">{{ viewMonth() }}</span>\n <span class=\"coar-mini-calendar-year\">{{ viewYear() }}</span>\n </span>\n\n <button type=\"button\" class=\"coar-mini-calendar-nav coar-mini-calendar-nav--next\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <coar-icon name=\"chevron-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-mini-calendar-nav coar-mini-calendar-nav--next\" aria-label=\"Next year\" (click)=\"nextYear()\">\n <coar-icon name=\"chevrons-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <div class=\"coar-mini-calendar-weekdays\" [class.coar-mini-calendar-weekdays--with-weeks]=\"showWeekNumbers()\">\n @if (showWeekNumbers()) {\n <span class=\"coar-mini-calendar-week-spacer\"></span>\n }\n @for (day of daysOfWeek(); track day) {\n <span class=\"coar-mini-calendar-weekday\">{{ day }}</span>\n }\n </div>\n\n <div class=\"coar-mini-calendar-grid\" [class.coar-mini-calendar-grid--with-weeks]=\"showWeekNumbers()\" role=\"grid\">\n @for (day of calendarDays(); track day.date.toString(); let i = $index) {\n @if (showWeekNumbers() && i % 7 === 0) {\n <span class=\"coar-mini-calendar-week-number\">{{ weekNumbers()[i / 7] }}</span>\n }\n\n <coar-popover [disabled]=\"day.isDisabled || day.markers.length === 0\" [openOnClick]=\"true\" [openOnHover]=\"true\" [interactive]=\"false\">\n <button\n coarPopoverTrigger\n type=\"button\"\n class=\"coar-mini-calendar-day\"\n [class.coar-mini-calendar-day--outside]=\"day.isOutsideMonth\"\n [class.coar-mini-calendar-day--today]=\"day.isToday\"\n [class.coar-mini-calendar-day--selected]=\"day.isSelected\"\n [class.coar-mini-calendar-day--focused]=\"day.isFocused\"\n [class.coar-mini-calendar-day--disabled]=\"day.isDisabled\"\n [class.coar-mini-calendar-day--weekend]=\"highlightWeekends() && day.isWeekend\"\n [class.coar-mini-calendar-day--marked]=\"day.markers.length > 0\"\n [class]=\"day.markerCssClass\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDate(day.date)\"\n >\n {{ day.day }}\n </button>\n\n @if (day.markers.length > 0) {\n <div coarPopoverContent class=\"coar-mini-calendar-marker-popover\">\n <div class=\"coar-mini-calendar-marker-popover__list\">\n @for (marker of getVisibleMarkers(day.markers); track marker.description) {\n <div class=\"coar-mini-calendar-marker-popover__item\">\n {{ marker.description }}\n </div>\n }\n\n @if (getHiddenMarkerCount(day.markers) > 0) {\n <div class=\"coar-mini-calendar-marker-popover__more\">+{{ getHiddenMarkerCount(day.markers) }} other events</div>\n }\n </div>\n </div>\n }\n </coar-popover>\n }\n </div>\n\n @if (showTodayButton()) {\n <div class=\"coar-mini-calendar-footer\">\n <button type=\"button\" class=\"coar-mini-calendar-today\" (click)=\"selectDate(today)\">Today</button>\n </div>\n }\n</div>\n", styles: [":host{display:block}.coar-mini-calendar{padding:var(--coar-spacing-m);min-width:280px;background:var(--coar-background-neutral-primary)}.coar-mini-calendar-header{display:flex;align-items:center;justify-content:space-between;gap:var(--coar-spacing-xs);margin-bottom:var(--coar-spacing-m)}.coar-mini-calendar-nav{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;border-radius:var(--coar-radius-xs);transition:background-color .15s ease,color .15s ease}.coar-mini-calendar-nav:hover{background:var(--coar-background-neutral-secondary);color:var(--coar-icon-neutral-primary)}.coar-mini-calendar-month-year{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);line-height:1.2}.coar-mini-calendar-month{font-size:var(--coar-body-base-size);font-weight:var(--coar-body-base-weight)}.coar-mini-calendar-year{font-size:var(--coar-body-sm-size);font-weight:var(--coar-body-sm-weight);color:var(--coar-text-neutral-secondary)}.coar-mini-calendar-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:var(--coar-spacing-xs)}.coar-mini-calendar-weekdays--with-weeks{grid-template-columns:32px repeat(7,1fr)}.coar-mini-calendar-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-secondary);text-transform:uppercase}.coar-mini-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.coar-mini-calendar-grid--with-weeks{position:relative;grid-template-columns:32px repeat(7,1fr)}.coar-mini-calendar-grid--with-weeks:before{content:\"\";position:absolute;left:30px;top:0;bottom:0;width:1px;background:var(--coar-border-neutral-secondary);opacity:.15}.coar-mini-calendar-week-number{display:flex;align-items:center;justify-content:center;min-height:32px;font-family:var(--coar-body-caption-family);font-size:10px;color:var(--coar-text-neutral-tertiary);opacity:.6}.coar-mini-calendar-day{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:1;min-height:32px;padding:2px;border:none;border-radius:0;background:transparent;background-clip:content-box;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);cursor:pointer;outline:none;transition:background-color .15s ease,color .15s ease}.coar-mini-calendar-day:hover:not(:disabled):not(.coar-mini-calendar-day--selected){background:var(--coar-background-neutral-secondary)}.coar-mini-calendar-day--outside{color:var(--coar-text-neutral-tertiary);opacity:.5}.coar-mini-calendar-day--today:not(.coar-mini-calendar-day--selected){font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);background:var(--coar-background-accent-tertiary)}.coar-mini-calendar-day--selected{background:var(--coar-background-accent-primary);color:var(--coar-text-on-bold);font-weight:var(--coar-body-small-bold-weight)}.coar-mini-calendar-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-mini-calendar-day--focused:not(.coar-mini-calendar-day--selected){outline:2px solid var(--coar-border-accent-primary);outline-offset:-2px}.coar-mini-calendar-day--disabled{color:var(--coar-text-neutral-disabled);cursor:not-allowed}.coar-mini-calendar-day--disabled:hover{background:transparent}.coar-mini-calendar-day--weekend{background:var(--coar-background-neutral-secondary)}.coar-mini-calendar-day--weekend:hover:not(:disabled):not(.coar-mini-calendar-day--selected){background:var(--coar-background-neutral-tertiary)}.coar-mini-calendar-day--weekend.coar-mini-calendar-day--selected{background:var(--coar-background-accent-primary)}.coar-mini-calendar-day--weekend.coar-mini-calendar-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-mini-calendar-day--marked{position:relative}.coar-mini-calendar-day--marked:after{content:\"\";position:absolute;top:2px;left:2px;right:2px;height:3px;border-radius:1px;background:var(--coar-border-semantic-info-subtle);pointer-events:none}.coar-mini-calendar-day--marked.coar-mini-calendar-day--selected:after{background:var(--coar-text-on-bold)}.coar-mini-calendar-marker-popover__list{display:flex;flex-direction:column;gap:var(--coar-spacing-xs)}.coar-mini-calendar-marker-popover__item{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);line-height:1.3}.coar-mini-calendar-marker-popover__more{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-secondary);line-height:1.3}.coar-mini-calendar-footer{display:flex;justify-content:center;margin-top:var(--coar-spacing-m);padding-top:var(--coar-spacing-m);border-top:1px solid var(--coar-border-neutral-tertiary)}.coar-mini-calendar-today{padding:var(--coar-spacing-xs) var(--coar-spacing-m);border:none;border-radius:var(--coar-radius-xs);background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);cursor:pointer;transition:background-color .15s ease}.coar-mini-calendar-today:hover{background:var(--coar-background-accent-tertiary)}\n"] }]
4401
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], dateFormatConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormatConfig", required: false }] }], showTodayButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTodayButton", required: false }] }], showWeekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWeekNumbers", required: false }] }], highlightWeekends: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightWeekends", required: false }] }], markers: [{ type: i0.Input, args: [{ isSignal: true, alias: "markers", required: false }] }] } });
4402
+
4016
4403
  /**
4017
4404
  * Date picker component using Temporal API.
4018
4405
  *
@@ -4029,19 +4416,15 @@ function getLocalizedWeekdays(locale, firstDayOfWeek) {
4029
4416
  * ```
4030
4417
  */
4031
4418
  class CoarDatePickerComponent extends CoarControlValueAccessor {
4032
- elementRef = inject(ElementRef);
4033
4419
  destroyRef = inject(DestroyRef);
4034
4420
  overlayBuilder = createOverlayBuilder();
4035
4421
  localizationService = inject(CoarLocalizationService, { optional: true });
4036
4422
  localizationDataStore = inject(CoarLocalizationDataStore, { optional: true });
4037
4423
  overlayRef = null;
4038
4424
  /** Current language from localization service (reactive) */
4039
- currentLanguage = computed(() => {
4040
- // Use the language Signal from service if available, otherwise undefined
4041
- const lang = this.localizationService?.language();
4042
- console.debug('[CoarDatePicker] currentLanguage computed:', lang);
4043
- return lang;
4044
- }, ...(ngDevMode ? [{ debugName: "currentLanguage" }] : []));
4425
+ currentLanguage = toSignal(this.localizationService?.languageState.value$ ?? of(''), {
4426
+ initialValue: this.localizationService?.languageState.value ?? '',
4427
+ });
4045
4428
  // ============================================================
4046
4429
  // Inputs
4047
4430
  // ============================================================
@@ -4084,28 +4467,6 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4084
4467
  /** Date markers for highlighting special dates (holidays, events, etc.) */
4085
4468
  markers = input([], ...(ngDevMode ? [{ debugName: "markers" }] : []));
4086
4469
  // ============================================================
4087
- // Marker Popover Rendering
4088
- // ============================================================
4089
- /** Maximum number of lines shown in the marker popover (including "+N" line). */
4090
- markerPopoverMaxLines = 5;
4091
- /**
4092
- * Visible markers before switching to "+N other events".
4093
- * With a max of 5 lines, we show 4 markers + one summary line.
4094
- */
4095
- markerPopoverVisibleMarkers = 4;
4096
- getVisibleMarkers(markers) {
4097
- if (markers.length <= this.markerPopoverMaxLines) {
4098
- return markers;
4099
- }
4100
- return markers.slice(0, this.markerPopoverVisibleMarkers);
4101
- }
4102
- getHiddenMarkerCount(markers) {
4103
- if (markers.length <= this.markerPopoverMaxLines) {
4104
- return 0;
4105
- }
4106
- return Math.max(0, markers.length - this.markerPopoverVisibleMarkers);
4107
- }
4108
- // ============================================================
4109
4470
  // Model & Outputs
4110
4471
  // ============================================================
4111
4472
  /** Current selected date (two-way bindable with [(value)]) */
@@ -4135,20 +4496,8 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4135
4496
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
4136
4497
  /** Calendar dropdown position (chosen before opening) */
4137
4498
  calendarPosition = signal('bottom', ...(ngDevMode ? [{ debugName: "calendarPosition" }] : []));
4138
- /** Currently viewed month/year in the calendar */
4139
- viewDate = signal(Temporal.Now.plainDateISO().toPlainYearMonth(), ...(ngDevMode ? [{ debugName: "viewDate" }] : []));
4140
- /** Focused date in the calendar (for keyboard navigation) */
4141
- focusedDate = signal(null, ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
4142
4499
  /** Display value for the input field */
4143
4500
  displayValue = signal('', ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
4144
- /** Days of week header (localized based on locale and firstDayOfWeek) */
4145
- daysOfWeek = computed(() => {
4146
- const locale = this.effectiveLocale();
4147
- const firstDay = this.firstDayOfWeek();
4148
- const days = getLocalizedWeekdays(locale, firstDay);
4149
- console.debug('[CoarDatePicker] daysOfWeek - locale:', locale, 'firstDay:', firstDay, 'days:', days);
4150
- return days;
4151
- }, ...(ngDevMode ? [{ debugName: "daysOfWeek" }] : []));
4152
4501
  /** Reference to the input element */
4153
4502
  inputRef = viewChild('dateInput', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
4154
4503
  /** Reference to the trigger element */
@@ -4169,9 +4518,9 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4169
4518
  return directConfig;
4170
4519
  }
4171
4520
  // 2. Try to get from localization data store (which uses Intl with proper firstDayOfWeek detection)
4172
- const currentLang = this.localizationService?.getCurrentLanguage();
4173
- const localeData = currentLang
4174
- ? this.localizationDataStore?.getLocaleData(currentLang)
4521
+ const storeLocale = this.locale() ?? this.currentLanguage();
4522
+ const localeData = storeLocale
4523
+ ? this.localizationDataStore?.getLocaleData(storeLocale)
4175
4524
  : undefined;
4176
4525
  if (localeData?.date) {
4177
4526
  return {
@@ -4181,25 +4530,8 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4181
4530
  }
4182
4531
  // 3. Fallback to Intl detection (for components without localization service)
4183
4532
  const locale = this.effectiveLocale();
4184
- try {
4185
- const formatter = new Intl.DateTimeFormat(locale);
4186
- const parts = formatter.formatToParts(new Date(2024, 0, 15));
4187
- const dayIndex = parts.findIndex((p) => p.type === 'day');
4188
- const monthIndex = parts.findIndex((p) => p.type === 'month');
4189
- const yearIndex = parts.findIndex((p) => p.type === 'year');
4190
- let pattern = 'dd.mm.yyyy';
4191
- if (dayIndex < monthIndex && monthIndex < yearIndex)
4192
- pattern = 'dd.mm.yyyy';
4193
- else if (monthIndex < dayIndex && dayIndex < yearIndex)
4194
- pattern = 'mm/dd/yyyy';
4195
- else if (yearIndex < monthIndex && monthIndex < dayIndex)
4196
- pattern = 'yyyy-mm-dd';
4197
- return { pattern, firstDayOfWeek: 1 };
4198
- }
4199
- catch {
4200
- // 4. Final fallback
4201
- return { pattern: 'dd.mm.yyyy', firstDayOfWeek: 1 };
4202
- }
4533
+ const detectedPattern = coarDetectDateFormatPatternFromIntl(locale);
4534
+ return { pattern: detectedPattern ?? 'dd.mm.yyyy', firstDayOfWeek: 1 };
4203
4535
  }, ...(ngDevMode ? [{ debugName: "effectiveDateFormat" }] : []));
4204
4536
  /** Get the date format pattern */
4205
4537
  dateFormat = computed(() => this.effectiveDateFormat().pattern, ...(ngDevMode ? [{ debugName: "dateFormat" }] : []));
@@ -4207,12 +4539,7 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4207
4539
  firstDayOfWeek = computed(() => this.effectiveDateFormat().firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
4208
4540
  /** Get the separator character for the current date format */
4209
4541
  separator = computed(() => {
4210
- const format = this.dateFormat();
4211
- if (format.includes('.'))
4212
- return '.';
4213
- if (format.includes('/'))
4214
- return '/';
4215
- return '-';
4542
+ return coarGetDateSeparatorForPattern(this.dateFormat());
4216
4543
  }, ...(ngDevMode ? [{ debugName: "separator" }] : []));
4217
4544
  /** Get placeholder text based on date format */
4218
4545
  inputPlaceholder = computed(() => {
@@ -4223,94 +4550,12 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4223
4550
  * Priority: input locale > locale service language > browser locale
4224
4551
  */
4225
4552
  effectiveLocale = computed(() => {
4226
- const localeInput = this.locale();
4227
- const currentLang = this.currentLanguage();
4228
- const effective = localeInput ?? currentLang ?? navigator.language;
4229
- console.debug('[CoarDatePicker] effectiveLocale - input:', localeInput, 'currentLang:', currentLang, 'effective:', effective);
4230
- return effective;
4553
+ return this.locale() ?? this.currentLanguage() ?? navigator.language;
4231
4554
  }, ...(ngDevMode ? [{ debugName: "effectiveLocale" }] : []));
4232
4555
  /** Whether the picker has an error state */
4233
4556
  hasError = computed(() => this.error(), ...(ngDevMode ? [{ debugName: "hasError" }] : []));
4234
4557
  /** Whether the picker is disabled */
4235
4558
  isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
4236
- /** Calendar grid for current view month */
4237
- calendarDays = computed(() => {
4238
- const viewMonth = this.viewDate();
4239
- const firstDay = viewMonth.toPlainDate({ day: 1 });
4240
- const daysInMonth = viewMonth.daysInMonth;
4241
- // Find what day of week the month starts on (1 = Monday, 7 = Sunday in Temporal)
4242
- const startDayOfWeek = firstDay.dayOfWeek;
4243
- const firstDayOfWeekSetting = this.firstDayOfWeek();
4244
- // Calculate days from previous month to show
4245
- // If firstDayOfWeek is 1 (Monday): offset from Monday
4246
- // If firstDayOfWeek is 7 (Sunday): offset from Sunday
4247
- let daysFromPrevMonth;
4248
- if (firstDayOfWeekSetting === 1) {
4249
- // Monday first: Monday=0, Tuesday=1, ..., Sunday=6
4250
- daysFromPrevMonth = (startDayOfWeek - 1 + 7) % 7;
4251
- }
4252
- else {
4253
- // Sunday first: Sunday=0, Monday=1, ..., Saturday=6
4254
- // Temporal uses: Sunday=7, so we convert
4255
- daysFromPrevMonth = startDayOfWeek % 7;
4256
- }
4257
- const days = [];
4258
- // Previous month days
4259
- if (daysFromPrevMonth > 0) {
4260
- const prevMonth = viewMonth.subtract({ months: 1 });
4261
- const prevMonthDays = prevMonth.daysInMonth;
4262
- for (let i = daysFromPrevMonth - 1; i >= 0; i--) {
4263
- const day = prevMonth.toPlainDate({ day: prevMonthDays - i });
4264
- days.push(this.createCalendarDay(day, true));
4265
- }
4266
- }
4267
- // Current month days
4268
- for (let d = 1; d <= daysInMonth; d++) {
4269
- const day = viewMonth.toPlainDate({ day: d });
4270
- days.push(this.createCalendarDay(day, false));
4271
- }
4272
- // Next month days to fill the grid (6 rows * 7 days = 42)
4273
- const remainingDays = 42 - days.length;
4274
- const nextMonth = viewMonth.add({ months: 1 });
4275
- for (let d = 1; d <= remainingDays; d++) {
4276
- const day = nextMonth.toPlainDate({ day: d });
4277
- days.push(this.createCalendarDay(day, true));
4278
- }
4279
- return days;
4280
- }, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
4281
- /** Month name for calendar header */
4282
- viewMonth = computed(() => {
4283
- const viewMonth = this.viewDate();
4284
- const locale = this.effectiveLocale();
4285
- const formatter = new Intl.DateTimeFormat(locale, {
4286
- month: 'long',
4287
- });
4288
- const jsDate = new Date(viewMonth.year, viewMonth.month - 1, 1);
4289
- const monthName = formatter.format(jsDate);
4290
- console.debug('[CoarDatePicker] viewMonth - locale:', locale, 'month:', viewMonth.month, 'name:', monthName);
4291
- return monthName;
4292
- }, ...(ngDevMode ? [{ debugName: "viewMonth" }] : []));
4293
- /** Year for calendar header */
4294
- viewYear = computed(() => {
4295
- return this.viewDate().year;
4296
- }, ...(ngDevMode ? [{ debugName: "viewYear" }] : []));
4297
- /** Week numbers for each row (6 rows) */
4298
- weekNumbers = computed(() => {
4299
- const days = this.calendarDays();
4300
- const weeks = [];
4301
- // Get the first day of each week (every 7 days)
4302
- for (let i = 0; i < 6; i++) {
4303
- const firstDayOfWeek = days[i * 7];
4304
- if (firstDayOfWeek) {
4305
- // weekOfYear may be undefined in some Temporal implementations
4306
- const weekNum = firstDayOfWeek.date.weekOfYear ?? this.calculateISOWeek(firstDayOfWeek.date);
4307
- weeks.push(weekNum);
4308
- }
4309
- }
4310
- return weeks;
4311
- }, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : []));
4312
- /** Today's date */
4313
- today = Temporal.Now.plainDateISO();
4314
4559
  // ============================================================
4315
4560
  // Constructor & Lifecycle
4316
4561
  // ============================================================
@@ -4320,21 +4565,20 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4320
4565
  effect(() => {
4321
4566
  const val = this.value();
4322
4567
  if (val) {
4323
- this.displayValue.set(this.formatDateForDisplay(val));
4324
- if (!this.isOpen()) {
4325
- this.viewDate.set(val.toPlainYearMonth());
4326
- }
4568
+ this.displayValue.set(coarFormatPlainDate(val, this.dateFormat()));
4327
4569
  }
4328
4570
  else {
4329
4571
  this.displayValue.set('');
4330
4572
  }
4331
4573
  });
4332
- // Initialize Maskito after render
4333
- afterNextRender(() => {
4574
+ // Keep Maskito config in sync with date format + constraints.
4575
+ effect(() => {
4334
4576
  const inputElement = this.inputRef()?.nativeElement;
4335
- if (inputElement) {
4336
- this.initializeMaskito(inputElement);
4577
+ if (!inputElement) {
4578
+ return;
4337
4579
  }
4580
+ this.maskitoInstance?.destroy();
4581
+ this.initializeMaskito(inputElement);
4338
4582
  });
4339
4583
  // Cleanup on destroy
4340
4584
  this.destroyRef.onDestroy(() => {
@@ -4373,17 +4617,12 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4373
4617
  .open({});
4374
4618
  this.overlayRef = ref;
4375
4619
  this.isOpen.set(true);
4376
- // Set initial focus date
4377
- const current = this.value() ?? this.today;
4378
- this.focusedDate.set(current);
4379
- this.viewDate.set(current.toPlainYearMonth());
4380
4620
  this.opened.emit();
4381
4621
  ref.afterClosed$.subscribe(() => {
4382
4622
  if (this.overlayRef !== ref)
4383
4623
  return;
4384
4624
  this.overlayRef = null;
4385
4625
  this.isOpen.set(false);
4386
- this.focusedDate.set(null);
4387
4626
  this.closed.emit();
4388
4627
  });
4389
4628
  }
@@ -4395,7 +4634,6 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4395
4634
  this.overlayRef = null;
4396
4635
  ref?.close();
4397
4636
  this.isOpen.set(false);
4398
- this.focusedDate.set(null);
4399
4637
  this.closed.emit();
4400
4638
  }
4401
4639
  /** Toggle the calendar dropdown */
@@ -4407,21 +4645,16 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4407
4645
  this.openCalendar();
4408
4646
  }
4409
4647
  }
4410
- /** Select a date */
4411
- selectDate(date) {
4648
+ onMiniCalendarValueChange(date) {
4649
+ if (!date)
4650
+ return;
4412
4651
  if (this.isDateDisabled(date))
4413
4652
  return;
4414
4653
  this.value.set(date);
4415
4654
  this.valueChange.emit(date);
4416
4655
  this.cvaOnChange(date);
4417
- // Move keyboard focus to selected date
4418
- this.focusedDate.set(date);
4419
4656
  // Calendar stays open - closes via click outside, Tab, or Escape
4420
4657
  }
4421
- /** Select today's date */
4422
- selectToday() {
4423
- this.selectDate(this.today);
4424
- }
4425
4658
  /** Clear the selected date */
4426
4659
  clearDate(event) {
4427
4660
  event.stopPropagation();
@@ -4429,27 +4662,6 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4429
4662
  this.valueChange.emit(null);
4430
4663
  this.cvaOnChange(null);
4431
4664
  }
4432
- /** Navigate to previous month */
4433
- previousMonth() {
4434
- this.viewDate.update((d) => d.subtract({ months: 1 }));
4435
- }
4436
- /** Navigate to next month */
4437
- nextMonth() {
4438
- this.viewDate.update((d) => d.add({ months: 1 }));
4439
- }
4440
- /** Navigate to previous year */
4441
- previousYear() {
4442
- this.viewDate.update((d) => d.subtract({ years: 1 }));
4443
- }
4444
- /** Navigate to next year */
4445
- nextYear() {
4446
- this.viewDate.update((d) => d.add({ years: 1 }));
4447
- }
4448
- /** Go to today's month */
4449
- goToToday() {
4450
- this.viewDate.set(this.today.toPlainYearMonth());
4451
- this.focusedDate.set(this.today);
4452
- }
4453
4665
  // ============================================================
4454
4666
  // CVA Methods
4455
4667
  // ============================================================
@@ -4476,63 +4688,6 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4476
4688
  onTriggerClick() {
4477
4689
  this.toggleCalendar();
4478
4690
  }
4479
- onDocumentKeydown(event) {
4480
- if (!this.isOpen())
4481
- return;
4482
- switch (event.key) {
4483
- case 'Escape':
4484
- event.preventDefault();
4485
- this.closeCalendar();
4486
- break;
4487
- case 'Enter':
4488
- case ' ': {
4489
- event.preventDefault();
4490
- const focused = this.focusedDate();
4491
- if (focused) {
4492
- this.selectDate(focused);
4493
- }
4494
- break;
4495
- }
4496
- case 'ArrowLeft':
4497
- event.preventDefault();
4498
- this.moveFocus(-1, 'day');
4499
- break;
4500
- case 'ArrowRight':
4501
- event.preventDefault();
4502
- this.moveFocus(1, 'day');
4503
- break;
4504
- case 'ArrowUp':
4505
- event.preventDefault();
4506
- this.moveFocus(-7, 'day');
4507
- break;
4508
- case 'ArrowDown':
4509
- event.preventDefault();
4510
- this.moveFocus(7, 'day');
4511
- break;
4512
- case 'PageUp':
4513
- event.preventDefault();
4514
- if (event.shiftKey) {
4515
- this.moveFocus(-1, 'year');
4516
- }
4517
- else {
4518
- this.moveFocus(-1, 'month');
4519
- }
4520
- break;
4521
- case 'PageDown':
4522
- event.preventDefault();
4523
- if (event.shiftKey) {
4524
- this.moveFocus(1, 'year');
4525
- }
4526
- else {
4527
- this.moveFocus(1, 'month');
4528
- }
4529
- break;
4530
- case 'Home':
4531
- event.preventDefault();
4532
- this.goToToday();
4533
- break;
4534
- }
4535
- }
4536
4691
  onTriggerKeydown(event) {
4537
4692
  if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
4538
4693
  event.preventDefault();
@@ -4572,7 +4727,6 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4572
4727
  const parsed = this.parseDateFromInput(text);
4573
4728
  if (parsed) {
4574
4729
  this.value.set(parsed);
4575
- this.viewDate.set(parsed.toPlainYearMonth());
4576
4730
  this.cvaOnTouched();
4577
4731
  this.valueChange.emit(parsed);
4578
4732
  }
@@ -4590,7 +4744,7 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4590
4744
  // Invalid date entered - reset to current value or clear
4591
4745
  const val = this.value();
4592
4746
  if (val) {
4593
- this.displayValue.set(this.formatDateForDisplay(val));
4747
+ this.displayValue.set(coarFormatPlainDate(val, this.dateFormat()));
4594
4748
  }
4595
4749
  else {
4596
4750
  this.displayValue.set('');
@@ -4621,145 +4775,20 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4621
4775
  const options = maskitoDateOptionsGenerator({
4622
4776
  mode: modeMap[format],
4623
4777
  separator,
4624
- min: minDate ? this.temporalToDate(minDate) : undefined,
4625
- max: maxDate ? this.temporalToDate(maxDate) : undefined,
4778
+ min: minDate ? coarTemporalPlainDateToDate(minDate) : undefined,
4779
+ max: maxDate ? coarTemporalPlainDateToDate(maxDate) : undefined,
4626
4780
  });
4627
4781
  this.maskitoInstance = new Maskito(inputElement, options);
4628
4782
  }
4629
- /**
4630
- * Convert Temporal.PlainDate to native Date for Maskito compatibility.
4631
- */
4632
- temporalToDate(temporal) {
4633
- return new Date(temporal.year, temporal.month - 1, temporal.day);
4634
- }
4635
- /**
4636
- * Calculate ISO week number for a date.
4637
- * ISO weeks start on Monday and week 1 contains the first Thursday of the year.
4638
- */
4639
- calculateISOWeek(date) {
4640
- const jsDate = this.temporalToDate(date);
4641
- const dayOfWeek = jsDate.getDay() || 7; // Convert Sunday (0) to 7
4642
- // Set to nearest Thursday (ISO week date algorithm)
4643
- jsDate.setDate(jsDate.getDate() + 4 - dayOfWeek);
4644
- const yearStart = new Date(jsDate.getFullYear(), 0, 1);
4645
- // Calculate full weeks to nearest Thursday
4646
- return Math.ceil(((jsDate.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
4647
- }
4648
- /**
4649
- * Format a Temporal.PlainDate for display according to the configured format.
4650
- */
4651
- formatDateForDisplay(date) {
4652
- const format = this.dateFormat();
4653
- const sep = this.separator();
4654
- const day = String(date.day).padStart(2, '0');
4655
- const month = String(date.month).padStart(2, '0');
4656
- const year = String(date.year);
4657
- switch (format) {
4658
- case 'dd.mm.yyyy':
4659
- case 'dd/mm/yyyy':
4660
- return `${day}${sep}${month}${sep}${year}`;
4661
- case 'mm/dd/yyyy':
4662
- return `${month}${sep}${day}${sep}${year}`;
4663
- case 'yyyy-mm-dd':
4664
- return `${year}${sep}${month}${sep}${day}`;
4665
- default:
4666
- return `${day}${sep}${month}${sep}${year}`;
4667
- }
4668
- }
4669
4783
  /**
4670
4784
  * Parse a date string in the configured format to Temporal.PlainDate.
4671
4785
  * Returns null if the string is incomplete or invalid.
4672
4786
  */
4673
4787
  parseDateFromInput(text) {
4674
- if (!text)
4675
- return null;
4676
- const sep = this.separator();
4677
- const parts = text.split(sep);
4678
- if (parts.length !== 3)
4679
- return null;
4680
- // Check all parts are complete numbers
4681
- if (parts.some((p) => p.length === 0 || !/^\d+$/.test(p)))
4682
- return null;
4683
- const format = this.dateFormat();
4684
- let year, month, day;
4685
- try {
4686
- switch (format) {
4687
- case 'dd.mm.yyyy':
4688
- case 'dd/mm/yyyy':
4689
- day = parseInt(parts[0], 10);
4690
- month = parseInt(parts[1], 10);
4691
- year = parseInt(parts[2], 10);
4692
- break;
4693
- case 'mm/dd/yyyy':
4694
- month = parseInt(parts[0], 10);
4695
- day = parseInt(parts[1], 10);
4696
- year = parseInt(parts[2], 10);
4697
- break;
4698
- case 'yyyy-mm-dd':
4699
- year = parseInt(parts[0], 10);
4700
- month = parseInt(parts[1], 10);
4701
- day = parseInt(parts[2], 10);
4702
- break;
4703
- default:
4704
- return null;
4705
- }
4706
- // Validate ranges before creating Temporal.PlainDate
4707
- if (year < 1 || month < 1 || month > 12 || day < 1 || day > 31) {
4708
- return null;
4709
- }
4710
- const date = Temporal.PlainDate.from({ year, month, day });
4711
- // Check against min/max bounds
4712
- const minDate = this.min();
4713
- const maxDate = this.max();
4714
- if (minDate && Temporal.PlainDate.compare(date, minDate) < 0) {
4715
- return null;
4716
- }
4717
- if (maxDate && Temporal.PlainDate.compare(date, maxDate) > 0) {
4718
- return null;
4719
- }
4720
- return date;
4721
- }
4722
- catch {
4723
- // Invalid date (e.g., Feb 30)
4724
- return null;
4725
- }
4726
- }
4727
- createCalendarDay(date, isOutsideMonth) {
4728
- const selected = this.value();
4729
- const focused = this.focusedDate();
4730
- // Temporal dayOfWeek: 1=Monday ... 6=Saturday, 7=Sunday
4731
- const dayOfWeek = date.dayOfWeek;
4732
- const markers = this.getMarkersForDate(date);
4733
- return {
4734
- date,
4735
- day: date.day,
4736
- isOutsideMonth,
4737
- isToday: Temporal.PlainDate.compare(date, this.today) === 0,
4738
- isSelected: selected ? Temporal.PlainDate.compare(date, selected) === 0 : false,
4739
- isFocused: focused ? Temporal.PlainDate.compare(date, focused) === 0 : false,
4740
- isDisabled: this.isDateDisabled(date),
4741
- isWeekend: dayOfWeek === 6 || dayOfWeek === 7,
4742
- markers,
4743
- markerCssClass: markers[0]?.cssClass ?? null,
4744
- };
4745
- }
4746
- /**
4747
- * Find all markers that apply to the given date.
4748
- * Checks if date falls within any marker's range.
4749
- */
4750
- getMarkersForDate(date) {
4751
- const markers = this.markers();
4752
- const matches = [];
4753
- for (const marker of markers) {
4754
- const start = marker.startDate;
4755
- const end = marker.endDate ?? marker.startDate;
4756
- // Check if date is within marker range (inclusive)
4757
- if (Temporal.PlainDate.compare(date, start) >= 0 &&
4758
- Temporal.PlainDate.compare(date, end) <= 0) {
4759
- matches.push(marker);
4760
- }
4761
- }
4762
- return matches;
4788
+ return coarParsePlainDateFromInput(text, this.dateFormat(), {
4789
+ min: this.min(),
4790
+ max: this.max(),
4791
+ });
4763
4792
  }
4764
4793
  isDateDisabled(date) {
4765
4794
  const minDate = this.min();
@@ -4772,38 +4801,12 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4772
4801
  }
4773
4802
  return false;
4774
4803
  }
4775
- moveFocus(amount, unit) {
4776
- const current = this.focusedDate() ?? this.value() ?? this.today;
4777
- let newDate;
4778
- switch (unit) {
4779
- case 'day':
4780
- newDate = current.add({ days: amount });
4781
- break;
4782
- case 'month':
4783
- newDate = current.add({ months: amount });
4784
- break;
4785
- case 'year':
4786
- newDate = current.add({ years: amount });
4787
- break;
4788
- }
4789
- // Check bounds
4790
- const minDate = this.min();
4791
- const maxDate = this.max();
4792
- if (minDate && Temporal.PlainDate.compare(newDate, minDate) < 0) {
4793
- newDate = minDate;
4794
- }
4795
- if (maxDate && Temporal.PlainDate.compare(newDate, maxDate) > 0) {
4796
- newDate = maxDate;
4797
- }
4798
- this.focusedDate.set(newDate);
4799
- this.viewDate.set(newDate.toPlainYearMonth());
4800
- }
4801
4804
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CoarDatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4802
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CoarDatePickerComponent, isStandalone: true, selector: "coar-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, dateFormatConfig: { classPropertyName: "dateFormatConfig", publicName: "dateFormatConfig", isSignal: true, isRequired: false, transformFunction: null }, showTodayButton: { classPropertyName: "showTodayButton", publicName: "showTodayButton", isSignal: true, isRequired: false, transformFunction: null }, showWeekNumbers: { classPropertyName: "showWeekNumbers", publicName: "showWeekNumbers", isSignal: true, isRequired: false, transformFunction: null }, highlightWeekends: { classPropertyName: "highlightWeekends", publicName: "highlightWeekends", isSignal: true, isRequired: false, transformFunction: null }, markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange", opened: "opened", closed: "closed" }, host: { listeners: { "document:keydown": "onDocumentKeydown($event)" }, properties: { "class.coar-date-picker--xs": "size() === \"xs\"", "class.coar-date-picker--sm": "size() === \"sm\"", "class.coar-date-picker--md": "size() === \"md\"", "class.coar-date-picker--lg": "size() === \"lg\"", "class.coar-date-picker--disabled": "isDisabled()", "class.coar-date-picker--readonly": "readonly()", "class.coar-date-picker--error": "hasError()", "class.coar-date-picker--open": "isOpen()" } }, providers: [coarProvideValueAccessor(() => CoarDatePickerComponent), CoarPopoverGroupService], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["dateInput"], descendants: true, isSignal: true }, { propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "calendarTemplateRef", first: true, predicate: ["calendarTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"coar-date-picker-wrapper\">\n <!-- Label -->\n @if (label()) {\n <span class=\"coar-date-picker-label\" [attr.id]=\"labelId()\">\n {{ label() }}\n @if (required()) {\n <span class=\"coar-date-picker-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n class=\"coar-date-picker-trigger\"\n [class.coar-date-picker-trigger--disabled]=\"isDisabled()\"\n [class.coar-date-picker-trigger--readonly]=\"readonly()\"\n [class.coar-date-picker-trigger--error]=\"hasError()\"\n [class.coar-date-picker-trigger--open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? calendarId() : null\"\n role=\"combobox\"\n >\n <!-- Clear Button (left side) - always present to prevent CLS -->\n <coar-icon\n name=\"x\"\n source=\"coar-builtin\"\n size=\"auto\"\n class=\"coar-date-picker-clear\"\n [class.coar-date-picker-clear--hidden]=\"!value() || isDisabled() || readonly()\"\n aria-hidden=\"true\"\n (click)=\"clearDate($event)\"\n />\n\n <!-- Date Input -->\n <input\n #dateInput\n type=\"text\"\n class=\"coar-date-picker-input\"\n [attr.id]=\"inputId()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder() || inputPlaceholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [attr.aria-labelledby]=\"label() ? labelId() : null\"\n [attr.aria-invalid]=\"hasError()\"\n autocomplete=\"off\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onTriggerKeydown($event)\"\n />\n\n <!-- Calendar Icon (right side) -->\n <button\n type=\"button\"\n class=\"coar-date-picker-calendar-btn\"\n aria-label=\"Open calendar\"\n [disabled]=\"isDisabled() || readonly()\"\n (click)=\"onTriggerClick()\"\n >\n <coar-icon name=\"calendar\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Calendar Dropdown (rendered via @cocoar/ui-overlay) -->\n <ng-template #calendarTemplate>\n <div\n class=\"coar-date-picker-calendar coar-date-picker-calendar--overlay\"\n [class.coar-date-picker-calendar--top]=\"calendarPosition() === 'top'\"\n [attr.id]=\"calendarId()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Calendar\"\n >\n <!-- Calendar Header -->\n <div class=\"coar-date-picker-header\">\n <button type=\"button\" class=\"coar-date-picker-nav\" aria-label=\"Previous year\" (click)=\"previousYear()\">\n <coar-icon name=\"chevrons-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-date-picker-nav\" aria-label=\"Previous month\" (click)=\"previousMonth()\">\n <coar-icon name=\"chevron-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n\n <span class=\"coar-date-picker-month-year\">\n <span class=\"coar-date-picker-month\">{{ viewMonth() }}</span>\n <span class=\"coar-date-picker-year\">{{ viewYear() }}</span>\n </span>\n\n <button type=\"button\" class=\"coar-date-picker-nav coar-date-picker-nav--next\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <coar-icon name=\"chevron-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-date-picker-nav coar-date-picker-nav--next\" aria-label=\"Next year\" (click)=\"nextYear()\">\n <coar-icon name=\"chevrons-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Days of Week Header -->\n <div class=\"coar-date-picker-weekdays\" [class.coar-date-picker-weekdays--with-weeks]=\"showWeekNumbers()\">\n @if (showWeekNumbers()) {\n <span class=\"coar-date-picker-week-spacer\"></span>\n }\n @for (day of daysOfWeek(); track day) {\n <span class=\"coar-date-picker-weekday\">{{ day }}</span>\n }\n </div>\n\n <!-- Calendar Grid -->\n <div class=\"coar-date-picker-grid\" [class.coar-date-picker-grid--with-weeks]=\"showWeekNumbers()\" role=\"grid\">\n @for (day of calendarDays(); track day.date.toString(); let i = $index) {\n <!-- Week number at start of each row -->\n @if (showWeekNumbers() && i % 7 === 0) {\n <span class=\"coar-date-picker-week-number\">{{ weekNumbers()[i / 7] }}</span>\n }\n <coar-popover [disabled]=\"day.isDisabled || day.markers.length === 0\" [openOnClick]=\"true\" [openOnHover]=\"true\" [interactive]=\"false\">\n <button\n coarPopoverTrigger\n type=\"button\"\n class=\"coar-date-picker-day\"\n [class.coar-date-picker-day--outside]=\"day.isOutsideMonth\"\n [class.coar-date-picker-day--today]=\"day.isToday\"\n [class.coar-date-picker-day--selected]=\"day.isSelected\"\n [class.coar-date-picker-day--focused]=\"day.isFocused\"\n [class.coar-date-picker-day--disabled]=\"day.isDisabled\"\n [class.coar-date-picker-day--weekend]=\"highlightWeekends() && day.isWeekend\"\n [class.coar-date-picker-day--marked]=\"day.markers.length > 0\"\n [class]=\"day.markerCssClass\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDate(day.date)\"\n >\n {{ day.day }}\n </button>\n\n @if (day.markers.length > 0) {\n <div coarPopoverContent class=\"coar-date-picker-marker-popover\">\n <div class=\"coar-date-picker-marker-popover__list\">\n @for (marker of getVisibleMarkers(day.markers); track marker.description) {\n <div class=\"coar-date-picker-marker-popover__item\">\n {{ marker.description }}\n </div>\n }\n\n @if (getHiddenMarkerCount(day.markers) > 0) {\n <div class=\"coar-date-picker-marker-popover__more\">+{{ getHiddenMarkerCount(day.markers) }} other events</div>\n }\n </div>\n </div>\n }\n </coar-popover>\n }\n </div>\n\n <!-- Footer with Today Button -->\n @if (showTodayButton()) {\n <div class=\"coar-date-picker-footer\">\n <button type=\"button\" class=\"coar-date-picker-today\" (click)=\"selectToday()\">Today</button>\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Helper/Error Message -->\n @if (message()) {\n <span class=\"coar-date-picker-message\" [class.coar-date-picker-message--error]=\"hasError()\">\n {{ message() }}\n </span>\n }\n</div>\n", styles: [":host{display:block;position:relative}.coar-date-picker-wrapper{display:flex;flex-direction:column;width:100%}.coar-date-picker-label{display:block;margin-bottom:var(--coar-component-md-label-margin);font-family:var(--coar-body-small-bold-family);font-size:var(--coar-component-md-label-font-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.coar-date-picker-required{color:var(--coar-text-semantic-error-bold);margin-left:var(--coar-spacing-xs)}:host(.coar-date-picker--xs) .coar-date-picker-label{font-size:var(--coar-component-xs-label-font-size);margin-bottom:var(--coar-component-xs-label-margin)}:host(.coar-date-picker--sm) .coar-date-picker-label{font-size:var(--coar-component-sm-label-font-size);margin-bottom:var(--coar-component-sm-label-margin)}:host(.coar-date-picker--lg) .coar-date-picker-label{font-size:var(--coar-component-lg-label-font-size);margin-bottom:var(--coar-component-lg-label-margin)}.coar-date-picker-trigger{display:flex;align-items:center;gap:var(--coar-spacing-s);height:var(--coar-component-md-height);padding:0;border:1px solid var(--coar-border-input);border-radius:var(--coar-radius-xs);background:var(--coar-surface-input);cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.coar-date-picker-trigger:hover:not(.coar-date-picker-trigger--disabled):not(.coar-date-picker-trigger--readonly):not(.coar-date-picker-trigger--error){border-color:var(--coar-border-input-hover)}.coar-date-picker-trigger:focus,.coar-date-picker-trigger:focus-within{outline:none;border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--open:not(.coar-date-picker-trigger--error){border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--disabled{background:var(--coar-surface-input-disabled);cursor:not-allowed;opacity:.6}.coar-date-picker-trigger--readonly{cursor:default}.coar-date-picker-trigger--error{border-color:var(--coar-border-semantic-error-bold)}.coar-date-picker-trigger--error:focus,.coar-date-picker-trigger--error.coar-date-picker-trigger--open{box-shadow:inset 0 0 0 1px var(--coar-border-semantic-error-bold)}:host(.coar-date-picker--xs) .coar-date-picker-trigger{height:var(--coar-component-xs-height);padding:0 var(--coar-spacing-s);gap:var(--coar-spacing-xs)}:host(.coar-date-picker--sm) .coar-date-picker-trigger{height:var(--coar-component-sm-height);padding:0 var(--coar-spacing-s)}:host(.coar-date-picker--lg) .coar-date-picker-trigger{height:var(--coar-component-lg-height);padding:0 var(--coar-spacing-l)}.coar-date-picker-input{flex:1;min-width:0;height:100%;padding:0;border:none;background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);outline:none;cursor:text;text-align:right}.coar-date-picker-input::selection{text-align:right}.coar-date-picker-input::placeholder{color:var(--coar-text-neutral-tertiary)}.coar-date-picker-input:disabled{cursor:not-allowed;color:var(--coar-text-neutral-disabled)}.coar-date-picker-input:read-only{cursor:default}:host(.coar-date-picker--xs) .coar-date-picker-input{font-size:var(--coar-component-xs-font-size)}:host(.coar-date-picker--sm) .coar-date-picker-input{font-size:var(--coar-component-sm-font-size)}:host(.coar-date-picker--lg) .coar-date-picker-input{font-size:var(--coar-component-lg-font-size)}.coar-date-picker-clear{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--coar-spacing-s);color:var(--coar-icon-neutral-disabled);cursor:pointer;transition:color .15s ease,opacity .15s ease;opacity:.4}.coar-date-picker-clear--hidden{opacity:0;pointer-events:none}.coar-date-picker-trigger:hover .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}:host(.coar-date-picker--open) .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}.coar-date-picker-clear:hover:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn{display:flex;align-items:center;justify-content:center;padding:0;margin-right:var(--coar-spacing-s);border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;transition:color .15s ease}.coar-date-picker-calendar-btn:hover:not(:disabled){color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn:disabled{cursor:not-allowed;color:var(--coar-icon-neutral-disabled)}.coar-date-picker-calendar{position:absolute;top:100%;left:0;z-index:1000;margin-top:var(--coar-spacing-xs);padding:var(--coar-spacing-m);min-width:280px;background:var(--coar-background-neutral-primary);border:1px solid var(--coar-border-neutral);border-radius:var(--coar-radius-s);box-shadow:var(--coar-shadow-m)}.coar-date-picker-calendar--overlay{position:static;inset:auto;margin-top:0;margin-bottom:0;z-index:auto}.coar-date-picker-calendar--portal{margin-top:0;margin-bottom:0}.coar-date-picker-calendar--css-anchor{top:anchor(bottom);left:anchor(left);bottom:auto;margin-top:var(--coar-spacing-xs)}.coar-date-picker-calendar--css-anchor.coar-date-picker-calendar--top{top:auto;bottom:anchor(top);margin-top:0;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-calendar--top:not(.coar-date-picker-calendar--overlay):not(.coar-date-picker-calendar--portal):not(.coar-date-picker-calendar--css-anchor){top:auto;bottom:100%;margin-top:0;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-header{display:flex;align-items:center;justify-content:space-between;gap:var(--coar-spacing-xs);margin-bottom:var(--coar-spacing-m)}.coar-date-picker-nav{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;border-radius:var(--coar-radius-xs);transition:background-color .15s ease,color .15s ease}.coar-date-picker-nav:hover{background:var(--coar-background-neutral-secondary);color:var(--coar-icon-neutral-primary)}.coar-date-picker-month-year{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);line-height:1.2}.coar-date-picker-month{font-size:var(--coar-body-base-size);font-weight:var(--coar-body-base-weight)}.coar-date-picker-year{font-size:var(--coar-body-sm-size);font-weight:var(--coar-body-sm-weight);color:var(--coar-text-neutral-secondary)}.coar-date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-weekdays--with-weeks{grid-template-columns:32px repeat(7,1fr)}.coar-date-picker-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-secondary);text-transform:uppercase}.coar-date-picker-grid{display:grid;grid-template-columns:repeat(7,1fr)}.coar-date-picker-grid--with-weeks{position:relative;grid-template-columns:32px repeat(7,1fr)}.coar-date-picker-grid--with-weeks:before{content:\"\";position:absolute;left:30px;top:0;bottom:0;width:1px;background:var(--coar-border-neutral-secondary);opacity:.15}.coar-date-picker-week-number{display:flex;align-items:center;justify-content:center;min-height:32px;font-family:var(--coar-body-caption-family);font-size:10px;color:var(--coar-text-neutral-tertiary);opacity:.6}.coar-date-picker-day{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:1;min-height:32px;padding:2px;border:none;border-radius:0;background:transparent;background-clip:content-box;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);cursor:pointer;outline:none;transition:background-color .15s ease,color .15s ease}.coar-date-picker-day:hover:not(:disabled):not(.coar-date-picker-day--selected){background:var(--coar-background-neutral-secondary)}.coar-date-picker-day--outside{color:var(--coar-text-neutral-tertiary);opacity:.5}.coar-date-picker-day--today:not(.coar-date-picker-day--selected){font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);background:var(--coar-background-accent-tertiary)}.coar-date-picker-day--selected{background:var(--coar-background-accent-primary);color:var(--coar-text-on-bold);font-weight:var(--coar-body-small-bold-weight)}.coar-date-picker-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-date-picker-day--focused:not(.coar-date-picker-day--selected){outline:2px solid var(--coar-border-accent-primary);outline-offset:-2px}.coar-date-picker-day--disabled{color:var(--coar-text-neutral-disabled);cursor:not-allowed}.coar-date-picker-day--disabled:hover{background:transparent}.coar-date-picker-day--weekend{background:var(--coar-background-neutral-secondary)}.coar-date-picker-day--weekend:hover:not(:disabled):not(.coar-date-picker-day--selected){background:var(--coar-background-neutral-tertiary)}.coar-date-picker-day--weekend.coar-date-picker-day--selected{background:var(--coar-background-accent-primary)}.coar-date-picker-day--weekend.coar-date-picker-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-date-picker-day--marked{position:relative}.coar-date-picker-day--marked:after{content:\"\";position:absolute;top:2px;left:2px;right:2px;height:3px;border-radius:1px;background:var(--coar-border-semantic-info-subtle);pointer-events:none}.coar-date-picker-day--marked.coar-date-picker-day--selected:after{background:var(--coar-text-on-bold)}.coar-date-picker-marker-popover__list{display:flex;flex-direction:column;gap:var(--coar-spacing-xs)}.coar-date-picker-marker-popover__item{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);line-height:1.3}.coar-date-picker-marker-popover__more{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-secondary);line-height:1.3}.coar-date-picker-footer{display:flex;justify-content:center;margin-top:var(--coar-spacing-m);padding-top:var(--coar-spacing-m);border-top:1px solid var(--coar-border-neutral-tertiary)}.coar-date-picker-today{padding:var(--coar-spacing-xs) var(--coar-spacing-m);border:none;border-radius:var(--coar-radius-xs);background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);cursor:pointer;transition:background-color .15s ease}.coar-date-picker-today:hover{background:var(--coar-background-accent-tertiary)}.coar-date-picker-message{margin-top:var(--coar-spacing-xs);font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);color:var(--coar-text-neutral-secondary)}.coar-date-picker-message--error{color:var(--coar-text-semantic-error-bold)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: CoarIconComponent, selector: "coar-icon", inputs: ["name", "source", "size", "rotate", "rotateTransition", "spin", "color", "label"] }, { kind: "component", type: CoarPopoverComponent, selector: "coar-popover", inputs: ["disabled", "openOnHover", "openOnClick", "interactive", "fallbackToBestFit", "clampToViewport"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4805
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: CoarDatePickerComponent, isStandalone: true, selector: "coar-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, dateFormatConfig: { classPropertyName: "dateFormatConfig", publicName: "dateFormatConfig", isSignal: true, isRequired: false, transformFunction: null }, showTodayButton: { classPropertyName: "showTodayButton", publicName: "showTodayButton", isSignal: true, isRequired: false, transformFunction: null }, showWeekNumbers: { classPropertyName: "showWeekNumbers", publicName: "showWeekNumbers", isSignal: true, isRequired: false, transformFunction: null }, highlightWeekends: { classPropertyName: "highlightWeekends", publicName: "highlightWeekends", isSignal: true, isRequired: false, transformFunction: null }, markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange", opened: "opened", closed: "closed" }, host: { properties: { "class.coar-date-picker--xs": "size() === \"xs\"", "class.coar-date-picker--sm": "size() === \"sm\"", "class.coar-date-picker--md": "size() === \"md\"", "class.coar-date-picker--lg": "size() === \"lg\"", "class.coar-date-picker--disabled": "isDisabled()", "class.coar-date-picker--readonly": "readonly()", "class.coar-date-picker--error": "hasError()", "class.coar-date-picker--open": "isOpen()" } }, providers: [coarProvideValueAccessor(() => CoarDatePickerComponent)], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["dateInput"], descendants: true, isSignal: true }, { propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "calendarTemplateRef", first: true, predicate: ["calendarTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"coar-date-picker-wrapper\">\n <!-- Label -->\n @if (label()) {\n <span class=\"coar-date-picker-label\" [attr.id]=\"labelId()\">\n {{ label() }}\n @if (required()) {\n <span class=\"coar-date-picker-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n class=\"coar-date-picker-trigger\"\n [class.coar-date-picker-trigger--disabled]=\"isDisabled()\"\n [class.coar-date-picker-trigger--readonly]=\"readonly()\"\n [class.coar-date-picker-trigger--error]=\"hasError()\"\n [class.coar-date-picker-trigger--open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? calendarId() : null\"\n role=\"combobox\"\n >\n <!-- Clear Button (left side) - always present to prevent CLS -->\n <coar-icon\n name=\"x\"\n source=\"coar-builtin\"\n size=\"auto\"\n class=\"coar-date-picker-clear\"\n [class.coar-date-picker-clear--hidden]=\"!value() || isDisabled() || readonly()\"\n aria-hidden=\"true\"\n (click)=\"clearDate($event)\"\n />\n\n <!-- Date Input -->\n <input\n #dateInput\n type=\"text\"\n class=\"coar-date-picker-input\"\n [attr.id]=\"inputId()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder() || inputPlaceholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [attr.aria-labelledby]=\"label() ? labelId() : null\"\n [attr.aria-invalid]=\"hasError()\"\n autocomplete=\"off\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onTriggerKeydown($event)\"\n />\n\n <!-- Calendar Icon (right side) -->\n <button\n type=\"button\"\n class=\"coar-date-picker-calendar-btn\"\n aria-label=\"Open calendar\"\n [disabled]=\"isDisabled() || readonly()\"\n (click)=\"onTriggerClick()\"\n >\n <coar-icon name=\"calendar\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Calendar Dropdown (rendered via @cocoar/ui-overlay) -->\n <ng-template #calendarTemplate>\n <div class=\"coar-date-picker-calendar-host\" [attr.id]=\"calendarId()\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Calendar\">\n <coar-mini-calendar\n [value]=\"value()\"\n (valueChange)=\"onMiniCalendarValueChange($event)\"\n [min]=\"min()\"\n [max]=\"max()\"\n [locale]=\"effectiveLocale()\"\n [dateFormatConfig]=\"effectiveDateFormat()\"\n [showTodayButton]=\"showTodayButton()\"\n [showWeekNumbers]=\"showWeekNumbers()\"\n [highlightWeekends]=\"highlightWeekends()\"\n [markers]=\"markers()\"\n />\n </div>\n </ng-template>\n\n <!-- Helper/Error Message -->\n @if (message()) {\n <span class=\"coar-date-picker-message\" [class.coar-date-picker-message--error]=\"hasError()\">\n {{ message() }}\n </span>\n }\n</div>\n", styles: [":host{display:block;position:relative}.coar-date-picker-wrapper{display:flex;flex-direction:column;width:100%}.coar-date-picker-label{display:block;margin-bottom:var(--coar-component-md-label-margin);font-family:var(--coar-body-small-bold-family);font-size:var(--coar-component-md-label-font-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.coar-date-picker-required{color:var(--coar-text-semantic-error-bold);margin-left:var(--coar-spacing-xs)}:host(.coar-date-picker--xs) .coar-date-picker-label{font-size:var(--coar-component-xs-label-font-size);margin-bottom:var(--coar-component-xs-label-margin)}:host(.coar-date-picker--sm) .coar-date-picker-label{font-size:var(--coar-component-sm-label-font-size);margin-bottom:var(--coar-component-sm-label-margin)}:host(.coar-date-picker--lg) .coar-date-picker-label{font-size:var(--coar-component-lg-label-font-size);margin-bottom:var(--coar-component-lg-label-margin)}.coar-date-picker-trigger{display:flex;align-items:center;gap:var(--coar-spacing-s);height:var(--coar-component-md-height);padding:0;border:1px solid var(--coar-border-input);border-radius:var(--coar-radius-xs);background:var(--coar-surface-input);cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.coar-date-picker-trigger:hover:not(.coar-date-picker-trigger--disabled):not(.coar-date-picker-trigger--readonly):not(.coar-date-picker-trigger--error){border-color:var(--coar-border-input-hover)}.coar-date-picker-trigger:focus,.coar-date-picker-trigger:focus-within{outline:none;border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--open:not(.coar-date-picker-trigger--error){border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--disabled{background:var(--coar-surface-input-disabled);cursor:not-allowed;opacity:.6}.coar-date-picker-trigger--readonly{cursor:default}.coar-date-picker-trigger--error{border-color:var(--coar-border-semantic-error-bold)}.coar-date-picker-trigger--error:focus,.coar-date-picker-trigger--error.coar-date-picker-trigger--open{box-shadow:inset 0 0 0 1px var(--coar-border-semantic-error-bold)}:host(.coar-date-picker--xs) .coar-date-picker-trigger{height:var(--coar-component-xs-height);padding:0 var(--coar-spacing-s);gap:var(--coar-spacing-xs)}:host(.coar-date-picker--sm) .coar-date-picker-trigger{height:var(--coar-component-sm-height);padding:0 var(--coar-spacing-s)}:host(.coar-date-picker--lg) .coar-date-picker-trigger{height:var(--coar-component-lg-height);padding:0 var(--coar-spacing-l)}.coar-date-picker-input{flex:1;min-width:0;height:100%;padding:0;border:none;background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);outline:none;cursor:text;text-align:right}.coar-date-picker-input::selection{text-align:right}.coar-date-picker-input::placeholder{color:var(--coar-text-neutral-tertiary)}.coar-date-picker-input:disabled{cursor:not-allowed;color:var(--coar-text-neutral-disabled)}.coar-date-picker-input:read-only{cursor:default}:host(.coar-date-picker--xs) .coar-date-picker-input{font-size:var(--coar-component-xs-font-size)}:host(.coar-date-picker--sm) .coar-date-picker-input{font-size:var(--coar-component-sm-font-size)}:host(.coar-date-picker--lg) .coar-date-picker-input{font-size:var(--coar-component-lg-font-size)}.coar-date-picker-clear{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--coar-spacing-s);color:var(--coar-icon-neutral-disabled);cursor:pointer;transition:color .15s ease,opacity .15s ease;opacity:.4}.coar-date-picker-clear--hidden{opacity:0;pointer-events:none}.coar-date-picker-trigger:hover .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}:host(.coar-date-picker--open) .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}.coar-date-picker-clear:hover:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn{display:flex;align-items:center;justify-content:center;padding:0;margin-right:var(--coar-spacing-s);border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;transition:color .15s ease}.coar-date-picker-calendar-btn:hover:not(:disabled){color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn:disabled{cursor:not-allowed;color:var(--coar-icon-neutral-disabled)}.coar-date-picker-calendar-host{display:block;border:1px solid var(--coar-border-neutral);border-radius:var(--coar-radius-s);box-shadow:var(--coar-shadow-m)}.coar-date-picker-message{margin-top:var(--coar-spacing-xs);font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);color:var(--coar-text-neutral-secondary)}.coar-date-picker-message--error{color:var(--coar-text-semantic-error-bold)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: CoarIconComponent, selector: "coar-icon", inputs: ["name", "source", "size", "rotate", "rotateTransition", "spin", "color", "label"] }, { kind: "component", type: CoarMiniCalendarComponent, selector: "coar-mini-calendar", inputs: ["value", "min", "max", "locale", "dateFormatConfig", "showTodayButton", "showWeekNumbers", "highlightWeekends", "markers"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4803
4806
  }
4804
4807
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CoarDatePickerComponent, decorators: [{
4805
4808
  type: Component,
4806
- args: [{ selector: 'coar-date-picker', standalone: true, imports: [FormsModule, CoarIconComponent, CoarPopoverComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [coarProvideValueAccessor(() => CoarDatePickerComponent), CoarPopoverGroupService], host: {
4809
+ args: [{ selector: 'coar-date-picker', standalone: true, imports: [FormsModule, CoarIconComponent, CoarMiniCalendarComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [coarProvideValueAccessor(() => CoarDatePickerComponent)], host: {
4807
4810
  '[class.coar-date-picker--xs]': 'size() === "xs"',
4808
4811
  '[class.coar-date-picker--sm]': 'size() === "sm"',
4809
4812
  '[class.coar-date-picker--md]': 'size() === "md"',
@@ -4812,13 +4815,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
4812
4815
  '[class.coar-date-picker--readonly]': 'readonly()',
4813
4816
  '[class.coar-date-picker--error]': 'hasError()',
4814
4817
  '[class.coar-date-picker--open]': 'isOpen()',
4815
- '(document:keydown)': 'onDocumentKeydown($event)',
4816
- }, template: "<div class=\"coar-date-picker-wrapper\">\n <!-- Label -->\n @if (label()) {\n <span class=\"coar-date-picker-label\" [attr.id]=\"labelId()\">\n {{ label() }}\n @if (required()) {\n <span class=\"coar-date-picker-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n class=\"coar-date-picker-trigger\"\n [class.coar-date-picker-trigger--disabled]=\"isDisabled()\"\n [class.coar-date-picker-trigger--readonly]=\"readonly()\"\n [class.coar-date-picker-trigger--error]=\"hasError()\"\n [class.coar-date-picker-trigger--open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? calendarId() : null\"\n role=\"combobox\"\n >\n <!-- Clear Button (left side) - always present to prevent CLS -->\n <coar-icon\n name=\"x\"\n source=\"coar-builtin\"\n size=\"auto\"\n class=\"coar-date-picker-clear\"\n [class.coar-date-picker-clear--hidden]=\"!value() || isDisabled() || readonly()\"\n aria-hidden=\"true\"\n (click)=\"clearDate($event)\"\n />\n\n <!-- Date Input -->\n <input\n #dateInput\n type=\"text\"\n class=\"coar-date-picker-input\"\n [attr.id]=\"inputId()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder() || inputPlaceholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [attr.aria-labelledby]=\"label() ? labelId() : null\"\n [attr.aria-invalid]=\"hasError()\"\n autocomplete=\"off\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onTriggerKeydown($event)\"\n />\n\n <!-- Calendar Icon (right side) -->\n <button\n type=\"button\"\n class=\"coar-date-picker-calendar-btn\"\n aria-label=\"Open calendar\"\n [disabled]=\"isDisabled() || readonly()\"\n (click)=\"onTriggerClick()\"\n >\n <coar-icon name=\"calendar\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Calendar Dropdown (rendered via @cocoar/ui-overlay) -->\n <ng-template #calendarTemplate>\n <div\n class=\"coar-date-picker-calendar coar-date-picker-calendar--overlay\"\n [class.coar-date-picker-calendar--top]=\"calendarPosition() === 'top'\"\n [attr.id]=\"calendarId()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Calendar\"\n >\n <!-- Calendar Header -->\n <div class=\"coar-date-picker-header\">\n <button type=\"button\" class=\"coar-date-picker-nav\" aria-label=\"Previous year\" (click)=\"previousYear()\">\n <coar-icon name=\"chevrons-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-date-picker-nav\" aria-label=\"Previous month\" (click)=\"previousMonth()\">\n <coar-icon name=\"chevron-left\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n\n <span class=\"coar-date-picker-month-year\">\n <span class=\"coar-date-picker-month\">{{ viewMonth() }}</span>\n <span class=\"coar-date-picker-year\">{{ viewYear() }}</span>\n </span>\n\n <button type=\"button\" class=\"coar-date-picker-nav coar-date-picker-nav--next\" aria-label=\"Next month\" (click)=\"nextMonth()\">\n <coar-icon name=\"chevron-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n <button type=\"button\" class=\"coar-date-picker-nav coar-date-picker-nav--next\" aria-label=\"Next year\" (click)=\"nextYear()\">\n <coar-icon name=\"chevrons-right\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Days of Week Header -->\n <div class=\"coar-date-picker-weekdays\" [class.coar-date-picker-weekdays--with-weeks]=\"showWeekNumbers()\">\n @if (showWeekNumbers()) {\n <span class=\"coar-date-picker-week-spacer\"></span>\n }\n @for (day of daysOfWeek(); track day) {\n <span class=\"coar-date-picker-weekday\">{{ day }}</span>\n }\n </div>\n\n <!-- Calendar Grid -->\n <div class=\"coar-date-picker-grid\" [class.coar-date-picker-grid--with-weeks]=\"showWeekNumbers()\" role=\"grid\">\n @for (day of calendarDays(); track day.date.toString(); let i = $index) {\n <!-- Week number at start of each row -->\n @if (showWeekNumbers() && i % 7 === 0) {\n <span class=\"coar-date-picker-week-number\">{{ weekNumbers()[i / 7] }}</span>\n }\n <coar-popover [disabled]=\"day.isDisabled || day.markers.length === 0\" [openOnClick]=\"true\" [openOnHover]=\"true\" [interactive]=\"false\">\n <button\n coarPopoverTrigger\n type=\"button\"\n class=\"coar-date-picker-day\"\n [class.coar-date-picker-day--outside]=\"day.isOutsideMonth\"\n [class.coar-date-picker-day--today]=\"day.isToday\"\n [class.coar-date-picker-day--selected]=\"day.isSelected\"\n [class.coar-date-picker-day--focused]=\"day.isFocused\"\n [class.coar-date-picker-day--disabled]=\"day.isDisabled\"\n [class.coar-date-picker-day--weekend]=\"highlightWeekends() && day.isWeekend\"\n [class.coar-date-picker-day--marked]=\"day.markers.length > 0\"\n [class]=\"day.markerCssClass\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDate(day.date)\"\n >\n {{ day.day }}\n </button>\n\n @if (day.markers.length > 0) {\n <div coarPopoverContent class=\"coar-date-picker-marker-popover\">\n <div class=\"coar-date-picker-marker-popover__list\">\n @for (marker of getVisibleMarkers(day.markers); track marker.description) {\n <div class=\"coar-date-picker-marker-popover__item\">\n {{ marker.description }}\n </div>\n }\n\n @if (getHiddenMarkerCount(day.markers) > 0) {\n <div class=\"coar-date-picker-marker-popover__more\">+{{ getHiddenMarkerCount(day.markers) }} other events</div>\n }\n </div>\n </div>\n }\n </coar-popover>\n }\n </div>\n\n <!-- Footer with Today Button -->\n @if (showTodayButton()) {\n <div class=\"coar-date-picker-footer\">\n <button type=\"button\" class=\"coar-date-picker-today\" (click)=\"selectToday()\">Today</button>\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Helper/Error Message -->\n @if (message()) {\n <span class=\"coar-date-picker-message\" [class.coar-date-picker-message--error]=\"hasError()\">\n {{ message() }}\n </span>\n }\n</div>\n", styles: [":host{display:block;position:relative}.coar-date-picker-wrapper{display:flex;flex-direction:column;width:100%}.coar-date-picker-label{display:block;margin-bottom:var(--coar-component-md-label-margin);font-family:var(--coar-body-small-bold-family);font-size:var(--coar-component-md-label-font-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.coar-date-picker-required{color:var(--coar-text-semantic-error-bold);margin-left:var(--coar-spacing-xs)}:host(.coar-date-picker--xs) .coar-date-picker-label{font-size:var(--coar-component-xs-label-font-size);margin-bottom:var(--coar-component-xs-label-margin)}:host(.coar-date-picker--sm) .coar-date-picker-label{font-size:var(--coar-component-sm-label-font-size);margin-bottom:var(--coar-component-sm-label-margin)}:host(.coar-date-picker--lg) .coar-date-picker-label{font-size:var(--coar-component-lg-label-font-size);margin-bottom:var(--coar-component-lg-label-margin)}.coar-date-picker-trigger{display:flex;align-items:center;gap:var(--coar-spacing-s);height:var(--coar-component-md-height);padding:0;border:1px solid var(--coar-border-input);border-radius:var(--coar-radius-xs);background:var(--coar-surface-input);cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.coar-date-picker-trigger:hover:not(.coar-date-picker-trigger--disabled):not(.coar-date-picker-trigger--readonly):not(.coar-date-picker-trigger--error){border-color:var(--coar-border-input-hover)}.coar-date-picker-trigger:focus,.coar-date-picker-trigger:focus-within{outline:none;border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--open:not(.coar-date-picker-trigger--error){border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--disabled{background:var(--coar-surface-input-disabled);cursor:not-allowed;opacity:.6}.coar-date-picker-trigger--readonly{cursor:default}.coar-date-picker-trigger--error{border-color:var(--coar-border-semantic-error-bold)}.coar-date-picker-trigger--error:focus,.coar-date-picker-trigger--error.coar-date-picker-trigger--open{box-shadow:inset 0 0 0 1px var(--coar-border-semantic-error-bold)}:host(.coar-date-picker--xs) .coar-date-picker-trigger{height:var(--coar-component-xs-height);padding:0 var(--coar-spacing-s);gap:var(--coar-spacing-xs)}:host(.coar-date-picker--sm) .coar-date-picker-trigger{height:var(--coar-component-sm-height);padding:0 var(--coar-spacing-s)}:host(.coar-date-picker--lg) .coar-date-picker-trigger{height:var(--coar-component-lg-height);padding:0 var(--coar-spacing-l)}.coar-date-picker-input{flex:1;min-width:0;height:100%;padding:0;border:none;background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);outline:none;cursor:text;text-align:right}.coar-date-picker-input::selection{text-align:right}.coar-date-picker-input::placeholder{color:var(--coar-text-neutral-tertiary)}.coar-date-picker-input:disabled{cursor:not-allowed;color:var(--coar-text-neutral-disabled)}.coar-date-picker-input:read-only{cursor:default}:host(.coar-date-picker--xs) .coar-date-picker-input{font-size:var(--coar-component-xs-font-size)}:host(.coar-date-picker--sm) .coar-date-picker-input{font-size:var(--coar-component-sm-font-size)}:host(.coar-date-picker--lg) .coar-date-picker-input{font-size:var(--coar-component-lg-font-size)}.coar-date-picker-clear{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--coar-spacing-s);color:var(--coar-icon-neutral-disabled);cursor:pointer;transition:color .15s ease,opacity .15s ease;opacity:.4}.coar-date-picker-clear--hidden{opacity:0;pointer-events:none}.coar-date-picker-trigger:hover .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}:host(.coar-date-picker--open) .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}.coar-date-picker-clear:hover:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn{display:flex;align-items:center;justify-content:center;padding:0;margin-right:var(--coar-spacing-s);border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;transition:color .15s ease}.coar-date-picker-calendar-btn:hover:not(:disabled){color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn:disabled{cursor:not-allowed;color:var(--coar-icon-neutral-disabled)}.coar-date-picker-calendar{position:absolute;top:100%;left:0;z-index:1000;margin-top:var(--coar-spacing-xs);padding:var(--coar-spacing-m);min-width:280px;background:var(--coar-background-neutral-primary);border:1px solid var(--coar-border-neutral);border-radius:var(--coar-radius-s);box-shadow:var(--coar-shadow-m)}.coar-date-picker-calendar--overlay{position:static;inset:auto;margin-top:0;margin-bottom:0;z-index:auto}.coar-date-picker-calendar--portal{margin-top:0;margin-bottom:0}.coar-date-picker-calendar--css-anchor{top:anchor(bottom);left:anchor(left);bottom:auto;margin-top:var(--coar-spacing-xs)}.coar-date-picker-calendar--css-anchor.coar-date-picker-calendar--top{top:auto;bottom:anchor(top);margin-top:0;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-calendar--top:not(.coar-date-picker-calendar--overlay):not(.coar-date-picker-calendar--portal):not(.coar-date-picker-calendar--css-anchor){top:auto;bottom:100%;margin-top:0;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-header{display:flex;align-items:center;justify-content:space-between;gap:var(--coar-spacing-xs);margin-bottom:var(--coar-spacing-m)}.coar-date-picker-nav{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;border-radius:var(--coar-radius-xs);transition:background-color .15s ease,color .15s ease}.coar-date-picker-nav:hover{background:var(--coar-background-neutral-secondary);color:var(--coar-icon-neutral-primary)}.coar-date-picker-month-year{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;font-family:var(--coar-body-base-family);color:var(--coar-text-neutral-primary);line-height:1.2}.coar-date-picker-month{font-size:var(--coar-body-base-size);font-weight:var(--coar-body-base-weight)}.coar-date-picker-year{font-size:var(--coar-body-sm-size);font-weight:var(--coar-body-sm-weight);color:var(--coar-text-neutral-secondary)}.coar-date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:var(--coar-spacing-xs)}.coar-date-picker-weekdays--with-weeks{grid-template-columns:32px repeat(7,1fr)}.coar-date-picker-weekday{display:flex;align-items:center;justify-content:center;height:32px;font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-secondary);text-transform:uppercase}.coar-date-picker-grid{display:grid;grid-template-columns:repeat(7,1fr)}.coar-date-picker-grid--with-weeks{position:relative;grid-template-columns:32px repeat(7,1fr)}.coar-date-picker-grid--with-weeks:before{content:\"\";position:absolute;left:30px;top:0;bottom:0;width:1px;background:var(--coar-border-neutral-secondary);opacity:.15}.coar-date-picker-week-number{display:flex;align-items:center;justify-content:center;min-height:32px;font-family:var(--coar-body-caption-family);font-size:10px;color:var(--coar-text-neutral-tertiary);opacity:.6}.coar-date-picker-day{display:flex;align-items:center;justify-content:center;width:100%;aspect-ratio:1;min-height:32px;padding:2px;border:none;border-radius:0;background:transparent;background-clip:content-box;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);cursor:pointer;outline:none;transition:background-color .15s ease,color .15s ease}.coar-date-picker-day:hover:not(:disabled):not(.coar-date-picker-day--selected){background:var(--coar-background-neutral-secondary)}.coar-date-picker-day--outside{color:var(--coar-text-neutral-tertiary);opacity:.5}.coar-date-picker-day--today:not(.coar-date-picker-day--selected){font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);background:var(--coar-background-accent-tertiary)}.coar-date-picker-day--selected{background:var(--coar-background-accent-primary);color:var(--coar-text-on-bold);font-weight:var(--coar-body-small-bold-weight)}.coar-date-picker-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-date-picker-day--focused:not(.coar-date-picker-day--selected){outline:2px solid var(--coar-border-accent-primary);outline-offset:-2px}.coar-date-picker-day--disabled{color:var(--coar-text-neutral-disabled);cursor:not-allowed}.coar-date-picker-day--disabled:hover{background:transparent}.coar-date-picker-day--weekend{background:var(--coar-background-neutral-secondary)}.coar-date-picker-day--weekend:hover:not(:disabled):not(.coar-date-picker-day--selected){background:var(--coar-background-neutral-tertiary)}.coar-date-picker-day--weekend.coar-date-picker-day--selected{background:var(--coar-background-accent-primary)}.coar-date-picker-day--weekend.coar-date-picker-day--selected:hover{background:var(--coar-background-accent-hover)}.coar-date-picker-day--marked{position:relative}.coar-date-picker-day--marked:after{content:\"\";position:absolute;top:2px;left:2px;right:2px;height:3px;border-radius:1px;background:var(--coar-border-semantic-info-subtle);pointer-events:none}.coar-date-picker-day--marked.coar-date-picker-day--selected:after{background:var(--coar-text-on-bold)}.coar-date-picker-marker-popover__list{display:flex;flex-direction:column;gap:var(--coar-spacing-xs)}.coar-date-picker-marker-popover__item{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);line-height:1.3}.coar-date-picker-marker-popover__more{font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-secondary);line-height:1.3}.coar-date-picker-footer{display:flex;justify-content:center;margin-top:var(--coar-spacing-m);padding-top:var(--coar-spacing-m);border-top:1px solid var(--coar-border-neutral-tertiary)}.coar-date-picker-today{padding:var(--coar-spacing-xs) var(--coar-spacing-m);border:none;border-radius:var(--coar-radius-xs);background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-accent-primary);cursor:pointer;transition:background-color .15s ease}.coar-date-picker-today:hover{background:var(--coar-background-accent-tertiary)}.coar-date-picker-message{margin-top:var(--coar-spacing-xs);font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);color:var(--coar-text-neutral-secondary)}.coar-date-picker-message--error{color:var(--coar-text-semantic-error-bold)}\n"] }]
4818
+ }, template: "<div class=\"coar-date-picker-wrapper\">\n <!-- Label -->\n @if (label()) {\n <span class=\"coar-date-picker-label\" [attr.id]=\"labelId()\">\n {{ label() }}\n @if (required()) {\n <span class=\"coar-date-picker-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n class=\"coar-date-picker-trigger\"\n [class.coar-date-picker-trigger--disabled]=\"isDisabled()\"\n [class.coar-date-picker-trigger--readonly]=\"readonly()\"\n [class.coar-date-picker-trigger--error]=\"hasError()\"\n [class.coar-date-picker-trigger--open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? calendarId() : null\"\n role=\"combobox\"\n >\n <!-- Clear Button (left side) - always present to prevent CLS -->\n <coar-icon\n name=\"x\"\n source=\"coar-builtin\"\n size=\"auto\"\n class=\"coar-date-picker-clear\"\n [class.coar-date-picker-clear--hidden]=\"!value() || isDisabled() || readonly()\"\n aria-hidden=\"true\"\n (click)=\"clearDate($event)\"\n />\n\n <!-- Date Input -->\n <input\n #dateInput\n type=\"text\"\n class=\"coar-date-picker-input\"\n [attr.id]=\"inputId()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder() || inputPlaceholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [attr.aria-labelledby]=\"label() ? labelId() : null\"\n [attr.aria-invalid]=\"hasError()\"\n autocomplete=\"off\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onTriggerKeydown($event)\"\n />\n\n <!-- Calendar Icon (right side) -->\n <button\n type=\"button\"\n class=\"coar-date-picker-calendar-btn\"\n aria-label=\"Open calendar\"\n [disabled]=\"isDisabled() || readonly()\"\n (click)=\"onTriggerClick()\"\n >\n <coar-icon name=\"calendar\" source=\"coar-builtin\" size=\"sm\" />\n </button>\n </div>\n\n <!-- Calendar Dropdown (rendered via @cocoar/ui-overlay) -->\n <ng-template #calendarTemplate>\n <div class=\"coar-date-picker-calendar-host\" [attr.id]=\"calendarId()\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Calendar\">\n <coar-mini-calendar\n [value]=\"value()\"\n (valueChange)=\"onMiniCalendarValueChange($event)\"\n [min]=\"min()\"\n [max]=\"max()\"\n [locale]=\"effectiveLocale()\"\n [dateFormatConfig]=\"effectiveDateFormat()\"\n [showTodayButton]=\"showTodayButton()\"\n [showWeekNumbers]=\"showWeekNumbers()\"\n [highlightWeekends]=\"highlightWeekends()\"\n [markers]=\"markers()\"\n />\n </div>\n </ng-template>\n\n <!-- Helper/Error Message -->\n @if (message()) {\n <span class=\"coar-date-picker-message\" [class.coar-date-picker-message--error]=\"hasError()\">\n {{ message() }}\n </span>\n }\n</div>\n", styles: [":host{display:block;position:relative}.coar-date-picker-wrapper{display:flex;flex-direction:column;width:100%}.coar-date-picker-label{display:block;margin-bottom:var(--coar-component-md-label-margin);font-family:var(--coar-body-small-bold-family);font-size:var(--coar-component-md-label-font-size);font-weight:var(--coar-body-small-bold-weight);color:var(--coar-text-neutral-primary);cursor:pointer;-webkit-user-select:none;user-select:none}.coar-date-picker-required{color:var(--coar-text-semantic-error-bold);margin-left:var(--coar-spacing-xs)}:host(.coar-date-picker--xs) .coar-date-picker-label{font-size:var(--coar-component-xs-label-font-size);margin-bottom:var(--coar-component-xs-label-margin)}:host(.coar-date-picker--sm) .coar-date-picker-label{font-size:var(--coar-component-sm-label-font-size);margin-bottom:var(--coar-component-sm-label-margin)}:host(.coar-date-picker--lg) .coar-date-picker-label{font-size:var(--coar-component-lg-label-font-size);margin-bottom:var(--coar-component-lg-label-margin)}.coar-date-picker-trigger{display:flex;align-items:center;gap:var(--coar-spacing-s);height:var(--coar-component-md-height);padding:0;border:1px solid var(--coar-border-input);border-radius:var(--coar-radius-xs);background:var(--coar-surface-input);cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.coar-date-picker-trigger:hover:not(.coar-date-picker-trigger--disabled):not(.coar-date-picker-trigger--readonly):not(.coar-date-picker-trigger--error){border-color:var(--coar-border-input-hover)}.coar-date-picker-trigger:focus,.coar-date-picker-trigger:focus-within{outline:none;border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--open:not(.coar-date-picker-trigger--error){border-color:var(--coar-border-accent-primary);box-shadow:inset 0 0 0 1px var(--coar-border-accent-primary)}.coar-date-picker-trigger--disabled{background:var(--coar-surface-input-disabled);cursor:not-allowed;opacity:.6}.coar-date-picker-trigger--readonly{cursor:default}.coar-date-picker-trigger--error{border-color:var(--coar-border-semantic-error-bold)}.coar-date-picker-trigger--error:focus,.coar-date-picker-trigger--error.coar-date-picker-trigger--open{box-shadow:inset 0 0 0 1px var(--coar-border-semantic-error-bold)}:host(.coar-date-picker--xs) .coar-date-picker-trigger{height:var(--coar-component-xs-height);padding:0 var(--coar-spacing-s);gap:var(--coar-spacing-xs)}:host(.coar-date-picker--sm) .coar-date-picker-trigger{height:var(--coar-component-sm-height);padding:0 var(--coar-spacing-s)}:host(.coar-date-picker--lg) .coar-date-picker-trigger{height:var(--coar-component-lg-height);padding:0 var(--coar-spacing-l)}.coar-date-picker-input{flex:1;min-width:0;height:100%;padding:0;border:none;background:transparent;font-family:var(--coar-body-small-base-family);font-size:var(--coar-body-small-base-size);color:var(--coar-text-neutral-primary);outline:none;cursor:text;text-align:right}.coar-date-picker-input::selection{text-align:right}.coar-date-picker-input::placeholder{color:var(--coar-text-neutral-tertiary)}.coar-date-picker-input:disabled{cursor:not-allowed;color:var(--coar-text-neutral-disabled)}.coar-date-picker-input:read-only{cursor:default}:host(.coar-date-picker--xs) .coar-date-picker-input{font-size:var(--coar-component-xs-font-size)}:host(.coar-date-picker--sm) .coar-date-picker-input{font-size:var(--coar-component-sm-font-size)}:host(.coar-date-picker--lg) .coar-date-picker-input{font-size:var(--coar-component-lg-font-size)}.coar-date-picker-clear{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--coar-spacing-s);color:var(--coar-icon-neutral-disabled);cursor:pointer;transition:color .15s ease,opacity .15s ease;opacity:.4}.coar-date-picker-clear--hidden{opacity:0;pointer-events:none}.coar-date-picker-trigger:hover .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}:host(.coar-date-picker--open) .coar-date-picker-clear:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-tertiary)}.coar-date-picker-clear:hover:not(.coar-date-picker-clear--hidden){opacity:1;color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn{display:flex;align-items:center;justify-content:center;padding:0;margin-right:var(--coar-spacing-s);border:none;background:transparent;color:var(--coar-icon-neutral-secondary);cursor:pointer;transition:color .15s ease}.coar-date-picker-calendar-btn:hover:not(:disabled){color:var(--coar-icon-neutral-primary)}.coar-date-picker-calendar-btn:disabled{cursor:not-allowed;color:var(--coar-icon-neutral-disabled)}.coar-date-picker-calendar-host{display:block;border:1px solid var(--coar-border-neutral);border-radius:var(--coar-radius-s);box-shadow:var(--coar-shadow-m)}.coar-date-picker-message{margin-top:var(--coar-spacing-xs);font-family:var(--coar-body-caption-family);font-size:var(--coar-body-caption-size);color:var(--coar-text-neutral-secondary)}.coar-date-picker-message--error{color:var(--coar-text-semantic-error-bold)}\n"] }]
4817
4819
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], dateFormatConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormatConfig", required: false }] }], showTodayButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTodayButton", required: false }] }], showWeekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWeekNumbers", required: false }] }], highlightWeekends: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightWeekends", required: false }] }], markers: [{ type: i0.Input, args: [{ isSignal: true, alias: "markers", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], inputRef: [{ type: i0.ViewChild, args: ['dateInput', { isSignal: true }] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], calendarTemplateRef: [{ type: i0.ViewChild, args: ['calendarTemplate', { isSignal: true }] }] } });
4818
4820
 
4819
4821
  /**
4820
4822
  * Generated bundle index. Do not edit.
4821
4823
  */
4822
4824
 
4823
- export { COAR_BUILTIN_ICON_SOURCE_KEY, COAR_DEFAULT_ICON_SOURCE_KEY, COAR_ICON_SOURCE_ENTRY, CoarBadgeComponent, CoarButtonComponent, CoarCardComponent, CoarCheckboxComponent, CoarCodeBlockComponent, CoarControlValueAccessor, CoarDatePickerComponent, CoarDividerComponent, CoarIconComponent, CoarIconService, CoarLabelComponent, CoarMultiSelectComponent, CoarNoteComponent, CoarNumberInputComponent, CoarPasswordInputComponent, CoarPopoverComponent, CoarPopoverGroupService, CoarScrollbarDirective, CoarSidebarComponent, CoarSingleSelectComponent, CoarTabComponent, CoarTabGroupComponent, CoarTableComponent, CoarTagComponent, CoarTagSelectComponent, CoarTextInputComponent, CoarTooltipDirective, coarProvideValueAccessor, provideCoarDefaultIconSource, provideCoarHttpIconSource, provideCoarIconBuiltInOverrides, provideCoarIconMapSource, provideCoarIconSource };
4825
+ export { COAR_BUILTIN_ICON_SOURCE_KEY, COAR_DEFAULT_ICON_SOURCE_KEY, COAR_ICON_SOURCE_ENTRY, CoarBadgeComponent, CoarButtonComponent, CoarCardComponent, CoarCheckboxComponent, CoarCodeBlockComponent, CoarControlValueAccessor, CoarDatePickerComponent, CoarDividerComponent, CoarIconComponent, CoarIconService, CoarLabelComponent, CoarMiniCalendarComponent, CoarMultiSelectComponent, CoarNoteComponent, CoarNumberInputComponent, CoarPasswordInputComponent, CoarPopoverComponent, CoarPopoverGroupService, CoarScrollbarDirective, CoarSidebarComponent, CoarSingleSelectComponent, CoarTabComponent, CoarTabGroupComponent, CoarTableComponent, CoarTagComponent, CoarTagSelectComponent, CoarTextInputComponent, CoarTooltipDirective, coarCalculateIsoWeekNumber, coarClampPlainDate, coarDetectDateFormatPatternFromIntl, coarFormatPlainDate, coarGetCalendarGridDates, coarGetDateSeparatorForPattern, coarGetLocalizedWeekdays, coarParsePlainDateFromInput, coarProvideValueAccessor, coarTemporalPlainDateToDate, provideCoarDefaultIconSource, provideCoarHttpIconSource, provideCoarIconBuiltInOverrides, provideCoarIconMapSource, provideCoarIconSource };
4824
4826
  //# sourceMappingURL=cocoar-ui-components.mjs.map