@aurodesignsystem-dev/auro-formkit 0.0.0-pr1401.0 → 0.0.0-pr1401.2

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 (37) 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 +60 -15
  6. package/components/combobox/demo/index.min.js +60 -15
  7. package/components/combobox/dist/comboboxKeyboardStrategy.d.ts +1 -1
  8. package/components/combobox/dist/index.js +60 -15
  9. package/components/combobox/dist/registered.js +60 -15
  10. package/components/counter/demo/api.min.js +2 -2
  11. package/components/counter/demo/index.min.js +2 -2
  12. package/components/counter/dist/index.js +2 -2
  13. package/components/counter/dist/registered.js +2 -2
  14. package/components/datepicker/demo/api.min.js +3 -3
  15. package/components/datepicker/demo/index.min.js +3 -3
  16. package/components/datepicker/dist/index.js +3 -3
  17. package/components/datepicker/dist/registered.js +3 -3
  18. package/components/dropdown/demo/api.min.js +1 -1
  19. package/components/dropdown/demo/index.min.js +1 -1
  20. package/components/dropdown/dist/index.js +1 -1
  21. package/components/dropdown/dist/registered.js +1 -1
  22. package/components/form/demo/api.min.js +116 -33
  23. package/components/form/demo/index.min.js +116 -33
  24. package/components/input/demo/api.min.js +1 -1
  25. package/components/input/demo/index.min.js +1 -1
  26. package/components/input/dist/index.js +1 -1
  27. package/components/input/dist/registered.js +1 -1
  28. package/components/radio/demo/api.min.js +1 -1
  29. package/components/radio/demo/index.min.js +1 -1
  30. package/components/radio/dist/index.js +1 -1
  31. package/components/radio/dist/registered.js +1 -1
  32. package/components/select/demo/api.min.js +48 -10
  33. package/components/select/demo/index.min.js +48 -10
  34. package/components/select/dist/index.js +48 -10
  35. package/components/select/dist/registered.js +48 -10
  36. package/custom-elements.json +1395 -1395
  37. package/package.json +1 -1
@@ -1687,7 +1687,7 @@ class AuroHelpText extends i$2 {
1687
1687
  }
1688
1688
  }
1689
1689
 
1690
- var formkitVersion = '202603262341';
1690
+ var formkitVersion = '202603272353';
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 = '202603262341';
1682
+ var formkitVersion = '202603272353';
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 = '202603262341';
1635
+ var formkitVersion = '202603272353';
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 = '202603262341';
1635
+ var formkitVersion = '202603272353';
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.
@@ -1137,7 +1137,29 @@ const ANNOUNCEMENT_DURATION_MS = 1000;
1137
1137
  // in the first component's live region.
1138
1138
  const pendingClearTimeouts = new WeakMap();
1139
1139
 
1140
+ /**
1141
+ * Returns the shadow root where live-region announcements should be routed.
1142
+ *
1143
+ * In fullscreen mode the component's own live region sits outside the modal
1144
+ * dialog and is inert, so announcements must go to the bib's live region
1145
+ * (inside the dialog) instead.
1146
+ *
1147
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element.
1148
+ * @param {ShadowRoot} fallbackRoot - The component's own shadow root (used in desktop mode).
1149
+ * @returns {ShadowRoot|null} The shadow root containing the target `#srAnnouncement` element,
1150
+ * or `null` when fullscreen mode is active but the bib shadow root is not yet available
1151
+ * (the announcement is silently skipped rather than sent to the inert host shadow root).
1152
+ */
1153
+ function getAnnouncementRoot(dropdown, fallbackRoot) {
1154
+ if (dropdown.isBibFullscreen) {
1155
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1156
+ return (bibEl && bibEl.shadowRoot) || null;
1157
+ }
1158
+ return fallbackRoot;
1159
+ }
1160
+
1140
1161
  function announceToScreenReader(shadowRoot, text) {
1162
+ if (!shadowRoot) return;
1141
1163
  const liveRegion = shadowRoot.querySelector('#srAnnouncement');
1142
1164
  if (liveRegion) {
1143
1165
  // Cancel any pending clear so a previous announcement's timeout
@@ -1201,6 +1223,27 @@ function guardTouchPassthrough(element) {
1201
1223
  }, { once: true });
1202
1224
  }
1203
1225
 
1226
+ /**
1227
+ * Closes the fullscreen dialog element synchronously.
1228
+ *
1229
+ * When a dropdown closes, Lit's async update cycle may call `dialog.close()`
1230
+ * too late — the browser's native focus restoration (back to `document.body`)
1231
+ * can race with the `requestAnimationFrame` in {@link restoreTriggerAfterClose},
1232
+ * stealing focus back to `body` after it was already placed on the trigger.
1233
+ *
1234
+ * Calling this *before* `restoreTriggerAfterClose` ensures the dialog's native
1235
+ * focus restore fires first, so the rAF wins the race.
1236
+ *
1237
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element whose bib may
1238
+ * contain a `<dialog>`.
1239
+ */
1240
+ function closeFullscreenDialog(dropdown) {
1241
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1242
+ if (bibEl) {
1243
+ bibEl.close();
1244
+ }
1245
+ }
1246
+
1204
1247
  /**
1205
1248
  * Restores the dropdown trigger after a fullscreen dialog closes.
1206
1249
  *
@@ -1332,7 +1375,7 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1332
1375
  }
1333
1376
 
1334
1377
  const comboboxKeyboardStrategy = {
1335
- async Enter(component, evt, ctx) {
1378
+ Enter(component, evt, ctx) {
1336
1379
  // If the clear button has focus, let the browser activate it normally.
1337
1380
  // stopPropagation prevents parent containers (e.g., forms) from treating
1338
1381
  // Enter as a submit, but we must NOT call preventDefault — that would
@@ -1343,11 +1386,15 @@ const comboboxKeyboardStrategy = {
1343
1386
  }
1344
1387
 
1345
1388
  if (ctx.isExpanded && component.optionActive) {
1346
- component.menu.makeSelection();
1347
- await component.updateComplete;
1348
1389
  evt.preventDefault();
1349
1390
  evt.stopPropagation();
1350
- component.setClearBtnFocus();
1391
+ // Set flags before makeSelection so the showBib guard and the
1392
+ // auroDropdown-toggled close handler both see them when the value
1393
+ // change propagates through Lit's microtask update cycle.
1394
+ component._focusClearBtnAfterClose = true;
1395
+ component._clearBtnFocusPending = true;
1396
+ component.menu.makeSelection();
1397
+ component.hideBib();
1351
1398
  } else {
1352
1399
  // Prevent the keypress from bubbling to parent containers (e.g., forms)
1353
1400
  // which could interpret Enter as a submit or trigger other unintended behavior.
@@ -1399,10 +1446,12 @@ const comboboxKeyboardStrategy = {
1399
1446
  // No active option, input has a value, clear button not focused →
1400
1447
  // move focus to the dialog's clear button.
1401
1448
  if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1449
+
1402
1450
  // Force clear button container visible to work around Safari not
1403
1451
  // propagating :focus-within through shadow DOM boundaries, which
1404
1452
  // causes .wrapper:not(:focus-within) to hide .notification.clear.
1405
1453
  const clearContainer = clearBtn.closest('.clear');
1454
+
1406
1455
  if (clearContainer) {
1407
1456
  clearContainer.style.display = 'flex';
1408
1457
  clearBtn.addEventListener('focusout', () => {
@@ -5087,7 +5136,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5087
5136
  }
5088
5137
  };
5089
5138
 
5090
- var formkitVersion$2 = '202603262341';
5139
+ var formkitVersion$2 = '202603272353';
5091
5140
 
5092
5141
  let AuroElement$2 = class AuroElement extends i$4 {
5093
5142
  static get properties() {
@@ -12851,7 +12900,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12851
12900
  }
12852
12901
  };
12853
12902
 
12854
- var formkitVersion$1 = '202603262341';
12903
+ var formkitVersion$1 = '202603272353';
12855
12904
 
12856
12905
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12857
12906
  // See LICENSE in the project root for license information.
@@ -13890,7 +13939,7 @@ class AuroBibtemplate extends i$4 {
13890
13939
  }
13891
13940
  }
13892
13941
 
13893
- var formkitVersion = '202603262341';
13942
+ var formkitVersion = '202603272353';
13894
13943
 
13895
13944
  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}`;
13896
13945
 
@@ -14981,6 +15030,8 @@ class AuroCombobox extends AuroElement {
14981
15030
  // during fullscreen open to prevent touch pass-through.
14982
15031
  this.menu.style.pointerEvents = '';
14983
15032
 
15033
+ closeFullscreenDialog(this.dropdown);
15034
+
14984
15035
  const shouldFocusClearBtn = this._focusClearBtnAfterClose;
14985
15036
  this._focusClearBtnAfterClose = false;
14986
15037
 
@@ -15107,6 +15158,7 @@ class AuroCombobox extends AuroElement {
15107
15158
  // the CSS rule `.wrapper:not(:focus-within) .notification.clear`
15108
15159
  // hides the container with display:none, preventing focus.
15109
15160
  const clearContainer = clearBtn.closest('.clear');
15161
+
15110
15162
  if (clearContainer) {
15111
15163
  clearContainer.style.display = 'flex';
15112
15164
  clearBtn.addEventListener('focusout', () => {
@@ -15291,14 +15343,7 @@ class AuroCombobox extends AuroElement {
15291
15343
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
15292
15344
  const optionCount = this.availableOptions.length;
15293
15345
 
15294
- // In fullscreen mode the combobox's live region is outside the modal
15295
- // dialog and inert, so route announcements to the bib's live region
15296
- // which is inside the dialog.
15297
- const bibEl = this.dropdown.bibElement && this.dropdown.bibElement.value;
15298
- const bibShadowRoot = bibEl && bibEl.shadowRoot;
15299
- const announcementRoot = this.dropdown.isBibFullscreen && bibShadowRoot
15300
- ? bibShadowRoot
15301
- : this.shadowRoot;
15346
+ const announcementRoot = getAnnouncementRoot(this.dropdown, this.shadowRoot);
15302
15347
 
15303
15348
  announceToScreenReader(announcementRoot, `${optionText}${selectedState}, ${optionIndex} of ${optionCount}`);
15304
15349
  }
@@ -1060,7 +1060,29 @@ const ANNOUNCEMENT_DURATION_MS = 1000;
1060
1060
  // in the first component's live region.
1061
1061
  const pendingClearTimeouts = new WeakMap();
1062
1062
 
1063
+ /**
1064
+ * Returns the shadow root where live-region announcements should be routed.
1065
+ *
1066
+ * In fullscreen mode the component's own live region sits outside the modal
1067
+ * dialog and is inert, so announcements must go to the bib's live region
1068
+ * (inside the dialog) instead.
1069
+ *
1070
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element.
1071
+ * @param {ShadowRoot} fallbackRoot - The component's own shadow root (used in desktop mode).
1072
+ * @returns {ShadowRoot|null} The shadow root containing the target `#srAnnouncement` element,
1073
+ * or `null` when fullscreen mode is active but the bib shadow root is not yet available
1074
+ * (the announcement is silently skipped rather than sent to the inert host shadow root).
1075
+ */
1076
+ function getAnnouncementRoot(dropdown, fallbackRoot) {
1077
+ if (dropdown.isBibFullscreen) {
1078
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1079
+ return (bibEl && bibEl.shadowRoot) || null;
1080
+ }
1081
+ return fallbackRoot;
1082
+ }
1083
+
1063
1084
  function announceToScreenReader(shadowRoot, text) {
1085
+ if (!shadowRoot) return;
1064
1086
  const liveRegion = shadowRoot.querySelector('#srAnnouncement');
1065
1087
  if (liveRegion) {
1066
1088
  // Cancel any pending clear so a previous announcement's timeout
@@ -1124,6 +1146,27 @@ function guardTouchPassthrough(element) {
1124
1146
  }, { once: true });
1125
1147
  }
1126
1148
 
1149
+ /**
1150
+ * Closes the fullscreen dialog element synchronously.
1151
+ *
1152
+ * When a dropdown closes, Lit's async update cycle may call `dialog.close()`
1153
+ * too late — the browser's native focus restoration (back to `document.body`)
1154
+ * can race with the `requestAnimationFrame` in {@link restoreTriggerAfterClose},
1155
+ * stealing focus back to `body` after it was already placed on the trigger.
1156
+ *
1157
+ * Calling this *before* `restoreTriggerAfterClose` ensures the dialog's native
1158
+ * focus restore fires first, so the rAF wins the race.
1159
+ *
1160
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element whose bib may
1161
+ * contain a `<dialog>`.
1162
+ */
1163
+ function closeFullscreenDialog(dropdown) {
1164
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1165
+ if (bibEl) {
1166
+ bibEl.close();
1167
+ }
1168
+ }
1169
+
1127
1170
  /**
1128
1171
  * Restores the dropdown trigger after a fullscreen dialog closes.
1129
1172
  *
@@ -1255,7 +1298,7 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1255
1298
  }
1256
1299
 
1257
1300
  const comboboxKeyboardStrategy = {
1258
- async Enter(component, evt, ctx) {
1301
+ Enter(component, evt, ctx) {
1259
1302
  // If the clear button has focus, let the browser activate it normally.
1260
1303
  // stopPropagation prevents parent containers (e.g., forms) from treating
1261
1304
  // Enter as a submit, but we must NOT call preventDefault — that would
@@ -1266,11 +1309,15 @@ const comboboxKeyboardStrategy = {
1266
1309
  }
1267
1310
 
1268
1311
  if (ctx.isExpanded && component.optionActive) {
1269
- component.menu.makeSelection();
1270
- await component.updateComplete;
1271
1312
  evt.preventDefault();
1272
1313
  evt.stopPropagation();
1273
- component.setClearBtnFocus();
1314
+ // Set flags before makeSelection so the showBib guard and the
1315
+ // auroDropdown-toggled close handler both see them when the value
1316
+ // change propagates through Lit's microtask update cycle.
1317
+ component._focusClearBtnAfterClose = true;
1318
+ component._clearBtnFocusPending = true;
1319
+ component.menu.makeSelection();
1320
+ component.hideBib();
1274
1321
  } else {
1275
1322
  // Prevent the keypress from bubbling to parent containers (e.g., forms)
1276
1323
  // which could interpret Enter as a submit or trigger other unintended behavior.
@@ -1322,10 +1369,12 @@ const comboboxKeyboardStrategy = {
1322
1369
  // No active option, input has a value, clear button not focused →
1323
1370
  // move focus to the dialog's clear button.
1324
1371
  if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1372
+
1325
1373
  // Force clear button container visible to work around Safari not
1326
1374
  // propagating :focus-within through shadow DOM boundaries, which
1327
1375
  // causes .wrapper:not(:focus-within) to hide .notification.clear.
1328
1376
  const clearContainer = clearBtn.closest('.clear');
1377
+
1329
1378
  if (clearContainer) {
1330
1379
  clearContainer.style.display = 'flex';
1331
1380
  clearBtn.addEventListener('focusout', () => {
@@ -5010,7 +5059,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$4 {
5010
5059
  }
5011
5060
  };
5012
5061
 
5013
- var formkitVersion$2 = '202603262341';
5062
+ var formkitVersion$2 = '202603272353';
5014
5063
 
5015
5064
  let AuroElement$2 = class AuroElement extends i$4 {
5016
5065
  static get properties() {
@@ -12774,7 +12823,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$4 {
12774
12823
  }
12775
12824
  };
12776
12825
 
12777
- var formkitVersion$1 = '202603262341';
12826
+ var formkitVersion$1 = '202603272353';
12778
12827
 
12779
12828
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12780
12829
  // See LICENSE in the project root for license information.
@@ -13813,7 +13862,7 @@ class AuroBibtemplate extends i$4 {
13813
13862
  }
13814
13863
  }
13815
13864
 
13816
- var formkitVersion = '202603262341';
13865
+ var formkitVersion = '202603272353';
13817
13866
 
13818
13867
  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}`;
13819
13868
 
@@ -14904,6 +14953,8 @@ class AuroCombobox extends AuroElement {
14904
14953
  // during fullscreen open to prevent touch pass-through.
14905
14954
  this.menu.style.pointerEvents = '';
14906
14955
 
14956
+ closeFullscreenDialog(this.dropdown);
14957
+
14907
14958
  const shouldFocusClearBtn = this._focusClearBtnAfterClose;
14908
14959
  this._focusClearBtnAfterClose = false;
14909
14960
 
@@ -15030,6 +15081,7 @@ class AuroCombobox extends AuroElement {
15030
15081
  // the CSS rule `.wrapper:not(:focus-within) .notification.clear`
15031
15082
  // hides the container with display:none, preventing focus.
15032
15083
  const clearContainer = clearBtn.closest('.clear');
15084
+
15033
15085
  if (clearContainer) {
15034
15086
  clearContainer.style.display = 'flex';
15035
15087
  clearBtn.addEventListener('focusout', () => {
@@ -15214,14 +15266,7 @@ class AuroCombobox extends AuroElement {
15214
15266
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
15215
15267
  const optionCount = this.availableOptions.length;
15216
15268
 
15217
- // In fullscreen mode the combobox's live region is outside the modal
15218
- // dialog and inert, so route announcements to the bib's live region
15219
- // which is inside the dialog.
15220
- const bibEl = this.dropdown.bibElement && this.dropdown.bibElement.value;
15221
- const bibShadowRoot = bibEl && bibEl.shadowRoot;
15222
- const announcementRoot = this.dropdown.isBibFullscreen && bibShadowRoot
15223
- ? bibShadowRoot
15224
- : this.shadowRoot;
15269
+ const announcementRoot = getAnnouncementRoot(this.dropdown, this.shadowRoot);
15225
15270
 
15226
15271
  announceToScreenReader(announcementRoot, `${optionText}${selectedState}, ${optionIndex} of ${optionCount}`);
15227
15272
  }
@@ -1,5 +1,5 @@
1
1
  export namespace comboboxKeyboardStrategy {
2
- function Enter(component: any, evt: any, ctx: any): Promise<void>;
2
+ function Enter(component: any, evt: any, ctx: any): void;
3
3
  function Tab(component: any, evt: any, ctx: any): void;
4
4
  function ArrowUp(component: any, evt: any, ctx: any): void;
5
5
  function ArrowDown(component: any, evt: any, ctx: any): void;
@@ -1023,7 +1023,29 @@ const ANNOUNCEMENT_DURATION_MS = 1000;
1023
1023
  // in the first component's live region.
1024
1024
  const pendingClearTimeouts = new WeakMap();
1025
1025
 
1026
+ /**
1027
+ * Returns the shadow root where live-region announcements should be routed.
1028
+ *
1029
+ * In fullscreen mode the component's own live region sits outside the modal
1030
+ * dialog and is inert, so announcements must go to the bib's live region
1031
+ * (inside the dialog) instead.
1032
+ *
1033
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element.
1034
+ * @param {ShadowRoot} fallbackRoot - The component's own shadow root (used in desktop mode).
1035
+ * @returns {ShadowRoot|null} The shadow root containing the target `#srAnnouncement` element,
1036
+ * or `null` when fullscreen mode is active but the bib shadow root is not yet available
1037
+ * (the announcement is silently skipped rather than sent to the inert host shadow root).
1038
+ */
1039
+ function getAnnouncementRoot(dropdown, fallbackRoot) {
1040
+ if (dropdown.isBibFullscreen) {
1041
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1042
+ return (bibEl && bibEl.shadowRoot) || null;
1043
+ }
1044
+ return fallbackRoot;
1045
+ }
1046
+
1026
1047
  function announceToScreenReader(shadowRoot, text) {
1048
+ if (!shadowRoot) return;
1027
1049
  const liveRegion = shadowRoot.querySelector('#srAnnouncement');
1028
1050
  if (liveRegion) {
1029
1051
  // Cancel any pending clear so a previous announcement's timeout
@@ -1087,6 +1109,27 @@ function guardTouchPassthrough(element) {
1087
1109
  }, { once: true });
1088
1110
  }
1089
1111
 
1112
+ /**
1113
+ * Closes the fullscreen dialog element synchronously.
1114
+ *
1115
+ * When a dropdown closes, Lit's async update cycle may call `dialog.close()`
1116
+ * too late — the browser's native focus restoration (back to `document.body`)
1117
+ * can race with the `requestAnimationFrame` in {@link restoreTriggerAfterClose},
1118
+ * stealing focus back to `body` after it was already placed on the trigger.
1119
+ *
1120
+ * Calling this *before* `restoreTriggerAfterClose` ensures the dialog's native
1121
+ * focus restore fires first, so the rAF wins the race.
1122
+ *
1123
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element whose bib may
1124
+ * contain a `<dialog>`.
1125
+ */
1126
+ function closeFullscreenDialog(dropdown) {
1127
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1128
+ if (bibEl) {
1129
+ bibEl.close();
1130
+ }
1131
+ }
1132
+
1090
1133
  /**
1091
1134
  * Restores the dropdown trigger after a fullscreen dialog closes.
1092
1135
  *
@@ -1212,7 +1255,7 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1212
1255
  }
1213
1256
 
1214
1257
  const comboboxKeyboardStrategy = {
1215
- async Enter(component, evt, ctx) {
1258
+ Enter(component, evt, ctx) {
1216
1259
  // If the clear button has focus, let the browser activate it normally.
1217
1260
  // stopPropagation prevents parent containers (e.g., forms) from treating
1218
1261
  // Enter as a submit, but we must NOT call preventDefault — that would
@@ -1223,11 +1266,15 @@ const comboboxKeyboardStrategy = {
1223
1266
  }
1224
1267
 
1225
1268
  if (ctx.isExpanded && component.optionActive) {
1226
- component.menu.makeSelection();
1227
- await component.updateComplete;
1228
1269
  evt.preventDefault();
1229
1270
  evt.stopPropagation();
1230
- component.setClearBtnFocus();
1271
+ // Set flags before makeSelection so the showBib guard and the
1272
+ // auroDropdown-toggled close handler both see them when the value
1273
+ // change propagates through Lit's microtask update cycle.
1274
+ component._focusClearBtnAfterClose = true;
1275
+ component._clearBtnFocusPending = true;
1276
+ component.menu.makeSelection();
1277
+ component.hideBib();
1231
1278
  } else {
1232
1279
  // Prevent the keypress from bubbling to parent containers (e.g., forms)
1233
1280
  // which could interpret Enter as a submit or trigger other unintended behavior.
@@ -1279,10 +1326,12 @@ const comboboxKeyboardStrategy = {
1279
1326
  // No active option, input has a value, clear button not focused →
1280
1327
  // move focus to the dialog's clear button.
1281
1328
  if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1329
+
1282
1330
  // Force clear button container visible to work around Safari not
1283
1331
  // propagating :focus-within through shadow DOM boundaries, which
1284
1332
  // causes .wrapper:not(:focus-within) to hide .notification.clear.
1285
1333
  const clearContainer = clearBtn.closest('.clear');
1334
+
1286
1335
  if (clearContainer) {
1287
1336
  clearContainer.style.display = 'flex';
1288
1337
  clearBtn.addEventListener('focusout', () => {
@@ -4943,7 +4992,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
4943
4992
  }
4944
4993
  };
4945
4994
 
4946
- var formkitVersion$2 = '202603262341';
4995
+ var formkitVersion$2 = '202603272353';
4947
4996
 
4948
4997
  let AuroElement$2 = class AuroElement extends LitElement {
4949
4998
  static get properties() {
@@ -12700,7 +12749,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
12700
12749
  }
12701
12750
  };
12702
12751
 
12703
- var formkitVersion$1 = '202603262341';
12752
+ var formkitVersion$1 = '202603272353';
12704
12753
 
12705
12754
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12706
12755
  // See LICENSE in the project root for license information.
@@ -13739,7 +13788,7 @@ class AuroBibtemplate extends LitElement {
13739
13788
  }
13740
13789
  }
13741
13790
 
13742
- var formkitVersion = '202603262341';
13791
+ var formkitVersion = '202603272353';
13743
13792
 
13744
13793
  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}`;
13745
13794
 
@@ -14830,6 +14879,8 @@ class AuroCombobox extends AuroElement {
14830
14879
  // during fullscreen open to prevent touch pass-through.
14831
14880
  this.menu.style.pointerEvents = '';
14832
14881
 
14882
+ closeFullscreenDialog(this.dropdown);
14883
+
14833
14884
  const shouldFocusClearBtn = this._focusClearBtnAfterClose;
14834
14885
  this._focusClearBtnAfterClose = false;
14835
14886
 
@@ -14956,6 +15007,7 @@ class AuroCombobox extends AuroElement {
14956
15007
  // the CSS rule `.wrapper:not(:focus-within) .notification.clear`
14957
15008
  // hides the container with display:none, preventing focus.
14958
15009
  const clearContainer = clearBtn.closest('.clear');
15010
+
14959
15011
  if (clearContainer) {
14960
15012
  clearContainer.style.display = 'flex';
14961
15013
  clearBtn.addEventListener('focusout', () => {
@@ -15140,14 +15192,7 @@ class AuroCombobox extends AuroElement {
15140
15192
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
15141
15193
  const optionCount = this.availableOptions.length;
15142
15194
 
15143
- // In fullscreen mode the combobox's live region is outside the modal
15144
- // dialog and inert, so route announcements to the bib's live region
15145
- // which is inside the dialog.
15146
- const bibEl = this.dropdown.bibElement && this.dropdown.bibElement.value;
15147
- const bibShadowRoot = bibEl && bibEl.shadowRoot;
15148
- const announcementRoot = this.dropdown.isBibFullscreen && bibShadowRoot
15149
- ? bibShadowRoot
15150
- : this.shadowRoot;
15195
+ const announcementRoot = getAnnouncementRoot(this.dropdown, this.shadowRoot);
15151
15196
 
15152
15197
  announceToScreenReader(announcementRoot, `${optionText}${selectedState}, ${optionIndex} of ${optionCount}`);
15153
15198
  }
@@ -1023,7 +1023,29 @@ const ANNOUNCEMENT_DURATION_MS = 1000;
1023
1023
  // in the first component's live region.
1024
1024
  const pendingClearTimeouts = new WeakMap();
1025
1025
 
1026
+ /**
1027
+ * Returns the shadow root where live-region announcements should be routed.
1028
+ *
1029
+ * In fullscreen mode the component's own live region sits outside the modal
1030
+ * dialog and is inert, so announcements must go to the bib's live region
1031
+ * (inside the dialog) instead.
1032
+ *
1033
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element.
1034
+ * @param {ShadowRoot} fallbackRoot - The component's own shadow root (used in desktop mode).
1035
+ * @returns {ShadowRoot|null} The shadow root containing the target `#srAnnouncement` element,
1036
+ * or `null` when fullscreen mode is active but the bib shadow root is not yet available
1037
+ * (the announcement is silently skipped rather than sent to the inert host shadow root).
1038
+ */
1039
+ function getAnnouncementRoot(dropdown, fallbackRoot) {
1040
+ if (dropdown.isBibFullscreen) {
1041
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1042
+ return (bibEl && bibEl.shadowRoot) || null;
1043
+ }
1044
+ return fallbackRoot;
1045
+ }
1046
+
1026
1047
  function announceToScreenReader(shadowRoot, text) {
1048
+ if (!shadowRoot) return;
1027
1049
  const liveRegion = shadowRoot.querySelector('#srAnnouncement');
1028
1050
  if (liveRegion) {
1029
1051
  // Cancel any pending clear so a previous announcement's timeout
@@ -1087,6 +1109,27 @@ function guardTouchPassthrough(element) {
1087
1109
  }, { once: true });
1088
1110
  }
1089
1111
 
1112
+ /**
1113
+ * Closes the fullscreen dialog element synchronously.
1114
+ *
1115
+ * When a dropdown closes, Lit's async update cycle may call `dialog.close()`
1116
+ * too late — the browser's native focus restoration (back to `document.body`)
1117
+ * can race with the `requestAnimationFrame` in {@link restoreTriggerAfterClose},
1118
+ * stealing focus back to `body` after it was already placed on the trigger.
1119
+ *
1120
+ * Calling this *before* `restoreTriggerAfterClose` ensures the dialog's native
1121
+ * focus restore fires first, so the rAF wins the race.
1122
+ *
1123
+ * @param {HTMLElement} dropdown - The `auro-dropdown` element whose bib may
1124
+ * contain a `<dialog>`.
1125
+ */
1126
+ function closeFullscreenDialog(dropdown) {
1127
+ const bibEl = dropdown.bibElement && dropdown.bibElement.value;
1128
+ if (bibEl) {
1129
+ bibEl.close();
1130
+ }
1131
+ }
1132
+
1090
1133
  /**
1091
1134
  * Restores the dropdown trigger after a fullscreen dialog closes.
1092
1135
  *
@@ -1212,7 +1255,7 @@ function isClearBtnFocused(ctx, clearBtn = getClearBtn(ctx)) {
1212
1255
  }
1213
1256
 
1214
1257
  const comboboxKeyboardStrategy = {
1215
- async Enter(component, evt, ctx) {
1258
+ Enter(component, evt, ctx) {
1216
1259
  // If the clear button has focus, let the browser activate it normally.
1217
1260
  // stopPropagation prevents parent containers (e.g., forms) from treating
1218
1261
  // Enter as a submit, but we must NOT call preventDefault — that would
@@ -1223,11 +1266,15 @@ const comboboxKeyboardStrategy = {
1223
1266
  }
1224
1267
 
1225
1268
  if (ctx.isExpanded && component.optionActive) {
1226
- component.menu.makeSelection();
1227
- await component.updateComplete;
1228
1269
  evt.preventDefault();
1229
1270
  evt.stopPropagation();
1230
- component.setClearBtnFocus();
1271
+ // Set flags before makeSelection so the showBib guard and the
1272
+ // auroDropdown-toggled close handler both see them when the value
1273
+ // change propagates through Lit's microtask update cycle.
1274
+ component._focusClearBtnAfterClose = true;
1275
+ component._clearBtnFocusPending = true;
1276
+ component.menu.makeSelection();
1277
+ component.hideBib();
1231
1278
  } else {
1232
1279
  // Prevent the keypress from bubbling to parent containers (e.g., forms)
1233
1280
  // which could interpret Enter as a submit or trigger other unintended behavior.
@@ -1279,10 +1326,12 @@ const comboboxKeyboardStrategy = {
1279
1326
  // No active option, input has a value, clear button not focused →
1280
1327
  // move focus to the dialog's clear button.
1281
1328
  if (clearBtn && !clearBtnHasFocus && ctx.activeInput.value) {
1329
+
1282
1330
  // Force clear button container visible to work around Safari not
1283
1331
  // propagating :focus-within through shadow DOM boundaries, which
1284
1332
  // causes .wrapper:not(:focus-within) to hide .notification.clear.
1285
1333
  const clearContainer = clearBtn.closest('.clear');
1334
+
1286
1335
  if (clearContainer) {
1287
1336
  clearContainer.style.display = 'flex';
1288
1337
  clearBtn.addEventListener('focusout', () => {
@@ -4943,7 +4992,7 @@ let AuroHelpText$2 = class AuroHelpText extends LitElement {
4943
4992
  }
4944
4993
  };
4945
4994
 
4946
- var formkitVersion$2 = '202603262341';
4995
+ var formkitVersion$2 = '202603272353';
4947
4996
 
4948
4997
  let AuroElement$2 = class AuroElement extends LitElement {
4949
4998
  static get properties() {
@@ -12700,7 +12749,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
12700
12749
  }
12701
12750
  };
12702
12751
 
12703
- var formkitVersion$1 = '202603262341';
12752
+ var formkitVersion$1 = '202603272353';
12704
12753
 
12705
12754
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12706
12755
  // See LICENSE in the project root for license information.
@@ -13739,7 +13788,7 @@ class AuroBibtemplate extends LitElement {
13739
13788
  }
13740
13789
  }
13741
13790
 
13742
- var formkitVersion = '202603262341';
13791
+ var formkitVersion = '202603272353';
13743
13792
 
13744
13793
  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}`;
13745
13794
 
@@ -14830,6 +14879,8 @@ class AuroCombobox extends AuroElement {
14830
14879
  // during fullscreen open to prevent touch pass-through.
14831
14880
  this.menu.style.pointerEvents = '';
14832
14881
 
14882
+ closeFullscreenDialog(this.dropdown);
14883
+
14833
14884
  const shouldFocusClearBtn = this._focusClearBtnAfterClose;
14834
14885
  this._focusClearBtnAfterClose = false;
14835
14886
 
@@ -14956,6 +15007,7 @@ class AuroCombobox extends AuroElement {
14956
15007
  // the CSS rule `.wrapper:not(:focus-within) .notification.clear`
14957
15008
  // hides the container with display:none, preventing focus.
14958
15009
  const clearContainer = clearBtn.closest('.clear');
15010
+
14959
15011
  if (clearContainer) {
14960
15012
  clearContainer.style.display = 'flex';
14961
15013
  clearBtn.addEventListener('focusout', () => {
@@ -15140,14 +15192,7 @@ class AuroCombobox extends AuroElement {
15140
15192
  const optionIndex = this.availableOptions.indexOf(this.optionActive) + 1;
15141
15193
  const optionCount = this.availableOptions.length;
15142
15194
 
15143
- // In fullscreen mode the combobox's live region is outside the modal
15144
- // dialog and inert, so route announcements to the bib's live region
15145
- // which is inside the dialog.
15146
- const bibEl = this.dropdown.bibElement && this.dropdown.bibElement.value;
15147
- const bibShadowRoot = bibEl && bibEl.shadowRoot;
15148
- const announcementRoot = this.dropdown.isBibFullscreen && bibShadowRoot
15149
- ? bibShadowRoot
15150
- : this.shadowRoot;
15195
+ const announcementRoot = getAnnouncementRoot(this.dropdown, this.shadowRoot);
15151
15196
 
15152
15197
  announceToScreenReader(announcementRoot, `${optionText}${selectedState}, ${optionIndex} of ${optionCount}`);
15153
15198
  }