@aurodesignsystem-dev/auro-formkit 0.0.0-pr1554.0 → 0.0.0-pr1554.10

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 (45) 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 +123 -43
  7. package/components/combobox/demo/getting-started.min.js +123 -43
  8. package/components/combobox/demo/index.min.js +123 -43
  9. package/components/combobox/dist/index.js +123 -43
  10. package/components/combobox/dist/registered.js +123 -43
  11. package/components/counter/demo/customize.min.js +47 -6
  12. package/components/counter/demo/index.min.js +47 -6
  13. package/components/counter/dist/index.js +47 -6
  14. package/components/counter/dist/registered.js +47 -6
  15. package/components/datepicker/demo/customize.min.js +85 -16
  16. package/components/datepicker/demo/index.min.js +85 -16
  17. package/components/datepicker/dist/index.js +85 -16
  18. package/components/datepicker/dist/registered.js +85 -16
  19. package/components/dropdown/demo/customize.min.js +46 -5
  20. package/components/dropdown/demo/getting-started.min.js +46 -5
  21. package/components/dropdown/demo/index.min.js +46 -5
  22. package/components/dropdown/dist/auro-dropdown.d.ts +8 -1
  23. package/components/dropdown/dist/index.js +46 -5
  24. package/components/dropdown/dist/registered.js +46 -5
  25. package/components/form/demo/customize.min.js +342 -83
  26. package/components/form/demo/getting-started.min.js +342 -83
  27. package/components/form/demo/index.min.js +342 -83
  28. package/components/form/demo/registerDemoDeps.min.js +342 -83
  29. package/components/input/demo/customize.min.js +38 -10
  30. package/components/input/demo/getting-started.min.js +38 -10
  31. package/components/input/demo/index.min.js +38 -10
  32. package/components/input/dist/index.js +38 -10
  33. package/components/input/dist/registered.js +38 -10
  34. package/components/radio/demo/customize.min.js +1 -1
  35. package/components/radio/demo/getting-started.min.js +1 -1
  36. package/components/radio/demo/index.min.js +1 -1
  37. package/components/radio/dist/index.js +1 -1
  38. package/components/radio/dist/registered.js +1 -1
  39. package/components/select/demo/customize.min.js +47 -6
  40. package/components/select/demo/getting-started.min.js +47 -6
  41. package/components/select/demo/index.min.js +47 -6
  42. package/components/select/dist/index.js +47 -6
  43. package/components/select/dist/registered.js +47 -6
  44. package/custom-elements.json +1783 -1777
  45. package/package.json +1 -1
@@ -4904,7 +4904,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
4904
4904
  }
4905
4905
  };
4906
4906
 
4907
- var formkitVersion$2 = '202607152158';
4907
+ var formkitVersion$2 = '202607160655';
4908
4908
 
4909
4909
  let AuroElement$2 = class AuroElement extends LitElement {
4910
4910
  static get properties() {
@@ -5033,7 +5033,6 @@ class AuroDropdown extends AuroElement$2 {
5033
5033
  static get shadowRootOptions() {
5034
5034
  return {
5035
5035
  ...AuroElement$2.shadowRootOptions,
5036
- delegatesFocus: true,
5037
5036
  };
5038
5037
  }
5039
5038
 
@@ -5200,7 +5199,47 @@ class AuroDropdown extends AuroElement$2 {
5200
5199
  focusables[0].focus();
5201
5200
  }
5202
5201
  } else {
5202
+ this.focusTrigger();
5203
+ }
5204
+ }
5205
+
5206
+ /**
5207
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5208
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5209
+ * element slotted into the trigger slot (e.g. the auro-input).
5210
+ * @private
5211
+ */
5212
+ focusTrigger() {
5213
+ if (this.trigger.hasAttribute('tabindex')) {
5203
5214
  this.trigger.focus();
5215
+ } else {
5216
+ // Slotted content isn't a DOM child of the trigger div, so
5217
+ // getFocusableElements can't find it. Query assigned nodes directly.
5218
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5219
+ if (slot) {
5220
+ const assigned = slot.assignedElements();
5221
+ for (const el of assigned) {
5222
+ if (el.hasAttribute('disabled')) {
5223
+ continue;
5224
+ }
5225
+ // Try finding a focusable descendant first (handles non-focusable
5226
+ // wrappers like <div> containing a <button>). If none found, try
5227
+ // focusing the element directly (works for custom elements like
5228
+ // auro-input that have delegatesFocus or a custom focus() method).
5229
+ const descendants = getFocusableElements(el);
5230
+ if (descendants.length > 0) {
5231
+ descendants[0].focus();
5232
+ return;
5233
+ }
5234
+ el.focus();
5235
+ return;
5236
+ }
5237
+ }
5238
+ // Fallback: try DOM children (non-slotted content)
5239
+ const focusables = getFocusableElements(this.trigger);
5240
+ if (focusables.length > 0) {
5241
+ focusables[0].focus();
5242
+ }
5204
5243
  }
5205
5244
  }
5206
5245
 
@@ -5654,14 +5693,16 @@ class AuroDropdown extends AuroElement$2 {
5654
5693
 
5655
5694
  const eventType = event.detail.eventType || "unknown";
5656
5695
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5657
- this.trigger.focus();
5696
+ this.focusTrigger();
5658
5697
  }
5659
5698
 
5660
5699
 
5661
5700
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5662
5701
  // — restoring to the trigger would trap the user on this dropdown, forcing
5663
5702
  // an extra Tab to move on. Escape and outside-click still restore.
5664
- if (!this.isPopoverVisible && eventType !== "focusloss") {
5703
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
5704
+ // its own focus restoration — skip the generic trigger focus to avoid races.
5705
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
5665
5706
  // wait til the bib gets fully closed and rendered
5666
5707
  setTimeout(() => {
5667
5708
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -5673,7 +5714,7 @@ class AuroDropdown extends AuroElement$2 {
5673
5714
  return;
5674
5715
  }
5675
5716
  // Restore focus to the trigger.
5676
- this.trigger.focus();
5717
+ this.focusTrigger();
5677
5718
  });
5678
5719
  }
5679
5720
  }
@@ -16847,9 +16888,10 @@ class DomHandler {
16847
16888
  class BaseInput extends AuroElement$1 {
16848
16889
 
16849
16890
  // Delegate focus to the native <input> inside the shadow root so that
16850
- // showModal()'s dialog focusing steps reach the input element.
16851
- // This keeps the mobile virtual keyboard open when the fullscreen dialog
16852
- // opens, because the browser sees an input-to-input focus transfer.
16891
+ // clicking anywhere on the input wrapper focuses the native input, and
16892
+ // programmatic .focus() calls on elements in the shadow DOM work correctly.
16893
+ // The initial-load focus theft was caused by the static `autofocus`
16894
+ // attribute on the bib input (now conditional), not by delegatesFocus.
16853
16895
  static get shadowRootOptions() {
16854
16896
  return {
16855
16897
  ...AuroElement$1.shadowRootOptions,
@@ -18526,7 +18568,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
18526
18568
  }
18527
18569
  };
18528
18570
 
18529
- var formkitVersion$1 = '202607152158';
18571
+ var formkitVersion$1 = '202607160655';
18530
18572
 
18531
18573
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18532
18574
  // See LICENSE in the project root for license information.
@@ -18812,18 +18854,45 @@ class AuroInput extends BaseInput {
18812
18854
  * @returns {void}
18813
18855
  */
18814
18856
  checkDisplayValueSlotChange() {
18815
- // flatten:true resolves through auro-combobox's forwarding slot
18816
- // (<slot name="displayValue" slot="displayValue">) so a clone appended
18817
- // directly to auro-input's light DOM alongside the forwarder still
18818
- // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18819
- // discarded any siblings past the forwarder.
18820
18857
  const slot = this.shadowRoot?.querySelector('slot[name="displayValue"]');
18821
18858
  if (!slot) {
18859
+ // Shadow slot not yet rendered — fall back to checking light-DOM
18860
+ // children so hasDisplayValueContent isn't stuck false when called
18861
+ // before firstUpdated (e.g. from auro-combobox during mount).
18862
+ // Check for any element (including custom elements like <auro-icon>
18863
+ // that render via shadow DOM with no text content).
18864
+ const lightDomContent = this.querySelector('[slot="displayValue"]:not(slot)');
18865
+ this.hasDisplayValueContent = Boolean(lightDomContent && (
18866
+ lightDomContent.textContent.trim().length > 0 ||
18867
+ lightDomContent.children.length > 0 ||
18868
+ lightDomContent.shadowRoot !== null
18869
+ ));
18870
+ this.requestUpdate();
18822
18871
  return;
18823
18872
  }
18824
18873
  const nodes = slot.assignedNodes({ flatten: true });
18825
18874
 
18826
- this.hasDisplayValueContent = nodes.length > 0;
18875
+ // Check for actual visible content, not just node existence.
18876
+ // An empty <span slot="displayValue"></span> forwarded from the
18877
+ // consumer should not be treated as "has content" — it causes the
18878
+ // displayValue wrapper to render (with hasContent class) but show
18879
+ // nothing, blocking the combobox's synthetic displayValue from
18880
+ // being visible on preset/deeplink load.
18881
+ // Custom elements (e.g. <auro-icon>) that render via shadow DOM are
18882
+ // treated as content even when they have no text or light-DOM children.
18883
+ this.hasDisplayValueContent = nodes.some((node) => {
18884
+ if (node.nodeType === Node.TEXT_NODE) {
18885
+ return node.textContent.trim().length > 0;
18886
+ }
18887
+ if (node.nodeType === Node.ELEMENT_NODE) {
18888
+ return node.textContent.trim().length > 0 ||
18889
+ node.children.length > 0 ||
18890
+ node.shadowRoot !== null;
18891
+ }
18892
+ return false;
18893
+ });
18894
+
18895
+ this.requestUpdate();
18827
18896
  }
18828
18897
 
18829
18898
  firstUpdated() {
@@ -19650,7 +19719,7 @@ class AuroBibtemplate extends LitElement {
19650
19719
  }
19651
19720
  }
19652
19721
 
19653
- var formkitVersion = '202607152158';
19722
+ var formkitVersion = '202607160655';
19654
19723
 
19655
19724
  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}`;
19656
19725
 
@@ -20702,6 +20771,14 @@ class AuroCombobox extends AuroElement {
20702
20771
  // auroMenu-selectedOption event hasn't fired yet, or we're on remount
20703
20772
  // with no options loaded). Synthesize a displayValue from the value so
20704
20773
  // the overlay isn't blank.
20774
+ //
20775
+ // NOTE: This renders the raw machine value (e.g. "SEA"), not the
20776
+ // human-readable label (e.g. "Seattle, WA"). For consumers where
20777
+ // value ≠ label, this produces a brief flash of the raw value until
20778
+ // the option elements load and updateTriggerTextDisplay re-runs with
20779
+ // the correct label. This is intentionally preferred over a blank
20780
+ // state — the displayValueInTrigger.remove() cleanup above ensures
20781
+ // this placeholder is replaced once the real option is available.
20705
20782
  const syntheticDV = document.createElement('span');
20706
20783
  syntheticDV.setAttribute('slot', 'displayValue');
20707
20784
  syntheticDV.textContent = this.value;
@@ -20954,7 +21031,11 @@ class AuroCombobox extends AuroElement {
20954
21031
  // after the dropdown layout settles.
20955
21032
 
20956
21033
  doubleRaf(() => {
20957
- this.setInputFocus();
21034
+ // Guard: skip if the dropdown closed before this rAF fired
21035
+ // (e.g. user selected an option immediately after the bib opened).
21036
+ if (this.dropdownOpen) {
21037
+ this.setInputFocus();
21038
+ }
20958
21039
  if (this._inFullscreenTransition) {
20959
21040
  this._inFullscreenTransition = false;
20960
21041
  }
@@ -21001,7 +21082,9 @@ class AuroCombobox extends AuroElement {
21001
21082
  }
21002
21083
 
21003
21084
  this._scheduleTimer(() => {
21004
- this.setInputFocus();
21085
+ if (this.dropdown.isPopoverVisible) {
21086
+ this.setInputFocus();
21087
+ }
21005
21088
  }, 0);
21006
21089
  });
21007
21090
  }
@@ -21010,14 +21093,19 @@ class AuroCombobox extends AuroElement {
21010
21093
  * @private
21011
21094
  */
21012
21095
  setClearBtnFocus() {
21013
- const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21014
- if (clearBtn) {
21015
- // Wait for the element to fully render across
21016
- // multiple Lit update cycles before moving focus
21017
- doubleRaf(() => {
21096
+ doubleRaf(() => {
21097
+ // First establish focus inside the input's shadow root.
21098
+ // Without this, clearBtn.focus() silently fails when focus is on
21099
+ // document.body (e.g. after a click selection closes the bib dialog).
21100
+ // delegatesFocus on BaseInput routes this to the native <input>.
21101
+ this.input.focus();
21102
+
21103
+ // Now move focus to the clear button within the same shadow root.
21104
+ const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21105
+ if (clearBtn) {
21018
21106
  clearBtn.focus();
21019
- });
21020
- }
21107
+ }
21108
+ });
21021
21109
  }
21022
21110
 
21023
21111
  /**
@@ -21228,6 +21316,9 @@ class AuroCombobox extends AuroElement {
21228
21316
  // only — fresh user selections take the existing hideBib path.
21229
21317
  if (isEcho && this.menu.optionSelected) {
21230
21318
  this._programmaticFilterRefresh = true;
21319
+ this.updateComplete.then(() => {
21320
+ this._programmaticFilterRefresh = false;
21321
+ });
21231
21322
  }
21232
21323
  });
21233
21324
 
@@ -21458,15 +21549,6 @@ class AuroCombobox extends AuroElement {
21458
21549
  * @returns {void}
21459
21550
  */
21460
21551
  handleTriggerInputValueChange(event) {
21461
- // Clear a stale _programmaticFilterRefresh when the user is genuinely
21462
- // interacting. On mount, updated('value') sets the flag, but the early
21463
- // return at `this.value === this.input.value` exits before clearing it.
21464
- // Without this, the first keystroke after mount fails to set _userTyped
21465
- // and the bib doesn't open.
21466
- if (this._programmaticFilterRefresh && this.componentHasFocus) {
21467
- this._programmaticFilterRefresh = false;
21468
- }
21469
-
21470
21552
  // 'input' fires for every user-initiated value change — typing, paste,
21471
21553
  // IME composition end, dead-key composition, drag-drop. Flip _userTyped
21472
21554
  // here so updated('availableOptions') auto-opens the bib for sources
@@ -21489,10 +21571,6 @@ class AuroCombobox extends AuroElement {
21489
21571
  if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0 && this.dropdown.isPopoverVisible) {
21490
21572
  this.setInputFocus();
21491
21573
  }
21492
-
21493
- if (this._programmaticFilterRefresh) {
21494
- this._programmaticFilterRefresh = false;
21495
- }
21496
21574
  }
21497
21575
 
21498
21576
  /**
@@ -21691,6 +21769,12 @@ class AuroCombobox extends AuroElement {
21691
21769
  // setting the flag unconditionally here masks the user-typed open path.
21692
21770
  if (!this._userTyped) {
21693
21771
  this._programmaticFilterRefresh = true;
21772
+ // Self-clear after this update cycle completes. This collapses
21773
+ // the previous scattered clear-points into one and prevents the
21774
+ // flag from surviving into the next user interaction.
21775
+ this.updateComplete.then(() => {
21776
+ this._programmaticFilterRefresh = false;
21777
+ });
21694
21778
  }
21695
21779
 
21696
21780
  if (this.input.value !== this.value) {
@@ -21780,10 +21864,6 @@ class AuroCombobox extends AuroElement {
21780
21864
  } else if (!this.dropdown.isBibFullscreen) {
21781
21865
  this.hideBib();
21782
21866
  }
21783
-
21784
- if (this._programmaticFilterRefresh) {
21785
- this._programmaticFilterRefresh = false;
21786
- }
21787
21867
  }
21788
21868
 
21789
21869
  if (changedProperties.has('error')) {
@@ -21965,7 +22045,7 @@ class AuroCombobox extends AuroElement {
21965
22045
  <slot @slotchange="${this.handleSlotChange}"></slot>
21966
22046
  <${this.inputTag}
21967
22047
  id="inputInBib"
21968
- autofocus
22048
+ ?autofocus="${this.dropdownOpen && this.dropdown?.isBibFullscreen}"
21969
22049
  @input="${this.handleInputValueChange}"
21970
22050
  .a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
21971
22051
  .a11yControls=${`${this.dropdownId}-floater-bib`}
@@ -1114,7 +1114,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
1114
1114
  }
1115
1115
  };
1116
1116
 
1117
- var formkitVersion$1 = '202607152158';
1117
+ var formkitVersion$1 = '202607160655';
1118
1118
 
1119
1119
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1120
1120
  // See LICENSE in the project root for license information.
@@ -5280,7 +5280,7 @@ class AuroHelpText extends i$2 {
5280
5280
  }
5281
5281
  }
5282
5282
 
5283
- var formkitVersion = '202607152158';
5283
+ var formkitVersion = '202607160655';
5284
5284
 
5285
5285
  let AuroElement$1 = class AuroElement extends i$2 {
5286
5286
  static get properties() {
@@ -5409,7 +5409,6 @@ class AuroDropdown extends AuroElement$1 {
5409
5409
  static get shadowRootOptions() {
5410
5410
  return {
5411
5411
  ...AuroElement$1.shadowRootOptions,
5412
- delegatesFocus: true,
5413
5412
  };
5414
5413
  }
5415
5414
 
@@ -5576,7 +5575,47 @@ class AuroDropdown extends AuroElement$1 {
5576
5575
  focusables[0].focus();
5577
5576
  }
5578
5577
  } else {
5578
+ this.focusTrigger();
5579
+ }
5580
+ }
5581
+
5582
+ /**
5583
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5584
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5585
+ * element slotted into the trigger slot (e.g. the auro-input).
5586
+ * @private
5587
+ */
5588
+ focusTrigger() {
5589
+ if (this.trigger.hasAttribute('tabindex')) {
5579
5590
  this.trigger.focus();
5591
+ } else {
5592
+ // Slotted content isn't a DOM child of the trigger div, so
5593
+ // getFocusableElements can't find it. Query assigned nodes directly.
5594
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5595
+ if (slot) {
5596
+ const assigned = slot.assignedElements();
5597
+ for (const el of assigned) {
5598
+ if (el.hasAttribute('disabled')) {
5599
+ continue;
5600
+ }
5601
+ // Try finding a focusable descendant first (handles non-focusable
5602
+ // wrappers like <div> containing a <button>). If none found, try
5603
+ // focusing the element directly (works for custom elements like
5604
+ // auro-input that have delegatesFocus or a custom focus() method).
5605
+ const descendants = getFocusableElements(el);
5606
+ if (descendants.length > 0) {
5607
+ descendants[0].focus();
5608
+ return;
5609
+ }
5610
+ el.focus();
5611
+ return;
5612
+ }
5613
+ }
5614
+ // Fallback: try DOM children (non-slotted content)
5615
+ const focusables = getFocusableElements(this.trigger);
5616
+ if (focusables.length > 0) {
5617
+ focusables[0].focus();
5618
+ }
5580
5619
  }
5581
5620
  }
5582
5621
 
@@ -6030,14 +6069,16 @@ class AuroDropdown extends AuroElement$1 {
6030
6069
 
6031
6070
  const eventType = event.detail.eventType || "unknown";
6032
6071
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
6033
- this.trigger.focus();
6072
+ this.focusTrigger();
6034
6073
  }
6035
6074
 
6036
6075
 
6037
6076
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
6038
6077
  // — restoring to the trigger would trap the user on this dropdown, forcing
6039
6078
  // an extra Tab to move on. Escape and outside-click still restore.
6040
- if (!this.isPopoverVisible && eventType !== "focusloss") {
6079
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
6080
+ // its own focus restoration — skip the generic trigger focus to avoid races.
6081
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
6041
6082
  // wait til the bib gets fully closed and rendered
6042
6083
  setTimeout(() => {
6043
6084
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -6049,7 +6090,7 @@ class AuroDropdown extends AuroElement$1 {
6049
6090
  return;
6050
6091
  }
6051
6092
  // Restore focus to the trigger.
6052
- this.trigger.focus();
6093
+ this.focusTrigger();
6053
6094
  });
6054
6095
  }
6055
6096
  }
@@ -1114,7 +1114,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
1114
1114
  }
1115
1115
  };
1116
1116
 
1117
- var formkitVersion$1 = '202607152158';
1117
+ var formkitVersion$1 = '202607160655';
1118
1118
 
1119
1119
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1120
1120
  // See LICENSE in the project root for license information.
@@ -5280,7 +5280,7 @@ class AuroHelpText extends i$2 {
5280
5280
  }
5281
5281
  }
5282
5282
 
5283
- var formkitVersion = '202607152158';
5283
+ var formkitVersion = '202607160655';
5284
5284
 
5285
5285
  let AuroElement$1 = class AuroElement extends i$2 {
5286
5286
  static get properties() {
@@ -5409,7 +5409,6 @@ class AuroDropdown extends AuroElement$1 {
5409
5409
  static get shadowRootOptions() {
5410
5410
  return {
5411
5411
  ...AuroElement$1.shadowRootOptions,
5412
- delegatesFocus: true,
5413
5412
  };
5414
5413
  }
5415
5414
 
@@ -5576,7 +5575,47 @@ class AuroDropdown extends AuroElement$1 {
5576
5575
  focusables[0].focus();
5577
5576
  }
5578
5577
  } else {
5578
+ this.focusTrigger();
5579
+ }
5580
+ }
5581
+
5582
+ /**
5583
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5584
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5585
+ * element slotted into the trigger slot (e.g. the auro-input).
5586
+ * @private
5587
+ */
5588
+ focusTrigger() {
5589
+ if (this.trigger.hasAttribute('tabindex')) {
5579
5590
  this.trigger.focus();
5591
+ } else {
5592
+ // Slotted content isn't a DOM child of the trigger div, so
5593
+ // getFocusableElements can't find it. Query assigned nodes directly.
5594
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5595
+ if (slot) {
5596
+ const assigned = slot.assignedElements();
5597
+ for (const el of assigned) {
5598
+ if (el.hasAttribute('disabled')) {
5599
+ continue;
5600
+ }
5601
+ // Try finding a focusable descendant first (handles non-focusable
5602
+ // wrappers like <div> containing a <button>). If none found, try
5603
+ // focusing the element directly (works for custom elements like
5604
+ // auro-input that have delegatesFocus or a custom focus() method).
5605
+ const descendants = getFocusableElements(el);
5606
+ if (descendants.length > 0) {
5607
+ descendants[0].focus();
5608
+ return;
5609
+ }
5610
+ el.focus();
5611
+ return;
5612
+ }
5613
+ }
5614
+ // Fallback: try DOM children (non-slotted content)
5615
+ const focusables = getFocusableElements(this.trigger);
5616
+ if (focusables.length > 0) {
5617
+ focusables[0].focus();
5618
+ }
5580
5619
  }
5581
5620
  }
5582
5621
 
@@ -6030,14 +6069,16 @@ class AuroDropdown extends AuroElement$1 {
6030
6069
 
6031
6070
  const eventType = event.detail.eventType || "unknown";
6032
6071
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
6033
- this.trigger.focus();
6072
+ this.focusTrigger();
6034
6073
  }
6035
6074
 
6036
6075
 
6037
6076
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
6038
6077
  // — restoring to the trigger would trap the user on this dropdown, forcing
6039
6078
  // an extra Tab to move on. Escape and outside-click still restore.
6040
- if (!this.isPopoverVisible && eventType !== "focusloss") {
6079
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
6080
+ // its own focus restoration — skip the generic trigger focus to avoid races.
6081
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
6041
6082
  // wait til the bib gets fully closed and rendered
6042
6083
  setTimeout(() => {
6043
6084
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -6049,7 +6090,7 @@ class AuroDropdown extends AuroElement$1 {
6049
6090
  return;
6050
6091
  }
6051
6092
  // Restore focus to the trigger.
6052
- this.trigger.focus();
6093
+ this.focusTrigger();
6053
6094
  });
6054
6095
  }
6055
6096
  }
@@ -1064,7 +1064,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
1064
1064
  }
1065
1065
  };
1066
1066
 
1067
- var formkitVersion$1 = '202607152158';
1067
+ var formkitVersion$1 = '202607160655';
1068
1068
 
1069
1069
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
1070
1070
  // See LICENSE in the project root for license information.
@@ -5212,7 +5212,7 @@ class AuroHelpText extends LitElement {
5212
5212
  }
5213
5213
  }
5214
5214
 
5215
- var formkitVersion = '202607152158';
5215
+ var formkitVersion = '202607160655';
5216
5216
 
5217
5217
  let AuroElement$1 = class AuroElement extends LitElement {
5218
5218
  static get properties() {
@@ -5341,7 +5341,6 @@ class AuroDropdown extends AuroElement$1 {
5341
5341
  static get shadowRootOptions() {
5342
5342
  return {
5343
5343
  ...AuroElement$1.shadowRootOptions,
5344
- delegatesFocus: true,
5345
5344
  };
5346
5345
  }
5347
5346
 
@@ -5508,7 +5507,47 @@ class AuroDropdown extends AuroElement$1 {
5508
5507
  focusables[0].focus();
5509
5508
  }
5510
5509
  } else {
5510
+ this.focusTrigger();
5511
+ }
5512
+ }
5513
+
5514
+ /**
5515
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5516
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5517
+ * element slotted into the trigger slot (e.g. the auro-input).
5518
+ * @private
5519
+ */
5520
+ focusTrigger() {
5521
+ if (this.trigger.hasAttribute('tabindex')) {
5511
5522
  this.trigger.focus();
5523
+ } else {
5524
+ // Slotted content isn't a DOM child of the trigger div, so
5525
+ // getFocusableElements can't find it. Query assigned nodes directly.
5526
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5527
+ if (slot) {
5528
+ const assigned = slot.assignedElements();
5529
+ for (const el of assigned) {
5530
+ if (el.hasAttribute('disabled')) {
5531
+ continue;
5532
+ }
5533
+ // Try finding a focusable descendant first (handles non-focusable
5534
+ // wrappers like <div> containing a <button>). If none found, try
5535
+ // focusing the element directly (works for custom elements like
5536
+ // auro-input that have delegatesFocus or a custom focus() method).
5537
+ const descendants = getFocusableElements(el);
5538
+ if (descendants.length > 0) {
5539
+ descendants[0].focus();
5540
+ return;
5541
+ }
5542
+ el.focus();
5543
+ return;
5544
+ }
5545
+ }
5546
+ // Fallback: try DOM children (non-slotted content)
5547
+ const focusables = getFocusableElements(this.trigger);
5548
+ if (focusables.length > 0) {
5549
+ focusables[0].focus();
5550
+ }
5512
5551
  }
5513
5552
  }
5514
5553
 
@@ -5962,14 +6001,16 @@ class AuroDropdown extends AuroElement$1 {
5962
6001
 
5963
6002
  const eventType = event.detail.eventType || "unknown";
5964
6003
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5965
- this.trigger.focus();
6004
+ this.focusTrigger();
5966
6005
  }
5967
6006
 
5968
6007
 
5969
6008
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5970
6009
  // — restoring to the trigger would trap the user on this dropdown, forcing
5971
6010
  // an extra Tab to move on. Escape and outside-click still restore.
5972
- if (!this.isPopoverVisible && eventType !== "focusloss") {
6011
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
6012
+ // its own focus restoration — skip the generic trigger focus to avoid races.
6013
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
5973
6014
  // wait til the bib gets fully closed and rendered
5974
6015
  setTimeout(() => {
5975
6016
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -5981,7 +6022,7 @@ class AuroDropdown extends AuroElement$1 {
5981
6022
  return;
5982
6023
  }
5983
6024
  // Restore focus to the trigger.
5984
- this.trigger.focus();
6025
+ this.focusTrigger();
5985
6026
  });
5986
6027
  }
5987
6028
  }