@nanahoshi/mona-ui 0.24.5 → 0.24.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/README.md +2 -0
  2. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +196 -137
  3. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +164 -3
  4. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +124 -140
  5. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +205 -202
  6. package/fesm2022/nanahoshi-mona-ui-filter.mjs +1 -1
  7. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-row.component-BMCM0W8s.mjs → nanahoshi-mona-ui-grid-grid-footer-row.component-CD_ODHpU.mjs} +2 -2
  8. package/fesm2022/{nanahoshi-mona-ui-grid-grid-list.component-BSlV8Sua.mjs → nanahoshi-mona-ui-grid-grid-list.component-0jN7I1jo.mjs} +4 -4
  9. package/fesm2022/{nanahoshi-mona-ui-grid-grid-row.component-CTOdnH29.mjs → nanahoshi-mona-ui-grid-grid-row.component-BI_iE7pl.mjs} +3 -3
  10. package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-C2kf5MwO.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-Sa1aAtJ-.mjs} +4 -4
  11. package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-Dh42tUui.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-BvUM9nPt.mjs} +8 -8
  12. package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
  13. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +195 -122
  14. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +149 -167
  15. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +182 -137
  16. package/package.json +2 -2
  17. package/types/nanahoshi-mona-ui-calendar.d.ts +30 -11
  18. package/types/nanahoshi-mona-ui-date-input.d.ts +74 -3
  19. package/types/nanahoshi-mona-ui-date-picker.d.ts +61 -33
  20. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +79 -38
  21. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +57 -16
  22. package/types/nanahoshi-mona-ui-time-picker.d.ts +72 -42
  23. package/types/nanahoshi-mona-ui-time-selector.d.ts +78 -46
@@ -1,19 +1,17 @@
1
1
  import { CdkTrapFocus } from '@angular/cdk/a11y';
2
2
  import { NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, DestroyRef, ElementRef, computed, linkedSignal, contentChild, viewChild, TemplateRef, output, input, model, effect, untracked, afterNextRender, forwardRef, Component } from '@angular/core';
4
+ import { inject, DestroyRef, ElementRef, computed, contentChild, viewChild, TemplateRef, input, output, booleanAttribute, model, effect, untracked, afterNextRender, forwardRef, Component } from '@angular/core';
5
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { any } from '@mirei/ts-collections';
7
6
  import { LucideCalendar } from '@lucide/angular';
8
7
  import { ButtonDirective } from '@nanahoshi/mona-ui/button';
9
8
  import { CalendarDecadeCellTemplateDirective, CalendarMonthCellTemplateDirective, CalendarYearCellTemplateDirective, CalendarComponent } from '@nanahoshi/mona-ui/calendar';
10
- import { CalendarService, datePopupThemeVariants, DateInputPrefixTemplateDirective } from '@nanahoshi/mona-ui/date-input';
9
+ import { CalendarService, datePopupThemeVariants, DateInputPrefixTemplateDirective, createTypedDateInput } from '@nanahoshi/mona-ui/date-input';
11
10
  import * as i1 from '@nanahoshi/mona-ui/dropdowns';
12
11
  import { DropdownService, DROPDOWN_POPUP_INPUT_TOKEN, DropdownPopupHandlerDirective } from '@nanahoshi/mona-ui/dropdowns';
13
- import { MonaI18nService, gregorianDateTime, getLocaleDateInputFormat, parseGregorianDate } from '@nanahoshi/mona-ui/i18n';
12
+ import { MonaI18nService, getLocaleDateInputFormat } from '@nanahoshi/mona-ui/i18n';
14
13
  import { themeControlSurfaceClasses, createElementControlId } from '@nanahoshi/mona-ui/internal';
15
14
  import { TextBoxComponent, TextBoxSuffixTemplateDirective, TextBoxPrefixTemplateDirective } from '@nanahoshi/mona-ui/text-box';
16
- import { fromEvent } from 'rxjs';
17
15
  import { twMerge } from 'tailwind-merge';
18
16
  import { cva } from 'class-variance-authority';
19
17
 
@@ -84,14 +82,12 @@ class DatePickerComponent {
84
82
  #dropdownService;
85
83
  #hostElementRef;
86
84
  #i18n;
87
- #id;
88
85
  constructor() {
89
86
  this.#calendarService = inject(CalendarService);
90
87
  this.#destroyRef = inject(DestroyRef);
91
88
  this.#dropdownService = inject(DropdownService);
92
89
  this.#hostElementRef = inject(ElementRef);
93
90
  this.#i18n = inject(MonaI18nService);
94
- this.#id = createElementControlId();
95
91
  this.baseClass = computed(() => {
96
92
  const focused = this.#dropdownService.popupRef() != null;
97
93
  const rounded = this.rounded();
@@ -101,16 +97,6 @@ class DatePickerComponent {
101
97
  return twMerge(variantClass, userClass);
102
98
  }, /* @ts-ignore */
103
99
  ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
104
- this.currentDateString = linkedSignal(() => {
105
- const value = this.value();
106
- const format = this.effectiveFormat();
107
- const locale = this.#i18n.localeId();
108
- if (!value) {
109
- return "";
110
- }
111
- return gregorianDateTime(value, locale).toFormat(format);
112
- }, /* @ts-ignore */
113
- ...(ngDevMode ? [{ debugName: "currentDateString" }] : /* istanbul ignore next */ []));
114
100
  this.decadeCellTemplate = contentChild(CalendarDecadeCellTemplateDirective, /* @ts-ignore */
115
101
  ...(ngDevMode ? [{ debugName: "decadeCellTemplate" }] : /* istanbul ignore next */ []));
116
102
  this.effectiveFormat = computed(() => {
@@ -120,30 +106,24 @@ class DatePickerComponent {
120
106
  this.expanded = computed(() => this.#dropdownService.popupRef() !== null, /* @ts-ignore */
121
107
  ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
122
108
  this.inputAttributes = computed(() => {
123
- const controls = this.popupId;
124
- const expanded = this.#dropdownService.popupRef() != null;
125
- const hasPopup = "grid";
126
- const invalid = this.invalidState();
127
109
  return {
128
110
  "aria-autocomplete": "none",
129
- "aria-controls": controls,
130
- "aria-expanded": expanded,
131
- "aria-haspopup": hasPopup,
132
- "aria-invalid": invalid,
133
- id: this.#id,
111
+ "aria-controls": this.popupId,
112
+ // The binder drops `false`, and a combobox must always say whether it's expanded.
113
+ "aria-expanded": this.expanded() ? "true" : "false",
114
+ "aria-haspopup": "dialog",
134
115
  // The text box hides its clear button when read-only, so typing is blocked here instead.
135
116
  readonly: this.readonly() || this.readonlyInput(),
136
117
  role: "combobox"
137
118
  };
138
119
  }, /* @ts-ignore */
139
120
  ...(ngDevMode ? [{ debugName: "inputAttributes" }] : /* istanbul ignore next */ []));
140
- this.invalidState = computed(() => this.touched() && (this.invalid() || (this.required() && !this.value())), /* @ts-ignore */
121
+ this.invalidState = computed(() => this.typedInput.errors().length > 0 ||
122
+ (this.touched() && (this.invalid() || (this.required() && !this.value()))), /* @ts-ignore */
141
123
  ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
142
124
  this.messages = this.#i18n.componentMessages("datePicker", DATE_PICKER_DEFAULT_MESSAGES);
143
125
  this.monthCellTemplate = contentChild(CalendarMonthCellTemplateDirective, /* @ts-ignore */
144
126
  ...(ngDevMode ? [{ debugName: "monthCellTemplate" }] : /* istanbul ignore next */ []));
145
- this.navigatedDate = linkedSignal(() => this.value() ?? new Date(), /* @ts-ignore */
146
- ...(ngDevMode ? [{ debugName: "navigatedDate" }] : /* istanbul ignore next */ []));
147
127
  this.pickerPopupClass = computed(() => {
148
128
  const rounded = this.rounded();
149
129
  const size = this.size();
@@ -158,6 +138,22 @@ class DatePickerComponent {
158
138
  this.prefixTemplate = contentChild(DateInputPrefixTemplateDirective, { ...(ngDevMode ? { debugName: "prefixTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
159
139
  this.yearCellTemplate = contentChild(CalendarYearCellTemplateDirective, /* @ts-ignore */
160
140
  ...(ngDevMode ? [{ debugName: "yearCellTemplate" }] : /* istanbul ignore next */ []));
141
+ /**
142
+ * @description Id of an element that describes the input, such as a hint or an error message.
143
+ * @default ""
144
+ */
145
+ this.ariaDescribedBy = input("", { ...(ngDevMode ? { debugName: "ariaDescribedBy" } : /* istanbul ignore next */ {}), alias: "aria-describedby" });
146
+ /**
147
+ * @description Accessible name of the input. Prefer a visible label, linked through {@link inputId} or
148
+ * {@link ariaLabelledBy}; the placeholder is not a label.
149
+ * @default ""
150
+ */
151
+ this.ariaLabel = input("", { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
152
+ /**
153
+ * @description Id of the element that labels the input.
154
+ * @default ""
155
+ */
156
+ this.ariaLabelledBy = input("", { ...(ngDevMode ? { debugName: "ariaLabelledBy" } : /* istanbul ignore next */ {}), alias: "aria-labelledby" });
161
157
  /**
162
158
  * @description Emits when the popup is about to close. This event is preventable.
163
159
  */
@@ -169,12 +165,13 @@ class DatePickerComponent {
169
165
  this.closed = output();
170
166
  /**
171
167
  * @description Sets the disabled state of the date picker.
168
+ * @default false
172
169
  */
173
- this.disabled = input(false, /* @ts-ignore */
174
- ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
170
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
175
171
  /**
176
172
  * @description Sets the disabled dates of the date picker.
177
- * Accepts either an iterable of Date objects or a predicate function.
173
+ * Accepts either an iterable of Date objects or a predicate function. Typing a disabled date is reported as a
174
+ * `disabledDate` error instead of setting the value.
178
175
  */
179
176
  this.disabledDates = input(/* @ts-ignore */
180
177
  ...(ngDevMode ? [undefined, { debugName: "disabledDates" }] : /* istanbul ignore next */ []));
@@ -186,23 +183,30 @@ class DatePickerComponent {
186
183
  ...(ngDevMode ? [{ debugName: "firstDay" }] : /* istanbul ignore next */ []));
187
184
  /**
188
185
  * @description Sets the date format of the date picker. If not specified, derives from the active locale.
186
+ * Typed text is also accepted with one-digit days and months and a two-digit year.
189
187
  * @default null
190
188
  */
191
189
  this.format = input(null, /* @ts-ignore */
192
190
  ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
191
+ /**
192
+ * @description Id of the inner `<input>` element. Point a `<label for>` or `<mona-label for>` at it to label the
193
+ * date picker. A unique id is generated when it isn't set.
194
+ * @default generated
195
+ */
196
+ this.inputId = input(createElementControlId(), /* @ts-ignore */
197
+ ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
193
198
  /**
194
199
  * @description Marks the date picker as invalid. When bound to a signal form field via `[formField]`,
195
200
  * this is written by the `FormField` directive.
196
201
  * @default false
197
202
  */
198
- this.invalid = input(false, /* @ts-ignore */
199
- ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
203
+ this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
200
204
  /**
201
- * @description Sets the maximum date of the date picker.
205
+ * @description Sets the maximum date of the date picker. A later typed date is reported as a `maxDate` error.
202
206
  */
203
207
  this.max = input(undefined, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: value => (value instanceof Date ? value : undefined) });
204
208
  /**
205
- * @description Sets the minimum date of the date picker.
209
+ * @description Sets the minimum date of the date picker. An earlier typed date is reported as a `minDate` error.
206
210
  */
207
211
  this.min = input(undefined, { ...(ngDevMode ? { debugName: "min" } : /* istanbul ignore next */ {}), transform: value => (value instanceof Date ? value : undefined) });
208
212
  /**
@@ -225,52 +229,50 @@ class DatePickerComponent {
225
229
  this.popupClass = input("", /* @ts-ignore */
226
230
  ...(ngDevMode ? [{ debugName: "popupClass" }] : /* istanbul ignore next */ []));
227
231
  /**
228
- * @description Sets the height of the popup element.
229
- * @default 200
232
+ * @description Sets the height of the popup element. When empty, the popup fits the calendar.
233
+ * @default ""
230
234
  */
231
235
  this.popupHeight = input("", /* @ts-ignore */
232
236
  ...(ngDevMode ? [{ debugName: "popupHeight" }] : /* istanbul ignore next */ []));
233
237
  /**
234
- * @description Sets the width of the popup element.
235
- * @default null
238
+ * @description Sets the width of the popup element. When empty, the popup fits the calendar.
239
+ * @default ""
236
240
  */
237
241
  this.popupWidth = input("", /* @ts-ignore */
238
242
  ...(ngDevMode ? [{ debugName: "popupWidth" }] : /* istanbul ignore next */ []));
239
243
  /**
240
244
  * @description Sets the readonly state of the date picker.
245
+ * @default false
241
246
  */
242
- this.readonly = input(false, /* @ts-ignore */
243
- ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
247
+ this.readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
244
248
  /**
245
249
  * @description When true, the input is readonly but the calendar button remains enabled.
246
250
  * @default false
247
251
  */
248
- this.readonlyInput = input(false, /* @ts-ignore */
249
- ...(ngDevMode ? [{ debugName: "readonlyInput" }] : /* istanbul ignore next */ []));
252
+ this.readonlyInput = input(false, { ...(ngDevMode ? { debugName: "readonlyInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
250
253
  /**
251
254
  * @description Sets the required state of the date picker.
252
255
  * When bound to a signal form field via `[formField]`, this is written by the `FormField` directive.
253
256
  * @default false
254
257
  */
255
- this.required = input(false, /* @ts-ignore */
256
- ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
258
+ this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
257
259
  /**
258
260
  * @description Sets the border radius of the date picker.
259
261
  */
260
262
  this.rounded = input("medium", /* @ts-ignore */
261
263
  ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
262
264
  /**
263
- * @description Sets the visibility of the clear button.
265
+ * @description Sets the visibility of the clear button. Clearing empties the value at once.
266
+ * @default false
264
267
  */
265
- this.showClearButton = input(false, /* @ts-ignore */
266
- ...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []));
268
+ this.showClearButton = input(false, { ...(ngDevMode ? { debugName: "showClearButton" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
267
269
  /**
268
270
  * @description Sets the size of the date picker.
269
271
  */
270
272
  this.size = input("medium", /* @ts-ignore */
271
273
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
272
274
  /**
273
- * @description Emitted when the date picker is interacted with via blur, selection, or clear.
275
+ * @description Emitted when focus leaves the date picker and its popup.
274
276
  * The `FormField` directive listens to this to mark the field as touched.
275
277
  */
276
278
  this.touch = output();
@@ -279,11 +281,11 @@ class DatePickerComponent {
279
281
  * this is written by the `FormField` directive.
280
282
  * @default false
281
283
  */
282
- this.touched = input(false, /* @ts-ignore */
283
- ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
284
+ this.touched = input(false, { ...(ngDevMode ? { debugName: "touched" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
284
285
  this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
285
286
  /**
286
- * @description Two-way bindable current date value.
287
+ * @description Two-way bindable current date value. Typed text is written on Enter and when the input loses
288
+ * focus; text that isn't a valid date keeps the previous value and marks the field invalid.
287
289
  * @default null
288
290
  */
289
291
  this.value = model(null, /* @ts-ignore */
@@ -292,60 +294,39 @@ class DatePickerComponent {
292
294
  * @description Enables the display of week numbers in the calendar.
293
295
  * @default false
294
296
  */
295
- this.weekNumber = input(false, /* @ts-ignore */
296
- ...(ngDevMode ? [{ debugName: "weekNumber" }] : /* istanbul ignore next */ []));
297
+ this.weekNumber = input(false, { ...(ngDevMode ? { debugName: "weekNumber" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
298
+ this.typedInput = createTypedDateInput({
299
+ constraints: () => ({ disabledDates: this.disabledDates(), max: this.max(), min: this.min(), unit: "date" }),
300
+ format: () => this.effectiveFormat(),
301
+ localeId: () => this.#i18n.localeId(),
302
+ value: this.value
303
+ });
297
304
  effect(() => {
298
305
  const popupTemplate = this.popupTemplate();
299
306
  untracked(() => this.#dropdownService.popupTemplate.set(popupTemplate));
300
307
  });
301
308
  afterNextRender({
302
309
  read: () => {
303
- this.setSubscriptions();
304
- this.setPopupCloseSubscriptions();
310
+ this.setCalendarKeyboardSubscription();
311
+ this.setPopupCloseSubscription();
305
312
  }
306
313
  });
307
314
  }
308
- focus() {
315
+ /**
316
+ * Focuses the input and places the caret after the text. Read-only pickers take focus too.
317
+ * @param options Options passed to the native `focus()` call, such as `preventScroll`.
318
+ */
319
+ focus(options) {
309
320
  const input = this.#hostElementRef.nativeElement.querySelector("input");
310
- if (input && !this.readonly()) {
311
- input.focus();
321
+ if (input) {
322
+ input.focus(options);
312
323
  input.setSelectionRange(input.value.length, input.value.length);
313
324
  }
314
325
  }
315
326
  onCalendarValueChange(date) {
316
327
  const singleDate = Array.isArray(date) ? null : date;
317
- this.setCurrentDate(singleDate);
318
- this.#dropdownService.popupRef()?.close();
319
- }
320
- onDateInputBlur() {
321
- if (this.#dropdownService.popupRef()) {
322
- this.touch.emit();
323
- return;
324
- }
325
- if (!this.currentDateString() && this.value()) {
326
- this.setCurrentDate(null);
327
- this.touch.emit();
328
- return;
329
- }
330
- const locale = this.#i18n.localeId();
331
- const dateTime = parseGregorianDate(this.currentDateString(), this.effectiveFormat(), locale);
332
- if (this.dateStringEquals(this.value(), dateTime.toJSDate())) {
333
- this.touch.emit();
334
- return;
335
- }
336
- if (dateTime.isValid) {
337
- const value = this.value();
338
- if (value && gregorianDateTime(value, locale).equals(dateTime)) {
339
- this.touch.emit();
340
- return;
341
- }
342
- this.setCurrentDate(dateTime.toJSDate());
343
- }
344
- else {
345
- this.setCurrentDate(null);
346
- this.currentDateString.set("");
347
- }
348
- this.touch.emit();
328
+ this.value.set(singleDate ? new Date(singleDate) : null);
329
+ this.closePopup();
349
330
  }
350
331
  onDateInputButtonClick() {
351
332
  const popupRef = this.#dropdownService.popupRef();
@@ -358,26 +339,30 @@ class DatePickerComponent {
358
339
  }
359
340
  this.openPopup();
360
341
  }
361
- onDateStringEdit(dateString) {
362
- this.currentDateString.set(dateString);
363
- }
364
- closePopup() {
365
- this.#dropdownService.popupRef()?.close();
366
- }
367
- compareDatesEqual(date1, date2) {
368
- return (date1.getFullYear() === date2.getFullYear() &&
369
- date1.getMonth() === date2.getMonth() &&
370
- date1.getDate() === date2.getDate());
342
+ onFocusIn(event) {
343
+ // The host is focusable only to pass focus on; focus inside it, such as a click in the text, stays put.
344
+ if (event.target === this.#hostElementRef.nativeElement) {
345
+ this.focus();
346
+ }
371
347
  }
372
- dateStringEquals(date1, date2) {
373
- if (date1 && date2) {
374
- const locale = this.#i18n.localeId();
375
- return (gregorianDateTime(date1, locale).toFormat(this.effectiveFormat()) ===
376
- gregorianDateTime(date2, locale).toFormat(this.effectiveFormat()));
348
+ onFocusOut(event) {
349
+ // Removing a focused picker from the page fires focusout after it is destroyed.
350
+ if (this.#destroyRef.destroyed) {
351
+ return;
377
352
  }
378
- return date1 === date2;
353
+ const nextTarget = event.relatedTarget;
354
+ if (nextTarget instanceof Node) {
355
+ const popupElement = this.#dropdownService.popupRef()?.overlayRef.overlayElement;
356
+ if (this.#hostElementRef.nativeElement.contains(nextTarget) || popupElement?.contains(nextTarget)) {
357
+ return;
358
+ }
359
+ }
360
+ this.touch.emit();
361
+ }
362
+ onInputBlur() {
363
+ this.typedInput.commit();
379
364
  }
380
- handleKeydown(event) {
365
+ onKeydown(event) {
381
366
  if (this.disabled() || this.readonly()) {
382
367
  return;
383
368
  }
@@ -386,18 +371,20 @@ class DatePickerComponent {
386
371
  this.openPopup();
387
372
  }
388
373
  else if ((event.altKey && event.key === "ArrowUp") || event.key === "Escape") {
389
- event.preventDefault();
390
- this.closePopup();
391
- }
392
- }
393
- isDateDisabledByInput(date, disabledDates) {
394
- if (typeof disabledDates === "function") {
395
- return disabledDates(date);
374
+ if (this.expanded()) {
375
+ event.preventDefault();
376
+ this.closePopup();
377
+ }
396
378
  }
397
- else if (disabledDates) {
398
- return any(disabledDates, d => this.compareDatesEqual(date, d));
379
+ else if (event.key === "Enter" && event.target instanceof HTMLInputElement) {
380
+ // Committed before a surrounding form submits; an IME uses Enter to confirm its text.
381
+ if (!event.isComposing && event.keyCode !== 229) {
382
+ this.typedInput.commit();
383
+ }
399
384
  }
400
- return false;
385
+ }
386
+ closePopup() {
387
+ this.#dropdownService.popupRef()?.close();
401
388
  }
402
389
  openPopup() {
403
390
  if (!this.#dropdownService.popupRef()) {
@@ -410,15 +397,7 @@ class DatePickerComponent {
410
397
  });
411
398
  }
412
399
  }
413
- setCurrentDate(date) {
414
- const newDate = date ? new Date(date) : null;
415
- this.value.set(newDate);
416
- this.touch.emit();
417
- }
418
- setKeyboardSubscriptions() {
419
- fromEvent(this.#hostElementRef.nativeElement, "keydown")
420
- .pipe(takeUntilDestroyed(this.#destroyRef))
421
- .subscribe(event => this.handleKeydown(event));
400
+ setCalendarKeyboardSubscription() {
422
401
  this.#calendarService.keydown$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(event => {
423
402
  const keyboardEvent = event.originalEvent;
424
403
  if (keyboardEvent &&
@@ -428,21 +407,19 @@ class DatePickerComponent {
428
407
  }
429
408
  });
430
409
  }
431
- setPopupCloseSubscriptions() {
410
+ setPopupCloseSubscription() {
432
411
  this.#dropdownService.popupCloseComplete$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(() => {
433
412
  if (this.#dropdownService.focusCanReturn()) {
434
413
  this.focus();
435
414
  }
415
+ else if (!this.#destroyRef.destroyed) {
416
+ // Focus left from inside the popup, which the host's focusout doesn't see.
417
+ this.touch.emit();
418
+ }
436
419
  });
437
420
  }
438
- setSubscriptions() {
439
- fromEvent(this.#hostElementRef.nativeElement, "focusin")
440
- .pipe(takeUntilDestroyed(this.#destroyRef))
441
- .subscribe(() => this.focus());
442
- this.setKeyboardSubscriptions();
443
- }
444
421
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
445
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: DatePickerComponent, isStandalone: true, selector: "mona-date-picker", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null }, firstDay: { classPropertyName: "firstDay", publicName: "firstDay", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, popupClass: { classPropertyName: "popupClass", publicName: "popupClass", isSignal: true, isRequired: false, transformFunction: null }, popupHeight: { classPropertyName: "popupHeight", publicName: "popupHeight", isSignal: true, isRequired: false, transformFunction: null }, popupWidth: { classPropertyName: "popupWidth", publicName: "popupWidth", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, readonlyInput: { classPropertyName: "readonlyInput", publicName: "readonlyInput", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showClearButton: { classPropertyName: "showClearButton", publicName: "showClearButton", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, weekNumber: { classPropertyName: "weekNumber", publicName: "weekNumber", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", closed: "closed", open: "open", opened: "opened", touch: "touch", value: "valueChange" }, host: { properties: { "attr.tabindex": "disabled() ? null : -1", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.data-disabled": "disabled() || null", "attr.data-expanded": "expanded()", "attr.data-invalid": "invalidState() || null", "attr.data-readonly": "readonly() || null", "class": "baseClass()" } }, providers: [
422
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: DatePickerComponent, isStandalone: true, selector: "mona-date-picker", inputs: { ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null }, firstDay: { classPropertyName: "firstDay", publicName: "firstDay", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, popupClass: { classPropertyName: "popupClass", publicName: "popupClass", isSignal: true, isRequired: false, transformFunction: null }, popupHeight: { classPropertyName: "popupHeight", publicName: "popupHeight", isSignal: true, isRequired: false, transformFunction: null }, popupWidth: { classPropertyName: "popupWidth", publicName: "popupWidth", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, readonlyInput: { classPropertyName: "readonlyInput", publicName: "readonlyInput", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showClearButton: { classPropertyName: "showClearButton", publicName: "showClearButton", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, weekNumber: { classPropertyName: "weekNumber", publicName: "weekNumber", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", closed: "closed", open: "open", opened: "opened", touch: "touch", value: "valueChange" }, host: { listeners: { "focusin": "onFocusIn($event)", "focusout": "onFocusOut($event)", "keydown": "onKeydown($event)" }, properties: { "attr.aria-describedby": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.tabindex": "disabled() ? null : -1", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.data-disabled": "disabled() || null", "attr.data-expanded": "expanded()", "attr.data-invalid": "invalidState() || null", "attr.data-readonly": "readonly() || null", "class": "baseClass()" } }, providers: [
446
423
  DropdownService,
447
424
  CalendarService,
448
425
  {
@@ -450,7 +427,7 @@ class DatePickerComponent {
450
427
  useExisting: forwardRef(() => DatePickerComponent),
451
428
  multi: false
452
429
  }
453
- ], queries: [{ propertyName: "decadeCellTemplate", first: true, predicate: CalendarDecadeCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "monthCellTemplate", first: true, predicate: CalendarMonthCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "prefixTemplate", first: true, predicate: DateInputPrefixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "yearCellTemplate", first: true, predicate: CalendarYearCellTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.DropdownPopupHandlerDirective }], ngImport: i0, template: "<mona-text-box\n (inputBlur)=\"onDateInputBlur()\"\n (valueChange)=\"onDateStringEdit($event)\"\n [disabled]=\"disabled()\"\n [value]=\"currentDateString()\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [inputAttributes]=\"inputAttributes()\"\n [invalid]=\"invalid()\"\n [required]=\"required()\"\n [clearButton]=\"showClearButton()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [touched]=\"touched()\">\n @if (prefixTemplate()) {\n <ng-template monaTextBoxPrefixTemplate>\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </ng-template>\n }\n <ng-template monaTextBoxSuffixTemplate>\n <button\n monaButton\n look=\"ghost\"\n [iconOnly]=\"true\"\n [rounded]=\"'none'\"\n [size]=\"size()\"\n class=\"aspect-square h-full w-auto\"\n [attr.aria-label]=\"messages().openCalendar\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"popupId\"\n [disabled]=\"disabled() || readonly()\"\n [tabindex]=\"-1\"\n (click)=\"onDateInputButtonClick()\">\n <svg lucideCalendar [size]=\"16\" aria-hidden=\"true\"></svg>\n </button>\n </ng-template>\n</mona-text-box>\n\n<ng-template #popupTemplate>\n <div\n [class]=\"pickerPopupClass()\"\n [id]=\"popupId\"\n aria-modal=\"true\"\n role=\"dialog\"\n [attr.aria-label]=\"messages().datePicker\"\n cdkTrapFocus>\n <mona-calendar\n [disabledDates]=\"disabledDates()\"\n [minDate]=\"min()\"\n [maxDate]=\"max()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [weekNumber]=\"weekNumber()\"\n [firstDay]=\"firstDay()\"\n [value]=\"value()\"\n (valueChange)=\"onCalendarValueChange($event)\">\n @if (decadeCellTemplate()) {\n <ng-template monaCalendarDecadeCellTemplate let-year>\n <ng-container\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year }\"></ng-container>\n </ng-template>\n }\n @if (monthCellTemplate()) {\n <ng-template monaCalendarMonthCellTemplate let-day let-date=\"date\">\n <ng-container\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: day, date }\"></ng-container>\n </ng-template>\n }\n @if (yearCellTemplate()) {\n <ng-template monaCalendarYearCellTemplate let-year let-text=\"text\">\n <ng-container\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year, text }\"></ng-container>\n </ng-template>\n }\n </mona-calendar>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: LucideCalendar, selector: "svg[lucideCalendar]" }, { kind: "component", type: CalendarComponent, selector: "mona-calendar", inputs: ["disabled", "disabledDates", "firstDay", "invalid", "maxDate", "minDate", "readonly", "required", "rounded", "selection", "touched", "class", "value", "weekNumber"], outputs: ["disabledChange", "touch", "valueChange"] }, { kind: "component", type: TextBoxComponent, selector: "mona-text-box", inputs: ["aria-describedby", "aria-label", "aria-labelledby", "clearButton", "disabled", "inputAttributes", "inputClass", "inputId", "inputStyle", "invalid", "maxLength", "minLength", "name", "placeholder", "readonly", "required", "rounded", "size", "touched", "type", "class", "value"], outputs: ["inputBlur", "inputFocus", "touch", "valueChange"] }, { kind: "directive", type: TextBoxSuffixTemplateDirective, selector: "ng-template[monaTextBoxSuffixTemplate]" }, { kind: "directive", type: CalendarDecadeCellTemplateDirective, selector: "ng-template[monaCalendarDecadeCellTemplate]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CalendarMonthCellTemplateDirective, selector: "ng-template[monaCalendarMonthCellTemplate]" }, { kind: "directive", type: CalendarYearCellTemplateDirective, selector: "ng-template[monaCalendarYearCellTemplate]" }, { kind: "directive", type: TextBoxPrefixTemplateDirective, selector: "ng-template[monaTextBoxPrefixTemplate]" }, { kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "type", "class"], outputs: ["lookChange", "selectedChange"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] }); }
430
+ ], queries: [{ propertyName: "decadeCellTemplate", first: true, predicate: CalendarDecadeCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "monthCellTemplate", first: true, predicate: CalendarMonthCellTemplateDirective, descendants: true, isSignal: true }, { propertyName: "prefixTemplate", first: true, predicate: DateInputPrefixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "yearCellTemplate", first: true, predicate: CalendarYearCellTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.DropdownPopupHandlerDirective }], ngImport: i0, template: "<mona-text-box\n (inputBlur)=\"onInputBlur()\"\n (valueChange)=\"typedInput.edit($event)\"\n [aria-describedby]=\"ariaDescribedBy()\"\n [aria-label]=\"ariaLabel()\"\n [aria-labelledby]=\"ariaLabelledBy()\"\n [disabled]=\"disabled()\"\n [inputId]=\"inputId()\"\n [value]=\"typedInput.text()\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [inputAttributes]=\"inputAttributes()\"\n [invalid]=\"invalidState()\"\n [required]=\"required()\"\n [clearButton]=\"showClearButton()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [touched]=\"invalidState() || touched()\">\n @if (prefixTemplate()) {\n <ng-template monaTextBoxPrefixTemplate>\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </ng-template>\n }\n <ng-template monaTextBoxSuffixTemplate>\n <button\n monaButton\n look=\"ghost\"\n [iconOnly]=\"true\"\n [rounded]=\"'none'\"\n [size]=\"size()\"\n class=\"aspect-square h-full w-auto\"\n [attr.aria-label]=\"messages().openCalendar\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"popupId\"\n [disabled]=\"disabled() || readonly()\"\n [tabindex]=\"-1\"\n (click)=\"onDateInputButtonClick()\">\n <svg lucideCalendar [size]=\"16\" aria-hidden=\"true\"></svg>\n </button>\n </ng-template>\n</mona-text-box>\n\n<ng-template #popupTemplate>\n <div\n [class]=\"pickerPopupClass()\"\n [id]=\"popupId\"\n aria-modal=\"true\"\n role=\"dialog\"\n [attr.aria-label]=\"messages().datePicker\"\n cdkTrapFocus>\n <mona-calendar\n focusOnMount\n [disabledDates]=\"disabledDates()\"\n [minDate]=\"min()\"\n [maxDate]=\"max()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [weekNumber]=\"weekNumber()\"\n [firstDay]=\"firstDay()\"\n [value]=\"value()\"\n (valueChange)=\"onCalendarValueChange($event)\">\n @if (decadeCellTemplate()) {\n <ng-template monaCalendarDecadeCellTemplate let-year>\n <ng-container\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year }\"></ng-container>\n </ng-template>\n }\n @if (monthCellTemplate()) {\n <ng-template monaCalendarMonthCellTemplate let-day let-date=\"date\">\n <ng-container\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: day, date }\"></ng-container>\n </ng-template>\n }\n @if (yearCellTemplate()) {\n <ng-template monaCalendarYearCellTemplate let-year let-text=\"text\">\n <ng-container\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year, text }\"></ng-container>\n </ng-template>\n }\n </mona-calendar>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: LucideCalendar, selector: "svg[lucideCalendar]" }, { kind: "component", type: CalendarComponent, selector: "mona-calendar", inputs: ["disabled", "disabledDates", "firstDay", "focusOnMount", "invalid", "maxDate", "minDate", "readonly", "required", "rounded", "selection", "touched", "class", "value", "weekNumber"], outputs: ["touch", "valueChange"] }, { kind: "component", type: TextBoxComponent, selector: "mona-text-box", inputs: ["aria-describedby", "aria-label", "aria-labelledby", "clearButton", "disabled", "inputAttributes", "inputClass", "inputId", "inputStyle", "invalid", "maxLength", "minLength", "name", "placeholder", "readonly", "required", "rounded", "size", "touched", "type", "class", "value"], outputs: ["inputBlur", "inputFocus", "touch", "valueChange"] }, { kind: "directive", type: TextBoxSuffixTemplateDirective, selector: "ng-template[monaTextBoxSuffixTemplate]" }, { kind: "directive", type: CalendarDecadeCellTemplateDirective, selector: "ng-template[monaCalendarDecadeCellTemplate]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CalendarMonthCellTemplateDirective, selector: "ng-template[monaCalendarMonthCellTemplate]" }, { kind: "directive", type: CalendarYearCellTemplateDirective, selector: "ng-template[monaCalendarYearCellTemplate]" }, { kind: "directive", type: TextBoxPrefixTemplateDirective, selector: "ng-template[monaTextBoxPrefixTemplate]" }, { kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "type", "class"], outputs: ["lookChange", "selectedChange"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] }); }
454
431
  }
455
432
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DatePickerComponent, decorators: [{
456
433
  type: Component,
@@ -475,15 +452,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
475
452
  ButtonDirective,
476
453
  CdkTrapFocus
477
454
  ], hostDirectives: [DropdownPopupHandlerDirective], host: {
455
+ // The ARIA inputs below are applied to the inner input, so the host must not keep the static attributes.
456
+ "[attr.aria-describedby]": "null",
457
+ "[attr.aria-label]": "null",
458
+ "[attr.aria-labelledby]": "null",
478
459
  "[attr.tabindex]": "disabled() ? null : -1",
479
460
  "[attr.aria-invalid]": "invalidState() ? 'true' : null",
480
461
  "[attr.data-disabled]": "disabled() || null",
481
462
  "[attr.data-expanded]": "expanded()",
482
463
  "[attr.data-invalid]": "invalidState() || null",
483
464
  "[attr.data-readonly]": "readonly() || null",
484
- "[class]": "baseClass()"
485
- }, template: "<mona-text-box\n (inputBlur)=\"onDateInputBlur()\"\n (valueChange)=\"onDateStringEdit($event)\"\n [disabled]=\"disabled()\"\n [value]=\"currentDateString()\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [inputAttributes]=\"inputAttributes()\"\n [invalid]=\"invalid()\"\n [required]=\"required()\"\n [clearButton]=\"showClearButton()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [touched]=\"touched()\">\n @if (prefixTemplate()) {\n <ng-template monaTextBoxPrefixTemplate>\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </ng-template>\n }\n <ng-template monaTextBoxSuffixTemplate>\n <button\n monaButton\n look=\"ghost\"\n [iconOnly]=\"true\"\n [rounded]=\"'none'\"\n [size]=\"size()\"\n class=\"aspect-square h-full w-auto\"\n [attr.aria-label]=\"messages().openCalendar\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"popupId\"\n [disabled]=\"disabled() || readonly()\"\n [tabindex]=\"-1\"\n (click)=\"onDateInputButtonClick()\">\n <svg lucideCalendar [size]=\"16\" aria-hidden=\"true\"></svg>\n </button>\n </ng-template>\n</mona-text-box>\n\n<ng-template #popupTemplate>\n <div\n [class]=\"pickerPopupClass()\"\n [id]=\"popupId\"\n aria-modal=\"true\"\n role=\"dialog\"\n [attr.aria-label]=\"messages().datePicker\"\n cdkTrapFocus>\n <mona-calendar\n [disabledDates]=\"disabledDates()\"\n [minDate]=\"min()\"\n [maxDate]=\"max()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [weekNumber]=\"weekNumber()\"\n [firstDay]=\"firstDay()\"\n [value]=\"value()\"\n (valueChange)=\"onCalendarValueChange($event)\">\n @if (decadeCellTemplate()) {\n <ng-template monaCalendarDecadeCellTemplate let-year>\n <ng-container\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year }\"></ng-container>\n </ng-template>\n }\n @if (monthCellTemplate()) {\n <ng-template monaCalendarMonthCellTemplate let-day let-date=\"date\">\n <ng-container\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: day, date }\"></ng-container>\n </ng-template>\n }\n @if (yearCellTemplate()) {\n <ng-template monaCalendarYearCellTemplate let-year let-text=\"text\">\n <ng-container\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year, text }\"></ng-container>\n </ng-template>\n }\n </mona-calendar>\n </div>\n</ng-template>\n" }]
486
- }], ctorParameters: () => [], propDecorators: { decadeCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarDecadeCellTemplateDirective), { isSignal: true }] }], monthCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarMonthCellTemplateDirective), { isSignal: true }] }], popupTemplate: [{ type: i0.ViewChild, args: ["popupTemplate", { isSignal: true }] }], prefixTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DateInputPrefixTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], yearCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarYearCellTemplateDirective), { isSignal: true }] }], close: [{ type: i0.Output, args: ["close"] }], closed: [{ type: i0.Output, args: ["closed"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: false }] }], firstDay: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDay", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], open: [{ type: i0.Output, args: ["open"] }], opened: [{ type: i0.Output, args: ["opened"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], popupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupClass", required: false }] }], popupHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupHeight", required: false }] }], popupWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupWidth", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], readonlyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyInput", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], showClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearButton", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], weekNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumber", required: false }] }] } });
465
+ "[class]": "baseClass()",
466
+ "(focusin)": "onFocusIn($event)",
467
+ "(focusout)": "onFocusOut($event)",
468
+ "(keydown)": "onKeydown($event)"
469
+ }, template: "<mona-text-box\n (inputBlur)=\"onInputBlur()\"\n (valueChange)=\"typedInput.edit($event)\"\n [aria-describedby]=\"ariaDescribedBy()\"\n [aria-label]=\"ariaLabel()\"\n [aria-labelledby]=\"ariaLabelledBy()\"\n [disabled]=\"disabled()\"\n [inputId]=\"inputId()\"\n [value]=\"typedInput.text()\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [inputAttributes]=\"inputAttributes()\"\n [invalid]=\"invalidState()\"\n [required]=\"required()\"\n [clearButton]=\"showClearButton()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [touched]=\"invalidState() || touched()\">\n @if (prefixTemplate()) {\n <ng-template monaTextBoxPrefixTemplate>\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </ng-template>\n }\n <ng-template monaTextBoxSuffixTemplate>\n <button\n monaButton\n look=\"ghost\"\n [iconOnly]=\"true\"\n [rounded]=\"'none'\"\n [size]=\"size()\"\n class=\"aspect-square h-full w-auto\"\n [attr.aria-label]=\"messages().openCalendar\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"popupId\"\n [disabled]=\"disabled() || readonly()\"\n [tabindex]=\"-1\"\n (click)=\"onDateInputButtonClick()\">\n <svg lucideCalendar [size]=\"16\" aria-hidden=\"true\"></svg>\n </button>\n </ng-template>\n</mona-text-box>\n\n<ng-template #popupTemplate>\n <div\n [class]=\"pickerPopupClass()\"\n [id]=\"popupId\"\n aria-modal=\"true\"\n role=\"dialog\"\n [attr.aria-label]=\"messages().datePicker\"\n cdkTrapFocus>\n <mona-calendar\n focusOnMount\n [disabledDates]=\"disabledDates()\"\n [minDate]=\"min()\"\n [maxDate]=\"max()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [weekNumber]=\"weekNumber()\"\n [firstDay]=\"firstDay()\"\n [value]=\"value()\"\n (valueChange)=\"onCalendarValueChange($event)\">\n @if (decadeCellTemplate()) {\n <ng-template monaCalendarDecadeCellTemplate let-year>\n <ng-container\n [ngTemplateOutlet]=\"decadeCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year }\"></ng-container>\n </ng-template>\n }\n @if (monthCellTemplate()) {\n <ng-template monaCalendarMonthCellTemplate let-day let-date=\"date\">\n <ng-container\n [ngTemplateOutlet]=\"monthCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: day, date }\"></ng-container>\n </ng-template>\n }\n @if (yearCellTemplate()) {\n <ng-template monaCalendarYearCellTemplate let-year let-text=\"text\">\n <ng-container\n [ngTemplateOutlet]=\"yearCellTemplate()?.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: year, text }\"></ng-container>\n </ng-template>\n }\n </mona-calendar>\n </div>\n</ng-template>\n" }]
470
+ }], ctorParameters: () => [], propDecorators: { decadeCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarDecadeCellTemplateDirective), { isSignal: true }] }], monthCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarMonthCellTemplateDirective), { isSignal: true }] }], popupTemplate: [{ type: i0.ViewChild, args: ["popupTemplate", { isSignal: true }] }], prefixTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DateInputPrefixTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], yearCellTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CalendarYearCellTemplateDirective), { isSignal: true }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], closed: [{ type: i0.Output, args: ["closed"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: false }] }], firstDay: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDay", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], open: [{ type: i0.Output, args: ["open"] }], opened: [{ type: i0.Output, args: ["opened"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], popupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupClass", required: false }] }], popupHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupHeight", required: false }] }], popupWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupWidth", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], readonlyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyInput", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], showClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearButton", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], weekNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumber", required: false }] }] } });
487
471
 
488
472
  /*
489
473
  * Public API Surface of @nanahoshi/mona-ui/date-picker