@aurodesignsystem-dev/auro-formkit 0.0.0-pr1507.0 → 0.0.0-pr1508.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 (63) hide show
  1. package/components/checkbox/demo/customize.html +1 -2
  2. package/components/checkbox/demo/customize.min.js +1 -1
  3. package/components/checkbox/demo/getting-started.min.js +1 -1
  4. package/components/checkbox/demo/index.min.js +1 -1
  5. package/components/checkbox/dist/index.js +1 -1
  6. package/components/checkbox/dist/registered.js +1 -1
  7. package/components/combobox/demo/customize.html +1 -2
  8. package/components/combobox/demo/customize.md +108 -132
  9. package/components/combobox/demo/customize.min.js +150 -293
  10. package/components/combobox/demo/getting-started.min.js +150 -293
  11. package/components/combobox/demo/index.min.js +150 -293
  12. package/components/combobox/dist/auro-combobox.d.ts +9 -0
  13. package/components/combobox/dist/index.js +150 -293
  14. package/components/combobox/dist/registered.js +150 -293
  15. package/components/counter/demo/customize.min.js +10 -2
  16. package/components/counter/demo/index.min.js +10 -2
  17. package/components/counter/dist/index.js +10 -2
  18. package/components/counter/dist/registered.js +10 -2
  19. package/components/datepicker/demo/api.md +2 -0
  20. package/components/datepicker/demo/customize.js +0 -2
  21. package/components/datepicker/demo/customize.md +138 -38
  22. package/components/datepicker/demo/customize.min.js +59 -168
  23. package/components/datepicker/demo/index.min.js +59 -150
  24. package/components/datepicker/dist/index.js +59 -150
  25. package/components/datepicker/dist/registered.js +59 -150
  26. package/components/datepicker/dist/src/auro-datepicker.d.ts +2 -0
  27. package/components/dropdown/demo/customize.min.js +9 -1
  28. package/components/dropdown/demo/getting-started.min.js +9 -1
  29. package/components/dropdown/demo/index.min.js +9 -1
  30. package/components/dropdown/dist/auro-dropdown.d.ts +1 -0
  31. package/components/dropdown/dist/index.js +9 -1
  32. package/components/dropdown/dist/registered.js +9 -1
  33. package/components/form/demo/customize.html +6 -6
  34. package/components/form/demo/customize.js +19 -0
  35. package/components/form/demo/customize.md +203 -51
  36. package/components/form/demo/customize.min.js +707 -633
  37. package/components/form/demo/getting-started.min.js +635 -633
  38. package/components/form/demo/index.min.js +635 -633
  39. package/components/form/demo/registerDemoDeps.min.js +272 -596
  40. package/components/form/dist/auro-form.d.ts +122 -4
  41. package/components/form/dist/index.js +363 -37
  42. package/components/form/dist/registered.js +363 -37
  43. package/components/input/demo/customize.html +1 -2
  44. package/components/input/demo/customize.md +54 -53
  45. package/components/input/demo/customize.min.js +41 -147
  46. package/components/input/demo/getting-started.min.js +41 -147
  47. package/components/input/demo/index.min.js +41 -147
  48. package/components/input/dist/base-input.d.ts +1 -49
  49. package/components/input/dist/index.js +41 -147
  50. package/components/input/dist/registered.js +41 -147
  51. package/components/radio/demo/customize.min.js +1 -1
  52. package/components/radio/demo/getting-started.min.js +1 -1
  53. package/components/radio/demo/index.min.js +1 -1
  54. package/components/radio/dist/index.js +1 -1
  55. package/components/radio/dist/registered.js +1 -1
  56. package/components/select/demo/customize.html +1 -2
  57. package/components/select/demo/customize.min.js +10 -2
  58. package/components/select/demo/getting-started.min.js +10 -2
  59. package/components/select/demo/index.min.js +10 -2
  60. package/components/select/dist/index.js +10 -2
  61. package/components/select/dist/registered.js +10 -2
  62. package/custom-elements.json +1592 -1707
  63. package/package.json +1 -1
@@ -10460,6 +10460,7 @@ let AuroInputUtilities$3 = class AuroInputUtilities {
10460
10460
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
10461
10461
 
10462
10462
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
10463
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
10463
10464
  return undefined;
10464
10465
  }
10465
10466
 
@@ -10611,10 +10612,8 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10611
10612
  this.layout = 'classic';
10612
10613
  this.locale = 'en-US';
10613
10614
  this.max = undefined;
10614
- this._maxObject = undefined;
10615
10615
  this.maxLength = undefined;
10616
10616
  this.min = undefined;
10617
- this._minObject = undefined;
10618
10617
  this.minLength = undefined;
10619
10618
  this.required = false;
10620
10619
  this.onDark = false;
@@ -10622,7 +10621,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
10622
10621
  this.size = 'lg';
10623
10622
  this.shape = 'classic';
10624
10623
  this.value = undefined;
10625
- this._valueObject = undefined;
10626
10624
 
10627
10625
  this._initializePrivateDefaults();
10628
10626
  }
@@ -11162,7 +11160,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11162
11160
  * @returns {Date|undefined}
11163
11161
  */
11164
11162
  get valueObject() {
11165
- return this._valueObject || this._computeDateObjectFallback(this.value);
11163
+ return this.value && dateFormatter$3.isValidDate(this.value) ? dateFormatter$3.stringToDateInstance(this.value) : undefined;
11166
11164
  }
11167
11165
 
11168
11166
  /**
@@ -11170,7 +11168,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11170
11168
  * @returns {Date|undefined}
11171
11169
  */
11172
11170
  get minObject() {
11173
- return this._minObject || this._computeDateObjectFallback(this.min);
11171
+ return this.min && dateFormatter$3.isValidDate(this.min) ? dateFormatter$3.stringToDateInstance(this.min) : undefined;
11174
11172
  }
11175
11173
 
11176
11174
  /**
@@ -11178,50 +11176,7 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11178
11176
  * @returns {Date|undefined}
11179
11177
  */
11180
11178
  get maxObject() {
11181
- return this._maxObject || this._computeDateObjectFallback(this.max);
11182
- }
11183
-
11184
- /**
11185
- * Parses a date string into a Date object when the corresponding `_*Object`
11186
- * field hasn't been synced yet by `updated()`. Returns undefined when the
11187
- * input type/format isn't a full date or the string is not a valid date.
11188
- *
11189
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
11190
- * inside its own `updated()` before this input's `updated()` has run
11191
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
11192
- * and range checks would otherwise silently no-op (flipping the result to
11193
- * `valid` or `patternMismatch`).
11194
- * @private
11195
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
11196
- * @returns {Date|undefined}
11197
- */
11198
- _computeDateObjectFallback(dateStr) {
11199
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
11200
- return undefined;
11201
- }
11202
- if (!dateFormatter$3.isValidDate(dateStr)) {
11203
- return undefined;
11204
- }
11205
- return dateFormatter$3.stringToDateInstance(dateStr);
11206
- }
11207
-
11208
- /**
11209
- * Internal setter for readonly date object properties.
11210
- * @private
11211
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
11212
- * @param {Date|undefined} propertyValue - Value to assign.
11213
- * @returns {void}
11214
- */
11215
- setDateObjectProperty(propertyName, propertyValue) {
11216
- const internalPropertyName = `_${propertyName}`;
11217
- const previousValue = this[internalPropertyName];
11218
-
11219
- if (previousValue === propertyValue) {
11220
- return;
11221
- }
11222
-
11223
- this[internalPropertyName] = propertyValue;
11224
- this.requestUpdate(propertyName, previousValue);
11179
+ return this.max && dateFormatter$3.isValidDate(this.max) ? dateFormatter$3.stringToDateInstance(this.max) : undefined;
11225
11180
  }
11226
11181
 
11227
11182
  connectedCallback() {
@@ -11250,7 +11205,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11250
11205
  format: this.format
11251
11206
  });
11252
11207
  this.configureDataForType();
11253
- this.syncDateValues();
11254
11208
  }
11255
11209
 
11256
11210
  disconnectedCallback() {
@@ -11270,10 +11224,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11270
11224
  this.wrapperElement.addEventListener('click', this.handleClick);
11271
11225
  }
11272
11226
 
11273
- // add attribute for query selectors when auro-input is registered under a custom name
11274
- if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
11275
- this.setAttribute('auro-input', '');
11276
- }
11277
11227
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
11278
11228
 
11279
11229
  // use validity message override if declared when initializing the component
@@ -11284,7 +11234,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11284
11234
  this.setCustomHelpTextMessage();
11285
11235
  this.configureAutoFormatting();
11286
11236
  this.configureDataForType();
11287
- this.syncDateValues();
11288
11237
  }
11289
11238
 
11290
11239
  /**
@@ -11421,8 +11370,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11421
11370
  this.configureDataForType();
11422
11371
  }
11423
11372
 
11424
- this.syncDateValues(changedProperties);
11425
-
11426
11373
  if (changedProperties.has('value')) {
11427
11374
  if (this.value && this.value.length > 0) {
11428
11375
  this.hasValue = true;
@@ -11444,14 +11391,14 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11444
11391
 
11445
11392
  if (formattedValue !== this.inputElement.value) {
11446
11393
  this.skipNextProgrammaticInputEvent = true;
11447
- if (this.maskInstance && this.type === 'credit-card') {
11394
+ if (this.maskInstance && this.type !== 'date') {
11448
11395
  // Route through the mask so its _value and el.value stay in lock-step
11449
11396
  // (set value calls updateControl which writes el.value = displayValue).
11450
11397
  // Writing el.value directly leaves the mask thinking displayValue is
11451
- // stale; _saveSelection on the next focus/click then warns. Scoped to
11452
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
11453
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
11454
- // and flip validity from patternMismatch to tooShort.
11398
+ // stale; _saveSelection on the next focus/click then warns. Date is
11399
+ // excluded because its formattedValue can be raw ISO when the calendar
11400
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
11401
+ // flip validity from patternMismatch to tooShort.
11455
11402
  this.maskInstance.value = formattedValue || '';
11456
11403
  } else if (formattedValue) {
11457
11404
  this.inputElement.value = formattedValue;
@@ -11493,120 +11440,65 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11493
11440
  }));
11494
11441
  }
11495
11442
 
11496
-
11497
- /**
11498
- * Synchronizes the ISO string values and Date object representations for date-related properties.
11499
- * This keeps the model and display values aligned when either side changes.
11500
- *
11501
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
11502
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
11503
- * represents a full year/month/day date format.
11504
- *
11505
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
11506
- * @returns {void}
11507
- * @private
11508
- */
11509
- syncDateValues(changedProperties = undefined) {
11510
- if (!this.util.isFullDateFormat(this.type, this.format)) {
11511
- return;
11512
- }
11513
-
11514
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
11515
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
11516
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
11517
- }
11518
-
11519
- /**
11520
- * Synchronizes one date object/string property pair.
11521
- * @private
11522
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
11523
- * @param {string} objectProperty - Date object property name.
11524
- * @param {string} valueProperty - ISO string property name.
11525
- * @returns {void}
11526
- */
11527
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
11528
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
11529
-
11530
- // objectProperty wins over valueProperty when both changed
11531
- if (objectPropertyChanged && this[objectProperty]) {
11532
- this[valueProperty] = dateFormatter$3.toISOFormatString(this[objectProperty]);
11533
- return;
11534
- }
11535
-
11536
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
11537
- if (!valuePropertyChanged) {
11538
- return;
11539
- }
11540
-
11541
- // 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)
11542
- if (
11543
- changedProperties &&
11544
- valueProperty === 'value' &&
11545
- changedProperties.get('value') === undefined &&
11546
- this[objectProperty] instanceof Date &&
11547
- this[valueProperty] === dateFormatter$3.toISOFormatString(this[objectProperty])
11548
- ) {
11549
- return;
11550
- }
11551
-
11552
- if (dateFormatter$3.isValidDate(this[valueProperty])) {
11553
- this.setDateObjectProperty(objectProperty, dateFormatter$3.stringToDateInstance(this[valueProperty]));
11554
- } else {
11555
- this.setDateObjectProperty(objectProperty, undefined);
11556
- }
11557
- }
11558
-
11559
11443
  /**
11560
11444
  * Sets up IMasks and logic based on auto-formatting requirements.
11561
11445
  * @private
11562
11446
  * @returns {void}
11563
11447
  */
11564
11448
  configureAutoFormatting() {
11565
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
11566
- // by _configuringMask above) could otherwise trigger handleInput
11567
- // processCreditCard configureAutoFormatting before the outer call's
11568
- // set value has finished its alignCursor pass.
11449
+ // _configuringMask gates two things: external re-entry into this method
11450
+ // while setup is mid-flight (from property changes that call back here),
11451
+ // and the accept/complete listeners below — both need to ignore the mask
11452
+ // events fired by our own value-restore step.
11569
11453
  if (this._configuringMask) return;
11570
11454
  this._configuringMask = true;
11571
11455
  try {
11456
+ // Destroy any prior mask so IMask can attach fresh under the new format.
11457
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
11458
+ // type switched from credit-card to text) the IMask() reassignment
11459
+ // below is skipped, and downstream writes at line ~823 would otherwise
11460
+ // route through the destroyed instance.
11572
11461
  if (this.maskInstance) {
11573
11462
  this.maskInstance.destroy();
11463
+ this.maskInstance = null;
11574
11464
  }
11575
11465
 
11576
- // Pass new format to util
11577
11466
  this.util.updateFormat(this.format);
11578
11467
 
11579
11468
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
11580
11469
 
11581
11470
  if (this.inputElement && maskOptions.mask) {
11582
-
11583
- // Stash and clear any existing value before IMask init.
11584
- // IMask's constructor processes the current input value which requires
11585
- // selection state clearing first avoids that scenario entirely.
11586
- // When the format changes (e.g. locale switch) and we have a valid ISO
11587
- // model value, compute the display string for the NEW format instead of
11588
- // re-using the old display string, which may be invalid in the new mask.
11471
+ // Capture the current display so it can be re-applied after IMask
11472
+ // attaches. The restore at the bottom goes through maskInstance.value
11473
+ // (not inputElement.value directly) so the mask's internal state and
11474
+ // the input's displayed text stay in lock-step.
11589
11475
  let existingValue = this.inputElement.value;
11476
+
11477
+ // Format-change case (e.g. locale switch): existingValue is the OLD
11478
+ // mask's display string and may not parse under the new mask. When
11479
+ // we have a valid date model, rebuild the display from valueObject
11480
+ // (the canonical source) using the new mask's format function.
11590
11481
  if (
11591
11482
  this.util.isFullDateFormat(this.type, this.format) &&
11592
11483
  this.value &&
11593
- dateFormatter$3.isValidDate(this.value) &&
11594
- this.valueObject instanceof Date &&
11595
- !Number.isNaN(this.valueObject.getTime()) &&
11484
+ this.valueObject &&
11596
11485
  typeof maskOptions.format === 'function'
11597
11486
  ) {
11598
11487
  existingValue = maskOptions.format(this.valueObject);
11599
11488
  }
11600
11489
 
11490
+ // Clear before IMask attaches so the constructor seeds an empty
11491
+ // internal value. Otherwise IMask reads the stale unmasked string
11492
+ // and emits a spurious 'accept' before the restore below runs.
11601
11493
  this.skipNextProgrammaticInputEvent = true;
11602
11494
  this.inputElement.value = '';
11603
11495
 
11604
11496
  this.maskInstance = IMask$3(this.inputElement, maskOptions);
11605
11497
 
11498
+ // Mask fires 'accept' on every value change, including the restore
11499
+ // step below. Skip events fired during configureAutoFormatting so
11500
+ // we don't overwrite a value the parent just pushed.
11606
11501
  this.maskInstance.on('accept', () => {
11607
- // Suppress propagation during configureAutoFormatting's own value-restoration
11608
- // (line below) — the mask emits 'accept' on every value-set, including ours,
11609
- // and we don't want to overwrite a value the parent just pushed.
11610
11502
  if (this._configuringMask) return;
11611
11503
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
11612
11504
  if (this.type === "date") {
@@ -11614,6 +11506,8 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11614
11506
  }
11615
11507
  });
11616
11508
 
11509
+ // Mask fires 'complete' on the restore step below for any value that
11510
+ // happens to be a complete match. Same setup-suppression as 'accept'.
11617
11511
  this.maskInstance.on('complete', () => {
11618
11512
  if (this._configuringMask) return;
11619
11513
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -11622,7 +11516,9 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11622
11516
  }
11623
11517
  });
11624
11518
 
11625
- // Restore the stashed value through IMask so it's properly masked
11519
+ // Write existingValue through the mask (not the input directly) so
11520
+ // the mask reformats it under the new rules and keeps its internal
11521
+ // _value aligned with the input's displayed text.
11626
11522
  if (existingValue) {
11627
11523
  this.maskInstance.value = existingValue;
11628
11524
  }
@@ -11790,7 +11686,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11790
11686
  */
11791
11687
  reset() {
11792
11688
  this.value = undefined;
11793
- this.setDateObjectProperty('valueObject', undefined);
11794
11689
  this.validation.reset(this);
11795
11690
  }
11796
11691
 
@@ -11799,7 +11694,6 @@ let BaseInput$2 = class BaseInput extends AuroElement$6 {
11799
11694
  */
11800
11695
  clear() {
11801
11696
  this.value = undefined;
11802
- this.setDateObjectProperty('valueObject', undefined);
11803
11697
  }
11804
11698
 
11805
11699
  /**
@@ -12328,7 +12222,7 @@ let AuroHelpText$8 = class AuroHelpText extends i$2 {
12328
12222
  }
12329
12223
  };
12330
12224
 
12331
- var formkitVersion$8 = '202606192121';
12225
+ var formkitVersion$8 = '202606231948';
12332
12226
 
12333
12227
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12334
12228
  // See LICENSE in the project root for license information.
@@ -23567,6 +23461,7 @@ let AuroInputUtilities$1 = class AuroInputUtilities {
23567
23461
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
23568
23462
 
23569
23463
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
23464
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
23570
23465
  return undefined;
23571
23466
  }
23572
23467
 
@@ -26447,7 +26342,7 @@ let AuroBibtemplate$3 = class AuroBibtemplate extends i$2 {
26447
26342
  }
26448
26343
  };
26449
26344
 
26450
- var formkitVersion$2$1 = '202606192121';
26345
+ var formkitVersion$2$1 = '202606231948';
26451
26346
 
26452
26347
  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}
26453
26348
  `,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}}
@@ -31958,7 +31853,7 @@ let AuroHelpText$2$1 = class AuroHelpText extends i$2 {
31958
31853
  }
31959
31854
  };
31960
31855
 
31961
- var formkitVersion$1$3 = '202606192121';
31856
+ var formkitVersion$1$3 = '202606231948';
31962
31857
 
31963
31858
  let AuroElement$2$2 = class AuroElement extends i$2 {
31964
31859
  static get properties() {
@@ -32909,6 +32804,14 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
32909
32804
  };
32910
32805
  this.addEventListener('keydown', this._bibTabHandler);
32911
32806
 
32807
+ // Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
32808
+ // desktopModal trap owns focus management. Without this, the very
32809
+ // first focus move into the bib (from the RAF below) triggers
32810
+ // handleFocusLoss → hideBib, tearing down the trap before the
32811
+ // user can press Tab.
32812
+ this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
32813
+ this.noHideOnThisFocusLoss = true;
32814
+
32912
32815
  // Move initial focus into the bib content, matching FocusTrap behavior
32913
32816
  requestAnimationFrame(() => {
32914
32817
  const focusables = getFocusableElements$3(this.bibContent);
@@ -43672,6 +43575,7 @@ let AuroInputUtilities$2 = class AuroInputUtilities {
43672
43575
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
43673
43576
 
43674
43577
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
43578
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
43675
43579
  return undefined;
43676
43580
  }
43677
43581
 
@@ -43823,10 +43727,8 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
43823
43727
  this.layout = 'classic';
43824
43728
  this.locale = 'en-US';
43825
43729
  this.max = undefined;
43826
- this._maxObject = undefined;
43827
43730
  this.maxLength = undefined;
43828
43731
  this.min = undefined;
43829
- this._minObject = undefined;
43830
43732
  this.minLength = undefined;
43831
43733
  this.required = false;
43832
43734
  this.onDark = false;
@@ -43834,7 +43736,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
43834
43736
  this.size = 'lg';
43835
43737
  this.shape = 'classic';
43836
43738
  this.value = undefined;
43837
- this._valueObject = undefined;
43838
43739
 
43839
43740
  this._initializePrivateDefaults();
43840
43741
  }
@@ -44374,7 +44275,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44374
44275
  * @returns {Date|undefined}
44375
44276
  */
44376
44277
  get valueObject() {
44377
- return this._valueObject || this._computeDateObjectFallback(this.value);
44278
+ return this.value && dateFormatter$2.isValidDate(this.value) ? dateFormatter$2.stringToDateInstance(this.value) : undefined;
44378
44279
  }
44379
44280
 
44380
44281
  /**
@@ -44382,7 +44283,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44382
44283
  * @returns {Date|undefined}
44383
44284
  */
44384
44285
  get minObject() {
44385
- return this._minObject || this._computeDateObjectFallback(this.min);
44286
+ return this.min && dateFormatter$2.isValidDate(this.min) ? dateFormatter$2.stringToDateInstance(this.min) : undefined;
44386
44287
  }
44387
44288
 
44388
44289
  /**
@@ -44390,50 +44291,7 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44390
44291
  * @returns {Date|undefined}
44391
44292
  */
44392
44293
  get maxObject() {
44393
- return this._maxObject || this._computeDateObjectFallback(this.max);
44394
- }
44395
-
44396
- /**
44397
- * Parses a date string into a Date object when the corresponding `_*Object`
44398
- * field hasn't been synced yet by `updated()`. Returns undefined when the
44399
- * input type/format isn't a full date or the string is not a valid date.
44400
- *
44401
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
44402
- * inside its own `updated()` before this input's `updated()` has run
44403
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
44404
- * and range checks would otherwise silently no-op (flipping the result to
44405
- * `valid` or `patternMismatch`).
44406
- * @private
44407
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
44408
- * @returns {Date|undefined}
44409
- */
44410
- _computeDateObjectFallback(dateStr) {
44411
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
44412
- return undefined;
44413
- }
44414
- if (!dateFormatter$2.isValidDate(dateStr)) {
44415
- return undefined;
44416
- }
44417
- return dateFormatter$2.stringToDateInstance(dateStr);
44418
- }
44419
-
44420
- /**
44421
- * Internal setter for readonly date object properties.
44422
- * @private
44423
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
44424
- * @param {Date|undefined} propertyValue - Value to assign.
44425
- * @returns {void}
44426
- */
44427
- setDateObjectProperty(propertyName, propertyValue) {
44428
- const internalPropertyName = `_${propertyName}`;
44429
- const previousValue = this[internalPropertyName];
44430
-
44431
- if (previousValue === propertyValue) {
44432
- return;
44433
- }
44434
-
44435
- this[internalPropertyName] = propertyValue;
44436
- this.requestUpdate(propertyName, previousValue);
44294
+ return this.max && dateFormatter$2.isValidDate(this.max) ? dateFormatter$2.stringToDateInstance(this.max) : undefined;
44437
44295
  }
44438
44296
 
44439
44297
  connectedCallback() {
@@ -44462,7 +44320,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44462
44320
  format: this.format
44463
44321
  });
44464
44322
  this.configureDataForType();
44465
- this.syncDateValues();
44466
44323
  }
44467
44324
 
44468
44325
  disconnectedCallback() {
@@ -44482,10 +44339,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44482
44339
  this.wrapperElement.addEventListener('click', this.handleClick);
44483
44340
  }
44484
44341
 
44485
- // add attribute for query selectors when auro-input is registered under a custom name
44486
- if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
44487
- this.setAttribute('auro-input', '');
44488
- }
44489
44342
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
44490
44343
 
44491
44344
  // use validity message override if declared when initializing the component
@@ -44496,7 +44349,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44496
44349
  this.setCustomHelpTextMessage();
44497
44350
  this.configureAutoFormatting();
44498
44351
  this.configureDataForType();
44499
- this.syncDateValues();
44500
44352
  }
44501
44353
 
44502
44354
  /**
@@ -44633,8 +44485,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44633
44485
  this.configureDataForType();
44634
44486
  }
44635
44487
 
44636
- this.syncDateValues(changedProperties);
44637
-
44638
44488
  if (changedProperties.has('value')) {
44639
44489
  if (this.value && this.value.length > 0) {
44640
44490
  this.hasValue = true;
@@ -44656,14 +44506,14 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44656
44506
 
44657
44507
  if (formattedValue !== this.inputElement.value) {
44658
44508
  this.skipNextProgrammaticInputEvent = true;
44659
- if (this.maskInstance && this.type === 'credit-card') {
44509
+ if (this.maskInstance && this.type !== 'date') {
44660
44510
  // Route through the mask so its _value and el.value stay in lock-step
44661
44511
  // (set value calls updateControl which writes el.value = displayValue).
44662
44512
  // Writing el.value directly leaves the mask thinking displayValue is
44663
- // stale; _saveSelection on the next focus/click then warns. Scoped to
44664
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
44665
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
44666
- // and flip validity from patternMismatch to tooShort.
44513
+ // stale; _saveSelection on the next focus/click then warns. Date is
44514
+ // excluded because its formattedValue can be raw ISO when the calendar
44515
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
44516
+ // flip validity from patternMismatch to tooShort.
44667
44517
  this.maskInstance.value = formattedValue || '';
44668
44518
  } else if (formattedValue) {
44669
44519
  this.inputElement.value = formattedValue;
@@ -44705,120 +44555,65 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44705
44555
  }));
44706
44556
  }
44707
44557
 
44708
-
44709
- /**
44710
- * Synchronizes the ISO string values and Date object representations for date-related properties.
44711
- * This keeps the model and display values aligned when either side changes.
44712
- *
44713
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
44714
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
44715
- * represents a full year/month/day date format.
44716
- *
44717
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
44718
- * @returns {void}
44719
- * @private
44720
- */
44721
- syncDateValues(changedProperties = undefined) {
44722
- if (!this.util.isFullDateFormat(this.type, this.format)) {
44723
- return;
44724
- }
44725
-
44726
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
44727
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
44728
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
44729
- }
44730
-
44731
- /**
44732
- * Synchronizes one date object/string property pair.
44733
- * @private
44734
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
44735
- * @param {string} objectProperty - Date object property name.
44736
- * @param {string} valueProperty - ISO string property name.
44737
- * @returns {void}
44738
- */
44739
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
44740
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
44741
-
44742
- // objectProperty wins over valueProperty when both changed
44743
- if (objectPropertyChanged && this[objectProperty]) {
44744
- this[valueProperty] = dateFormatter$2.toISOFormatString(this[objectProperty]);
44745
- return;
44746
- }
44747
-
44748
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
44749
- if (!valuePropertyChanged) {
44750
- return;
44751
- }
44752
-
44753
- // 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)
44754
- if (
44755
- changedProperties &&
44756
- valueProperty === 'value' &&
44757
- changedProperties.get('value') === undefined &&
44758
- this[objectProperty] instanceof Date &&
44759
- this[valueProperty] === dateFormatter$2.toISOFormatString(this[objectProperty])
44760
- ) {
44761
- return;
44762
- }
44763
-
44764
- if (dateFormatter$2.isValidDate(this[valueProperty])) {
44765
- this.setDateObjectProperty(objectProperty, dateFormatter$2.stringToDateInstance(this[valueProperty]));
44766
- } else {
44767
- this.setDateObjectProperty(objectProperty, undefined);
44768
- }
44769
- }
44770
-
44771
44558
  /**
44772
44559
  * Sets up IMasks and logic based on auto-formatting requirements.
44773
44560
  * @private
44774
44561
  * @returns {void}
44775
44562
  */
44776
44563
  configureAutoFormatting() {
44777
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
44778
- // by _configuringMask above) could otherwise trigger handleInput
44779
- // processCreditCard configureAutoFormatting before the outer call's
44780
- // set value has finished its alignCursor pass.
44564
+ // _configuringMask gates two things: external re-entry into this method
44565
+ // while setup is mid-flight (from property changes that call back here),
44566
+ // and the accept/complete listeners below — both need to ignore the mask
44567
+ // events fired by our own value-restore step.
44781
44568
  if (this._configuringMask) return;
44782
44569
  this._configuringMask = true;
44783
44570
  try {
44571
+ // Destroy any prior mask so IMask can attach fresh under the new format.
44572
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
44573
+ // type switched from credit-card to text) the IMask() reassignment
44574
+ // below is skipped, and downstream writes at line ~823 would otherwise
44575
+ // route through the destroyed instance.
44784
44576
  if (this.maskInstance) {
44785
44577
  this.maskInstance.destroy();
44578
+ this.maskInstance = null;
44786
44579
  }
44787
44580
 
44788
- // Pass new format to util
44789
44581
  this.util.updateFormat(this.format);
44790
44582
 
44791
44583
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
44792
44584
 
44793
44585
  if (this.inputElement && maskOptions.mask) {
44794
-
44795
- // Stash and clear any existing value before IMask init.
44796
- // IMask's constructor processes the current input value which requires
44797
- // selection state clearing first avoids that scenario entirely.
44798
- // When the format changes (e.g. locale switch) and we have a valid ISO
44799
- // model value, compute the display string for the NEW format instead of
44800
- // re-using the old display string, which may be invalid in the new mask.
44586
+ // Capture the current display so it can be re-applied after IMask
44587
+ // attaches. The restore at the bottom goes through maskInstance.value
44588
+ // (not inputElement.value directly) so the mask's internal state and
44589
+ // the input's displayed text stay in lock-step.
44801
44590
  let existingValue = this.inputElement.value;
44591
+
44592
+ // Format-change case (e.g. locale switch): existingValue is the OLD
44593
+ // mask's display string and may not parse under the new mask. When
44594
+ // we have a valid date model, rebuild the display from valueObject
44595
+ // (the canonical source) using the new mask's format function.
44802
44596
  if (
44803
44597
  this.util.isFullDateFormat(this.type, this.format) &&
44804
44598
  this.value &&
44805
- dateFormatter$2.isValidDate(this.value) &&
44806
- this.valueObject instanceof Date &&
44807
- !Number.isNaN(this.valueObject.getTime()) &&
44599
+ this.valueObject &&
44808
44600
  typeof maskOptions.format === 'function'
44809
44601
  ) {
44810
44602
  existingValue = maskOptions.format(this.valueObject);
44811
44603
  }
44812
44604
 
44605
+ // Clear before IMask attaches so the constructor seeds an empty
44606
+ // internal value. Otherwise IMask reads the stale unmasked string
44607
+ // and emits a spurious 'accept' before the restore below runs.
44813
44608
  this.skipNextProgrammaticInputEvent = true;
44814
44609
  this.inputElement.value = '';
44815
44610
 
44816
44611
  this.maskInstance = IMask$2(this.inputElement, maskOptions);
44817
44612
 
44613
+ // Mask fires 'accept' on every value change, including the restore
44614
+ // step below. Skip events fired during configureAutoFormatting so
44615
+ // we don't overwrite a value the parent just pushed.
44818
44616
  this.maskInstance.on('accept', () => {
44819
- // Suppress propagation during configureAutoFormatting's own value-restoration
44820
- // (line below) — the mask emits 'accept' on every value-set, including ours,
44821
- // and we don't want to overwrite a value the parent just pushed.
44822
44617
  if (this._configuringMask) return;
44823
44618
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
44824
44619
  if (this.type === "date") {
@@ -44826,6 +44621,8 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44826
44621
  }
44827
44622
  });
44828
44623
 
44624
+ // Mask fires 'complete' on the restore step below for any value that
44625
+ // happens to be a complete match. Same setup-suppression as 'accept'.
44829
44626
  this.maskInstance.on('complete', () => {
44830
44627
  if (this._configuringMask) return;
44831
44628
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -44834,7 +44631,9 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
44834
44631
  }
44835
44632
  });
44836
44633
 
44837
- // Restore the stashed value through IMask so it's properly masked
44634
+ // Write existingValue through the mask (not the input directly) so
44635
+ // the mask reformats it under the new rules and keeps its internal
44636
+ // _value aligned with the input's displayed text.
44838
44637
  if (existingValue) {
44839
44638
  this.maskInstance.value = existingValue;
44840
44639
  }
@@ -45002,7 +44801,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45002
44801
  */
45003
44802
  reset() {
45004
44803
  this.value = undefined;
45005
- this.setDateObjectProperty('valueObject', undefined);
45006
44804
  this.validation.reset(this);
45007
44805
  }
45008
44806
 
@@ -45011,7 +44809,6 @@ let BaseInput$1 = class BaseInput extends AuroElement$1$3 {
45011
44809
  */
45012
44810
  clear() {
45013
44811
  this.value = undefined;
45014
- this.setDateObjectProperty('valueObject', undefined);
45015
44812
  }
45016
44813
 
45017
44814
  /**
@@ -45540,7 +45337,7 @@ let AuroHelpText$1$3 = class AuroHelpText extends i$2 {
45540
45337
  }
45541
45338
  };
45542
45339
 
45543
- var formkitVersion$7 = '202606192121';
45340
+ var formkitVersion$7 = '202606231948';
45544
45341
 
45545
45342
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
45546
45343
  // See LICENSE in the project root for license information.
@@ -46960,6 +46757,8 @@ const datepickerKeyboardStrategy = {
46960
46757
  * @slot label - Defines the label content for the entire datepicker when `layout="snowflake"`.
46961
46758
  * @slot toLabel - Defines the label content for the second input when the `range` attribute is used.
46962
46759
  * @slot fromLabel - Defines the label content for the first input.
46760
+ * @slot optionalFromLabel - Overrides the "(optional)" text rendered next to the first input's label when the datepicker is not `required`.
46761
+ * @slot optionalToLabel - Overrides the "(optional)" text rendered next to the second input's label when `range` is set and the datepicker is not `required`.
46963
46762
  * @slot date_YYYY_MM_DD - Defines the content to display in the auro-calendar-cell for the specified date. The content text is colored using the success state token when the `highlight` attribute is applied to the slot.
46964
46763
  * @slot popover_YYYY_MM_DD - Defines the content to display in the auro-calendar-cell popover for the specified date.
46965
46764
  * @csspart dropdown - Use for customizing the style of the dropdown.
@@ -48555,7 +48354,9 @@ class AuroDatePicker extends AuroElement$5 {
48555
48354
  // update the calendar
48556
48355
  if (this.valueEndObject) {
48557
48356
  this.calendar.dateTo = this.convertToWcValidTime(this.valueEndObject);
48558
- this.calendarRenderUtil.updateCentralDate(this, this.valueEndObject);
48357
+ if (!this.wasCellClick) {
48358
+ this.calendarRenderUtil.updateCentralDate(this, this.valueEndObject);
48359
+ }
48559
48360
  } else {
48560
48361
  if (this.inputList[1].value !== this.valueEnd) {
48561
48362
  this.inputList[1].value = this.valueEnd || '';
@@ -48950,6 +48751,7 @@ class AuroDatePicker extends AuroElement$5 {
48950
48751
  }
48951
48752
  <span slot="ariaLabel.clear">${this.runtimeUtils.getSlotText(this, 'ariaLabel.input.clear') || i18n$2(this.lang, 'clearInput')}</span>
48952
48753
  <span slot="label"><slot name="fromLabel"></slot></span>
48754
+ <slot name="optionalFromLabel" slot="optionalLabel"> (optional)</slot>
48953
48755
  </${this.inputTag}>
48954
48756
  </div>
48955
48757
 
@@ -48994,6 +48796,7 @@ class AuroDatePicker extends AuroElement$5 {
48994
48796
  }
48995
48797
  <span slot="ariaLabel.clear">${this.runtimeUtils.getSlotText(this, 'ariaLabel.input.clear') || this.runtimeUtils.getSlotText(this, 'ariaLabel.input.clear') || i18n$2(this.lang, 'clearInput')}</span>
48996
48798
  <span slot="label"><slot name="toLabel"></slot></span>
48799
+ <slot name="optionalToLabel" slot="optionalLabel"> (optional)</slot>
48997
48800
  </${this.inputTag}>
48998
48801
  </div>
48999
48802
  ` : undefined}
@@ -50237,7 +50040,7 @@ let AuroHelpText$1$2 = class AuroHelpText extends i$2 {
50237
50040
  }
50238
50041
  };
50239
50042
 
50240
- var formkitVersion$1$2 = '202606192121';
50043
+ var formkitVersion$1$2 = '202606231948';
50241
50044
 
50242
50045
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
50243
50046
  // See LICENSE in the project root for license information.
@@ -54565,7 +54368,7 @@ let AuroHelpText$6 = class AuroHelpText extends i$2 {
54565
54368
  }
54566
54369
  };
54567
54370
 
54568
- var formkitVersion$6 = '202606192121';
54371
+ var formkitVersion$6 = '202606231948';
54569
54372
 
54570
54373
  let AuroElement$1$2 = class AuroElement extends i$2 {
54571
54374
  static get properties() {
@@ -55516,6 +55319,14 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
55516
55319
  };
55517
55320
  this.addEventListener('keydown', this._bibTabHandler);
55518
55321
 
55322
+ // Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
55323
+ // desktopModal trap owns focus management. Without this, the very
55324
+ // first focus move into the bib (from the RAF below) triggers
55325
+ // handleFocusLoss → hideBib, tearing down the trap before the
55326
+ // user can press Tab.
55327
+ this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
55328
+ this.noHideOnThisFocusLoss = true;
55329
+
55519
55330
  // Move initial focus into the bib content, matching FocusTrap behavior
55520
55331
  requestAnimationFrame(() => {
55521
55332
  const focusables = getFocusableElements$2(this.bibContent);
@@ -58497,7 +58308,7 @@ let AuroHelpText$5 = class AuroHelpText extends i$2 {
58497
58308
  }
58498
58309
  };
58499
58310
 
58500
- var formkitVersion$5 = '202606192121';
58311
+ var formkitVersion$5 = '202606231948';
58501
58312
 
58502
58313
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
58503
58314
  // See LICENSE in the project root for license information.
@@ -60247,7 +60058,7 @@ let AuroHelpText$4 = class AuroHelpText extends i$2 {
60247
60058
  }
60248
60059
  };
60249
60060
 
60250
- var formkitVersion$4 = '202606192121';
60061
+ var formkitVersion$4 = '202606231948';
60251
60062
 
60252
60063
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
60253
60064
  // See LICENSE in the project root for license information.
@@ -61423,6 +61234,8 @@ function navigateArrow$1(component, direction, options = {}) {
61423
61234
  }
61424
61235
  }
61425
61236
 
61237
+ /* eslint-disable no-underscore-dangle */
61238
+
61426
61239
  /**
61427
61240
  * Returns the clear button element from the active input's shadow
61428
61241
  * DOM, if available.
@@ -61458,11 +61271,9 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
61458
61271
  * @param {Object} menu - The menu component.
61459
61272
  */
61460
61273
  function reconcileMenuIndex(menu) {
61461
- // eslint-disable-next-line no-underscore-dangle
61462
61274
  if (menu._index < 0 && menu.optionActive && menu.items) {
61463
61275
  const idx = menu.items.indexOf(menu.optionActive);
61464
61276
  if (idx >= 0) {
61465
- // eslint-disable-next-line no-underscore-dangle
61466
61277
  menu._index = idx;
61467
61278
  }
61468
61279
  }
@@ -65462,7 +65273,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$2 {
65462
65273
  }
65463
65274
  };
65464
65275
 
65465
- var formkitVersion$2 = '202606192121';
65276
+ var formkitVersion$2 = '202606231948';
65466
65277
 
65467
65278
  let AuroElement$2$1 = class AuroElement extends i$2 {
65468
65279
  static get properties() {
@@ -66413,6 +66224,14 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
66413
66224
  };
66414
66225
  this.addEventListener('keydown', this._bibTabHandler);
66415
66226
 
66227
+ // Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
66228
+ // desktopModal trap owns focus management. Without this, the very
66229
+ // first focus move into the bib (from the RAF below) triggers
66230
+ // handleFocusLoss → hideBib, tearing down the trap before the
66231
+ // user can press Tab.
66232
+ this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
66233
+ this.noHideOnThisFocusLoss = true;
66234
+
66416
66235
  // Move initial focus into the bib content, matching FocusTrap behavior
66417
66236
  requestAnimationFrame(() => {
66418
66237
  const focusables = getFocusableElements$1(this.bibContent);
@@ -77176,6 +76995,7 @@ class AuroInputUtilities {
77176
76995
  const maskOptions = this.getMaskOptions('date', normalizedFormat);
77177
76996
 
77178
76997
  if (!(valueObject instanceof Date) || Number.isNaN(valueObject.getTime()) || !maskOptions || typeof maskOptions.format !== 'function') {
76998
+ console.debug('Invalid date object or mask options for formatting', { valueObject, maskOptions }); // eslint-disable-line no-console
77179
76999
  return undefined;
77180
77000
  }
77181
77001
 
@@ -77327,10 +77147,8 @@ class BaseInput extends AuroElement$1$1 {
77327
77147
  this.layout = 'classic';
77328
77148
  this.locale = 'en-US';
77329
77149
  this.max = undefined;
77330
- this._maxObject = undefined;
77331
77150
  this.maxLength = undefined;
77332
77151
  this.min = undefined;
77333
- this._minObject = undefined;
77334
77152
  this.minLength = undefined;
77335
77153
  this.required = false;
77336
77154
  this.onDark = false;
@@ -77338,7 +77156,6 @@ class BaseInput extends AuroElement$1$1 {
77338
77156
  this.size = 'lg';
77339
77157
  this.shape = 'classic';
77340
77158
  this.value = undefined;
77341
- this._valueObject = undefined;
77342
77159
 
77343
77160
  this._initializePrivateDefaults();
77344
77161
  }
@@ -77878,7 +77695,7 @@ class BaseInput extends AuroElement$1$1 {
77878
77695
  * @returns {Date|undefined}
77879
77696
  */
77880
77697
  get valueObject() {
77881
- return this._valueObject || this._computeDateObjectFallback(this.value);
77698
+ return this.value && dateFormatter.isValidDate(this.value) ? dateFormatter.stringToDateInstance(this.value) : undefined;
77882
77699
  }
77883
77700
 
77884
77701
  /**
@@ -77886,7 +77703,7 @@ class BaseInput extends AuroElement$1$1 {
77886
77703
  * @returns {Date|undefined}
77887
77704
  */
77888
77705
  get minObject() {
77889
- return this._minObject || this._computeDateObjectFallback(this.min);
77706
+ return this.min && dateFormatter.isValidDate(this.min) ? dateFormatter.stringToDateInstance(this.min) : undefined;
77890
77707
  }
77891
77708
 
77892
77709
  /**
@@ -77894,50 +77711,7 @@ class BaseInput extends AuroElement$1$1 {
77894
77711
  * @returns {Date|undefined}
77895
77712
  */
77896
77713
  get maxObject() {
77897
- return this._maxObject || this._computeDateObjectFallback(this.max);
77898
- }
77899
-
77900
- /**
77901
- * Parses a date string into a Date object when the corresponding `_*Object`
77902
- * field hasn't been synced yet by `updated()`. Returns undefined when the
77903
- * input type/format isn't a full date or the string is not a valid date.
77904
- *
77905
- * Why this exists: a parent (datepicker) can call `inputN.validate()` from
77906
- * inside its own `updated()` before this input's `updated()` has run
77907
- * `syncDateValues()` — so `_valueObject`/`_maxObject` are still `undefined`
77908
- * and range checks would otherwise silently no-op (flipping the result to
77909
- * `valid` or `patternMismatch`).
77910
- * @private
77911
- * @param {string|undefined} dateStr - ISO date string from `value`/`min`/`max`.
77912
- * @returns {Date|undefined}
77913
- */
77914
- _computeDateObjectFallback(dateStr) {
77915
- if (!dateStr || !this.util || !this.util.isFullDateFormat(this.type, this.format)) {
77916
- return undefined;
77917
- }
77918
- if (!dateFormatter.isValidDate(dateStr)) {
77919
- return undefined;
77920
- }
77921
- return dateFormatter.stringToDateInstance(dateStr);
77922
- }
77923
-
77924
- /**
77925
- * Internal setter for readonly date object properties.
77926
- * @private
77927
- * @param {'valueObject'|'minObject'|'maxObject'} propertyName - Public object property name.
77928
- * @param {Date|undefined} propertyValue - Value to assign.
77929
- * @returns {void}
77930
- */
77931
- setDateObjectProperty(propertyName, propertyValue) {
77932
- const internalPropertyName = `_${propertyName}`;
77933
- const previousValue = this[internalPropertyName];
77934
-
77935
- if (previousValue === propertyValue) {
77936
- return;
77937
- }
77938
-
77939
- this[internalPropertyName] = propertyValue;
77940
- this.requestUpdate(propertyName, previousValue);
77714
+ return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
77941
77715
  }
77942
77716
 
77943
77717
  connectedCallback() {
@@ -77966,7 +77740,6 @@ class BaseInput extends AuroElement$1$1 {
77966
77740
  format: this.format
77967
77741
  });
77968
77742
  this.configureDataForType();
77969
- this.syncDateValues();
77970
77743
  }
77971
77744
 
77972
77745
  disconnectedCallback() {
@@ -77986,10 +77759,6 @@ class BaseInput extends AuroElement$1$1 {
77986
77759
  this.wrapperElement.addEventListener('click', this.handleClick);
77987
77760
  }
77988
77761
 
77989
- // add attribute for query selectors when auro-input is registered under a custom name
77990
- if (this.tagName.toLowerCase() !== 'auro-input' && !this.hasAttribute('auro-input')) {
77991
- this.setAttribute('auro-input', '');
77992
- }
77993
77762
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
77994
77763
 
77995
77764
  // use validity message override if declared when initializing the component
@@ -78000,7 +77769,6 @@ class BaseInput extends AuroElement$1$1 {
78000
77769
  this.setCustomHelpTextMessage();
78001
77770
  this.configureAutoFormatting();
78002
77771
  this.configureDataForType();
78003
- this.syncDateValues();
78004
77772
  }
78005
77773
 
78006
77774
  /**
@@ -78137,8 +77905,6 @@ class BaseInput extends AuroElement$1$1 {
78137
77905
  this.configureDataForType();
78138
77906
  }
78139
77907
 
78140
- this.syncDateValues(changedProperties);
78141
-
78142
77908
  if (changedProperties.has('value')) {
78143
77909
  if (this.value && this.value.length > 0) {
78144
77910
  this.hasValue = true;
@@ -78160,14 +77926,14 @@ class BaseInput extends AuroElement$1$1 {
78160
77926
 
78161
77927
  if (formattedValue !== this.inputElement.value) {
78162
77928
  this.skipNextProgrammaticInputEvent = true;
78163
- if (this.maskInstance && this.type === 'credit-card') {
77929
+ if (this.maskInstance && this.type !== 'date') {
78164
77930
  // Route through the mask so its _value and el.value stay in lock-step
78165
77931
  // (set value calls updateControl which writes el.value = displayValue).
78166
77932
  // Writing el.value directly leaves the mask thinking displayValue is
78167
- // stale; _saveSelection on the next focus/click then warns. Scoped to
78168
- // credit-card so date's own formattedValue (raw ISO when calendar-invalid)
78169
- // isn't re-masked through the mm/dd/yyyy mask, which would truncate it
78170
- // and flip validity from patternMismatch to tooShort.
77933
+ // stale; _saveSelection on the next focus/click then warns. Date is
77934
+ // excluded because its formattedValue can be raw ISO when the calendar
77935
+ // is invalid, and re-masking through mm/dd/yyyy would truncate it and
77936
+ // flip validity from patternMismatch to tooShort.
78171
77937
  this.maskInstance.value = formattedValue || '';
78172
77938
  } else if (formattedValue) {
78173
77939
  this.inputElement.value = formattedValue;
@@ -78209,120 +77975,65 @@ class BaseInput extends AuroElement$1$1 {
78209
77975
  }));
78210
77976
  }
78211
77977
 
78212
-
78213
- /**
78214
- * Synchronizes the ISO string values and Date object representations for date-related properties.
78215
- * This keeps the model and display values aligned when either side changes.
78216
- *
78217
- * When a full date format is in use, this method updates `value`, `min`, and `max` from their corresponding
78218
- * Date objects or vice versa, based on which properties have changed. It only runs when the current configuration
78219
- * represents a full year/month/day date format.
78220
- *
78221
- * @param {Map<string, unknown>|undefined} [changedProperties=undefined] - Optional map of changed properties used to limit which values are synchronized.
78222
- * @returns {void}
78223
- * @private
78224
- */
78225
- syncDateValues(changedProperties = undefined) {
78226
- if (!this.util.isFullDateFormat(this.type, this.format)) {
78227
- return;
78228
- }
78229
-
78230
- this.syncSingleDateValue(changedProperties, 'valueObject', 'value');
78231
- this.syncSingleDateValue(changedProperties, 'minObject', 'min');
78232
- this.syncSingleDateValue(changedProperties, 'maxObject', 'max');
78233
- }
78234
-
78235
- /**
78236
- * Synchronizes one date object/string property pair.
78237
- * @private
78238
- * @param {Map<string, unknown>|undefined} changedProperties - Map of changed properties from Lit.
78239
- * @param {string} objectProperty - Date object property name.
78240
- * @param {string} valueProperty - ISO string property name.
78241
- * @returns {void}
78242
- */
78243
- syncSingleDateValue(changedProperties, objectProperty, valueProperty) {
78244
- const objectPropertyChanged = !changedProperties || changedProperties.has(objectProperty);
78245
-
78246
- // objectProperty wins over valueProperty when both changed
78247
- if (objectPropertyChanged && this[objectProperty]) {
78248
- this[valueProperty] = dateFormatter.toISOFormatString(this[objectProperty]);
78249
- return;
78250
- }
78251
-
78252
- const valuePropertyChanged = !changedProperties || changedProperties.has(valueProperty);
78253
- if (!valuePropertyChanged) {
78254
- return;
78255
- }
78256
-
78257
- // 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)
78258
- if (
78259
- changedProperties &&
78260
- valueProperty === 'value' &&
78261
- changedProperties.get('value') === undefined &&
78262
- this[objectProperty] instanceof Date &&
78263
- this[valueProperty] === dateFormatter.toISOFormatString(this[objectProperty])
78264
- ) {
78265
- return;
78266
- }
78267
-
78268
- if (dateFormatter.isValidDate(this[valueProperty])) {
78269
- this.setDateObjectProperty(objectProperty, dateFormatter.stringToDateInstance(this[valueProperty]));
78270
- } else {
78271
- this.setDateObjectProperty(objectProperty, undefined);
78272
- }
78273
- }
78274
-
78275
77978
  /**
78276
77979
  * Sets up IMasks and logic based on auto-formatting requirements.
78277
77980
  * @private
78278
77981
  * @returns {void}
78279
77982
  */
78280
77983
  configureAutoFormatting() {
78281
- // Re-entrancy guard. The patched-setter's synthetic input event (suppressed
78282
- // by _configuringMask above) could otherwise trigger handleInput
78283
- // processCreditCard configureAutoFormatting before the outer call's
78284
- // set value has finished its alignCursor pass.
77984
+ // _configuringMask gates two things: external re-entry into this method
77985
+ // while setup is mid-flight (from property changes that call back here),
77986
+ // and the accept/complete listeners below — both need to ignore the mask
77987
+ // events fired by our own value-restore step.
78285
77988
  if (this._configuringMask) return;
78286
77989
  this._configuringMask = true;
78287
77990
  try {
77991
+ // Destroy any prior mask so IMask can attach fresh under the new format.
77992
+ // Null the reference too — if the new maskOptions.mask is falsy (e.g.
77993
+ // type switched from credit-card to text) the IMask() reassignment
77994
+ // below is skipped, and downstream writes at line ~823 would otherwise
77995
+ // route through the destroyed instance.
78288
77996
  if (this.maskInstance) {
78289
77997
  this.maskInstance.destroy();
77998
+ this.maskInstance = null;
78290
77999
  }
78291
78000
 
78292
- // Pass new format to util
78293
78001
  this.util.updateFormat(this.format);
78294
78002
 
78295
78003
  const maskOptions = this.util.getMaskOptions(this.type, this.format);
78296
78004
 
78297
78005
  if (this.inputElement && maskOptions.mask) {
78298
-
78299
- // Stash and clear any existing value before IMask init.
78300
- // IMask's constructor processes the current input value which requires
78301
- // selection state clearing first avoids that scenario entirely.
78302
- // When the format changes (e.g. locale switch) and we have a valid ISO
78303
- // model value, compute the display string for the NEW format instead of
78304
- // re-using the old display string, which may be invalid in the new mask.
78006
+ // Capture the current display so it can be re-applied after IMask
78007
+ // attaches. The restore at the bottom goes through maskInstance.value
78008
+ // (not inputElement.value directly) so the mask's internal state and
78009
+ // the input's displayed text stay in lock-step.
78305
78010
  let existingValue = this.inputElement.value;
78011
+
78012
+ // Format-change case (e.g. locale switch): existingValue is the OLD
78013
+ // mask's display string and may not parse under the new mask. When
78014
+ // we have a valid date model, rebuild the display from valueObject
78015
+ // (the canonical source) using the new mask's format function.
78306
78016
  if (
78307
78017
  this.util.isFullDateFormat(this.type, this.format) &&
78308
78018
  this.value &&
78309
- dateFormatter.isValidDate(this.value) &&
78310
- this.valueObject instanceof Date &&
78311
- !Number.isNaN(this.valueObject.getTime()) &&
78019
+ this.valueObject &&
78312
78020
  typeof maskOptions.format === 'function'
78313
78021
  ) {
78314
78022
  existingValue = maskOptions.format(this.valueObject);
78315
78023
  }
78316
78024
 
78025
+ // Clear before IMask attaches so the constructor seeds an empty
78026
+ // internal value. Otherwise IMask reads the stale unmasked string
78027
+ // and emits a spurious 'accept' before the restore below runs.
78317
78028
  this.skipNextProgrammaticInputEvent = true;
78318
78029
  this.inputElement.value = '';
78319
78030
 
78320
78031
  this.maskInstance = IMask(this.inputElement, maskOptions);
78321
78032
 
78033
+ // Mask fires 'accept' on every value change, including the restore
78034
+ // step below. Skip events fired during configureAutoFormatting so
78035
+ // we don't overwrite a value the parent just pushed.
78322
78036
  this.maskInstance.on('accept', () => {
78323
- // Suppress propagation during configureAutoFormatting's own value-restoration
78324
- // (line below) — the mask emits 'accept' on every value-set, including ours,
78325
- // and we don't want to overwrite a value the parent just pushed.
78326
78037
  if (this._configuringMask) return;
78327
78038
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
78328
78039
  if (this.type === "date") {
@@ -78330,6 +78041,8 @@ class BaseInput extends AuroElement$1$1 {
78330
78041
  }
78331
78042
  });
78332
78043
 
78044
+ // Mask fires 'complete' on the restore step below for any value that
78045
+ // happens to be a complete match. Same setup-suppression as 'accept'.
78333
78046
  this.maskInstance.on('complete', () => {
78334
78047
  if (this._configuringMask) return;
78335
78048
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
@@ -78338,7 +78051,9 @@ class BaseInput extends AuroElement$1$1 {
78338
78051
  }
78339
78052
  });
78340
78053
 
78341
- // Restore the stashed value through IMask so it's properly masked
78054
+ // Write existingValue through the mask (not the input directly) so
78055
+ // the mask reformats it under the new rules and keeps its internal
78056
+ // _value aligned with the input's displayed text.
78342
78057
  if (existingValue) {
78343
78058
  this.maskInstance.value = existingValue;
78344
78059
  }
@@ -78506,7 +78221,6 @@ class BaseInput extends AuroElement$1$1 {
78506
78221
  */
78507
78222
  reset() {
78508
78223
  this.value = undefined;
78509
- this.setDateObjectProperty('valueObject', undefined);
78510
78224
  this.validation.reset(this);
78511
78225
  }
78512
78226
 
@@ -78515,7 +78229,6 @@ class BaseInput extends AuroElement$1$1 {
78515
78229
  */
78516
78230
  clear() {
78517
78231
  this.value = undefined;
78518
- this.setDateObjectProperty('valueObject', undefined);
78519
78232
  }
78520
78233
 
78521
78234
  /**
@@ -79044,7 +78757,7 @@ let AuroHelpText$1$1 = class AuroHelpText extends i$2 {
79044
78757
  }
79045
78758
  };
79046
78759
 
79047
- var formkitVersion$1$1 = '202606192121';
78760
+ var formkitVersion$1$1 = '202606231948';
79048
78761
 
79049
78762
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
79050
78763
  // See LICENSE in the project root for license information.
@@ -80165,7 +79878,7 @@ let AuroBibtemplate$1 = class AuroBibtemplate extends i$2 {
80165
79878
  }
80166
79879
  };
80167
79880
 
80168
- var formkitVersion$3 = '202606192121';
79881
+ var formkitVersion$3 = '202606231948';
80169
79882
 
80170
79883
  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}`;
80171
79884
 
@@ -81152,7 +80865,7 @@ class AuroCombobox extends AuroElement$3 {
81152
80865
  if (this.menu) {
81153
80866
  this.menu.matchWord = normalizeFilterValue(this.input.value);
81154
80867
  }
81155
- const label = getOptionLabel(this.menu.optionSelected) || this.menu.currentLabel;
80868
+ const label = getOptionLabel(this.menu.optionSelected);
81156
80869
  this.updateTriggerTextDisplay(label || this.value);
81157
80870
  }
81158
80871
 
@@ -81166,40 +80879,9 @@ class AuroCombobox extends AuroElement$3 {
81166
80879
  // in suggestion mode, do not override input value if no selection has been made and the input currently has focus
81167
80880
  const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
81168
80881
 
81169
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
81170
- const nextValue = label || this.value;
81171
- // Only set the flag when there's an actual write to suppress —
81172
- // syncValuesAndStates re-enters here during typing when both inputs
81173
- // already match, and a no-op flag flip would make the bib branch's
81174
- // bail eat legitimate user-input events.
81175
- const triggerNeedsSync = this.input.value !== nextValue;
81176
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
81177
- if (triggerNeedsSync || bibNeedsSync) {
81178
- this._syncingDisplayValue = true;
81179
- if (triggerNeedsSync) {
81180
- this.input.value = nextValue;
81181
- }
81182
- if (bibNeedsSync) {
81183
- this.inputInBib.value = nextValue;
81184
- }
81185
- const pending = [];
81186
- if (triggerNeedsSync) {
81187
- pending.push(this.input.updateComplete);
81188
- }
81189
- if (bibNeedsSync) {
81190
- pending.push(this.inputInBib.updateComplete);
81191
- }
81192
- Promise.all(pending).then(() => {
81193
- // imask reasserts otherwise, and handleBlur reverts to its stale value.
81194
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
81195
- this.input.maskInstance.updateValue();
81196
- }
81197
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
81198
- this.inputInBib.maskInstance.updateValue();
81199
- }
81200
- this._syncingDisplayValue = false;
81201
- });
81202
- }
80882
+ const suppressed = this.persistInput || (this.behavior === 'suggestion' && isInputFocusedWithNoSelection);
80883
+ if (!suppressed) {
80884
+ this.syncInputValuesAcrossTriggerAndBib(label || this.value);
81203
80885
  }
81204
80886
 
81205
80887
  // update the displayValue in the trigger if displayValue slot content is present
@@ -81227,6 +80909,48 @@ class AuroCombobox extends AuroElement$3 {
81227
80909
  this.requestUpdate();
81228
80910
  }
81229
80911
 
80912
+ /**
80913
+ * Writes nextValue to the trigger input and the bib input when their current
80914
+ * value differs, then re-asserts imask after Lit's update flushes.
80915
+ * @param {string} nextValue - The value to write to both inputs.
80916
+ * @returns {Promise<void> | null} Promise that resolves after the inputs flush,
80917
+ * or null when no sync was needed (so callers can skip post-flush work).
80918
+ * @private
80919
+ */
80920
+ syncInputValuesAcrossTriggerAndBib(nextValue) {
80921
+ // Only set the flag when there's an actual write to suppress —
80922
+ // syncValuesAndStates re-enters here during typing when both inputs
80923
+ // already match, and a no-op flag flip would make the bib branch's
80924
+ // bail eat legitimate user-input events.
80925
+ const triggerNeedsSync = this.input.value !== nextValue;
80926
+ const bibNeedsSync = this.inputInBib.value !== nextValue;
80927
+ if (!triggerNeedsSync && !bibNeedsSync) {
80928
+ return null;
80929
+ }
80930
+
80931
+ this._syncingDisplayValue = true;
80932
+
80933
+ const pending = [];
80934
+ if (triggerNeedsSync) {
80935
+ this.input.value = nextValue;
80936
+ pending.push(this.input.updateComplete);
80937
+ }
80938
+ if (bibNeedsSync) {
80939
+ this.inputInBib.value = nextValue;
80940
+ pending.push(this.inputInBib.updateComplete);
80941
+ }
80942
+ return Promise.all(pending).then(() => {
80943
+ // imask reasserts otherwise, and handleBlur reverts to its stale value.
80944
+ if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
80945
+ this.input.maskInstance.updateValue();
80946
+ }
80947
+ if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
80948
+ this.inputInBib.maskInstance.updateValue();
80949
+ }
80950
+ this._syncingDisplayValue = false;
80951
+ });
80952
+ }
80953
+
81230
80954
  /**
81231
80955
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
81232
80956
  * @private
@@ -81254,9 +80978,9 @@ class AuroCombobox extends AuroElement$3 {
81254
80978
  this.syncValuesAndStates();
81255
80979
  }
81256
80980
 
81257
- // Re-activate when optionActive is no longer visible, or when _index has
81258
- // been reset (e.g. by clearSelection in an async update) so that
81259
- // makeSelection() can find the correct option.
80981
+ // Re-activate when optionActive is not in the current scrollable viewport,
80982
+ // or when _index has been reset (e.g. by clearSelection in an async update)
80983
+ // so that makeSelection() can find the correct option.
81260
80984
  if (!this.availableOptions.includes(this.menu.optionActive) || this.menu._index < 0) {
81261
80985
  this.activateFirstEnabledAvailableOption();
81262
80986
  }
@@ -81390,28 +81114,25 @@ class AuroCombobox extends AuroElement$3 {
81390
81114
 
81391
81115
  guardTouchPassthrough$1(this.menu);
81392
81116
 
81393
- // The dialog's showModal() steals focus from the trigger.
81394
- // A single rAF is enough for the dialog DOM to be painted and
81395
- // focusable, then doubleRaf finalizes the transition.
81117
+ // showModal() takes focus away from the trigger. Early focus once
81118
+ // the dialog has painted; the shared doubleRaf below is the fallback
81119
+ // for when the dialog needs an extra frame and also clears the
81120
+ // validation guard.
81396
81121
  requestAnimationFrame(() => {
81397
81122
  this.setInputFocus();
81398
81123
  });
81399
-
81400
- doubleRaf$1(() => {
81401
- this.setInputFocus();
81402
- this._inFullscreenTransition = false;
81403
- });
81404
- } else {
81405
- // Desktop popover-open: restore the trigger caret to end-of-text.
81406
- // Clicking the trigger lands on auro-input's floating <label for="…">
81407
- // overlay; Chrome resets the native input's selection to [0, 0] on
81408
- // label-focus before any JS runs. setInputFocus()'s non-fullscreen
81409
- // branch parks the caret at end. doubleRaf lets the dropdown layout
81410
- // settle first, matching the fullscreen branch timing.
81411
- doubleRaf$1(() => {
81412
- this.setInputFocus();
81413
- });
81414
81124
  }
81125
+ // else (desktop popover-open): Chrome resets the trigger caret to
81126
+ // [0, 0] when its floating <label for="…"> overlay receives focus.
81127
+ // The shared doubleRaf below parks the caret back at end-of-text
81128
+ // after the dropdown layout settles.
81129
+
81130
+ doubleRaf$1(() => {
81131
+ this.setInputFocus();
81132
+ if (this._inFullscreenTransition) {
81133
+ this._inFullscreenTransition = false;
81134
+ }
81135
+ });
81415
81136
  }
81416
81137
  });
81417
81138
 
@@ -81516,24 +81237,7 @@ class AuroCombobox extends AuroElement$3 {
81516
81237
  nativeInput.setSelectionRange(len, len);
81517
81238
  }
81518
81239
  } else {
81519
- // Safety net for the strategy-change setTimeout: a viewport-crossing
81520
- // fullscreen→floating switch can close the dialog and leave focus on
81521
- // body. Every other Branch 2 callsite already has focus on the input
81522
- // via the focusin → this.focus() redirect (L1448-1452), so this is a
81523
- // no-op in the common case.
81524
- if (!this.input.componentHasFocus) {
81525
- this.input.focus();
81526
- }
81527
-
81528
- // Park the trigger native input's caret at end-of-text every time the
81529
- // popover opens. Chrome focuses the native via the floating <label for="…">
81530
- // overlay on click and resets selection to [0, 0]; no JS fires between
81531
- // mousedown and selectionchange, so we restore the caret here.
81532
- const triggerNativeInput = this.input.inputElement;
81533
- if (triggerNativeInput && triggerNativeInput.value) {
81534
- const len = triggerNativeInput.value.length;
81535
- triggerNativeInput.setSelectionRange(len, len);
81536
- }
81240
+ this.input.focus();
81537
81241
  }
81538
81242
  }
81539
81243
 
@@ -81639,7 +81343,7 @@ class AuroCombobox extends AuroElement$3 {
81639
81343
  if (this.menu.optionSelected) {
81640
81344
  const selected = this.menu.optionSelected;
81641
81345
 
81642
- if (!this.optionSelected || this.optionSelected !== selected) {
81346
+ if (this.optionSelected !== selected) {
81643
81347
  this.optionSelected = selected;
81644
81348
  }
81645
81349
 
@@ -81652,7 +81356,7 @@ class AuroCombobox extends AuroElement$3 {
81652
81356
  }
81653
81357
 
81654
81358
  // Update display
81655
- this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected) || this.menu.value);
81359
+ this.updateTriggerTextDisplay(getOptionLabel(this.optionSelected));
81656
81360
 
81657
81361
  // Update match word for filtering
81658
81362
  const trimmedInput = normalizeFilterValue(this.input.value);
@@ -81668,13 +81372,22 @@ class AuroCombobox extends AuroElement$3 {
81668
81372
  this.hideBib();
81669
81373
  }
81670
81374
 
81375
+ // Move focus to the clear button when the user makes a selection.
81376
+ if (!isEcho && this.menu.value !== undefined) {
81377
+ this.setClearBtnFocus();
81378
+ }
81379
+
81671
81380
  // Announce the selection after the dropdown closes so it isn't
81672
81381
  // overridden by VoiceOver's "collapsed" announcement from aria-expanded.
81382
+ // Skip when there's no selected value (e.g. menu.clearSelection() from
81383
+ // the unmatched-value path), otherwise VoiceOver reads "undefined".
81673
81384
  const selectedValue = this.menu.value;
81674
- const announcementDelay = 300;
81675
- setTimeout(() => {
81676
- announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
81677
- }, announcementDelay);
81385
+ if (selectedValue) {
81386
+ const announcementDelay = 300;
81387
+ setTimeout(() => {
81388
+ announceToScreenReader$1(this._getAnnouncementRoot(), `${selectedValue}, selected`);
81389
+ }, announcementDelay);
81390
+ }
81678
81391
  }
81679
81392
 
81680
81393
  // Programmatic value syncs leave availableOptions stale because
@@ -81688,18 +81401,6 @@ class AuroCombobox extends AuroElement$3 {
81688
81401
  this._programmaticFilterRefresh = false;
81689
81402
  }, 0);
81690
81403
  }
81691
-
81692
- // base-input skips auto-validate when focus is inside its own shadow,
81693
- // which it is after setTriggerInputFocus — re-run so prior tooShort
81694
- // clears. processCreditCard reasserts errorMessage on every render.
81695
- if (!isEcho && this.menu.optionSelected && this.input.validate) {
81696
- this.input.updateComplete.then(() => {
81697
- this.input.validate(true);
81698
- if (this.input.validity === 'valid') {
81699
- this.input.errorMessage = '';
81700
- }
81701
- });
81702
- }
81703
81404
  });
81704
81405
 
81705
81406
  this.menu.addEventListener('auroMenu-customEventFired', () => {
@@ -82034,15 +81735,7 @@ class AuroCombobox extends AuroElement$3 {
82034
81735
  this.menu.value = undefined;
82035
81736
  this.validation.reset(this);
82036
81737
  this.touched = false;
82037
- // Force validity back to the cleared state. validation.reset() calls
82038
- // validate() at the end, and (post-credit-card-fix) the trigger input's
82039
- // residual validity may still be copied into the combobox by the
82040
- // auroInputElements loop. Explicitly clear here so reset() actually
82041
- // leaves the component in a "no validity" state.
82042
81738
  this.validity = undefined;
82043
- this.errorMessage = '';
82044
- this.input.validity = undefined;
82045
- this.input.errorMessage = '';
82046
81739
  }
82047
81740
 
82048
81741
  /**
@@ -82095,52 +81788,27 @@ class AuroCombobox extends AuroElement$3 {
82095
81788
  this.input.value = this.value;
82096
81789
  }
82097
81790
 
82098
- // Sync menu.value only when an option actually matches; otherwise clear it.
81791
+ // Sync menu.value only when an option actually matches, or when filter
81792
+ // mode needs setMenuValue to dispatch auroMenu-selectValueFailure (the
81793
+ // listener at line 1206 clears combobox.value, mirroring select's
81794
+ // pattern). Otherwise sync the input display for freeform values.
82099
81795
  if (this.menu.options && this.menu.options.length > 0) {
82100
- if (this.menu.options.some((opt) => opt.value === this.value)) {
82101
- this.setMenuValue(this.value);
82102
- } else if (this.behavior === 'filter') {
82103
- // In filter mode, freeform values aren't allowed. Push the unmatched
82104
- // value through setMenuValue so menu dispatches auroMenu-selectValueFailure
82105
- // and the listener at line 1206 clears combobox.value (mirrors select's
82106
- // pattern). Bypassing setMenuValue here would skip the failure cascade.
81796
+ if (this.menu.options.some((opt) => opt.value === this.value) || this.behavior === 'filter') {
82107
81797
  this.setMenuValue(this.value);
82108
81798
  } else {
82109
- if (this.menu.value) {
82110
- this.menu.value = undefined;
81799
+ // Clear menu.value AND menu.optionSelected together. Clearing only
81800
+ // menu.value leaves the previously-selected option element pinned
81801
+ // as menu.optionSelected; a later auroMenu-selectedOption event
81802
+ // would then write its stale .value back into combobox.value.
81803
+ if (this.menu.value || this.menu.optionSelected) {
81804
+ this.menu.clearSelection();
82111
81805
  }
82112
- // Sync the display for programmatic freeform value changes (e.g. the
82113
- // swap-values pattern). Guard with _syncingDisplayValue so that the
82114
- // re-entrant input event from base-input.notifyValueChanged() is
82115
- // ignored by handleInputValueChange. Skip the sync when input already
82116
- // matches to avoid spurious events during the normal typing path.
82117
- const nextValue = this.value || '';
82118
- const triggerNeedsSync = this.input.value !== nextValue;
82119
- const bibNeedsSync = Boolean(this.inputInBib && this.inputInBib !== this.input && this.inputInBib.value !== nextValue);
82120
- if (triggerNeedsSync || bibNeedsSync) {
82121
- this._syncingDisplayValue = true;
82122
- if (triggerNeedsSync) {
82123
- this.input.value = nextValue;
82124
- }
82125
- if (bibNeedsSync) {
82126
- this.inputInBib.value = nextValue;
82127
- }
82128
- const pending = [];
82129
- if (triggerNeedsSync) {
82130
- pending.push(this.input.updateComplete);
82131
- }
82132
- if (bibNeedsSync) {
82133
- pending.push(this.inputInBib.updateComplete);
82134
- }
82135
- Promise.all(pending).then(() => {
82136
- if (triggerNeedsSync && this.input.maskInstance && typeof this.input.maskInstance.updateValue === 'function') {
82137
- this.input.maskInstance.updateValue();
82138
- }
82139
- if (bibNeedsSync && this.inputInBib && this.inputInBib.maskInstance && typeof this.inputInBib.maskInstance.updateValue === 'function') {
82140
- this.inputInBib.maskInstance.updateValue();
82141
- }
82142
- this._syncingDisplayValue = false;
82143
- // handleInputValueChange bailed on the flag — refresh the filter.
81806
+ // Suggestion-mode freeform value: sync the trigger + bib to show it,
81807
+ // then refresh the filter once the inputs flush (handleInputValueChange
81808
+ // bailed on _syncingDisplayValue).
81809
+ const syncPromise = this.syncInputValuesAcrossTriggerAndBib(this.value || '');
81810
+ if (syncPromise) {
81811
+ syncPromise.then(() => {
82144
81812
  this._programmaticFilterRefresh = true;
82145
81813
  this.handleMenuOptions();
82146
81814
  setTimeout(() => {
@@ -88973,7 +88641,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
88973
88641
  }
88974
88642
  };
88975
88643
 
88976
- var formkitVersion$1 = '202606192121';
88644
+ var formkitVersion$1 = '202606231948';
88977
88645
 
88978
88646
  class AuroElement extends i$2 {
88979
88647
  static get properties() {
@@ -89924,6 +89592,14 @@ class AuroDropdown extends AuroElement {
89924
89592
  };
89925
89593
  this.addEventListener('keydown', this._bibTabHandler);
89926
89594
 
89595
+ // Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
89596
+ // desktopModal trap owns focus management. Without this, the very
89597
+ // first focus move into the bib (from the RAF below) triggers
89598
+ // handleFocusLoss → hideBib, tearing down the trap before the
89599
+ // user can press Tab.
89600
+ this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
89601
+ this.noHideOnThisFocusLoss = true;
89602
+
89927
89603
  // Move initial focus into the bib content, matching FocusTrap behavior
89928
89604
  requestAnimationFrame(() => {
89929
89605
  const focusables = getFocusableElements(this.bibContent);
@@ -90986,7 +90662,7 @@ class AuroHelpText extends i$2 {
90986
90662
  }
90987
90663
  }
90988
90664
 
90989
- var formkitVersion = '202606192121';
90665
+ var formkitVersion = '202606231948';
90990
90666
 
90991
90667
  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}`;
90992
90668