@aurodesignsystem-dev/auro-formkit 0.0.0-pr1516.0 → 0.0.0-pr1519.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.
Files changed (54) hide show
  1. package/components/checkbox/demo/customize.min.js +18 -10
  2. package/components/checkbox/demo/getting-started.min.js +18 -10
  3. package/components/checkbox/demo/index.min.js +18 -10
  4. package/components/checkbox/dist/index.js +18 -10
  5. package/components/checkbox/dist/registered.js +18 -10
  6. package/components/combobox/README.md +1 -1
  7. package/components/combobox/demo/customize.md +2 -10
  8. package/components/combobox/demo/customize.min.js +454 -467
  9. package/components/combobox/demo/getting-started.min.js +454 -463
  10. package/components/combobox/demo/index.md +1 -1
  11. package/components/combobox/demo/index.min.js +454 -463
  12. package/components/combobox/demo/keyboard-behavior.md +2 -142
  13. package/components/combobox/demo/readme.md +1 -1
  14. package/components/combobox/demo/why-combobox.md +2 -2
  15. package/components/combobox/dist/auro-combobox.d.ts +30 -14
  16. package/components/combobox/dist/index.js +454 -463
  17. package/components/combobox/dist/registered.js +454 -463
  18. package/components/counter/demo/customize.min.js +32 -12
  19. package/components/counter/demo/index.min.js +32 -12
  20. package/components/counter/dist/index.js +32 -12
  21. package/components/counter/dist/registered.js +32 -12
  22. package/components/datepicker/demo/customize.min.js +183 -167
  23. package/components/datepicker/demo/index.min.js +183 -167
  24. package/components/datepicker/dist/index.js +183 -167
  25. package/components/datepicker/dist/registered.js +183 -167
  26. package/components/dropdown/demo/customize.min.js +14 -2
  27. package/components/dropdown/demo/getting-started.min.js +14 -2
  28. package/components/dropdown/demo/index.min.js +14 -2
  29. package/components/dropdown/dist/index.js +14 -2
  30. package/components/dropdown/dist/registered.js +14 -2
  31. package/components/form/demo/customize.min.js +851 -829
  32. package/components/form/demo/getting-started.min.js +851 -829
  33. package/components/form/demo/index.min.js +851 -829
  34. package/components/form/demo/registerDemoDeps.min.js +851 -829
  35. package/components/input/demo/api.md +58 -57
  36. package/components/input/demo/customize.min.js +114 -155
  37. package/components/input/demo/getting-started.min.js +114 -155
  38. package/components/input/demo/index.min.js +114 -155
  39. package/components/input/dist/base-input.d.ts +9 -51
  40. package/components/input/dist/index.js +114 -155
  41. package/components/input/dist/registered.js +114 -155
  42. package/components/input/dist/utilities.d.ts +9 -0
  43. package/components/radio/demo/customize.min.js +18 -10
  44. package/components/radio/demo/getting-started.min.js +18 -10
  45. package/components/radio/demo/index.min.js +18 -10
  46. package/components/radio/dist/index.js +18 -10
  47. package/components/radio/dist/registered.js +18 -10
  48. package/components/select/demo/customize.min.js +32 -12
  49. package/components/select/demo/getting-started.min.js +32 -12
  50. package/components/select/demo/index.min.js +32 -12
  51. package/components/select/dist/index.js +32 -12
  52. package/components/select/dist/registered.js +32 -12
  53. package/custom-elements.json +142 -278
  54. package/package.json +1 -1
@@ -5455,11 +5455,17 @@ let AuroFormValidation$7 = class AuroFormValidation {
5455
5455
  return;
5456
5456
  }
5457
5457
 
5458
- // Validate that the date passed was the correct format and is a valid date
5458
+ // Validate that the date passed was the correct format and is a valid date.
5459
+ // For partial date formats, valueObject is never populated; validate them directly.
5459
5460
  if (elem.value && !elem.valueObject) {
5460
- elem.validity = 'patternMismatch';
5461
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
5462
- return;
5461
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
5462
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
5463
+
5464
+ if (!isValidPartial) {
5465
+ elem.validity = 'patternMismatch';
5466
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
5467
+ return;
5468
+ }
5463
5469
  }
5464
5470
 
5465
5471
  // Perform the rest of the validation
@@ -5553,15 +5559,17 @@ let AuroFormValidation$7 = class AuroFormValidation {
5553
5559
  );
5554
5560
  }
5555
5561
 
5556
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
5557
- if (this.auroInputElements?.length === 2) {
5558
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
5562
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
5563
+
5564
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
5565
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
5566
+ // field (datepicker is the intended consumer — start/end are independently required).
5567
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
5568
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
5559
5569
  hasValue = false;
5560
5570
  }
5561
5571
  }
5562
5572
 
5563
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
5564
-
5565
5573
  if (isCombobox) {
5566
5574
 
5567
5575
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -11461,6 +11469,42 @@ let AuroInputUtilities$3 = class AuroInputUtilities {
11461
11469
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
11462
11470
  }
11463
11471
 
11472
+ /**
11473
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
11474
+ * Single-component formats are checked as integer ranges; multi-component formats use
11475
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
11476
+ * @param {string} value - The user-facing display value.
11477
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
11478
+ * @returns {boolean}
11479
+ */
11480
+ isValidPartialDate(value, format$1) {
11481
+ if (!value || !format$1) {
11482
+ return false;
11483
+ }
11484
+ const normalizedFormat = format$1.toLowerCase();
11485
+
11486
+ if (normalizedFormat === 'dd') {
11487
+ const num = Number(value);
11488
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
11489
+ }
11490
+ if (normalizedFormat === 'yy') {
11491
+ const num = Number(value);
11492
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
11493
+ }
11494
+ if (normalizedFormat === 'yyyy') {
11495
+ const num = Number(value);
11496
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
11497
+ }
11498
+
11499
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
11500
+ // Use the 1st of the current month as the reference so that formats
11501
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
11502
+ const referenceDate = new Date();
11503
+ referenceDate.setDate(1);
11504
+ const parsed = parse$3(value, dateFnsMask, referenceDate);
11505
+ return isValid$3(parsed) && format$3(parsed, dateFnsMask) === value;
11506
+ }
11507
+
11464
11508
  /**
11465
11509
  * Converts a display string to its model value.
11466
11510
  * For full date formats, converts the display string to an ISO date string.
@@ -11508,6 +11552,7 @@ let AuroInputUtilities$3 = class AuroInputUtilities {
11508
11552
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
11509
11553
 
11510
11554
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
11555
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
11511
11556
  return undefined;
11512
11557
  }
11513
11558
 
@@ -11665,6 +11710,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11665
11710
  // so a parent (datepicker/combobox) calling `validate()` synchronously
11666
11711
  // during its own update cycle sees a populated util instance.
11667
11712
  this.activeLabel = false;
11713
+
11668
11714
  /** @private */
11669
11715
  this.allowedInputTypes = [
11670
11716
  "text",
@@ -11675,6 +11721,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11675
11721
  "tel"
11676
11722
  ];
11677
11723
  this.appearance = "default";
11724
+
11678
11725
  /** @private */
11679
11726
  this.dateFormatMap = {
11680
11727
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -11693,23 +11740,24 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11693
11740
  'mm/dd': 'dateMMDD'
11694
11741
  };
11695
11742
  this.disabled = false;
11743
+
11696
11744
  /** @private */
11697
11745
  this.domHandler = new DomHandler$3();
11698
11746
  this.dvInputOnly = false;
11699
11747
  this.hasValue = false;
11700
11748
  this.hideLabelVisually = false;
11701
11749
  this.icon = false;
11750
+
11702
11751
  /** @private */
11703
11752
  this.inputIconName = undefined;
11753
+
11704
11754
  /** @private */
11705
11755
  this.label = 'Input label is undefined';
11706
11756
  this.layout = 'classic';
11707
11757
  this.locale = 'en-US';
11708
11758
  this.max = undefined;
11709
- this._maxObject = undefined;
11710
11759
  this.maxLength = undefined;
11711
11760
  this.min = undefined;
11712
- this._minObject = undefined;
11713
11761
  this.minLength = undefined;
11714
11762
  this.noValidate = false;
11715
11763
  this.onDark = false;
@@ -11726,23 +11774,27 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11726
11774
  "email"
11727
11775
  ];
11728
11776
  this.shape = 'classic';
11777
+
11729
11778
  /** @private */
11730
11779
  this.showPassword = false;
11731
11780
  this.size = 'lg';
11732
11781
  this.touched = false;
11782
+
11733
11783
  /** @private */
11734
11784
  this.uniqueId = new UniqueId$2().create();
11785
+
11735
11786
  /** @private */
11736
11787
  this.util = new AuroInputUtilities$3({
11737
11788
  locale: this.locale,
11738
11789
  format: this.format
11739
11790
  });
11791
+
11740
11792
  /** @private */
11741
11793
  this.validation = new AuroFormValidation$7();
11794
+
11742
11795
  /** @private */
11743
11796
  this.validationCCLength = undefined;
11744
11797
  this.value = undefined;
11745
- this._valueObject = undefined;
11746
11798
  }
11747
11799
 
11748
11800
  // function to define props used within the scope of this component
@@ -12072,6 +12124,13 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12072
12124
  type: String
12073
12125
  },
12074
12126
 
12127
+ /**
12128
+ * Custom help text message to display when validity = `patternMismatch`.
12129
+ */
12130
+ setCustomValidityPatternMismatch: {
12131
+ type: String
12132
+ },
12133
+
12075
12134
  /**
12076
12135
  * Custom help text message to display when validity = `rangeOverflow`.
12077
12136
  */
@@ -12142,7 +12201,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12142
12201
 
12143
12202
  /**
12144
12203
  * Populates the `type` attribute on the input.
12145
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
12204
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
12146
12205
  * @default 'text'
12147
12206
  */
12148
12207
  type: {
@@ -12180,7 +12239,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12180
12239
  * @returns {Date|undefined}
12181
12240
  */
12182
12241
  get valueObject() {
12183
- return this._valueObject || this._computeDateObjectFallback(this.value);
12242
+ return this.value && dateFormatter$3.isValidDate(this.value) ? dateFormatter$3.stringToDateInstance(this.value) : undefined;
12184
12243
  }
12185
12244
 
12186
12245
  /**
@@ -12188,7 +12247,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12188
12247
  * @returns {Date|undefined}
12189
12248
  */
12190
12249
  get minObject() {
12191
- return this._minObject || this._computeDateObjectFallback(this.min);
12250
+ return this.min && dateFormatter$3.isValidDate(this.min) ? dateFormatter$3.stringToDateInstance(this.min) : undefined;
12192
12251
  }
12193
12252
 
12194
12253
  /**
@@ -12196,50 +12255,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12196
12255
  * @returns {Date|undefined}
12197
12256
  */
12198
12257
  get maxObject() {
12199
- return this._maxObject || this._computeDateObjectFallback(this.max);
12200
- }
12201
-
12202
- /**
12203
- * Parses a date string into a Date object when the corresponding `_*Object`
12204
- * field hasn't been synced yet by `updated()`. Returns undefined when the
12205
- * input type/format isn't a full date or the string is not a valid date.
12206
- *
12207
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
12208
- * inside its own `updated()` before this input's `updated()` has run
12209
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
12210
- * and range checks would otherwise silently no-op (flipping the result to
12211
- * `valid` or `patternMismatch`).
12212
- * @private
12213
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
12214
- * @returns {Date|undefined}
12215
- */
12216
- _computeDateObjectFallback(dateStr) {
12217
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
12218
- return undefined;
12219
- }
12220
- if (!dateFormatter$3.isValidDate(dateStr)) {
12221
- return undefined;
12222
- }
12223
- return dateFormatter$3.stringToDateInstance(dateStr);
12224
- }
12225
-
12226
- /**
12227
- * Internal setter for readonly date object properties.
12228
- * @private
12229
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
12230
- * @param {Date|undefined} propertyValue - Value to assign.
12231
- * @returns {void}
12232
- */
12233
- setDateObjectProperty(propertyName, propertyValue) {
12234
- const internalPropertyName = `_${propertyName}`;
12235
- const previousValue = this[internalPropertyName];
12236
-
12237
- if (previousValue === propertyValue) {
12238
- return;
12239
- }
12240
-
12241
- this[internalPropertyName] = propertyValue;
12242
- this.requestUpdate(propertyName, previousValue);
12258
+ return this.max && dateFormatter$3.isValidDate(this.max) ? dateFormatter$3.stringToDateInstance(this.max) : undefined;
12243
12259
  }
12244
12260
 
12245
12261
  connectedCallback() {
@@ -12268,7 +12284,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12268
12284
  format: this.format
12269
12285
  });
12270
12286
  this.configureDataForType();
12271
- this.syncDateValues();
12272
12287
  }
12273
12288
 
12274
12289
  disconnectedCallback() {
@@ -12307,7 +12322,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12307
12322
  this.setCustomHelpTextMessage();
12308
12323
  this.configureAutoFormatting();
12309
12324
  this.configureDataForType();
12310
- this.syncDateValues();
12311
12325
  }
12312
12326
 
12313
12327
  /**
@@ -12451,8 +12465,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12451
12465
  this.configureDataForType();
12452
12466
  }
12453
12467
 
12454
- this.syncDateValues(changedProperties);
12455
-
12456
12468
  if (changedProperties.has('value')) {
12457
12469
  if (this.value && this.value.length > 0) {
12458
12470
  this.hasValue = true;
@@ -12474,14 +12486,14 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12474
12486
 
12475
12487
  if (formattedValue !== this.inputElement.value) {
12476
12488
  this.skipNextProgrammaticInputEvent = true;
12477
- if (this.maskInstance && this.type === 'credit-card') {
12489
+ if (this.maskInstance && this.type !== 'date') {
12478
12490
  // Route through the mask so its _value and el.value stay in lock-step
12479
12491
  // (set value calls updateControl which writes el.value = displayValue).
12480
12492
  // Writing el.value directly leaves the mask thinking displayValue is
12481
- // stale; _saveSelection on the next focus/click then warns. Scoped to
12482
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
12483
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
12484
- // and flip validity from patternMismatch to tooShort.
12493
+ // stale; _saveSelection on the next focus/click then warns. Date is
12494
+ // excluded because its formattedValue can be raw ISO when the calendar
12495
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
12496
+ // flip validity from patternMismatch to tooShort.
12485
12497
  this.maskInstance.value = formattedValue || '';
12486
12498
  } else if (formattedValue) {
12487
12499
  this.inputElement.value = formattedValue;
@@ -12523,120 +12535,65 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12523
12535
  }));
12524
12536
  }
12525
12537
 
12526
-
12527
- /**
12528
- * Synchronizes the ISO string values and Date object representations for date-related properties.
12529
- * This keeps the model and display values aligned when either side changes.
12530
- *
12531
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
12532
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
12533
- * represents a full year/month/day date format.
12534
- *
12535
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
12536
- * @returns {void}
12537
- * @private
12538
- */
12539
- syncDateValues(changedProperties = undefined) {
12540
- if (!this.util.isFullDateFormat(this.type, this.format)) {
12541
- return;
12542
- }
12543
-
12544
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
12545
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
12546
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
12547
- }
12548
-
12549
- /**
12550
- * Synchronizes one date object/string property pair.
12551
- * @private
12552
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
12553
- * @param {string} objectProperty - Date object property name.
12554
- * @param {string} valueProperty - ISO string property name.
12555
- * @returns {void}
12556
- */
12557
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
12558
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
12559
-
12560
- // objectProperty wins over valueProperty when both changed
12561
- if (objectPropertyChanged && this[objectProperty]) {
12562
- this[valueProperty] = dateFormatter$3.toISOFormatString(this[objectProperty]);
12563
- return;
12564
- }
12565
-
12566
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
12567
- if (!valuePropertyChanged) {
12568
- return;
12569
- }
12570
-
12571
- // when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
12572
- if (
12573
- changedProperties &&
12574
- valueProperty === 'value' &&
12575
- changedProperties.get('value') === undefined &&
12576
- this[objectProperty] instanceof Date &&
12577
- this[valueProperty] === dateFormatter$3.toISOFormatString(this[objectProperty])
12578
- ) {
12579
- return;
12580
- }
12581
-
12582
- if (dateFormatter$3.isValidDate(this[valueProperty])) {
12583
- this.setDateObjectProperty(objectProperty, dateFormatter$3.stringToDateInstance(this[valueProperty]));
12584
- } else {
12585
- this.setDateObjectProperty(objectProperty, undefined);
12586
- }
12587
- }
12588
-
12589
12538
  /**
12590
12539
  * Sets up IMasks and logic based on auto-formatting requirements.
12591
12540
  * @private
12592
12541
  * @returns {void}
12593
12542
  */
12594
12543
  configureAutoFormatting() {
12595
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
12596
- // by _configuringMask above) could otherwise trigger handleInput
12597
- // processCreditCard configureAutoFormatting before the outer call's
12598
- // set value has finished its alignCursor pass.
12544
+ // _configuringMask gates two things: external re-entry into this method
12545
+ // while setup is mid-flight (from property changes that call back here),
12546
+ // and the accept/complete listeners below — both need to ignore the mask
12547
+ // events fired by our own value-restore step.
12599
12548
  if (this._configuringMask) return;
12600
12549
  this._configuringMask = true;
12601
12550
  try {
12551
+ // Destroy any prior mask so IMask can attach fresh under the new format.
12552
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
12553
+ // type switched from credit-card to text) the IMask() reassignment
12554
+ // below is skipped, and downstream writes at line ~823 would otherwise
12555
+ // route through the destroyed instance.
12602
12556
  if (this.maskInstance) {
12603
12557
  this.maskInstance.destroy();
12558
+ this.maskInstance = null;
12604
12559
  }
12605
12560
 
12606
- // Pass new format to util
12607
12561
  this.util.updateFormat(this.format);
12608
12562
 
12609
12563
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
12610
12564
 
12611
12565
  if (this.inputElement && maskOptions.mask) {
12612
-
12613
- // Stash and clear any existing value before IMask init.
12614
- // IMask's constructor processes the current input value which requires
12615
- // selection state clearing first avoids that scenario entirely.
12616
- // When the format changes (e.g. locale switch) and we have a valid ISO
12617
- // model value, compute the display string for the NEW format instead of
12618
- // re-using the old display string, which may be invalid in the new mask.
12566
+ // Capture the current display so it can be re-applied after IMask
12567
+ // attaches. The restore at the bottom goes through maskInstance.value
12568
+ // (not inputElement.value directly) so the mask's internal state and
12569
+ // the input's displayed text stay in lock-step.
12619
12570
  let existingValue = this.inputElement.value;
12571
+
12572
+ // Format-change case (e.g. locale switch): existingValue is the OLD
12573
+ // mask's display string and may not parse under the new mask. When
12574
+ // we have a valid date model, rebuild the display from valueObject
12575
+ // (the canonical source) using the new mask's format function.
12620
12576
  if (
12621
12577
  this.util.isFullDateFormat(this.type, this.format) &&
12622
12578
  this.value &&
12623
- dateFormatter$3.isValidDate(this.value) &&
12624
- this.valueObject instanceof Date &&
12625
- !Number.isNaN(this.valueObject.getTime()) &&
12579
+ this.valueObject &&
12626
12580
  typeof maskOptions.format === 'function'
12627
12581
  ) {
12628
12582
  existingValue = maskOptions.format(this.valueObject);
12629
12583
  }
12630
12584
 
12585
+ // Clear before IMask attaches so the constructor seeds an empty
12586
+ // internal value. Otherwise IMask reads the stale unmasked string
12587
+ // and emits a spurious 'accept' before the restore below runs.
12631
12588
  this.skipNextProgrammaticInputEvent = true;
12632
12589
  this.inputElement.value = '';
12633
12590
 
12634
12591
  this.maskInstance = IMask$3(this.inputElement, maskOptions);
12635
12592
 
12593
+ // Mask fires 'accept' on every value change, including the restore
12594
+ // step below. Skip events fired during configureAutoFormatting so
12595
+ // we don't overwrite a value the parent just pushed.
12636
12596
  this.maskInstance.on('accept', () => {
12637
- // Suppress propagation during configureAutoFormatting's own value-restoration
12638
- // (line below) — the mask emits 'accept' on every value-set, including ours,
12639
- // and we don't want to overwrite a value the parent just pushed.
12640
12597
  if (this._configuringMask) return;
12641
12598
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
12642
12599
  if (this.type === "date") {
@@ -12644,6 +12601,8 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12644
12601
  }
12645
12602
  });
12646
12603
 
12604
+ // Mask fires 'complete' on the restore step below for any value that
12605
+ // happens to be a complete match. Same setup-suppression as 'accept'.
12647
12606
  this.maskInstance.on('complete', () => {
12648
12607
  if (this._configuringMask) return;
12649
12608
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -12652,7 +12611,9 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12652
12611
  }
12653
12612
  });
12654
12613
 
12655
- // Restore the stashed value through IMask so it's properly masked
12614
+ // Write existingValue through the mask (not the input directly) so
12615
+ // the mask reformats it under the new rules and keeps its internal
12616
+ // _value aligned with the input's displayed text.
12656
12617
  if (existingValue) {
12657
12618
  this.maskInstance.value = existingValue;
12658
12619
  }
@@ -12746,9 +12707,9 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12746
12707
  // the gated types currently support it, since the list is a public
12747
12708
  // property a consumer could mutate.
12748
12709
  if (this.setSelectionInputTypes.includes(this.type)) {
12749
- let selectionStart;
12710
+ let selectionStart = null;
12750
12711
  try {
12751
- selectionStart = this.inputElement.selectionStart;
12712
+ ({ selectionStart } = this.inputElement);
12752
12713
  } catch (error) { // eslint-disable-line no-unused-vars
12753
12714
  return;
12754
12715
  }
@@ -12852,7 +12813,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12852
12813
  */
12853
12814
  reset() {
12854
12815
  this.value = undefined;
12855
- this.setDateObjectProperty('valueObject', undefined);
12856
12816
  this.validation.reset(this);
12857
12817
  }
12858
12818
 
@@ -12861,7 +12821,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
12861
12821
  */
12862
12822
  clear() {
12863
12823
  this.value = undefined;
12864
- this.setDateObjectProperty('valueObject', undefined);
12865
12824
  }
12866
12825
 
12867
12826
  /**
@@ -13390,7 +13349,7 @@ let AuroHelpText$8 = class AuroHelpText extends i$3 {
13390
13349
  }
13391
13350
  };
13392
13351
 
13393
- var formkitVersion$8 = '202606292156';
13352
+ var formkitVersion$8 = '202607011722';
13394
13353
 
13395
13354
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
13396
13355
  // See LICENSE in the project root for license information.
@@ -14665,11 +14624,17 @@ let AuroFormValidation$1$1 = class AuroFormValidation {
14665
14624
  return;
14666
14625
  }
14667
14626
 
14668
- // Validate that the date passed was the correct format and is a valid date
14627
+ // Validate that the date passed was the correct format and is a valid date.
14628
+ // For partial date formats, valueObject is never populated; validate them directly.
14669
14629
  if (elem.value && !elem.valueObject) {
14670
- elem.validity = 'patternMismatch';
14671
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
14672
- return;
14630
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
14631
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
14632
+
14633
+ if (!isValidPartial) {
14634
+ elem.validity = 'patternMismatch';
14635
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
14636
+ return;
14637
+ }
14673
14638
  }
14674
14639
 
14675
14640
  // Perform the rest of the validation
@@ -14763,15 +14728,17 @@ let AuroFormValidation$1$1 = class AuroFormValidation {
14763
14728
  );
14764
14729
  }
14765
14730
 
14766
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
14767
- if (this.auroInputElements?.length === 2) {
14768
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
14731
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
14732
+
14733
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
14734
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
14735
+ // field (datepicker is the intended consumer — start/end are independently required).
14736
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
14737
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
14769
14738
  hasValue = false;
14770
14739
  }
14771
14740
  }
14772
14741
 
14773
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
14774
-
14775
14742
  if (isCombobox) {
14776
14743
 
14777
14744
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -24594,6 +24561,42 @@ let AuroInputUtilities$1 = class AuroInputUtilities {
24594
24561
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
24595
24562
  }
24596
24563
 
24564
+ /**
24565
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
24566
+ * Single-component formats are checked as integer ranges; multi-component formats use
24567
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
24568
+ * @param {string} value - The user-facing display value.
24569
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
24570
+ * @returns {boolean}
24571
+ */
24572
+ isValidPartialDate(value, format) {
24573
+ if (!value || !format) {
24574
+ return false;
24575
+ }
24576
+ const normalizedFormat = format.toLowerCase();
24577
+
24578
+ if (normalizedFormat === 'dd') {
24579
+ const num = Number(value);
24580
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
24581
+ }
24582
+ if (normalizedFormat === 'yy') {
24583
+ const num = Number(value);
24584
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
24585
+ }
24586
+ if (normalizedFormat === 'yyyy') {
24587
+ const num = Number(value);
24588
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
24589
+ }
24590
+
24591
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
24592
+ // Use the 1st of the current month as the reference so that formats
24593
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
24594
+ const referenceDate = new Date();
24595
+ referenceDate.setDate(1);
24596
+ const parsed = parse$1(value, dateFnsMask, referenceDate);
24597
+ return isValid$1(parsed) && format$1(parsed, dateFnsMask) === value;
24598
+ }
24599
+
24597
24600
  /**
24598
24601
  * Converts a display string to its model value.
24599
24602
  * For full date formats, converts the display string to an ISO date string.
@@ -24641,6 +24644,7 @@ let AuroInputUtilities$1 = class AuroInputUtilities {
24641
24644
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
24642
24645
 
24643
24646
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
24647
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
24644
24648
  return undefined;
24645
24649
  }
24646
24650
 
@@ -27666,7 +27670,7 @@ let AuroBibtemplate$3 = class AuroBibtemplate extends i$3 {
27666
27670
  }
27667
27671
  };
27668
27672
 
27669
- var formkitVersion$2$1 = '202606292156';
27673
+ var formkitVersion$2$1 = '202607011722';
27670
27674
 
27671
27675
  let l$1$2 = class l{generateElementName(t,e){let o=t;return o+="-",o+=e.replace(/[.]/g,"_"),o}generateTag(o,s,a){const r=this.generateElementName(o,s),i=i$2`${s$3(r)}`;return customElements.get(r)||customElements.define(r,class extends a{}),i}};let d$1$2 = class d{registerComponent(t,e){customElements.get(t)||customElements.define(t,class extends e{});}closestElement(t,e=this,o=(e,s=e&&e.closest(t))=>e&&e!==document&&e!==window?s||o(e.getRootNode().host):null){return o(e)}handleComponentTagRename(t,e){const o=e.toLowerCase();t.tagName.toLowerCase()!==o&&t.setAttribute(o,true);}elementMatch(t,e){const o=e.toLowerCase();return t.tagName.toLowerCase()===o||t.hasAttribute(o)}getSlotText(t,e){const o=t.shadowRoot?.querySelector(`slot[name="${e}"]`),s=(o?.assignedNodes({flatten:true})||[]).map(t=>t.textContent?.trim()).join(" ").trim();return s||null}};let h$1$2 = class h{registerComponent(t,e){customElements.get(t)||customElements.define(t,class extends e{});}closestElement(t,e=this,o=(e,s=e&&e.closest(t))=>e&&e!==document&&e!==window?s||o(e.getRootNode().host):null){return o(e)}handleComponentTagRename(t,e){const o=e.toLowerCase();t.tagName.toLowerCase()!==o&&t.setAttribute(o,true);}elementMatch(t,e){const o=e.toLowerCase();return t.tagName.toLowerCase()===o||t.hasAttribute(o)}};var c$1$3=i$6`:host{color:var(--ds-auro-loader-color)}:host>span{background-color:var(--ds-auro-loader-background-color);border-color:var(--ds-auro-loader-border-color)}:host([onlight]),:host([appearance=brand]){--ds-auro-loader-color: var(--ds-basic-color-brand-primary, #01426a)}:host([ondark]),:host([appearance=inverse]){--ds-auro-loader-color: var(--ds-basic-color-texticon-inverse, #ffffff)}:host([orbit])>span{--ds-auro-loader-background-color: transparent}:host([orbit])>span:nth-child(1){--ds-auro-loader-border-color: currentcolor;opacity:.25}:host([orbit])>span:nth-child(2){--ds-auro-loader-border-color: currentcolor;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}
27672
27676
  `,u$4$2=i$6`.body-default{font-size:var(--wcss-body-default-font-size, 1rem);line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-lg{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, .875rem);line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-xs{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs{font-size:var(--wcss-body-xs-font-size, .75rem);line-height:var(--wcss-body-xs-line-height, 1rem)}.body-2xs{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:var(--wcss-body-2xs-font-size, .625rem);font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0);line-height:var(--wcss-body-2xs-line-height, .875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 450);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 450);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, .05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, .05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, .05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, .05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, .05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, .1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(.875rem, 1.1666666667vw, .875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, .1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}:focus:not(:focus-visible){outline:3px solid transparent}:host,:host>span{position:relative}:host{width:2rem;height:2rem;display:inline-block;font-size:0}:host>span{position:absolute;display:inline-block;float:none;top:0;left:0;width:2rem;height:2rem;border-radius:100%;border-style:solid;border-width:0;box-sizing:border-box}:host([xs]),:host([xs])>span{width:1.2rem;height:1.2rem}:host([sm]),:host([sm])>span{width:3rem;height:3rem}:host([md]),:host([md])>span{width:5rem;height:5rem}:host([lg]),:host([lg])>span{width:8rem;height:8rem}:host{--margin: .375rem;--margin-xs: .2rem;--margin-sm: .5rem;--margin-md: .75rem;--margin-lg: 1rem}:host([pulse]),:host([pulse])>span{position:relative}:host([pulse]){width:calc(3rem + var(--margin) * 6);height:calc(1rem + var(--margin) * 2)}:host([pulse])>span{width:1rem;height:1rem;margin:var(--margin);animation:pulse 1.5s ease infinite}:host([pulse][xs]){width:calc(1.95rem + var(--margin-xs) * 6);height:calc(.65rem + var(--margin-xs) * 2)}:host([pulse][xs])>span{margin:var(--margin-xs);width:.65rem;height:.65rem}:host([pulse][sm]){width:calc(6rem + var(--margin-sm) * 6);height:calc(2rem + var(--margin-sm) * 2)}:host([pulse][sm])>span{margin:var(--margin-sm);width:2rem;height:2rem}:host([pulse][md]){width:calc(9rem + var(--margin-md) * 6);height:calc(3rem + var(--margin-md) * 2)}:host([pulse][md])>span{margin:var(--margin-md);width:3rem;height:3rem}:host([pulse][lg]){width:calc(15rem + var(--margin-lg) * 6);height:calc(5rem + var(--margin-lg) * 2)}:host([pulse][lg])>span{margin:var(--margin-lg);width:5rem;height:5rem}:host([pulse])>span:nth-child(1){animation-delay:-.4s}:host([pulse])>span:nth-child(2){animation-delay:-.2s}:host([pulse])>span:nth-child(3){animation-delay:0ms}@keyframes pulse{0%,to{opacity:.1;transform:scale(.9)}50%{opacity:1;transform:scale(1.1)}}:host([orbit]),:host([orbit])>span{opacity:1}:host([orbit])>span{border-width:5px}:host([orbit])>span:nth-child(2){animation:orbit 2s linear infinite}:host([orbit][sm])>span{border-width:8px}:host([orbit][md])>span{border-width:13px}:host([orbit][lg])>span{border-width:21px}@keyframes orbit{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host([ringworm])>svg{animation:rotate 2s linear infinite;height:100%;width:100%;stroke:currentcolor;stroke-width:8}:host([ringworm]) .path{stroke-dashoffset:0;animation:ringworm 1.5s ease-in-out infinite;stroke-linecap:round}@keyframes rotate{to{transform:rotate(360deg)}}@keyframes ringworm{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}:host([laser]){position:static;width:100%;display:block;height:0;overflow:hidden;font-size:unset}:host([laser])>span{position:fixed;width:100%;height:.25rem;border-radius:0;z-index:100}:host([laser])>span:nth-child(1){border-color:currentcolor;opacity:.25}:host([laser])>span:nth-child(2){border-color:currentcolor;animation:laser 2s linear infinite;opacity:1;width:50%}:host([laser][sm])>span:nth-child(2){width:20%}:host([laser][md])>span:nth-child(2){width:30%}:host([laser][lg])>span:nth-child(2){width:50%;animation-duration:1.5s}:host([laser][xl])>span:nth-child(2){width:80%;animation-duration:1.5s}@keyframes laser{0%{left:-100%}to{left:110%}}:host>.no-animation{display:none}@media (prefers-reduced-motion: reduce){:host{display:flex;align-items:center;justify-content:center}:host>span{opacity:1}:host>.loader{display:none}:host>svg{display:none}:host>.no-animation{display:block}}
@@ -33418,7 +33422,7 @@ let AuroHelpText$2$1 = class AuroHelpText extends i$3 {
33418
33422
  }
33419
33423
  };
33420
33424
 
33421
- var formkitVersion$1$3 = '202606292156';
33425
+ var formkitVersion$1$3 = '202607011722';
33422
33426
 
33423
33427
  let AuroElement$2$2 = class AuroElement extends i$3 {
33424
33428
  static get properties() {
@@ -34170,7 +34174,19 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
34170
34174
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
34171
34175
  this.trigger.focus();
34172
34176
  }
34173
- }
34177
+
34178
+
34179
+ if (!this.isPopoverVisible) {
34180
+ // wait til the bib gets fully closed and rendered
34181
+ setTimeout(() => {
34182
+ // check if it's still closed and the focus is still within the dropdown, but not in the bib. If so, move focus to the trigger.
34183
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
34184
+ return;
34185
+ }
34186
+ // Move focus out of bib into trigger.
34187
+ this.trigger.focus();
34188
+ });
34189
+ } }
34174
34190
 
34175
34191
  firstUpdated() {
34176
34192
  // Configure the floater to, this will generate the ID for the bib
@@ -39095,11 +39111,17 @@ let AuroFormValidation$6 = class AuroFormValidation {
39095
39111
  return;
39096
39112
  }
39097
39113
 
39098
- // Validate that the date passed was the correct format and is a valid date
39114
+ // Validate that the date passed was the correct format and is a valid date.
39115
+ // For partial date formats, valueObject is never populated; validate them directly.
39099
39116
  if (elem.value && !elem.valueObject) {
39100
- elem.validity = 'patternMismatch';
39101
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
39102
- return;
39117
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
39118
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
39119
+
39120
+ if (!isValidPartial) {
39121
+ elem.validity = 'patternMismatch';
39122
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
39123
+ return;
39124
+ }
39103
39125
  }
39104
39126
 
39105
39127
  // Perform the rest of the validation
@@ -39193,15 +39215,17 @@ let AuroFormValidation$6 = class AuroFormValidation {
39193
39215
  );
39194
39216
  }
39195
39217
 
39196
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
39197
- if (this.auroInputElements?.length === 2) {
39198
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
39218
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
39219
+
39220
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
39221
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
39222
+ // field (datepicker is the intended consumer — start/end are independently required).
39223
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
39224
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
39199
39225
  hasValue = false;
39200
39226
  }
39201
39227
  }
39202
39228
 
39203
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
39204
-
39205
39229
  if (isCombobox) {
39206
39230
 
39207
39231
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -45101,6 +45125,42 @@ let AuroInputUtilities$2 = class AuroInputUtilities {
45101
45125
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
45102
45126
  }
45103
45127
 
45128
+ /**
45129
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
45130
+ * Single-component formats are checked as integer ranges; multi-component formats use
45131
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
45132
+ * @param {string} value - The user-facing display value.
45133
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
45134
+ * @returns {boolean}
45135
+ */
45136
+ isValidPartialDate(value, format$1) {
45137
+ if (!value || !format$1) {
45138
+ return false;
45139
+ }
45140
+ const normalizedFormat = format$1.toLowerCase();
45141
+
45142
+ if (normalizedFormat === 'dd') {
45143
+ const num = Number(value);
45144
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
45145
+ }
45146
+ if (normalizedFormat === 'yy') {
45147
+ const num = Number(value);
45148
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
45149
+ }
45150
+ if (normalizedFormat === 'yyyy') {
45151
+ const num = Number(value);
45152
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
45153
+ }
45154
+
45155
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
45156
+ // Use the 1st of the current month as the reference so that formats
45157
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
45158
+ const referenceDate = new Date();
45159
+ referenceDate.setDate(1);
45160
+ const parsed = parse$2(value, dateFnsMask, referenceDate);
45161
+ return isValid$2(parsed) && format$2(parsed, dateFnsMask) === value;
45162
+ }
45163
+
45104
45164
  /**
45105
45165
  * Converts a display string to its model value.
45106
45166
  * For full date formats, converts the display string to an ISO date string.
@@ -45148,6 +45208,7 @@ let AuroInputUtilities$2 = class AuroInputUtilities {
45148
45208
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
45149
45209
 
45150
45210
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
45211
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
45151
45212
  return undefined;
45152
45213
  }
45153
45214
 
@@ -45305,6 +45366,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45305
45366
  // so a parent (datepicker/combobox) calling `validate()` synchronously
45306
45367
  // during its own update cycle sees a populated util instance.
45307
45368
  this.activeLabel = false;
45369
+
45308
45370
  /** @private */
45309
45371
  this.allowedInputTypes = [
45310
45372
  "text",
@@ -45315,6 +45377,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45315
45377
  "tel"
45316
45378
  ];
45317
45379
  this.appearance = "default";
45380
+
45318
45381
  /** @private */
45319
45382
  this.dateFormatMap = {
45320
45383
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -45333,23 +45396,24 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45333
45396
  'mm/dd': 'dateMMDD'
45334
45397
  };
45335
45398
  this.disabled = false;
45399
+
45336
45400
  /** @private */
45337
45401
  this.domHandler = new DomHandler$2();
45338
45402
  this.dvInputOnly = false;
45339
45403
  this.hasValue = false;
45340
45404
  this.hideLabelVisually = false;
45341
45405
  this.icon = false;
45406
+
45342
45407
  /** @private */
45343
45408
  this.inputIconName = undefined;
45409
+
45344
45410
  /** @private */
45345
45411
  this.label = 'Input label is undefined';
45346
45412
  this.layout = 'classic';
45347
45413
  this.locale = 'en-US';
45348
45414
  this.max = undefined;
45349
- this._maxObject = undefined;
45350
45415
  this.maxLength = undefined;
45351
45416
  this.min = undefined;
45352
- this._minObject = undefined;
45353
45417
  this.minLength = undefined;
45354
45418
  this.noValidate = false;
45355
45419
  this.onDark = false;
@@ -45366,23 +45430,27 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45366
45430
  "email"
45367
45431
  ];
45368
45432
  this.shape = 'classic';
45433
+
45369
45434
  /** @private */
45370
45435
  this.showPassword = false;
45371
45436
  this.size = 'lg';
45372
45437
  this.touched = false;
45438
+
45373
45439
  /** @private */
45374
45440
  this.uniqueId = new UniqueId$1().create();
45441
+
45375
45442
  /** @private */
45376
45443
  this.util = new AuroInputUtilities$2({
45377
45444
  locale: this.locale,
45378
45445
  format: this.format
45379
45446
  });
45447
+
45380
45448
  /** @private */
45381
45449
  this.validation = new AuroFormValidation$6();
45450
+
45382
45451
  /** @private */
45383
45452
  this.validationCCLength = undefined;
45384
45453
  this.value = undefined;
45385
- this._valueObject = undefined;
45386
45454
  }
45387
45455
 
45388
45456
  // function to define props used within the scope of this component
@@ -45712,6 +45780,13 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45712
45780
  type: String
45713
45781
  },
45714
45782
 
45783
+ /**
45784
+ * Custom help text message to display when validity = `patternMismatch`.
45785
+ */
45786
+ setCustomValidityPatternMismatch: {
45787
+ type: String
45788
+ },
45789
+
45715
45790
  /**
45716
45791
  * Custom help text message to display when validity = `rangeOverflow`.
45717
45792
  */
@@ -45782,7 +45857,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45782
45857
 
45783
45858
  /**
45784
45859
  * Populates the `type` attribute on the input.
45785
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
45860
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
45786
45861
  * @default 'text'
45787
45862
  */
45788
45863
  type: {
@@ -45820,7 +45895,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45820
45895
  * @returns {Date|undefined}
45821
45896
  */
45822
45897
  get valueObject() {
45823
- return this._valueObject || this._computeDateObjectFallback(this.value);
45898
+ return this.value && dateFormatter$2.isValidDate(this.value) ? dateFormatter$2.stringToDateInstance(this.value) : undefined;
45824
45899
  }
45825
45900
 
45826
45901
  /**
@@ -45828,7 +45903,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45828
45903
  * @returns {Date|undefined}
45829
45904
  */
45830
45905
  get minObject() {
45831
- return this._minObject || this._computeDateObjectFallback(this.min);
45906
+ return this.min && dateFormatter$2.isValidDate(this.min) ? dateFormatter$2.stringToDateInstance(this.min) : undefined;
45832
45907
  }
45833
45908
 
45834
45909
  /**
@@ -45836,50 +45911,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45836
45911
  * @returns {Date|undefined}
45837
45912
  */
45838
45913
  get maxObject() {
45839
- return this._maxObject || this._computeDateObjectFallback(this.max);
45840
- }
45841
-
45842
- /**
45843
- * Parses a date string into a Date object when the corresponding `_*Object`
45844
- * field hasn't been synced yet by `updated()`. Returns undefined when the
45845
- * input type/format isn't a full date or the string is not a valid date.
45846
- *
45847
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
45848
- * inside its own `updated()` before this input's `updated()` has run
45849
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
45850
- * and range checks would otherwise silently no-op (flipping the result to
45851
- * `valid` or `patternMismatch`).
45852
- * @private
45853
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
45854
- * @returns {Date|undefined}
45855
- */
45856
- _computeDateObjectFallback(dateStr) {
45857
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
45858
- return undefined;
45859
- }
45860
- if (!dateFormatter$2.isValidDate(dateStr)) {
45861
- return undefined;
45862
- }
45863
- return dateFormatter$2.stringToDateInstance(dateStr);
45864
- }
45865
-
45866
- /**
45867
- * Internal setter for readonly date object properties.
45868
- * @private
45869
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
45870
- * @param {Date|undefined} propertyValue - Value to assign.
45871
- * @returns {void}
45872
- */
45873
- setDateObjectProperty(propertyName, propertyValue) {
45874
- const internalPropertyName = `_${propertyName}`;
45875
- const previousValue = this[internalPropertyName];
45876
-
45877
- if (previousValue === propertyValue) {
45878
- return;
45879
- }
45880
-
45881
- this[internalPropertyName] = propertyValue;
45882
- this.requestUpdate(propertyName, previousValue);
45914
+ return this.max && dateFormatter$2.isValidDate(this.max) ? dateFormatter$2.stringToDateInstance(this.max) : undefined;
45883
45915
  }
45884
45916
 
45885
45917
  connectedCallback() {
@@ -45908,7 +45940,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45908
45940
  format: this.format
45909
45941
  });
45910
45942
  this.configureDataForType();
45911
- this.syncDateValues();
45912
45943
  }
45913
45944
 
45914
45945
  disconnectedCallback() {
@@ -45947,7 +45978,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45947
45978
  this.setCustomHelpTextMessage();
45948
45979
  this.configureAutoFormatting();
45949
45980
  this.configureDataForType();
45950
- this.syncDateValues();
45951
45981
  }
45952
45982
 
45953
45983
  /**
@@ -46091,8 +46121,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46091
46121
  this.configureDataForType();
46092
46122
  }
46093
46123
 
46094
- this.syncDateValues(changedProperties);
46095
-
46096
46124
  if (changedProperties.has('value')) {
46097
46125
  if (this.value && this.value.length > 0) {
46098
46126
  this.hasValue = true;
@@ -46114,14 +46142,14 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46114
46142
 
46115
46143
  if (formattedValue !== this.inputElement.value) {
46116
46144
  this.skipNextProgrammaticInputEvent = true;
46117
- if (this.maskInstance && this.type === 'credit-card') {
46145
+ if (this.maskInstance && this.type !== 'date') {
46118
46146
  // Route through the mask so its _value and el.value stay in lock-step
46119
46147
  // (set value calls updateControl which writes el.value = displayValue).
46120
46148
  // Writing el.value directly leaves the mask thinking displayValue is
46121
- // stale; _saveSelection on the next focus/click then warns. Scoped to
46122
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
46123
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
46124
- // and flip validity from patternMismatch to tooShort.
46149
+ // stale; _saveSelection on the next focus/click then warns. Date is
46150
+ // excluded because its formattedValue can be raw ISO when the calendar
46151
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
46152
+ // flip validity from patternMismatch to tooShort.
46125
46153
  this.maskInstance.value = formattedValue || '';
46126
46154
  } else if (formattedValue) {
46127
46155
  this.inputElement.value = formattedValue;
@@ -46163,120 +46191,65 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46163
46191
  }));
46164
46192
  }
46165
46193
 
46166
-
46167
- /**
46168
- * Synchronizes the ISO string values and Date object representations for date-related properties.
46169
- * This keeps the model and display values aligned when either side changes.
46170
- *
46171
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
46172
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
46173
- * represents a full year/month/day date format.
46174
- *
46175
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
46176
- * @returns {void}
46177
- * @private
46178
- */
46179
- syncDateValues(changedProperties = undefined) {
46180
- if (!this.util.isFullDateFormat(this.type, this.format)) {
46181
- return;
46182
- }
46183
-
46184
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
46185
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
46186
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
46187
- }
46188
-
46189
- /**
46190
- * Synchronizes one date object/string property pair.
46191
- * @private
46192
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
46193
- * @param {string} objectProperty - Date object property name.
46194
- * @param {string} valueProperty - ISO string property name.
46195
- * @returns {void}
46196
- */
46197
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
46198
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
46199
-
46200
- // objectProperty wins over valueProperty when both changed
46201
- if (objectPropertyChanged && this[objectProperty]) {
46202
- this[valueProperty] = dateFormatter$2.toISOFormatString(this[objectProperty]);
46203
- return;
46204
- }
46205
-
46206
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
46207
- if (!valuePropertyChanged) {
46208
- return;
46209
- }
46210
-
46211
- // when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
46212
- if (
46213
- changedProperties &&
46214
- valueProperty === 'value' &&
46215
- changedProperties.get('value') === undefined &&
46216
- this[objectProperty] instanceof Date &&
46217
- this[valueProperty] === dateFormatter$2.toISOFormatString(this[objectProperty])
46218
- ) {
46219
- return;
46220
- }
46221
-
46222
- if (dateFormatter$2.isValidDate(this[valueProperty])) {
46223
- this.setDateObjectProperty(objectProperty, dateFormatter$2.stringToDateInstance(this[valueProperty]));
46224
- } else {
46225
- this.setDateObjectProperty(objectProperty, undefined);
46226
- }
46227
- }
46228
-
46229
46194
  /**
46230
46195
  * Sets up IMasks and logic based on auto-formatting requirements.
46231
46196
  * @private
46232
46197
  * @returns {void}
46233
46198
  */
46234
46199
  configureAutoFormatting() {
46235
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
46236
- // by _configuringMask above) could otherwise trigger handleInput
46237
- // processCreditCard configureAutoFormatting before the outer call's
46238
- // set value has finished its alignCursor pass.
46200
+ // _configuringMask gates two things: external re-entry into this method
46201
+ // while setup is mid-flight (from property changes that call back here),
46202
+ // and the accept/complete listeners below — both need to ignore the mask
46203
+ // events fired by our own value-restore step.
46239
46204
  if (this._configuringMask) return;
46240
46205
  this._configuringMask = true;
46241
46206
  try {
46207
+ // Destroy any prior mask so IMask can attach fresh under the new format.
46208
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
46209
+ // type switched from credit-card to text) the IMask() reassignment
46210
+ // below is skipped, and downstream writes at line ~823 would otherwise
46211
+ // route through the destroyed instance.
46242
46212
  if (this.maskInstance) {
46243
46213
  this.maskInstance.destroy();
46214
+ this.maskInstance = null;
46244
46215
  }
46245
46216
 
46246
- // Pass new format to util
46247
46217
  this.util.updateFormat(this.format);
46248
46218
 
46249
46219
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
46250
46220
 
46251
46221
  if (this.inputElement && maskOptions.mask) {
46252
-
46253
- // Stash and clear any existing value before IMask init.
46254
- // IMask's constructor processes the current input value which requires
46255
- // selection state clearing first avoids that scenario entirely.
46256
- // When the format changes (e.g. locale switch) and we have a valid ISO
46257
- // model value, compute the display string for the NEW format instead of
46258
- // re-using the old display string, which may be invalid in the new mask.
46222
+ // Capture the current display so it can be re-applied after IMask
46223
+ // attaches. The restore at the bottom goes through maskInstance.value
46224
+ // (not inputElement.value directly) so the mask's internal state and
46225
+ // the input's displayed text stay in lock-step.
46259
46226
  let existingValue = this.inputElement.value;
46227
+
46228
+ // Format-change case (e.g. locale switch): existingValue is the OLD
46229
+ // mask's display string and may not parse under the new mask. When
46230
+ // we have a valid date model, rebuild the display from valueObject
46231
+ // (the canonical source) using the new mask's format function.
46260
46232
  if (
46261
46233
  this.util.isFullDateFormat(this.type, this.format) &&
46262
46234
  this.value &&
46263
- dateFormatter$2.isValidDate(this.value) &&
46264
- this.valueObject instanceof Date &&
46265
- !Number.isNaN(this.valueObject.getTime()) &&
46235
+ this.valueObject &&
46266
46236
  typeof maskOptions.format === 'function'
46267
46237
  ) {
46268
46238
  existingValue = maskOptions.format(this.valueObject);
46269
46239
  }
46270
46240
 
46241
+ // Clear before IMask attaches so the constructor seeds an empty
46242
+ // internal value. Otherwise IMask reads the stale unmasked string
46243
+ // and emits a spurious 'accept' before the restore below runs.
46271
46244
  this.skipNextProgrammaticInputEvent = true;
46272
46245
  this.inputElement.value = '';
46273
46246
 
46274
46247
  this.maskInstance = IMask$2(this.inputElement, maskOptions);
46275
46248
 
46249
+ // Mask fires 'accept' on every value change, including the restore
46250
+ // step below. Skip events fired during configureAutoFormatting so
46251
+ // we don't overwrite a value the parent just pushed.
46276
46252
  this.maskInstance.on('accept', () => {
46277
- // Suppress propagation during configureAutoFormatting's own value-restoration
46278
- // (line below) — the mask emits 'accept' on every value-set, including ours,
46279
- // and we don't want to overwrite a value the parent just pushed.
46280
46253
  if (this._configuringMask) return;
46281
46254
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
46282
46255
  if (this.type === "date") {
@@ -46284,6 +46257,8 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46284
46257
  }
46285
46258
  });
46286
46259
 
46260
+ // Mask fires 'complete' on the restore step below for any value that
46261
+ // happens to be a complete match. Same setup-suppression as 'accept'.
46287
46262
  this.maskInstance.on('complete', () => {
46288
46263
  if (this._configuringMask) return;
46289
46264
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -46292,7 +46267,9 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46292
46267
  }
46293
46268
  });
46294
46269
 
46295
- // Restore the stashed value through IMask so it's properly masked
46270
+ // Write existingValue through the mask (not the input directly) so
46271
+ // the mask reformats it under the new rules and keeps its internal
46272
+ // _value aligned with the input's displayed text.
46296
46273
  if (existingValue) {
46297
46274
  this.maskInstance.value = existingValue;
46298
46275
  }
@@ -46386,9 +46363,9 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46386
46363
  // the gated types currently support it, since the list is a public
46387
46364
  // property a consumer could mutate.
46388
46365
  if (this.setSelectionInputTypes.includes(this.type)) {
46389
- let selectionStart;
46366
+ let selectionStart = null;
46390
46367
  try {
46391
- selectionStart = this.inputElement.selectionStart;
46368
+ ({ selectionStart } = this.inputElement);
46392
46369
  } catch (error) { // eslint-disable-line no-unused-vars
46393
46370
  return;
46394
46371
  }
@@ -46492,7 +46469,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46492
46469
  */
46493
46470
  reset() {
46494
46471
  this.value = undefined;
46495
- this.setDateObjectProperty('valueObject', undefined);
46496
46472
  this.validation.reset(this);
46497
46473
  }
46498
46474
 
@@ -46501,7 +46477,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
46501
46477
  */
46502
46478
  clear() {
46503
46479
  this.value = undefined;
46504
- this.setDateObjectProperty('valueObject', undefined);
46505
46480
  }
46506
46481
 
46507
46482
  /**
@@ -47030,7 +47005,7 @@ let AuroHelpText$1$3 = class AuroHelpText extends i$3 {
47030
47005
  }
47031
47006
  };
47032
47007
 
47033
- var formkitVersion$7 = '202606292156';
47008
+ var formkitVersion$7 = '202607011722';
47034
47009
 
47035
47010
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
47036
47011
  // See LICENSE in the project root for license information.
@@ -51326,11 +51301,17 @@ let AuroFormValidation$5 = class AuroFormValidation {
51326
51301
  return;
51327
51302
  }
51328
51303
 
51329
- // Validate that the date passed was the correct format and is a valid date
51304
+ // Validate that the date passed was the correct format and is a valid date.
51305
+ // For partial date formats, valueObject is never populated; validate them directly.
51330
51306
  if (elem.value && !elem.valueObject) {
51331
- elem.validity = 'patternMismatch';
51332
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
51333
- return;
51307
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
51308
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
51309
+
51310
+ if (!isValidPartial) {
51311
+ elem.validity = 'patternMismatch';
51312
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
51313
+ return;
51314
+ }
51334
51315
  }
51335
51316
 
51336
51317
  // Perform the rest of the validation
@@ -51424,15 +51405,17 @@ let AuroFormValidation$5 = class AuroFormValidation {
51424
51405
  );
51425
51406
  }
51426
51407
 
51427
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
51428
- if (this.auroInputElements?.length === 2) {
51429
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
51408
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
51409
+
51410
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
51411
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
51412
+ // field (datepicker is the intended consumer — start/end are independently required).
51413
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
51414
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
51430
51415
  hasValue = false;
51431
51416
  }
51432
51417
  }
51433
51418
 
51434
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
51435
-
51436
51419
  if (isCombobox) {
51437
51420
 
51438
51421
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -51897,7 +51880,7 @@ let AuroHelpText$1$2 = class AuroHelpText extends i$3 {
51897
51880
  }
51898
51881
  };
51899
51882
 
51900
- var formkitVersion$1$2 = '202606292156';
51883
+ var formkitVersion$1$2 = '202607011722';
51901
51884
 
51902
51885
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
51903
51886
  // See LICENSE in the project root for license information.
@@ -56225,7 +56208,7 @@ let AuroHelpText$6 = class AuroHelpText extends i$3 {
56225
56208
  }
56226
56209
  };
56227
56210
 
56228
- var formkitVersion$6 = '202606292156';
56211
+ var formkitVersion$6 = '202607011722';
56229
56212
 
56230
56213
  let AuroElement$1$2 = class AuroElement extends i$3 {
56231
56214
  static get properties() {
@@ -56977,7 +56960,19 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
56977
56960
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
56978
56961
  this.trigger.focus();
56979
56962
  }
56980
- }
56963
+
56964
+
56965
+ if (!this.isPopoverVisible) {
56966
+ // wait til the bib gets fully closed and rendered
56967
+ setTimeout(() => {
56968
+ // check if it's still closed and the focus is still within the dropdown, but not in the bib. If so, move focus to the trigger.
56969
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
56970
+ return;
56971
+ }
56972
+ // Move focus out of bib into trigger.
56973
+ this.trigger.focus();
56974
+ });
56975
+ } }
56981
56976
 
56982
56977
  firstUpdated() {
56983
56978
  // Configure the floater to, this will generate the ID for the bib
@@ -59676,11 +59671,17 @@ let AuroFormValidation$4 = class AuroFormValidation {
59676
59671
  return;
59677
59672
  }
59678
59673
 
59679
- // Validate that the date passed was the correct format and is a valid date
59674
+ // Validate that the date passed was the correct format and is a valid date.
59675
+ // For partial date formats, valueObject is never populated; validate them directly.
59680
59676
  if (elem.value && !elem.valueObject) {
59681
- elem.validity = 'patternMismatch';
59682
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
59683
- return;
59677
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
59678
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
59679
+
59680
+ if (!isValidPartial) {
59681
+ elem.validity = 'patternMismatch';
59682
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
59683
+ return;
59684
+ }
59684
59685
  }
59685
59686
 
59686
59687
  // Perform the rest of the validation
@@ -59774,15 +59775,17 @@ let AuroFormValidation$4 = class AuroFormValidation {
59774
59775
  );
59775
59776
  }
59776
59777
 
59777
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
59778
- if (this.auroInputElements?.length === 2) {
59779
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
59778
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
59779
+
59780
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
59781
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
59782
+ // field (datepicker is the intended consumer — start/end are independently required).
59783
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
59784
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
59780
59785
  hasValue = false;
59781
59786
  }
59782
59787
  }
59783
59788
 
59784
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
59785
-
59786
59789
  if (isCombobox) {
59787
59790
 
59788
59791
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -60173,7 +60176,7 @@ let AuroHelpText$5 = class AuroHelpText extends i$3 {
60173
60176
  }
60174
60177
  };
60175
60178
 
60176
- var formkitVersion$5 = '202606292156';
60179
+ var formkitVersion$5 = '202607011722';
60177
60180
 
60178
60181
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
60179
60182
  // See LICENSE in the project root for license information.
@@ -61422,11 +61425,17 @@ let AuroFormValidation$3 = class AuroFormValidation {
61422
61425
  return;
61423
61426
  }
61424
61427
 
61425
- // Validate that the date passed was the correct format and is a valid date
61428
+ // Validate that the date passed was the correct format and is a valid date.
61429
+ // For partial date formats, valueObject is never populated; validate them directly.
61426
61430
  if (elem.value && !elem.valueObject) {
61427
- elem.validity = 'patternMismatch';
61428
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
61429
- return;
61431
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
61432
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
61433
+
61434
+ if (!isValidPartial) {
61435
+ elem.validity = 'patternMismatch';
61436
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
61437
+ return;
61438
+ }
61430
61439
  }
61431
61440
 
61432
61441
  // Perform the rest of the validation
@@ -61520,15 +61529,17 @@ let AuroFormValidation$3 = class AuroFormValidation {
61520
61529
  );
61521
61530
  }
61522
61531
 
61523
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
61524
- if (this.auroInputElements?.length === 2) {
61525
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
61532
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
61533
+
61534
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
61535
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
61536
+ // field (datepicker is the intended consumer — start/end are independently required).
61537
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
61538
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
61526
61539
  hasValue = false;
61527
61540
  }
61528
61541
  }
61529
61542
 
61530
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
61531
-
61532
61543
  if (isCombobox) {
61533
61544
 
61534
61545
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -61923,7 +61934,7 @@ let AuroHelpText$4 = class AuroHelpText extends i$3 {
61923
61934
  }
61924
61935
  };
61925
61936
 
61926
- var formkitVersion$4 = '202606292156';
61937
+ var formkitVersion$4 = '202607011722';
61927
61938
 
61928
61939
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
61929
61940
  // See LICENSE in the project root for license information.
@@ -62682,11 +62693,17 @@ let AuroFormValidation$1 = class AuroFormValidation {
62682
62693
  return;
62683
62694
  }
62684
62695
 
62685
- // Validate that the date passed was the correct format and is a valid date
62696
+ // Validate that the date passed was the correct format and is a valid date.
62697
+ // For partial date formats, valueObject is never populated; validate them directly.
62686
62698
  if (elem.value && !elem.valueObject) {
62687
- elem.validity = 'patternMismatch';
62688
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
62689
- return;
62699
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
62700
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
62701
+
62702
+ if (!isValidPartial) {
62703
+ elem.validity = 'patternMismatch';
62704
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
62705
+ return;
62706
+ }
62690
62707
  }
62691
62708
 
62692
62709
  // Perform the rest of the validation
@@ -62780,15 +62797,17 @@ let AuroFormValidation$1 = class AuroFormValidation {
62780
62797
  );
62781
62798
  }
62782
62799
 
62783
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
62784
- if (this.auroInputElements?.length === 2) {
62785
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
62800
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
62801
+
62802
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
62803
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
62804
+ // field (datepicker is the intended consumer — start/end are independently required).
62805
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
62806
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
62786
62807
  hasValue = false;
62787
62808
  }
62788
62809
  }
62789
62810
 
62790
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
62791
-
62792
62811
  if (isCombobox) {
62793
62812
 
62794
62813
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -63099,6 +63118,8 @@ function navigateArrow$1(component, direction, options = {}) {
63099
63118
  }
63100
63119
  }
63101
63120
 
63121
+ /* eslint-disable no-underscore-dangle */
63122
+
63102
63123
  /**
63103
63124
  * Returns the clear button element from the active input's shadow
63104
63125
  * DOM, if available.
@@ -63134,11 +63155,9 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
63134
63155
  * @param {Object} menu - The menu component.
63135
63156
  */
63136
63157
  function reconcileMenuIndex(menu) {
63137
- // eslint-disable-next-line no-underscore-dangle
63138
63158
  if (menu._index < 0 && menu.optionActive && menu.items) {
63139
63159
  const idx = menu.items.indexOf(menu.optionActive);
63140
63160
  if (idx >= 0) {
63141
- // eslint-disable-next-line no-underscore-dangle
63142
63161
  menu._index = idx;
63143
63162
  }
63144
63163
  }
@@ -63157,11 +63176,7 @@ const comboboxKeyboardStrategy = {
63157
63176
 
63158
63177
  // navigate if bib is open otherwise open it
63159
63178
  if (component.dropdown.isPopoverVisible) {
63160
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
63161
- component.activateLastEnabledAvailableOption();
63162
- } else {
63163
- navigateArrow$1(component, 'down');
63164
- }
63179
+ navigateArrow$1(component, 'down');
63165
63180
  } else {
63166
63181
  component.showBib();
63167
63182
  }
@@ -63180,11 +63195,7 @@ const comboboxKeyboardStrategy = {
63180
63195
 
63181
63196
  // navigate if bib is open otherwise open it
63182
63197
  if (component.dropdown.isPopoverVisible) {
63183
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
63184
- component.activateFirstEnabledAvailableOption();
63185
- } else {
63186
- navigateArrow$1(component, 'up');
63187
- }
63198
+ navigateArrow$1(component, 'up');
63188
63199
  } else {
63189
63200
  component.showBib();
63190
63201
  }
@@ -63200,13 +63211,18 @@ const comboboxKeyboardStrategy = {
63200
63211
  },
63201
63212
 
63202
63213
  Enter(component, evt, ctx) {
63214
+ // Forms should not submit on Enter from a combobox, regardless of which
63215
+ // child element (input, clear button, menu) is focused.
63216
+ evt.stopPropagation();
63217
+
63203
63218
  if (isClearBtnFocused(ctx)) {
63204
- // If the clear button has focus, let the browser activate it normally.
63205
- // stopPropagation prevents parent containers (e.g., forms) from treating
63206
- // Enter as a submit, but we must NOT call preventDefault — that would
63207
- // block the browser's built-in "Enter activates focused button" behavior.
63208
- evt.stopPropagation();
63209
- } else if (ctx.isExpanded && component.menu.optionActive) {
63219
+ // Let the browser dispatch Enter to the focused clear button so its
63220
+ // built-in activation fires and clears the selection. Do NOT call
63221
+ // preventDefault — that would block the activation.
63222
+ return;
63223
+ }
63224
+
63225
+ if (ctx.isExpanded && component.menu.optionActive) {
63210
63226
  reconcileMenuIndex(component.menu);
63211
63227
  component.menu.makeSelection();
63212
63228
 
@@ -63215,14 +63231,8 @@ const comboboxKeyboardStrategy = {
63215
63231
  }
63216
63232
 
63217
63233
  evt.preventDefault();
63218
- evt.stopPropagation();
63219
63234
  } else {
63220
- // Prevent the keypress from bubbling to parent containers (e.g., forms)
63221
- // which could interpret Enter as a submit or trigger other unintended behavior.
63222
- // This is safe because showBib() opens the dialog programmatically,
63223
- // not via event propagation.
63224
63235
  evt.preventDefault();
63225
- evt.stopPropagation();
63226
63236
  component.showBib();
63227
63237
  }
63228
63238
  },
@@ -63267,7 +63277,7 @@ const comboboxKeyboardStrategy = {
63267
63277
  component.setClearBtnFocus();
63268
63278
  }
63269
63279
  }
63270
- },
63280
+ }
63271
63281
  };
63272
63282
 
63273
63283
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
@@ -67138,7 +67148,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
67138
67148
  }
67139
67149
  };
67140
67150
 
67141
- var formkitVersion$2 = '202606292156';
67151
+ var formkitVersion$2 = '202607011722';
67142
67152
 
67143
67153
  let AuroElement$2$1 = class AuroElement extends i$3 {
67144
67154
  static get properties() {
@@ -67890,7 +67900,19 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
67890
67900
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
67891
67901
  this.trigger.focus();
67892
67902
  }
67893
- }
67903
+
67904
+
67905
+ if (!this.isPopoverVisible) {
67906
+ // wait til the bib gets fully closed and rendered
67907
+ setTimeout(() => {
67908
+ // check if it's still closed and the focus is still within the dropdown, but not in the bib. If so, move focus to the trigger.
67909
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
67910
+ return;
67911
+ }
67912
+ // Move focus out of bib into trigger.
67913
+ this.trigger.focus();
67914
+ });
67915
+ } }
67894
67916
 
67895
67917
  firstUpdated() {
67896
67918
  // Configure the floater to, this will generate the ID for the bib
@@ -72815,11 +72837,17 @@ let AuroFormValidation$2 = class AuroFormValidation {
72815
72837
  return;
72816
72838
  }
72817
72839
 
72818
- // Validate that the date passed was the correct format and is a valid date
72840
+ // Validate that the date passed was the correct format and is a valid date.
72841
+ // For partial date formats, valueObject is never populated; validate them directly.
72819
72842
  if (elem.value && !elem.valueObject) {
72820
- elem.validity = 'patternMismatch';
72821
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
72822
- return;
72843
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
72844
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
72845
+
72846
+ if (!isValidPartial) {
72847
+ elem.validity = 'patternMismatch';
72848
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
72849
+ return;
72850
+ }
72823
72851
  }
72824
72852
 
72825
72853
  // Perform the rest of the validation
@@ -72913,15 +72941,17 @@ let AuroFormValidation$2 = class AuroFormValidation {
72913
72941
  );
72914
72942
  }
72915
72943
 
72916
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
72917
- if (this.auroInputElements?.length === 2) {
72918
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
72944
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
72945
+
72946
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
72947
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
72948
+ // field (datepicker is the intended consumer — start/end are independently required).
72949
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
72950
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
72919
72951
  hasValue = false;
72920
72952
  }
72921
72953
  }
72922
72954
 
72923
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
72924
-
72925
72955
  if (isCombobox) {
72926
72956
 
72927
72957
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -78821,6 +78851,42 @@ class AuroInputUtilities {
78821
78851
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
78822
78852
  }
78823
78853
 
78854
+ /**
78855
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
78856
+ * Single-component formats are checked as integer ranges; multi-component formats use
78857
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
78858
+ * @param {string} value - The user-facing display value.
78859
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
78860
+ * @returns {boolean}
78861
+ */
78862
+ isValidPartialDate(value, format$1) {
78863
+ if (!value || !format$1) {
78864
+ return false;
78865
+ }
78866
+ const normalizedFormat = format$1.toLowerCase();
78867
+
78868
+ if (normalizedFormat === 'dd') {
78869
+ const num = Number(value);
78870
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
78871
+ }
78872
+ if (normalizedFormat === 'yy') {
78873
+ const num = Number(value);
78874
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
78875
+ }
78876
+ if (normalizedFormat === 'yyyy') {
78877
+ const num = Number(value);
78878
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
78879
+ }
78880
+
78881
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
78882
+ // Use the 1st of the current month as the reference so that formats
78883
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
78884
+ const referenceDate = new Date();
78885
+ referenceDate.setDate(1);
78886
+ const parsed = parse(value, dateFnsMask, referenceDate);
78887
+ return isValid(parsed) && format(parsed, dateFnsMask) === value;
78888
+ }
78889
+
78824
78890
  /**
78825
78891
  * Converts a display string to its model value.
78826
78892
  * For full date formats, converts the display string to an ISO date string.
@@ -78868,6 +78934,7 @@ class AuroInputUtilities {
78868
78934
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
78869
78935
 
78870
78936
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
78937
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
78871
78938
  return undefined;
78872
78939
  }
78873
78940
 
@@ -79025,6 +79092,7 @@ class BaseInput extends AuroElement$1$1 {
79025
79092
  // so a parent (datepicker/combobox) calling `validate()` synchronously
79026
79093
  // during its own update cycle sees a populated util instance.
79027
79094
  this.activeLabel = false;
79095
+
79028
79096
  /** @private */
79029
79097
  this.allowedInputTypes = [
79030
79098
  "text",
@@ -79035,6 +79103,7 @@ class BaseInput extends AuroElement$1$1 {
79035
79103
  "tel"
79036
79104
  ];
79037
79105
  this.appearance = "default";
79106
+
79038
79107
  /** @private */
79039
79108
  this.dateFormatMap = {
79040
79109
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -79053,23 +79122,24 @@ class BaseInput extends AuroElement$1$1 {
79053
79122
  'mm/dd': 'dateMMDD'
79054
79123
  };
79055
79124
  this.disabled = false;
79125
+
79056
79126
  /** @private */
79057
79127
  this.domHandler = new DomHandler();
79058
79128
  this.dvInputOnly = false;
79059
79129
  this.hasValue = false;
79060
79130
  this.hideLabelVisually = false;
79061
79131
  this.icon = false;
79132
+
79062
79133
  /** @private */
79063
79134
  this.inputIconName = undefined;
79135
+
79064
79136
  /** @private */
79065
79137
  this.label = 'Input label is undefined';
79066
79138
  this.layout = 'classic';
79067
79139
  this.locale = 'en-US';
79068
79140
  this.max = undefined;
79069
- this._maxObject = undefined;
79070
79141
  this.maxLength = undefined;
79071
79142
  this.min = undefined;
79072
- this._minObject = undefined;
79073
79143
  this.minLength = undefined;
79074
79144
  this.noValidate = false;
79075
79145
  this.onDark = false;
@@ -79086,23 +79156,27 @@ class BaseInput extends AuroElement$1$1 {
79086
79156
  "email"
79087
79157
  ];
79088
79158
  this.shape = 'classic';
79159
+
79089
79160
  /** @private */
79090
79161
  this.showPassword = false;
79091
79162
  this.size = 'lg';
79092
79163
  this.touched = false;
79164
+
79093
79165
  /** @private */
79094
79166
  this.uniqueId = new UniqueId().create();
79167
+
79095
79168
  /** @private */
79096
79169
  this.util = new AuroInputUtilities({
79097
79170
  locale: this.locale,
79098
79171
  format: this.format
79099
79172
  });
79173
+
79100
79174
  /** @private */
79101
79175
  this.validation = new AuroFormValidation$2();
79176
+
79102
79177
  /** @private */
79103
79178
  this.validationCCLength = undefined;
79104
79179
  this.value = undefined;
79105
- this._valueObject = undefined;
79106
79180
  }
79107
79181
 
79108
79182
  // function to define props used within the scope of this component
@@ -79432,6 +79506,13 @@ class BaseInput extends AuroElement$1$1 {
79432
79506
  type: String
79433
79507
  },
79434
79508
 
79509
+ /**
79510
+ * Custom help text message to display when validity = `patternMismatch`.
79511
+ */
79512
+ setCustomValidityPatternMismatch: {
79513
+ type: String
79514
+ },
79515
+
79435
79516
  /**
79436
79517
  * Custom help text message to display when validity = `rangeOverflow`.
79437
79518
  */
@@ -79502,7 +79583,7 @@ class BaseInput extends AuroElement$1$1 {
79502
79583
 
79503
79584
  /**
79504
79585
  * Populates the `type` attribute on the input.
79505
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
79586
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
79506
79587
  * @default 'text'
79507
79588
  */
79508
79589
  type: {
@@ -79540,7 +79621,7 @@ class BaseInput extends AuroElement$1$1 {
79540
79621
  * @returns {Date|undefined}
79541
79622
  */
79542
79623
  get valueObject() {
79543
- return this._valueObject || this._computeDateObjectFallback(this.value);
79624
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
79544
79625
  }
79545
79626
 
79546
79627
  /**
@@ -79548,7 +79629,7 @@ class BaseInput extends AuroElement$1$1 {
79548
79629
  * @returns {Date|undefined}
79549
79630
  */
79550
79631
  get minObject() {
79551
- return this._minObject || this._computeDateObjectFallback(this.min);
79632
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
79552
79633
  }
79553
79634
 
79554
79635
  /**
@@ -79556,50 +79637,7 @@ class BaseInput extends AuroElement$1$1 {
79556
79637
  * @returns {Date|undefined}
79557
79638
  */
79558
79639
  get maxObject() {
79559
- return this._maxObject || this._computeDateObjectFallback(this.max);
79560
- }
79561
-
79562
- /**
79563
- * Parses a date string into a Date object when the corresponding `_*Object`
79564
- * field hasn't been synced yet by `updated()`. Returns undefined when the
79565
- * input type/format isn't a full date or the string is not a valid date.
79566
- *
79567
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
79568
- * inside its own `updated()` before this input's `updated()` has run
79569
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
79570
- * and range checks would otherwise silently no-op (flipping the result to
79571
- * `valid` or `patternMismatch`).
79572
- * @private
79573
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
79574
- * @returns {Date|undefined}
79575
- */
79576
- _computeDateObjectFallback(dateStr) {
79577
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
79578
- return undefined;
79579
- }
79580
- if (!dateFormatter.isValidDate(dateStr)) {
79581
- return undefined;
79582
- }
79583
- return dateFormatter.stringToDateInstance(dateStr);
79584
- }
79585
-
79586
- /**
79587
- * Internal setter for readonly date object properties.
79588
- * @private
79589
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
79590
- * @param {Date|undefined} propertyValue - Value to assign.
79591
- * @returns {void}
79592
- */
79593
- setDateObjectProperty(propertyName, propertyValue) {
79594
- const internalPropertyName = `_${propertyName}`;
79595
- const previousValue = this[internalPropertyName];
79596
-
79597
- if (previousValue === propertyValue) {
79598
- return;
79599
- }
79600
-
79601
- this[internalPropertyName] = propertyValue;
79602
- this.requestUpdate(propertyName, previousValue);
79640
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
79603
79641
  }
79604
79642
 
79605
79643
  connectedCallback() {
@@ -79628,7 +79666,6 @@ class BaseInput extends AuroElement$1$1 {
79628
79666
  format: this.format
79629
79667
  });
79630
79668
  this.configureDataForType();
79631
- this.syncDateValues();
79632
79669
  }
79633
79670
 
79634
79671
  disconnectedCallback() {
@@ -79667,7 +79704,6 @@ class BaseInput extends AuroElement$1$1 {
79667
79704
  this.setCustomHelpTextMessage();
79668
79705
  this.configureAutoFormatting();
79669
79706
  this.configureDataForType();
79670
- this.syncDateValues();
79671
79707
  }
79672
79708
 
79673
79709
  /**
@@ -79811,8 +79847,6 @@ class BaseInput extends AuroElement$1$1 {
79811
79847
  this.configureDataForType();
79812
79848
  }
79813
79849
 
79814
- this.syncDateValues(changedProperties);
79815
-
79816
79850
  if (changedProperties.has('value')) {
79817
79851
  if (this.value && this.value.length > 0) {
79818
79852
  this.hasValue = true;
@@ -79834,14 +79868,14 @@ class BaseInput extends AuroElement$1$1 {
79834
79868
 
79835
79869
  if (formattedValue !== this.inputElement.value) {
79836
79870
  this.skipNextProgrammaticInputEvent = true;
79837
- if (this.maskInstance && this.type === 'credit-card') {
79871
+ if (this.maskInstance && this.type !== 'date') {
79838
79872
  // Route through the mask so its _value and el.value stay in lock-step
79839
79873
  // (set value calls updateControl which writes el.value = displayValue).
79840
79874
  // Writing el.value directly leaves the mask thinking displayValue is
79841
- // stale; _saveSelection on the next focus/click then warns. Scoped to
79842
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
79843
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
79844
- // and flip validity from patternMismatch to tooShort.
79875
+ // stale; _saveSelection on the next focus/click then warns. Date is
79876
+ // excluded because its formattedValue can be raw ISO when the calendar
79877
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
79878
+ // flip validity from patternMismatch to tooShort.
79845
79879
  this.maskInstance.value = formattedValue || '';
79846
79880
  } else if (formattedValue) {
79847
79881
  this.inputElement.value = formattedValue;
@@ -79883,120 +79917,65 @@ class BaseInput extends AuroElement$1$1 {
79883
79917
  }));
79884
79918
  }
79885
79919
 
79886
-
79887
- /**
79888
- * Synchronizes the ISO string values and Date object representations for date-related properties.
79889
- * This keeps the model and display values aligned when either side changes.
79890
- *
79891
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
79892
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
79893
- * represents a full year/month/day date format.
79894
- *
79895
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
79896
- * @returns {void}
79897
- * @private
79898
- */
79899
- syncDateValues(changedProperties = undefined) {
79900
- if (!this.util.isFullDateFormat(this.type, this.format)) {
79901
- return;
79902
- }
79903
-
79904
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
79905
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
79906
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
79907
- }
79908
-
79909
- /**
79910
- * Synchronizes one date object/string property pair.
79911
- * @private
79912
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
79913
- * @param {string} objectProperty - Date object property name.
79914
- * @param {string} valueProperty - ISO string property name.
79915
- * @returns {void}
79916
- */
79917
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
79918
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
79919
-
79920
- // objectProperty wins over valueProperty when both changed
79921
- if (objectPropertyChanged && this[objectProperty]) {
79922
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
79923
- return;
79924
- }
79925
-
79926
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
79927
- if (!valuePropertyChanged) {
79928
- return;
79929
- }
79930
-
79931
- // when value is newly set to the same ISO string that corresponds to the existing Date object, do not clear the Date object (avoid unnecessary updates)
79932
- if (
79933
- changedProperties &&
79934
- valueProperty === 'value' &&
79935
- changedProperties.get('value') === undefined &&
79936
- this[objectProperty] instanceof Date &&
79937
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
79938
- ) {
79939
- return;
79940
- }
79941
-
79942
- if (dateFormatter.isValidDate(this[valueProperty])) {
79943
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
79944
- } else {
79945
- this.setDateObjectProperty(objectProperty, undefined);
79946
- }
79947
- }
79948
-
79949
79920
  /**
79950
79921
  * Sets up IMasks and logic based on auto-formatting requirements.
79951
79922
  * @private
79952
79923
  * @returns {void}
79953
79924
  */
79954
79925
  configureAutoFormatting() {
79955
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
79956
- // by _configuringMask above) could otherwise trigger handleInput
79957
- // processCreditCard configureAutoFormatting before the outer call's
79958
- // set value has finished its alignCursor pass.
79926
+ // _configuringMask gates two things: external re-entry into this method
79927
+ // while setup is mid-flight (from property changes that call back here),
79928
+ // and the accept/complete listeners below — both need to ignore the mask
79929
+ // events fired by our own value-restore step.
79959
79930
  if (this._configuringMask) return;
79960
79931
  this._configuringMask = true;
79961
79932
  try {
79933
+ // Destroy any prior mask so IMask can attach fresh under the new format.
79934
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
79935
+ // type switched from credit-card to text) the IMask() reassignment
79936
+ // below is skipped, and downstream writes at line ~823 would otherwise
79937
+ // route through the destroyed instance.
79962
79938
  if (this.maskInstance) {
79963
79939
  this.maskInstance.destroy();
79940
+ this.maskInstance = null;
79964
79941
  }
79965
79942
 
79966
- // Pass new format to util
79967
79943
  this.util.updateFormat(this.format);
79968
79944
 
79969
79945
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
79970
79946
 
79971
79947
  if (this.inputElement && maskOptions.mask) {
79972
-
79973
- // Stash and clear any existing value before IMask init.
79974
- // IMask's constructor processes the current input value which requires
79975
- // selection state clearing first avoids that scenario entirely.
79976
- // When the format changes (e.g. locale switch) and we have a valid ISO
79977
- // model value, compute the display string for the NEW format instead of
79978
- // re-using the old display string, which may be invalid in the new mask.
79948
+ // Capture the current display so it can be re-applied after IMask
79949
+ // attaches. The restore at the bottom goes through maskInstance.value
79950
+ // (not inputElement.value directly) so the mask's internal state and
79951
+ // the input's displayed text stay in lock-step.
79979
79952
  let existingValue = this.inputElement.value;
79953
+
79954
+ // Format-change case (e.g. locale switch): existingValue is the OLD
79955
+ // mask's display string and may not parse under the new mask. When
79956
+ // we have a valid date model, rebuild the display from valueObject
79957
+ // (the canonical source) using the new mask's format function.
79980
79958
  if (
79981
79959
  this.util.isFullDateFormat(this.type, this.format) &&
79982
79960
  this.value &&
79983
- dateFormatter.isValidDate(this.value) &&
79984
- this.valueObject instanceof Date &&
79985
- !Number.isNaN(this.valueObject.getTime()) &&
79961
+ this.valueObject &&
79986
79962
  typeof maskOptions.format === 'function'
79987
79963
  ) {
79988
79964
  existingValue = maskOptions.format(this.valueObject);
79989
79965
  }
79990
79966
 
79967
+ // Clear before IMask attaches so the constructor seeds an empty
79968
+ // internal value. Otherwise IMask reads the stale unmasked string
79969
+ // and emits a spurious 'accept' before the restore below runs.
79991
79970
  this.skipNextProgrammaticInputEvent = true;
79992
79971
  this.inputElement.value = '';
79993
79972
 
79994
79973
  this.maskInstance = IMask(this.inputElement, maskOptions);
79995
79974
 
79975
+ // Mask fires 'accept' on every value change, including the restore
79976
+ // step below. Skip events fired during configureAutoFormatting so
79977
+ // we don't overwrite a value the parent just pushed.
79996
79978
  this.maskInstance.on('accept', () => {
79997
- // Suppress propagation during configureAutoFormatting's own value-restoration
79998
- // (line below) — the mask emits 'accept' on every value-set, including ours,
79999
- // and we don't want to overwrite a value the parent just pushed.
80000
79979
  if (this._configuringMask) return;
80001
79980
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
80002
79981
  if (this.type === "date") {
@@ -80004,6 +79983,8 @@ class BaseInput extends AuroElement$1$1 {
80004
79983
  }
80005
79984
  });
80006
79985
 
79986
+ // Mask fires 'complete' on the restore step below for any value that
79987
+ // happens to be a complete match. Same setup-suppression as 'accept'.
80007
79988
  this.maskInstance.on('complete', () => {
80008
79989
  if (this._configuringMask) return;
80009
79990
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -80012,7 +79993,9 @@ class BaseInput extends AuroElement$1$1 {
80012
79993
  }
80013
79994
  });
80014
79995
 
80015
- // Restore the stashed value through IMask so it's properly masked
79996
+ // Write existingValue through the mask (not the input directly) so
79997
+ // the mask reformats it under the new rules and keeps its internal
79998
+ // _value aligned with the input's displayed text.
80016
79999
  if (existingValue) {
80017
80000
  this.maskInstance.value = existingValue;
80018
80001
  }
@@ -80106,9 +80089,9 @@ class BaseInput extends AuroElement$1$1 {
80106
80089
  // the gated types currently support it, since the list is a public
80107
80090
  // property a consumer could mutate.
80108
80091
  if (this.setSelectionInputTypes.includes(this.type)) {
80109
- let selectionStart;
80092
+ let selectionStart = null;
80110
80093
  try {
80111
- selectionStart = this.inputElement.selectionStart;
80094
+ ({ selectionStart } = this.inputElement);
80112
80095
  } catch (error) { // eslint-disable-line no-unused-vars
80113
80096
  return;
80114
80097
  }
@@ -80212,7 +80195,6 @@ class BaseInput extends AuroElement$1$1 {
80212
80195
  */
80213
80196
  reset() {
80214
80197
  this.value = undefined;
80215
- this.setDateObjectProperty('valueObject', undefined);
80216
80198
  this.validation.reset(this);
80217
80199
  }
80218
80200
 
@@ -80221,7 +80203,6 @@ class BaseInput extends AuroElement$1$1 {
80221
80203
  */
80222
80204
  clear() {
80223
80205
  this.value = undefined;
80224
- this.setDateObjectProperty('valueObject', undefined);
80225
80206
  }
80226
80207
 
80227
80208
  /**
@@ -80750,7 +80731,7 @@ let AuroHelpText$1$1 = class AuroHelpText extends i$3 {
80750
80731
  }
80751
80732
  };
80752
80733
 
80753
- var formkitVersion$1$1 = '202606292156';
80734
+ var formkitVersion$1$1 = '202607011722';
80754
80735
 
80755
80736
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
80756
80737
  // See LICENSE in the project root for license information.
@@ -81876,7 +81857,7 @@ let AuroBibtemplate$1 = class AuroBibtemplate extends i$3 {
81876
81857
  }
81877
81858
  };
81878
81859
 
81879
- var formkitVersion$3 = '202606292156';
81860
+ var formkitVersion$3 = '202607011722';
81880
81861
 
81881
81862
  var styleCss$1$3 = i$6`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
81882
81863
 
@@ -82244,12 +82225,23 @@ function getOptionLabel(option) {
82244
82225
  if (!option) {
82245
82226
  return '';
82246
82227
  }
82247
- const clone = option.cloneNode(true);
82248
- const displayValueEl = clone.querySelector('[slot="displayValue"]');
82249
- if (displayValueEl) {
82250
- displayValueEl.remove();
82228
+
82229
+ // Consumer-provided override: short-circuit the DOM walk entirely.
82230
+ if (option.dataset && option.dataset.label) {
82231
+ return option.dataset.label;
82251
82232
  }
82252
- return (clone.textContent || '').replace(/\s+/gu, ' ').trim();
82233
+
82234
+ // Walk direct children — the `slot` attribute only applies to direct children
82235
+ // of the slot host, so a shallow filter is sufficient. Avoids the cloneNode +
82236
+ // querySelector allocation that ran on every keystroke via syncValuesAndStates.
82237
+ let text = '';
82238
+ for (const node of option.childNodes) {
82239
+ const isDisplayValueSlot = node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'displayValue';
82240
+ if (!isDisplayValueSlot) {
82241
+ text += node.textContent || '';
82242
+ }
82243
+ }
82244
+ return text.replace(/\s+/gu, ' ').trim();
82253
82245
  }
82254
82246
 
82255
82247
  // See https://git.io/JJ6SJ for "How to document your components using JSDoc"
@@ -82324,8 +82316,6 @@ class AuroCombobox extends AuroElement$3 {
82324
82316
  this.availableOptions = [];
82325
82317
  this.dropdownId = undefined;
82326
82318
  this.dropdownOpen = false;
82327
- this.triggerExpandedState = false;
82328
- this._expandedTimeout = null;
82329
82319
  this._inFullscreenTransition = false;
82330
82320
  this.errorMessage = null;
82331
82321
  this.isHiddenWhileLoading = false;
@@ -82336,6 +82326,30 @@ class AuroCombobox extends AuroElement$3 {
82336
82326
  this.touched = false;
82337
82327
  this.validation = new AuroFormValidation$1();
82338
82328
  this.validity = undefined;
82329
+ this._userTyped = false;
82330
+ // Tracks every setTimeout scheduled via _scheduleTimer so
82331
+ // disconnectedCallback can cancel them. Without this, a detached
82332
+ // combobox's pending timers still fire — most are no-ops, but
82333
+ // configureMenu's racing-condition retry would otherwise loop.
82334
+ this._pendingTimers = new Set();
82335
+ }
82336
+
82337
+ /**
82338
+ * setTimeout wrapper that records the timer id so disconnectedCallback
82339
+ * can cancel any outstanding callbacks. The id is removed from the set
82340
+ * once the callback fires so the set doesn't grow unbounded.
82341
+ * @param {Function} fn - Callback to run.
82342
+ * @param {number} ms - Delay in milliseconds.
82343
+ * @returns {number} The timer id.
82344
+ * @private
82345
+ */
82346
+ _scheduleTimer(fn, ms) {
82347
+ const id = setTimeout(() => {
82348
+ this._pendingTimers.delete(id);
82349
+ fn();
82350
+ }, ms);
82351
+ this._pendingTimers.add(id);
82352
+ return id;
82339
82353
  }
82340
82354
 
82341
82355
  // This function is to define props used within the scope of this component
@@ -82697,17 +82711,6 @@ class AuroCombobox extends AuroElement$3 {
82697
82711
  attribute: false
82698
82712
  },
82699
82713
 
82700
- /**
82701
- * Deferred aria-expanded state for the trigger input.
82702
- * Delays the "true" transition so VoiceOver finishes its character echo
82703
- * before announcing "expanded".
82704
- * @private
82705
- */
82706
- triggerExpandedState: {
82707
- type: Boolean,
82708
- reflect: false,
82709
- attribute: false
82710
- },
82711
82714
  };
82712
82715
  }
82713
82716
 
@@ -82730,13 +82733,6 @@ class AuroCombobox extends AuroElement$3 {
82730
82733
  return this.input.value;
82731
82734
  }
82732
82735
 
82733
- // /**
82734
- // * Sets the value of the input element within the combobox.
82735
- // */
82736
- // set inputValue(value) {
82737
- // this.input.value = value;
82738
- // }
82739
-
82740
82736
  /**
82741
82737
  * Checks if the element is valid.
82742
82738
  * @returns {boolean} - Returns true if the element is valid, false otherwise.
@@ -82863,7 +82859,7 @@ class AuroCombobox extends AuroElement$3 {
82863
82859
  if (this.menu) {
82864
82860
  this.menu.matchWord = normalizeFilterValue(this.input.value);
82865
82861
  }
82866
- const label = getOptionLabel(this.menu.optionSelected) || this.menu.currentLabel;
82862
+ const label = getOptionLabel(this.menu.optionSelected);
82867
82863
  this.updateTriggerTextDisplay(label || this.value);
82868
82864
  }
82869
82865
 
@@ -82877,44 +82873,16 @@ class AuroCombobox extends AuroElement$3 {
82877
82873
  // in suggestion mode, do not override input value if no selection has been made and the input currently has focus
82878
82874
  const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
82879
82875
 
82880
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
82881
- const nextValue = label || this.value;
82882
- // Only set the flag when there's an actual write to suppress —
82883
- // syncValuesAndStates re-enters here during typing when both inputs
82884
- // already match, and a no-op flag flip would make the bib branch's
82885
- // bail eat legitimate user-input events.
82886
- const triggerNeedsSync = this.input.value !== nextValue;
82887
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
82888
- if (triggerNeedsSync || bibNeedsSync) {
82889
- this._syncingDisplayValue = true;
82890
- if (triggerNeedsSync) {
82891
- this.input.value = nextValue;
82892
- }
82893
- if (bibNeedsSync) {
82894
- this.inputInBib.value = nextValue;
82895
- }
82896
- const pending = [];
82897
- if (triggerNeedsSync) {
82898
- pending.push(this.input.updateComplete);
82899
- }
82900
- if (bibNeedsSync) {
82901
- pending.push(this.inputInBib.updateComplete);
82902
- }
82903
- Promise.all(pending).then(() => {
82904
- // imask reasserts otherwise, and handleBlur reverts to its stale value.
82905
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
82906
- this.input.maskInstance.updateValue();
82907
- }
82908
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
82909
- this.inputInBib.maskInstance.updateValue();
82910
- }
82911
- this._syncingDisplayValue = false;
82912
- });
82913
- }
82876
+ const suppressed = this.persistInput || (this.behavior === 'suggestion' && isInputFocusedWithNoSelection);
82877
+ if (!suppressed) {
82878
+ this.syncInputValuesAcrossTriggerAndBib(label || this.value);
82914
82879
  }
82915
82880
 
82916
- // update the displayValue in the trigger if displayValue slot content is present
82917
- const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]');
82881
+ // Replace any previously appended displayValue clone in the trigger.
82882
+ // :not(slot) excludes the template's <slot name="displayValue"
82883
+ // slot="displayValue"> forwarder, which also has slot="displayValue"
82884
+ // and would otherwise be matched first and removed.
82885
+ const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]:not(slot)');
82918
82886
 
82919
82887
  if (displayValueInTrigger) {
82920
82888
  displayValueInTrigger.remove();
@@ -82938,6 +82906,53 @@ class AuroCombobox extends AuroElement$3 {
82938
82906
  this.requestUpdate();
82939
82907
  }
82940
82908
 
82909
+ /**
82910
+ * Writes nextValue to the trigger input and the bib input when their current
82911
+ * value differs, then re-asserts imask after Lit's update flushes.
82912
+ * @param {string} nextValue - The value to write to both inputs.
82913
+ * @returns {Promise<void>} Resolves after both inputs flush and imask
82914
+ * re-asserts; resolves immediately when no sync is needed.
82915
+ * @private
82916
+ */
82917
+ async syncInputValuesAcrossTriggerAndBib(nextValue) {
82918
+ // Only set the flag when there's an actual write to suppress —
82919
+ // syncValuesAndStates re-enters here during typing when both inputs
82920
+ // already match, and a no-op flag flip would make the bib branch's
82921
+ // bail eat legitimate user-input events.
82922
+ const triggerNeedsSync = this.input.value !== nextValue;
82923
+ const bibNeedsSync = Boolean(this.inputInBib) && this.inputInBib.value !== nextValue;
82924
+ if (!triggerNeedsSync && !bibNeedsSync) {
82925
+ return;
82926
+ }
82927
+
82928
+ this._syncingDisplayValue = true;
82929
+
82930
+ const pending = [];
82931
+ if (triggerNeedsSync) {
82932
+ this.input.value = nextValue;
82933
+ pending.push(this.input.updateComplete);
82934
+ }
82935
+ if (bibNeedsSync) {
82936
+ this.inputInBib.value = nextValue;
82937
+ pending.push(this.inputInBib.updateComplete);
82938
+ }
82939
+ // finally — not a bare .then — so that an imask throw (see commit
82940
+ // d1857401c: imask can throw on credit-card format change) doesn't strand
82941
+ // _syncingDisplayValue=true and silently swallow every subsequent input.
82942
+ try {
82943
+ await Promise.all(pending);
82944
+ // imask reasserts otherwise, and handleBlur reverts to its stale value.
82945
+ if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
82946
+ this.input.maskInstance.updateValue();
82947
+ }
82948
+ if (bibNeedsSync && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
82949
+ this.inputInBib.maskInstance.updateValue();
82950
+ }
82951
+ } finally {
82952
+ this._syncingDisplayValue = false;
82953
+ }
82954
+ }
82955
+
82941
82956
  /**
82942
82957
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
82943
82958
  * @private
@@ -82946,6 +82961,13 @@ class AuroCombobox extends AuroElement$3 {
82946
82961
  handleMenuOptions() {
82947
82962
  this.generateOptionsArray();
82948
82963
  this.availableOptions = [];
82964
+ // Single source of truth for the menu's filter/highlight token per call.
82965
+ // syncValuesAndStates re-writes the same value on exact-match keystrokes —
82966
+ // Lit's hasChanged makes that a no-op — and the prior duplicate set inside
82967
+ // handleTriggerInputValueChange is gone.
82968
+ if (this.menu) {
82969
+ this.menu.matchWord = normalizeFilterValue(this.input.value);
82970
+ }
82949
82971
  this.updateFilter();
82950
82972
 
82951
82973
  // Set aria-setsize/aria-posinset on each visible option so screen readers
@@ -82957,17 +82979,14 @@ class AuroCombobox extends AuroElement$3 {
82957
82979
  option.setAttribute('aria-posinset', index + 1);
82958
82980
  });
82959
82981
 
82960
- if (this.value && this.input.value && !this.menu.value) {
82961
- if (this.behavior === 'suggestion' && this.menu.options && this.menu.options.some((opt) => opt.value === this.value)) {
82962
- this.setMenuValue(this.value);
82963
- }
82964
-
82982
+ if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
82983
+ this.setMenuValue(this.input.value);
82965
82984
  this.syncValuesAndStates();
82966
82985
  }
82967
82986
 
82968
- // Re-activate when optionActive is no longer visible, or when _index has
82969
- // been reset (e.g. by clearSelection in an async update) so that
82970
- // makeSelection() can find the correct option.
82987
+ // Re-activate when optionActive is not in the current scrollable viewport,
82988
+ // or when _index has been reset (e.g. by clearSelection in an async update)
82989
+ // so that makeSelection() can find the correct option.
82971
82990
  if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
82972
82991
  this.activateFirstEnabledAvailableOption();
82973
82992
  }
@@ -83040,18 +83059,6 @@ class AuroCombobox extends AuroElement$3 {
83040
83059
  this.dropdownOpen = ev.detail.expanded;
83041
83060
  this.updateMenuShapeSize();
83042
83061
 
83043
- // Defer aria-expanded "true" so VoiceOver finishes character echo
83044
- // before announcing "expanded". Set "false" immediately on close.
83045
- clearTimeout(this._expandedTimeout);
83046
- if (this.dropdownOpen) {
83047
- const expandedDelay = 150;
83048
- this._expandedTimeout = setTimeout(() => {
83049
- this.triggerExpandedState = true;
83050
- }, expandedDelay);
83051
- } else {
83052
- this.triggerExpandedState = false;
83053
- }
83054
-
83055
83062
  // Clear aria-activedescendant when dropdown closes
83056
83063
  if (!this.dropdownOpen && this.input) {
83057
83064
  this.input.setActiveDescendant(null);
@@ -83101,28 +83108,25 @@ class AuroCombobox extends AuroElement$3 {
83101
83108
 
83102
83109
  guardTouchPassthrough$1(this.menu);
83103
83110
 
83104
- // The dialog's showModal() steals focus from the trigger.
83105
- // A single rAF is enough for the dialog DOM to be painted and
83106
- // focusable, then doubleRaf finalizes the transition.
83111
+ // showModal() takes focus away from the trigger. Early focus once
83112
+ // the dialog has painted; the shared doubleRaf below is the fallback
83113
+ // for when the dialog needs an extra frame and also clears the
83114
+ // validation guard.
83107
83115
  requestAnimationFrame(() => {
83108
83116
  this.setInputFocus();
83109
83117
  });
83110
-
83111
- doubleRaf$1(() => {
83112
- this.setInputFocus();
83113
- this._inFullscreenTransition = false;
83114
- });
83115
- } else {
83116
- // Desktop popover-open: restore the trigger caret to end-of-text.
83117
- // Clicking the trigger lands on auro-input's floating <label for="…">
83118
- // overlay; Chrome resets the native input's selection to [0, 0] on
83119
- // label-focus before any JS runs. setInputFocus()'s non-fullscreen
83120
- // branch parks the caret at end. doubleRaf lets the dropdown layout
83121
- // settle first, matching the fullscreen branch timing.
83122
- doubleRaf$1(() => {
83123
- this.setInputFocus();
83124
- });
83125
83118
  }
83119
+ // else (desktop popover-open): Chrome resets the trigger caret to
83120
+ // [0, 0] when its floating <label for="…"> overlay receives focus.
83121
+ // The shared doubleRaf below parks the caret back at end-of-text
83122
+ // after the dropdown layout settles.
83123
+
83124
+ doubleRaf$1(() => {
83125
+ this.setInputFocus();
83126
+ if (this._inFullscreenTransition) {
83127
+ this._inFullscreenTransition = false;
83128
+ }
83129
+ });
83126
83130
  }
83127
83131
  });
83128
83132
 
@@ -83159,7 +83163,7 @@ class AuroCombobox extends AuroElement$3 {
83159
83163
  this.dropdown.trigger.inert = false;
83160
83164
  }
83161
83165
 
83162
- setTimeout(() => {
83166
+ this._scheduleTimer(() => {
83163
83167
  this.setInputFocus();
83164
83168
  }, 0);
83165
83169
  });
@@ -83303,7 +83307,7 @@ class AuroCombobox extends AuroElement$3 {
83303
83307
 
83304
83308
  // racing condition on custom-combobox with custom-menu
83305
83309
  if (!this.menu) {
83306
- setTimeout(() => {
83310
+ this._scheduleTimer(() => {
83307
83311
  this.configureMenu();
83308
83312
  }, 0);
83309
83313
  return;
@@ -83333,7 +83337,7 @@ class AuroCombobox extends AuroElement$3 {
83333
83337
  if (this.menu.optionSelected) {
83334
83338
  const selected = this.menu.optionSelected;
83335
83339
 
83336
- if (!this.optionSelected || this.optionSelected !== selected) {
83340
+ if (this.optionSelected !== selected) {
83337
83341
  this.optionSelected = selected;
83338
83342
  }
83339
83343
 
@@ -83346,7 +83350,7 @@ class AuroCombobox extends AuroElement$3 {
83346
83350
  }
83347
83351
 
83348
83352
  // Update display
83349
- this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected) || this.menu.value);
83353
+ this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected));
83350
83354
 
83351
83355
  // Update match word for filtering
83352
83356
  const trimmedInput = normalizeFilterValue(this.input.value);
@@ -83358,17 +83362,24 @@ class AuroCombobox extends AuroElement$3 {
83358
83362
  // Hide dropdown on selection (except during slot changes)
83359
83363
  if (evt.detail && evt.detail.source !== 'slotchange') {
83360
83364
  // do not close while typing in suggestion mode with no value selected, to allow freeform input
83361
- if (this.menu.value || this.behavior !== 'suggestion') {
83362
- this.hideBib();
83365
+ this.hideBib();
83366
+
83367
+ // Move focus to the clear button when the user makes a selection.
83368
+ if (!isEcho && this.menu.value !== undefined) {
83369
+ this.setClearBtnFocus();
83363
83370
  }
83364
83371
 
83365
83372
  // Announce the selection after the dropdown closes so it isn't
83366
83373
  // overridden by VoiceOver's "collapsed" announcement from aria-expanded.
83374
+ // Skip when there's no selected value (e.g. menu.clearSelection() from
83375
+ // the unmatched-value path), otherwise VoiceOver reads "undefined".
83367
83376
  const selectedValue = this.menu.value;
83368
- const announcementDelay = 300;
83369
- setTimeout(() => {
83370
- announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
83371
- }, announcementDelay);
83377
+ if (selectedValue) {
83378
+ const announcementDelay = 300;
83379
+ this._scheduleTimer(() => {
83380
+ announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
83381
+ }, announcementDelay);
83382
+ }
83372
83383
  }
83373
83384
 
83374
83385
  // Programmatic value syncs leave availableOptions stale because
@@ -83377,22 +83388,6 @@ class AuroCombobox extends AuroElement$3 {
83377
83388
  // only — fresh user selections take the existing hideBib path.
83378
83389
  if (isEcho && this.menu.optionSelected) {
83379
83390
  this._programmaticFilterRefresh = true;
83380
- this.handleMenuOptions();
83381
- setTimeout(() => {
83382
- this._programmaticFilterRefresh = false;
83383
- }, 0);
83384
- }
83385
-
83386
- // base-input skips auto-validate when focus is inside its own shadow,
83387
- // which it is after setTriggerInputFocus — re-run so prior tooShort
83388
- // clears. processCreditCard reasserts errorMessage on every render.
83389
- if (!isEcho && this.menu.optionSelected && this.input.validate) {
83390
- this.input.updateComplete.then(() => {
83391
- this.input.validate(true);
83392
- if (this.input.validity === 'valid') {
83393
- this.input.errorMessage = '';
83394
- }
83395
- });
83396
83391
  }
83397
83392
  });
83398
83393
 
@@ -83405,6 +83400,14 @@ class AuroCombobox extends AuroElement$3 {
83405
83400
  // stale option. Safe from re-entrancy because any resulting
83406
83401
  // input.value changes dispatch isProgrammatic events.
83407
83402
  this.menu.addEventListener('auroMenu-selectValueFailure', () => {
83403
+ // Announce the rejection BEFORE we clear `this.value` so the live
83404
+ // region carries the attempted value — without this the bib closes
83405
+ // silently and screen-reader users get no signal that their request
83406
+ // (e.g. a direct setMenuValue() call) was dropped.
83407
+ const attemptedValue = this.value;
83408
+ if (attemptedValue) {
83409
+ announceToScreenReader$1(this._getAnnouncementRoot(), `No matching option for ${attemptedValue}`);
83410
+ }
83408
83411
  this.value = undefined;
83409
83412
  this.optionSelected = undefined;
83410
83413
  });
@@ -83416,10 +83419,13 @@ class AuroCombobox extends AuroElement$3 {
83416
83419
  this.input.setActiveDescendant(this.optionActive);
83417
83420
  }
83418
83421
 
83419
- // Announce the active option for screen readers including position,
83420
- // since shadow DOM boundaries prevent native reading of
83421
- // aria-setsize/aria-posinset via aria-activedescendant.
83422
- if (this.optionActive) {
83422
+ // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
83423
+ // and aria-activedescendant references across that boundary are lost —
83424
+ // VoiceOver/NVDA don't read the active option natively, so we mirror it
83425
+ // into the polite live region. In popover mode aria-activedescendant on
83426
+ // the trigger input is read natively; double-announcing would flood the
83427
+ // queue on arrow-key repeat.
83428
+ if (this.optionActive && this.dropdown.isBibFullscreen) {
83423
83429
  const optionText = this.optionActive.textContent.trim();
83424
83430
  const selectedState = this.optionActive.hasAttribute('selected') ? ', selected' : ', not selected';
83425
83431
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
@@ -83452,7 +83458,12 @@ class AuroCombobox extends AuroElement$3 {
83452
83458
  * Validate every time we remove focus from the combo box.
83453
83459
  */
83454
83460
  this.addEventListener('focusout', () => {
83455
- if (!this.componentHasFocus && !this._inFullscreenTransition) {
83461
+ // Skip while the dropdown is open — focus transits out briefly on
83462
+ // mousedown of a menu option (popover top-layer breaks :focus-within),
83463
+ // and validating against the pre-selection value flashes a stale error
83464
+ // between mousedown and mouseup. The next focusout fires after the
83465
+ // dropdown closes and validates against the post-selection value.
83466
+ if (!this.componentHasFocus && !this._inFullscreenTransition && !this.dropdownOpen) {
83456
83467
  this.validate();
83457
83468
  }
83458
83469
  });
@@ -83515,49 +83526,40 @@ class AuroCombobox extends AuroElement$3 {
83515
83526
  if (this._syncingDisplayValue) {
83516
83527
  return;
83517
83528
  }
83518
- this._syncingBibValue = true;
83519
- this.input.value = this.inputInBib.value;
83520
- this.input.updateComplete.then(() => {
83521
- this._syncingBibValue = false;
83522
- });
83523
-
83524
- // Run filtering inline — the re-entrant event won't reach this code.
83525
- this.menu.matchWord = normalizeFilterValue(this.inputInBib.value);
83526
- this.optionActive = null;
83527
83529
 
83528
- // In suggestion mode, keep the combobox value in sync with the typed
83529
- // text so that freeform values are captured (mirroring the non-fullscreen
83530
- // path). Clear the selection when the input is emptied.
83531
- if (this.behavior === 'suggestion') {
83532
- this.value = this.inputInBib.value || undefined;
83530
+ // Filtering runs via re-entrance: writing this.input.value below
83531
+ // dispatches an 'input' event that the trigger's listener routes to
83532
+ // handleTriggerInputValueChange, which refreshes the menu filter.
83533
+ if (this.input.value !== this.inputInBib.value) {
83534
+ this._syncingBibValue = true;
83535
+ this.input.value = this.inputInBib.value;
83536
+ this.input.updateComplete.then(() => {
83537
+ this._syncingBibValue = false;
83538
+ });
83533
83539
  }
83534
83540
 
83535
- this.handleMenuOptions();
83536
83541
  this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
83537
- return;
83542
+ } else if (event.target === this.input) {
83543
+
83544
+ // Also sync the native input immediately so keystrokes arriving
83545
+ // before Lit's async update cycle (e.g. rapid Backspaces during a
83546
+ // fullscreen transition) operate on the correct content.
83547
+ // Skip the next programmatic input event to prevent the patched setter
83548
+ // from re-entering handleInputValueChange via the bib path.
83549
+ const bibNativeInput = this.inputInBib.inputElement;
83550
+ if (bibNativeInput && bibNativeInput.value !== this.input.value) {
83551
+ this.inputInBib.skipNextProgrammaticInputEvent = true;
83552
+ bibNativeInput.value = this.input.value || '';
83553
+ }
83538
83554
  }
83539
83555
 
83556
+ this.value = this.input.value;
83557
+
83540
83558
  // Ignore re-entrant input events caused by programmatic value sets.
83541
83559
  if (this._syncingBibValue || this._syncingDisplayValue) {
83542
83560
  return;
83543
83561
  }
83544
83562
 
83545
- this.inputInBib.value = this.input.value;
83546
-
83547
- // Also sync the native input immediately so keystrokes arriving
83548
- // before Lit's async update cycle (e.g. rapid Backspaces during a
83549
- // fullscreen transition) operate on the correct content.
83550
- // Skip the next programmatic input event to prevent the patched setter
83551
- // from re-entering handleInputValueChange via the bib path.
83552
- const bibNativeInput = this.inputInBib.inputElement;
83553
- if (bibNativeInput && bibNativeInput.value !== this.input.value) {
83554
- this.inputInBib.skipNextProgrammaticInputEvent = true;
83555
- bibNativeInput.value = this.input.value || '';
83556
- }
83557
-
83558
- this.menu.matchWord = normalizeFilterValue(this.input.value);
83559
- this.optionActive = null;
83560
-
83561
83563
  if (this.behavior === 'suggestion') {
83562
83564
  this.value = this.input.value;
83563
83565
  }
@@ -83565,7 +83567,6 @@ class AuroCombobox extends AuroElement$3 {
83565
83567
  if (!this.input.value && !this._clearing) {
83566
83568
  this.clear();
83567
83569
  }
83568
- this.handleMenuOptions();
83569
83570
 
83570
83571
  // Validate only if the value was set programmatically (not during user
83571
83572
  // interaction). In fullscreen dialog mode, componentHasFocus returns false
@@ -83575,34 +83576,44 @@ class AuroCombobox extends AuroElement$3 {
83575
83576
  this.validate();
83576
83577
  }
83577
83578
 
83578
- if (this.input.value && this.input.value.length === 0) {
83579
- // Hide menu if value is empty, otherwise show if there are available suggestions
83580
- this.hideBib();
83581
- } else if (this.menu.loading) {
83582
- // if input has value but menu is loading, show bib immediately
83583
- this.showBib();
83584
- } else if (this.availableOptions.length === 0 && !this.dropdown.isBibFullscreen) {
83585
- // Force dropdown bib to hide if input value has no matching suggestions
83586
- this.hideBib();
83579
+ this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
83580
+ }
83581
+
83582
+ /**
83583
+ * Handles input value changes originating from the trigger input.
83584
+ * Refreshes menu options and filtering, delegates to handleInputValueChange
83585
+ * for value synchronization, and manages fullscreen bib focus.
83586
+ * @private
83587
+ * @param {Event} event - The input event from the trigger input element.
83588
+ * @returns {void}
83589
+ */
83590
+ handleTriggerInputValueChange(event) {
83591
+ // 'input' fires for every user-initiated value change — typing, paste,
83592
+ // IME composition end, dead-key composition, drag-drop. Flip _userTyped
83593
+ // here so updated('availableOptions') auto-opens the bib for sources
83594
+ // that keydown alone misses: paste fires no keydown, IME uses
83595
+ // key='Process', and dead keys produce multi-char keys (all bypass the
83596
+ // prior keydown.key.length===1 gate). Skip programmatic syncs.
83597
+ if (!this._syncingDisplayValue && !this._syncingBibValue && !this._programmaticFilterRefresh) {
83598
+ this._userTyped = true;
83587
83599
  }
83588
83600
 
83589
- // iOS virtual keyboard retention: when in fullscreen mode, ensure the
83590
- // dialog opens and the bib input is focused synchronously within the
83591
- // input event (user gesture) chain. Without this, Lit's async update
83592
- // cycle delays showModal() past the user activation window, causing
83593
- // iOS Safari to dismiss the virtual keyboard when the fullscreen
83594
- // dialog opens — the user then has to tap the input again to resume
83595
- // typing.
83596
- if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0) {
83597
- if (!this.dropdown.isPopoverVisible) {
83598
- this.showBib();
83599
- }
83600
- if (this.dropdown.isPopoverVisible) {
83601
- this.setInputFocus();
83602
- }
83601
+ this.handleMenuOptions();
83602
+ this.optionActive = null;
83603
+
83604
+ if (this.value === this.input.value) {
83605
+ return;
83603
83606
  }
83604
83607
 
83605
- this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
83608
+ this.handleInputValueChange(event);
83609
+
83610
+ if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0 && this.dropdown.isPopoverVisible) {
83611
+ this.setInputFocus();
83612
+ }
83613
+
83614
+ if (this._programmaticFilterRefresh) {
83615
+ this._programmaticFilterRefresh = false;
83616
+ }
83606
83617
  }
83607
83618
 
83608
83619
  /**
@@ -83670,6 +83681,11 @@ class AuroCombobox extends AuroElement$3 {
83670
83681
  disconnectedCallback() {
83671
83682
  super.disconnectedCallback();
83672
83683
  this._inFullscreenTransition = false;
83684
+ // Cancel any outstanding timers so detached callbacks don't fire on
83685
+ // disposed DOM — most are no-ops, but configureMenu's racing-condition
83686
+ // retry would otherwise keep rescheduling itself indefinitely.
83687
+ this._pendingTimers.forEach((id) => clearTimeout(id));
83688
+ this._pendingTimers.clear();
83673
83689
  }
83674
83690
 
83675
83691
  firstUpdated() {
@@ -83711,7 +83727,7 @@ class AuroCombobox extends AuroElement$3 {
83711
83727
  this.menu.value = value;
83712
83728
  // Backup clear: if menu.value === menu.optionSelected.value already, the
83713
83729
  // listener won't fire and the flag would swallow the next user click.
83714
- setTimeout(() => {
83730
+ this._scheduleTimer(() => {
83715
83731
  this._pendingMenuValueSync = false;
83716
83732
  }, 0);
83717
83733
  }
@@ -83728,15 +83744,7 @@ class AuroCombobox extends AuroElement$3 {
83728
83744
  this.menu.value = undefined;
83729
83745
  this.validation.reset(this);
83730
83746
  this.touched = false;
83731
- // Force validity back to the cleared state. validation.reset() calls
83732
- // validate() at the end, and (post-credit-card-fix) the trigger input's
83733
- // residual validity may still be copied into the combobox by the
83734
- // auroInputElements loop. Explicitly clear here so reset() actually
83735
- // leaves the component in a "no validity" state.
83736
83747
  this.validity = undefined;
83737
- this.errorMessage = '';
83738
- this.input.validity = undefined;
83739
- this.input.errorMessage = '';
83740
83748
  }
83741
83749
 
83742
83750
  /**
@@ -83754,6 +83762,17 @@ class AuroCombobox extends AuroElement$3 {
83754
83762
  this.optionSelected = undefined;
83755
83763
  this.value = undefined;
83756
83764
 
83765
+ // Clear the appended displayValue clone in the trigger if present.
83766
+ // :not(slot) excludes the template's <slot name="displayValue"
83767
+ // slot="displayValue"> forwarder (line 1816), which also has
83768
+ // slot="displayValue" and would otherwise be matched first and removed,
83769
+ // permanently breaking the consumer-provided displayValue slot.
83770
+ const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]:not(slot)');
83771
+
83772
+ if (displayValueInTrigger) {
83773
+ displayValueInTrigger.remove();
83774
+ }
83775
+
83757
83776
  if (this.input.value) {
83758
83777
  this.input.clear();
83759
83778
  }
@@ -83777,81 +83796,50 @@ class AuroCombobox extends AuroElement$3 {
83777
83796
  }
83778
83797
 
83779
83798
  updated(changedProperties) {
83780
- // After the component is ready, send direct value changes to auro-menu.
83799
+ // After the component is ready, propagate direct changes down to child components.
83781
83800
  if (changedProperties.has('value')) {
83782
- if (this.value && this.value.length > 0) {
83783
- this.hasValue = true;
83784
- } else {
83785
- this.hasValue = false;
83801
+ // Only flag programmatic refreshes — user-typed value changes must not
83802
+ // suppress the availableOptions branch's showBib(). Firefox batches
83803
+ // 'value' and 'availableOptions' into the same updated() call, so
83804
+ // setting the flag unconditionally here masks the user-typed open path.
83805
+ if (!this._userTyped) {
83806
+ this._programmaticFilterRefresh = true;
83786
83807
  }
83787
83808
 
83788
- if (this.hasValue && !this.input.value && (!this.menu.options || this.menu.options.length === 0)) {
83789
- this.input.value = this.value;
83790
- }
83809
+ if (this.input.value !== this.value) {
83810
+ // Clear menu.value AND menu.optionSelected together. Clearing only
83811
+ // menu.value leaves the previously-selected option element pinned
83812
+ // as menu.optionSelected; a later auroMenu-selectedOption event
83813
+ // would then write its stale .value back into combobox.value
83814
+ // (e.g. Tab-after-Backspace re-selecting the prior option).
83815
+ if (this.menu.value || this.menu.optionSelected) {
83816
+ this.menu.clearSelection();
83817
+ }
83791
83818
 
83792
- // Sync menu.value only when an option actually matches; otherwise clear it.
83793
- if (this.menu.options && this.menu.options.length > 0) {
83794
- if (this.menu.options.some((opt) => opt.value === this.value)) {
83795
- this.setMenuValue(this.value);
83796
- } else if (this.behavior === 'filter') {
83797
- // In filter mode, freeform values aren't allowed. Push the unmatched
83798
- // value through setMenuValue so menu dispatches auroMenu-selectValueFailure
83799
- // and the listener at line 1206 clears combobox.value (mirrors select's
83800
- // pattern). Bypassing setMenuValue here would skip the failure cascade.
83801
- this.setMenuValue(this.value);
83802
- } else {
83803
- if (this.menu.value) {
83804
- this.menu.value = undefined;
83805
- }
83806
- // Sync the display for programmatic freeform value changes (e.g. the
83807
- // swap-values pattern). Guard with _syncingDisplayValue so that the
83808
- // re-entrant input event from base-input.notifyValueChanged() is
83809
- // ignored by handleInputValueChange. Skip the sync when input already
83810
- // matches to avoid spurious events during the normal typing path.
83811
- const nextValue = this.value || '';
83812
- const triggerNeedsSync = this.input.value !== nextValue;
83813
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
83814
- if (triggerNeedsSync || bibNeedsSync) {
83815
- this._syncingDisplayValue = true;
83816
- if (triggerNeedsSync) {
83817
- this.input.value = nextValue;
83818
- }
83819
- if (bibNeedsSync) {
83820
- this.inputInBib.value = nextValue;
83821
- }
83822
- const pending = [];
83823
- if (triggerNeedsSync) {
83824
- pending.push(this.input.updateComplete);
83825
- }
83826
- if (bibNeedsSync) {
83827
- pending.push(this.inputInBib.updateComplete);
83828
- }
83829
- Promise.all(pending).then(() => {
83830
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
83831
- this.input.maskInstance.updateValue();
83832
- }
83833
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
83834
- this.inputInBib.maskInstance.updateValue();
83835
- }
83836
- this._syncingDisplayValue = false;
83837
- // handleInputValueChange bailed on the flag — refresh the filter.
83838
- this._programmaticFilterRefresh = true;
83839
- this.handleMenuOptions();
83840
- setTimeout(() => {
83841
- this._programmaticFilterRefresh = false;
83842
- }, 0);
83843
- });
83844
- }
83819
+ if (!this.persistInput) {
83820
+ this.syncInputValuesAcrossTriggerAndBib(this.value || '');
83821
+ }
83822
+
83823
+ // Programmatic value with no matching option: updateFilter will close
83824
+ // the bib silently (see line 648 no noMatchOption + 0 results
83825
+ // hides). Announce so screen-reader users hear the request was
83826
+ // dropped. Gated on `input.value !== this.value` so this never fires
83827
+ // for user typing that path always reconciles input.value to
83828
+ // this.value before updated() runs.
83829
+ if (
83830
+ this.value &&
83831
+ this.menu &&
83832
+ this.menu.options &&
83833
+ this.menu.options.length > 0 &&
83834
+ !this.menu.options.some((opt) => opt.value === this.value)
83835
+ ) {
83836
+ announceToScreenReader$1(this._getAnnouncementRoot(), `No matching option for ${this.value}`);
83845
83837
  }
83846
83838
  }
83839
+
83847
83840
  if (!this.value) {
83848
83841
  this.clear();
83849
83842
  }
83850
- if (this.value && !this.componentHasFocus) {
83851
- // If the value got set programmatically make sure we hide the bib
83852
- // when input is not taking the focus (input can be in dropdown.trigger or in bibtemplate)
83853
- this.hideBib();
83854
- }
83855
83843
 
83856
83844
  // Sync the input and match word, but don't directly set menu.value again
83857
83845
  if (this.menu) {
@@ -83864,7 +83852,7 @@ class AuroCombobox extends AuroElement$3 {
83864
83852
  composed: true,
83865
83853
  detail: {
83866
83854
  optionSelected: this.menu.optionSelected,
83867
- value: this.menu.value
83855
+ value: this.value
83868
83856
  }
83869
83857
  }));
83870
83858
 
@@ -83887,16 +83875,30 @@ class AuroCombobox extends AuroElement$3 {
83887
83875
  // from a programmatic filter refresh after a value swap — the user
83888
83876
  // didn't interact, so we shouldn't auto-open the bib (especially for
83889
83877
  // the no-match path where the existing condition unconditionally fires).
83890
- if (this._programmaticFilterRefresh) {
83891
- this._programmaticFilterRefresh = false;
83892
- } else if ((this.availableOptions.length > 0 && (this.componentHasFocus || this.dropdownOpen)) || (this.menu && this.menu.loading) || (this.availableOptions.length === 0 && this.noMatchOption)) {
83893
- this.showBib();
83878
+ if ((this.menu && !this._programmaticFilterRefresh)) {
83879
+ if (
83880
+ this.availableOptions.length > 0 ||
83881
+ this.menu.loading ||
83882
+ this.noMatchOption
83883
+ ) {
83884
+ if (this._userTyped) {
83885
+ if (!this.dropdownOpen) {
83886
+ this.showBib();
83887
+ }
83888
+ this._userTyped = false;
83889
+ }
83890
+ }
83891
+
83894
83892
  if (!this.availableOptions.includes(this.menu.optionActive)) {
83895
83893
  this.activateFirstEnabledAvailableOption();
83896
83894
  }
83897
- } else if (this.dropdown && this.dropdown.isPopoverVisible) {
83895
+ } else if (!this.dropdown.isBibFullscreen) {
83898
83896
  this.hideBib();
83899
83897
  }
83898
+
83899
+ if (this._programmaticFilterRefresh) {
83900
+ this._programmaticFilterRefresh = false;
83901
+ }
83900
83902
  }
83901
83903
 
83902
83904
  if (changedProperties.has('error')) {
@@ -84038,10 +84040,10 @@ class AuroCombobox extends AuroElement$3 {
84038
84040
  shape="${this.shape}"
84039
84041
  size="${this.size}">
84040
84042
  <${this.inputTag}
84041
- @input="${this.handleInputValueChange}"
84043
+ @input="${this.handleTriggerInputValueChange}"
84042
84044
  appearance="${this.onDark ? 'inverse' : this.appearance}"
84043
84045
  .a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
84044
- .a11yExpanded="${this.triggerExpandedState}"
84046
+ .a11yExpanded="${this.dropdownOpen}"
84045
84047
  .a11yControls="${this.dropdownId}"
84046
84048
  .autocomplete="${this.autocomplete}"
84047
84049
  .inputmode="${this.inputmode}"
@@ -86191,11 +86193,17 @@ class AuroFormValidation {
86191
86193
  return;
86192
86194
  }
86193
86195
 
86194
- // Validate that the date passed was the correct format and is a valid date
86196
+ // Validate that the date passed was the correct format and is a valid date.
86197
+ // For partial date formats, valueObject is never populated; validate them directly.
86195
86198
  if (elem.value && !elem.valueObject) {
86196
- elem.validity = 'patternMismatch';
86197
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
86198
- return;
86199
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
86200
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
86201
+
86202
+ if (!isValidPartial) {
86203
+ elem.validity = 'patternMismatch';
86204
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
86205
+ return;
86206
+ }
86199
86207
  }
86200
86208
 
86201
86209
  // Perform the rest of the validation
@@ -86289,15 +86297,17 @@ class AuroFormValidation {
86289
86297
  );
86290
86298
  }
86291
86299
 
86292
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
86293
- if (this.auroInputElements?.length === 2) {
86294
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
86300
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
86301
+
86302
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
86303
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
86304
+ // field (datepicker is the intended consumer — start/end are independently required).
86305
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
86306
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
86295
86307
  hasValue = false;
86296
86308
  }
86297
86309
  }
86298
86310
 
86299
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
86300
-
86301
86311
  if (isCombobox) {
86302
86312
 
86303
86313
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -90678,7 +90688,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
90678
90688
  }
90679
90689
  };
90680
90690
 
90681
- var formkitVersion$1 = '202606292156';
90691
+ var formkitVersion$1 = '202607011722';
90682
90692
 
90683
90693
  class AuroElement extends i$3 {
90684
90694
  static get properties() {
@@ -91430,7 +91440,19 @@ class AuroDropdown extends AuroElement {
91430
91440
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
91431
91441
  this.trigger.focus();
91432
91442
  }
91433
- }
91443
+
91444
+
91445
+ if (!this.isPopoverVisible) {
91446
+ // wait til the bib gets fully closed and rendered
91447
+ setTimeout(() => {
91448
+ // check if it's still closed and the focus is still within the dropdown, but not in the bib. If so, move focus to the trigger.
91449
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
91450
+ return;
91451
+ }
91452
+ // Move focus out of bib into trigger.
91453
+ this.trigger.focus();
91454
+ });
91455
+ } }
91434
91456
 
91435
91457
  firstUpdated() {
91436
91458
  // Configure the floater to, this will generate the ID for the bib
@@ -92700,7 +92722,7 @@ class AuroHelpText extends i$3 {
92700
92722
  }
92701
92723
  }
92702
92724
 
92703
- var formkitVersion = '202606292156';
92725
+ var formkitVersion = '202607011722';
92704
92726
 
92705
92727
  var styleCss = i$6`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer [slot=displayValue]{display:none}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{height:auto}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
92706
92728