@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
@@ -4894,7 +4894,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
4894
4894
  }
4895
4895
  };
4896
4896
 
4897
- var formkitVersion$2 = '202607022050';
4897
+ var formkitVersion$2 = '202607061916';
4898
4898
 
4899
4899
  let AuroElement$2 = class AuroElement extends i$3 {
4900
4900
  static get properties() {
@@ -16909,14 +16909,16 @@ class BaseInput extends AuroElement$1 {
16909
16909
  this.label = 'Input label is undefined';
16910
16910
  this.layout = 'classic';
16911
16911
  this.locale = 'en-US';
16912
+ this._format = undefined;
16913
+
16914
+ /** @private */
16915
+ this._userSetFormat = false;
16912
16916
  this.max = undefined;
16913
16917
  this.maxLength = undefined;
16914
16918
  this.min = undefined;
16915
16919
  this.minLength = undefined;
16916
16920
  this.noValidate = false;
16917
16921
  this.onDark = false;
16918
- // Raw values returned from the input mask before model normalization.
16919
- this._rawMaskValue = undefined;
16920
16922
  this.required = false;
16921
16923
  this.setCustomValidityForType = undefined;
16922
16924
  // Credit Card is intentionally excluded — its mask manages the cursor
@@ -17074,7 +17076,8 @@ class BaseInput extends AuroElement$1 {
17074
17076
  */
17075
17077
  format: {
17076
17078
  type: String,
17077
- reflect: true
17079
+ reflect: true,
17080
+ noAccessor: true
17078
17081
  },
17079
17082
 
17080
17083
  /**
@@ -17412,6 +17415,34 @@ class BaseInput extends AuroElement$1 {
17412
17415
  return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
17413
17416
  }
17414
17417
 
17418
+ get format() {
17419
+ return this._format;
17420
+ }
17421
+
17422
+ /**
17423
+ * Overrides LitElement's generated accessor so we can track whether the
17424
+ * consumer explicitly set `format`. Locale-derived updates use
17425
+ * `_setFormatFromLocale` instead, which skips this flag.
17426
+ */
17427
+ set format(value) {
17428
+ const oldValue = this._format;
17429
+ this._format = value ? value.toLowerCase() : value;
17430
+ this._userSetFormat = Boolean(value);
17431
+ this.requestUpdate('format', oldValue);
17432
+ }
17433
+
17434
+ /**
17435
+ * Sets format without marking it as user-set. Used by locale auto-derive
17436
+ * so that a subsequent locale change can still update the format.
17437
+ * @private
17438
+ * @param {string} value
17439
+ */
17440
+ _setFormatFromLocale(value) {
17441
+ const oldValue = this._format;
17442
+ this._format = value ? value.toLowerCase() : value;
17443
+ this.requestUpdate('format', oldValue);
17444
+ }
17445
+
17415
17446
  connectedCallback() {
17416
17447
  super.connectedCallback();
17417
17448
 
@@ -17459,15 +17490,6 @@ class BaseInput extends AuroElement$1 {
17459
17490
 
17460
17491
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
17461
17492
 
17462
- // Normalize the format token to lowercase so case-mixed values supplied
17463
- // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
17464
- // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
17465
- // format silently misses the map and leaves `setCustomValidityForType`
17466
- // unset.
17467
- if (this.format) {
17468
- this.format = this.format.toLowerCase();
17469
- }
17470
-
17471
17493
  // use validity message override if declared when initializing the component
17472
17494
  if (this.hasAttribute('setCustomValidity')) {
17473
17495
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -17574,12 +17596,10 @@ class BaseInput extends AuroElement$1 {
17574
17596
  updated(changedProperties) {
17575
17597
  super.updated(changedProperties);
17576
17598
 
17577
- // When locale changes without an explicit format override, derive format from the new locale.
17578
- // Only runs if the current format is still the previous locale's default (not user-overridden).
17599
+ // When locale changes, auto-derive format unless the consumer explicitly set one.
17579
17600
  if (changedProperties.has('locale') && !changedProperties.has('format') && this.type === 'date') {
17580
- const previousLocaleFormat = getDateFormatFromLocale(changedProperties.get('locale'));
17581
- if (!this.format || this.format.toLowerCase() === previousLocaleFormat) {
17582
- this.format = getDateFormatFromLocale(this.locale);
17601
+ if (!this._userSetFormat) {
17602
+ this._setFormatFromLocale(getDateFormatFromLocale(this.locale));
17583
17603
  }
17584
17604
  }
17585
17605
 
@@ -17750,9 +17770,6 @@ class BaseInput extends AuroElement$1 {
17750
17770
  this.maskInstance.on('accept', () => {
17751
17771
  if (this._configuringMask) return;
17752
17772
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17753
- if (this.type === "date") {
17754
- this._rawMaskValue = this.maskInstance.value;
17755
- }
17756
17773
  });
17757
17774
 
17758
17775
  // Mask fires 'complete' on the restore step below for any value that
@@ -17760,9 +17777,6 @@ class BaseInput extends AuroElement$1 {
17760
17777
  this.maskInstance.on('complete', () => {
17761
17778
  if (this._configuringMask) return;
17762
17779
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17763
- if (this.type === "date") {
17764
- this._rawMaskValue = this.maskInstance.value;
17765
- }
17766
17780
  });
17767
17781
 
17768
17782
  // Write existingValue through the mask (not the input directly) so
@@ -17783,14 +17797,17 @@ class BaseInput extends AuroElement$1 {
17783
17797
  * @returns {void}
17784
17798
  */
17785
17799
  notifyValueChanged() {
17786
- let inputEvent = null;
17787
-
17788
- inputEvent = new Event('input', {
17800
+ // This echoes Lit's reactive value update (and handleClickClear's
17801
+ // programmatic clear) — it is NOT a fresh user-input event. Mark it
17802
+ // `isProgrammatic` so consumers (e.g. auro-combobox) can distinguish
17803
+ // it from genuine user typing and skip clobbering their own
17804
+ // programmatic state during init-time renders.
17805
+ const inputEvent = new Event('input', {
17789
17806
  bubbles: true,
17790
17807
  composed: true,
17791
17808
  });
17809
+ inputEvent.isProgrammatic = true;
17792
17810
 
17793
- // Dispatched event to alert outside shadow DOM context of event firing.
17794
17811
  this.dispatchEvent(inputEvent);
17795
17812
  }
17796
17813
 
@@ -17999,8 +18016,7 @@ class BaseInput extends AuroElement$1 {
17999
18016
 
18000
18017
  // Set default date format if type=date and no format is defined
18001
18018
  if (this.type === "date" && !this.format) {
18002
- // Use locale to determine default date format
18003
- this.format = this.util.getDateMaskFromLocale().toLowerCase();
18019
+ this._setFormatFromLocale(this.util.getDateMaskFromLocale().toLowerCase());
18004
18020
  this.util.updateFormat(this.format);
18005
18021
  }
18006
18022
  }
@@ -18029,7 +18045,7 @@ class BaseInput extends AuroElement$1 {
18029
18045
  const creditCard = this.matchInputValueToCreditCard();
18030
18046
  const previousFormat = this.format;
18031
18047
 
18032
- this.format = creditCard.maskFormat;
18048
+ this._setFormatFromLocale(creditCard.maskFormat);
18033
18049
 
18034
18050
  this.maxLength = creditCard.formatLength;
18035
18051
  this.minLength = creditCard.formatMinLength;
@@ -18503,7 +18519,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
18503
18519
  }
18504
18520
  };
18505
18521
 
18506
- var formkitVersion$1 = '202607022050';
18522
+ var formkitVersion$1 = '202607061916';
18507
18523
 
18508
18524
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18509
18525
  // See LICENSE in the project root for license information.
@@ -18789,20 +18805,15 @@ class AuroInput extends BaseInput {
18789
18805
  * @returns {void}
18790
18806
  */
18791
18807
  checkDisplayValueSlotChange() {
18792
- let nodes = this.shadowRoot.querySelector('slot[name="displayValue"]').assignedNodes();
18793
-
18794
- // Handle when DisplayValue is multi-level slot content (e.g. combobox passing displayValue to input)
18795
- if (nodes && nodes[0] && nodes[0].tagName === 'SLOT') {
18796
- nodes = nodes[0].assignedNodes();
18797
- }
18798
-
18799
- let hasContent = false;
18808
+ // flatten:true resolves through auro-combobox's forwarding slot
18809
+ // (<slot name="displayValue" slot="displayValue">) so a clone appended
18810
+ // directly to auro-input's light DOM alongside the forwarder still
18811
+ // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18812
+ // discarded any siblings past the forwarder.
18813
+ const slot = this.shadowRoot.querySelector('slot[name="displayValue"]');
18814
+ const nodes = slot.assignedNodes({ flatten: true });
18800
18815
 
18801
- if (nodes.length > 0) {
18802
- hasContent = true;
18803
- }
18804
-
18805
- this.hasDisplayValueContent = hasContent;
18816
+ this.hasDisplayValueContent = nodes.length > 0;
18806
18817
  }
18807
18818
 
18808
18819
  firstUpdated() {
@@ -19629,7 +19640,7 @@ class AuroBibtemplate extends i$3 {
19629
19640
  }
19630
19641
  }
19631
19642
 
19632
- var formkitVersion = '202607022050';
19643
+ var formkitVersion = '202607061916';
19633
19644
 
19634
19645
  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}`;
19635
19646
 
@@ -20728,9 +20739,19 @@ class AuroCombobox extends AuroElement {
20728
20739
  /**
20729
20740
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
20730
20741
  * @private
20742
+ * @param {object} [options={}] - Optional flag bag.
20743
+ * @param {boolean} [options.preferComboboxValue=false] - When true,
20744
+ * handleMenuOptions matches the selected option against `this.value`
20745
+ * first instead of `this.input.value`. Needed on mount and re-mount
20746
+ * because under `persistInput` the consumer's typedValue prop can drift
20747
+ * from the framework value (Svelte `{#key}` re-mount after a swap, or
20748
+ * SPA preselect after route change) and the old input-first match would
20749
+ * then pick the stale text. Only handleSlotChange passes this; typing
20750
+ * and clearing paths keep the input-first match so user clears aren't
20751
+ * undone.
20731
20752
  * @returns {void}
20732
20753
  */
20733
- handleMenuOptions() {
20754
+ handleMenuOptions({ preferComboboxValue = false } = {}) {
20734
20755
  this.generateOptionsArray();
20735
20756
  this.availableOptions = [];
20736
20757
  // Single source of truth for the menu's filter/highlight token per call.
@@ -20751,7 +20772,20 @@ class AuroCombobox extends AuroElement {
20751
20772
  option.setAttribute('aria-posinset', index + 1);
20752
20773
  });
20753
20774
 
20754
- if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
20775
+ // On mount/re-mount (via handleSlotChange), prefer the framework-set
20776
+ // `this.value` when it matches a menu option. Covers SPA preselect and
20777
+ // consumer swap patterns (e.g. Svelte `{#key}` re-mount) where
20778
+ // `this.value` is authoritative but `this.input.value` may be empty or
20779
+ // carry stale typed text from another field. Event-driven callers do
20780
+ // not pass the flag, otherwise user clears would be undone by
20781
+ // re-syncing to the previous combobox.value.
20782
+ if (preferComboboxValue &&
20783
+ this.value &&
20784
+ this.menu.options?.some((opt) => opt.value === this.value)) {
20785
+ this.setMenuValue(this.value);
20786
+ this.syncValuesAndStates();
20787
+ } else if (this.input.value &&
20788
+ this.menu.options?.some((opt) => opt.value === this.input.value)) {
20755
20789
  this.setMenuValue(this.input.value);
20756
20790
  this.syncValuesAndStates();
20757
20791
  }
@@ -21188,7 +21222,25 @@ class AuroCombobox extends AuroElement {
21188
21222
  this.optionActive = evt.detail;
21189
21223
 
21190
21224
  if (this.input) {
21191
- this.input.setActiveDescendant(this.optionActive);
21225
+ // setActiveDescendant runs after Lit's update finishes because the
21226
+ // template's `.a11yActivedescendant` binding calls setAttribute on
21227
+ // the internal <input> in auro-input.updated(), which clears the
21228
+ // reflected ariaActiveDescendantElement property. Setting the ref
21229
+ // synchronously here would get overwritten by that attribute write.
21230
+ // Awaiting updateComplete lets the attribute write finish first,
21231
+ // then the ref sticks and screen readers can cross the shadow-DOM
21232
+ // boundary to the auro-menuoption in light DOM.
21233
+ //
21234
+ // The equality check covers the async gap: this.optionActive can
21235
+ // change before the callback runs (user arrowed elsewhere, or the
21236
+ // menu closed and cleared it to null), so we bail if the target
21237
+ // no longer matches to avoid reinstating a stale ref.
21238
+ const targetOption = this.optionActive;
21239
+ this.updateComplete.then(() => {
21240
+ if (this.input && this.optionActive === targetOption) {
21241
+ this.input.setActiveDescendant(targetOption);
21242
+ }
21243
+ });
21192
21244
  }
21193
21245
 
21194
21246
  // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
@@ -21325,6 +21377,18 @@ class AuroCombobox extends AuroElement {
21325
21377
  }
21326
21378
  }
21327
21379
 
21380
+ // SPA preselect guard: on init render, auro-input's notifyValueChanged
21381
+ // echoes an empty value through as an isProgrammatic input event before
21382
+ // the framework-set combobox.value has propagated down to the input.
21383
+ // Without this bail, the `this.value = this.input.value` below clobbers
21384
+ // the framework value with '' and clear() wipes optionSelected. Scoped
21385
+ // to the exact shape of that echo (isProgrammatic + non-empty combobox
21386
+ // value + empty input.value) so it doesn't affect the swap/typed paths
21387
+ // where value/input already track each other through the sync helpers.
21388
+ if (event && event.isProgrammatic && this.value && !this.input.value) {
21389
+ return;
21390
+ }
21391
+
21328
21392
  this.value = this.input.value;
21329
21393
 
21330
21394
  // Ignore re-entrant input events caused by programmatic value sets.
@@ -21757,7 +21821,11 @@ class AuroCombobox extends AuroElement {
21757
21821
  }
21758
21822
  });
21759
21823
 
21760
- this.handleMenuOptions();
21824
+ // Slot change (mount/re-mount): pass `preferComboboxValue` so that a
21825
+ // framework-set `this.value` wins over any stale `input.value` when
21826
+ // matching against the newly-available options. Fixes the display
21827
+ // for SPA preselect and Svelte `{#key}` re-mount swap patterns.
21828
+ this.handleMenuOptions({ preferComboboxValue: true });
21761
21829
 
21762
21830
  break;
21763
21831
 
@@ -424,6 +424,16 @@ export class AuroCombobox extends AuroElement {
424
424
  /**
425
425
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
426
426
  * @private
427
+ * @param {object} [options={}] - Optional flag bag.
428
+ * @param {boolean} [options.preferComboboxValue=false] - When true,
429
+ * handleMenuOptions matches the selected option against `this.value`
430
+ * first instead of `this.input.value`. Needed on mount and re-mount
431
+ * because under `persistInput` the consumer's typedValue prop can drift
432
+ * from the framework value (Svelte `{#key}` re-mount after a swap, or
433
+ * SPA preselect after route change) and the old input-first match would
434
+ * then pick the stale text. Only handleSlotChange passes this; typing
435
+ * and clearing paths keep the input-first match so user clears aren't
436
+ * undone.
427
437
  * @returns {void}
428
438
  */
429
439
  private handleMenuOptions;
@@ -4812,7 +4812,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
4812
4812
  }
4813
4813
  };
4814
4814
 
4815
- var formkitVersion$2 = '202607022050';
4815
+ var formkitVersion$2 = '202607061916';
4816
4816
 
4817
4817
  let AuroElement$2 = class AuroElement extends LitElement {
4818
4818
  static get properties() {
@@ -16820,14 +16820,16 @@ class BaseInput extends AuroElement$1 {
16820
16820
  this.label = 'Input label is undefined';
16821
16821
  this.layout = 'classic';
16822
16822
  this.locale = 'en-US';
16823
+ this._format = undefined;
16824
+
16825
+ /** @private */
16826
+ this._userSetFormat = false;
16823
16827
  this.max = undefined;
16824
16828
  this.maxLength = undefined;
16825
16829
  this.min = undefined;
16826
16830
  this.minLength = undefined;
16827
16831
  this.noValidate = false;
16828
16832
  this.onDark = false;
16829
- // Raw values returned from the input mask before model normalization.
16830
- this._rawMaskValue = undefined;
16831
16833
  this.required = false;
16832
16834
  this.setCustomValidityForType = undefined;
16833
16835
  // Credit Card is intentionally excluded — its mask manages the cursor
@@ -16985,7 +16987,8 @@ class BaseInput extends AuroElement$1 {
16985
16987
  */
16986
16988
  format: {
16987
16989
  type: String,
16988
- reflect: true
16990
+ reflect: true,
16991
+ noAccessor: true
16989
16992
  },
16990
16993
 
16991
16994
  /**
@@ -17323,6 +17326,34 @@ class BaseInput extends AuroElement$1 {
17323
17326
  return this.max && dateFormatter.isValidDate(this.max) ? dateFormatter.stringToDateInstance(this.max) : undefined;
17324
17327
  }
17325
17328
 
17329
+ get format() {
17330
+ return this._format;
17331
+ }
17332
+
17333
+ /**
17334
+ * Overrides LitElement's generated accessor so we can track whether the
17335
+ * consumer explicitly set `format`. Locale-derived updates use
17336
+ * `_setFormatFromLocale` instead, which skips this flag.
17337
+ */
17338
+ set format(value) {
17339
+ const oldValue = this._format;
17340
+ this._format = value ? value.toLowerCase() : value;
17341
+ this._userSetFormat = Boolean(value);
17342
+ this.requestUpdate('format', oldValue);
17343
+ }
17344
+
17345
+ /**
17346
+ * Sets format without marking it as user-set. Used by locale auto-derive
17347
+ * so that a subsequent locale change can still update the format.
17348
+ * @private
17349
+ * @param {string} value
17350
+ */
17351
+ _setFormatFromLocale(value) {
17352
+ const oldValue = this._format;
17353
+ this._format = value ? value.toLowerCase() : value;
17354
+ this.requestUpdate('format', oldValue);
17355
+ }
17356
+
17326
17357
  connectedCallback() {
17327
17358
  super.connectedCallback();
17328
17359
 
@@ -17370,15 +17401,6 @@ class BaseInput extends AuroElement$1 {
17370
17401
 
17371
17402
  this.inputId = this.id ? `${this.id}-input` : window.crypto.randomUUID();
17372
17403
 
17373
- // Normalize the format token to lowercase so case-mixed values supplied
17374
- // via attribute (e.g. `format="MM/DD/YYYY"`) hit the `dateFormatMap`
17375
- // lookup inside `setCustomHelpTextMessage`. Without this, an uppercase
17376
- // format silently misses the map and leaves `setCustomValidityForType`
17377
- // unset.
17378
- if (this.format) {
17379
- this.format = this.format.toLowerCase();
17380
- }
17381
-
17382
17404
  // use validity message override if declared when initializing the component
17383
17405
  if (this.hasAttribute('setCustomValidity')) {
17384
17406
  this.ValidityMessageOverride = this.setCustomValidity;
@@ -17485,12 +17507,10 @@ class BaseInput extends AuroElement$1 {
17485
17507
  updated(changedProperties) {
17486
17508
  super.updated(changedProperties);
17487
17509
 
17488
- // When locale changes without an explicit format override, derive format from the new locale.
17489
- // Only runs if the current format is still the previous locale's default (not user-overridden).
17510
+ // When locale changes, auto-derive format unless the consumer explicitly set one.
17490
17511
  if (changedProperties.has('locale') && !changedProperties.has('format') && this.type === 'date') {
17491
- const previousLocaleFormat = getDateFormatFromLocale(changedProperties.get('locale'));
17492
- if (!this.format || this.format.toLowerCase() === previousLocaleFormat) {
17493
- this.format = getDateFormatFromLocale(this.locale);
17512
+ if (!this._userSetFormat) {
17513
+ this._setFormatFromLocale(getDateFormatFromLocale(this.locale));
17494
17514
  }
17495
17515
  }
17496
17516
 
@@ -17661,9 +17681,6 @@ class BaseInput extends AuroElement$1 {
17661
17681
  this.maskInstance.on('accept', () => {
17662
17682
  if (this._configuringMask) return;
17663
17683
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17664
- if (this.type === "date") {
17665
- this._rawMaskValue = this.maskInstance.value;
17666
- }
17667
17684
  });
17668
17685
 
17669
17686
  // Mask fires 'complete' on the restore step below for any value that
@@ -17671,9 +17688,6 @@ class BaseInput extends AuroElement$1 {
17671
17688
  this.maskInstance.on('complete', () => {
17672
17689
  if (this._configuringMask) return;
17673
17690
  this.value = this.util.toModelValue(this.maskInstance.value, this.format);
17674
- if (this.type === "date") {
17675
- this._rawMaskValue = this.maskInstance.value;
17676
- }
17677
17691
  });
17678
17692
 
17679
17693
  // Write existingValue through the mask (not the input directly) so
@@ -17694,14 +17708,17 @@ class BaseInput extends AuroElement$1 {
17694
17708
  * @returns {void}
17695
17709
  */
17696
17710
  notifyValueChanged() {
17697
- let inputEvent = null;
17698
-
17699
- inputEvent = new Event('input', {
17711
+ // This echoes Lit's reactive value update (and handleClickClear's
17712
+ // programmatic clear) — it is NOT a fresh user-input event. Mark it
17713
+ // `isProgrammatic` so consumers (e.g. auro-combobox) can distinguish
17714
+ // it from genuine user typing and skip clobbering their own
17715
+ // programmatic state during init-time renders.
17716
+ const inputEvent = new Event('input', {
17700
17717
  bubbles: true,
17701
17718
  composed: true,
17702
17719
  });
17720
+ inputEvent.isProgrammatic = true;
17703
17721
 
17704
- // Dispatched event to alert outside shadow DOM context of event firing.
17705
17722
  this.dispatchEvent(inputEvent);
17706
17723
  }
17707
17724
 
@@ -17910,8 +17927,7 @@ class BaseInput extends AuroElement$1 {
17910
17927
 
17911
17928
  // Set default date format if type=date and no format is defined
17912
17929
  if (this.type === "date" && !this.format) {
17913
- // Use locale to determine default date format
17914
- this.format = this.util.getDateMaskFromLocale().toLowerCase();
17930
+ this._setFormatFromLocale(this.util.getDateMaskFromLocale().toLowerCase());
17915
17931
  this.util.updateFormat(this.format);
17916
17932
  }
17917
17933
  }
@@ -17940,7 +17956,7 @@ class BaseInput extends AuroElement$1 {
17940
17956
  const creditCard = this.matchInputValueToCreditCard();
17941
17957
  const previousFormat = this.format;
17942
17958
 
17943
- this.format = creditCard.maskFormat;
17959
+ this._setFormatFromLocale(creditCard.maskFormat);
17944
17960
 
17945
17961
  this.maxLength = creditCard.formatLength;
17946
17962
  this.minLength = creditCard.formatMinLength;
@@ -18414,7 +18430,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
18414
18430
  }
18415
18431
  };
18416
18432
 
18417
- var formkitVersion$1 = '202607022050';
18433
+ var formkitVersion$1 = '202607061916';
18418
18434
 
18419
18435
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18420
18436
  // See LICENSE in the project root for license information.
@@ -18700,20 +18716,15 @@ class AuroInput extends BaseInput {
18700
18716
  * @returns {void}
18701
18717
  */
18702
18718
  checkDisplayValueSlotChange() {
18703
- let nodes = this.shadowRoot.querySelector('slot[name="displayValue"]').assignedNodes();
18704
-
18705
- // Handle when DisplayValue is multi-level slot content (e.g. combobox passing displayValue to input)
18706
- if (nodes && nodes[0] && nodes[0].tagName === 'SLOT') {
18707
- nodes = nodes[0].assignedNodes();
18708
- }
18709
-
18710
- let hasContent = false;
18719
+ // flatten:true resolves through auro-combobox's forwarding slot
18720
+ // (<slot name="displayValue" slot="displayValue">) so a clone appended
18721
+ // directly to auro-input's light DOM alongside the forwarder still
18722
+ // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18723
+ // discarded any siblings past the forwarder.
18724
+ const slot = this.shadowRoot.querySelector('slot[name="displayValue"]');
18725
+ const nodes = slot.assignedNodes({ flatten: true });
18711
18726
 
18712
- if (nodes.length > 0) {
18713
- hasContent = true;
18714
- }
18715
-
18716
- this.hasDisplayValueContent = hasContent;
18727
+ this.hasDisplayValueContent = nodes.length > 0;
18717
18728
  }
18718
18729
 
18719
18730
  firstUpdated() {
@@ -19540,7 +19551,7 @@ class AuroBibtemplate extends LitElement {
19540
19551
  }
19541
19552
  }
19542
19553
 
19543
- var formkitVersion = '202607022050';
19554
+ var formkitVersion = '202607061916';
19544
19555
 
19545
19556
  var styleCss$1 = css`.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}`;
19546
19557
 
@@ -20639,9 +20650,19 @@ class AuroCombobox extends AuroElement {
20639
20650
  /**
20640
20651
  * Processes hidden state of all menu options and determines if there are any available options not hidden.
20641
20652
  * @private
20653
+ * @param {object} [options={}] - Optional flag bag.
20654
+ * @param {boolean} [options.preferComboboxValue=false] - When true,
20655
+ * handleMenuOptions matches the selected option against `this.value`
20656
+ * first instead of `this.input.value`. Needed on mount and re-mount
20657
+ * because under `persistInput` the consumer's typedValue prop can drift
20658
+ * from the framework value (Svelte `{#key}` re-mount after a swap, or
20659
+ * SPA preselect after route change) and the old input-first match would
20660
+ * then pick the stale text. Only handleSlotChange passes this; typing
20661
+ * and clearing paths keep the input-first match so user clears aren't
20662
+ * undone.
20642
20663
  * @returns {void}
20643
20664
  */
20644
- handleMenuOptions() {
20665
+ handleMenuOptions({ preferComboboxValue = false } = {}) {
20645
20666
  this.generateOptionsArray();
20646
20667
  this.availableOptions = [];
20647
20668
  // Single source of truth for the menu's filter/highlight token per call.
@@ -20662,7 +20683,20 @@ class AuroCombobox extends AuroElement {
20662
20683
  option.setAttribute('aria-posinset', index + 1);
20663
20684
  });
20664
20685
 
20665
- if (this.input.value && this.menu.options && this.menu.options.some((opt) => opt.value === this.input.value)) {
20686
+ // On mount/re-mount (via handleSlotChange), prefer the framework-set
20687
+ // `this.value` when it matches a menu option. Covers SPA preselect and
20688
+ // consumer swap patterns (e.g. Svelte `{#key}` re-mount) where
20689
+ // `this.value` is authoritative but `this.input.value` may be empty or
20690
+ // carry stale typed text from another field. Event-driven callers do
20691
+ // not pass the flag, otherwise user clears would be undone by
20692
+ // re-syncing to the previous combobox.value.
20693
+ if (preferComboboxValue &&
20694
+ this.value &&
20695
+ this.menu.options?.some((opt) => opt.value === this.value)) {
20696
+ this.setMenuValue(this.value);
20697
+ this.syncValuesAndStates();
20698
+ } else if (this.input.value &&
20699
+ this.menu.options?.some((opt) => opt.value === this.input.value)) {
20666
20700
  this.setMenuValue(this.input.value);
20667
20701
  this.syncValuesAndStates();
20668
20702
  }
@@ -21099,7 +21133,25 @@ class AuroCombobox extends AuroElement {
21099
21133
  this.optionActive = evt.detail;
21100
21134
 
21101
21135
  if (this.input) {
21102
- this.input.setActiveDescendant(this.optionActive);
21136
+ // setActiveDescendant runs after Lit's update finishes because the
21137
+ // template's `.a11yActivedescendant` binding calls setAttribute on
21138
+ // the internal <input> in auro-input.updated(), which clears the
21139
+ // reflected ariaActiveDescendantElement property. Setting the ref
21140
+ // synchronously here would get overwritten by that attribute write.
21141
+ // Awaiting updateComplete lets the attribute write finish first,
21142
+ // then the ref sticks and screen readers can cross the shadow-DOM
21143
+ // boundary to the auro-menuoption in light DOM.
21144
+ //
21145
+ // The equality check covers the async gap: this.optionActive can
21146
+ // change before the callback runs (user arrowed elsewhere, or the
21147
+ // menu closed and cleared it to null), so we bail if the target
21148
+ // no longer matches to avoid reinstating a stale ref.
21149
+ const targetOption = this.optionActive;
21150
+ this.updateComplete.then(() => {
21151
+ if (this.input && this.optionActive === targetOption) {
21152
+ this.input.setActiveDescendant(targetOption);
21153
+ }
21154
+ });
21103
21155
  }
21104
21156
 
21105
21157
  // In fullscreen mode the menu sits inside a nested <dialog> shadow root,
@@ -21236,6 +21288,18 @@ class AuroCombobox extends AuroElement {
21236
21288
  }
21237
21289
  }
21238
21290
 
21291
+ // SPA preselect guard: on init render, auro-input's notifyValueChanged
21292
+ // echoes an empty value through as an isProgrammatic input event before
21293
+ // the framework-set combobox.value has propagated down to the input.
21294
+ // Without this bail, the `this.value = this.input.value` below clobbers
21295
+ // the framework value with '' and clear() wipes optionSelected. Scoped
21296
+ // to the exact shape of that echo (isProgrammatic + non-empty combobox
21297
+ // value + empty input.value) so it doesn't affect the swap/typed paths
21298
+ // where value/input already track each other through the sync helpers.
21299
+ if (event && event.isProgrammatic && this.value && !this.input.value) {
21300
+ return;
21301
+ }
21302
+
21239
21303
  this.value = this.input.value;
21240
21304
 
21241
21305
  // Ignore re-entrant input events caused by programmatic value sets.
@@ -21668,7 +21732,11 @@ class AuroCombobox extends AuroElement {
21668
21732
  }
21669
21733
  });
21670
21734
 
21671
- this.handleMenuOptions();
21735
+ // Slot change (mount/re-mount): pass `preferComboboxValue` so that a
21736
+ // framework-set `this.value` wins over any stale `input.value` when
21737
+ // matching against the newly-available options. Fixes the display
21738
+ // for SPA preselect and Svelte `{#key}` re-mount swap patterns.
21739
+ this.handleMenuOptions({ preferComboboxValue: true });
21672
21740
 
21673
21741
  break;
21674
21742