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

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 (48) 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 +187 -141
  6. package/components/combobox/demo/index.min.js +187 -141
  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 +187 -141
  11. package/components/combobox/dist/registered.js +187 -141
  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.md +1 -1
  17. package/components/datepicker/demo/api.min.js +77 -157
  18. package/components/datepicker/demo/index.min.js +77 -157
  19. package/components/datepicker/demo/keyboardBehavior.md +1 -6
  20. package/components/datepicker/dist/auro-datepicker.d.ts +8 -7
  21. package/components/datepicker/dist/datepickerKeyboardStrategy.d.ts +1 -4
  22. package/components/datepicker/dist/index.js +77 -157
  23. package/components/datepicker/dist/registered.js +77 -157
  24. package/components/dropdown/demo/api.min.js +1 -1
  25. package/components/dropdown/demo/index.min.js +1 -1
  26. package/components/dropdown/dist/index.js +1 -1
  27. package/components/dropdown/dist/registered.js +1 -1
  28. package/components/form/demo/api.min.js +382 -390
  29. package/components/form/demo/index.min.js +382 -390
  30. package/components/input/demo/api.min.js +106 -77
  31. package/components/input/demo/index.min.js +106 -77
  32. package/components/input/dist/auro-input.d.ts +11 -0
  33. package/components/input/dist/base-input.d.ts +1 -0
  34. package/components/input/dist/index.js +36 -18
  35. package/components/input/dist/registered.js +36 -18
  36. package/components/menu/demo/keyboardBehavior.md +0 -0
  37. package/components/radio/demo/api.min.js +1 -1
  38. package/components/radio/demo/index.min.js +1 -1
  39. package/components/radio/demo/keyboardBehavior.md +0 -0
  40. package/components/radio/dist/index.js +1 -1
  41. package/components/radio/dist/registered.js +1 -1
  42. package/components/select/demo/api.min.js +13 -4
  43. package/components/select/demo/index.min.js +13 -4
  44. package/components/select/dist/index.js +13 -4
  45. package/components/select/dist/registered.js +13 -4
  46. package/custom-elements.json +1449 -1401
  47. package/package.json +3 -3
  48. /package/components/datepicker/demo/{keyboardBehavior.html → keyboard-behavior.html} +0 -0
@@ -1687,7 +1687,7 @@ class AuroHelpText extends i$2 {
1687
1687
  }
1688
1688
  }
1689
1689
 
1690
- var formkitVersion = '202604022013';
1690
+ var formkitVersion = '202604032311';
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 = '202604032311';
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 = '202604032311';
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 = '202604032311';
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,33 @@ 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
1346
  return;
1341
1347
  }
1342
1348
 
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
- return;
1363
- }
1364
-
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) {
1349
+ // option display and navigation are prevented if there are no available options
1350
+ if (component.availableOptions.length > 0) {
1368
1351
  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
1352
 
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
- }
1353
+ // navigate if bib is open otherwise open it
1354
+ if (component.dropdown.isPopoverVisible) {
1399
1355
 
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();
1356
+ if (evt.altKey || evt.metaKey) {
1357
+ component.activateLastEnabledAvailableOption();
1405
1358
  } else {
1406
- clearBtn.focus();
1359
+ navigateArrow(component, 'down');
1407
1360
  }
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();
1361
+ } else {
1362
+ component.showBib();
1415
1363
  }
1416
- component.hideBib();
1417
- return;
1418
- }
1419
-
1420
- // Non-fullscreen: select + close
1421
- if (component.menu.optionActive && component.menu.optionActive.value) {
1422
- component.menu.value = component.menu.optionActive.value;
1423
1364
  }
1424
- component.hideBib();
1425
1365
  },
1426
1366
 
1427
1367
  ArrowUp(component, evt, ctx) {
@@ -1430,31 +1370,85 @@ const comboboxKeyboardStrategy = {
1430
1370
  return;
1431
1371
  }
1432
1372
 
1373
+ // option display and navigation are prevented if there are no available options
1433
1374
  if (component.availableOptions.length > 0) {
1434
- component.showBib();
1375
+ evt.preventDefault();
1376
+
1377
+ // navigate if bib is open otherwise open it
1378
+ if (component.dropdown.isPopoverVisible) {
1379
+ if (evt.altKey || evt.metaKey) {
1380
+ component.activateFirstEnabledAvailableOption();
1381
+ } else {
1382
+ navigateArrow(component, 'up');
1383
+ }
1384
+ } else {
1385
+ component.showBib();
1386
+ }
1435
1387
  }
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) {
1388
+ },
1389
+
1390
+ End(component, evt, ctx) {
1391
+ if (ctx.isExpanded) {
1439
1392
  evt.preventDefault();
1440
- navigateArrow(component, 'up');
1393
+ evt.stopPropagation();
1394
+ component.activateLastEnabledAvailableOption();
1441
1395
  }
1442
1396
  },
1443
1397
 
1444
- ArrowDown(component, evt, ctx) {
1445
- // If the clear button has focus, let the browser handle ArrowDown normally.
1398
+ Enter(component, evt, ctx) {
1446
1399
  if (isClearBtnFocused(ctx)) {
1447
- return;
1448
- }
1400
+ // If the clear button has focus, let the browser activate it normally.
1401
+ // stopPropagation prevents parent containers (e.g., forms) from treating
1402
+ // Enter as a submit, but we must NOT call preventDefault — that would
1403
+ // block the browser's built-in "Enter activates focused button" behavior.
1404
+ evt.stopPropagation();
1405
+ } else if (ctx.isExpanded && component.menu.optionActive) {
1406
+ component.menu.makeSelection();
1449
1407
 
1450
- if (component.availableOptions.length > 0) {
1408
+ if (ctx.isModal) {
1409
+ component.setTriggerInputFocus();
1410
+ }
1411
+
1412
+ evt.preventDefault();
1413
+ evt.stopPropagation();
1414
+ } else {
1415
+ // Prevent the keypress from bubbling to parent containers (e.g., forms)
1416
+ // which could interpret Enter as a submit or trigger other unintended behavior.
1417
+ // This is safe because showBib() opens the dialog programmatically,
1418
+ // not via event propagation.
1419
+ evt.preventDefault();
1420
+ evt.stopPropagation();
1451
1421
  component.showBib();
1452
1422
  }
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) {
1423
+ },
1424
+
1425
+ Escape(component, _evt, ctx) {
1426
+ if (ctx.isExpanded && ctx.isModal) {
1427
+ component.setTriggerInputFocus();
1428
+ }
1429
+ },
1430
+
1431
+ Home(component, evt, ctx) {
1432
+ if (ctx.isExpanded) {
1456
1433
  evt.preventDefault();
1457
- navigateArrow(component, 'down');
1434
+ evt.stopPropagation();
1435
+ component.activateFirstEnabledAvailableOption();
1436
+ }
1437
+ },
1438
+
1439
+ Tab(component, evt, ctx) {
1440
+ if (ctx.isExpanded && !isClearBtnFocused(ctx)) {
1441
+ // ClearBtn will not bubble up tab key events when it's focused, so need to manage it here when focused
1442
+ component.menu.makeSelection();
1443
+ component.hideBib();
1444
+
1445
+ // In fullscreen modal mode, closing the dialog does not
1446
+ // automatically restores focus to the input. In the tab case,
1447
+ // Explicitly move focus to the trigger's clear button so the
1448
+ // user can continues tabbing through the page normally.
1449
+ if (ctx.isModal && !evt.shiftKey) {
1450
+ component.setClearBtnFocus();
1451
+ }
1458
1452
  }
1459
1453
  },
1460
1454
  };
@@ -5060,7 +5054,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5060
5054
  }
5061
5055
  };
5062
5056
 
5063
- var formkitVersion$2 = '202604022013';
5057
+ var formkitVersion$2 = '202604032311';
5064
5058
 
5065
5059
  let AuroElement$2 = class AuroElement extends i$4 {
5066
5060
  static get properties() {
@@ -11801,6 +11795,16 @@ class BaseInput extends AuroElement$1 {
11801
11795
  this.wrapperElement = this.shadowRoot.querySelector('.wrapper');
11802
11796
  this.inputElement = this.renderRoot.querySelector('input');
11803
11797
  this.labelElement = this.shadowRoot.querySelector('label');
11798
+ this.clearBtn = this.clearButtonRef.value;
11799
+
11800
+ // This must get moved into inputKeyboardStrategy when implemented
11801
+ this.clearBtn.addEventListener('keydown', (evt) => {
11802
+ evt.stopPropagation();
11803
+ });
11804
+
11805
+ this.clearBtn.addEventListener('click', (evt) => {
11806
+ evt.stopPropagation();
11807
+ });
11804
11808
 
11805
11809
  this.patchInputEvent(this.inputElement);
11806
11810
 
@@ -12824,7 +12828,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12824
12828
  }
12825
12829
  };
12826
12830
 
12827
- var formkitVersion$1 = '202604022013';
12831
+ var formkitVersion$1 = '202604032311';
12828
12832
 
12829
12833
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12830
12834
  // See LICENSE in the project root for license information.
@@ -12881,6 +12885,11 @@ class AuroInput extends BaseInput {
12881
12885
  * @private
12882
12886
  */
12883
12887
  this.iconTag = versioning.generateTag('auro-formkit-input-icon', iconVersion$2, _$2);
12888
+
12889
+ /**
12890
+ * @private
12891
+ */
12892
+ this.clearButtonRef = e$1();
12884
12893
  }
12885
12894
 
12886
12895
  static get styles() {
@@ -12898,6 +12907,19 @@ class AuroInput extends BaseInput {
12898
12907
  ];
12899
12908
  }
12900
12909
 
12910
+ /**
12911
+ * Returns classmap configuration for the clear button visibility.
12912
+ * The button is hidden when the input has no value, is read-only, or is disabled.
12913
+ * @private
12914
+ * @returns {Record<string, boolean>} - Classmap object controlling clear button display state.
12915
+ */
12916
+ get clearBtnClassMap() {
12917
+ return {
12918
+ 'util_displayHidden': !this.hasValue || this.readyOnly || this.disabled
12919
+ };
12920
+ }
12921
+
12922
+
12901
12923
  /**
12902
12924
  * Determines if the HTML input element should be visually hidden.
12903
12925
  * Returns true when display value content exists without focus and has a value,
@@ -13217,10 +13239,11 @@ class AuroInput extends BaseInput {
13217
13239
  <${this.buttonTag}
13218
13240
  @click="${this.handleClickClear}"
13219
13241
  appearance="${this.onDark ? 'inverse' : this.appearance}"
13220
- class="notificationBtn clearBtn"
13242
+ class="notificationBtn clearBtn ${e$3(this.clearBtnClassMap)}"
13221
13243
  shape="circle"
13222
13244
  size="sm"
13223
- variant="ghost">
13245
+ variant="ghost"
13246
+ ${n$2(this.clearButtonRef)}>
13224
13247
  <span><slot name="ariaLabel.clear">Clear Input</slot></span>
13225
13248
  <${this.iconTag}
13226
13249
  aria-hidden="true"
@@ -13365,11 +13388,7 @@ class AuroInput extends BaseInput {
13365
13388
  <div part="accent-right" class="accents right">
13366
13389
  ${this.renderValidationErrorIconHtml()}
13367
13390
  ${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}
13391
+ ${this.renderHtmlActionClear()}
13373
13392
  </div>
13374
13393
  </div>
13375
13394
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13401,11 +13420,7 @@ class AuroInput extends BaseInput {
13401
13420
  ${this.layout.includes('right') || this.layout === "emphasized" ? u$7`
13402
13421
  ${this.renderValidationErrorIconHtml()}
13403
13422
  ` : undefined}
13404
- ${this.hasValue ? u$7`
13405
- ${!this.disabled && !this.readonly ? u$7`
13406
- ${this.renderHtmlActionClear()}
13407
- ` : undefined}
13408
- ` : undefined}
13423
+ ${this.renderHtmlActionClear()}
13409
13424
  </div>
13410
13425
  </div>
13411
13426
  <div class="${e$3(this.helpTextClasses)}" part="inputHelpText">
@@ -13433,11 +13448,7 @@ class AuroInput extends BaseInput {
13433
13448
  </div>
13434
13449
  <div class="accents right">
13435
13450
  ${this.renderValidationErrorIconHtml()}
13436
- ${this.hasValue ? u$7`
13437
- ${!this.disabled && !this.readonly ? u$7`
13438
- ${this.renderHtmlActionClear()}
13439
- ` : undefined}
13440
- ` : undefined}
13451
+ ${this.renderHtmlActionClear()}
13441
13452
  </div>
13442
13453
  </div>
13443
13454
  <div class="helpTextWrapper leftIndent rightIndent" part="inputHelpText">
@@ -13863,7 +13874,7 @@ class AuroBibtemplate extends i$4 {
13863
13874
  }
13864
13875
  }
13865
13876
 
13866
- var formkitVersion = '202604022013';
13877
+ var formkitVersion = '202604032311';
13867
13878
 
13868
13879
  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
13880
 
@@ -14342,6 +14353,7 @@ class AuroCombobox extends AuroElement {
14342
14353
 
14343
14354
  /**
14344
14355
  * Array of available options to display in the dropdown.
14356
+ * This array contains all non-hidden options (e.g., hidden by filtering on input value).
14345
14357
  * @private
14346
14358
  */
14347
14359
  availableOptions: {
@@ -14719,12 +14731,40 @@ class AuroCombobox extends AuroElement {
14719
14731
  AuroLibraryRuntimeUtils$4.prototype.registerComponent(name, AuroCombobox);
14720
14732
  }
14721
14733
 
14734
+ /**
14735
+ * Mark the first available (non-hidden), enabled option as `active`.
14736
+ * @private
14737
+ * @returns {void}
14738
+ */
14739
+ activateFirstEnabledAvailableOption() {
14740
+ const firstEnabledOptionIndex = this.availableOptions.findIndex((opt) => !opt.disabled);
14741
+ this.updateActiveOption(firstEnabledOptionIndex);
14742
+ }
14743
+
14744
+ /**
14745
+ * Mark the last available (non-hidden), enabled option as `active`.
14746
+ * @private
14747
+ * @returns {void}
14748
+ */
14749
+ activateLastEnabledAvailableOption() {
14750
+ let lastEnabledOptionIndex = -1;
14751
+
14752
+ // Work backwards through the available options array to find the last enabled option
14753
+ for (let index = this.availableOptions.length - 1; index >= 0; index -= 1) {
14754
+ if (!this.availableOptions[index].disabled) {
14755
+ lastEnabledOptionIndex = index;
14756
+ break;
14757
+ }
14758
+ }
14759
+
14760
+ this.updateActiveOption(lastEnabledOptionIndex);
14761
+ }
14762
+
14722
14763
  /**
14723
14764
  * Updates the filter for the available options based on the input value.
14724
14765
  * @private
14725
14766
  */
14726
14767
  updateFilter() {
14727
-
14728
14768
  // Reset available options if noFilter is set to false after being true.
14729
14769
  if (this.noFilter) {
14730
14770
  this.availableOptions = [...this.options];
@@ -14843,6 +14883,10 @@ class AuroCombobox extends AuroElement {
14843
14883
  if (this.value && this.input.value && !this.menu.value) {
14844
14884
  this.syncValuesAndStates();
14845
14885
  }
14886
+
14887
+ if (!this.availableOptions.includes(this.menu.optionActive)) {
14888
+ this.activateFirstEnabledAvailableOption();
14889
+ }
14846
14890
  }
14847
14891
 
14848
14892
  /**
@@ -14916,9 +14960,6 @@ class AuroCombobox extends AuroElement {
14916
14960
  if (this.dropdownOpen) {
14917
14961
  const expandedDelay = 150;
14918
14962
  this._expandedTimeout = setTimeout(() => {
14919
- if (!this.value) {
14920
- this.updateActiveOption(0);
14921
- }
14922
14963
  this.triggerExpandedState = true;
14923
14964
  }, expandedDelay);
14924
14965
  } else {
@@ -14928,22 +14969,16 @@ class AuroCombobox extends AuroElement {
14928
14969
  // Clear aria-activedescendant when dropdown closes
14929
14970
  if (!this.dropdownOpen && this.input) {
14930
14971
  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
14972
 
14942
14973
  // Restore pointer events on the menu in case they were disabled
14943
14974
  // during fullscreen open to prevent touch pass-through.
14944
14975
  this.menu.style.pointerEvents = '';
14945
14976
 
14946
- restoreTriggerAfterClose(this.dropdown, this.input);
14977
+ // When closing a fullscreen bib, restore focus to the trigger so that
14978
+ // keyboard navigation continues from the correct place in the page
14979
+ if (this.dropdown.isBibFullscreen) {
14980
+ restoreTriggerAfterClose(this.dropdown, this.input);
14981
+ }
14947
14982
  }
14948
14983
 
14949
14984
  if (this.dropdownOpen) {
@@ -14978,13 +15013,6 @@ class AuroCombobox extends AuroElement {
14978
15013
  this.setInputFocus();
14979
15014
  this._inFullscreenTransition = false;
14980
15015
  });
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
15016
  }
14989
15017
  }
14990
15018
  });
@@ -15034,7 +15062,25 @@ class AuroCombobox extends AuroElement {
15034
15062
  setClearBtnFocus() {
15035
15063
  const clearBtn = this.input.shadowRoot.querySelector('.clearBtn');
15036
15064
  if (clearBtn) {
15037
- clearBtn.focus();
15065
+ // Wait for the element to fully render across
15066
+ // multiple Lit update cycles before moving focus
15067
+ doubleRaf(() => {
15068
+ clearBtn.focus();
15069
+ });
15070
+ }
15071
+ }
15072
+
15073
+ /**
15074
+ * @private
15075
+ */
15076
+ setTriggerInputFocus() {
15077
+ const input = this.input.shadowRoot.querySelector('input');
15078
+ if (input) {
15079
+ // Wait for the element to fully render across
15080
+ // multiple Lit update cycles before moving focus
15081
+ doubleRaf(() => {
15082
+ input.focus();
15083
+ });
15038
15084
  }
15039
15085
  }
15040
15086