@eagami/ui 5.35.0 → 5.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16764,9 +16764,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
16764
16764
  * configurable steps for minutes and seconds, optional seconds column, and
16765
16765
  * integrates with Angular forms via `ControlValueAccessor`.
16766
16766
  *
16767
- * Keyboard: Tab moves between the hour, minute, (seconds), and AM/PM columns.
16768
- * Each spinner accepts ArrowUp/ArrowDown to step by 1 (or by the configured
16769
- * step), PageUp/PageDown for a coarser bump, and digit keys to type a value
16767
+ * The field itself is a text input: a time can be typed by hand and is read
16768
+ * leniently on Enter or blur. Bare digits are a 24-hour clock ("5" is 05:00,
16769
+ * "1234" is 12:34, "123456" adds seconds), `:`, `.`, `h`, and spaces all
16770
+ * separate units ("17h30", "12.34"), and an AM/PM suffix reads the hour on
16771
+ * the 12-hour clock ("5pm" is 17:00). Text that parses to no time is
16772
+ * discarded and the field falls back to the current value; clearing the text
16773
+ * clears the value.
16774
+ *
16775
+ * Keyboard: ArrowDown opens the popover and moves into the hour column. Tab
16776
+ * moves between the hour, minute, (seconds), and AM/PM columns. Each spinner
16777
+ * accepts ArrowUp/ArrowDown to step by 1 (or by the configured step),
16778
+ * PageUp/PageDown for a coarser bump, and digit keys to type a value
16770
16779
  * directly. After typing two digits (or one digit that already maxes the
16771
16780
  * unit), focus auto-advances to the next column. Backspace clears the typed
16772
16781
  * buffer; Escape closes the popover.
@@ -16774,6 +16783,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
16774
16783
  class TimePickerComponent {
16775
16784
  triggerEl = viewChild('triggerEl', /* @ts-ignore */
16776
16785
  ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
16786
+ inputEl = viewChild('inputEl', /* @ts-ignore */
16787
+ ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
16777
16788
  hoursEl = viewChild('hoursEl', /* @ts-ignore */
16778
16789
  ...(ngDevMode ? [{ debugName: "hoursEl" }] : /* istanbul ignore next */ []));
16779
16790
  minutesEl = viewChild('minutesEl', /* @ts-ignore */
@@ -16822,6 +16833,9 @@ class TimePickerComponent {
16822
16833
  changed = output();
16823
16834
  isOpen = signal(false, /* @ts-ignore */
16824
16835
  ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
16836
+ /** Raw text under edit in the field, or `null` while it mirrors the value. */
16837
+ typedText = signal(null, /* @ts-ignore */
16838
+ ...(ngDevMode ? [{ debugName: "typedText" }] : /* istanbul ignore next */ []));
16825
16839
  /** Typed-digit buffer for the currently focused column, or `null` when idle. */
16826
16840
  editBuffer = signal(null, /* @ts-ignore */
16827
16841
  ...(ngDevMode ? [{ debugName: "editBuffer" }] : /* istanbul ignore next */ []));
@@ -16922,13 +16936,15 @@ class TimePickerComponent {
16922
16936
  ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
16923
16937
  resolvedPlaceholder = computed(() => this.placeholder() ?? this.i18n.messages().timePicker.placeholder, /* @ts-ignore */
16924
16938
  ...(ngDevMode ? [{ debugName: "resolvedPlaceholder" }] : /* istanbul ignore next */ []));
16939
+ /** What the field's input shows: the text mid-edit, else the formatted value. */
16940
+ triggerText = computed(() => this.typedText() ?? this.displayValue() ?? '', /* @ts-ignore */
16941
+ ...(ngDevMode ? [{ debugName: "triggerText" }] : /* istanbul ignore next */ []));
16925
16942
  triggerClasses = computed(() => ({
16926
16943
  [`ea-time-picker__trigger--${this.size()}`]: true,
16927
16944
  'ea-time-picker__trigger--error': this.hasError(),
16928
16945
  'ea-time-picker__trigger--open': this.isOpen(),
16929
16946
  'ea-time-picker__trigger--disabled': this.isDisabled(),
16930
16947
  'ea-time-picker__trigger--readonly': this.readonly() && !this.isDisabled(),
16931
- 'ea-time-picker__trigger--placeholder': !this.hasValue(),
16932
16948
  }), /* @ts-ignore */
16933
16949
  ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
16934
16950
  wrapperClasses = computed(() => ({
@@ -16956,15 +16972,16 @@ class TimePickerComponent {
16956
16972
  constructor() {
16957
16973
  this.destroyRef.onDestroy(() => this.stopHold());
16958
16974
  }
16959
- toggle() {
16960
- if (this.isDisabled() || this.readonly()) {
16975
+ /**
16976
+ * A click anywhere on the field opens the popover and leaves the focus in
16977
+ * the input, so the caret lands where it was aimed and typing can start
16978
+ * straight away. A click while open only moves the caret.
16979
+ */
16980
+ onTriggerClick() {
16981
+ if (this.isDisabled() || this.readonly() || this.isOpen()) {
16961
16982
  return;
16962
16983
  }
16963
- const opening = !this.isOpen();
16964
- this.isOpen.set(opening);
16965
- if (opening) {
16966
- this.focusHoursWhenReady();
16967
- }
16984
+ this.isOpen.set(true);
16968
16985
  }
16969
16986
  /**
16970
16987
  * Push focus into the hours input once the popover surface has been
@@ -17000,17 +17017,66 @@ class TimePickerComponent {
17000
17017
  if (this.isDisabled() || this.readonly()) {
17001
17018
  return;
17002
17019
  }
17003
- if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
17020
+ if (event.key === 'ArrowDown') {
17004
17021
  event.preventDefault();
17005
17022
  if (!this.isOpen()) {
17006
17023
  this.isOpen.set(true);
17007
- this.focusHoursWhenReady();
17008
17024
  }
17025
+ this.focusHoursWhenReady();
17009
17026
  }
17010
- else if (event.key === 'Escape' && this.isOpen()) {
17027
+ else if (event.key === 'Enter') {
17011
17028
  event.preventDefault();
17029
+ this.commitTyped();
17012
17030
  this.close();
17013
- this.triggerEl()?.nativeElement.focus();
17031
+ }
17032
+ else if (event.key === 'Escape') {
17033
+ // Left alone when there is nothing to let go of, so the press can
17034
+ // still close whatever layer holds the field
17035
+ if (this.typedText() === null && !this.isOpen()) {
17036
+ return;
17037
+ }
17038
+ event.preventDefault();
17039
+ this.typedText.set(null);
17040
+ this.close();
17041
+ }
17042
+ }
17043
+ onTriggerInput(event) {
17044
+ if (this.isDisabled() || this.readonly()) {
17045
+ return;
17046
+ }
17047
+ const el = event.currentTarget;
17048
+ this.typedText.set(el.value);
17049
+ }
17050
+ onTriggerBlur() {
17051
+ this.commitTyped();
17052
+ this.onTouched();
17053
+ }
17054
+ /**
17055
+ * Reads the hand-typed text and commits what it says: a time updates the
17056
+ * value, emptied text clears it, and anything unreadable is dropped so the
17057
+ * field falls back to the value it already shows.
17058
+ */
17059
+ commitTyped() {
17060
+ const text = this.typedText();
17061
+ if (text === null) {
17062
+ return;
17063
+ }
17064
+ this.typedText.set(null);
17065
+ if (!text.trim()) {
17066
+ if (this.value() !== null) {
17067
+ this.value.set(null);
17068
+ this.onChange(null);
17069
+ this.changed.emit(null);
17070
+ }
17071
+ return;
17072
+ }
17073
+ const labels = this.i18n.messages().timePicker;
17074
+ const parsed = parseTypedTime(text, {
17075
+ am: labels.amLabel,
17076
+ pm: labels.pmLabel,
17077
+ });
17078
+ if (parsed) {
17079
+ this.commit(parsed);
17014
17080
  }
17015
17081
  }
17016
17082
  /** Stepper button or keyboard arrow nudges one column up or down. */
@@ -17119,17 +17185,17 @@ class TimePickerComponent {
17119
17185
  // default `00:00` (the fallback returned by `parsed()`).
17120
17186
  this.commit(this.parsed());
17121
17187
  this.close();
17122
- this.triggerEl()?.nativeElement.focus();
17188
+ this.inputEl()?.nativeElement.focus();
17123
17189
  }
17124
17190
  // Escape bubbles up to the popover wrapper's handler, which closes
17125
17191
  // Tab is handled by the browser; (blur) on the leaving input flushes
17126
17192
  }
17127
- /** Escape from anywhere inside the popover closes it and refocuses the trigger. */
17193
+ /** Escape from anywhere inside the popover closes it and refocuses the field. */
17128
17194
  onPopoverEscape(event) {
17129
17195
  event.preventDefault();
17130
17196
  this.editBuffer.set(null);
17131
17197
  this.close();
17132
- this.triggerEl()?.nativeElement.focus();
17198
+ this.inputEl()?.nativeElement.focus();
17133
17199
  }
17134
17200
  /** Select-all on focus so the first keystroke replaces the current value. */
17135
17201
  onSpinnerFocus(event) {
@@ -17269,7 +17335,7 @@ class TimePickerComponent {
17269
17335
  useExisting: forwardRef(() => TimePickerComponent),
17270
17336
  multi: true,
17271
17337
  },
17272
- ], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "hoursEl", first: true, predicate: ["hoursEl"], descendants: true, isSignal: true }, { propertyName: "minutesEl", first: true, predicate: ["minutesEl"], descendants: true, isSignal: true }, { propertyName: "secondsEl", first: true, predicate: ["secondsEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-time-picker-field ea-time-picker-field--{{ size() }}\">\n @if (label(); as labelText) {\n <ea-field-label\n [text]=\"labelText\"\n [forId]=\"id()\"\n [required]=\"required()\" />\n }\n\n <div class=\"ea-time-picker\">\n <div\n class=\"ea-time-picker__trigger-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? popoverId() : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span class=\"ea-time-picker__trigger-value\">\n <bdi>{{ displayValue() || resolvedPlaceholder() }}</bdi>\n </span>\n </button>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-time-picker__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [aria-label]=\"i18n.messages().timePicker.dialogLabel\"\n [surfaceId]=\"popoverId()\"\n [trapFocus]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-time-picker__popover\"\n [ngClass]=\"popoverClasses()\"\n (keydown.escape)=\"onPopoverEscape($event)\">\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (click)=\"onStepClick('hours', 1, $event)\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (click)=\"onStepClick('hours', -1, $event)\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (click)=\"onStepClick('minutes', 1, $event)\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (click)=\"onStepClick('minutes', -1, $event)\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (click)=\"onStepClick('seconds', 1, $event)\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (click)=\"onStepClick('seconds', -1, $event)\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n [attr.aria-pressed]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n [attr.aria-pressed]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n <ea-field-messages\n [id]=\"id()\"\n [error]=\"errorText()\"\n [hint]=\"showHint() ? hint() : null\" />\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:.375em;--ea-field-label-size: .875em;--ea-field-messages-size: .8125em}.ea-time-picker-field--2xs{font-size:var(--font-size-2xs)}.ea-time-picker-field--xs{font-size:var(--font-size-xs)}.ea-time-picker-field--sm{font-size:var(--font-size-sm)}.ea-time-picker-field--md{font-size:var(--font-size-md)}.ea-time-picker-field--lg{font-size:var(--font-size-lg)}.ea-time-picker-field--xl{font-size:var(--font-size-xl)}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;gap:.5em;width:100%;min-height:2.5em;padding:.5em .75em;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);text-align:start;color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow)}.ea-time-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}@media(forced-colors:active){.ea-time-picker__trigger--error.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--readonly{cursor:default}.ea-time-picker__trigger--readonly:focus-visible{border-color:var(--color-border-focus);box-shadow:none}@media(forced-colors:active){.ea-time-picker__trigger--readonly:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--placeholder .ea-time-picker__trigger-value{color:var(--color-text-tertiary)}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.ea-time-picker__clear{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__clear>*{font-size:1.25em}.ea-time-picker__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__clear:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__clear:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__clear:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__clear{z-index:1;position:absolute;top:50%;inset-inline-end:var(--space-2);transform:translateY(-50%)}.ea-time-picker__popover{display:flex;align-items:center;gap:.5em;padding:.75em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--ea-time-picker-popover-background-color, var(--color-bg-elevated))}@media(forced-colors:active){.ea-time-picker__popover{border:1px solid CanvasText}}.ea-time-picker__popover--2xs{font-size:var(--font-size-2xs)}.ea-time-picker__popover--xs{font-size:var(--font-size-xs)}.ea-time-picker__popover--sm{font-size:var(--font-size-sm)}.ea-time-picker__popover--md{font-size:var(--font-size-md)}.ea-time-picker__popover--lg{font-size:var(--font-size-lg)}.ea-time-picker__popover--xl{font-size:var(--font-size-xl)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:.25em}.ea-time-picker__step{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step>*{font-size:1.25em}.ea-time-picker__step:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__step:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__step:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__step:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__step{width:2.25em}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:1em;height:1em}.ea-time-picker__value{width:2.25em;height:2.25em;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__value:focus{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__value:focus{background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:.25em;margin-inline-start:.25em}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;min-width:3.33em;padding:.33em .66em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:.75em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__period-option:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}@media(forced-colors:active){.ea-time-picker__period-option--active{background-color:Highlight;border-color:Highlight;color:HighlightText}}\n"], dependencies: [{ kind: "component", type: ChevronDownIconComponent, selector: "ea-icon-chevron-down" }, { kind: "component", type: ChevronUpIconComponent, selector: "ea-icon-chevron-up" }, { kind: "component", type: ClockIconComponent, selector: "ea-icon-clock" }, { kind: "component", type: FieldLabelComponent, selector: "ea-field-label", inputs: ["text", "forId", "required", "labelId"] }, { kind: "component", type: FieldMessagesComponent, selector: "ea-field-messages", inputs: ["id", "error", "hint"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "aria-labelledby", "trapFocus", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "maxWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
17338
+ ], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }, { propertyName: "hoursEl", first: true, predicate: ["hoursEl"], descendants: true, isSignal: true }, { propertyName: "minutesEl", first: true, predicate: ["minutesEl"], descendants: true, isSignal: true }, { propertyName: "secondsEl", first: true, predicate: ["secondsEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-time-picker-field ea-time-picker-field--{{ size() }}\">\n @if (label(); as labelText) {\n <ea-field-label\n [text]=\"labelText\"\n [forId]=\"id()\"\n [required]=\"required()\" />\n }\n\n <div class=\"ea-time-picker\">\n <div\n class=\"ea-time-picker__trigger-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <div\n #triggerEl\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n (click)=\"onTriggerClick()\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <input\n #inputEl\n type=\"text\"\n class=\"ea-time-picker__input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"resolvedPlaceholder()\"\n [value]=\"triggerText()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? popoverId() : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"onTriggerInput($event)\"\n (keydown)=\"handleTriggerKeydown($event)\"\n (blur)=\"onTriggerBlur()\" />\n </div>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-time-picker__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [aria-label]=\"i18n.messages().timePicker.dialogLabel\"\n [surfaceId]=\"popoverId()\"\n [trapFocus]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-time-picker__popover\"\n [ngClass]=\"popoverClasses()\"\n (keydown.escape)=\"onPopoverEscape($event)\">\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (click)=\"onStepClick('hours', 1, $event)\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (click)=\"onStepClick('hours', -1, $event)\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (click)=\"onStepClick('minutes', 1, $event)\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (click)=\"onStepClick('minutes', -1, $event)\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (click)=\"onStepClick('seconds', 1, $event)\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (click)=\"onStepClick('seconds', -1, $event)\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n [attr.aria-pressed]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n [attr.aria-pressed]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n <ea-field-messages\n [id]=\"id()\"\n [error]=\"errorText()\"\n [hint]=\"showHint() ? hint() : null\" />\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:.375em;--ea-field-label-size: .875em;--ea-field-messages-size: .8125em}.ea-time-picker-field--2xs{font-size:var(--font-size-2xs)}.ea-time-picker-field--xs{font-size:var(--font-size-xs)}.ea-time-picker-field--sm{font-size:var(--font-size-sm)}.ea-time-picker-field--md{font-size:var(--font-size-md)}.ea-time-picker-field--lg{font-size:var(--font-size-lg)}.ea-time-picker-field--xl{font-size:var(--font-size-xl)}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;gap:.5em;width:100%;min-height:2.5em;padding:.5em .75em;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);text-align:start;color:var(--color-text-primary);cursor:text;transition:var(--transition-colors),var(--transition-shadow)}.ea-time-picker__trigger:focus-within{box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger:focus-within{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}@media(forced-colors:active){.ea-time-picker__trigger--error.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--readonly{cursor:default}.ea-time-picker__trigger--readonly:focus-visible{border-color:var(--color-border-focus);box-shadow:none}@media(forced-colors:active){.ea-time-picker__trigger--readonly:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__input{overflow:hidden;flex:1;min-width:0;padding:0;font-size:inherit;white-space:nowrap;font-family:inherit;text-overflow:ellipsis;font-variant-numeric:tabular-nums;border:0;background:none;color:inherit;cursor:inherit}.ea-time-picker__input:focus{outline:none}.ea-time-picker__input::placeholder{color:var(--color-text-tertiary)}.ea-time-picker__input:disabled{cursor:not-allowed}.ea-time-picker__clear{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__clear>*{font-size:1.25em}.ea-time-picker__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__clear:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__clear:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__clear:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__clear{z-index:1;position:absolute;top:50%;inset-inline-end:var(--space-2);transform:translateY(-50%)}.ea-time-picker__popover{display:flex;align-items:center;gap:.5em;padding:.75em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--ea-time-picker-popover-background-color, var(--color-bg-elevated))}@media(forced-colors:active){.ea-time-picker__popover{border:1px solid CanvasText}}.ea-time-picker__popover--2xs{font-size:var(--font-size-2xs)}.ea-time-picker__popover--xs{font-size:var(--font-size-xs)}.ea-time-picker__popover--sm{font-size:var(--font-size-sm)}.ea-time-picker__popover--md{font-size:var(--font-size-md)}.ea-time-picker__popover--lg{font-size:var(--font-size-lg)}.ea-time-picker__popover--xl{font-size:var(--font-size-xl)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:.25em}.ea-time-picker__step{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step>*{font-size:1.25em}.ea-time-picker__step:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__step:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__step:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__step:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__step{width:2.25em}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:1em;height:1em}.ea-time-picker__value{width:2.25em;height:2.25em;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__value:focus{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__value:focus{background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:.25em;margin-inline-start:.25em}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;min-width:3.33em;padding:.33em .66em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:.75em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__period-option:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}@media(forced-colors:active){.ea-time-picker__period-option--active{background-color:Highlight;border-color:Highlight;color:HighlightText}}\n"], dependencies: [{ kind: "component", type: ChevronDownIconComponent, selector: "ea-icon-chevron-down" }, { kind: "component", type: ChevronUpIconComponent, selector: "ea-icon-chevron-up" }, { kind: "component", type: ClockIconComponent, selector: "ea-icon-clock" }, { kind: "component", type: FieldLabelComponent, selector: "ea-field-label", inputs: ["text", "forId", "required", "labelId"] }, { kind: "component", type: FieldMessagesComponent, selector: "ea-field-messages", inputs: ["id", "error", "hint"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "aria-labelledby", "trapFocus", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "maxWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
17273
17339
  }
17274
17340
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TimePickerComponent, decorators: [{
17275
17341
  type: Component,
@@ -17288,8 +17354,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
17288
17354
  useExisting: forwardRef(() => TimePickerComponent),
17289
17355
  multi: true,
17290
17356
  },
17291
- ], template: "<div class=\"ea-time-picker-field ea-time-picker-field--{{ size() }}\">\n @if (label(); as labelText) {\n <ea-field-label\n [text]=\"labelText\"\n [forId]=\"id()\"\n [required]=\"required()\" />\n }\n\n <div class=\"ea-time-picker\">\n <div\n class=\"ea-time-picker__trigger-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? popoverId() : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span class=\"ea-time-picker__trigger-value\">\n <bdi>{{ displayValue() || resolvedPlaceholder() }}</bdi>\n </span>\n </button>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-time-picker__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [aria-label]=\"i18n.messages().timePicker.dialogLabel\"\n [surfaceId]=\"popoverId()\"\n [trapFocus]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-time-picker__popover\"\n [ngClass]=\"popoverClasses()\"\n (keydown.escape)=\"onPopoverEscape($event)\">\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (click)=\"onStepClick('hours', 1, $event)\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (click)=\"onStepClick('hours', -1, $event)\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (click)=\"onStepClick('minutes', 1, $event)\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (click)=\"onStepClick('minutes', -1, $event)\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (click)=\"onStepClick('seconds', 1, $event)\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (click)=\"onStepClick('seconds', -1, $event)\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n [attr.aria-pressed]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n [attr.aria-pressed]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n <ea-field-messages\n [id]=\"id()\"\n [error]=\"errorText()\"\n [hint]=\"showHint() ? hint() : null\" />\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:.375em;--ea-field-label-size: .875em;--ea-field-messages-size: .8125em}.ea-time-picker-field--2xs{font-size:var(--font-size-2xs)}.ea-time-picker-field--xs{font-size:var(--font-size-xs)}.ea-time-picker-field--sm{font-size:var(--font-size-sm)}.ea-time-picker-field--md{font-size:var(--font-size-md)}.ea-time-picker-field--lg{font-size:var(--font-size-lg)}.ea-time-picker-field--xl{font-size:var(--font-size-xl)}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;gap:.5em;width:100%;min-height:2.5em;padding:.5em .75em;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);text-align:start;color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow)}.ea-time-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}@media(forced-colors:active){.ea-time-picker__trigger--error.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--readonly{cursor:default}.ea-time-picker__trigger--readonly:focus-visible{border-color:var(--color-border-focus);box-shadow:none}@media(forced-colors:active){.ea-time-picker__trigger--readonly:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--placeholder .ea-time-picker__trigger-value{color:var(--color-text-tertiary)}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.ea-time-picker__clear{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__clear>*{font-size:1.25em}.ea-time-picker__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__clear:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__clear:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__clear:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__clear{z-index:1;position:absolute;top:50%;inset-inline-end:var(--space-2);transform:translateY(-50%)}.ea-time-picker__popover{display:flex;align-items:center;gap:.5em;padding:.75em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--ea-time-picker-popover-background-color, var(--color-bg-elevated))}@media(forced-colors:active){.ea-time-picker__popover{border:1px solid CanvasText}}.ea-time-picker__popover--2xs{font-size:var(--font-size-2xs)}.ea-time-picker__popover--xs{font-size:var(--font-size-xs)}.ea-time-picker__popover--sm{font-size:var(--font-size-sm)}.ea-time-picker__popover--md{font-size:var(--font-size-md)}.ea-time-picker__popover--lg{font-size:var(--font-size-lg)}.ea-time-picker__popover--xl{font-size:var(--font-size-xl)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:.25em}.ea-time-picker__step{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step>*{font-size:1.25em}.ea-time-picker__step:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__step:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__step:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__step:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__step{width:2.25em}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:1em;height:1em}.ea-time-picker__value{width:2.25em;height:2.25em;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__value:focus{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__value:focus{background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:.25em;margin-inline-start:.25em}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;min-width:3.33em;padding:.33em .66em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:.75em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__period-option:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}@media(forced-colors:active){.ea-time-picker__period-option--active{background-color:Highlight;border-color:Highlight;color:HighlightText}}\n"] }]
17292
- }], ctorParameters: () => [], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], hoursEl: [{ type: i0.ViewChild, args: ['hoursEl', { isSignal: true }] }], minutesEl: [{ type: i0.ViewChild, args: ['minutesEl', { isSignal: true }] }], secondsEl: [{ type: i0.ViewChild, args: ['secondsEl', { isSignal: true }] }], 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 }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], includeSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "includeSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], secondStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondStep", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
17357
+ ], template: "<div class=\"ea-time-picker-field ea-time-picker-field--{{ size() }}\">\n @if (label(); as labelText) {\n <ea-field-label\n [text]=\"labelText\"\n [forId]=\"id()\"\n [required]=\"required()\" />\n }\n\n <div class=\"ea-time-picker\">\n <div\n class=\"ea-time-picker__trigger-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <div\n #triggerEl\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n (click)=\"onTriggerClick()\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <input\n #inputEl\n type=\"text\"\n class=\"ea-time-picker__input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"readonly()\"\n [placeholder]=\"resolvedPlaceholder()\"\n [value]=\"triggerText()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-controls]=\"isOpen() ? popoverId() : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"onTriggerInput($event)\"\n (keydown)=\"handleTriggerKeydown($event)\"\n (blur)=\"onTriggerBlur()\" />\n </div>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-time-picker__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [aria-label]=\"i18n.messages().timePicker.dialogLabel\"\n [surfaceId]=\"popoverId()\"\n [trapFocus]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-time-picker__popover\"\n [ngClass]=\"popoverClasses()\"\n (keydown.escape)=\"onPopoverEscape($event)\">\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (click)=\"onStepClick('hours', 1, $event)\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (click)=\"onStepClick('hours', -1, $event)\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (click)=\"onStepClick('minutes', 1, $event)\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (click)=\"onStepClick('minutes', -1, $event)\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (click)=\"onStepClick('seconds', 1, $event)\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (click)=\"onStepClick('seconds', -1, $event)\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n [attr.aria-pressed]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n [attr.aria-pressed]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n <ea-field-messages\n [id]=\"id()\"\n [error]=\"errorText()\"\n [hint]=\"showHint() ? hint() : null\" />\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:.375em;--ea-field-label-size: .875em;--ea-field-messages-size: .8125em}.ea-time-picker-field--2xs{font-size:var(--font-size-2xs)}.ea-time-picker-field--xs{font-size:var(--font-size-xs)}.ea-time-picker-field--sm{font-size:var(--font-size-sm)}.ea-time-picker-field--md{font-size:var(--font-size-md)}.ea-time-picker-field--lg{font-size:var(--font-size-lg)}.ea-time-picker-field--xl{font-size:var(--font-size-xl)}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;gap:.5em;width:100%;min-height:2.5em;padding:.5em .75em;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);text-align:start;color:var(--color-text-primary);cursor:text;transition:var(--transition-colors),var(--transition-shadow)}.ea-time-picker__trigger:focus-within{box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger:focus-within{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}@media(forced-colors:active){.ea-time-picker__trigger--error.ea-time-picker__trigger--open{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--readonly{cursor:default}.ea-time-picker__trigger--readonly:focus-visible{border-color:var(--color-border-focus);box-shadow:none}@media(forced-colors:active){.ea-time-picker__trigger--readonly:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__input{overflow:hidden;flex:1;min-width:0;padding:0;font-size:inherit;white-space:nowrap;font-family:inherit;text-overflow:ellipsis;font-variant-numeric:tabular-nums;border:0;background:none;color:inherit;cursor:inherit}.ea-time-picker__input:focus{outline:none}.ea-time-picker__input::placeholder{color:var(--color-text-tertiary)}.ea-time-picker__input:disabled{cursor:not-allowed}.ea-time-picker__clear{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__clear>*{font-size:1.25em}.ea-time-picker__clear:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__clear:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__clear:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__clear:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__clear{z-index:1;position:absolute;top:50%;inset-inline-end:var(--space-2);transform:translateY(-50%)}.ea-time-picker__popover{display:flex;align-items:center;gap:.5em;padding:.75em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--ea-time-picker-popover-background-color, var(--color-bg-elevated))}@media(forced-colors:active){.ea-time-picker__popover{border:1px solid CanvasText}}.ea-time-picker__popover--2xs{font-size:var(--font-size-2xs)}.ea-time-picker__popover--xs{font-size:var(--font-size-xs)}.ea-time-picker__popover--sm{font-size:var(--font-size-sm)}.ea-time-picker__popover--md{font-size:var(--font-size-md)}.ea-time-picker__popover--lg{font-size:var(--font-size-lg)}.ea-time-picker__popover--xl{font-size:var(--font-size-xl)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:.25em}.ea-time-picker__step{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step>*{font-size:1.25em}.ea-time-picker__step:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-time-picker__step:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__step:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__step:disabled{cursor:not-allowed;opacity:.5}.ea-time-picker__step{width:2.25em}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:1em;height:1em}.ea-time-picker__value{width:2.25em;height:2.25em;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__value:focus{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__value:focus{background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:1em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:.25em;margin-inline-start:.25em}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;min-width:3.33em;padding:.33em .66em;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:.75em;font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-time-picker__period-option:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}@media(forced-colors:active){.ea-time-picker__period-option--active{background-color:Highlight;border-color:Highlight;color:HighlightText}}\n"] }]
17358
+ }], ctorParameters: () => [], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], hoursEl: [{ type: i0.ViewChild, args: ['hoursEl', { isSignal: true }] }], minutesEl: [{ type: i0.ViewChild, args: ['minutesEl', { isSignal: true }] }], secondsEl: [{ type: i0.ViewChild, args: ['secondsEl', { isSignal: true }] }], 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 }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], includeSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "includeSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], secondStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondStep", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
17293
17359
  /** Delay before a held chevron button starts repeating, in ms. */
17294
17360
  const HOLD_INITIAL_DELAY = 400;
17295
17361
  /** Repeat interval while a chevron button is held, in ms. */
@@ -17302,6 +17368,67 @@ const HOLD_FAST_INTERVAL_MS = 35;
17302
17368
  function pad2(n) {
17303
17369
  return n < 10 ? `0${n}` : `${n}`;
17304
17370
  }
17371
+ /**
17372
+ * Reads a hand-typed time, leniently. Bare digits are a 24-hour clock ("5" is
17373
+ * 05:00, "130" is 01:30, "1234" is 12:34, "123456" adds seconds); `:`, `.`,
17374
+ * `h`, and spaces all separate units ("17h30", "12.34", "12 34"); a trailing
17375
+ * AM/PM token, in English or the current locale's labels, reads the hour on
17376
+ * the 12-hour clock ("5pm" is 17:00, "12am" is 00:00). Returns `null` for
17377
+ * anything that names no valid time.
17378
+ */
17379
+ function parseTypedTime(text, labels) {
17380
+ let rest = text.trim().toLowerCase();
17381
+ let period = null;
17382
+ const tokens = [
17383
+ [labels.am.toLowerCase(), 'am'],
17384
+ [labels.pm.toLowerCase(), 'pm'],
17385
+ ['a.m.', 'am'],
17386
+ ['p.m.', 'pm'],
17387
+ ['am', 'am'],
17388
+ ['pm', 'pm'],
17389
+ ['a', 'am'],
17390
+ ['p', 'pm'],
17391
+ ];
17392
+ for (const [token, kind] of tokens) {
17393
+ if (token && rest.endsWith(token)) {
17394
+ rest = rest.slice(0, -token.length).trim();
17395
+ period = kind;
17396
+ break;
17397
+ }
17398
+ }
17399
+ const separated = rest.replace(/[.h]/g, ':').replace(/\s+/g, ':').replace(/:$/, '');
17400
+ let hours;
17401
+ let minutes;
17402
+ let seconds;
17403
+ const parts = /^(\d{1,2})(?::(\d{1,2})(?::(\d{1,2}))?)?$/.exec(separated);
17404
+ if (parts) {
17405
+ hours = parseInt(parts[1], 10);
17406
+ minutes = parts[2] !== undefined ? parseInt(parts[2], 10) : 0;
17407
+ seconds = parts[3] !== undefined ? parseInt(parts[3], 10) : 0;
17408
+ }
17409
+ else if (/^\d{3,6}$/.test(separated)) {
17410
+ // An unbroken run splits from the right: minutes take two digits, seconds
17411
+ // two more when present, and the hour keeps whatever is left
17412
+ const withSeconds = separated.length >= 5;
17413
+ const tail = withSeconds ? separated.slice(-4) : separated.slice(-2);
17414
+ hours = parseInt(separated.slice(0, separated.length - tail.length), 10);
17415
+ minutes = parseInt(tail.slice(0, 2), 10);
17416
+ seconds = withSeconds ? parseInt(tail.slice(2), 10) : 0;
17417
+ }
17418
+ else {
17419
+ return null;
17420
+ }
17421
+ if (minutes > 59 || seconds > 59) {
17422
+ return null;
17423
+ }
17424
+ if (period === null) {
17425
+ return hours <= 23 ? { hours, minutes, seconds } : null;
17426
+ }
17427
+ if (hours > 12) {
17428
+ return null;
17429
+ }
17430
+ return { hours: (hours % 12) + (period === 'pm' ? 12 : 0), minutes, seconds };
17431
+ }
17305
17432
  /** Parse `"HH:MM"` / `"HH:MM:SS"`; returns `null` for any malformed input. */
17306
17433
  function parseTime(input) {
17307
17434
  if (!input) {