@aurodesignsystem-dev/auro-formkit 0.0.0-pr1408.16 → 0.0.0-pr1408.17

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 (41) 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 +184 -143
  6. package/components/combobox/demo/index.min.js +184 -143
  7. package/components/combobox/demo/keyboardBehavior.md +9 -36
  8. package/components/combobox/dist/auro-combobox.d.ts +17 -0
  9. package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +6 -3
  10. package/components/combobox/dist/index.js +184 -143
  11. package/components/combobox/dist/registered.js +184 -143
  12. package/components/counter/demo/api.min.js +2 -2
  13. package/components/counter/demo/index.min.js +2 -2
  14. package/components/counter/dist/index.js +2 -2
  15. package/components/counter/dist/registered.js +2 -2
  16. package/components/datepicker/demo/api.min.js +44 -22
  17. package/components/datepicker/demo/index.min.js +44 -22
  18. package/components/datepicker/dist/index.js +44 -22
  19. package/components/datepicker/dist/registered.js +44 -22
  20. package/components/dropdown/demo/api.min.js +1 -1
  21. package/components/dropdown/demo/index.min.js +1 -1
  22. package/components/dropdown/dist/index.js +1 -1
  23. package/components/dropdown/dist/registered.js +1 -1
  24. package/components/form/demo/api.min.js +342 -257
  25. package/components/form/demo/index.min.js +342 -257
  26. package/components/input/demo/api.min.js +102 -77
  27. package/components/input/demo/index.min.js +102 -77
  28. package/components/input/dist/auro-input.d.ts +11 -0
  29. package/components/input/dist/base-input.d.ts +1 -0
  30. package/components/input/dist/index.js +32 -18
  31. package/components/input/dist/registered.js +32 -18
  32. package/components/radio/demo/api.min.js +1 -1
  33. package/components/radio/demo/index.min.js +1 -1
  34. package/components/radio/dist/index.js +1 -1
  35. package/components/radio/dist/registered.js +1 -1
  36. package/components/select/demo/api.min.js +13 -4
  37. package/components/select/demo/index.min.js +13 -4
  38. package/components/select/dist/index.js +13 -4
  39. package/components/select/dist/registered.js +13 -4
  40. package/custom-elements.json +1435 -1391
  41. package/package.json +1 -1
@@ -1687,7 +1687,7 @@ class AuroHelpText extends i$2 {
1687
1687
  }
1688
1688
  }
1689
1689
 
1690
- var formkitVersion = '202604022013';
1690
+ var formkitVersion = '202604031704';
1691
1691
 
1692
1692
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1693
1693
  // See LICENSE in the project root for license information.
@@ -1679,7 +1679,7 @@ class AuroHelpText extends i$2 {
1679
1679
  }
1680
1680
  }
1681
1681
 
1682
- var formkitVersion = '202604022013';
1682
+ var formkitVersion = '202604031704';
1683
1683
 
1684
1684
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1685
1685
  // See LICENSE in the project root for license information.
@@ -1632,7 +1632,7 @@ class AuroHelpText extends LitElement {
1632
1632
  }
1633
1633
  }
1634
1634
 
1635
- var formkitVersion = '202604022013';
1635
+ var formkitVersion = '202604031704';
1636
1636
 
1637
1637
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1638
1638
  // See LICENSE in the project root for license information.
@@ -1632,7 +1632,7 @@ class AuroHelpText extends LitElement {
1632
1632
  }
1633
1633
  }
1634
1634
 
1635
- var formkitVersion = '202604022013';
1635
+ var formkitVersion = '202604031704';
1636
1636
 
1637
1637
  // Copyright (c) 2026 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1638
1638
  // See LICENSE in the project root for license information.
@@ -1202,7 +1202,13 @@ function guardTouchPassthrough(element) {
1202
1202
  }
1203
1203
 
1204
1204
  /**
1205
- * Restores the dropdown trigger after a fullscreen dialog closes.
1205
+ * Restores the dropdown trigger after a fullscreen dialog closes
1206
+ * when focus doesn't leave the component (e.g. using Esc or Enter keys).
1207
+ * When leaving the component (e.g., tabbing out of the combobox after closing
1208
+ * the fullscreen dialog), focus restoration is handled by the browser's native
1209
+ * dialog focus restoration behavior, so this function only restores focus
1210
+ * when focus remains inside the component after the dialog closes.
1211
+
1206
1212
  *
1207
1213
  * Removes the `inert` attribute from the trigger so it is accessible again,
1208
1214
  * and restores focus to the given target after one animation frame. The rAF
@@ -1218,8 +1224,11 @@ function guardTouchPassthrough(element) {
1218
1224
  function restoreTriggerAfterClose(dropdown, focusTarget) {
1219
1225
  dropdown.trigger.inert = false;
1220
1226
 
1227
+ // Wait a frame so that dialog.close() has completed and the browser's
1228
+ // native focus restoration has run before we attempt to focus the
1229
+ // trigger / input programmatically.
1221
1230
  requestAnimationFrame(() => {
1222
- if (!dropdown.isPopoverVisible) {
1231
+ if (!dropdown.isPopoverVisible && dropdown.trigger.contains(document.activeElement)) {
1223
1232
  focusTarget.focus();
1224
1233
  }
1225
1234
  });
@@ -1326,102 +1335,32 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1326
1335
  if (!clearBtn) {
1327
1336
  return false;
1328
1337
  }
1329
- return Boolean(clearBtn.shadowRoot && clearBtn.shadowRoot.activeElement !== null);
1338
+ const isFocused = Boolean(clearBtn.shadowRoot && clearBtn.shadowRoot.activeElement !== null);
1339
+ return isFocused;
1330
1340
  }
1331
1341
 
1332
1342
  const comboboxKeyboardStrategy = {
1333
- async Enter(component, evt, ctx) {
1334
- // If the clear button has focus, let the browser activate it normally.
1335
- // stopPropagation prevents parent containers (e.g., forms) from treating
1336
- // Enter as a submit, but we must NOT call preventDefault — that would
1337
- // block the browser's built-in "Enter activates focused button" behavior.
1343
+ ArrowDown(component, evt, ctx) {
1344
+ // If the clear button has focus, let the browser handle ArrowDown normally.
1338
1345
  if (isClearBtnFocused(ctx)) {
1339
- evt.stopPropagation();
1340
- return;
1341
- }
1342
-
1343
- if (ctx.isExpanded && component.optionActive) {
1344
- component.menu.makeSelection();
1345
- await component.updateComplete;
1346
- evt.preventDefault();
1347
- evt.stopPropagation();
1348
- component.setClearBtnFocus();
1349
- } else {
1350
- // Prevent the keypress from bubbling to parent containers (e.g., forms)
1351
- // which could interpret Enter as a submit or trigger other unintended behavior.
1352
- // This is safe because showBib() opens the dialog programmatically,
1353
- // not via event propagation.
1354
- evt.preventDefault();
1355
- evt.stopPropagation();
1356
- component.showBib();
1357
- }
1358
- },
1359
-
1360
- Tab(component, evt, ctx) {
1361
- if (!ctx.isExpanded) {
1362
1346
  return;
1363
1347
  }
1364
1348
 
1365
- // Shift+Tab moves the highlight to the first non-disabled option
1366
- // without making a selection or closing the bib.
1367
- if (evt.shiftKey) {
1368
- evt.preventDefault();
1369
- const firstActive = component.menu.menuService.menuOptions.find((option) => option.isActive);
1370
- if (firstActive) {
1371
- component.menu.updateActiveOption(firstActive);
1372
- }
1373
- return;
1374
- }
1375
-
1376
- if (ctx.isModal) {
1377
- if (!ctx.activeInput) {
1378
- return;
1379
- }
1380
- const clearBtn = getClearBtn(ctx);
1381
- const clearBtnHasFocus = isClearBtnFocused(ctx, clearBtn);
1382
-
1383
- // Tab from input: if clear button exists and doesn't have focus, focus it
1384
- if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1385
- // Force clear button container visible to work around Safari not
1386
- // propagating :focus-within through shadow DOM boundaries, which
1387
- // causes .wrapper:not(:focus-within) to hide .notification.clear.
1388
- const clearContainer = clearBtn.closest('.clear');
1389
- if (clearContainer) {
1390
- clearContainer.style.display = 'flex';
1391
- clearBtn.addEventListener('focusout', () => {
1392
- // Delay cleanup so :focus-within settles when focus moves
1393
- // to a sibling (e.g., Shift+Tab back to the input).
1394
- requestAnimationFrame(() => {
1395
- clearContainer.style.display = '';
1396
- });
1397
- }, { once: true });
1398
- }
1349
+ // option display and navigation are prevented if there are no available options
1350
+ if (component.availableOptions.length > 0) {
1351
+ // navigate if bib is open otherwise open it
1352
+ if (component.dropdown.isPopoverVisible) {
1353
+ evt.preventDefault();
1399
1354
 
1400
- // Focus the native button inside auro-button so the browser
1401
- // treats it as a real focusable element inside the dialog.
1402
- const nativeBtn = clearBtn.shadowRoot && clearBtn.shadowRoot.querySelector('button');
1403
- if (nativeBtn) {
1404
- nativeBtn.focus();
1355
+ if (evt.altKey || evt.metaKey) {
1356
+ component.activateLastEnabledAvailableOption();
1405
1357
  } else {
1406
- clearBtn.focus();
1358
+ navigateArrow(component, 'down');
1407
1359
  }
1408
- return;
1409
- }
1410
-
1411
- // Tab from clear button (or no clear button / no value) →
1412
- // select the highlighted option if any, then close
1413
- if (component.optionActive) {
1414
- component.menu.makeSelection();
1360
+ } else {
1361
+ component.showBib();
1415
1362
  }
1416
- component.hideBib();
1417
- return;
1418
1363
  }
1419
-
1420
- // Non-fullscreen: select + close
1421
- if (component.menu.optionActive && component.menu.optionActive.value) {
1422
- component.menu.value = component.menu.optionActive.value;
1423
- }
1424
- component.hideBib();
1425
1364
  },
1426
1365
 
1427
1366
  ArrowUp(component, evt, ctx) {
@@ -1430,31 +1369,85 @@ const comboboxKeyboardStrategy = {
1430
1369
  return;
1431
1370
  }
1432
1371
 
1372
+ // option display and navigation are prevented if there are no available options
1433
1373
  if (component.availableOptions.length > 0) {
1434
- component.showBib();
1374
+ // navigate if bib is open otherwise open it
1375
+ if (component.dropdown.isPopoverVisible) {
1376
+ evt.preventDefault();
1377
+
1378
+ if (evt.altKey || evt.metaKey) {
1379
+ component.activateFirstEnabledAvailableOption();
1380
+ } else {
1381
+ navigateArrow(component, 'up');
1382
+ }
1383
+ } else {
1384
+ component.showBib();
1385
+ }
1435
1386
  }
1436
- // Read live visibility — ctx.isExpanded was computed before showBib() above,
1437
- // so it wouldn't reflect the state change.
1438
- if (component.dropdown.isPopoverVisible) {
1387
+ },
1388
+
1389
+ End(component, evt, ctx) {
1390
+ if (ctx.isExpanded) {
1439
1391
  evt.preventDefault();
1440
- navigateArrow(component, 'up');
1392
+ evt.stopPropagation();
1393
+ component.activateLastEnabledAvailableOption();
1441
1394
  }
1442
1395
  },
1443
1396
 
1444
- ArrowDown(component, evt, ctx) {
1445
- // If the clear button has focus, let the browser handle ArrowDown normally.
1397
+ Enter(component, evt, ctx) {
1446
1398
  if (isClearBtnFocused(ctx)) {
1447
- return;
1448
- }
1399
+ // If the clear button has focus, let the browser activate it normally.
1400
+ // stopPropagation prevents parent containers (e.g., forms) from treating
1401
+ // Enter as a submit, but we must NOT call preventDefault — that would
1402
+ // block the browser's built-in "Enter activates focused button" behavior.
1403
+ evt.stopPropagation();
1404
+ } else if (ctx.isExpanded && component.menu.optionActive) {
1405
+ component.menu.makeSelection();
1449
1406
 
1450
- if (component.availableOptions.length > 0) {
1407
+ if (ctx.isModal) {
1408
+ component.setTriggerInputFocus();
1409
+ }
1410
+
1411
+ evt.preventDefault();
1412
+ evt.stopPropagation();
1413
+ } else {
1414
+ // Prevent the keypress from bubbling to parent containers (e.g., forms)
1415
+ // which could interpret Enter as a submit or trigger other unintended behavior.
1416
+ // This is safe because showBib() opens the dialog programmatically,
1417
+ // not via event propagation.
1418
+ evt.preventDefault();
1419
+ evt.stopPropagation();
1451
1420
  component.showBib();
1452
1421
  }
1453
- // Read live visibility — ctx.isExpanded was computed before showBib() above,
1454
- // so it wouldn't reflect the state change.
1455
- if (component.dropdown.isPopoverVisible) {
1422
+ },
1423
+
1424
+ Escape(component, _evt, ctx) {
1425
+ if (ctx.isExpanded && ctx.isModal) {
1426
+ component.setTriggerInputFocus();
1427
+ }
1428
+ },
1429
+
1430
+ Home(component, evt, ctx) {
1431
+ if (ctx.isExpanded) {
1456
1432
  evt.preventDefault();
1457
- navigateArrow(component, 'down');
1433
+ evt.stopPropagation();
1434
+ component.activateFirstEnabledAvailableOption();
1435
+ }
1436
+ },
1437
+
1438
+ Tab(component, evt, ctx) {
1439
+ if (ctx.isExpanded && !isClearBtnFocused(ctx)) {
1440
+ // ClearBtn will not bubble up tab key events when it's focused, so need to manage it here when focused
1441
+ component.menu.makeSelection();
1442
+ component.hideBib();
1443
+
1444
+ // In fullscreen modal mode, closing the dialog does not
1445
+ // automatically restores focus to the input. In the tab case,
1446
+ // Explicitly move focus to the trigger's clear button so the
1447
+ // user can continues tabbing through the page normally.
1448
+ if (ctx.isModal && !evt.shiftKey) {
1449
+ component.setClearBtnFocus();
1450
+ }
1458
1451
  }
1459
1452
  },
1460
1453
  };
@@ -5060,7 +5053,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5060
5053
  }
5061
5054
  };
5062
5055
 
5063
- var formkitVersion$2 = '202604022013';
5056
+ var formkitVersion$2 = '202604031704';
5064
5057
 
5065
5058
  let AuroElement$2 = class AuroElement extends i$4 {
5066
5059
  static get properties() {
@@ -11801,6 +11794,12 @@ class BaseInput extends AuroElement$1 {
11801
11794
  this.wrapperElement = this.shadowRoot.querySelector('.wrapper');
11802
11795
  this.inputElement = this.renderRoot.querySelector('input');
11803
11796
  this.labelElement = this.shadowRoot.querySelector('label');
11797
+ this.clearBtn = this.clearButtonRef.value;
11798
+
11799
+ // This must get moved into inputKeyboardStrategy when implemented
11800
+ this.clearBtn.addEventListener('keydown', (evt) => {
11801
+ evt.stopPropagation();
11802
+ });
11804
11803
 
11805
11804
  this.patchInputEvent(this.inputElement);
11806
11805
 
@@ -12824,7 +12823,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12824
12823
  }
12825
12824
  };
12826
12825
 
12827
- var formkitVersion$1 = '202604022013';
12826
+ var formkitVersion$1 = '202604031704';
12828
12827
 
12829
12828
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12830
12829
  // See LICENSE in the project root for license information.
@@ -12881,6 +12880,11 @@ class AuroInput extends BaseInput {
12881
12880
  * @private
12882
12881
  */
12883
12882
  this.iconTag = versioning.generateTag('auro-formkit-input-icon', iconVersion$2, _$2);
12883
+
12884
+ /**
12885
+ * @private
12886
+ */
12887
+ this.clearButtonRef = e$1();
12884
12888
  }
12885
12889
 
12886
12890
  static get styles() {
@@ -12898,6 +12902,19 @@ class AuroInput extends BaseInput {
12898
12902
  ];
12899
12903
  }
12900
12904
 
12905
+ /**
12906
+ * Returns classmap configuration for the clear button visibility.
12907
+ * The button is hidden when the input has no value, is read-only, or is disabled.
12908
+ * @private
12909
+ * @returns {Record<string, boolean>} - Classmap object controlling clear button display state.
12910
+ */
12911
+ get clearBtnClassMap() {
12912
+ return {
12913
+ 'util_displayHidden': !this.hasValue || this.readyOnly || this.disabled
12914
+ };
12915
+ }
12916
+
12917
+
12901
12918
  /**
12902
12919
  * Determines if the HTML input element should be visually hidden.
12903
12920
  * Returns true when display value content exists without focus and has a value,
@@ -13217,10 +13234,11 @@ class AuroInput extends BaseInput {
13217
13234
  <${this.buttonTag}
13218
13235
  @click="${this.handleClickClear}"
13219
13236
  appearance="${this.onDark ? 'inverse' : this.appearance}"
13220
- class="notificationBtn clearBtn"
13237
+ class="notificationBtn clearBtn ${e$3(this.clearBtnClassMap)}"
13221
13238
  shape="circle"
13222
13239
  size="sm"
13223
- variant="ghost">
13240
+ variant="ghost"
13241
+ ${n$2(this.clearButtonRef)}>
13224
13242
  <span><slot name="ariaLabel.clear">Clear Input</slot></span>
13225
13243
  <${this.iconTag}
13226
13244
  aria-hidden="true"
@@ -13365,11 +13383,7 @@ class AuroInput extends BaseInput {
13365
13383
  <div part="accent-right" class="accents right">
13366
13384
  ${this.renderValidationErrorIconHtml()}
13367
13385
  ${this.hasValue && this.type === 'password' ? this.renderHtmlNotificationPassword() : undefined}
13368
- ${this.hasValue ? u$7`
13369
- ${!this.disabled && !this.readonly ? u$7`
13370
- ${this.renderHtmlActionClear()}
13371
- ` : undefined}
13372
- ` : undefined}
13386
+ ${this.renderHtmlActionClear()}
13373
13387
  </div>
13374
13388
  </div>
13375
13389
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13401,11 +13415,7 @@ class AuroInput extends BaseInput {
13401
13415
  ${this.layout.includes('right') || this.layout === "emphasized" ? u$7`
13402
13416
  ${this.renderValidationErrorIconHtml()}
13403
13417
  ` : undefined}
13404
- ${this.hasValue ? u$7`
13405
- ${!this.disabled && !this.readonly ? u$7`
13406
- ${this.renderHtmlActionClear()}
13407
- ` : undefined}
13408
- ` : undefined}
13418
+ ${this.renderHtmlActionClear()}
13409
13419
  </div>
13410
13420
  </div>
13411
13421
  <div class="${e$3(this.helpTextClasses)}" part="inputHelpText">
@@ -13433,11 +13443,7 @@ class AuroInput extends BaseInput {
13433
13443
  </div>
13434
13444
  <div class="accents right">
13435
13445
  ${this.renderValidationErrorIconHtml()}
13436
- ${this.hasValue ? u$7`
13437
- ${!this.disabled && !this.readonly ? u$7`
13438
- ${this.renderHtmlActionClear()}
13439
- ` : undefined}
13440
- ` : undefined}
13446
+ ${this.renderHtmlActionClear()}
13441
13447
  </div>
13442
13448
  </div>
13443
13449
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13863,7 +13869,7 @@ class AuroBibtemplate extends i$4 {
13863
13869
  }
13864
13870
  }
13865
13871
 
13866
- var formkitVersion = '202604022013';
13872
+ var formkitVersion = '202604031704';
13867
13873
 
13868
13874
  var styleCss$3 = i$7`.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}`;
13869
13875
 
@@ -14342,6 +14348,7 @@ class AuroCombobox extends AuroElement {
14342
14348
 
14343
14349
  /**
14344
14350
  * Array of available options to display in the dropdown.
14351
+ * This array contains all non-hidden options (e.g., hidden by filtering on input value).
14345
14352
  * @private
14346
14353
  */
14347
14354
  availableOptions: {
@@ -14719,12 +14726,40 @@ class AuroCombobox extends AuroElement {
14719
14726
  AuroLibraryRuntimeUtils$4.prototype.registerComponent(name, AuroCombobox);
14720
14727
  }
14721
14728
 
14729
+ /**
14730
+ * Mark the first available (non-hidden), enabled option as `active`.
14731
+ * @private
14732
+ * @returns {void}
14733
+ */
14734
+ activateFirstEnabledAvailableOption() {
14735
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled);
14736
+ this.updateActiveOption(firstEnabledOptionIndex);
14737
+ }
14738
+
14739
+ /**
14740
+ * Mark the last available (non-hidden), enabled option as `active`.
14741
+ * @private
14742
+ * @returns {void}
14743
+ */
14744
+ activateLastEnabledAvailableOption() {
14745
+ let lastEnabledOptionIndex = -1;
14746
+
14747
+ // Work backwards through the available options array to find the last enabled option
14748
+ for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14749
+ if (!this.availableOptions[index].disabled) {
14750
+ lastEnabledOptionIndex = index;
14751
+ break;
14752
+ }
14753
+ }
14754
+
14755
+ this.updateActiveOption(lastEnabledOptionIndex);
14756
+ }
14757
+
14722
14758
  /**
14723
14759
  * Updates the filter for the available options based on the input value.
14724
14760
  * @private
14725
14761
  */
14726
14762
  updateFilter() {
14727
-
14728
14763
  // Reset available options if noFilter is set to false after being true.
14729
14764
  if (this.noFilter) {
14730
14765
  this.availableOptions = [...this.options];
@@ -14843,6 +14878,10 @@ class AuroCombobox extends AuroElement {
14843
14878
  if (this.value && this.input.value && !this.menu.value) {
14844
14879
  this.syncValuesAndStates();
14845
14880
  }
14881
+
14882
+ if (!this.availableOptions.includes(this.menu.optionActive)) {
14883
+ this.activateFirstEnabledAvailableOption();
14884
+ }
14846
14885
  }
14847
14886
 
14848
14887
  /**
@@ -14916,9 +14955,6 @@ class AuroCombobox extends AuroElement {
14916
14955
  if (this.dropdownOpen) {
14917
14956
  const expandedDelay = 150;
14918
14957
  this._expandedTimeout = setTimeout(() => {
14919
- if (!this.value) {
14920
- this.updateActiveOption(0);
14921
- }
14922
14958
  this.triggerExpandedState = true;
14923
14959
  }, expandedDelay);
14924
14960
  } else {
@@ -14928,22 +14964,16 @@ class AuroCombobox extends AuroElement {
14928
14964
  // Clear aria-activedescendant when dropdown closes
14929
14965
  if (!this.dropdownOpen && this.input) {
14930
14966
  this.input.setActiveDescendant(null);
14931
- this.optionActive = null;
14932
-
14933
- // Remove the highlighted state from all menu options so re-opening
14934
- // the dropdown doesn't show a stale highlight.
14935
- if (this.options) {
14936
- this.options.forEach((opt) => {
14937
- opt.active = false;
14938
- opt.classList.remove('active');
14939
- });
14940
- }
14941
14967
 
14942
14968
  // Restore pointer events on the menu in case they were disabled
14943
14969
  // during fullscreen open to prevent touch pass-through.
14944
14970
  this.menu.style.pointerEvents = '';
14945
14971
 
14946
- restoreTriggerAfterClose(this.dropdown, this.input);
14972
+ // When closing a fullscreen bib, restore focus to the trigger so that
14973
+ // keyboard navigation continues from the correct place in the page
14974
+ if (this.dropdown.isBibFullscreen) {
14975
+ restoreTriggerAfterClose(this.dropdown, this.input);
14976
+ }
14947
14977
  }
14948
14978
 
14949
14979
  if (this.dropdownOpen) {
@@ -14978,13 +15008,6 @@ class AuroCombobox extends AuroElement {
14978
15008
  this.setInputFocus();
14979
15009
  this._inFullscreenTransition = false;
14980
15010
  });
14981
- } else {
14982
- // wait a frame in case the bib gets hidden immediately after showing because there is no value
14983
- setTimeout(() => {
14984
- if (this.componentHasFocus) {
14985
- this.setInputFocus();
14986
- }
14987
- }, 0);
14988
15011
  }
14989
15012
  }
14990
15013
  });
@@ -15034,7 +15057,25 @@ class AuroCombobox extends AuroElement {
15034
15057
  setClearBtnFocus() {
15035
15058
  const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
15036
15059
  if (clearBtn) {
15037
- clearBtn.focus();
15060
+ // Wait for the element to fully render across
15061
+ // multiple Lit update cycles before moving focus
15062
+ doubleRaf(() => {
15063
+ clearBtn.focus();
15064
+ });
15065
+ }
15066
+ }
15067
+
15068
+ /**
15069
+ * @private
15070
+ */
15071
+ setTriggerInputFocus() {
15072
+ const input = this.input.shadowRoot.querySelector('input');
15073
+ if (input) {
15074
+ // Wait for the element to fully render across
15075
+ // multiple Lit update cycles before moving focus
15076
+ doubleRaf(() => {
15077
+ input.focus();
15078
+ });
15038
15079
  }
15039
15080
  }
15040
15081