@aurodesignsystem-dev/auro-formkit 0.0.0-pr1431.2 → 0.0.0-pr1433.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 (43) hide show
  1. package/components/checkbox/demo/api.min.js +1 -1
  2. package/components/checkbox/demo/index.min.js +1 -1
  3. package/components/checkbox/dist/index.js +1 -1
  4. package/components/checkbox/dist/registered.js +1 -1
  5. package/components/combobox/demo/api.min.js +235 -47
  6. package/components/combobox/demo/index.min.js +235 -47
  7. package/components/combobox/dist/auro-combobox.d.ts +4 -0
  8. package/components/combobox/dist/index.js +144 -24
  9. package/components/combobox/dist/registered.js +144 -24
  10. package/components/counter/demo/api.min.js +30 -2
  11. package/components/counter/demo/index.min.js +30 -2
  12. package/components/counter/dist/index.js +30 -2
  13. package/components/counter/dist/registered.js +30 -2
  14. package/components/datepicker/demo/api.min.js +33 -3
  15. package/components/datepicker/demo/index.min.js +33 -3
  16. package/components/datepicker/dist/index.js +33 -3
  17. package/components/datepicker/dist/registered.js +33 -3
  18. package/components/dropdown/demo/api.min.js +29 -1
  19. package/components/dropdown/demo/index.min.js +29 -1
  20. package/components/dropdown/dist/index.js +29 -1
  21. package/components/dropdown/dist/registered.js +29 -1
  22. package/components/form/demo/api.min.js +331 -57
  23. package/components/form/demo/index.min.js +331 -57
  24. package/components/input/demo/api.min.js +1 -1
  25. package/components/input/demo/index.min.js +1 -1
  26. package/components/input/dist/index.js +1 -1
  27. package/components/input/dist/registered.js +1 -1
  28. package/components/menu/demo/api.md +1 -1
  29. package/components/menu/demo/api.min.js +91 -23
  30. package/components/menu/demo/index.min.js +91 -23
  31. package/components/menu/dist/auro-menuoption.d.ts +2 -0
  32. package/components/menu/dist/index.js +91 -23
  33. package/components/menu/dist/registered.js +91 -23
  34. package/components/radio/demo/api.min.js +1 -1
  35. package/components/radio/demo/index.min.js +1 -1
  36. package/components/radio/dist/index.js +1 -1
  37. package/components/radio/dist/registered.js +1 -1
  38. package/components/select/demo/api.min.js +121 -25
  39. package/components/select/demo/index.min.js +121 -25
  40. package/components/select/dist/index.js +30 -2
  41. package/components/select/dist/registered.js +30 -2
  42. package/custom-elements.json +422 -411
  43. package/package.json +2 -2
@@ -3139,6 +3139,7 @@ class AuroFloatingUI {
3139
3139
  this.focusHandler = null;
3140
3140
  this.clickHandler = null;
3141
3141
  this.keyDownHandler = null;
3142
+ this.touchHandler = null;
3142
3143
 
3143
3144
  /**
3144
3145
  * @private
@@ -3556,6 +3557,28 @@ class AuroFloatingUI {
3556
3557
  setTimeout(() => {
3557
3558
  window.addEventListener("click", this.clickHandler);
3558
3559
  }, 0);
3560
+
3561
+ // iOS Safari does not fire `click` on non-interactive elements, so
3562
+ // tapping an inert backdrop never reaches the click handler above.
3563
+ // Mirror the same outside-tap logic with a passive touchstart listener.
3564
+ this.touchHandler = (evt) => {
3565
+ const element = this.element;
3566
+ if (!element?.bib) {
3567
+ return;
3568
+ }
3569
+
3570
+ // fullscreen (modal) dialog handles its own dismissal
3571
+ if (element.bib.hasAttribute("isfullscreen")) {
3572
+ return;
3573
+ }
3574
+
3575
+ const path = evt.composedPath();
3576
+ if (!path.includes(element.trigger) && !path.includes(element.bib)) {
3577
+ this.hideBib("click");
3578
+ }
3579
+ };
3580
+
3581
+ window.addEventListener("touchstart", this.touchHandler, { passive: true });
3559
3582
  }
3560
3583
 
3561
3584
  cleanupHideHandlers() {
@@ -3571,6 +3594,11 @@ class AuroFloatingUI {
3571
3594
  this.clickHandler = null;
3572
3595
  }
3573
3596
 
3597
+ if (this.touchHandler) {
3598
+ window.removeEventListener("touchstart", this.touchHandler);
3599
+ this.touchHandler = null;
3600
+ }
3601
+
3574
3602
  if (this.keyDownHandler) {
3575
3603
  document.removeEventListener("keydown", this.keyDownHandler);
3576
3604
  this.keyDownHandler = null;
@@ -5045,7 +5073,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
5045
5073
  }
5046
5074
  };
5047
5075
 
5048
- var formkitVersion$2 = '202604091435';
5076
+ var formkitVersion$2 = '202604100244';
5049
5077
 
5050
5078
  let AuroElement$2 = class AuroElement extends LitElement {
5051
5079
  static get properties() {
@@ -12802,7 +12830,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
12802
12830
  }
12803
12831
  };
12804
12832
 
12805
- var formkitVersion$1 = '202604091435';
12833
+ var formkitVersion$1 = '202604100244';
12806
12834
 
12807
12835
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12808
12836
  // See LICENSE in the project root for license information.
@@ -13867,11 +13895,11 @@ class AuroBibtemplate extends LitElement {
13867
13895
  }
13868
13896
  }
13869
13897
 
13870
- var formkitVersion = '202604091435';
13898
+ var formkitVersion = '202604100244';
13871
13899
 
13872
13900
  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}`;
13873
13901
 
13874
- var styleEmphasizedCss = css`:host([layout*=emphasized][shape*=pill]) [auro-input]{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input]:hover{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input]{width:100%}:host([layout*=emphasized][shape*=pill]) [auro-input]::part(inputHelpText){display:none}:host([layout=emphasized]) [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown]:hover{--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown][layout*=emphasized]::part(wrapper){--ds-auro-dropdown-trigger-background-color: transparent}`;
13902
+ var styleEmphasizedCss = css`:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]:hover{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]{width:100%}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]::part(inputHelpText){display:none}:host([layout=emphasized]) [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown]:hover{--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown][layout*=emphasized]::part(wrapper){--ds-auro-dropdown-trigger-background-color: transparent}`;
13875
13903
 
13876
13904
  var styleSnowflakeCss = css`:host([layout*=snowflake][shape*=snowflake]) [auro-input]{width:100%}:host([layout*=snowflake][shape*=snowflake]) [auro-input]::part(inputHelpText){display:none}:host([layout*=snowflake][shape*=snowflake])::part(helpText){text-align:center}`;
13877
13905
 
@@ -14730,7 +14758,7 @@ class AuroCombobox extends AuroElement {
14730
14758
  * @returns {void}
14731
14759
  */
14732
14760
  activateFirstEnabledAvailableOption() {
14733
- const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled && !opt.noMatch);
14761
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled && !opt.hasAttribute('nomatch'));
14734
14762
  this.updateActiveOption(firstEnabledOptionIndex);
14735
14763
  }
14736
14764
 
@@ -14744,7 +14772,7 @@ class AuroCombobox extends AuroElement {
14744
14772
 
14745
14773
  // Work backwards through the available options array to find the last enabled option
14746
14774
  for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14747
- if (!this.availableOptions[index].disabled && !this.availableOptions[index].noMatch) {
14775
+ if (!this.availableOptions[index].disabled && !this.availableOptions[index].hasAttribute('nomatch')) {
14748
14776
  lastEnabledOptionIndex = index;
14749
14777
  break;
14750
14778
  }
@@ -14829,14 +14857,18 @@ class AuroCombobox extends AuroElement {
14829
14857
  /**
14830
14858
  * Update displayValue or input.value, it's called when making a selection.
14831
14859
  * @param {string} label - The label of the selected option.
14860
+ * @param {object} [options={}] - Optional display update settings.
14861
+ * @param {boolean} [options.force=false] - Force display sync while focused.
14832
14862
  * @private
14833
14863
  */
14834
- updateTriggerTextDisplay(label) {
14864
+ updateTriggerTextDisplay(label, options = {}) {
14865
+ const { force = false } = options;
14866
+
14835
14867
  // update the input content if persistInput is false
14836
14868
  // in suggestion mode, do not override input value if no selection has been made and the input currently has focus
14837
14869
  const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
14838
14870
 
14839
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
14871
+ if (!this.persistInput && (force || !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection))) {
14840
14872
  this.input.value = label || this.value;
14841
14873
  }
14842
14874
 
@@ -14913,6 +14945,13 @@ class AuroCombobox extends AuroElement {
14913
14945
  * @returns {void}
14914
14946
  */
14915
14947
  showBib() {
14948
+ // Do not auto-open from programmatic value/option updates when the
14949
+ // combobox is not focused. User-driven interactions still open normally
14950
+ // once focus enters the component.
14951
+ if (!this.componentHasFocus && !this.dropdown.isPopoverVisible) {
14952
+ return;
14953
+ }
14954
+
14916
14955
  if (!this.input.value && !this.dropdown.isBibFullscreen) {
14917
14956
  this.dropdown.hide();
14918
14957
  return;
@@ -15201,6 +15240,25 @@ class AuroCombobox extends AuroElement {
15201
15240
 
15202
15241
  // Handle menu option selection like select does
15203
15242
  this.menu.addEventListener('auroMenu-selectedOption', (event) => {
15243
+ const hasMatchingOptionForValue =
15244
+ typeof this.value === 'string' &&
15245
+ this.value.length > 0 &&
15246
+ this.menu && Array.isArray(this.menu.options) &&
15247
+ this.menu.options.some((opt) => opt.value === this.value);
15248
+
15249
+ const isInitNoMatch = event.detail && event.detail.reason === 'no-match' &&
15250
+ this.menu && this.menu.options && this.menu.options.length === 0 &&
15251
+ typeof this.value === 'string' &&
15252
+ this.value.length > 0;
15253
+
15254
+ const isTransientProgrammaticNoMatch = event.detail && event.detail.reason === 'no-match' &&
15255
+ this._suppressNextEmptyInputClear &&
15256
+ hasMatchingOptionForValue;
15257
+
15258
+ if (isInitNoMatch || isTransientProgrammaticNoMatch) {
15259
+ return;
15260
+ }
15261
+
15204
15262
  // Update the optionSelected from the event details, not manually
15205
15263
  [this.optionSelected] = event.detail.options;
15206
15264
 
@@ -15376,7 +15434,18 @@ class AuroCombobox extends AuroElement {
15376
15434
  }
15377
15435
 
15378
15436
  if (!this.input.value) {
15379
- this.clear();
15437
+ const hasCommittedValue = typeof this.value === 'string' && this.value.length > 0;
15438
+ const hasCommittedSelection = Boolean(this.menu && this.menu.optionSelected);
15439
+ const isBlurSideEffect = !this.componentHasFocus && !this.dropdownOpen;
15440
+ const isTransientEmptyInputEvent = this._suppressNextEmptyInputClear && (!event || !event.detail || event.detail.value === null || event.detail.value === undefined);
15441
+
15442
+ // Preserve a committed value when an empty input event is emitted as a
15443
+ // side effect of focus leaving the combobox (e.g., clicking a swap
15444
+ // control between two comboboxes). User-driven empty input while focused
15445
+ // should still clear as before.
15446
+ if (!(isTransientEmptyInputEvent || (isBlurSideEffect && hasCommittedValue && hasCommittedSelection))) {
15447
+ this.clear();
15448
+ }
15380
15449
  }
15381
15450
  this.handleMenuOptions();
15382
15451
 
@@ -15559,6 +15628,19 @@ class AuroCombobox extends AuroElement {
15559
15628
  }
15560
15629
 
15561
15630
  updated(changedProperties) {
15631
+ if (changedProperties.has('typedValue')) {
15632
+ const nextTypedValue = this.typedValue === null || this.typedValue === undefined ? '' : this.typedValue;
15633
+ if (this.input && this.input.value !== nextTypedValue) {
15634
+ this.input.value = nextTypedValue;
15635
+ }
15636
+ if (this.inputInBib && this.inputInBib.value !== nextTypedValue) {
15637
+ this.inputInBib.value = nextTypedValue;
15638
+ }
15639
+ if (this.menu) {
15640
+ this.menu.matchWord = normalizeFilterValue(nextTypedValue);
15641
+ }
15642
+ }
15643
+
15562
15644
  // After the component is ready, send direct value changes to auro-menu.
15563
15645
  if (changedProperties.has('value')) {
15564
15646
  if (this.value && this.value.length > 0) {
@@ -15586,6 +15668,19 @@ class AuroCombobox extends AuroElement {
15586
15668
  this.clear();
15587
15669
  }
15588
15670
  }
15671
+
15672
+ // Keep trigger text synced after value/menu state has settled. Force the
15673
+ // update so external programmatic swaps reflect immediately in the UI
15674
+ // even if the input still technically holds focus during the same tick.
15675
+ if (this.value) {
15676
+ const selectedOption = this.menu && this.menu.optionSelected;
15677
+ const hasMatchingSelectedOption = selectedOption && selectedOption.value === this.value;
15678
+ const selectedOptionLabel = (selectedOption && selectedOption.getAttribute('label')) || (selectedOption && selectedOption.textContent ? selectedOption.textContent.trim() : undefined);
15679
+ const nextDisplayLabel = hasMatchingSelectedOption ? (selectedOptionLabel || this.value) : this.value;
15680
+
15681
+ this.updateTriggerTextDisplay(nextDisplayLabel, { force: true });
15682
+ }
15683
+
15589
15684
  if (this.value && !this.componentHasFocus) {
15590
15685
  // If the value got set programmatically make sure we hide the bib
15591
15686
  // when input is not taking the focus (input can be in dropdown.trigger or in bibtemplate)
@@ -15597,22 +15692,47 @@ class AuroCombobox extends AuroElement {
15597
15692
  this.menu.matchWord = normalizeFilterValue(this.input.value);
15598
15693
  }
15599
15694
 
15600
- this.dispatchEvent(new CustomEvent('input', {
15601
- bubbles: true,
15602
- cancelable: false,
15603
- composed: true,
15604
- detail: {
15605
- optionSelected: this.menu.optionSelected,
15606
- value: this.menu.value
15607
- }
15608
- }));
15695
+ // Only dispatch 'input' when the value transition is meaningful — at least one
15696
+ // of old/new must be a non-empty string. Skipping the event when both are
15697
+ // empty/undefined prevents a feedback loop during SPA navigation where Lit's
15698
+ // initial update cycle fires before the parent framework (e.g. Svelte) has
15699
+ // had a chance to set the preselected value as a property. Without this
15700
+ // guard the event arrives with el.value === undefined, the surrounding
15701
+ // framework reads it as '' and writes that back, permanently obscuring the
15702
+ // intended preselected value.
15703
+ const _oldValue = changedProperties.get('value');
15704
+ const _oldIsNonEmpty = typeof _oldValue === 'string' && _oldValue.length > 0;
15705
+ const _newIsNonEmpty = typeof this.value === 'string' && this.value.length > 0;
15706
+
15707
+ if (_newIsNonEmpty && this.menu && Array.isArray(this.menu.options) && this.menu.options.some((opt) => opt.value === this.value)) {
15708
+ this._suppressNextEmptyInputClear = true;
15709
+ clearTimeout(this._suppressNextEmptyInputClearTimeout);
15710
+ const suppressNextEmptyInputClearDelay = 300;
15711
+ this._suppressNextEmptyInputClearTimeout = setTimeout(() => {
15712
+ this._suppressNextEmptyInputClear = false;
15713
+ }, suppressNextEmptyInputClearDelay);
15714
+ } else {
15715
+ this._suppressNextEmptyInputClear = false;
15716
+ }
15609
15717
 
15610
- // Deprecated, need to be removed.
15611
- this.dispatchEvent(new CustomEvent('auroCombobox-valueSet', {
15612
- bubbles: true,
15613
- cancelable: false,
15614
- composed: true,
15615
- }));
15718
+ if (_oldIsNonEmpty || _newIsNonEmpty) {
15719
+ this.dispatchEvent(new CustomEvent('input', {
15720
+ bubbles: true,
15721
+ cancelable: false,
15722
+ composed: true,
15723
+ detail: {
15724
+ optionSelected: this.menu.optionSelected,
15725
+ value: this.menu.value
15726
+ }
15727
+ }));
15728
+
15729
+ // Deprecated, need to be removed.
15730
+ this.dispatchEvent(new CustomEvent('auroCombobox-valueSet', {
15731
+ bubbles: true,
15732
+ cancelable: false,
15733
+ composed: true,
15734
+ }));
15735
+ }
15616
15736
  }
15617
15737
 
15618
15738
  if (changedProperties.has('availableOptions')) {
@@ -3139,6 +3139,7 @@ class AuroFloatingUI {
3139
3139
  this.focusHandler = null;
3140
3140
  this.clickHandler = null;
3141
3141
  this.keyDownHandler = null;
3142
+ this.touchHandler = null;
3142
3143
 
3143
3144
  /**
3144
3145
  * @private
@@ -3556,6 +3557,28 @@ class AuroFloatingUI {
3556
3557
  setTimeout(() => {
3557
3558
  window.addEventListener("click", this.clickHandler);
3558
3559
  }, 0);
3560
+
3561
+ // iOS Safari does not fire `click` on non-interactive elements, so
3562
+ // tapping an inert backdrop never reaches the click handler above.
3563
+ // Mirror the same outside-tap logic with a passive touchstart listener.
3564
+ this.touchHandler = (evt) => {
3565
+ const element = this.element;
3566
+ if (!element?.bib) {
3567
+ return;
3568
+ }
3569
+
3570
+ // fullscreen (modal) dialog handles its own dismissal
3571
+ if (element.bib.hasAttribute("isfullscreen")) {
3572
+ return;
3573
+ }
3574
+
3575
+ const path = evt.composedPath();
3576
+ if (!path.includes(element.trigger) && !path.includes(element.bib)) {
3577
+ this.hideBib("click");
3578
+ }
3579
+ };
3580
+
3581
+ window.addEventListener("touchstart", this.touchHandler, { passive: true });
3559
3582
  }
3560
3583
 
3561
3584
  cleanupHideHandlers() {
@@ -3571,6 +3594,11 @@ class AuroFloatingUI {
3571
3594
  this.clickHandler = null;
3572
3595
  }
3573
3596
 
3597
+ if (this.touchHandler) {
3598
+ window.removeEventListener("touchstart", this.touchHandler);
3599
+ this.touchHandler = null;
3600
+ }
3601
+
3574
3602
  if (this.keyDownHandler) {
3575
3603
  document.removeEventListener("keydown", this.keyDownHandler);
3576
3604
  this.keyDownHandler = null;
@@ -5045,7 +5073,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
5045
5073
  }
5046
5074
  };
5047
5075
 
5048
- var formkitVersion$2 = '202604091435';
5076
+ var formkitVersion$2 = '202604100244';
5049
5077
 
5050
5078
  let AuroElement$2 = class AuroElement extends LitElement {
5051
5079
  static get properties() {
@@ -12802,7 +12830,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
12802
12830
  }
12803
12831
  };
12804
12832
 
12805
- var formkitVersion$1 = '202604091435';
12833
+ var formkitVersion$1 = '202604100244';
12806
12834
 
12807
12835
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12808
12836
  // See LICENSE in the project root for license information.
@@ -13867,11 +13895,11 @@ class AuroBibtemplate extends LitElement {
13867
13895
  }
13868
13896
  }
13869
13897
 
13870
- var formkitVersion = '202604091435';
13898
+ var formkitVersion = '202604100244';
13871
13899
 
13872
13900
  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}`;
13873
13901
 
13874
- var styleEmphasizedCss = css`:host([layout*=emphasized][shape*=pill]) [auro-input]{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input]:hover{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input]{width:100%}:host([layout*=emphasized][shape*=pill]) [auro-input]::part(inputHelpText){display:none}:host([layout=emphasized]) [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown]:hover{--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown][layout*=emphasized]::part(wrapper){--ds-auro-dropdown-trigger-background-color: transparent}`;
13902
+ var styleEmphasizedCss = css`:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]:hover{--ds-auro-input-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843));--ds-auro-input-container-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]{width:100%}:host([layout*=emphasized][shape*=pill]) [auro-input][slot=trigger]::part(inputHelpText){display:none}:host([layout=emphasized]) [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown]:hover{--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown][layout*=emphasized]::part(wrapper){--ds-auro-dropdown-trigger-background-color: transparent}`;
13875
13903
 
13876
13904
  var styleSnowflakeCss = css`:host([layout*=snowflake][shape*=snowflake]) [auro-input]{width:100%}:host([layout*=snowflake][shape*=snowflake]) [auro-input]::part(inputHelpText){display:none}:host([layout*=snowflake][shape*=snowflake])::part(helpText){text-align:center}`;
13877
13905
 
@@ -14730,7 +14758,7 @@ class AuroCombobox extends AuroElement {
14730
14758
  * @returns {void}
14731
14759
  */
14732
14760
  activateFirstEnabledAvailableOption() {
14733
- const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled && !opt.noMatch);
14761
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled && !opt.hasAttribute('nomatch'));
14734
14762
  this.updateActiveOption(firstEnabledOptionIndex);
14735
14763
  }
14736
14764
 
@@ -14744,7 +14772,7 @@ class AuroCombobox extends AuroElement {
14744
14772
 
14745
14773
  // Work backwards through the available options array to find the last enabled option
14746
14774
  for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14747
- if (!this.availableOptions[index].disabled && !this.availableOptions[index].noMatch) {
14775
+ if (!this.availableOptions[index].disabled && !this.availableOptions[index].hasAttribute('nomatch')) {
14748
14776
  lastEnabledOptionIndex = index;
14749
14777
  break;
14750
14778
  }
@@ -14829,14 +14857,18 @@ class AuroCombobox extends AuroElement {
14829
14857
  /**
14830
14858
  * Update displayValue or input.value, it's called when making a selection.
14831
14859
  * @param {string} label - The label of the selected option.
14860
+ * @param {object} [options={}] - Optional display update settings.
14861
+ * @param {boolean} [options.force=false] - Force display sync while focused.
14832
14862
  * @private
14833
14863
  */
14834
- updateTriggerTextDisplay(label) {
14864
+ updateTriggerTextDisplay(label, options = {}) {
14865
+ const { force = false } = options;
14866
+
14835
14867
  // update the input content if persistInput is false
14836
14868
  // in suggestion mode, do not override input value if no selection has been made and the input currently has focus
14837
14869
  const isInputFocusedWithNoSelection = !this.menu.value && (this.input.matches(':focus-within') || (this.inputInBib && this.inputInBib.matches(':focus-within')));
14838
14870
 
14839
- if (!this.persistInput && !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection)) {
14871
+ if (!this.persistInput && (force || !(this.behavior === 'suggestion' && isInputFocusedWithNoSelection))) {
14840
14872
  this.input.value = label || this.value;
14841
14873
  }
14842
14874
 
@@ -14913,6 +14945,13 @@ class AuroCombobox extends AuroElement {
14913
14945
  * @returns {void}
14914
14946
  */
14915
14947
  showBib() {
14948
+ // Do not auto-open from programmatic value/option updates when the
14949
+ // combobox is not focused. User-driven interactions still open normally
14950
+ // once focus enters the component.
14951
+ if (!this.componentHasFocus && !this.dropdown.isPopoverVisible) {
14952
+ return;
14953
+ }
14954
+
14916
14955
  if (!this.input.value && !this.dropdown.isBibFullscreen) {
14917
14956
  this.dropdown.hide();
14918
14957
  return;
@@ -15201,6 +15240,25 @@ class AuroCombobox extends AuroElement {
15201
15240
 
15202
15241
  // Handle menu option selection like select does
15203
15242
  this.menu.addEventListener('auroMenu-selectedOption', (event) => {
15243
+ const hasMatchingOptionForValue =
15244
+ typeof this.value === 'string' &&
15245
+ this.value.length > 0 &&
15246
+ this.menu && Array.isArray(this.menu.options) &&
15247
+ this.menu.options.some((opt) => opt.value === this.value);
15248
+
15249
+ const isInitNoMatch = event.detail && event.detail.reason === 'no-match' &&
15250
+ this.menu && this.menu.options && this.menu.options.length === 0 &&
15251
+ typeof this.value === 'string' &&
15252
+ this.value.length > 0;
15253
+
15254
+ const isTransientProgrammaticNoMatch = event.detail && event.detail.reason === 'no-match' &&
15255
+ this._suppressNextEmptyInputClear &&
15256
+ hasMatchingOptionForValue;
15257
+
15258
+ if (isInitNoMatch || isTransientProgrammaticNoMatch) {
15259
+ return;
15260
+ }
15261
+
15204
15262
  // Update the optionSelected from the event details, not manually
15205
15263
  [this.optionSelected] = event.detail.options;
15206
15264
 
@@ -15376,7 +15434,18 @@ class AuroCombobox extends AuroElement {
15376
15434
  }
15377
15435
 
15378
15436
  if (!this.input.value) {
15379
- this.clear();
15437
+ const hasCommittedValue = typeof this.value === 'string' && this.value.length > 0;
15438
+ const hasCommittedSelection = Boolean(this.menu && this.menu.optionSelected);
15439
+ const isBlurSideEffect = !this.componentHasFocus && !this.dropdownOpen;
15440
+ const isTransientEmptyInputEvent = this._suppressNextEmptyInputClear && (!event || !event.detail || event.detail.value === null || event.detail.value === undefined);
15441
+
15442
+ // Preserve a committed value when an empty input event is emitted as a
15443
+ // side effect of focus leaving the combobox (e.g., clicking a swap
15444
+ // control between two comboboxes). User-driven empty input while focused
15445
+ // should still clear as before.
15446
+ if (!(isTransientEmptyInputEvent || (isBlurSideEffect && hasCommittedValue && hasCommittedSelection))) {
15447
+ this.clear();
15448
+ }
15380
15449
  }
15381
15450
  this.handleMenuOptions();
15382
15451
 
@@ -15559,6 +15628,19 @@ class AuroCombobox extends AuroElement {
15559
15628
  }
15560
15629
 
15561
15630
  updated(changedProperties) {
15631
+ if (changedProperties.has('typedValue')) {
15632
+ const nextTypedValue = this.typedValue === null || this.typedValue === undefined ? '' : this.typedValue;
15633
+ if (this.input && this.input.value !== nextTypedValue) {
15634
+ this.input.value = nextTypedValue;
15635
+ }
15636
+ if (this.inputInBib && this.inputInBib.value !== nextTypedValue) {
15637
+ this.inputInBib.value = nextTypedValue;
15638
+ }
15639
+ if (this.menu) {
15640
+ this.menu.matchWord = normalizeFilterValue(nextTypedValue);
15641
+ }
15642
+ }
15643
+
15562
15644
  // After the component is ready, send direct value changes to auro-menu.
15563
15645
  if (changedProperties.has('value')) {
15564
15646
  if (this.value && this.value.length > 0) {
@@ -15586,6 +15668,19 @@ class AuroCombobox extends AuroElement {
15586
15668
  this.clear();
15587
15669
  }
15588
15670
  }
15671
+
15672
+ // Keep trigger text synced after value/menu state has settled. Force the
15673
+ // update so external programmatic swaps reflect immediately in the UI
15674
+ // even if the input still technically holds focus during the same tick.
15675
+ if (this.value) {
15676
+ const selectedOption = this.menu && this.menu.optionSelected;
15677
+ const hasMatchingSelectedOption = selectedOption && selectedOption.value === this.value;
15678
+ const selectedOptionLabel = (selectedOption && selectedOption.getAttribute('label')) || (selectedOption && selectedOption.textContent ? selectedOption.textContent.trim() : undefined);
15679
+ const nextDisplayLabel = hasMatchingSelectedOption ? (selectedOptionLabel || this.value) : this.value;
15680
+
15681
+ this.updateTriggerTextDisplay(nextDisplayLabel, { force: true });
15682
+ }
15683
+
15589
15684
  if (this.value && !this.componentHasFocus) {
15590
15685
  // If the value got set programmatically make sure we hide the bib
15591
15686
  // when input is not taking the focus (input can be in dropdown.trigger or in bibtemplate)
@@ -15597,22 +15692,47 @@ class AuroCombobox extends AuroElement {
15597
15692
  this.menu.matchWord = normalizeFilterValue(this.input.value);
15598
15693
  }
15599
15694
 
15600
- this.dispatchEvent(new CustomEvent('input', {
15601
- bubbles: true,
15602
- cancelable: false,
15603
- composed: true,
15604
- detail: {
15605
- optionSelected: this.menu.optionSelected,
15606
- value: this.menu.value
15607
- }
15608
- }));
15695
+ // Only dispatch 'input' when the value transition is meaningful — at least one
15696
+ // of old/new must be a non-empty string. Skipping the event when both are
15697
+ // empty/undefined prevents a feedback loop during SPA navigation where Lit's
15698
+ // initial update cycle fires before the parent framework (e.g. Svelte) has
15699
+ // had a chance to set the preselected value as a property. Without this
15700
+ // guard the event arrives with el.value === undefined, the surrounding
15701
+ // framework reads it as '' and writes that back, permanently obscuring the
15702
+ // intended preselected value.
15703
+ const _oldValue = changedProperties.get('value');
15704
+ const _oldIsNonEmpty = typeof _oldValue === 'string' && _oldValue.length > 0;
15705
+ const _newIsNonEmpty = typeof this.value === 'string' && this.value.length > 0;
15706
+
15707
+ if (_newIsNonEmpty && this.menu && Array.isArray(this.menu.options) && this.menu.options.some((opt) => opt.value === this.value)) {
15708
+ this._suppressNextEmptyInputClear = true;
15709
+ clearTimeout(this._suppressNextEmptyInputClearTimeout);
15710
+ const suppressNextEmptyInputClearDelay = 300;
15711
+ this._suppressNextEmptyInputClearTimeout = setTimeout(() => {
15712
+ this._suppressNextEmptyInputClear = false;
15713
+ }, suppressNextEmptyInputClearDelay);
15714
+ } else {
15715
+ this._suppressNextEmptyInputClear = false;
15716
+ }
15609
15717
 
15610
- // Deprecated, need to be removed.
15611
- this.dispatchEvent(new CustomEvent('auroCombobox-valueSet', {
15612
- bubbles: true,
15613
- cancelable: false,
15614
- composed: true,
15615
- }));
15718
+ if (_oldIsNonEmpty || _newIsNonEmpty) {
15719
+ this.dispatchEvent(new CustomEvent('input', {
15720
+ bubbles: true,
15721
+ cancelable: false,
15722
+ composed: true,
15723
+ detail: {
15724
+ optionSelected: this.menu.optionSelected,
15725
+ value: this.menu.value
15726
+ }
15727
+ }));
15728
+
15729
+ // Deprecated, need to be removed.
15730
+ this.dispatchEvent(new CustomEvent('auroCombobox-valueSet', {
15731
+ bubbles: true,
15732
+ cancelable: false,
15733
+ composed: true,
15734
+ }));
15735
+ }
15616
15736
  }
15617
15737
 
15618
15738
  if (changedProperties.has('availableOptions')) {
@@ -1521,7 +1521,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
1521
1521
  }
1522
1522
  };
1523
1523
 
1524
- var formkitVersion$1 = '202604091435';
1524
+ var formkitVersion$1 = '202604100244';
1525
1525
 
1526
1526
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1527
1527
  // See LICENSE in the project root for license information.
@@ -3799,6 +3799,7 @@ class AuroFloatingUI {
3799
3799
  this.focusHandler = null;
3800
3800
  this.clickHandler = null;
3801
3801
  this.keyDownHandler = null;
3802
+ this.touchHandler = null;
3802
3803
 
3803
3804
  /**
3804
3805
  * @private
@@ -4216,6 +4217,28 @@ class AuroFloatingUI {
4216
4217
  setTimeout(() => {
4217
4218
  window.addEventListener("click", this.clickHandler);
4218
4219
  }, 0);
4220
+
4221
+ // iOS Safari does not fire `click` on non-interactive elements, so
4222
+ // tapping an inert backdrop never reaches the click handler above.
4223
+ // Mirror the same outside-tap logic with a passive touchstart listener.
4224
+ this.touchHandler = (evt) => {
4225
+ const element = this.element;
4226
+ if (!element?.bib) {
4227
+ return;
4228
+ }
4229
+
4230
+ // fullscreen (modal) dialog handles its own dismissal
4231
+ if (element.bib.hasAttribute("isfullscreen")) {
4232
+ return;
4233
+ }
4234
+
4235
+ const path = evt.composedPath();
4236
+ if (!path.includes(element.trigger) && !path.includes(element.bib)) {
4237
+ this.hideBib("click");
4238
+ }
4239
+ };
4240
+
4241
+ window.addEventListener("touchstart", this.touchHandler, { passive: true });
4219
4242
  }
4220
4243
 
4221
4244
  cleanupHideHandlers() {
@@ -4231,6 +4254,11 @@ class AuroFloatingUI {
4231
4254
  this.clickHandler = null;
4232
4255
  }
4233
4256
 
4257
+ if (this.touchHandler) {
4258
+ window.removeEventListener("touchstart", this.touchHandler);
4259
+ this.touchHandler = null;
4260
+ }
4261
+
4234
4262
  if (this.keyDownHandler) {
4235
4263
  document.removeEventListener("keydown", this.keyDownHandler);
4236
4264
  this.keyDownHandler = null;
@@ -5705,7 +5733,7 @@ class AuroHelpText extends i$2 {
5705
5733
  }
5706
5734
  }
5707
5735
 
5708
- var formkitVersion = '202604091435';
5736
+ var formkitVersion = '202604100244';
5709
5737
 
5710
5738
  let AuroElement$1 = class AuroElement extends i$2 {
5711
5739
  static get properties() {