@aurodesignsystem-dev/auro-formkit 0.0.0-pr1554.1 → 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 -49
  7. package/components/combobox/demo/getting-started.min.js +123 -49
  8. package/components/combobox/demo/index.min.js +123 -49
  9. package/components/combobox/dist/index.js +123 -49
  10. package/components/combobox/dist/registered.js +123 -49
  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 -22
  16. package/components/datepicker/demo/index.min.js +85 -22
  17. package/components/datepicker/dist/index.js +85 -22
  18. package/components/datepicker/dist/registered.js +85 -22
  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 -101
  26. package/components/form/demo/getting-started.min.js +342 -101
  27. package/components/form/demo/index.min.js +342 -101
  28. package/components/form/demo/registerDemoDeps.min.js +342 -101
  29. package/components/input/demo/customize.min.js +38 -16
  30. package/components/input/demo/getting-started.min.js +38 -16
  31. package/components/input/demo/index.min.js +38 -16
  32. package/components/input/dist/index.js +38 -16
  33. package/components/input/dist/registered.js +38 -16
  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 +1529 -1523
  45. package/package.json +1 -1
@@ -4971,7 +4971,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
4971
4971
  }
4972
4972
  };
4973
4973
 
4974
- var formkitVersion$2 = '202607152206';
4974
+ var formkitVersion$2 = '202607160655';
4975
4975
 
4976
4976
  let AuroElement$2 = class AuroElement extends i$3 {
4977
4977
  static get properties() {
@@ -5100,7 +5100,6 @@ class AuroDropdown extends AuroElement$2 {
5100
5100
  static get shadowRootOptions() {
5101
5101
  return {
5102
5102
  ...AuroElement$2.shadowRootOptions,
5103
- delegatesFocus: true,
5104
5103
  };
5105
5104
  }
5106
5105
 
@@ -5267,7 +5266,47 @@ class AuroDropdown extends AuroElement$2 {
5267
5266
  focusables[0].focus();
5268
5267
  }
5269
5268
  } else {
5269
+ this.focusTrigger();
5270
+ }
5271
+ }
5272
+
5273
+ /**
5274
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5275
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5276
+ * element slotted into the trigger slot (e.g. the auro-input).
5277
+ * @private
5278
+ */
5279
+ focusTrigger() {
5280
+ if (this.trigger.hasAttribute('tabindex')) {
5270
5281
  this.trigger.focus();
5282
+ } else {
5283
+ // Slotted content isn't a DOM child of the trigger div, so
5284
+ // getFocusableElements can't find it. Query assigned nodes directly.
5285
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5286
+ if (slot) {
5287
+ const assigned = slot.assignedElements();
5288
+ for (const el of assigned) {
5289
+ if (el.hasAttribute('disabled')) {
5290
+ continue;
5291
+ }
5292
+ // Try finding a focusable descendant first (handles non-focusable
5293
+ // wrappers like <div> containing a <button>). If none found, try
5294
+ // focusing the element directly (works for custom elements like
5295
+ // auro-input that have delegatesFocus or a custom focus() method).
5296
+ const descendants = getFocusableElements(el);
5297
+ if (descendants.length > 0) {
5298
+ descendants[0].focus();
5299
+ return;
5300
+ }
5301
+ el.focus();
5302
+ return;
5303
+ }
5304
+ }
5305
+ // Fallback: try DOM children (non-slotted content)
5306
+ const focusables = getFocusableElements(this.trigger);
5307
+ if (focusables.length > 0) {
5308
+ focusables[0].focus();
5309
+ }
5271
5310
  }
5272
5311
  }
5273
5312
 
@@ -5721,14 +5760,16 @@ class AuroDropdown extends AuroElement$2 {
5721
5760
 
5722
5761
  const eventType = event.detail.eventType || "unknown";
5723
5762
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5724
- this.trigger.focus();
5763
+ this.focusTrigger();
5725
5764
  }
5726
5765
 
5727
5766
 
5728
5767
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5729
5768
  // — restoring to the trigger would trap the user on this dropdown, forcing
5730
5769
  // an extra Tab to move on. Escape and outside-click still restore.
5731
- if (!this.isPopoverVisible && eventType !== "focusloss") {
5770
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
5771
+ // its own focus restoration — skip the generic trigger focus to avoid races.
5772
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
5732
5773
  // wait til the bib gets fully closed and rendered
5733
5774
  setTimeout(() => {
5734
5775
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -5740,7 +5781,7 @@ class AuroDropdown extends AuroElement$2 {
5740
5781
  return;
5741
5782
  }
5742
5783
  // Restore focus to the trigger.
5743
- this.trigger.focus();
5784
+ this.focusTrigger();
5744
5785
  });
5745
5786
  }
5746
5787
  }
@@ -16921,9 +16962,10 @@ class DomHandler {
16921
16962
  class BaseInput extends AuroElement$1 {
16922
16963
 
16923
16964
  // Delegate focus to the native <input> inside the shadow root so that
16924
- // showModal()'s dialog focusing steps reach the input element.
16925
- // This keeps the mobile virtual keyboard open when the fullscreen dialog
16926
- // opens, because the browser sees an input-to-input focus transfer.
16965
+ // clicking anywhere on the input wrapper focuses the native input, and
16966
+ // programmatic .focus() calls on elements in the shadow DOM work correctly.
16967
+ // The initial-load focus theft was caused by the static `autofocus`
16968
+ // attribute on the bib input (now conditional), not by delegatesFocus.
16927
16969
  static get shadowRootOptions() {
16928
16970
  return {
16929
16971
  ...AuroElement$1.shadowRootOptions,
@@ -18600,7 +18642,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
18600
18642
  }
18601
18643
  };
18602
18644
 
18603
- var formkitVersion$1 = '202607152206';
18645
+ var formkitVersion$1 = '202607160655';
18604
18646
 
18605
18647
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18606
18648
  // See LICENSE in the project root for license information.
@@ -18886,24 +18928,45 @@ class AuroInput extends BaseInput {
18886
18928
  * @returns {void}
18887
18929
  */
18888
18930
  checkDisplayValueSlotChange() {
18889
- // flatten:true resolves through auro-combobox's forwarding slot
18890
- // (<slot name="displayValue" slot="displayValue">) so a clone appended
18891
- // directly to auro-input's light DOM alongside the forwarder still
18892
- // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18893
- // discarded any siblings past the forwarder.
18894
18931
  const slot = this.shadowRoot?.querySelector('slot[name="displayValue"]');
18895
18932
  if (!slot) {
18896
- // Shadow root not yet rendered — fall back to checking light-DOM
18897
- // children so hasDisplayValueContent isn't stuck false after an
18898
- // early call from auro-combobox during mount.
18899
- this.hasDisplayValueContent = Boolean(
18900
- this.querySelector('[slot="displayValue"]:not(slot)')
18901
- );
18933
+ // Shadow slot not yet rendered — fall back to checking light-DOM
18934
+ // children so hasDisplayValueContent isn't stuck false when called
18935
+ // before firstUpdated (e.g. from auro-combobox during mount).
18936
+ // Check for any element (including custom elements like <auro-icon>
18937
+ // that render via shadow DOM with no text content).
18938
+ const lightDomContent = this.querySelector('[slot="displayValue"]:not(slot)');
18939
+ this.hasDisplayValueContent = Boolean(lightDomContent && (
18940
+ lightDomContent.textContent.trim().length > 0 ||
18941
+ lightDomContent.children.length > 0 ||
18942
+ lightDomContent.shadowRoot !== null
18943
+ ));
18944
+ this.requestUpdate();
18902
18945
  return;
18903
18946
  }
18904
18947
  const nodes = slot.assignedNodes({ flatten: true });
18905
18948
 
18906
- this.hasDisplayValueContent = nodes.length > 0;
18949
+ // Check for actual visible content, not just node existence.
18950
+ // An empty <span slot="displayValue"></span> forwarded from the
18951
+ // consumer should not be treated as "has content" — it causes the
18952
+ // displayValue wrapper to render (with hasContent class) but show
18953
+ // nothing, blocking the combobox's synthetic displayValue from
18954
+ // being visible on preset/deeplink load.
18955
+ // Custom elements (e.g. <auro-icon>) that render via shadow DOM are
18956
+ // treated as content even when they have no text or light-DOM children.
18957
+ this.hasDisplayValueContent = nodes.some((node) => {
18958
+ if (node.nodeType === Node.TEXT_NODE) {
18959
+ return node.textContent.trim().length > 0;
18960
+ }
18961
+ if (node.nodeType === Node.ELEMENT_NODE) {
18962
+ return node.textContent.trim().length > 0 ||
18963
+ node.children.length > 0 ||
18964
+ node.shadowRoot !== null;
18965
+ }
18966
+ return false;
18967
+ });
18968
+
18969
+ this.requestUpdate();
18907
18970
  }
18908
18971
 
18909
18972
  firstUpdated() {
@@ -19730,7 +19793,7 @@ class AuroBibtemplate extends i$3 {
19730
19793
  }
19731
19794
  }
19732
19795
 
19733
- var formkitVersion = '202607152206';
19796
+ var formkitVersion = '202607160655';
19734
19797
 
19735
19798
  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}`;
19736
19799
 
@@ -20782,6 +20845,14 @@ class AuroCombobox extends AuroElement {
20782
20845
  // auroMenu-selectedOption event hasn't fired yet, or we're on remount
20783
20846
  // with no options loaded). Synthesize a displayValue from the value so
20784
20847
  // the overlay isn't blank.
20848
+ //
20849
+ // NOTE: This renders the raw machine value (e.g. "SEA"), not the
20850
+ // human-readable label (e.g. "Seattle, WA"). For consumers where
20851
+ // value ≠ label, this produces a brief flash of the raw value until
20852
+ // the option elements load and updateTriggerTextDisplay re-runs with
20853
+ // the correct label. This is intentionally preferred over a blank
20854
+ // state — the displayValueInTrigger.remove() cleanup above ensures
20855
+ // this placeholder is replaced once the real option is available.
20785
20856
  const syntheticDV = document.createElement('span');
20786
20857
  syntheticDV.setAttribute('slot', 'displayValue');
20787
20858
  syntheticDV.textContent = this.value;
@@ -21034,7 +21105,11 @@ class AuroCombobox extends AuroElement {
21034
21105
  // after the dropdown layout settles.
21035
21106
 
21036
21107
  doubleRaf(() => {
21037
- this.setInputFocus();
21108
+ // Guard: skip if the dropdown closed before this rAF fired
21109
+ // (e.g. user selected an option immediately after the bib opened).
21110
+ if (this.dropdownOpen) {
21111
+ this.setInputFocus();
21112
+ }
21038
21113
  if (this._inFullscreenTransition) {
21039
21114
  this._inFullscreenTransition = false;
21040
21115
  }
@@ -21081,7 +21156,9 @@ class AuroCombobox extends AuroElement {
21081
21156
  }
21082
21157
 
21083
21158
  this._scheduleTimer(() => {
21084
- this.setInputFocus();
21159
+ if (this.dropdown.isPopoverVisible) {
21160
+ this.setInputFocus();
21161
+ }
21085
21162
  }, 0);
21086
21163
  });
21087
21164
  }
@@ -21090,14 +21167,19 @@ class AuroCombobox extends AuroElement {
21090
21167
  * @private
21091
21168
  */
21092
21169
  setClearBtnFocus() {
21093
- const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21094
- if (clearBtn) {
21095
- // Wait for the element to fully render across
21096
- // multiple Lit update cycles before moving focus
21097
- doubleRaf(() => {
21170
+ doubleRaf(() => {
21171
+ // First establish focus inside the input's shadow root.
21172
+ // Without this, clearBtn.focus() silently fails when focus is on
21173
+ // document.body (e.g. after a click selection closes the bib dialog).
21174
+ // delegatesFocus on BaseInput routes this to the native <input>.
21175
+ this.input.focus();
21176
+
21177
+ // Now move focus to the clear button within the same shadow root.
21178
+ const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21179
+ if (clearBtn) {
21098
21180
  clearBtn.focus();
21099
- });
21100
- }
21181
+ }
21182
+ });
21101
21183
  }
21102
21184
 
21103
21185
  /**
@@ -21308,6 +21390,9 @@ class AuroCombobox extends AuroElement {
21308
21390
  // only — fresh user selections take the existing hideBib path.
21309
21391
  if (isEcho && this.menu.optionSelected) {
21310
21392
  this._programmaticFilterRefresh = true;
21393
+ this.updateComplete.then(() => {
21394
+ this._programmaticFilterRefresh = false;
21395
+ });
21311
21396
  }
21312
21397
  });
21313
21398
 
@@ -21538,15 +21623,6 @@ class AuroCombobox extends AuroElement {
21538
21623
  * @returns {void}
21539
21624
  */
21540
21625
  handleTriggerInputValueChange(event) {
21541
- // Clear a stale _programmaticFilterRefresh when the user is genuinely
21542
- // interacting. On mount, updated('value') sets the flag, but the early
21543
- // return at `this.value === this.input.value` exits before clearing it.
21544
- // Without this, the first keystroke after mount fails to set _userTyped
21545
- // and the bib doesn't open.
21546
- if (this._programmaticFilterRefresh && this.componentHasFocus) {
21547
- this._programmaticFilterRefresh = false;
21548
- }
21549
-
21550
21626
  // 'input' fires for every user-initiated value change — typing, paste,
21551
21627
  // IME composition end, dead-key composition, drag-drop. Flip _userTyped
21552
21628
  // here so updated('availableOptions') auto-opens the bib for sources
@@ -21569,10 +21645,6 @@ class AuroCombobox extends AuroElement {
21569
21645
  if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0 && this.dropdown.isPopoverVisible) {
21570
21646
  this.setInputFocus();
21571
21647
  }
21572
-
21573
- if (this._programmaticFilterRefresh) {
21574
- this._programmaticFilterRefresh = false;
21575
- }
21576
21648
  }
21577
21649
 
21578
21650
  /**
@@ -21771,6 +21843,12 @@ class AuroCombobox extends AuroElement {
21771
21843
  // setting the flag unconditionally here masks the user-typed open path.
21772
21844
  if (!this._userTyped) {
21773
21845
  this._programmaticFilterRefresh = true;
21846
+ // Self-clear after this update cycle completes. This collapses
21847
+ // the previous scattered clear-points into one and prevents the
21848
+ // flag from surviving into the next user interaction.
21849
+ this.updateComplete.then(() => {
21850
+ this._programmaticFilterRefresh = false;
21851
+ });
21774
21852
  }
21775
21853
 
21776
21854
  if (this.input.value !== this.value) {
@@ -21860,10 +21938,6 @@ class AuroCombobox extends AuroElement {
21860
21938
  } else if (!this.dropdown.isBibFullscreen) {
21861
21939
  this.hideBib();
21862
21940
  }
21863
-
21864
- if (this._programmaticFilterRefresh) {
21865
- this._programmaticFilterRefresh = false;
21866
- }
21867
21941
  }
21868
21942
 
21869
21943
  if (changedProperties.has('error')) {
@@ -22045,7 +22119,7 @@ class AuroCombobox extends AuroElement {
22045
22119
  <slot @slotchange="${this.handleSlotChange}"></slot>
22046
22120
  <${this.inputTag}
22047
22121
  id="inputInBib"
22048
- autofocus
22122
+ ?autofocus="${this.dropdownOpen && this.dropdown?.isBibFullscreen}"
22049
22123
  @input="${this.handleInputValueChange}"
22050
22124
  .a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
22051
22125
  .a11yControls=${`${this.dropdownId}-floater-bib`}
@@ -4986,7 +4986,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$3 {
4986
4986
  }
4987
4987
  };
4988
4988
 
4989
- var formkitVersion$2 = '202607152206';
4989
+ var formkitVersion$2 = '202607160655';
4990
4990
 
4991
4991
  let AuroElement$2 = class AuroElement extends i$3 {
4992
4992
  static get properties() {
@@ -5115,7 +5115,6 @@ class AuroDropdown extends AuroElement$2 {
5115
5115
  static get shadowRootOptions() {
5116
5116
  return {
5117
5117
  ...AuroElement$2.shadowRootOptions,
5118
- delegatesFocus: true,
5119
5118
  };
5120
5119
  }
5121
5120
 
@@ -5282,7 +5281,47 @@ class AuroDropdown extends AuroElement$2 {
5282
5281
  focusables[0].focus();
5283
5282
  }
5284
5283
  } else {
5284
+ this.focusTrigger();
5285
+ }
5286
+ }
5287
+
5288
+ /**
5289
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5290
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5291
+ * element slotted into the trigger slot (e.g. the auro-input).
5292
+ * @private
5293
+ */
5294
+ focusTrigger() {
5295
+ if (this.trigger.hasAttribute('tabindex')) {
5285
5296
  this.trigger.focus();
5297
+ } else {
5298
+ // Slotted content isn't a DOM child of the trigger div, so
5299
+ // getFocusableElements can't find it. Query assigned nodes directly.
5300
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5301
+ if (slot) {
5302
+ const assigned = slot.assignedElements();
5303
+ for (const el of assigned) {
5304
+ if (el.hasAttribute('disabled')) {
5305
+ continue;
5306
+ }
5307
+ // Try finding a focusable descendant first (handles non-focusable
5308
+ // wrappers like <div> containing a <button>). If none found, try
5309
+ // focusing the element directly (works for custom elements like
5310
+ // auro-input that have delegatesFocus or a custom focus() method).
5311
+ const descendants = getFocusableElements(el);
5312
+ if (descendants.length > 0) {
5313
+ descendants[0].focus();
5314
+ return;
5315
+ }
5316
+ el.focus();
5317
+ return;
5318
+ }
5319
+ }
5320
+ // Fallback: try DOM children (non-slotted content)
5321
+ const focusables = getFocusableElements(this.trigger);
5322
+ if (focusables.length > 0) {
5323
+ focusables[0].focus();
5324
+ }
5286
5325
  }
5287
5326
  }
5288
5327
 
@@ -5736,14 +5775,16 @@ class AuroDropdown extends AuroElement$2 {
5736
5775
 
5737
5776
  const eventType = event.detail.eventType || "unknown";
5738
5777
  if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5739
- this.trigger.focus();
5778
+ this.focusTrigger();
5740
5779
  }
5741
5780
 
5742
5781
 
5743
5782
  // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5744
5783
  // — restoring to the trigger would trap the user on this dropdown, forcing
5745
5784
  // an extra Tab to move on. Escape and outside-click still restore.
5746
- if (!this.isPopoverVisible && eventType !== "focusloss") {
5785
+ // When noHideOnThisFocusLoss is true, the consumer (e.g. combobox) manages
5786
+ // its own focus restoration — skip the generic trigger focus to avoid races.
5787
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noHideOnThisFocusLoss) {
5747
5788
  // wait til the bib gets fully closed and rendered
5748
5789
  setTimeout(() => {
5749
5790
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -5755,7 +5796,7 @@ class AuroDropdown extends AuroElement$2 {
5755
5796
  return;
5756
5797
  }
5757
5798
  // Restore focus to the trigger.
5758
- this.trigger.focus();
5799
+ this.focusTrigger();
5759
5800
  });
5760
5801
  }
5761
5802
  }
@@ -16936,9 +16977,10 @@ class DomHandler {
16936
16977
  class BaseInput extends AuroElement$1 {
16937
16978
 
16938
16979
  // Delegate focus to the native <input> inside the shadow root so that
16939
- // showModal()'s dialog focusing steps reach the input element.
16940
- // This keeps the mobile virtual keyboard open when the fullscreen dialog
16941
- // opens, because the browser sees an input-to-input focus transfer.
16980
+ // clicking anywhere on the input wrapper focuses the native input, and
16981
+ // programmatic .focus() calls on elements in the shadow DOM work correctly.
16982
+ // The initial-load focus theft was caused by the static `autofocus`
16983
+ // attribute on the bib input (now conditional), not by delegatesFocus.
16942
16984
  static get shadowRootOptions() {
16943
16985
  return {
16944
16986
  ...AuroElement$1.shadowRootOptions,
@@ -18615,7 +18657,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
18615
18657
  }
18616
18658
  };
18617
18659
 
18618
- var formkitVersion$1 = '202607152206';
18660
+ var formkitVersion$1 = '202607160655';
18619
18661
 
18620
18662
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
18621
18663
  // See LICENSE in the project root for license information.
@@ -18901,24 +18943,45 @@ class AuroInput extends BaseInput {
18901
18943
  * @returns {void}
18902
18944
  */
18903
18945
  checkDisplayValueSlotChange() {
18904
- // flatten:true resolves through auro-combobox's forwarding slot
18905
- // (<slot name="displayValue" slot="displayValue">) so a clone appended
18906
- // directly to auro-input's light DOM alongside the forwarder still
18907
- // counts as content. The prior nodes[0].tagName === 'SLOT' recursion
18908
- // discarded any siblings past the forwarder.
18909
18946
  const slot = this.shadowRoot?.querySelector('slot[name="displayValue"]');
18910
18947
  if (!slot) {
18911
- // Shadow root not yet rendered — fall back to checking light-DOM
18912
- // children so hasDisplayValueContent isn't stuck false after an
18913
- // early call from auro-combobox during mount.
18914
- this.hasDisplayValueContent = Boolean(
18915
- this.querySelector('[slot="displayValue"]:not(slot)')
18916
- );
18948
+ // Shadow slot not yet rendered — fall back to checking light-DOM
18949
+ // children so hasDisplayValueContent isn't stuck false when called
18950
+ // before firstUpdated (e.g. from auro-combobox during mount).
18951
+ // Check for any element (including custom elements like <auro-icon>
18952
+ // that render via shadow DOM with no text content).
18953
+ const lightDomContent = this.querySelector('[slot="displayValue"]:not(slot)');
18954
+ this.hasDisplayValueContent = Boolean(lightDomContent && (
18955
+ lightDomContent.textContent.trim().length > 0 ||
18956
+ lightDomContent.children.length > 0 ||
18957
+ lightDomContent.shadowRoot !== null
18958
+ ));
18959
+ this.requestUpdate();
18917
18960
  return;
18918
18961
  }
18919
18962
  const nodes = slot.assignedNodes({ flatten: true });
18920
18963
 
18921
- this.hasDisplayValueContent = nodes.length > 0;
18964
+ // Check for actual visible content, not just node existence.
18965
+ // An empty <span slot="displayValue"></span> forwarded from the
18966
+ // consumer should not be treated as "has content" — it causes the
18967
+ // displayValue wrapper to render (with hasContent class) but show
18968
+ // nothing, blocking the combobox's synthetic displayValue from
18969
+ // being visible on preset/deeplink load.
18970
+ // Custom elements (e.g. <auro-icon>) that render via shadow DOM are
18971
+ // treated as content even when they have no text or light-DOM children.
18972
+ this.hasDisplayValueContent = nodes.some((node) => {
18973
+ if (node.nodeType === Node.TEXT_NODE) {
18974
+ return node.textContent.trim().length > 0;
18975
+ }
18976
+ if (node.nodeType === Node.ELEMENT_NODE) {
18977
+ return node.textContent.trim().length > 0 ||
18978
+ node.children.length > 0 ||
18979
+ node.shadowRoot !== null;
18980
+ }
18981
+ return false;
18982
+ });
18983
+
18984
+ this.requestUpdate();
18922
18985
  }
18923
18986
 
18924
18987
  firstUpdated() {
@@ -19745,7 +19808,7 @@ class AuroBibtemplate extends i$3 {
19745
19808
  }
19746
19809
  }
19747
19810
 
19748
- var formkitVersion = '202607152206';
19811
+ var formkitVersion = '202607160655';
19749
19812
 
19750
19813
  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}`;
19751
19814
 
@@ -20797,6 +20860,14 @@ class AuroCombobox extends AuroElement {
20797
20860
  // auroMenu-selectedOption event hasn't fired yet, or we're on remount
20798
20861
  // with no options loaded). Synthesize a displayValue from the value so
20799
20862
  // the overlay isn't blank.
20863
+ //
20864
+ // NOTE: This renders the raw machine value (e.g. "SEA"), not the
20865
+ // human-readable label (e.g. "Seattle, WA"). For consumers where
20866
+ // value ≠ label, this produces a brief flash of the raw value until
20867
+ // the option elements load and updateTriggerTextDisplay re-runs with
20868
+ // the correct label. This is intentionally preferred over a blank
20869
+ // state — the displayValueInTrigger.remove() cleanup above ensures
20870
+ // this placeholder is replaced once the real option is available.
20800
20871
  const syntheticDV = document.createElement('span');
20801
20872
  syntheticDV.setAttribute('slot', 'displayValue');
20802
20873
  syntheticDV.textContent = this.value;
@@ -21049,7 +21120,11 @@ class AuroCombobox extends AuroElement {
21049
21120
  // after the dropdown layout settles.
21050
21121
 
21051
21122
  doubleRaf(() => {
21052
- this.setInputFocus();
21123
+ // Guard: skip if the dropdown closed before this rAF fired
21124
+ // (e.g. user selected an option immediately after the bib opened).
21125
+ if (this.dropdownOpen) {
21126
+ this.setInputFocus();
21127
+ }
21053
21128
  if (this._inFullscreenTransition) {
21054
21129
  this._inFullscreenTransition = false;
21055
21130
  }
@@ -21096,7 +21171,9 @@ class AuroCombobox extends AuroElement {
21096
21171
  }
21097
21172
 
21098
21173
  this._scheduleTimer(() => {
21099
- this.setInputFocus();
21174
+ if (this.dropdown.isPopoverVisible) {
21175
+ this.setInputFocus();
21176
+ }
21100
21177
  }, 0);
21101
21178
  });
21102
21179
  }
@@ -21105,14 +21182,19 @@ class AuroCombobox extends AuroElement {
21105
21182
  * @private
21106
21183
  */
21107
21184
  setClearBtnFocus() {
21108
- const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21109
- if (clearBtn) {
21110
- // Wait for the element to fully render across
21111
- // multiple Lit update cycles before moving focus
21112
- doubleRaf(() => {
21185
+ doubleRaf(() => {
21186
+ // First establish focus inside the input's shadow root.
21187
+ // Without this, clearBtn.focus() silently fails when focus is on
21188
+ // document.body (e.g. after a click selection closes the bib dialog).
21189
+ // delegatesFocus on BaseInput routes this to the native <input>.
21190
+ this.input.focus();
21191
+
21192
+ // Now move focus to the clear button within the same shadow root.
21193
+ const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
21194
+ if (clearBtn) {
21113
21195
  clearBtn.focus();
21114
- });
21115
- }
21196
+ }
21197
+ });
21116
21198
  }
21117
21199
 
21118
21200
  /**
@@ -21323,6 +21405,9 @@ class AuroCombobox extends AuroElement {
21323
21405
  // only — fresh user selections take the existing hideBib path.
21324
21406
  if (isEcho && this.menu.optionSelected) {
21325
21407
  this._programmaticFilterRefresh = true;
21408
+ this.updateComplete.then(() => {
21409
+ this._programmaticFilterRefresh = false;
21410
+ });
21326
21411
  }
21327
21412
  });
21328
21413
 
@@ -21553,15 +21638,6 @@ class AuroCombobox extends AuroElement {
21553
21638
  * @returns {void}
21554
21639
  */
21555
21640
  handleTriggerInputValueChange(event) {
21556
- // Clear a stale _programmaticFilterRefresh when the user is genuinely
21557
- // interacting. On mount, updated('value') sets the flag, but the early
21558
- // return at `this.value === this.input.value` exits before clearing it.
21559
- // Without this, the first keystroke after mount fails to set _userTyped
21560
- // and the bib doesn't open.
21561
- if (this._programmaticFilterRefresh && this.componentHasFocus) {
21562
- this._programmaticFilterRefresh = false;
21563
- }
21564
-
21565
21641
  // 'input' fires for every user-initiated value change — typing, paste,
21566
21642
  // IME composition end, dead-key composition, drag-drop. Flip _userTyped
21567
21643
  // here so updated('availableOptions') auto-opens the bib for sources
@@ -21584,10 +21660,6 @@ class AuroCombobox extends AuroElement {
21584
21660
  if (this.dropdown.isBibFullscreen && this.input.value && this.input.value.length > 0 && this.dropdown.isPopoverVisible) {
21585
21661
  this.setInputFocus();
21586
21662
  }
21587
-
21588
- if (this._programmaticFilterRefresh) {
21589
- this._programmaticFilterRefresh = false;
21590
- }
21591
21663
  }
21592
21664
 
21593
21665
  /**
@@ -21786,6 +21858,12 @@ class AuroCombobox extends AuroElement {
21786
21858
  // setting the flag unconditionally here masks the user-typed open path.
21787
21859
  if (!this._userTyped) {
21788
21860
  this._programmaticFilterRefresh = true;
21861
+ // Self-clear after this update cycle completes. This collapses
21862
+ // the previous scattered clear-points into one and prevents the
21863
+ // flag from surviving into the next user interaction.
21864
+ this.updateComplete.then(() => {
21865
+ this._programmaticFilterRefresh = false;
21866
+ });
21789
21867
  }
21790
21868
 
21791
21869
  if (this.input.value !== this.value) {
@@ -21875,10 +21953,6 @@ class AuroCombobox extends AuroElement {
21875
21953
  } else if (!this.dropdown.isBibFullscreen) {
21876
21954
  this.hideBib();
21877
21955
  }
21878
-
21879
- if (this._programmaticFilterRefresh) {
21880
- this._programmaticFilterRefresh = false;
21881
- }
21882
21956
  }
21883
21957
 
21884
21958
  if (changedProperties.has('error')) {
@@ -22060,7 +22134,7 @@ class AuroCombobox extends AuroElement {
22060
22134
  <slot @slotchange="${this.handleSlotChange}"></slot>
22061
22135
  <${this.inputTag}
22062
22136
  id="inputInBib"
22063
- autofocus
22137
+ ?autofocus="${this.dropdownOpen && this.dropdown?.isBibFullscreen}"
22064
22138
  @input="${this.handleInputValueChange}"
22065
22139
  .a11yActivedescendant="${this.dropdownOpen && this.optionActive ? this.optionActive.id : undefined}"
22066
22140
  .a11yControls=${`${this.dropdownId}-floater-bib`}