@aurodesignsystem-dev/auro-formkit 0.0.0-pr1532.1 → 0.0.0-pr1534.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/components/checkbox/demo/customize.min.js +1 -1
  2. package/components/checkbox/demo/getting-started.min.js +1 -1
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/customize.min.js +118 -50
  7. package/components/combobox/demo/getting-started.min.js +118 -50
  8. package/components/combobox/demo/index.min.js +118 -50
  9. package/components/combobox/dist/auro-combobox.d.ts +10 -0
  10. package/components/combobox/dist/index.js +118 -50
  11. package/components/combobox/dist/registered.js +118 -50
  12. package/components/counter/demo/customize.min.js +2 -2
  13. package/components/counter/demo/index.min.js +2 -2
  14. package/components/counter/dist/index.js +2 -2
  15. package/components/counter/dist/registered.js +2 -2
  16. package/components/datepicker/demo/accessibility.md +17 -8
  17. package/components/datepicker/demo/api.md +1 -1
  18. package/components/datepicker/demo/customize.min.js +229 -72
  19. package/components/datepicker/demo/index.min.js +229 -72
  20. package/components/datepicker/demo/keyboard-behavior.md +3 -3
  21. package/components/datepicker/demo/voiceover.md +4 -4
  22. package/components/datepicker/demo/why-datepicker.md +2 -2
  23. package/components/datepicker/dist/auro-calendar-cell.d.ts +11 -0
  24. package/components/datepicker/dist/auro-calendar.d.ts +26 -2
  25. package/components/datepicker/dist/auro-datepicker.d.ts +9 -1
  26. package/components/datepicker/dist/index.js +229 -72
  27. package/components/datepicker/dist/registered.js +229 -72
  28. package/components/dropdown/demo/customize.min.js +1 -1
  29. package/components/dropdown/demo/getting-started.min.js +1 -1
  30. package/components/dropdown/demo/index.min.js +1 -1
  31. package/components/dropdown/dist/index.js +1 -1
  32. package/components/dropdown/dist/registered.js +1 -1
  33. package/components/form/demo/customize.min.js +408 -172
  34. package/components/form/demo/getting-started.min.js +408 -172
  35. package/components/form/demo/index.min.js +408 -172
  36. package/components/form/demo/registerDemoDeps.min.js +408 -172
  37. package/components/input/demo/customize.min.js +56 -45
  38. package/components/input/demo/getting-started.min.js +56 -45
  39. package/components/input/demo/index.min.js +56 -45
  40. package/components/input/dist/base-input.d.ts +20 -4
  41. package/components/input/dist/index.js +56 -45
  42. package/components/input/dist/registered.js +56 -45
  43. package/components/radio/demo/customize.min.js +1 -1
  44. package/components/radio/demo/getting-started.min.js +1 -1
  45. package/components/radio/demo/index.min.js +1 -1
  46. package/components/radio/dist/index.js +1 -1
  47. package/components/radio/dist/registered.js +1 -1
  48. package/components/select/demo/customize.min.js +2 -2
  49. package/components/select/demo/getting-started.min.js +2 -2
  50. package/components/select/demo/index.min.js +2 -2
  51. package/components/select/dist/index.js +2 -2
  52. package/components/select/dist/registered.js +2 -2
  53. package/custom-elements.json +4349 -4251
  54. package/package.json +1 -1
@@ -1275,7 +1275,7 @@ class AuroHelpText extends i$2 {
1275
1275
  }
1276
1276
  }
1277
1277
 
1278
- var formkitVersion = '202607022050';
1278
+ var formkitVersion = '202607061916';
1279
1279
 
1280
1280
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1281
1281
  // See LICENSE in the project root for license information.
@@ -1275,7 +1275,7 @@ class AuroHelpText extends i$2 {
1275
1275
  }
1276
1276
  }
1277
1277
 
1278
- var formkitVersion = '202607022050';
1278
+ var formkitVersion = '202607061916';
1279
1279
 
1280
1280
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1281
1281
  // See LICENSE in the project root for license information.
@@ -1275,7 +1275,7 @@ class AuroHelpText extends i$2 {
1275
1275
  }
1276
1276
  }
1277
1277
 
1278
- var formkitVersion = '202607022050';
1278
+ var formkitVersion = '202607061916';
1279
1279
 
1280
1280
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1281
1281
  // See LICENSE in the project root for license information.
@@ -1228,7 +1228,7 @@ class AuroHelpText extends LitElement {
1228
1228
  }
1229
1229
  }
1230
1230
 
1231
- var formkitVersion = '202607022050';
1231
+ var formkitVersion = '202607061916';
1232
1232
 
1233
1233
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1234
1234
  // See LICENSE in the project root for license information.
@@ -1228,7 +1228,7 @@ class AuroHelpText extends LitElement {
1228
1228
  }
1229
1229
  }
1230
1230
 
1231
- var formkitVersion = '202607022050';
1231
+ var formkitVersion = '202607061916';
1232
1232
 
1233
1233
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1234
1234
  // See LICENSE in the project root for license information.
@@ -4879,7 +4879,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
4879
4879
  }
4880
4880
  };
4881
4881
 
4882
- var formkitVersion$2 = '202607022050';
4882
+ var formkitVersion$2 = '202607061916';
4883
4883
 
4884
4884
  let AuroElement$2 = class AuroElement extends i$3 {
4885
4885
  static get properties() {
@@ -16894,14 +16894,16 @@ class BaseInput extends AuroElement$1 {
16894
16894
  this.label = 'Input label is undefined';
16895
16895
  this.layout = 'classic';
16896
16896
  this.locale = 'en-US';
16897
+ this._format = undefined;
16898
+
16899
+ /** @private */
16900
+ this._userSetFormat = false;
16897
16901
  this.max = undefined;
16898
16902
  this.maxLength = undefined;
16899
16903
  this.min = undefined;
16900
16904
  this.minLength = undefined;
16901
16905
  this.noValidate = false;
16902
16906
  this.onDark = false;
16903
- // Raw values returned from the input mask before model normalization.
16904
- this._rawMaskValue = undefined;
16905
16907
  this.required = false;
16906
16908
  this.setCustomValidityForType = undefined;
16907
16909
  // Credit Card is intentionally excluded — its mask manages the cursor
@@ -17059,7 +17061,8 @@ class BaseInput extends AuroElement$1 {
17059
17061
  */
17060
17062
  format: {
17061
17063
  type: String,
17062
- reflect: true
17064
+ reflect: true,
17065
+ noAccessor: true
17063
17066
  },
17064
17067
 
17065
17068
  /**
@@ -17397,6 +17400,34 @@ class BaseInput extends AuroElement$1 {
17397
17400
  return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
17398
17401
  }
17399
17402
 
17403
+ get format() {
17404
+ return this._format;
17405
+ }
17406
+
17407
+ /**
17408
+ * Overrides LitElement's generated accessor so we can track whether the
17409
+ * consumer explicitly set `format`. Locale-derived updates use
17410
+ * `_setFormatFromLocale` instead, which skips this flag.
17411
+ */
17412
+ set format(value) {
17413
+ const oldValue = this._format;
17414
+ this._format = value ? value.toLowerCase() : value;
17415
+ this._userSetFormat = Boolean(value);
17416
+ this.requestUpdate('format', oldValue);
17417
+ }
17418
+
17419
+ /**
17420
+ * Sets format without marking it as user-set. Used by locale auto-derive
17421
+ * so that a subsequent locale change can still update the format.
17422
+ * @private
17423
+ * @param {string} value
17424
+ */
17425
+ _setFormatFromLocale(value) {
17426
+ const oldValue = this._format;
17427
+ this._format = value ? value.toLowerCase() : value;
17428
+ this.requestUpdate('format', oldValue);
17429
+ }
17430
+
17400
17431
  connectedCallback() {
17401
17432
  super.connectedCallback();
17402
17433
 
@@ -17444,15 +17475,6 @@ class BaseInput extends AuroElement$1 {
17444
17475
 
17445
17476
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
17446
17477
 
17447
- // Normalize the format token to lowercase so case-mixed values supplied
17448
- // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
17449
- // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
17450
- // format silently misses the map and leaves `setCustomValidityForType`
17451
- // unset.
17452
- if (this.format) {
17453
- this.format = this.format.toLowerCase();
17454
- }
17455
-
17456
17478
  // use validity message override if declared when initializing the component
17457
17479
  if (this.hasAttribute('setCustomValidity')) {
17458
17480
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -17559,12 +17581,10 @@ class BaseInput extends AuroElement$1 {
17559
17581
  updated(changedProperties) {
17560
17582
  super.updated(changedProperties);
17561
17583
 
17562
- // When locale changes without an explicit format override, derive format from the new locale.
17563
- // Only runs if the current format is still the previous locale's default (not user-overridden).
17584
+ // When locale changes, auto-derive format unless the consumer explicitly set one.
17564
17585
  if (changedProperties.has('locale') && !changedProperties.has('format') && this.type === 'date') {
17565
- const previousLocaleFormat = getDateFormatFromLocale(changedProperties.get('locale'));
17566
- if (!this.format || this.format.toLowerCase() === previousLocaleFormat) {
17567
- this.format = getDateFormatFromLocale(this.locale);
17586
+ if (!this._userSetFormat) {
17587
+ this._setFormatFromLocale(getDateFormatFromLocale(this.locale));
17568
17588
  }
17569
17589
  }
17570
17590
 
@@ -17735,9 +17755,6 @@ class BaseInput extends AuroElement$1 {
17735
17755
  this.maskInstance.on('accept', () => {
17736
17756
  if (this._configuringMask) return;
17737
17757
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17738
- if (this.type === "date") {
17739
- this._rawMaskValue = this.maskInstance.value;
17740
- }
17741
17758
  });
17742
17759
 
17743
17760
  // Mask fires 'complete' on the restore step below for any value that
@@ -17745,9 +17762,6 @@ class BaseInput extends AuroElement$1 {
17745
17762
  this.maskInstance.on('complete', () => {
17746
17763
  if (this._configuringMask) return;
17747
17764
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17748
- if (this.type === "date") {
17749
- this._rawMaskValue = this.maskInstance.value;
17750
- }
17751
17765
  });
17752
17766
 
17753
17767
  // Write existingValue through the mask (not the input directly) so
@@ -17768,14 +17782,17 @@ class BaseInput extends AuroElement$1 {
17768
17782
  * @returns {void}
17769
17783
  */
17770
17784
  notifyValueChanged() {
17771
- let inputEvent = null;
17772
-
17773
- inputEvent = new Event('input', {
17785
+ // This echoes Lit's reactive value update (and handleClickClear's
17786
+ // programmatic clear) — it is NOT a fresh user-input event. Mark it
17787
+ // `isProgrammatic` so consumers (e.g. auro-combobox) can distinguish
17788
+ // it from genuine user typing and skip clobbering their own
17789
+ // programmatic state during init-time renders.
17790
+ const inputEvent = new Event('input', {
17774
17791
  bubbles: true,
17775
17792
  composed: true,
17776
17793
  });
17794
+ inputEvent.isProgrammatic = true;
17777
17795
 
17778
- // Dispatched event to alert outside shadow DOM context of event firing.
17779
17796
  this.dispatchEvent(inputEvent);
17780
17797
  }
17781
17798
 
@@ -17984,8 +18001,7 @@ class BaseInput extends AuroElement$1 {
17984
18001
 
17985
18002
  // Set default date format if type=date and no format is defined
17986
18003
  if (this.type === "date" && !this.format) {
17987
- // Use locale to determine default date format
17988
- this.format = this.util.getDateMaskFromLocale().toLowerCase();
18004
+ this._setFormatFromLocale(this.util.getDateMaskFromLocale().toLowerCase());
17989
18005
  this.util.updateFormat(this.format);
17990
18006
  }
17991
18007
  }
@@ -18014,7 +18030,7 @@ class BaseInput extends AuroElement$1 {
18014
18030
  const creditCard = this.matchInputValueToCreditCard();
18015
18031
  const previousFormat = this.format;
18016
18032
 
18017
- this.format = creditCard.maskFormat;
18033
+ this._setFormatFromLocale(creditCard.maskFormat);
18018
18034
 
18019
18035
  this.maxLength = creditCard.formatLength;
18020
18036
  this.minLength = creditCard.formatMinLength;
@@ -18488,7 +18504,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
18488
18504
  }
18489
18505
  };
18490
18506
 
18491
- var formkitVersion$1 = '202607022050';
18507
+ var formkitVersion$1 = '202607061916';
18492
18508
 
18493
18509
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18494
18510
  // See LICENSE in the project root for license information.
@@ -18774,20 +18790,15 @@ class AuroInput extends BaseInput {
18774
18790
  * @returns {void}
18775
18791
  */
18776
18792
  checkDisplayValueSlotChange() {
18777
- let nodes = this.shadowRoot.querySelector('slot[name="displayValue"]').assignedNodes();
18778
-
18779
- // Handle when DisplayValue is multi-level slot content (e.g. combobox passing displayValue to input)
18780
- if (nodes && nodes[0] && nodes[0].tagName === 'SLOT') {
18781
- nodes = nodes[0].assignedNodes();
18782
- }
18783
-
18784
- let hasContent = false;
18793
+ // flatten:true resolves through auro-combobox's forwarding slot
18794
+ // (<slot name="displayValue" slot="displayValue">) so a clone appended
18795
+ // directly to auro-input's light DOM alongside the forwarder still
18796
+ // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18797
+ // discarded any siblings past the forwarder.
18798
+ const slot = this.shadowRoot.querySelector('slot[name="displayValue"]');
18799
+ const nodes = slot.assignedNodes({ flatten: true });
18785
18800
 
18786
- if (nodes.length > 0) {
18787
- hasContent = true;
18788
- }
18789
-
18790
- this.hasDisplayValueContent = hasContent;
18801
+ this.hasDisplayValueContent = nodes.length > 0;
18791
18802
  }
18792
18803
 
18793
18804
  firstUpdated() {
@@ -19614,7 +19625,7 @@ class AuroBibtemplate extends i$3 {
19614
19625
  }
19615
19626
  }
19616
19627
 
19617
- var formkitVersion = '202607022050';
19628
+ var formkitVersion = '202607061916';
19618
19629
 
19619
19630
  var styleCss$3 = i$6`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
19620
19631
 
@@ -20713,9 +20724,19 @@ class AuroCombobox extends AuroElement {
20713
20724
  /**
20714
20725
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
20715
20726
  * @private
20727
+ * @param {object} [options={}] - Optional flag bag.
20728
+ * @param {boolean} [options.preferComboboxValue=false] - When true,
20729
+ * handleMenuOptions matches the selected option against `this.value`
20730
+ * first instead of `this.input.value`. Needed on mount and re-mount
20731
+ * because under `persistInput` the consumer's typedValue prop can drift
20732
+ * from the framework value (Svelte `{#key}` re-mount after a swap, or
20733
+ * SPA preselect after route change) and the old input-first match would
20734
+ * then pick the stale text. Only handleSlotChange passes this; typing
20735
+ * and clearing paths keep the input-first match so user clears aren't
20736
+ * undone.
20716
20737
  * @returns {void}
20717
20738
  */
20718
- handleMenuOptions() {
20739
+ handleMenuOptions({ preferComboboxValue = false } = {}) {
20719
20740
  this.generateOptionsArray();
20720
20741
  this.availableOptions = [];
20721
20742
  // Single source of truth for the menu's filter/highlight token per call.
@@ -20736,7 +20757,20 @@ class AuroCombobox extends AuroElement {
20736
20757
  option.setAttribute('aria-posinset', index + 1);
20737
20758
  });
20738
20759
 
20739
- if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
20760
+ // On mount/re-mount (via handleSlotChange), prefer the framework-set
20761
+ // `this.value` when it matches a menu option. Covers SPA preselect and
20762
+ // consumer swap patterns (e.g. Svelte `{#key}` re-mount) where
20763
+ // `this.value` is authoritative but `this.input.value` may be empty or
20764
+ // carry stale typed text from another field. Event-driven callers do
20765
+ // not pass the flag, otherwise user clears would be undone by
20766
+ // re-syncing to the previous combobox.value.
20767
+ if (preferComboboxValue &&
20768
+ this.value &&
20769
+ this.menu.options?.some((opt) => opt.value === this.value)) {
20770
+ this.setMenuValue(this.value);
20771
+ this.syncValuesAndStates();
20772
+ } else if (this.input.value &&
20773
+ this.menu.options?.some((opt) => opt.value === this.input.value)) {
20740
20774
  this.setMenuValue(this.input.value);
20741
20775
  this.syncValuesAndStates();
20742
20776
  }
@@ -21173,7 +21207,25 @@ class AuroCombobox extends AuroElement {
21173
21207
  this.optionActive = evt.detail;
21174
21208
 
21175
21209
  if (this.input) {
21176
- this.input.setActiveDescendant(this.optionActive);
21210
+ // setActiveDescendant runs after Lit's update finishes because the
21211
+ // template's `.a11yActivedescendant` binding calls setAttribute on
21212
+ // the internal <input> in auro-input.updated(), which clears the
21213
+ // reflected ariaActiveDescendantElement property. Setting the ref
21214
+ // synchronously here would get overwritten by that attribute write.
21215
+ // Awaiting updateComplete lets the attribute write finish first,
21216
+ // then the ref sticks and screen readers can cross the shadow-DOM
21217
+ // boundary to the auro-menuoption in light DOM.
21218
+ //
21219
+ // The equality check covers the async gap: this.optionActive can
21220
+ // change before the callback runs (user arrowed elsewhere, or the
21221
+ // menu closed and cleared it to null), so we bail if the target
21222
+ // no longer matches to avoid reinstating a stale ref.
21223
+ const targetOption = this.optionActive;
21224
+ this.updateComplete.then(() => {
21225
+ if (this.input && this.optionActive === targetOption) {
21226
+ this.input.setActiveDescendant(targetOption);
21227
+ }
21228
+ });
21177
21229
  }
21178
21230
 
21179
21231
  // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
@@ -21310,6 +21362,18 @@ class AuroCombobox extends AuroElement {
21310
21362
  }
21311
21363
  }
21312
21364
 
21365
+ // SPA preselect guard: on init render, auro-input's notifyValueChanged
21366
+ // echoes an empty value through as an isProgrammatic input event before
21367
+ // the framework-set combobox.value has propagated down to the input.
21368
+ // Without this bail, the `this.value = this.input.value` below clobbers
21369
+ // the framework value with '' and clear() wipes optionSelected. Scoped
21370
+ // to the exact shape of that echo (isProgrammatic + non-empty combobox
21371
+ // value + empty input.value) so it doesn't affect the swap/typed paths
21372
+ // where value/input already track each other through the sync helpers.
21373
+ if (event && event.isProgrammatic && this.value && !this.input.value) {
21374
+ return;
21375
+ }
21376
+
21313
21377
  this.value = this.input.value;
21314
21378
 
21315
21379
  // Ignore re-entrant input events caused by programmatic value sets.
@@ -21742,7 +21806,11 @@ class AuroCombobox extends AuroElement {
21742
21806
  }
21743
21807
  });
21744
21808
 
21745
- this.handleMenuOptions();
21809
+ // Slot change (mount/re-mount): pass `preferComboboxValue` so that a
21810
+ // framework-set `this.value` wins over any stale `input.value` when
21811
+ // matching against the newly-available options. Fixes the display
21812
+ // for SPA preselect and Svelte `{#key}` re-mount swap patterns.
21813
+ this.handleMenuOptions({ preferComboboxValue: true });
21746
21814
 
21747
21815
  break;
21748
21816
 
@@ -4879,7 +4879,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
4879
4879
  }
4880
4880
  };
4881
4881
 
4882
- var formkitVersion$2 = '202607022050';
4882
+ var formkitVersion$2 = '202607061916';
4883
4883
 
4884
4884
  let AuroElement$2 = class AuroElement extends i$3 {
4885
4885
  static get properties() {
@@ -16894,14 +16894,16 @@ class BaseInput extends AuroElement$1 {
16894
16894
  this.label = 'Input label is undefined';
16895
16895
  this.layout = 'classic';
16896
16896
  this.locale = 'en-US';
16897
+ this._format = undefined;
16898
+
16899
+ /** @private */
16900
+ this._userSetFormat = false;
16897
16901
  this.max = undefined;
16898
16902
  this.maxLength = undefined;
16899
16903
  this.min = undefined;
16900
16904
  this.minLength = undefined;
16901
16905
  this.noValidate = false;
16902
16906
  this.onDark = false;
16903
- // Raw values returned from the input mask before model normalization.
16904
- this._rawMaskValue = undefined;
16905
16907
  this.required = false;
16906
16908
  this.setCustomValidityForType = undefined;
16907
16909
  // Credit Card is intentionally excluded — its mask manages the cursor
@@ -17059,7 +17061,8 @@ class BaseInput extends AuroElement$1 {
17059
17061
  */
17060
17062
  format: {
17061
17063
  type: String,
17062
- reflect: true
17064
+ reflect: true,
17065
+ noAccessor: true
17063
17066
  },
17064
17067
 
17065
17068
  /**
@@ -17397,6 +17400,34 @@ class BaseInput extends AuroElement$1 {
17397
17400
  return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
17398
17401
  }
17399
17402
 
17403
+ get format() {
17404
+ return this._format;
17405
+ }
17406
+
17407
+ /**
17408
+ * Overrides LitElement's generated accessor so we can track whether the
17409
+ * consumer explicitly set `format`. Locale-derived updates use
17410
+ * `_setFormatFromLocale` instead, which skips this flag.
17411
+ */
17412
+ set format(value) {
17413
+ const oldValue = this._format;
17414
+ this._format = value ? value.toLowerCase() : value;
17415
+ this._userSetFormat = Boolean(value);
17416
+ this.requestUpdate('format', oldValue);
17417
+ }
17418
+
17419
+ /**
17420
+ * Sets format without marking it as user-set. Used by locale auto-derive
17421
+ * so that a subsequent locale change can still update the format.
17422
+ * @private
17423
+ * @param {string} value
17424
+ */
17425
+ _setFormatFromLocale(value) {
17426
+ const oldValue = this._format;
17427
+ this._format = value ? value.toLowerCase() : value;
17428
+ this.requestUpdate('format', oldValue);
17429
+ }
17430
+
17400
17431
  connectedCallback() {
17401
17432
  super.connectedCallback();
17402
17433
 
@@ -17444,15 +17475,6 @@ class BaseInput extends AuroElement$1 {
17444
17475
 
17445
17476
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
17446
17477
 
17447
- // Normalize the format token to lowercase so case-mixed values supplied
17448
- // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
17449
- // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
17450
- // format silently misses the map and leaves `setCustomValidityForType`
17451
- // unset.
17452
- if (this.format) {
17453
- this.format = this.format.toLowerCase();
17454
- }
17455
-
17456
17478
  // use validity message override if declared when initializing the component
17457
17479
  if (this.hasAttribute('setCustomValidity')) {
17458
17480
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -17559,12 +17581,10 @@ class BaseInput extends AuroElement$1 {
17559
17581
  updated(changedProperties) {
17560
17582
  super.updated(changedProperties);
17561
17583
 
17562
- // When locale changes without an explicit format override, derive format from the new locale.
17563
- // Only runs if the current format is still the previous locale's default (not user-overridden).
17584
+ // When locale changes, auto-derive format unless the consumer explicitly set one.
17564
17585
  if (changedProperties.has('locale') && !changedProperties.has('format') && this.type === 'date') {
17565
- const previousLocaleFormat = getDateFormatFromLocale(changedProperties.get('locale'));
17566
- if (!this.format || this.format.toLowerCase() === previousLocaleFormat) {
17567
- this.format = getDateFormatFromLocale(this.locale);
17586
+ if (!this._userSetFormat) {
17587
+ this._setFormatFromLocale(getDateFormatFromLocale(this.locale));
17568
17588
  }
17569
17589
  }
17570
17590
 
@@ -17735,9 +17755,6 @@ class BaseInput extends AuroElement$1 {
17735
17755
  this.maskInstance.on('accept', () => {
17736
17756
  if (this._configuringMask) return;
17737
17757
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17738
- if (this.type === "date") {
17739
- this._rawMaskValue = this.maskInstance.value;
17740
- }
17741
17758
  });
17742
17759
 
17743
17760
  // Mask fires 'complete' on the restore step below for any value that
@@ -17745,9 +17762,6 @@ class BaseInput extends AuroElement$1 {
17745
17762
  this.maskInstance.on('complete', () => {
17746
17763
  if (this._configuringMask) return;
17747
17764
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17748
- if (this.type === "date") {
17749
- this._rawMaskValue = this.maskInstance.value;
17750
- }
17751
17765
  });
17752
17766
 
17753
17767
  // Write existingValue through the mask (not the input directly) so
@@ -17768,14 +17782,17 @@ class BaseInput extends AuroElement$1 {
17768
17782
  * @returns {void}
17769
17783
  */
17770
17784
  notifyValueChanged() {
17771
- let inputEvent = null;
17772
-
17773
- inputEvent = new Event('input', {
17785
+ // This echoes Lit's reactive value update (and handleClickClear's
17786
+ // programmatic clear) — it is NOT a fresh user-input event. Mark it
17787
+ // `isProgrammatic` so consumers (e.g. auro-combobox) can distinguish
17788
+ // it from genuine user typing and skip clobbering their own
17789
+ // programmatic state during init-time renders.
17790
+ const inputEvent = new Event('input', {
17774
17791
  bubbles: true,
17775
17792
  composed: true,
17776
17793
  });
17794
+ inputEvent.isProgrammatic = true;
17777
17795
 
17778
- // Dispatched event to alert outside shadow DOM context of event firing.
17779
17796
  this.dispatchEvent(inputEvent);
17780
17797
  }
17781
17798
 
@@ -17984,8 +18001,7 @@ class BaseInput extends AuroElement$1 {
17984
18001
 
17985
18002
  // Set default date format if type=date and no format is defined
17986
18003
  if (this.type === "date" && !this.format) {
17987
- // Use locale to determine default date format
17988
- this.format = this.util.getDateMaskFromLocale().toLowerCase();
18004
+ this._setFormatFromLocale(this.util.getDateMaskFromLocale().toLowerCase());
17989
18005
  this.util.updateFormat(this.format);
17990
18006
  }
17991
18007
  }
@@ -18014,7 +18030,7 @@ class BaseInput extends AuroElement$1 {
18014
18030
  const creditCard = this.matchInputValueToCreditCard();
18015
18031
  const previousFormat = this.format;
18016
18032
 
18017
- this.format = creditCard.maskFormat;
18033
+ this._setFormatFromLocale(creditCard.maskFormat);
18018
18034
 
18019
18035
  this.maxLength = creditCard.formatLength;
18020
18036
  this.minLength = creditCard.formatMinLength;
@@ -18488,7 +18504,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
18488
18504
  }
18489
18505
  };
18490
18506
 
18491
- var formkitVersion$1 = '202607022050';
18507
+ var formkitVersion$1 = '202607061916';
18492
18508
 
18493
18509
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18494
18510
  // See LICENSE in the project root for license information.
@@ -18774,20 +18790,15 @@ class AuroInput extends BaseInput {
18774
18790
  * @returns {void}
18775
18791
  */
18776
18792
  checkDisplayValueSlotChange() {
18777
- let nodes = this.shadowRoot.querySelector('slot[name="displayValue"]').assignedNodes();
18778
-
18779
- // Handle when DisplayValue is multi-level slot content (e.g. combobox passing displayValue to input)
18780
- if (nodes && nodes[0] && nodes[0].tagName === 'SLOT') {
18781
- nodes = nodes[0].assignedNodes();
18782
- }
18783
-
18784
- let hasContent = false;
18793
+ // flatten:true resolves through auro-combobox's forwarding slot
18794
+ // (<slot name="displayValue" slot="displayValue">) so a clone appended
18795
+ // directly to auro-input's light DOM alongside the forwarder still
18796
+ // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18797
+ // discarded any siblings past the forwarder.
18798
+ const slot = this.shadowRoot.querySelector('slot[name="displayValue"]');
18799
+ const nodes = slot.assignedNodes({ flatten: true });
18785
18800
 
18786
- if (nodes.length > 0) {
18787
- hasContent = true;
18788
- }
18789
-
18790
- this.hasDisplayValueContent = hasContent;
18801
+ this.hasDisplayValueContent = nodes.length > 0;
18791
18802
  }
18792
18803
 
18793
18804
  firstUpdated() {
@@ -19614,7 +19625,7 @@ class AuroBibtemplate extends i$3 {
19614
19625
  }
19615
19626
  }
19616
19627
 
19617
- var formkitVersion = '202607022050';
19628
+ var formkitVersion = '202607061916';
19618
19629
 
19619
19630
  var styleCss$3 = i$6`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
19620
19631
 
@@ -20713,9 +20724,19 @@ class AuroCombobox extends AuroElement {
20713
20724
  /**
20714
20725
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
20715
20726
  * @private
20727
+ * @param {object} [options={}] - Optional flag bag.
20728
+ * @param {boolean} [options.preferComboboxValue=false] - When true,
20729
+ * handleMenuOptions matches the selected option against `this.value`
20730
+ * first instead of `this.input.value`. Needed on mount and re-mount
20731
+ * because under `persistInput` the consumer's typedValue prop can drift
20732
+ * from the framework value (Svelte `{#key}` re-mount after a swap, or
20733
+ * SPA preselect after route change) and the old input-first match would
20734
+ * then pick the stale text. Only handleSlotChange passes this; typing
20735
+ * and clearing paths keep the input-first match so user clears aren't
20736
+ * undone.
20716
20737
  * @returns {void}
20717
20738
  */
20718
- handleMenuOptions() {
20739
+ handleMenuOptions({ preferComboboxValue = false } = {}) {
20719
20740
  this.generateOptionsArray();
20720
20741
  this.availableOptions = [];
20721
20742
  // Single source of truth for the menu's filter/highlight token per call.
@@ -20736,7 +20757,20 @@ class AuroCombobox extends AuroElement {
20736
20757
  option.setAttribute('aria-posinset', index + 1);
20737
20758
  });
20738
20759
 
20739
- if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
20760
+ // On mount/re-mount (via handleSlotChange), prefer the framework-set
20761
+ // `this.value` when it matches a menu option. Covers SPA preselect and
20762
+ // consumer swap patterns (e.g. Svelte `{#key}` re-mount) where
20763
+ // `this.value` is authoritative but `this.input.value` may be empty or
20764
+ // carry stale typed text from another field. Event-driven callers do
20765
+ // not pass the flag, otherwise user clears would be undone by
20766
+ // re-syncing to the previous combobox.value.
20767
+ if (preferComboboxValue &&
20768
+ this.value &&
20769
+ this.menu.options?.some((opt) => opt.value === this.value)) {
20770
+ this.setMenuValue(this.value);
20771
+ this.syncValuesAndStates();
20772
+ } else if (this.input.value &&
20773
+ this.menu.options?.some((opt) => opt.value === this.input.value)) {
20740
20774
  this.setMenuValue(this.input.value);
20741
20775
  this.syncValuesAndStates();
20742
20776
  }
@@ -21173,7 +21207,25 @@ class AuroCombobox extends AuroElement {
21173
21207
  this.optionActive = evt.detail;
21174
21208
 
21175
21209
  if (this.input) {
21176
- this.input.setActiveDescendant(this.optionActive);
21210
+ // setActiveDescendant runs after Lit's update finishes because the
21211
+ // template's `.a11yActivedescendant` binding calls setAttribute on
21212
+ // the internal <input> in auro-input.updated(), which clears the
21213
+ // reflected ariaActiveDescendantElement property. Setting the ref
21214
+ // synchronously here would get overwritten by that attribute write.
21215
+ // Awaiting updateComplete lets the attribute write finish first,
21216
+ // then the ref sticks and screen readers can cross the shadow-DOM
21217
+ // boundary to the auro-menuoption in light DOM.
21218
+ //
21219
+ // The equality check covers the async gap: this.optionActive can
21220
+ // change before the callback runs (user arrowed elsewhere, or the
21221
+ // menu closed and cleared it to null), so we bail if the target
21222
+ // no longer matches to avoid reinstating a stale ref.
21223
+ const targetOption = this.optionActive;
21224
+ this.updateComplete.then(() => {
21225
+ if (this.input && this.optionActive === targetOption) {
21226
+ this.input.setActiveDescendant(targetOption);
21227
+ }
21228
+ });
21177
21229
  }
21178
21230
 
21179
21231
  // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
@@ -21310,6 +21362,18 @@ class AuroCombobox extends AuroElement {
21310
21362
  }
21311
21363
  }
21312
21364
 
21365
+ // SPA preselect guard: on init render, auro-input's notifyValueChanged
21366
+ // echoes an empty value through as an isProgrammatic input event before
21367
+ // the framework-set combobox.value has propagated down to the input.
21368
+ // Without this bail, the `this.value = this.input.value` below clobbers
21369
+ // the framework value with '' and clear() wipes optionSelected. Scoped
21370
+ // to the exact shape of that echo (isProgrammatic + non-empty combobox
21371
+ // value + empty input.value) so it doesn't affect the swap/typed paths
21372
+ // where value/input already track each other through the sync helpers.
21373
+ if (event && event.isProgrammatic && this.value && !this.input.value) {
21374
+ return;
21375
+ }
21376
+
21313
21377
  this.value = this.input.value;
21314
21378
 
21315
21379
  // Ignore re-entrant input events caused by programmatic value sets.
@@ -21742,7 +21806,11 @@ class AuroCombobox extends AuroElement {
21742
21806
  }
21743
21807
  });
21744
21808
 
21745
- this.handleMenuOptions();
21809
+ // Slot change (mount/re-mount): pass `preferComboboxValue` so that a
21810
+ // framework-set `this.value` wins over any stale `input.value` when
21811
+ // matching against the newly-available options. Fixes the display
21812
+ // for SPA preselect and Svelte `{#key}` re-mount swap patterns.
21813
+ this.handleMenuOptions({ preferComboboxValue: true });
21746
21814
 
21747
21815
  break;
21748
21816