@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
@@ -4414,11 +4414,17 @@ let AuroFormValidation$7 = class AuroFormValidation {
4414
4414
  return;
4415
4415
  }
4416
4416
 
4417
- // Validate that the date passed was the correct format and is a valid date
4417
+ // Validate that the date passed was the correct format and is a valid date.
4418
+ // For partial date formats, valueObject is never populated; validate them directly.
4418
4419
  if (elem.value && !elem.valueObject) {
4419
- elem.validity = 'patternMismatch';
4420
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
4421
- return;
4420
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
4421
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
4422
+
4423
+ if (!isValidPartial) {
4424
+ elem.validity = 'patternMismatch';
4425
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
4426
+ return;
4427
+ }
4422
4428
  }
4423
4429
 
4424
4430
  // Perform the rest of the validation
@@ -4512,15 +4518,17 @@ let AuroFormValidation$7 = class AuroFormValidation {
4512
4518
  );
4513
4519
  }
4514
4520
 
4515
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
4516
- if (this.auroInputElements?.length === 2) {
4517
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
4521
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4522
+
4523
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
4524
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
4525
+ // field (datepicker is the intended consumer — start/end are independently required).
4526
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
4527
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
4518
4528
  hasValue = false;
4519
4529
  }
4520
4530
  }
4521
4531
 
4522
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
4523
-
4524
4532
  if (isCombobox) {
4525
4533
 
4526
4534
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -10420,6 +10428,42 @@ let AuroInputUtilities$3 = class AuroInputUtilities {
10420
10428
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
10421
10429
  }
10422
10430
 
10431
+ /**
10432
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
10433
+ * Single-component formats are checked as integer ranges; multi-component formats use
10434
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
10435
+ * @param {string} value - The user-facing display value.
10436
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
10437
+ * @returns {boolean}
10438
+ */
10439
+ isValidPartialDate(value, format$1) {
10440
+ if (!value || !format$1) {
10441
+ return false;
10442
+ }
10443
+ const normalizedFormat = format$1.toLowerCase();
10444
+
10445
+ if (normalizedFormat === 'dd') {
10446
+ const num = Number(value);
10447
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
10448
+ }
10449
+ if (normalizedFormat === 'yy') {
10450
+ const num = Number(value);
10451
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
10452
+ }
10453
+ if (normalizedFormat === 'yyyy') {
10454
+ const num = Number(value);
10455
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
10456
+ }
10457
+
10458
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
10459
+ // Use the 1st of the current month as the reference so that formats
10460
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
10461
+ const referenceDate = new Date();
10462
+ referenceDate.setDate(1);
10463
+ const parsed = parse$3(value, dateFnsMask, referenceDate);
10464
+ return isValid$3(parsed) && format$3(parsed, dateFnsMask) === value;
10465
+ }
10466
+
10423
10467
  /**
10424
10468
  * Converts a display string to its model value.
10425
10469
  * For full date formats, converts the display string to an ISO date string.
@@ -10467,6 +10511,7 @@ let AuroInputUtilities$3 = class AuroInputUtilities {
10467
10511
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10468
10512
 
10469
10513
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10514
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10470
10515
  return undefined;
10471
10516
  }
10472
10517
 
@@ -10624,6 +10669,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10624
10669
  // so a parent (datepicker/combobox) calling `validate()` synchronously
10625
10670
  // during its own update cycle sees a populated util instance.
10626
10671
  this.activeLabel = false;
10672
+
10627
10673
  /** @private */
10628
10674
  this.allowedInputTypes = [
10629
10675
  "text",
@@ -10634,6 +10680,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10634
10680
  "tel"
10635
10681
  ];
10636
10682
  this.appearance = "default";
10683
+
10637
10684
  /** @private */
10638
10685
  this.dateFormatMap = {
10639
10686
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -10652,23 +10699,24 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10652
10699
  'mm/dd': 'dateMMDD'
10653
10700
  };
10654
10701
  this.disabled = false;
10702
+
10655
10703
  /** @private */
10656
10704
  this.domHandler = new DomHandler$3();
10657
10705
  this.dvInputOnly = false;
10658
10706
  this.hasValue = false;
10659
10707
  this.hideLabelVisually = false;
10660
10708
  this.icon = false;
10709
+
10661
10710
  /** @private */
10662
10711
  this.inputIconName = undefined;
10712
+
10663
10713
  /** @private */
10664
10714
  this.label = 'Input label is undefined';
10665
10715
  this.layout = 'classic';
10666
10716
  this.locale = 'en-US';
10667
10717
  this.max = undefined;
10668
- this._maxObject = undefined;
10669
10718
  this.maxLength = undefined;
10670
10719
  this.min = undefined;
10671
- this._minObject = undefined;
10672
10720
  this.minLength = undefined;
10673
10721
  this.noValidate = false;
10674
10722
  this.onDark = false;
@@ -10685,23 +10733,27 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10685
10733
  "email"
10686
10734
  ];
10687
10735
  this.shape = 'classic';
10736
+
10688
10737
  /** @private */
10689
10738
  this.showPassword = false;
10690
10739
  this.size = 'lg';
10691
10740
  this.touched = false;
10741
+
10692
10742
  /** @private */
10693
10743
  this.uniqueId = new UniqueId$2().create();
10744
+
10694
10745
  /** @private */
10695
10746
  this.util = new AuroInputUtilities$3({
10696
10747
  locale: this.locale,
10697
10748
  format: this.format
10698
10749
  });
10750
+
10699
10751
  /** @private */
10700
10752
  this.validation = new AuroFormValidation$7();
10753
+
10701
10754
  /** @private */
10702
10755
  this.validationCCLength = undefined;
10703
10756
  this.value = undefined;
10704
- this._valueObject = undefined;
10705
10757
  }
10706
10758
 
10707
10759
  // function to define props used within the scope of this component
@@ -11031,6 +11083,13 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11031
11083
  type: String
11032
11084
  },
11033
11085
 
11086
+ /**
11087
+ * Custom help text message to display when validity = `patternMismatch`.
11088
+ */
11089
+ setCustomValidityPatternMismatch: {
11090
+ type: String
11091
+ },
11092
+
11034
11093
  /**
11035
11094
  * Custom help text message to display when validity = `rangeOverflow`.
11036
11095
  */
@@ -11101,7 +11160,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11101
11160
 
11102
11161
  /**
11103
11162
  * Populates the `type` attribute on the input.
11104
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
11163
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
11105
11164
  * @default 'text'
11106
11165
  */
11107
11166
  type: {
@@ -11139,7 +11198,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11139
11198
  * @returns {Date|undefined}
11140
11199
  */
11141
11200
  get valueObject() {
11142
- return this._valueObject || this._computeDateObjectFallback(this.value);
11201
+ return this.value && dateFormatter$3.isValidDate(this.value) ? dateFormatter$3.stringToDateInstance(this.value) : undefined;
11143
11202
  }
11144
11203
 
11145
11204
  /**
@@ -11147,7 +11206,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11147
11206
  * @returns {Date|undefined}
11148
11207
  */
11149
11208
  get minObject() {
11150
- return this._minObject || this._computeDateObjectFallback(this.min);
11209
+ return this.min && dateFormatter$3.isValidDate(this.min) ? dateFormatter$3.stringToDateInstance(this.min) : undefined;
11151
11210
  }
11152
11211
 
11153
11212
  /**
@@ -11155,50 +11214,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11155
11214
  * @returns {Date|undefined}
11156
11215
  */
11157
11216
  get maxObject() {
11158
- return this._maxObject || this._computeDateObjectFallback(this.max);
11159
- }
11160
-
11161
- /**
11162
- * Parses a date string into a Date object when the corresponding `_*Object`
11163
- * field hasn't been synced yet by `updated()`. Returns undefined when the
11164
- * input type/format isn't a full date or the string is not a valid date.
11165
- *
11166
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
11167
- * inside its own `updated()` before this input's `updated()` has run
11168
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
11169
- * and range checks would otherwise silently no-op (flipping the result to
11170
- * `valid` or `patternMismatch`).
11171
- * @private
11172
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
11173
- * @returns {Date|undefined}
11174
- */
11175
- _computeDateObjectFallback(dateStr) {
11176
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
11177
- return undefined;
11178
- }
11179
- if (!dateFormatter$3.isValidDate(dateStr)) {
11180
- return undefined;
11181
- }
11182
- return dateFormatter$3.stringToDateInstance(dateStr);
11183
- }
11184
-
11185
- /**
11186
- * Internal setter for readonly date object properties.
11187
- * @private
11188
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
11189
- * @param {Date|undefined} propertyValue - Value to assign.
11190
- * @returns {void}
11191
- */
11192
- setDateObjectProperty(propertyName, propertyValue) {
11193
- const internalPropertyName = `_${propertyName}`;
11194
- const previousValue = this[internalPropertyName];
11195
-
11196
- if (previousValue === propertyValue) {
11197
- return;
11198
- }
11199
-
11200
- this[internalPropertyName] = propertyValue;
11201
- this.requestUpdate(propertyName, previousValue);
11217
+ return this.max && dateFormatter$3.isValidDate(this.max) ? dateFormatter$3.stringToDateInstance(this.max) : undefined;
11202
11218
  }
11203
11219
 
11204
11220
  connectedCallback() {
@@ -11227,7 +11243,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11227
11243
  format: this.format
11228
11244
  });
11229
11245
  this.configureDataForType();
11230
- this.syncDateValues();
11231
11246
  }
11232
11247
 
11233
11248
  disconnectedCallback() {
@@ -11266,7 +11281,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11266
11281
  this.setCustomHelpTextMessage();
11267
11282
  this.configureAutoFormatting();
11268
11283
  this.configureDataForType();
11269
- this.syncDateValues();
11270
11284
  }
11271
11285
 
11272
11286
  /**
@@ -11410,8 +11424,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11410
11424
  this.configureDataForType();
11411
11425
  }
11412
11426
 
11413
- this.syncDateValues(changedProperties);
11414
-
11415
11427
  if (changedProperties.has('value')) {
11416
11428
  if (this.value && this.value.length > 0) {
11417
11429
  this.hasValue = true;
@@ -11433,14 +11445,14 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11433
11445
 
11434
11446
  if (formattedValue !== this.inputElement.value) {
11435
11447
  this.skipNextProgrammaticInputEvent = true;
11436
- if (this.maskInstance && this.type === 'credit-card') {
11448
+ if (this.maskInstance && this.type !== 'date') {
11437
11449
  // Route through the mask so its _value and el.value stay in lock-step
11438
11450
  // (set value calls updateControl which writes el.value = displayValue).
11439
11451
  // Writing el.value directly leaves the mask thinking displayValue is
11440
- // stale; _saveSelection on the next focus/click then warns. Scoped to
11441
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11442
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11443
- // and flip validity from patternMismatch to tooShort.
11452
+ // stale; _saveSelection on the next focus/click then warns. Date is
11453
+ // excluded because its formattedValue can be raw ISO when the calendar
11454
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11455
+ // flip validity from patternMismatch to tooShort.
11444
11456
  this.maskInstance.value = formattedValue || '';
11445
11457
  } else if (formattedValue) {
11446
11458
  this.inputElement.value = formattedValue;
@@ -11482,120 +11494,65 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11482
11494
  }));
11483
11495
  }
11484
11496
 
11485
-
11486
- /**
11487
- * Synchronizes the ISO string values and Date object representations for date-related properties.
11488
- * This keeps the model and display values aligned when either side changes.
11489
- *
11490
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11491
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11492
- * represents a full year/month/day date format.
11493
- *
11494
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11495
- * @returns {void}
11496
- * @private
11497
- */
11498
- syncDateValues(changedProperties = undefined) {
11499
- if (!this.util.isFullDateFormat(this.type, this.format)) {
11500
- return;
11501
- }
11502
-
11503
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11504
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11505
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11506
- }
11507
-
11508
- /**
11509
- * Synchronizes one date object/string property pair.
11510
- * @private
11511
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11512
- * @param {string} objectProperty - Date object property name.
11513
- * @param {string} valueProperty - ISO string property name.
11514
- * @returns {void}
11515
- */
11516
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11517
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11518
-
11519
- // objectProperty wins over valueProperty when both changed
11520
- if (objectPropertyChanged && this[objectProperty]) {
11521
- this[valueProperty] = dateFormatter$3.toISOFormatString(this[objectProperty]);
11522
- return;
11523
- }
11524
-
11525
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11526
- if (!valuePropertyChanged) {
11527
- return;
11528
- }
11529
-
11530
- // 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)
11531
- if (
11532
- changedProperties &&
11533
- valueProperty === 'value' &&
11534
- changedProperties.get('value') === undefined &&
11535
- this[objectProperty] instanceof Date &&
11536
- this[valueProperty] === dateFormatter$3.toISOFormatString(this[objectProperty])
11537
- ) {
11538
- return;
11539
- }
11540
-
11541
- if (dateFormatter$3.isValidDate(this[valueProperty])) {
11542
- this.setDateObjectProperty(objectProperty, dateFormatter$3.stringToDateInstance(this[valueProperty]));
11543
- } else {
11544
- this.setDateObjectProperty(objectProperty, undefined);
11545
- }
11546
- }
11547
-
11548
11497
  /**
11549
11498
  * Sets up IMasks and logic based on auto-formatting requirements.
11550
11499
  * @private
11551
11500
  * @returns {void}
11552
11501
  */
11553
11502
  configureAutoFormatting() {
11554
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11555
- // by _configuringMask above) could otherwise trigger handleInput
11556
- // processCreditCard configureAutoFormatting before the outer call's
11557
- // set value has finished its alignCursor pass.
11503
+ // _configuringMask gates two things: external re-entry into this method
11504
+ // while setup is mid-flight (from property changes that call back here),
11505
+ // and the accept/complete listeners below — both need to ignore the mask
11506
+ // events fired by our own value-restore step.
11558
11507
  if (this._configuringMask) return;
11559
11508
  this._configuringMask = true;
11560
11509
  try {
11510
+ // Destroy any prior mask so IMask can attach fresh under the new format.
11511
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11512
+ // type switched from credit-card to text) the IMask() reassignment
11513
+ // below is skipped, and downstream writes at line ~823 would otherwise
11514
+ // route through the destroyed instance.
11561
11515
  if (this.maskInstance) {
11562
11516
  this.maskInstance.destroy();
11517
+ this.maskInstance = null;
11563
11518
  }
11564
11519
 
11565
- // Pass new format to util
11566
11520
  this.util.updateFormat(this.format);
11567
11521
 
11568
11522
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11569
11523
 
11570
11524
  if (this.inputElement && maskOptions.mask) {
11571
-
11572
- // Stash and clear any existing value before IMask init.
11573
- // IMask's constructor processes the current input value which requires
11574
- // selection state clearing first avoids that scenario entirely.
11575
- // When the format changes (e.g. locale switch) and we have a valid ISO
11576
- // model value, compute the display string for the NEW format instead of
11577
- // re-using the old display string, which may be invalid in the new mask.
11525
+ // Capture the current display so it can be re-applied after IMask
11526
+ // attaches. The restore at the bottom goes through maskInstance.value
11527
+ // (not inputElement.value directly) so the mask's internal state and
11528
+ // the input's displayed text stay in lock-step.
11578
11529
  let existingValue = this.inputElement.value;
11530
+
11531
+ // Format-change case (e.g. locale switch): existingValue is the OLD
11532
+ // mask's display string and may not parse under the new mask. When
11533
+ // we have a valid date model, rebuild the display from valueObject
11534
+ // (the canonical source) using the new mask's format function.
11579
11535
  if (
11580
11536
  this.util.isFullDateFormat(this.type, this.format) &&
11581
11537
  this.value &&
11582
- dateFormatter$3.isValidDate(this.value) &&
11583
- this.valueObject instanceof Date &&
11584
- !Number.isNaN(this.valueObject.getTime()) &&
11538
+ this.valueObject &&
11585
11539
  typeof maskOptions.format === 'function'
11586
11540
  ) {
11587
11541
  existingValue = maskOptions.format(this.valueObject);
11588
11542
  }
11589
11543
 
11544
+ // Clear before IMask attaches so the constructor seeds an empty
11545
+ // internal value. Otherwise IMask reads the stale unmasked string
11546
+ // and emits a spurious 'accept' before the restore below runs.
11590
11547
  this.skipNextProgrammaticInputEvent = true;
11591
11548
  this.inputElement.value = '';
11592
11549
 
11593
11550
  this.maskInstance = IMask$3(this.inputElement, maskOptions);
11594
11551
 
11552
+ // Mask fires 'accept' on every value change, including the restore
11553
+ // step below. Skip events fired during configureAutoFormatting so
11554
+ // we don't overwrite a value the parent just pushed.
11595
11555
  this.maskInstance.on('accept', () => {
11596
- // Suppress propagation during configureAutoFormatting's own value-restoration
11597
- // (line below) — the mask emits 'accept' on every value-set, including ours,
11598
- // and we don't want to overwrite a value the parent just pushed.
11599
11556
  if (this._configuringMask) return;
11600
11557
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11601
11558
  if (this.type === "date") {
@@ -11603,6 +11560,8 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11603
11560
  }
11604
11561
  });
11605
11562
 
11563
+ // Mask fires 'complete' on the restore step below for any value that
11564
+ // happens to be a complete match. Same setup-suppression as 'accept'.
11606
11565
  this.maskInstance.on('complete', () => {
11607
11566
  if (this._configuringMask) return;
11608
11567
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11611,7 +11570,9 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11611
11570
  }
11612
11571
  });
11613
11572
 
11614
- // Restore the stashed value through IMask so it's properly masked
11573
+ // Write existingValue through the mask (not the input directly) so
11574
+ // the mask reformats it under the new rules and keeps its internal
11575
+ // _value aligned with the input's displayed text.
11615
11576
  if (existingValue) {
11616
11577
  this.maskInstance.value = existingValue;
11617
11578
  }
@@ -11705,9 +11666,9 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11705
11666
  // the gated types currently support it, since the list is a public
11706
11667
  // property a consumer could mutate.
11707
11668
  if (this.setSelectionInputTypes.includes(this.type)) {
11708
- let selectionStart;
11669
+ let selectionStart = null;
11709
11670
  try {
11710
- selectionStart = this.inputElement.selectionStart;
11671
+ ({ selectionStart } = this.inputElement);
11711
11672
  } catch (error) { // eslint-disable-line no-unused-vars
11712
11673
  return;
11713
11674
  }
@@ -11811,7 +11772,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11811
11772
  */
11812
11773
  reset() {
11813
11774
  this.value = undefined;
11814
- this.setDateObjectProperty('valueObject', undefined);
11815
11775
  this.validation.reset(this);
11816
11776
  }
11817
11777
 
@@ -11820,7 +11780,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11820
11780
  */
11821
11781
  clear() {
11822
11782
  this.value = undefined;
11823
- this.setDateObjectProperty('valueObject', undefined);
11824
11783
  }
11825
11784
 
11826
11785
  /**
@@ -12349,7 +12308,7 @@ let AuroHelpText$8 = class AuroHelpText extends i$2 {
12349
12308
  }
12350
12309
  };
12351
12310
 
12352
- var formkitVersion$8 = '202606292156';
12311
+ var formkitVersion$8 = '202607011722';
12353
12312
 
12354
12313
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12355
12314
  // See LICENSE in the project root for license information.
@@ -13624,11 +13583,17 @@ let AuroFormValidation$1$1 = class AuroFormValidation {
13624
13583
  return;
13625
13584
  }
13626
13585
 
13627
- // Validate that the date passed was the correct format and is a valid date
13586
+ // Validate that the date passed was the correct format and is a valid date.
13587
+ // For partial date formats, valueObject is never populated; validate them directly.
13628
13588
  if (elem.value && !elem.valueObject) {
13629
- elem.validity = 'patternMismatch';
13630
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
13631
- return;
13589
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
13590
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
13591
+
13592
+ if (!isValidPartial) {
13593
+ elem.validity = 'patternMismatch';
13594
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
13595
+ return;
13596
+ }
13632
13597
  }
13633
13598
 
13634
13599
  // Perform the rest of the validation
@@ -13722,15 +13687,17 @@ let AuroFormValidation$1$1 = class AuroFormValidation {
13722
13687
  );
13723
13688
  }
13724
13689
 
13725
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
13726
- if (this.auroInputElements?.length === 2) {
13727
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
13690
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
13691
+
13692
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
13693
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
13694
+ // field (datepicker is the intended consumer — start/end are independently required).
13695
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
13696
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
13728
13697
  hasValue = false;
13729
13698
  }
13730
13699
  }
13731
13700
 
13732
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
13733
-
13734
13701
  if (isCombobox) {
13735
13702
 
13736
13703
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -23553,6 +23520,42 @@ let AuroInputUtilities$1 = class AuroInputUtilities {
23553
23520
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
23554
23521
  }
23555
23522
 
23523
+ /**
23524
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
23525
+ * Single-component formats are checked as integer ranges; multi-component formats use
23526
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
23527
+ * @param {string} value - The user-facing display value.
23528
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
23529
+ * @returns {boolean}
23530
+ */
23531
+ isValidPartialDate(value, format) {
23532
+ if (!value || !format) {
23533
+ return false;
23534
+ }
23535
+ const normalizedFormat = format.toLowerCase();
23536
+
23537
+ if (normalizedFormat === 'dd') {
23538
+ const num = Number(value);
23539
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
23540
+ }
23541
+ if (normalizedFormat === 'yy') {
23542
+ const num = Number(value);
23543
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
23544
+ }
23545
+ if (normalizedFormat === 'yyyy') {
23546
+ const num = Number(value);
23547
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
23548
+ }
23549
+
23550
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
23551
+ // Use the 1st of the current month as the reference so that formats
23552
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
23553
+ const referenceDate = new Date();
23554
+ referenceDate.setDate(1);
23555
+ const parsed = parse$1(value, dateFnsMask, referenceDate);
23556
+ return isValid$1(parsed) && format$1(parsed, dateFnsMask) === value;
23557
+ }
23558
+
23556
23559
  /**
23557
23560
  * Converts a display string to its model value.
23558
23561
  * For full date formats, converts the display string to an ISO date string.
@@ -23600,6 +23603,7 @@ let AuroInputUtilities$1 = class AuroInputUtilities {
23600
23603
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
23601
23604
 
23602
23605
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
23606
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
23603
23607
  return undefined;
23604
23608
  }
23605
23609
 
@@ -26625,7 +26629,7 @@ let AuroBibtemplate$3 = class AuroBibtemplate extends i$2 {
26625
26629
  }
26626
26630
  };
26627
26631
 
26628
- var formkitVersion$2$1 = '202606292156';
26632
+ var formkitVersion$2$1 = '202607011722';
26629
26633
 
26630
26634
  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$5`${s$5(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$4`: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}
26631
26635
  `,u$4$2=i$4`.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}}
@@ -32377,7 +32381,7 @@ let AuroHelpText$2$1 = class AuroHelpText extends i$2 {
32377
32381
  }
32378
32382
  };
32379
32383
 
32380
- var formkitVersion$1$3 = '202606292156';
32384
+ var formkitVersion$1$3 = '202607011722';
32381
32385
 
32382
32386
  let AuroElement$2$2 = class AuroElement extends i$2 {
32383
32387
  static get properties() {
@@ -33129,7 +33133,19 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
33129
33133
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
33130
33134
  this.trigger.focus();
33131
33135
  }
33132
- }
33136
+
33137
+
33138
+ if (!this.isPopoverVisible) {
33139
+ // wait til the bib gets fully closed and rendered
33140
+ setTimeout(() => {
33141
+ // 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.
33142
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
33143
+ return;
33144
+ }
33145
+ // Move focus out of bib into trigger.
33146
+ this.trigger.focus();
33147
+ });
33148
+ } }
33133
33149
 
33134
33150
  firstUpdated() {
33135
33151
  // Configure the floater to, this will generate the ID for the bib
@@ -38054,11 +38070,17 @@ let AuroFormValidation$6 = class AuroFormValidation {
38054
38070
  return;
38055
38071
  }
38056
38072
 
38057
- // Validate that the date passed was the correct format and is a valid date
38073
+ // Validate that the date passed was the correct format and is a valid date.
38074
+ // For partial date formats, valueObject is never populated; validate them directly.
38058
38075
  if (elem.value && !elem.valueObject) {
38059
- elem.validity = 'patternMismatch';
38060
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
38061
- return;
38076
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
38077
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
38078
+
38079
+ if (!isValidPartial) {
38080
+ elem.validity = 'patternMismatch';
38081
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
38082
+ return;
38083
+ }
38062
38084
  }
38063
38085
 
38064
38086
  // Perform the rest of the validation
@@ -38152,15 +38174,17 @@ let AuroFormValidation$6 = class AuroFormValidation {
38152
38174
  );
38153
38175
  }
38154
38176
 
38155
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
38156
- if (this.auroInputElements?.length === 2) {
38157
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
38177
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
38178
+
38179
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
38180
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
38181
+ // field (datepicker is the intended consumer — start/end are independently required).
38182
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
38183
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
38158
38184
  hasValue = false;
38159
38185
  }
38160
38186
  }
38161
38187
 
38162
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
38163
-
38164
38188
  if (isCombobox) {
38165
38189
 
38166
38190
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -44060,6 +44084,42 @@ let AuroInputUtilities$2 = class AuroInputUtilities {
44060
44084
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
44061
44085
  }
44062
44086
 
44087
+ /**
44088
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
44089
+ * Single-component formats are checked as integer ranges; multi-component formats use
44090
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
44091
+ * @param {string} value - The user-facing display value.
44092
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
44093
+ * @returns {boolean}
44094
+ */
44095
+ isValidPartialDate(value, format$1) {
44096
+ if (!value || !format$1) {
44097
+ return false;
44098
+ }
44099
+ const normalizedFormat = format$1.toLowerCase();
44100
+
44101
+ if (normalizedFormat === 'dd') {
44102
+ const num = Number(value);
44103
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
44104
+ }
44105
+ if (normalizedFormat === 'yy') {
44106
+ const num = Number(value);
44107
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
44108
+ }
44109
+ if (normalizedFormat === 'yyyy') {
44110
+ const num = Number(value);
44111
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
44112
+ }
44113
+
44114
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
44115
+ // Use the 1st of the current month as the reference so that formats
44116
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
44117
+ const referenceDate = new Date();
44118
+ referenceDate.setDate(1);
44119
+ const parsed = parse$2(value, dateFnsMask, referenceDate);
44120
+ return isValid$2(parsed) && format$2(parsed, dateFnsMask) === value;
44121
+ }
44122
+
44063
44123
  /**
44064
44124
  * Converts a display string to its model value.
44065
44125
  * For full date formats, converts the display string to an ISO date string.
@@ -44107,6 +44167,7 @@ let AuroInputUtilities$2 = class AuroInputUtilities {
44107
44167
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
44108
44168
 
44109
44169
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
44170
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
44110
44171
  return undefined;
44111
44172
  }
44112
44173
 
@@ -44264,6 +44325,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44264
44325
  // so a parent (datepicker/combobox) calling `validate()` synchronously
44265
44326
  // during its own update cycle sees a populated util instance.
44266
44327
  this.activeLabel = false;
44328
+
44267
44329
  /** @private */
44268
44330
  this.allowedInputTypes = [
44269
44331
  "text",
@@ -44274,6 +44336,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44274
44336
  "tel"
44275
44337
  ];
44276
44338
  this.appearance = "default";
44339
+
44277
44340
  /** @private */
44278
44341
  this.dateFormatMap = {
44279
44342
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -44292,23 +44355,24 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44292
44355
  'mm/dd': 'dateMMDD'
44293
44356
  };
44294
44357
  this.disabled = false;
44358
+
44295
44359
  /** @private */
44296
44360
  this.domHandler = new DomHandler$2();
44297
44361
  this.dvInputOnly = false;
44298
44362
  this.hasValue = false;
44299
44363
  this.hideLabelVisually = false;
44300
44364
  this.icon = false;
44365
+
44301
44366
  /** @private */
44302
44367
  this.inputIconName = undefined;
44368
+
44303
44369
  /** @private */
44304
44370
  this.label = 'Input label is undefined';
44305
44371
  this.layout = 'classic';
44306
44372
  this.locale = 'en-US';
44307
44373
  this.max = undefined;
44308
- this._maxObject = undefined;
44309
44374
  this.maxLength = undefined;
44310
44375
  this.min = undefined;
44311
- this._minObject = undefined;
44312
44376
  this.minLength = undefined;
44313
44377
  this.noValidate = false;
44314
44378
  this.onDark = false;
@@ -44325,23 +44389,27 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44325
44389
  "email"
44326
44390
  ];
44327
44391
  this.shape = 'classic';
44392
+
44328
44393
  /** @private */
44329
44394
  this.showPassword = false;
44330
44395
  this.size = 'lg';
44331
44396
  this.touched = false;
44397
+
44332
44398
  /** @private */
44333
44399
  this.uniqueId = new UniqueId$1().create();
44400
+
44334
44401
  /** @private */
44335
44402
  this.util = new AuroInputUtilities$2({
44336
44403
  locale: this.locale,
44337
44404
  format: this.format
44338
44405
  });
44406
+
44339
44407
  /** @private */
44340
44408
  this.validation = new AuroFormValidation$6();
44409
+
44341
44410
  /** @private */
44342
44411
  this.validationCCLength = undefined;
44343
44412
  this.value = undefined;
44344
- this._valueObject = undefined;
44345
44413
  }
44346
44414
 
44347
44415
  // function to define props used within the scope of this component
@@ -44671,6 +44739,13 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44671
44739
  type: String
44672
44740
  },
44673
44741
 
44742
+ /**
44743
+ * Custom help text message to display when validity = `patternMismatch`.
44744
+ */
44745
+ setCustomValidityPatternMismatch: {
44746
+ type: String
44747
+ },
44748
+
44674
44749
  /**
44675
44750
  * Custom help text message to display when validity = `rangeOverflow`.
44676
44751
  */
@@ -44741,7 +44816,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44741
44816
 
44742
44817
  /**
44743
44818
  * Populates the `type` attribute on the input.
44744
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
44819
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
44745
44820
  * @default 'text'
44746
44821
  */
44747
44822
  type: {
@@ -44779,7 +44854,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44779
44854
  * @returns {Date|undefined}
44780
44855
  */
44781
44856
  get valueObject() {
44782
- return this._valueObject || this._computeDateObjectFallback(this.value);
44857
+ return this.value && dateFormatter$2.isValidDate(this.value) ? dateFormatter$2.stringToDateInstance(this.value) : undefined;
44783
44858
  }
44784
44859
 
44785
44860
  /**
@@ -44787,7 +44862,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44787
44862
  * @returns {Date|undefined}
44788
44863
  */
44789
44864
  get minObject() {
44790
- return this._minObject || this._computeDateObjectFallback(this.min);
44865
+ return this.min && dateFormatter$2.isValidDate(this.min) ? dateFormatter$2.stringToDateInstance(this.min) : undefined;
44791
44866
  }
44792
44867
 
44793
44868
  /**
@@ -44795,50 +44870,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44795
44870
  * @returns {Date|undefined}
44796
44871
  */
44797
44872
  get maxObject() {
44798
- return this._maxObject || this._computeDateObjectFallback(this.max);
44799
- }
44800
-
44801
- /**
44802
- * Parses a date string into a Date object when the corresponding `_*Object`
44803
- * field hasn't been synced yet by `updated()`. Returns undefined when the
44804
- * input type/format isn't a full date or the string is not a valid date.
44805
- *
44806
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
44807
- * inside its own `updated()` before this input's `updated()` has run
44808
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
44809
- * and range checks would otherwise silently no-op (flipping the result to
44810
- * `valid` or `patternMismatch`).
44811
- * @private
44812
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
44813
- * @returns {Date|undefined}
44814
- */
44815
- _computeDateObjectFallback(dateStr) {
44816
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
44817
- return undefined;
44818
- }
44819
- if (!dateFormatter$2.isValidDate(dateStr)) {
44820
- return undefined;
44821
- }
44822
- return dateFormatter$2.stringToDateInstance(dateStr);
44823
- }
44824
-
44825
- /**
44826
- * Internal setter for readonly date object properties.
44827
- * @private
44828
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
44829
- * @param {Date|undefined} propertyValue - Value to assign.
44830
- * @returns {void}
44831
- */
44832
- setDateObjectProperty(propertyName, propertyValue) {
44833
- const internalPropertyName = `_${propertyName}`;
44834
- const previousValue = this[internalPropertyName];
44835
-
44836
- if (previousValue === propertyValue) {
44837
- return;
44838
- }
44839
-
44840
- this[internalPropertyName] = propertyValue;
44841
- this.requestUpdate(propertyName, previousValue);
44873
+ return this.max && dateFormatter$2.isValidDate(this.max) ? dateFormatter$2.stringToDateInstance(this.max) : undefined;
44842
44874
  }
44843
44875
 
44844
44876
  connectedCallback() {
@@ -44867,7 +44899,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44867
44899
  format: this.format
44868
44900
  });
44869
44901
  this.configureDataForType();
44870
- this.syncDateValues();
44871
44902
  }
44872
44903
 
44873
44904
  disconnectedCallback() {
@@ -44906,7 +44937,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44906
44937
  this.setCustomHelpTextMessage();
44907
44938
  this.configureAutoFormatting();
44908
44939
  this.configureDataForType();
44909
- this.syncDateValues();
44910
44940
  }
44911
44941
 
44912
44942
  /**
@@ -45050,8 +45080,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45050
45080
  this.configureDataForType();
45051
45081
  }
45052
45082
 
45053
- this.syncDateValues(changedProperties);
45054
-
45055
45083
  if (changedProperties.has('value')) {
45056
45084
  if (this.value && this.value.length > 0) {
45057
45085
  this.hasValue = true;
@@ -45073,14 +45101,14 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45073
45101
 
45074
45102
  if (formattedValue !== this.inputElement.value) {
45075
45103
  this.skipNextProgrammaticInputEvent = true;
45076
- if (this.maskInstance && this.type === 'credit-card') {
45104
+ if (this.maskInstance && this.type !== 'date') {
45077
45105
  // Route through the mask so its _value and el.value stay in lock-step
45078
45106
  // (set value calls updateControl which writes el.value = displayValue).
45079
45107
  // Writing el.value directly leaves the mask thinking displayValue is
45080
- // stale; _saveSelection on the next focus/click then warns. Scoped to
45081
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
45082
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
45083
- // and flip validity from patternMismatch to tooShort.
45108
+ // stale; _saveSelection on the next focus/click then warns. Date is
45109
+ // excluded because its formattedValue can be raw ISO when the calendar
45110
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
45111
+ // flip validity from patternMismatch to tooShort.
45084
45112
  this.maskInstance.value = formattedValue || '';
45085
45113
  } else if (formattedValue) {
45086
45114
  this.inputElement.value = formattedValue;
@@ -45122,120 +45150,65 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45122
45150
  }));
45123
45151
  }
45124
45152
 
45125
-
45126
- /**
45127
- * Synchronizes the ISO string values and Date object representations for date-related properties.
45128
- * This keeps the model and display values aligned when either side changes.
45129
- *
45130
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
45131
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
45132
- * represents a full year/month/day date format.
45133
- *
45134
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
45135
- * @returns {void}
45136
- * @private
45137
- */
45138
- syncDateValues(changedProperties = undefined) {
45139
- if (!this.util.isFullDateFormat(this.type, this.format)) {
45140
- return;
45141
- }
45142
-
45143
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
45144
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
45145
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
45146
- }
45147
-
45148
- /**
45149
- * Synchronizes one date object/string property pair.
45150
- * @private
45151
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
45152
- * @param {string} objectProperty - Date object property name.
45153
- * @param {string} valueProperty - ISO string property name.
45154
- * @returns {void}
45155
- */
45156
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
45157
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
45158
-
45159
- // objectProperty wins over valueProperty when both changed
45160
- if (objectPropertyChanged && this[objectProperty]) {
45161
- this[valueProperty] = dateFormatter$2.toISOFormatString(this[objectProperty]);
45162
- return;
45163
- }
45164
-
45165
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
45166
- if (!valuePropertyChanged) {
45167
- return;
45168
- }
45169
-
45170
- // 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)
45171
- if (
45172
- changedProperties &&
45173
- valueProperty === 'value' &&
45174
- changedProperties.get('value') === undefined &&
45175
- this[objectProperty] instanceof Date &&
45176
- this[valueProperty] === dateFormatter$2.toISOFormatString(this[objectProperty])
45177
- ) {
45178
- return;
45179
- }
45180
-
45181
- if (dateFormatter$2.isValidDate(this[valueProperty])) {
45182
- this.setDateObjectProperty(objectProperty, dateFormatter$2.stringToDateInstance(this[valueProperty]));
45183
- } else {
45184
- this.setDateObjectProperty(objectProperty, undefined);
45185
- }
45186
- }
45187
-
45188
45153
  /**
45189
45154
  * Sets up IMasks and logic based on auto-formatting requirements.
45190
45155
  * @private
45191
45156
  * @returns {void}
45192
45157
  */
45193
45158
  configureAutoFormatting() {
45194
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
45195
- // by _configuringMask above) could otherwise trigger handleInput
45196
- // processCreditCard configureAutoFormatting before the outer call's
45197
- // set value has finished its alignCursor pass.
45159
+ // _configuringMask gates two things: external re-entry into this method
45160
+ // while setup is mid-flight (from property changes that call back here),
45161
+ // and the accept/complete listeners below — both need to ignore the mask
45162
+ // events fired by our own value-restore step.
45198
45163
  if (this._configuringMask) return;
45199
45164
  this._configuringMask = true;
45200
45165
  try {
45166
+ // Destroy any prior mask so IMask can attach fresh under the new format.
45167
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
45168
+ // type switched from credit-card to text) the IMask() reassignment
45169
+ // below is skipped, and downstream writes at line ~823 would otherwise
45170
+ // route through the destroyed instance.
45201
45171
  if (this.maskInstance) {
45202
45172
  this.maskInstance.destroy();
45173
+ this.maskInstance = null;
45203
45174
  }
45204
45175
 
45205
- // Pass new format to util
45206
45176
  this.util.updateFormat(this.format);
45207
45177
 
45208
45178
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
45209
45179
 
45210
45180
  if (this.inputElement && maskOptions.mask) {
45211
-
45212
- // Stash and clear any existing value before IMask init.
45213
- // IMask's constructor processes the current input value which requires
45214
- // selection state clearing first avoids that scenario entirely.
45215
- // When the format changes (e.g. locale switch) and we have a valid ISO
45216
- // model value, compute the display string for the NEW format instead of
45217
- // re-using the old display string, which may be invalid in the new mask.
45181
+ // Capture the current display so it can be re-applied after IMask
45182
+ // attaches. The restore at the bottom goes through maskInstance.value
45183
+ // (not inputElement.value directly) so the mask's internal state and
45184
+ // the input's displayed text stay in lock-step.
45218
45185
  let existingValue = this.inputElement.value;
45186
+
45187
+ // Format-change case (e.g. locale switch): existingValue is the OLD
45188
+ // mask's display string and may not parse under the new mask. When
45189
+ // we have a valid date model, rebuild the display from valueObject
45190
+ // (the canonical source) using the new mask's format function.
45219
45191
  if (
45220
45192
  this.util.isFullDateFormat(this.type, this.format) &&
45221
45193
  this.value &&
45222
- dateFormatter$2.isValidDate(this.value) &&
45223
- this.valueObject instanceof Date &&
45224
- !Number.isNaN(this.valueObject.getTime()) &&
45194
+ this.valueObject &&
45225
45195
  typeof maskOptions.format === 'function'
45226
45196
  ) {
45227
45197
  existingValue = maskOptions.format(this.valueObject);
45228
45198
  }
45229
45199
 
45200
+ // Clear before IMask attaches so the constructor seeds an empty
45201
+ // internal value. Otherwise IMask reads the stale unmasked string
45202
+ // and emits a spurious 'accept' before the restore below runs.
45230
45203
  this.skipNextProgrammaticInputEvent = true;
45231
45204
  this.inputElement.value = '';
45232
45205
 
45233
45206
  this.maskInstance = IMask$2(this.inputElement, maskOptions);
45234
45207
 
45208
+ // Mask fires 'accept' on every value change, including the restore
45209
+ // step below. Skip events fired during configureAutoFormatting so
45210
+ // we don't overwrite a value the parent just pushed.
45235
45211
  this.maskInstance.on('accept', () => {
45236
- // Suppress propagation during configureAutoFormatting's own value-restoration
45237
- // (line below) — the mask emits 'accept' on every value-set, including ours,
45238
- // and we don't want to overwrite a value the parent just pushed.
45239
45212
  if (this._configuringMask) return;
45240
45213
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
45241
45214
  if (this.type === "date") {
@@ -45243,6 +45216,8 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45243
45216
  }
45244
45217
  });
45245
45218
 
45219
+ // Mask fires 'complete' on the restore step below for any value that
45220
+ // happens to be a complete match. Same setup-suppression as 'accept'.
45246
45221
  this.maskInstance.on('complete', () => {
45247
45222
  if (this._configuringMask) return;
45248
45223
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -45251,7 +45226,9 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45251
45226
  }
45252
45227
  });
45253
45228
 
45254
- // Restore the stashed value through IMask so it's properly masked
45229
+ // Write existingValue through the mask (not the input directly) so
45230
+ // the mask reformats it under the new rules and keeps its internal
45231
+ // _value aligned with the input's displayed text.
45255
45232
  if (existingValue) {
45256
45233
  this.maskInstance.value = existingValue;
45257
45234
  }
@@ -45345,9 +45322,9 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45345
45322
  // the gated types currently support it, since the list is a public
45346
45323
  // property a consumer could mutate.
45347
45324
  if (this.setSelectionInputTypes.includes(this.type)) {
45348
- let selectionStart;
45325
+ let selectionStart = null;
45349
45326
  try {
45350
- selectionStart = this.inputElement.selectionStart;
45327
+ ({ selectionStart } = this.inputElement);
45351
45328
  } catch (error) { // eslint-disable-line no-unused-vars
45352
45329
  return;
45353
45330
  }
@@ -45451,7 +45428,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45451
45428
  */
45452
45429
  reset() {
45453
45430
  this.value = undefined;
45454
- this.setDateObjectProperty('valueObject', undefined);
45455
45431
  this.validation.reset(this);
45456
45432
  }
45457
45433
 
@@ -45460,7 +45436,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45460
45436
  */
45461
45437
  clear() {
45462
45438
  this.value = undefined;
45463
- this.setDateObjectProperty('valueObject', undefined);
45464
45439
  }
45465
45440
 
45466
45441
  /**
@@ -45989,7 +45964,7 @@ let AuroHelpText$1$3 = class AuroHelpText extends i$2 {
45989
45964
  }
45990
45965
  };
45991
45966
 
45992
- var formkitVersion$7 = '202606292156';
45967
+ var formkitVersion$7 = '202607011722';
45993
45968
 
45994
45969
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
45995
45970
  // See LICENSE in the project root for license information.
@@ -50285,11 +50260,17 @@ let AuroFormValidation$5 = class AuroFormValidation {
50285
50260
  return;
50286
50261
  }
50287
50262
 
50288
- // Validate that the date passed was the correct format and is a valid date
50263
+ // Validate that the date passed was the correct format and is a valid date.
50264
+ // For partial date formats, valueObject is never populated; validate them directly.
50289
50265
  if (elem.value && !elem.valueObject) {
50290
- elem.validity = 'patternMismatch';
50291
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
50292
- return;
50266
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
50267
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
50268
+
50269
+ if (!isValidPartial) {
50270
+ elem.validity = 'patternMismatch';
50271
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
50272
+ return;
50273
+ }
50293
50274
  }
50294
50275
 
50295
50276
  // Perform the rest of the validation
@@ -50383,15 +50364,17 @@ let AuroFormValidation$5 = class AuroFormValidation {
50383
50364
  );
50384
50365
  }
50385
50366
 
50386
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
50387
- if (this.auroInputElements?.length === 2) {
50388
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
50367
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
50368
+
50369
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
50370
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
50371
+ // field (datepicker is the intended consumer — start/end are independently required).
50372
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
50373
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
50389
50374
  hasValue = false;
50390
50375
  }
50391
50376
  }
50392
50377
 
50393
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
50394
-
50395
50378
  if (isCombobox) {
50396
50379
 
50397
50380
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -50856,7 +50839,7 @@ let AuroHelpText$1$2 = class AuroHelpText extends i$2 {
50856
50839
  }
50857
50840
  };
50858
50841
 
50859
- var formkitVersion$1$2 = '202606292156';
50842
+ var formkitVersion$1$2 = '202607011722';
50860
50843
 
50861
50844
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
50862
50845
  // See LICENSE in the project root for license information.
@@ -55184,7 +55167,7 @@ let AuroHelpText$6 = class AuroHelpText extends i$2 {
55184
55167
  }
55185
55168
  };
55186
55169
 
55187
- var formkitVersion$6 = '202606292156';
55170
+ var formkitVersion$6 = '202607011722';
55188
55171
 
55189
55172
  let AuroElement$1$2 = class AuroElement extends i$2 {
55190
55173
  static get properties() {
@@ -55936,7 +55919,19 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
55936
55919
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
55937
55920
  this.trigger.focus();
55938
55921
  }
55939
- }
55922
+
55923
+
55924
+ if (!this.isPopoverVisible) {
55925
+ // wait til the bib gets fully closed and rendered
55926
+ setTimeout(() => {
55927
+ // 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.
55928
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
55929
+ return;
55930
+ }
55931
+ // Move focus out of bib into trigger.
55932
+ this.trigger.focus();
55933
+ });
55934
+ } }
55940
55935
 
55941
55936
  firstUpdated() {
55942
55937
  // Configure the floater to, this will generate the ID for the bib
@@ -58635,11 +58630,17 @@ let AuroFormValidation$4 = class AuroFormValidation {
58635
58630
  return;
58636
58631
  }
58637
58632
 
58638
- // Validate that the date passed was the correct format and is a valid date
58633
+ // Validate that the date passed was the correct format and is a valid date.
58634
+ // For partial date formats, valueObject is never populated; validate them directly.
58639
58635
  if (elem.value && !elem.valueObject) {
58640
- elem.validity = 'patternMismatch';
58641
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
58642
- return;
58636
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
58637
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
58638
+
58639
+ if (!isValidPartial) {
58640
+ elem.validity = 'patternMismatch';
58641
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
58642
+ return;
58643
+ }
58643
58644
  }
58644
58645
 
58645
58646
  // Perform the rest of the validation
@@ -58733,15 +58734,17 @@ let AuroFormValidation$4 = class AuroFormValidation {
58733
58734
  );
58734
58735
  }
58735
58736
 
58736
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
58737
- if (this.auroInputElements?.length === 2) {
58738
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
58737
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
58738
+
58739
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
58740
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
58741
+ // field (datepicker is the intended consumer — start/end are independently required).
58742
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
58743
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
58739
58744
  hasValue = false;
58740
58745
  }
58741
58746
  }
58742
58747
 
58743
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
58744
-
58745
58748
  if (isCombobox) {
58746
58749
 
58747
58750
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -59132,7 +59135,7 @@ let AuroHelpText$5 = class AuroHelpText extends i$2 {
59132
59135
  }
59133
59136
  };
59134
59137
 
59135
- var formkitVersion$5 = '202606292156';
59138
+ var formkitVersion$5 = '202607011722';
59136
59139
 
59137
59140
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
59138
59141
  // See LICENSE in the project root for license information.
@@ -60381,11 +60384,17 @@ let AuroFormValidation$3 = class AuroFormValidation {
60381
60384
  return;
60382
60385
  }
60383
60386
 
60384
- // Validate that the date passed was the correct format and is a valid date
60387
+ // Validate that the date passed was the correct format and is a valid date.
60388
+ // For partial date formats, valueObject is never populated; validate them directly.
60385
60389
  if (elem.value && !elem.valueObject) {
60386
- elem.validity = 'patternMismatch';
60387
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
60388
- return;
60390
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
60391
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
60392
+
60393
+ if (!isValidPartial) {
60394
+ elem.validity = 'patternMismatch';
60395
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
60396
+ return;
60397
+ }
60389
60398
  }
60390
60399
 
60391
60400
  // Perform the rest of the validation
@@ -60479,15 +60488,17 @@ let AuroFormValidation$3 = class AuroFormValidation {
60479
60488
  );
60480
60489
  }
60481
60490
 
60482
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
60483
- if (this.auroInputElements?.length === 2) {
60484
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
60491
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
60492
+
60493
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
60494
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
60495
+ // field (datepicker is the intended consumer — start/end are independently required).
60496
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
60497
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
60485
60498
  hasValue = false;
60486
60499
  }
60487
60500
  }
60488
60501
 
60489
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
60490
-
60491
60502
  if (isCombobox) {
60492
60503
 
60493
60504
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -60882,7 +60893,7 @@ let AuroHelpText$4 = class AuroHelpText extends i$2 {
60882
60893
  }
60883
60894
  };
60884
60895
 
60885
- var formkitVersion$4 = '202606292156';
60896
+ var formkitVersion$4 = '202607011722';
60886
60897
 
60887
60898
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
60888
60899
  // See LICENSE in the project root for license information.
@@ -61641,11 +61652,17 @@ let AuroFormValidation$1 = class AuroFormValidation {
61641
61652
  return;
61642
61653
  }
61643
61654
 
61644
- // Validate that the date passed was the correct format and is a valid date
61655
+ // Validate that the date passed was the correct format and is a valid date.
61656
+ // For partial date formats, valueObject is never populated; validate them directly.
61645
61657
  if (elem.value && !elem.valueObject) {
61646
- elem.validity = 'patternMismatch';
61647
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
61648
- return;
61658
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
61659
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
61660
+
61661
+ if (!isValidPartial) {
61662
+ elem.validity = 'patternMismatch';
61663
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
61664
+ return;
61665
+ }
61649
61666
  }
61650
61667
 
61651
61668
  // Perform the rest of the validation
@@ -61739,15 +61756,17 @@ let AuroFormValidation$1 = class AuroFormValidation {
61739
61756
  );
61740
61757
  }
61741
61758
 
61742
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
61743
- if (this.auroInputElements?.length === 2) {
61744
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
61759
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
61760
+
61761
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
61762
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
61763
+ // field (datepicker is the intended consumer — start/end are independently required).
61764
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
61765
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
61745
61766
  hasValue = false;
61746
61767
  }
61747
61768
  }
61748
61769
 
61749
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
61750
-
61751
61770
  if (isCombobox) {
61752
61771
 
61753
61772
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -62058,6 +62077,8 @@ function navigateArrow$1(component, direction, options = {}) {
62058
62077
  }
62059
62078
  }
62060
62079
 
62080
+ /* eslint-disable no-underscore-dangle */
62081
+
62061
62082
  /**
62062
62083
  * Returns the clear button element from the active input's shadow
62063
62084
  * DOM, if available.
@@ -62093,11 +62114,9 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
62093
62114
  * @param {Object} menu - The menu component.
62094
62115
  */
62095
62116
  function reconcileMenuIndex(menu) {
62096
- // eslint-disable-next-line no-underscore-dangle
62097
62117
  if (menu._index < 0 && menu.optionActive && menu.items) {
62098
62118
  const idx = menu.items.indexOf(menu.optionActive);
62099
62119
  if (idx >= 0) {
62100
- // eslint-disable-next-line no-underscore-dangle
62101
62120
  menu._index = idx;
62102
62121
  }
62103
62122
  }
@@ -62116,11 +62135,7 @@ const comboboxKeyboardStrategy = {
62116
62135
 
62117
62136
  // navigate if bib is open otherwise open it
62118
62137
  if (component.dropdown.isPopoverVisible) {
62119
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
62120
- component.activateLastEnabledAvailableOption();
62121
- } else {
62122
- navigateArrow$1(component, 'down');
62123
- }
62138
+ navigateArrow$1(component, 'down');
62124
62139
  } else {
62125
62140
  component.showBib();
62126
62141
  }
@@ -62139,11 +62154,7 @@ const comboboxKeyboardStrategy = {
62139
62154
 
62140
62155
  // navigate if bib is open otherwise open it
62141
62156
  if (component.dropdown.isPopoverVisible) {
62142
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
62143
- component.activateFirstEnabledAvailableOption();
62144
- } else {
62145
- navigateArrow$1(component, 'up');
62146
- }
62157
+ navigateArrow$1(component, 'up');
62147
62158
  } else {
62148
62159
  component.showBib();
62149
62160
  }
@@ -62159,13 +62170,18 @@ const comboboxKeyboardStrategy = {
62159
62170
  },
62160
62171
 
62161
62172
  Enter(component, evt, ctx) {
62173
+ // Forms should not submit on Enter from a combobox, regardless of which
62174
+ // child element (input, clear button, menu) is focused.
62175
+ evt.stopPropagation();
62176
+
62162
62177
  if (isClearBtnFocused(ctx)) {
62163
- // If the clear button has focus, let the browser activate it normally.
62164
- // stopPropagation prevents parent containers (e.g., forms) from treating
62165
- // Enter as a submit, but we must NOT call preventDefault — that would
62166
- // block the browser's built-in "Enter activates focused button" behavior.
62167
- evt.stopPropagation();
62168
- } else if (ctx.isExpanded && component.menu.optionActive) {
62178
+ // Let the browser dispatch Enter to the focused clear button so its
62179
+ // built-in activation fires and clears the selection. Do NOT call
62180
+ // preventDefault — that would block the activation.
62181
+ return;
62182
+ }
62183
+
62184
+ if (ctx.isExpanded && component.menu.optionActive) {
62169
62185
  reconcileMenuIndex(component.menu);
62170
62186
  component.menu.makeSelection();
62171
62187
 
@@ -62174,14 +62190,8 @@ const comboboxKeyboardStrategy = {
62174
62190
  }
62175
62191
 
62176
62192
  evt.preventDefault();
62177
- evt.stopPropagation();
62178
62193
  } else {
62179
- // Prevent the keypress from bubbling to parent containers (e.g., forms)
62180
- // which could interpret Enter as a submit or trigger other unintended behavior.
62181
- // This is safe because showBib() opens the dialog programmatically,
62182
- // not via event propagation.
62183
62194
  evt.preventDefault();
62184
- evt.stopPropagation();
62185
62195
  component.showBib();
62186
62196
  }
62187
62197
  },
@@ -62226,7 +62236,7 @@ const comboboxKeyboardStrategy = {
62226
62236
  component.setClearBtnFocus();
62227
62237
  }
62228
62238
  }
62229
- },
62239
+ }
62230
62240
  };
62231
62241
 
62232
62242
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
@@ -66097,7 +66107,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$2 {
66097
66107
  }
66098
66108
  };
66099
66109
 
66100
- var formkitVersion$2 = '202606292156';
66110
+ var formkitVersion$2 = '202607011722';
66101
66111
 
66102
66112
  let AuroElement$2$1 = class AuroElement extends i$2 {
66103
66113
  static get properties() {
@@ -66849,7 +66859,19 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
66849
66859
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
66850
66860
  this.trigger.focus();
66851
66861
  }
66852
- }
66862
+
66863
+
66864
+ if (!this.isPopoverVisible) {
66865
+ // wait til the bib gets fully closed and rendered
66866
+ setTimeout(() => {
66867
+ // 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.
66868
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
66869
+ return;
66870
+ }
66871
+ // Move focus out of bib into trigger.
66872
+ this.trigger.focus();
66873
+ });
66874
+ } }
66853
66875
 
66854
66876
  firstUpdated() {
66855
66877
  // Configure the floater to, this will generate the ID for the bib
@@ -71774,11 +71796,17 @@ let AuroFormValidation$2 = class AuroFormValidation {
71774
71796
  return;
71775
71797
  }
71776
71798
 
71777
- // Validate that the date passed was the correct format and is a valid date
71799
+ // Validate that the date passed was the correct format and is a valid date.
71800
+ // For partial date formats, valueObject is never populated; validate them directly.
71778
71801
  if (elem.value && !elem.valueObject) {
71779
- elem.validity = 'patternMismatch';
71780
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
71781
- return;
71802
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
71803
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
71804
+
71805
+ if (!isValidPartial) {
71806
+ elem.validity = 'patternMismatch';
71807
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
71808
+ return;
71809
+ }
71782
71810
  }
71783
71811
 
71784
71812
  // Perform the rest of the validation
@@ -71872,15 +71900,17 @@ let AuroFormValidation$2 = class AuroFormValidation {
71872
71900
  );
71873
71901
  }
71874
71902
 
71875
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
71876
- if (this.auroInputElements?.length === 2) {
71877
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
71903
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
71904
+
71905
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
71906
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
71907
+ // field (datepicker is the intended consumer — start/end are independently required).
71908
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
71909
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
71878
71910
  hasValue = false;
71879
71911
  }
71880
71912
  }
71881
71913
 
71882
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
71883
-
71884
71914
  if (isCombobox) {
71885
71915
 
71886
71916
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -77780,6 +77810,42 @@ class AuroInputUtilities {
77780
77810
  return type === 'date' && normalizedFormat.includes('yy') && normalizedFormat.includes('mm') && normalizedFormat.includes('dd');
77781
77811
  }
77782
77812
 
77813
+ /**
77814
+ * Validates a value against a partial date format (one that lacks yy/mm/dd all three).
77815
+ * Single-component formats are checked as integer ranges; multi-component formats use
77816
+ * a date-fns parse + round-trip to confirm both validity and exact formatting.
77817
+ * @param {string} value - The user-facing display value.
77818
+ * @param {string} format - The partial date format string (e.g. "mm/yyyy", "yyyy", "dd").
77819
+ * @returns {boolean}
77820
+ */
77821
+ isValidPartialDate(value, format$1) {
77822
+ if (!value || !format$1) {
77823
+ return false;
77824
+ }
77825
+ const normalizedFormat = format$1.toLowerCase();
77826
+
77827
+ if (normalizedFormat === 'dd') {
77828
+ const num = Number(value);
77829
+ return (/^\d{2}$/u).test(value) && num >= 1 && num <= 31;
77830
+ }
77831
+ if (normalizedFormat === 'yy') {
77832
+ const num = Number(value);
77833
+ return (/^\d{2}$/u).test(value) && num >= 0 && num <= 99;
77834
+ }
77835
+ if (normalizedFormat === 'yyyy') {
77836
+ const num = Number(value);
77837
+ return (/^\d{4}$/u).test(value) && num >= 1 && num <= 9999;
77838
+ }
77839
+
77840
+ const dateFnsMask = this.toDateFnsMask(normalizedFormat);
77841
+ // Use the 1st of the current month as the reference so that formats
77842
+ // omitting a day (e.g. MM/yyyy) never roll over on days 29–31.
77843
+ const referenceDate = new Date();
77844
+ referenceDate.setDate(1);
77845
+ const parsed = parse(value, dateFnsMask, referenceDate);
77846
+ return isValid(parsed) && format(parsed, dateFnsMask) === value;
77847
+ }
77848
+
77783
77849
  /**
77784
77850
  * Converts a display string to its model value.
77785
77851
  * For full date formats, converts the display string to an ISO date string.
@@ -77827,6 +77893,7 @@ class AuroInputUtilities {
77827
77893
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
77828
77894
 
77829
77895
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
77896
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
77830
77897
  return undefined;
77831
77898
  }
77832
77899
 
@@ -77984,6 +78051,7 @@ class BaseInput extends AuroElement$1$1 {
77984
78051
  // so a parent (datepicker/combobox) calling `validate()` synchronously
77985
78052
  // during its own update cycle sees a populated util instance.
77986
78053
  this.activeLabel = false;
78054
+
77987
78055
  /** @private */
77988
78056
  this.allowedInputTypes = [
77989
78057
  "text",
@@ -77994,6 +78062,7 @@ class BaseInput extends AuroElement$1$1 {
77994
78062
  "tel"
77995
78063
  ];
77996
78064
  this.appearance = "default";
78065
+
77997
78066
  /** @private */
77998
78067
  this.dateFormatMap = {
77999
78068
  'mm/dd/yyyy': 'dateMMDDYYYY',
@@ -78012,23 +78081,24 @@ class BaseInput extends AuroElement$1$1 {
78012
78081
  'mm/dd': 'dateMMDD'
78013
78082
  };
78014
78083
  this.disabled = false;
78084
+
78015
78085
  /** @private */
78016
78086
  this.domHandler = new DomHandler();
78017
78087
  this.dvInputOnly = false;
78018
78088
  this.hasValue = false;
78019
78089
  this.hideLabelVisually = false;
78020
78090
  this.icon = false;
78091
+
78021
78092
  /** @private */
78022
78093
  this.inputIconName = undefined;
78094
+
78023
78095
  /** @private */
78024
78096
  this.label = 'Input label is undefined';
78025
78097
  this.layout = 'classic';
78026
78098
  this.locale = 'en-US';
78027
78099
  this.max = undefined;
78028
- this._maxObject = undefined;
78029
78100
  this.maxLength = undefined;
78030
78101
  this.min = undefined;
78031
- this._minObject = undefined;
78032
78102
  this.minLength = undefined;
78033
78103
  this.noValidate = false;
78034
78104
  this.onDark = false;
@@ -78045,23 +78115,27 @@ class BaseInput extends AuroElement$1$1 {
78045
78115
  "email"
78046
78116
  ];
78047
78117
  this.shape = 'classic';
78118
+
78048
78119
  /** @private */
78049
78120
  this.showPassword = false;
78050
78121
  this.size = 'lg';
78051
78122
  this.touched = false;
78123
+
78052
78124
  /** @private */
78053
78125
  this.uniqueId = new UniqueId().create();
78126
+
78054
78127
  /** @private */
78055
78128
  this.util = new AuroInputUtilities({
78056
78129
  locale: this.locale,
78057
78130
  format: this.format
78058
78131
  });
78132
+
78059
78133
  /** @private */
78060
78134
  this.validation = new AuroFormValidation$2();
78135
+
78061
78136
  /** @private */
78062
78137
  this.validationCCLength = undefined;
78063
78138
  this.value = undefined;
78064
- this._valueObject = undefined;
78065
78139
  }
78066
78140
 
78067
78141
  // function to define props used within the scope of this component
@@ -78391,6 +78465,13 @@ class BaseInput extends AuroElement$1$1 {
78391
78465
  type: String
78392
78466
  },
78393
78467
 
78468
+ /**
78469
+ * Custom help text message to display when validity = `patternMismatch`.
78470
+ */
78471
+ setCustomValidityPatternMismatch: {
78472
+ type: String
78473
+ },
78474
+
78394
78475
  /**
78395
78476
  * Custom help text message to display when validity = `rangeOverflow`.
78396
78477
  */
@@ -78461,7 +78542,7 @@ class BaseInput extends AuroElement$1$1 {
78461
78542
 
78462
78543
  /**
78463
78544
  * Populates the `type` attribute on the input.
78464
- * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number'}
78545
+ * @type {'text' | 'password' | 'email' | 'credit-card' | 'tel' | 'number' | 'date'}
78465
78546
  * @default 'text'
78466
78547
  */
78467
78548
  type: {
@@ -78499,7 +78580,7 @@ class BaseInput extends AuroElement$1$1 {
78499
78580
  * @returns {Date|undefined}
78500
78581
  */
78501
78582
  get valueObject() {
78502
- return this._valueObject || this._computeDateObjectFallback(this.value);
78583
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
78503
78584
  }
78504
78585
 
78505
78586
  /**
@@ -78507,7 +78588,7 @@ class BaseInput extends AuroElement$1$1 {
78507
78588
  * @returns {Date|undefined}
78508
78589
  */
78509
78590
  get minObject() {
78510
- return this._minObject || this._computeDateObjectFallback(this.min);
78591
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
78511
78592
  }
78512
78593
 
78513
78594
  /**
@@ -78515,50 +78596,7 @@ class BaseInput extends AuroElement$1$1 {
78515
78596
  * @returns {Date|undefined}
78516
78597
  */
78517
78598
  get maxObject() {
78518
- return this._maxObject || this._computeDateObjectFallback(this.max);
78519
- }
78520
-
78521
- /**
78522
- * Parses a date string into a Date object when the corresponding `_*Object`
78523
- * field hasn't been synced yet by `updated()`. Returns undefined when the
78524
- * input type/format isn't a full date or the string is not a valid date.
78525
- *
78526
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
78527
- * inside its own `updated()` before this input's `updated()` has run
78528
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
78529
- * and range checks would otherwise silently no-op (flipping the result to
78530
- * `valid` or `patternMismatch`).
78531
- * @private
78532
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
78533
- * @returns {Date|undefined}
78534
- */
78535
- _computeDateObjectFallback(dateStr) {
78536
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
78537
- return undefined;
78538
- }
78539
- if (!dateFormatter.isValidDate(dateStr)) {
78540
- return undefined;
78541
- }
78542
- return dateFormatter.stringToDateInstance(dateStr);
78543
- }
78544
-
78545
- /**
78546
- * Internal setter for readonly date object properties.
78547
- * @private
78548
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
78549
- * @param {Date|undefined} propertyValue - Value to assign.
78550
- * @returns {void}
78551
- */
78552
- setDateObjectProperty(propertyName, propertyValue) {
78553
- const internalPropertyName = `_${propertyName}`;
78554
- const previousValue = this[internalPropertyName];
78555
-
78556
- if (previousValue === propertyValue) {
78557
- return;
78558
- }
78559
-
78560
- this[internalPropertyName] = propertyValue;
78561
- this.requestUpdate(propertyName, previousValue);
78599
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
78562
78600
  }
78563
78601
 
78564
78602
  connectedCallback() {
@@ -78587,7 +78625,6 @@ class BaseInput extends AuroElement$1$1 {
78587
78625
  format: this.format
78588
78626
  });
78589
78627
  this.configureDataForType();
78590
- this.syncDateValues();
78591
78628
  }
78592
78629
 
78593
78630
  disconnectedCallback() {
@@ -78626,7 +78663,6 @@ class BaseInput extends AuroElement$1$1 {
78626
78663
  this.setCustomHelpTextMessage();
78627
78664
  this.configureAutoFormatting();
78628
78665
  this.configureDataForType();
78629
- this.syncDateValues();
78630
78666
  }
78631
78667
 
78632
78668
  /**
@@ -78770,8 +78806,6 @@ class BaseInput extends AuroElement$1$1 {
78770
78806
  this.configureDataForType();
78771
78807
  }
78772
78808
 
78773
- this.syncDateValues(changedProperties);
78774
-
78775
78809
  if (changedProperties.has('value')) {
78776
78810
  if (this.value && this.value.length > 0) {
78777
78811
  this.hasValue = true;
@@ -78793,14 +78827,14 @@ class BaseInput extends AuroElement$1$1 {
78793
78827
 
78794
78828
  if (formattedValue !== this.inputElement.value) {
78795
78829
  this.skipNextProgrammaticInputEvent = true;
78796
- if (this.maskInstance && this.type === 'credit-card') {
78830
+ if (this.maskInstance && this.type !== 'date') {
78797
78831
  // Route through the mask so its _value and el.value stay in lock-step
78798
78832
  // (set value calls updateControl which writes el.value = displayValue).
78799
78833
  // Writing el.value directly leaves the mask thinking displayValue is
78800
- // stale; _saveSelection on the next focus/click then warns. Scoped to
78801
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
78802
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
78803
- // and flip validity from patternMismatch to tooShort.
78834
+ // stale; _saveSelection on the next focus/click then warns. Date is
78835
+ // excluded because its formattedValue can be raw ISO when the calendar
78836
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
78837
+ // flip validity from patternMismatch to tooShort.
78804
78838
  this.maskInstance.value = formattedValue || '';
78805
78839
  } else if (formattedValue) {
78806
78840
  this.inputElement.value = formattedValue;
@@ -78842,120 +78876,65 @@ class BaseInput extends AuroElement$1$1 {
78842
78876
  }));
78843
78877
  }
78844
78878
 
78845
-
78846
- /**
78847
- * Synchronizes the ISO string values and Date object representations for date-related properties.
78848
- * This keeps the model and display values aligned when either side changes.
78849
- *
78850
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
78851
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
78852
- * represents a full year/month/day date format.
78853
- *
78854
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
78855
- * @returns {void}
78856
- * @private
78857
- */
78858
- syncDateValues(changedProperties = undefined) {
78859
- if (!this.util.isFullDateFormat(this.type, this.format)) {
78860
- return;
78861
- }
78862
-
78863
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
78864
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
78865
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
78866
- }
78867
-
78868
- /**
78869
- * Synchronizes one date object/string property pair.
78870
- * @private
78871
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
78872
- * @param {string} objectProperty - Date object property name.
78873
- * @param {string} valueProperty - ISO string property name.
78874
- * @returns {void}
78875
- */
78876
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
78877
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
78878
-
78879
- // objectProperty wins over valueProperty when both changed
78880
- if (objectPropertyChanged && this[objectProperty]) {
78881
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
78882
- return;
78883
- }
78884
-
78885
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
78886
- if (!valuePropertyChanged) {
78887
- return;
78888
- }
78889
-
78890
- // 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)
78891
- if (
78892
- changedProperties &&
78893
- valueProperty === 'value' &&
78894
- changedProperties.get('value') === undefined &&
78895
- this[objectProperty] instanceof Date &&
78896
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
78897
- ) {
78898
- return;
78899
- }
78900
-
78901
- if (dateFormatter.isValidDate(this[valueProperty])) {
78902
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
78903
- } else {
78904
- this.setDateObjectProperty(objectProperty, undefined);
78905
- }
78906
- }
78907
-
78908
78879
  /**
78909
78880
  * Sets up IMasks and logic based on auto-formatting requirements.
78910
78881
  * @private
78911
78882
  * @returns {void}
78912
78883
  */
78913
78884
  configureAutoFormatting() {
78914
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
78915
- // by _configuringMask above) could otherwise trigger handleInput
78916
- // processCreditCard configureAutoFormatting before the outer call's
78917
- // set value has finished its alignCursor pass.
78885
+ // _configuringMask gates two things: external re-entry into this method
78886
+ // while setup is mid-flight (from property changes that call back here),
78887
+ // and the accept/complete listeners below — both need to ignore the mask
78888
+ // events fired by our own value-restore step.
78918
78889
  if (this._configuringMask) return;
78919
78890
  this._configuringMask = true;
78920
78891
  try {
78892
+ // Destroy any prior mask so IMask can attach fresh under the new format.
78893
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
78894
+ // type switched from credit-card to text) the IMask() reassignment
78895
+ // below is skipped, and downstream writes at line ~823 would otherwise
78896
+ // route through the destroyed instance.
78921
78897
  if (this.maskInstance) {
78922
78898
  this.maskInstance.destroy();
78899
+ this.maskInstance = null;
78923
78900
  }
78924
78901
 
78925
- // Pass new format to util
78926
78902
  this.util.updateFormat(this.format);
78927
78903
 
78928
78904
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
78929
78905
 
78930
78906
  if (this.inputElement && maskOptions.mask) {
78931
-
78932
- // Stash and clear any existing value before IMask init.
78933
- // IMask's constructor processes the current input value which requires
78934
- // selection state clearing first avoids that scenario entirely.
78935
- // When the format changes (e.g. locale switch) and we have a valid ISO
78936
- // model value, compute the display string for the NEW format instead of
78937
- // re-using the old display string, which may be invalid in the new mask.
78907
+ // Capture the current display so it can be re-applied after IMask
78908
+ // attaches. The restore at the bottom goes through maskInstance.value
78909
+ // (not inputElement.value directly) so the mask's internal state and
78910
+ // the input's displayed text stay in lock-step.
78938
78911
  let existingValue = this.inputElement.value;
78912
+
78913
+ // Format-change case (e.g. locale switch): existingValue is the OLD
78914
+ // mask's display string and may not parse under the new mask. When
78915
+ // we have a valid date model, rebuild the display from valueObject
78916
+ // (the canonical source) using the new mask's format function.
78939
78917
  if (
78940
78918
  this.util.isFullDateFormat(this.type, this.format) &&
78941
78919
  this.value &&
78942
- dateFormatter.isValidDate(this.value) &&
78943
- this.valueObject instanceof Date &&
78944
- !Number.isNaN(this.valueObject.getTime()) &&
78920
+ this.valueObject &&
78945
78921
  typeof maskOptions.format === 'function'
78946
78922
  ) {
78947
78923
  existingValue = maskOptions.format(this.valueObject);
78948
78924
  }
78949
78925
 
78926
+ // Clear before IMask attaches so the constructor seeds an empty
78927
+ // internal value. Otherwise IMask reads the stale unmasked string
78928
+ // and emits a spurious 'accept' before the restore below runs.
78950
78929
  this.skipNextProgrammaticInputEvent = true;
78951
78930
  this.inputElement.value = '';
78952
78931
 
78953
78932
  this.maskInstance = IMask(this.inputElement, maskOptions);
78954
78933
 
78934
+ // Mask fires 'accept' on every value change, including the restore
78935
+ // step below. Skip events fired during configureAutoFormatting so
78936
+ // we don't overwrite a value the parent just pushed.
78955
78937
  this.maskInstance.on('accept', () => {
78956
- // Suppress propagation during configureAutoFormatting's own value-restoration
78957
- // (line below) — the mask emits 'accept' on every value-set, including ours,
78958
- // and we don't want to overwrite a value the parent just pushed.
78959
78938
  if (this._configuringMask) return;
78960
78939
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
78961
78940
  if (this.type === "date") {
@@ -78963,6 +78942,8 @@ class BaseInput extends AuroElement$1$1 {
78963
78942
  }
78964
78943
  });
78965
78944
 
78945
+ // Mask fires 'complete' on the restore step below for any value that
78946
+ // happens to be a complete match. Same setup-suppression as 'accept'.
78966
78947
  this.maskInstance.on('complete', () => {
78967
78948
  if (this._configuringMask) return;
78968
78949
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -78971,7 +78952,9 @@ class BaseInput extends AuroElement$1$1 {
78971
78952
  }
78972
78953
  });
78973
78954
 
78974
- // Restore the stashed value through IMask so it's properly masked
78955
+ // Write existingValue through the mask (not the input directly) so
78956
+ // the mask reformats it under the new rules and keeps its internal
78957
+ // _value aligned with the input's displayed text.
78975
78958
  if (existingValue) {
78976
78959
  this.maskInstance.value = existingValue;
78977
78960
  }
@@ -79065,9 +79048,9 @@ class BaseInput extends AuroElement$1$1 {
79065
79048
  // the gated types currently support it, since the list is a public
79066
79049
  // property a consumer could mutate.
79067
79050
  if (this.setSelectionInputTypes.includes(this.type)) {
79068
- let selectionStart;
79051
+ let selectionStart = null;
79069
79052
  try {
79070
- selectionStart = this.inputElement.selectionStart;
79053
+ ({ selectionStart } = this.inputElement);
79071
79054
  } catch (error) { // eslint-disable-line no-unused-vars
79072
79055
  return;
79073
79056
  }
@@ -79171,7 +79154,6 @@ class BaseInput extends AuroElement$1$1 {
79171
79154
  */
79172
79155
  reset() {
79173
79156
  this.value = undefined;
79174
- this.setDateObjectProperty('valueObject', undefined);
79175
79157
  this.validation.reset(this);
79176
79158
  }
79177
79159
 
@@ -79180,7 +79162,6 @@ class BaseInput extends AuroElement$1$1 {
79180
79162
  */
79181
79163
  clear() {
79182
79164
  this.value = undefined;
79183
- this.setDateObjectProperty('valueObject', undefined);
79184
79165
  }
79185
79166
 
79186
79167
  /**
@@ -79709,7 +79690,7 @@ let AuroHelpText$1$1 = class AuroHelpText extends i$2 {
79709
79690
  }
79710
79691
  };
79711
79692
 
79712
- var formkitVersion$1$1 = '202606292156';
79693
+ var formkitVersion$1$1 = '202607011722';
79713
79694
 
79714
79695
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
79715
79696
  // See LICENSE in the project root for license information.
@@ -80835,7 +80816,7 @@ let AuroBibtemplate$1 = class AuroBibtemplate extends i$2 {
80835
80816
  }
80836
80817
  };
80837
80818
 
80838
- var formkitVersion$3 = '202606292156';
80819
+ var formkitVersion$3 = '202607011722';
80839
80820
 
80840
80821
  var styleCss$1$3 = i$4`.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}`;
80841
80822
 
@@ -81203,12 +81184,23 @@ function getOptionLabel(option) {
81203
81184
  if (!option) {
81204
81185
  return '';
81205
81186
  }
81206
- const clone = option.cloneNode(true);
81207
- const displayValueEl = clone.querySelector('[slot="displayValue"]');
81208
- if (displayValueEl) {
81209
- displayValueEl.remove();
81187
+
81188
+ // Consumer-provided override: short-circuit the DOM walk entirely.
81189
+ if (option.dataset && option.dataset.label) {
81190
+ return option.dataset.label;
81191
+ }
81192
+
81193
+ // Walk direct children — the `slot` attribute only applies to direct children
81194
+ // of the slot host, so a shallow filter is sufficient. Avoids the cloneNode +
81195
+ // querySelector allocation that ran on every keystroke via syncValuesAndStates.
81196
+ let text = '';
81197
+ for (const node of option.childNodes) {
81198
+ const isDisplayValueSlot = node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'displayValue';
81199
+ if (!isDisplayValueSlot) {
81200
+ text += node.textContent || '';
81201
+ }
81210
81202
  }
81211
- return (clone.textContent || '').replace(/\s+/gu, ' ').trim();
81203
+ return text.replace(/\s+/gu, ' ').trim();
81212
81204
  }
81213
81205
 
81214
81206
  // See https://git.io/JJ6SJ for "How to document your components using JSDoc"
@@ -81283,8 +81275,6 @@ class AuroCombobox extends AuroElement$3 {
81283
81275
  this.availableOptions = [];
81284
81276
  this.dropdownId = undefined;
81285
81277
  this.dropdownOpen = false;
81286
- this.triggerExpandedState = false;
81287
- this._expandedTimeout = null;
81288
81278
  this._inFullscreenTransition = false;
81289
81279
  this.errorMessage = null;
81290
81280
  this.isHiddenWhileLoading = false;
@@ -81295,6 +81285,30 @@ class AuroCombobox extends AuroElement$3 {
81295
81285
  this.touched = false;
81296
81286
  this.validation = new AuroFormValidation$1();
81297
81287
  this.validity = undefined;
81288
+ this._userTyped = false;
81289
+ // Tracks every setTimeout scheduled via _scheduleTimer so
81290
+ // disconnectedCallback can cancel them. Without this, a detached
81291
+ // combobox's pending timers still fire — most are no-ops, but
81292
+ // configureMenu's racing-condition retry would otherwise loop.
81293
+ this._pendingTimers = new Set();
81294
+ }
81295
+
81296
+ /**
81297
+ * setTimeout wrapper that records the timer id so disconnectedCallback
81298
+ * can cancel any outstanding callbacks. The id is removed from the set
81299
+ * once the callback fires so the set doesn't grow unbounded.
81300
+ * @param {Function} fn - Callback to run.
81301
+ * @param {number} ms - Delay in milliseconds.
81302
+ * @returns {number} The timer id.
81303
+ * @private
81304
+ */
81305
+ _scheduleTimer(fn, ms) {
81306
+ const id = setTimeout(() => {
81307
+ this._pendingTimers.delete(id);
81308
+ fn();
81309
+ }, ms);
81310
+ this._pendingTimers.add(id);
81311
+ return id;
81298
81312
  }
81299
81313
 
81300
81314
  // This function is to define props used within the scope of this component
@@ -81656,17 +81670,6 @@ class AuroCombobox extends AuroElement$3 {
81656
81670
  attribute: false
81657
81671
  },
81658
81672
 
81659
- /**
81660
- * Deferred aria-expanded state for the trigger input.
81661
- * Delays the "true" transition so VoiceOver finishes its character echo
81662
- * before announcing "expanded".
81663
- * @private
81664
- */
81665
- triggerExpandedState: {
81666
- type: Boolean,
81667
- reflect: false,
81668
- attribute: false
81669
- },
81670
81673
  };
81671
81674
  }
81672
81675
 
@@ -81689,13 +81692,6 @@ class AuroCombobox extends AuroElement$3 {
81689
81692
  return this.input.value;
81690
81693
  }
81691
81694
 
81692
- // /**
81693
- // * Sets the value of the input element within the combobox.
81694
- // */
81695
- // set inputValue(value) {
81696
- // this.input.value = value;
81697
- // }
81698
-
81699
81695
  /**
81700
81696
  * Checks if the element is valid.
81701
81697
  * @returns {boolean} - Returns true if the element is valid, false otherwise.
@@ -81822,7 +81818,7 @@ class AuroCombobox extends AuroElement$3 {
81822
81818
  if (this.menu) {
81823
81819
  this.menu.matchWord = normalizeFilterValue(this.input.value);
81824
81820
  }
81825
- const label = getOptionLabel(this.menu.optionSelected) || this.menu.currentLabel;
81821
+ const label = getOptionLabel(this.menu.optionSelected);
81826
81822
  this.updateTriggerTextDisplay(label || this.value);
81827
81823
  }
81828
81824
 
@@ -81836,44 +81832,16 @@ class AuroCombobox extends AuroElement$3 {
81836
81832
  // in suggestion mode, do not override input value if no selection has been made and the input currently has focus
81837
81833
  const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
81838
81834
 
81839
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
81840
- const nextValue = label || this.value;
81841
- // Only set the flag when there's an actual write to suppress —
81842
- // syncValuesAndStates re-enters here during typing when both inputs
81843
- // already match, and a no-op flag flip would make the bib branch's
81844
- // bail eat legitimate user-input events.
81845
- const triggerNeedsSync = this.input.value !== nextValue;
81846
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
81847
- if (triggerNeedsSync || bibNeedsSync) {
81848
- this._syncingDisplayValue = true;
81849
- if (triggerNeedsSync) {
81850
- this.input.value = nextValue;
81851
- }
81852
- if (bibNeedsSync) {
81853
- this.inputInBib.value = nextValue;
81854
- }
81855
- const pending = [];
81856
- if (triggerNeedsSync) {
81857
- pending.push(this.input.updateComplete);
81858
- }
81859
- if (bibNeedsSync) {
81860
- pending.push(this.inputInBib.updateComplete);
81861
- }
81862
- Promise.all(pending).then(() => {
81863
- // imask reasserts otherwise, and handleBlur reverts to its stale value.
81864
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
81865
- this.input.maskInstance.updateValue();
81866
- }
81867
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
81868
- this.inputInBib.maskInstance.updateValue();
81869
- }
81870
- this._syncingDisplayValue = false;
81871
- });
81872
- }
81835
+ const suppressed = this.persistInput || (this.behavior === 'suggestion' && isInputFocusedWithNoSelection);
81836
+ if (!suppressed) {
81837
+ this.syncInputValuesAcrossTriggerAndBib(label || this.value);
81873
81838
  }
81874
81839
 
81875
- // update the displayValue in the trigger if displayValue slot content is present
81876
- const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]');
81840
+ // Replace any previously appended displayValue clone in the trigger.
81841
+ // :not(slot) excludes the template's <slot name="displayValue"
81842
+ // slot="displayValue"> forwarder, which also has slot="displayValue"
81843
+ // and would otherwise be matched first and removed.
81844
+ const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]:not(slot)');
81877
81845
 
81878
81846
  if (displayValueInTrigger) {
81879
81847
  displayValueInTrigger.remove();
@@ -81897,6 +81865,53 @@ class AuroCombobox extends AuroElement$3 {
81897
81865
  this.requestUpdate();
81898
81866
  }
81899
81867
 
81868
+ /**
81869
+ * Writes nextValue to the trigger input and the bib input when their current
81870
+ * value differs, then re-asserts imask after Lit's update flushes.
81871
+ * @param {string} nextValue - The value to write to both inputs.
81872
+ * @returns {Promise<void>} Resolves after both inputs flush and imask
81873
+ * re-asserts; resolves immediately when no sync is needed.
81874
+ * @private
81875
+ */
81876
+ async syncInputValuesAcrossTriggerAndBib(nextValue) {
81877
+ // Only set the flag when there's an actual write to suppress —
81878
+ // syncValuesAndStates re-enters here during typing when both inputs
81879
+ // already match, and a no-op flag flip would make the bib branch's
81880
+ // bail eat legitimate user-input events.
81881
+ const triggerNeedsSync = this.input.value !== nextValue;
81882
+ const bibNeedsSync = Boolean(this.inputInBib) && this.inputInBib.value !== nextValue;
81883
+ if (!triggerNeedsSync && !bibNeedsSync) {
81884
+ return;
81885
+ }
81886
+
81887
+ this._syncingDisplayValue = true;
81888
+
81889
+ const pending = [];
81890
+ if (triggerNeedsSync) {
81891
+ this.input.value = nextValue;
81892
+ pending.push(this.input.updateComplete);
81893
+ }
81894
+ if (bibNeedsSync) {
81895
+ this.inputInBib.value = nextValue;
81896
+ pending.push(this.inputInBib.updateComplete);
81897
+ }
81898
+ // finally — not a bare .then — so that an imask throw (see commit
81899
+ // d1857401c: imask can throw on credit-card format change) doesn't strand
81900
+ // _syncingDisplayValue=true and silently swallow every subsequent input.
81901
+ try {
81902
+ await Promise.all(pending);
81903
+ // imask reasserts otherwise, and handleBlur reverts to its stale value.
81904
+ if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
81905
+ this.input.maskInstance.updateValue();
81906
+ }
81907
+ if (bibNeedsSync && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
81908
+ this.inputInBib.maskInstance.updateValue();
81909
+ }
81910
+ } finally {
81911
+ this._syncingDisplayValue = false;
81912
+ }
81913
+ }
81914
+
81900
81915
  /**
81901
81916
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
81902
81917
  * @private
@@ -81905,6 +81920,13 @@ class AuroCombobox extends AuroElement$3 {
81905
81920
  handleMenuOptions() {
81906
81921
  this.generateOptionsArray();
81907
81922
  this.availableOptions = [];
81923
+ // Single source of truth for the menu's filter/highlight token per call.
81924
+ // syncValuesAndStates re-writes the same value on exact-match keystrokes —
81925
+ // Lit's hasChanged makes that a no-op — and the prior duplicate set inside
81926
+ // handleTriggerInputValueChange is gone.
81927
+ if (this.menu) {
81928
+ this.menu.matchWord = normalizeFilterValue(this.input.value);
81929
+ }
81908
81930
  this.updateFilter();
81909
81931
 
81910
81932
  // Set aria-setsize/aria-posinset on each visible option so screen readers
@@ -81916,17 +81938,14 @@ class AuroCombobox extends AuroElement$3 {
81916
81938
  option.setAttribute('aria-posinset', index + 1);
81917
81939
  });
81918
81940
 
81919
- if (this.value && this.input.value && !this.menu.value) {
81920
- if (this.behavior === 'suggestion' && this.menu.options && this.menu.options.some((opt) => opt.value === this.value)) {
81921
- this.setMenuValue(this.value);
81922
- }
81923
-
81941
+ if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
81942
+ this.setMenuValue(this.input.value);
81924
81943
  this.syncValuesAndStates();
81925
81944
  }
81926
81945
 
81927
- // Re-activate when optionActive is no longer visible, or when _index has
81928
- // been reset (e.g. by clearSelection in an async update) so that
81929
- // makeSelection() can find the correct option.
81946
+ // Re-activate when optionActive is not in the current scrollable viewport,
81947
+ // or when _index has been reset (e.g. by clearSelection in an async update)
81948
+ // so that makeSelection() can find the correct option.
81930
81949
  if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
81931
81950
  this.activateFirstEnabledAvailableOption();
81932
81951
  }
@@ -81999,18 +82018,6 @@ class AuroCombobox extends AuroElement$3 {
81999
82018
  this.dropdownOpen = ev.detail.expanded;
82000
82019
  this.updateMenuShapeSize();
82001
82020
 
82002
- // Defer aria-expanded "true" so VoiceOver finishes character echo
82003
- // before announcing "expanded". Set "false" immediately on close.
82004
- clearTimeout(this._expandedTimeout);
82005
- if (this.dropdownOpen) {
82006
- const expandedDelay = 150;
82007
- this._expandedTimeout = setTimeout(() => {
82008
- this.triggerExpandedState = true;
82009
- }, expandedDelay);
82010
- } else {
82011
- this.triggerExpandedState = false;
82012
- }
82013
-
82014
82021
  // Clear aria-activedescendant when dropdown closes
82015
82022
  if (!this.dropdownOpen && this.input) {
82016
82023
  this.input.setActiveDescendant(null);
@@ -82060,28 +82067,25 @@ class AuroCombobox extends AuroElement$3 {
82060
82067
 
82061
82068
  guardTouchPassthrough$1(this.menu);
82062
82069
 
82063
- // The dialog's showModal() steals focus from the trigger.
82064
- // A single rAF is enough for the dialog DOM to be painted and
82065
- // focusable, then doubleRaf finalizes the transition.
82070
+ // showModal() takes focus away from the trigger. Early focus once
82071
+ // the dialog has painted; the shared doubleRaf below is the fallback
82072
+ // for when the dialog needs an extra frame and also clears the
82073
+ // validation guard.
82066
82074
  requestAnimationFrame(() => {
82067
82075
  this.setInputFocus();
82068
82076
  });
82069
-
82070
- doubleRaf$1(() => {
82071
- this.setInputFocus();
82072
- this._inFullscreenTransition = false;
82073
- });
82074
- } else {
82075
- // Desktop popover-open: restore the trigger caret to end-of-text.
82076
- // Clicking the trigger lands on auro-input's floating <label for="…">
82077
- // overlay; Chrome resets the native input's selection to [0, 0] on
82078
- // label-focus before any JS runs. setInputFocus()'s non-fullscreen
82079
- // branch parks the caret at end. doubleRaf lets the dropdown layout
82080
- // settle first, matching the fullscreen branch timing.
82081
- doubleRaf$1(() => {
82082
- this.setInputFocus();
82083
- });
82084
82077
  }
82078
+ // else (desktop popover-open): Chrome resets the trigger caret to
82079
+ // [0, 0] when its floating <label for="…"> overlay receives focus.
82080
+ // The shared doubleRaf below parks the caret back at end-of-text
82081
+ // after the dropdown layout settles.
82082
+
82083
+ doubleRaf$1(() => {
82084
+ this.setInputFocus();
82085
+ if (this._inFullscreenTransition) {
82086
+ this._inFullscreenTransition = false;
82087
+ }
82088
+ });
82085
82089
  }
82086
82090
  });
82087
82091
 
@@ -82118,7 +82122,7 @@ class AuroCombobox extends AuroElement$3 {
82118
82122
  this.dropdown.trigger.inert = false;
82119
82123
  }
82120
82124
 
82121
- setTimeout(() => {
82125
+ this._scheduleTimer(() => {
82122
82126
  this.setInputFocus();
82123
82127
  }, 0);
82124
82128
  });
@@ -82262,7 +82266,7 @@ class AuroCombobox extends AuroElement$3 {
82262
82266
 
82263
82267
  // racing condition on custom-combobox with custom-menu
82264
82268
  if (!this.menu) {
82265
- setTimeout(() => {
82269
+ this._scheduleTimer(() => {
82266
82270
  this.configureMenu();
82267
82271
  }, 0);
82268
82272
  return;
@@ -82292,7 +82296,7 @@ class AuroCombobox extends AuroElement$3 {
82292
82296
  if (this.menu.optionSelected) {
82293
82297
  const selected = this.menu.optionSelected;
82294
82298
 
82295
- if (!this.optionSelected || this.optionSelected !== selected) {
82299
+ if (this.optionSelected !== selected) {
82296
82300
  this.optionSelected = selected;
82297
82301
  }
82298
82302
 
@@ -82305,7 +82309,7 @@ class AuroCombobox extends AuroElement$3 {
82305
82309
  }
82306
82310
 
82307
82311
  // Update display
82308
- this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected) || this.menu.value);
82312
+ this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected));
82309
82313
 
82310
82314
  // Update match word for filtering
82311
82315
  const trimmedInput = normalizeFilterValue(this.input.value);
@@ -82317,17 +82321,24 @@ class AuroCombobox extends AuroElement$3 {
82317
82321
  // Hide dropdown on selection (except during slot changes)
82318
82322
  if (evt.detail && evt.detail.source !== 'slotchange') {
82319
82323
  // do not close while typing in suggestion mode with no value selected, to allow freeform input
82320
- if (this.menu.value || this.behavior !== 'suggestion') {
82321
- this.hideBib();
82324
+ this.hideBib();
82325
+
82326
+ // Move focus to the clear button when the user makes a selection.
82327
+ if (!isEcho && this.menu.value !== undefined) {
82328
+ this.setClearBtnFocus();
82322
82329
  }
82323
82330
 
82324
82331
  // Announce the selection after the dropdown closes so it isn't
82325
82332
  // overridden by VoiceOver's "collapsed" announcement from aria-expanded.
82333
+ // Skip when there's no selected value (e.g. menu.clearSelection() from
82334
+ // the unmatched-value path), otherwise VoiceOver reads "undefined".
82326
82335
  const selectedValue = this.menu.value;
82327
- const announcementDelay = 300;
82328
- setTimeout(() => {
82329
- announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
82330
- }, announcementDelay);
82336
+ if (selectedValue) {
82337
+ const announcementDelay = 300;
82338
+ this._scheduleTimer(() => {
82339
+ announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
82340
+ }, announcementDelay);
82341
+ }
82331
82342
  }
82332
82343
 
82333
82344
  // Programmatic value syncs leave availableOptions stale because
@@ -82336,22 +82347,6 @@ class AuroCombobox extends AuroElement$3 {
82336
82347
  // only — fresh user selections take the existing hideBib path.
82337
82348
  if (isEcho && this.menu.optionSelected) {
82338
82349
  this._programmaticFilterRefresh = true;
82339
- this.handleMenuOptions();
82340
- setTimeout(() => {
82341
- this._programmaticFilterRefresh = false;
82342
- }, 0);
82343
- }
82344
-
82345
- // base-input skips auto-validate when focus is inside its own shadow,
82346
- // which it is after setTriggerInputFocus — re-run so prior tooShort
82347
- // clears. processCreditCard reasserts errorMessage on every render.
82348
- if (!isEcho && this.menu.optionSelected && this.input.validate) {
82349
- this.input.updateComplete.then(() => {
82350
- this.input.validate(true);
82351
- if (this.input.validity === 'valid') {
82352
- this.input.errorMessage = '';
82353
- }
82354
- });
82355
82350
  }
82356
82351
  });
82357
82352
 
@@ -82364,6 +82359,14 @@ class AuroCombobox extends AuroElement$3 {
82364
82359
  // stale option. Safe from re-entrancy because any resulting
82365
82360
  // input.value changes dispatch isProgrammatic events.
82366
82361
  this.menu.addEventListener('auroMenu-selectValueFailure', () => {
82362
+ // Announce the rejection BEFORE we clear `this.value` so the live
82363
+ // region carries the attempted value — without this the bib closes
82364
+ // silently and screen-reader users get no signal that their request
82365
+ // (e.g. a direct setMenuValue() call) was dropped.
82366
+ const attemptedValue = this.value;
82367
+ if (attemptedValue) {
82368
+ announceToScreenReader$1(this._getAnnouncementRoot(), `No matching option for ${attemptedValue}`);
82369
+ }
82367
82370
  this.value = undefined;
82368
82371
  this.optionSelected = undefined;
82369
82372
  });
@@ -82375,10 +82378,13 @@ class AuroCombobox extends AuroElement$3 {
82375
82378
  this.input.setActiveDescendant(this.optionActive);
82376
82379
  }
82377
82380
 
82378
- // Announce the active option for screen readers including position,
82379
- // since shadow DOM boundaries prevent native reading of
82380
- // aria-setsize/aria-posinset via aria-activedescendant.
82381
- if (this.optionActive) {
82381
+ // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
82382
+ // and aria-activedescendant references across that boundary are lost —
82383
+ // VoiceOver/NVDA don't read the active option natively, so we mirror it
82384
+ // into the polite live region. In popover mode aria-activedescendant on
82385
+ // the trigger input is read natively; double-announcing would flood the
82386
+ // queue on arrow-key repeat.
82387
+ if (this.optionActive && this.dropdown.isBibFullscreen) {
82382
82388
  const optionText = this.optionActive.textContent.trim();
82383
82389
  const selectedState = this.optionActive.hasAttribute('selected') ? ', selected' : ', not selected';
82384
82390
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
@@ -82411,7 +82417,12 @@ class AuroCombobox extends AuroElement$3 {
82411
82417
  * Validate every time we remove focus from the combo box.
82412
82418
  */
82413
82419
  this.addEventListener('focusout', () => {
82414
- if (!this.componentHasFocus && !this._inFullscreenTransition) {
82420
+ // Skip while the dropdown is open — focus transits out briefly on
82421
+ // mousedown of a menu option (popover top-layer breaks :focus-within),
82422
+ // and validating against the pre-selection value flashes a stale error
82423
+ // between mousedown and mouseup. The next focusout fires after the
82424
+ // dropdown closes and validates against the post-selection value.
82425
+ if (!this.componentHasFocus && !this._inFullscreenTransition && !this.dropdownOpen) {
82415
82426
  this.validate();
82416
82427
  }
82417
82428
  });
@@ -82474,49 +82485,40 @@ class AuroCombobox extends AuroElement$3 {
82474
82485
  if (this._syncingDisplayValue) {
82475
82486
  return;
82476
82487
  }
82477
- this._syncingBibValue = true;
82478
- this.input.value = this.inputInBib.value;
82479
- this.input.updateComplete.then(() => {
82480
- this._syncingBibValue = false;
82481
- });
82482
-
82483
- // Run filtering inline — the re-entrant event won't reach this code.
82484
- this.menu.matchWord = normalizeFilterValue(this.inputInBib.value);
82485
- this.optionActive = null;
82486
82488
 
82487
- // In suggestion mode, keep the combobox value in sync with the typed
82488
- // text so that freeform values are captured (mirroring the non-fullscreen
82489
- // path). Clear the selection when the input is emptied.
82490
- if (this.behavior === 'suggestion') {
82491
- this.value = this.inputInBib.value || undefined;
82489
+ // Filtering runs via re-entrance: writing this.input.value below
82490
+ // dispatches an 'input' event that the trigger's listener routes to
82491
+ // handleTriggerInputValueChange, which refreshes the menu filter.
82492
+ if (this.input.value !== this.inputInBib.value) {
82493
+ this._syncingBibValue = true;
82494
+ this.input.value = this.inputInBib.value;
82495
+ this.input.updateComplete.then(() => {
82496
+ this._syncingBibValue = false;
82497
+ });
82492
82498
  }
82493
82499
 
82494
- this.handleMenuOptions();
82495
82500
  this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
82496
- return;
82501
+ } else if (event.target === this.input) {
82502
+
82503
+ // Also sync the native input immediately so keystrokes arriving
82504
+ // before Lit's async update cycle (e.g. rapid Backspaces during a
82505
+ // fullscreen transition) operate on the correct content.
82506
+ // Skip the next programmatic input event to prevent the patched setter
82507
+ // from re-entering handleInputValueChange via the bib path.
82508
+ const bibNativeInput = this.inputInBib.inputElement;
82509
+ if (bibNativeInput && bibNativeInput.value !== this.input.value) {
82510
+ this.inputInBib.skipNextProgrammaticInputEvent = true;
82511
+ bibNativeInput.value = this.input.value || '';
82512
+ }
82497
82513
  }
82498
82514
 
82515
+ this.value = this.input.value;
82516
+
82499
82517
  // Ignore re-entrant input events caused by programmatic value sets.
82500
82518
  if (this._syncingBibValue || this._syncingDisplayValue) {
82501
82519
  return;
82502
82520
  }
82503
82521
 
82504
- this.inputInBib.value = this.input.value;
82505
-
82506
- // Also sync the native input immediately so keystrokes arriving
82507
- // before Lit's async update cycle (e.g. rapid Backspaces during a
82508
- // fullscreen transition) operate on the correct content.
82509
- // Skip the next programmatic input event to prevent the patched setter
82510
- // from re-entering handleInputValueChange via the bib path.
82511
- const bibNativeInput = this.inputInBib.inputElement;
82512
- if (bibNativeInput && bibNativeInput.value !== this.input.value) {
82513
- this.inputInBib.skipNextProgrammaticInputEvent = true;
82514
- bibNativeInput.value = this.input.value || '';
82515
- }
82516
-
82517
- this.menu.matchWord = normalizeFilterValue(this.input.value);
82518
- this.optionActive = null;
82519
-
82520
82522
  if (this.behavior === 'suggestion') {
82521
82523
  this.value = this.input.value;
82522
82524
  }
@@ -82524,7 +82526,6 @@ class AuroCombobox extends AuroElement$3 {
82524
82526
  if (!this.input.value && !this._clearing) {
82525
82527
  this.clear();
82526
82528
  }
82527
- this.handleMenuOptions();
82528
82529
 
82529
82530
  // Validate only if the value was set programmatically (not during user
82530
82531
  // interaction). In fullscreen dialog mode, componentHasFocus returns false
@@ -82534,34 +82535,44 @@ class AuroCombobox extends AuroElement$3 {
82534
82535
  this.validate();
82535
82536
  }
82536
82537
 
82537
- if (this.input.value && this.input.value.length === 0) {
82538
- // Hide menu if value is empty, otherwise show if there are available suggestions
82539
- this.hideBib();
82540
- } else if (this.menu.loading) {
82541
- // if input has value but menu is loading, show bib immediately
82542
- this.showBib();
82543
- } else if (this.availableOptions.length === 0 && !this.dropdown.isBibFullscreen) {
82544
- // Force dropdown bib to hide if input value has no matching suggestions
82545
- this.hideBib();
82538
+ this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
82539
+ }
82540
+
82541
+ /**
82542
+ * Handles input value changes originating from the trigger input.
82543
+ * Refreshes menu options and filtering, delegates to handleInputValueChange
82544
+ * for value synchronization, and manages fullscreen bib focus.
82545
+ * @private
82546
+ * @param {Event} event - The input event from the trigger input element.
82547
+ * @returns {void}
82548
+ */
82549
+ handleTriggerInputValueChange(event) {
82550
+ // 'input' fires for every user-initiated value change — typing, paste,
82551
+ // IME composition end, dead-key composition, drag-drop. Flip _userTyped
82552
+ // here so updated('availableOptions') auto-opens the bib for sources
82553
+ // that keydown alone misses: paste fires no keydown, IME uses
82554
+ // key='Process', and dead keys produce multi-char keys (all bypass the
82555
+ // prior keydown.key.length===1 gate). Skip programmatic syncs.
82556
+ if (!this._syncingDisplayValue && !this._syncingBibValue && !this._programmaticFilterRefresh) {
82557
+ this._userTyped = true;
82546
82558
  }
82547
82559
 
82548
- // iOS virtual keyboard retention: when in fullscreen mode, ensure the
82549
- // dialog opens and the bib input is focused synchronously within the
82550
- // input event (user gesture) chain. Without this, Lit's async update
82551
- // cycle delays showModal() past the user activation window, causing
82552
- // iOS Safari to dismiss the virtual keyboard when the fullscreen
82553
- // dialog opens — the user then has to tap the input again to resume
82554
- // typing.
82555
- if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0) {
82556
- if (!this.dropdown.isPopoverVisible) {
82557
- this.showBib();
82558
- }
82559
- if (this.dropdown.isPopoverVisible) {
82560
- this.setInputFocus();
82561
- }
82560
+ this.handleMenuOptions();
82561
+ this.optionActive = null;
82562
+
82563
+ if (this.value === this.input.value) {
82564
+ return;
82562
82565
  }
82563
82566
 
82564
- this.dispatchEvent(new CustomEvent('inputValue', { detail: { value: this.inputValue } }));
82567
+ this.handleInputValueChange(event);
82568
+
82569
+ if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0 && this.dropdown.isPopoverVisible) {
82570
+ this.setInputFocus();
82571
+ }
82572
+
82573
+ if (this._programmaticFilterRefresh) {
82574
+ this._programmaticFilterRefresh = false;
82575
+ }
82565
82576
  }
82566
82577
 
82567
82578
  /**
@@ -82629,6 +82640,11 @@ class AuroCombobox extends AuroElement$3 {
82629
82640
  disconnectedCallback() {
82630
82641
  super.disconnectedCallback();
82631
82642
  this._inFullscreenTransition = false;
82643
+ // Cancel any outstanding timers so detached callbacks don't fire on
82644
+ // disposed DOM — most are no-ops, but configureMenu's racing-condition
82645
+ // retry would otherwise keep rescheduling itself indefinitely.
82646
+ this._pendingTimers.forEach((id) => clearTimeout(id));
82647
+ this._pendingTimers.clear();
82632
82648
  }
82633
82649
 
82634
82650
  firstUpdated() {
@@ -82670,7 +82686,7 @@ class AuroCombobox extends AuroElement$3 {
82670
82686
  this.menu.value = value;
82671
82687
  // Backup clear: if menu.value === menu.optionSelected.value already, the
82672
82688
  // listener won't fire and the flag would swallow the next user click.
82673
- setTimeout(() => {
82689
+ this._scheduleTimer(() => {
82674
82690
  this._pendingMenuValueSync = false;
82675
82691
  }, 0);
82676
82692
  }
@@ -82687,15 +82703,7 @@ class AuroCombobox extends AuroElement$3 {
82687
82703
  this.menu.value = undefined;
82688
82704
  this.validation.reset(this);
82689
82705
  this.touched = false;
82690
- // Force validity back to the cleared state. validation.reset() calls
82691
- // validate() at the end, and (post-credit-card-fix) the trigger input's
82692
- // residual validity may still be copied into the combobox by the
82693
- // auroInputElements loop. Explicitly clear here so reset() actually
82694
- // leaves the component in a "no validity" state.
82695
82706
  this.validity = undefined;
82696
- this.errorMessage = '';
82697
- this.input.validity = undefined;
82698
- this.input.errorMessage = '';
82699
82707
  }
82700
82708
 
82701
82709
  /**
@@ -82713,6 +82721,17 @@ class AuroCombobox extends AuroElement$3 {
82713
82721
  this.optionSelected = undefined;
82714
82722
  this.value = undefined;
82715
82723
 
82724
+ // Clear the appended displayValue clone in the trigger if present.
82725
+ // :not(slot) excludes the template's <slot name="displayValue"
82726
+ // slot="displayValue"> forwarder (line 1816), which also has
82727
+ // slot="displayValue" and would otherwise be matched first and removed,
82728
+ // permanently breaking the consumer-provided displayValue slot.
82729
+ const displayValueInTrigger = this.input.querySelector('[slot="displayValue"]:not(slot)');
82730
+
82731
+ if (displayValueInTrigger) {
82732
+ displayValueInTrigger.remove();
82733
+ }
82734
+
82716
82735
  if (this.input.value) {
82717
82736
  this.input.clear();
82718
82737
  }
@@ -82736,81 +82755,50 @@ class AuroCombobox extends AuroElement$3 {
82736
82755
  }
82737
82756
 
82738
82757
  updated(changedProperties) {
82739
- // After the component is ready, send direct value changes to auro-menu.
82758
+ // After the component is ready, propagate direct changes down to child components.
82740
82759
  if (changedProperties.has('value')) {
82741
- if (this.value && this.value.length > 0) {
82742
- this.hasValue = true;
82743
- } else {
82744
- this.hasValue = false;
82760
+ // Only flag programmatic refreshes — user-typed value changes must not
82761
+ // suppress the availableOptions branch's showBib(). Firefox batches
82762
+ // 'value' and 'availableOptions' into the same updated() call, so
82763
+ // setting the flag unconditionally here masks the user-typed open path.
82764
+ if (!this._userTyped) {
82765
+ this._programmaticFilterRefresh = true;
82745
82766
  }
82746
82767
 
82747
- if (this.hasValue && !this.input.value && (!this.menu.options || this.menu.options.length === 0)) {
82748
- this.input.value = this.value;
82749
- }
82768
+ if (this.input.value !== this.value) {
82769
+ // Clear menu.value AND menu.optionSelected together. Clearing only
82770
+ // menu.value leaves the previously-selected option element pinned
82771
+ // as menu.optionSelected; a later auroMenu-selectedOption event
82772
+ // would then write its stale .value back into combobox.value
82773
+ // (e.g. Tab-after-Backspace re-selecting the prior option).
82774
+ if (this.menu.value || this.menu.optionSelected) {
82775
+ this.menu.clearSelection();
82776
+ }
82750
82777
 
82751
- // Sync menu.value only when an option actually matches; otherwise clear it.
82752
- if (this.menu.options && this.menu.options.length > 0) {
82753
- if (this.menu.options.some((opt) => opt.value === this.value)) {
82754
- this.setMenuValue(this.value);
82755
- } else if (this.behavior === 'filter') {
82756
- // In filter mode, freeform values aren't allowed. Push the unmatched
82757
- // value through setMenuValue so menu dispatches auroMenu-selectValueFailure
82758
- // and the listener at line 1206 clears combobox.value (mirrors select's
82759
- // pattern). Bypassing setMenuValue here would skip the failure cascade.
82760
- this.setMenuValue(this.value);
82761
- } else {
82762
- if (this.menu.value) {
82763
- this.menu.value = undefined;
82764
- }
82765
- // Sync the display for programmatic freeform value changes (e.g. the
82766
- // swap-values pattern). Guard with _syncingDisplayValue so that the
82767
- // re-entrant input event from base-input.notifyValueChanged() is
82768
- // ignored by handleInputValueChange. Skip the sync when input already
82769
- // matches to avoid spurious events during the normal typing path.
82770
- const nextValue = this.value || '';
82771
- const triggerNeedsSync = this.input.value !== nextValue;
82772
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
82773
- if (triggerNeedsSync || bibNeedsSync) {
82774
- this._syncingDisplayValue = true;
82775
- if (triggerNeedsSync) {
82776
- this.input.value = nextValue;
82777
- }
82778
- if (bibNeedsSync) {
82779
- this.inputInBib.value = nextValue;
82780
- }
82781
- const pending = [];
82782
- if (triggerNeedsSync) {
82783
- pending.push(this.input.updateComplete);
82784
- }
82785
- if (bibNeedsSync) {
82786
- pending.push(this.inputInBib.updateComplete);
82787
- }
82788
- Promise.all(pending).then(() => {
82789
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
82790
- this.input.maskInstance.updateValue();
82791
- }
82792
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
82793
- this.inputInBib.maskInstance.updateValue();
82794
- }
82795
- this._syncingDisplayValue = false;
82796
- // handleInputValueChange bailed on the flag — refresh the filter.
82797
- this._programmaticFilterRefresh = true;
82798
- this.handleMenuOptions();
82799
- setTimeout(() => {
82800
- this._programmaticFilterRefresh = false;
82801
- }, 0);
82802
- });
82803
- }
82778
+ if (!this.persistInput) {
82779
+ this.syncInputValuesAcrossTriggerAndBib(this.value || '');
82780
+ }
82781
+
82782
+ // Programmatic value with no matching option: updateFilter will close
82783
+ // the bib silently (see line 648 no noMatchOption + 0 results
82784
+ // hides). Announce so screen-reader users hear the request was
82785
+ // dropped. Gated on `input.value !== this.value` so this never fires
82786
+ // for user typing that path always reconciles input.value to
82787
+ // this.value before updated() runs.
82788
+ if (
82789
+ this.value &&
82790
+ this.menu &&
82791
+ this.menu.options &&
82792
+ this.menu.options.length > 0 &&
82793
+ !this.menu.options.some((opt) => opt.value === this.value)
82794
+ ) {
82795
+ announceToScreenReader$1(this._getAnnouncementRoot(), `No matching option for ${this.value}`);
82804
82796
  }
82805
82797
  }
82798
+
82806
82799
  if (!this.value) {
82807
82800
  this.clear();
82808
82801
  }
82809
- if (this.value && !this.componentHasFocus) {
82810
- // If the value got set programmatically make sure we hide the bib
82811
- // when input is not taking the focus (input can be in dropdown.trigger or in bibtemplate)
82812
- this.hideBib();
82813
- }
82814
82802
 
82815
82803
  // Sync the input and match word, but don't directly set menu.value again
82816
82804
  if (this.menu) {
@@ -82823,7 +82811,7 @@ class AuroCombobox extends AuroElement$3 {
82823
82811
  composed: true,
82824
82812
  detail: {
82825
82813
  optionSelected: this.menu.optionSelected,
82826
- value: this.menu.value
82814
+ value: this.value
82827
82815
  }
82828
82816
  }));
82829
82817
 
@@ -82846,16 +82834,30 @@ class AuroCombobox extends AuroElement$3 {
82846
82834
  // from a programmatic filter refresh after a value swap — the user
82847
82835
  // didn't interact, so we shouldn't auto-open the bib (especially for
82848
82836
  // the no-match path where the existing condition unconditionally fires).
82849
- if (this._programmaticFilterRefresh) {
82850
- this._programmaticFilterRefresh = false;
82851
- } else if ((this.availableOptions.length > 0 && (this.componentHasFocus || this.dropdownOpen)) || (this.menu && this.menu.loading) || (this.availableOptions.length === 0 && this.noMatchOption)) {
82852
- this.showBib();
82837
+ if ((this.menu && !this._programmaticFilterRefresh)) {
82838
+ if (
82839
+ this.availableOptions.length > 0 ||
82840
+ this.menu.loading ||
82841
+ this.noMatchOption
82842
+ ) {
82843
+ if (this._userTyped) {
82844
+ if (!this.dropdownOpen) {
82845
+ this.showBib();
82846
+ }
82847
+ this._userTyped = false;
82848
+ }
82849
+ }
82850
+
82853
82851
  if (!this.availableOptions.includes(this.menu.optionActive)) {
82854
82852
  this.activateFirstEnabledAvailableOption();
82855
82853
  }
82856
- } else if (this.dropdown && this.dropdown.isPopoverVisible) {
82854
+ } else if (!this.dropdown.isBibFullscreen) {
82857
82855
  this.hideBib();
82858
82856
  }
82857
+
82858
+ if (this._programmaticFilterRefresh) {
82859
+ this._programmaticFilterRefresh = false;
82860
+ }
82859
82861
  }
82860
82862
 
82861
82863
  if (changedProperties.has('error')) {
@@ -82997,10 +82999,10 @@ class AuroCombobox extends AuroElement$3 {
82997
82999
  shape="${this.shape}"
82998
83000
  size="${this.size}">
82999
83001
  <${this.inputTag}
83000
- @input="${this.handleInputValueChange}"
83002
+ @input="${this.handleTriggerInputValueChange}"
83001
83003
  appearance="${this.onDark ? 'inverse' : this.appearance}"
83002
83004
  .a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
83003
- .a11yExpanded="${this.triggerExpandedState}"
83005
+ .a11yExpanded="${this.dropdownOpen}"
83004
83006
  .a11yControls="${this.dropdownId}"
83005
83007
  .autocomplete="${this.autocomplete}"
83006
83008
  .inputmode="${this.inputmode}"
@@ -85150,11 +85152,17 @@ class AuroFormValidation {
85150
85152
  return;
85151
85153
  }
85152
85154
 
85153
- // Validate that the date passed was the correct format and is a valid date
85155
+ // Validate that the date passed was the correct format and is a valid date.
85156
+ // For partial date formats, valueObject is never populated; validate them directly.
85154
85157
  if (elem.value && !elem.valueObject) {
85155
- elem.validity = 'patternMismatch';
85156
- elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
85157
- return;
85158
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
85159
+ const isValidPartial = isPartialDateFormat && elem.util.isValidPartialDate(elem.value, elem.format);
85160
+
85161
+ if (!isValidPartial) {
85162
+ elem.validity = 'patternMismatch';
85163
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
85164
+ return;
85165
+ }
85158
85166
  }
85159
85167
 
85160
85168
  // Perform the rest of the validation
@@ -85248,15 +85256,17 @@ class AuroFormValidation {
85248
85256
  );
85249
85257
  }
85250
85258
 
85251
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
85252
- if (this.auroInputElements?.length === 2) {
85253
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
85259
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
85260
+
85261
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
85262
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
85263
+ // field (datepicker is the intended consumer — start/end are independently required).
85264
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
85265
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
85254
85266
  hasValue = false;
85255
85267
  }
85256
85268
  }
85257
85269
 
85258
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
85259
-
85260
85270
  if (isCombobox) {
85261
85271
 
85262
85272
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -89637,7 +89647,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
89637
89647
  }
89638
89648
  };
89639
89649
 
89640
- var formkitVersion$1 = '202606292156';
89650
+ var formkitVersion$1 = '202607011722';
89641
89651
 
89642
89652
  class AuroElement extends i$2 {
89643
89653
  static get properties() {
@@ -90389,7 +90399,19 @@ class AuroDropdown extends AuroElement {
90389
90399
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
90390
90400
  this.trigger.focus();
90391
90401
  }
90392
- }
90402
+
90403
+
90404
+ if (!this.isPopoverVisible) {
90405
+ // wait til the bib gets fully closed and rendered
90406
+ setTimeout(() => {
90407
+ // 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.
90408
+ if (!this.isPopoverVisible || !this.bib.matches(':focus-within')) {
90409
+ return;
90410
+ }
90411
+ // Move focus out of bib into trigger.
90412
+ this.trigger.focus();
90413
+ });
90414
+ } }
90393
90415
 
90394
90416
  firstUpdated() {
90395
90417
  // Configure the floater to, this will generate the ID for the bib
@@ -91659,7 +91681,7 @@ class AuroHelpText extends i$2 {
91659
91681
  }
91660
91682
  }
91661
91683
 
91662
- var formkitVersion = '202606292156';
91684
+ var formkitVersion = '202607011722';
91663
91685
 
91664
91686
  var styleCss = i$4`.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}`;
91665
91687