@aurodesignsystem-dev/auro-formkit 0.0.0-pr1503.3 → 0.0.0-pr1503.5

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 (190) hide show
  1. package/components/bibtemplate/dist/index.js +1 -1
  2. package/components/bibtemplate/dist/registered.js +1 -1
  3. package/components/checkbox/demo/accessibility.md +1 -1
  4. package/components/checkbox/demo/customize.html +1 -2
  5. package/components/checkbox/demo/customize.min.js +23 -8
  6. package/components/checkbox/demo/getting-started.min.js +23 -8
  7. package/components/checkbox/demo/index.min.js +23 -8
  8. package/components/checkbox/dist/index.js +23 -8
  9. package/components/checkbox/dist/registered.js +23 -8
  10. package/components/combobox/README.md +1 -1
  11. package/components/combobox/demo/accessibility.md +1 -1
  12. package/components/combobox/demo/api.md +2 -2
  13. package/components/combobox/demo/customize.html +1 -2
  14. package/components/combobox/demo/customize.md +166 -142
  15. package/components/combobox/demo/customize.min.js +2515 -2316
  16. package/components/combobox/demo/getting-started.min.js +2515 -2312
  17. package/components/combobox/demo/index.md +2 -1
  18. package/components/combobox/demo/index.min.js +2515 -2312
  19. package/components/combobox/demo/keyboard-behavior.md +3 -146
  20. package/components/combobox/demo/readme.md +1 -1
  21. package/components/combobox/demo/why-combobox.md +2 -2
  22. package/components/combobox/dist/auro-combobox.d.ts +49 -15
  23. package/components/combobox/dist/index.js +1462 -753
  24. package/components/combobox/dist/registered.js +1462 -753
  25. package/components/counter/demo/customize.min.js +188 -244
  26. package/components/counter/demo/index.min.js +188 -244
  27. package/components/counter/dist/auro-counter.d.ts +0 -8
  28. package/components/counter/dist/index.js +188 -244
  29. package/components/counter/dist/registered.js +188 -244
  30. package/components/datepicker/demo/accessibility.md +20 -10
  31. package/components/datepicker/demo/api.md +65 -62
  32. package/components/datepicker/demo/customize.md +180 -40
  33. package/components/datepicker/demo/customize.min.js +1690 -777
  34. package/components/datepicker/demo/getting-started.md +118 -2
  35. package/components/datepicker/demo/index.min.js +1690 -759
  36. package/components/datepicker/demo/keyboard-behavior.md +3 -3
  37. package/components/datepicker/demo/voiceover.md +4 -4
  38. package/components/datepicker/demo/why-datepicker.md +2 -2
  39. package/components/datepicker/dist/{src/auro-calendar-cell.d.ts → auro-calendar-cell.d.ts} +48 -3
  40. package/components/datepicker/dist/{src/auro-calendar.d.ts → auro-calendar.d.ts} +188 -10
  41. package/components/datepicker/dist/{src/auro-datepicker.d.ts → auro-datepicker.d.ts} +89 -6
  42. package/components/datepicker/dist/blackoutUtils.d.ts +43 -0
  43. package/components/datepicker/dist/index.js +1690 -759
  44. package/components/datepicker/dist/registered.js +1690 -759
  45. package/components/dropdown/demo/customize.html +3 -0
  46. package/components/dropdown/demo/customize.min.js +142 -208
  47. package/components/dropdown/demo/getting-started.min.js +131 -207
  48. package/components/dropdown/demo/index.min.js +131 -207
  49. package/components/dropdown/dist/auro-dropdown.d.ts +17 -1
  50. package/components/dropdown/dist/index.js +131 -207
  51. package/components/dropdown/dist/registered.js +131 -207
  52. package/components/form/demo/api.md +3 -3
  53. package/components/form/demo/customize.html +6 -6
  54. package/components/form/demo/customize.md +535 -135
  55. package/components/form/demo/customize.min.js +6307 -4378
  56. package/components/form/demo/getting-started.md +344 -96
  57. package/components/form/demo/getting-started.min.js +6255 -4378
  58. package/components/form/demo/index.min.js +6206 -4378
  59. package/components/form/demo/registerDemoDeps.min.js +5827 -4333
  60. package/components/form/dist/auro-form.d.ts +128 -10
  61. package/components/form/dist/index.js +377 -43
  62. package/components/form/dist/registered.js +377 -43
  63. package/components/input/demo/accessibility.md +1 -1
  64. package/components/input/demo/api.md +58 -57
  65. package/components/input/demo/customize.html +1 -2
  66. package/components/input/demo/customize.md +62 -61
  67. package/components/input/demo/customize.min.js +396 -275
  68. package/components/input/demo/getting-started.min.js +396 -275
  69. package/components/input/demo/index.min.js +396 -275
  70. package/components/input/dist/auro-input.d.ts +1 -1
  71. package/components/input/dist/base-input.d.ts +60 -81
  72. package/components/input/dist/index.js +409 -276
  73. package/components/input/dist/registered.js +396 -275
  74. package/components/input/dist/utilities.d.ts +10 -1
  75. package/components/menu/demo/accessibility.md +9 -4
  76. package/components/menu/demo/api.md +48 -45
  77. package/components/menu/demo/css-only.md +26 -19
  78. package/components/menu/demo/customize.md +307 -75
  79. package/components/menu/demo/design.md +1 -1
  80. package/components/menu/demo/getting-started.md +144 -7
  81. package/components/menu/demo/index.min.js +961 -1341
  82. package/components/menu/demo/keyboard-behavior.md +83 -4
  83. package/components/menu/demo/voiceover.md +21 -14
  84. package/components/menu/demo/why-menu.md +8 -9
  85. package/components/menu/dist/auro-menu-utils.d.ts +19 -0
  86. package/components/menu/dist/auro-menu.d.ts +97 -116
  87. package/components/menu/dist/auro-menuoption.d.ts +39 -133
  88. package/components/menu/dist/index.js +823 -1309
  89. package/components/menu/dist/registered.js +835 -1309
  90. package/components/radio/demo/accessibility.md +1 -1
  91. package/components/radio/demo/customize.min.js +23 -8
  92. package/components/radio/demo/getting-started.min.js +23 -8
  93. package/components/radio/demo/index.min.js +23 -8
  94. package/components/radio/dist/index.js +23 -8
  95. package/components/radio/dist/registered.js +23 -8
  96. package/components/select/demo/accessibility.md +6 -1
  97. package/components/select/demo/api.md +3 -2
  98. package/components/select/demo/customize.html +1 -2
  99. package/components/select/demo/customize.md +210 -5
  100. package/components/select/demo/customize.min.js +1613 -1854
  101. package/components/select/demo/design.md +10 -10
  102. package/components/select/demo/getting-started.md +1 -1
  103. package/components/select/demo/getting-started.min.js +1617 -1903
  104. package/components/select/demo/index.md +2 -2
  105. package/components/select/demo/index.min.js +1613 -1854
  106. package/components/select/demo/keyboard-behavior.md +81 -54
  107. package/components/select/demo/voiceover.md +28 -15
  108. package/components/select/dist/auro-select.d.ts +70 -12
  109. package/components/select/dist/index.js +580 -315
  110. package/components/select/dist/registered.js +580 -315
  111. package/components/select/dist/selectUtils.d.ts +24 -0
  112. package/custom-elements.json +8071 -7919
  113. package/package.json +7 -3
  114. package/components/checkbox/demo/customize.js +0 -22
  115. package/components/checkbox/demo/demo-support.js +0 -1
  116. package/components/checkbox/demo/getting-started.js +0 -22
  117. package/components/checkbox/demo/index.js +0 -8
  118. package/components/checkbox/demo/styles.scss +0 -1
  119. package/components/combobox/demo/customize.js +0 -24
  120. package/components/combobox/demo/demo-support.js +0 -1
  121. package/components/combobox/demo/getting-started.js +0 -21
  122. package/components/combobox/demo/index.js +0 -23
  123. package/components/combobox/demo/styles.scss +0 -1
  124. package/components/counter/demo/customize.js +0 -21
  125. package/components/counter/demo/demo-support.js +0 -1
  126. package/components/counter/demo/index.js +0 -21
  127. package/components/counter/demo/styles.scss +0 -1
  128. package/components/datepicker/demo/customize.js +0 -19
  129. package/components/datepicker/demo/demo-support.js +0 -1
  130. package/components/datepicker/demo/index.js +0 -23
  131. package/components/datepicker/demo/styles.scss +0 -1
  132. package/components/dropdown/demo/customize.js +0 -9
  133. package/components/dropdown/demo/demo-support.js +0 -1
  134. package/components/dropdown/demo/getting-started.js +0 -9
  135. package/components/dropdown/demo/index.js +0 -16
  136. package/components/dropdown/demo/styles.scss +0 -1
  137. package/components/form/demo/customize.js +0 -9
  138. package/components/form/demo/demo-support.js +0 -1
  139. package/components/form/demo/getting-started.js +0 -9
  140. package/components/form/demo/index.js +0 -5
  141. package/components/form/demo/registerDemoDeps.js +0 -23
  142. package/components/form/demo/styles.scss +0 -1
  143. package/components/input/demo/customize.js +0 -25
  144. package/components/input/demo/demo-support.js +0 -1
  145. package/components/input/demo/getting-started.js +0 -8
  146. package/components/input/demo/index.js +0 -8
  147. package/components/input/demo/styles.css +0 -974
  148. package/components/input/demo/styles.scss +0 -1
  149. package/components/menu/demo/demo-support.js +0 -1
  150. package/components/menu/demo/index.js +0 -25
  151. package/components/menu/demo/styles.scss +0 -1
  152. package/components/menu/dist/auro-menu.context.d.ts +0 -238
  153. package/components/radio/demo/customize.js +0 -22
  154. package/components/radio/demo/demo-support.js +0 -1
  155. package/components/radio/demo/getting-started.js +0 -24
  156. package/components/radio/demo/index.js +0 -8
  157. package/components/radio/demo/styles.scss +0 -1
  158. package/components/select/demo/customize.js +0 -11
  159. package/components/select/demo/demo-support.js +0 -1
  160. package/components/select/demo/getting-started.js +0 -26
  161. package/components/select/demo/index.js +0 -11
  162. package/components/select/demo/styles.scss +0 -1
  163. /package/components/counter/dist/styles/{counter-wrapper-color-css.d.ts → counter-group-color-css.d.ts} +0 -0
  164. /package/components/datepicker/dist/{src/auro-calendar-month.d.ts → auro-calendar-month.d.ts} +0 -0
  165. /package/components/datepicker/dist/{src/buttonVersion.d.ts → buttonVersion.d.ts} +0 -0
  166. /package/components/datepicker/dist/{src/datepickerKeyboardStrategy.d.ts → datepickerKeyboardStrategy.d.ts} +0 -0
  167. /package/components/datepicker/dist/{src/iconVersion.d.ts → iconVersion.d.ts} +0 -0
  168. /package/components/datepicker/dist/{src/index.d.ts → index.d.ts} +0 -0
  169. /package/components/datepicker/dist/{src/popoverVersion.d.ts → popoverVersion.d.ts} +0 -0
  170. /package/components/datepicker/dist/{src/styles → styles}/classic/color-css.d.ts +0 -0
  171. /package/components/datepicker/dist/{src/styles → styles}/classic/style-css.d.ts +0 -0
  172. /package/components/datepicker/dist/{src/styles → styles}/color-calendar-css.d.ts +0 -0
  173. /package/components/datepicker/dist/{src/styles → styles}/color-cell-css.d.ts +0 -0
  174. /package/components/datepicker/dist/{src/styles → styles}/color-css.d.ts +0 -0
  175. /package/components/datepicker/dist/{src/styles → styles}/color-month-css.d.ts +0 -0
  176. /package/components/datepicker/dist/{src/styles → styles}/shapeSize-css.d.ts +0 -0
  177. /package/components/datepicker/dist/{src/styles → styles}/snowflake/color-css.d.ts +0 -0
  178. /package/components/datepicker/dist/{src/styles → styles}/snowflake/style-css.d.ts +0 -0
  179. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-cell-css.d.ts +0 -0
  180. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-css.d.ts +0 -0
  181. /package/components/datepicker/dist/{src/styles → styles}/style-auro-calendar-month-css.d.ts +0 -0
  182. /package/components/datepicker/dist/{src/styles → styles}/style-css.d.ts +0 -0
  183. /package/components/datepicker/dist/{src/styles → styles}/tokens-css.d.ts +0 -0
  184. /package/components/datepicker/dist/{src/utilities.d.ts → utilities.d.ts} +0 -0
  185. /package/components/datepicker/dist/{src/utilitiesCalendar.d.ts → utilitiesCalendar.d.ts} +0 -0
  186. /package/components/datepicker/dist/{src/utilitiesCalendarRender.d.ts → utilitiesCalendarRender.d.ts} +0 -0
  187. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/day.d.ts +0 -0
  188. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker-calendar.d.ts +0 -0
  189. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker-cell.d.ts +0 -0
  190. /package/components/datepicker/dist/{src/vendor → vendor}/wc-range-datepicker/range-datepicker.d.ts +0 -0
@@ -418,8 +418,21 @@ class AuroFormValidation {
418
418
  return;
419
419
  }
420
420
 
421
- // Validate that the date passed was the correct format and is a valid date
421
+ // Validate that the date passed was the correct format and is a valid date.
422
+ // For partial date formats, valueObject is never populated; validate them directly.
422
423
  if (elem.value && !elem.valueObject) {
424
+ const isPartialDateFormat = elem.util && !elem.util.isFullDateFormat(elem.type, elem.format);
425
+
426
+ if (isPartialDateFormat) {
427
+ if (!elem.util.isValidPartialDate(elem.value, elem.format)) {
428
+ elem.validity = 'patternMismatch';
429
+ elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
430
+ }
431
+ // Partial date format — validate directly and skip max/min checks since valueObject is undefined.
432
+ return;
433
+ }
434
+
435
+ // Full date format with no valueObject means the value is not a valid calendar date.
423
436
  elem.validity = 'patternMismatch';
424
437
  elem.errorMessage = elem.setCustomValidityPatternMismatch || elem.setCustomValidity || 'Invalid Date Format Entered';
425
438
  return;
@@ -516,15 +529,17 @@ class AuroFormValidation {
516
529
  );
517
530
  }
518
531
 
519
- // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false;
520
- if (this.auroInputElements?.length === 2) {
521
- if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) {
532
+ const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
533
+
534
+ // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false.
535
+ // Skip for combobox: its second auro-input is the fullscreen-bib mirror of the same value, not an independent
536
+ // field (datepicker is the intended consumer — start/end are independently required).
537
+ if (this.auroInputElements?.length === 2 && !isCombobox) {
538
+ if (!this.auroInputElements[1].value || this.auroInputElements[1].value.length === 0) {
522
539
  hasValue = false;
523
540
  }
524
541
  }
525
542
 
526
- const isCombobox = this.runtimeUtils.elementMatch(elem, 'auro-combobox');
527
-
528
543
  if (isCombobox) {
529
544
 
530
545
  if (!elem.persistInput || elem.behavior === "filter") {
@@ -623,7 +638,7 @@ class AuroFormValidation {
623
638
  } else if (this.runtimeUtils.elementMatch(elem, 'auro-input') && elem.errorMessage === '') {
624
639
  const input = elem.renderRoot.querySelector('input');
625
640
 
626
- if (input.validationMessage.length > 0) {
641
+ if (input && input.validationMessage.length > 0) {
627
642
  elem.errorMessage = input.validationMessage;
628
643
  }
629
644
  } else if (this.runtimeUtils.elementMatch(elem, 'auro-combobox') && elem.errorMessage === '') {
@@ -838,13 +853,40 @@ function navigateArrow(component, direction, options = {}) {
838
853
  /* es-module-lexer 1.7.0 */
839
854
  var ImportType$1;!function(A){A[A.Static=1]="Static",A[A.Dynamic=2]="Dynamic",A[A.ImportMeta=3]="ImportMeta",A[A.StaticSourcePhase=4]="StaticSourcePhase",A[A.DynamicSourcePhase=5]="DynamicSourcePhase",A[A.StaticDeferPhase=6]="StaticDeferPhase",A[A.DynamicDeferPhase=7]="DynamicDeferPhase";}(ImportType$1||(ImportType$1={}));1===new Uint8Array(new Uint16Array([1]).buffer)[0];const E$1=()=>{return A="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GzYCHAtBAEEAKAKwCkECajYCsAoCQAJAAkACQEEAECkiAUHhAEYNACABQfcARg0BQQAoArAKIQEMAgtBACgCsAoiAUECakHACEEKEC8NAUEGIQIMAgtBACgCsAoiAS8BAkHpAEcNACABLwEEQfQARw0AQQQhAiABLwEGQegARg0BC0EAIAFBfmo2ArAKDwtBACABIAJBAXRqNgKwCgJAQQEQKUH7AEYNAEEAIAE2ArAKDwtBACgCsAoiACECA0BBACACQQJqNgKwCgJAAkACQEEBECkiAkEiRg0AIAJBJ0cNAUEnEBpBAEEAKAKwCkECajYCsApBARApIQIMAgtBIhAaQQBBACgCsApBAmo2ArAKQQEQKSECDAELIAIQLCECCwJAIAJBOkYNAEEAIAE2ArAKDwtBAEEAKAKwCkECajYCsAoCQEEBECkiAkEiRg0AIAJBJ0YNAEEAIAE2ArAKDwsgAhAaQQBBACgCsApBAmo2ArAKAkACQEEBECkiAkEsRg0AIAJB/QBGDQFBACABNgKwCg8LQQBBACgCsApBAmo2ArAKQQEQKUH9AEYNAEEAKAKwCiECDAELC0EAKALwCSIBIAA2AhAgAUEAKAKwCkECajYCDAttAQJ/AkACQANAAkAgAEH//wNxIgFBd2oiAkEXSw0AQQEgAnRBn4CABHENAgsgAUGgAUYNASAAIQIgARAoDQJBACECQQBBACgCsAoiAEECajYCsAogAC8BAiIADQAMAgsLIAAhAgsgAkH//wNxC6sBAQR/AkACQEEAKAKwCiICLwEAIgNB4QBGDQAgASEEIAAhBQwBC0EAIAJBBGo2ArAKQQEQKSECQQAoArAKIQUCQAJAIAJBIkYNACACQSdGDQAgAhAsGkEAKAKwCiEEDAELIAIQGkEAQQAoArAKQQJqIgQ2ArAKC0EBECkhA0EAKAKwCiECCwJAIAIgBUYNACAFIARBACAAIAAgAUYiAhtBACABIAIbEAILIAMLcgEEf0EAKAKwCiEAQQAoArQKIQECQAJAA0AgAEECaiECIAAgAU8NAQJAAkAgAi8BACIDQaR/ag4CAQQACyACIQAgA0F2ag4EAgEBAgELIABBBGohAAwACwtBACACNgKwChAlQQAPC0EAIAI2ArAKQd0AC0kBA39BACEDAkAgAkUNAAJAA0AgAC0AACIEIAEtAAAiBUcNASABQQFqIQEgAEEBaiEAIAJBf2oiAg0ADAILCyAEIAVrIQMLIAMLC+wBAgBBgAgLzgEAAHgAcABvAHIAdABtAHAAbwByAHQAZgBvAHIAZQB0AGEAbwB1AHIAYwBlAHIAbwBtAHUAbgBjAHQAaQBvAG4AcwBzAGUAcgB0AHYAbwB5AGkAZQBkAGUAbABlAGMAbwBuAHQAaQBuAGkAbgBzAHQAYQBuAHQAeQBiAHIAZQBhAHIAZQB0AHUAcgBkAGUAYgB1AGcAZwBlAGEAdwBhAGkAdABoAHIAdwBoAGkAbABlAGkAZgBjAGEAdABjAGYAaQBuAGEAbABsAGUAbABzAABB0AkLEAEAAAACAAAAAAQAAEA5AAA=","undefined"!=typeof Buffer?Buffer.from(A,"base64"):Uint8Array.from(atob(A),(A=>A.charCodeAt(0)));var A;};WebAssembly.compile(E$1()).then(WebAssembly.instantiate).then((({exports:A})=>{}));
840
855
 
856
+ /**
857
+ * Returns the enabled (non-disabled) options for a menu, safely.
858
+ *
859
+ * Auro-menu's `options` getter returns `undefined` when the menu has no items
860
+ * (initItems sets `items` to undefined for empty menus). Callers that reach for
861
+ * `.find()` / `[...spread]` would otherwise crash; this helper normalizes the
862
+ * empty case to `[]` so array methods are always safe.
863
+ *
864
+ * @param {HTMLElement | null | undefined} menu - The auro-menu element.
865
+ * @returns {Array<HTMLElement>} Non-disabled options, empty array when none.
866
+ */
867
+
868
+ /**
869
+ * Returns the active (selectable + visible) options for type-ahead navigation.
870
+ *
871
+ * Uses auro-menuoption's `isActive` getter, which excludes disabled, hidden,
872
+ * and static options (e.g. `static nomatch` placeholders) so the type-ahead
873
+ * cursor never lands on a non-actionable item. Same empty-safe handling as
874
+ * `getEnabledOptions`.
875
+ *
876
+ * @param {HTMLElement | null | undefined} menu - The auro-menu element.
877
+ * @returns {Array<HTMLElement>} Active options, empty array when none.
878
+ */
879
+ function getActiveOptions(menu) {
880
+ return (menu?.options || []).filter((option) => option.isActive);
881
+ }
882
+
841
883
  /* eslint-disable new-cap */
842
884
 
843
885
  const selectKeyboardStrategy = {
844
886
  ArrowDown(component, evt, ctx) {
845
887
  evt.preventDefault();
846
888
  if (ctx.isExpanded) {
847
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
889
+ if (evt.altKey || evt.ctrlKey) {
848
890
  // navigate to last enabled option
849
891
  selectKeyboardStrategy.End(component, evt, ctx);
850
892
  } else {
@@ -858,7 +900,7 @@ const selectKeyboardStrategy = {
858
900
  ArrowUp(component, evt, ctx) {
859
901
  evt.preventDefault();
860
902
  if (ctx.isExpanded) {
861
- if (evt.altKey || evt.ctrlKey || evt.metaKey) {
903
+ if (evt.altKey || evt.ctrlKey) {
862
904
  // navigate to first enabled option
863
905
  selectKeyboardStrategy.Home(component, evt, ctx);
864
906
  } else {
@@ -870,6 +912,14 @@ const selectKeyboardStrategy = {
870
912
  },
871
913
 
872
914
  Escape(component, evt, ctx) {
915
+ // Always clear the type-ahead buffer — Escape is a universal cancel.
916
+ // Safe to call when the buffer is empty.
917
+ // eslint-disable-next-line no-underscore-dangle
918
+ if (typeof component._clearTypeaheadBuffer === 'function') {
919
+ // eslint-disable-next-line no-underscore-dangle
920
+ component._clearTypeaheadBuffer();
921
+ }
922
+
873
923
  if (!ctx.isExpanded) {
874
924
  return;
875
925
  }
@@ -881,18 +931,30 @@ const selectKeyboardStrategy = {
881
931
  },
882
932
 
883
933
  End(component, evt, ctx) {
884
- if (!ctx.isExpanded) {
885
- return;
886
- }
887
934
  evt.preventDefault();
888
935
  evt.stopPropagation();
889
- const lastOption = [...component.menu.menuService.menuOptions].reverse().find((option) => !option.disabled);
890
- if (lastOption) {
891
- component.menu.updateActiveOption(lastOption);
936
+ // `pop()` is safe here: getActiveOptions returns a fresh filtered array.
937
+ // Uses "active" (not "enabled") so hidden and static rows — which a screen
938
+ // reader must not announce as focused — are skipped.
939
+ const lastOption = getActiveOptions(component.menu).pop();
940
+ if (!lastOption) {
941
+ return;
942
+ }
943
+ // Pre-stash before show() so the auroDropdown-toggled handler's
944
+ // `!optionActive` guard short-circuits the firstActive/selected fallback —
945
+ // otherwise show() synchronously fires the handler and writes
946
+ // aria-activedescendant once before we overwrite it.
947
+ component.menu.updateActiveOption(lastOption);
948
+ if (!ctx.isExpanded) {
949
+ component.dropdown.show();
892
950
  }
893
951
  },
894
952
 
895
953
  Enter(component, evt, ctx) {
954
+ // Prevent the keypress from bubbling to parent containers (e.g., forms)
955
+ // which could interpret Enter as a submit. Matches APG select-only combobox
956
+ // and native <select> behavior: Enter opens the listbox when closed, selects
957
+ // the active option when open — it does not submit a parent form.
896
958
  evt.preventDefault();
897
959
  evt.stopPropagation();
898
960
  if (!ctx.isExpanded) {
@@ -903,14 +965,16 @@ const selectKeyboardStrategy = {
903
965
  },
904
966
 
905
967
  Home(component, evt, ctx) {
906
- if (!ctx.isExpanded) {
907
- return;
908
- }
909
968
  evt.preventDefault();
910
969
  evt.stopPropagation();
911
- const firstOption = component.menu.menuService.menuOptions.find((option) => !option.disabled);
912
- if (firstOption) {
913
- component.menu.updateActiveOption(firstOption);
970
+ const [firstOption] = getActiveOptions(component.menu);
971
+ if (!firstOption) {
972
+ return;
973
+ }
974
+ // See End() for why this must run before show().
975
+ component.menu.updateActiveOption(firstOption);
976
+ if (!ctx.isExpanded) {
977
+ component.dropdown.show();
914
978
  }
915
979
  },
916
980
 
@@ -928,16 +992,34 @@ const selectKeyboardStrategy = {
928
992
  },
929
993
 
930
994
  default(component, evt, ctx) {
931
- component.updateActiveOptionBasedOnKey(evt.key);
995
+ // Ignore keys chorded with Ctrl/Meta/Alt so browser/OS shortcuts
996
+ // (Cmd+C, Ctrl+V, Alt+X, Cmd+Space, …) don't leak into typeahead
997
+ // or toggle the bib. Native <select> ignores modified keys.
998
+ // ArrowUp/ArrowDown handle modifier+arrow explicitly above; this
999
+ // guard only affects the default (printable/Space) branch.
1000
+ if (evt.ctrlKey || evt.metaKey || evt.altKey) {
1001
+ return;
1002
+ }
1003
+
1004
+ // Space resolves to either typeahead-buffer extension or bib toggle
1005
+ // depending on whether a type-ahead buffer is active. Mirrors native
1006
+ // <select> and the WAI-ARIA APG Listbox guidance: mid-typeahead space
1007
+ // is a search character (e.g. "San Francisco"); otherwise it toggles.
932
1008
  if (evt.key === ' ') {
933
1009
  evt.preventDefault();
934
1010
  evt.stopPropagation();
1011
+ if (component.typeaheadBuffer && component.typeaheadBuffer.length > 0) {
1012
+ component.updateActiveOptionBasedOnKey(evt.key);
1013
+ return;
1014
+ }
935
1015
  if (ctx.isExpanded) {
936
1016
  component.dropdown.hide();
937
- return;
1017
+ } else {
1018
+ component.dropdown.show();
938
1019
  }
939
- component.dropdown.show();
1020
+ return;
940
1021
  }
1022
+ component.updateActiveOptionBasedOnKey(evt.key);
941
1023
  },
942
1024
  };
943
1025
 
@@ -3233,12 +3315,40 @@ class AuroFloatingUI {
3233
3315
  return;
3234
3316
  }
3235
3317
 
3318
+ // Chrome-specific: during popover top-layer promotion after a click on a
3319
+ // slotted focusable, :focus-within can briefly evaluate false while the
3320
+ // active element is still structurally inside the trigger/bib. Fall back
3321
+ // to a shadow-piercing ancestry walk from the deep active element before
3322
+ // treating this as a real focus loss.
3323
+ try {
3324
+ let active = document.activeElement;
3325
+ while (active && active.shadowRoot && active.shadowRoot.activeElement) {
3326
+ active = active.shadowRoot.activeElement;
3327
+ }
3328
+ const targets = [element, element.trigger, element.bib].filter(Boolean);
3329
+ let node = active;
3330
+ while (node) {
3331
+ if (targets.includes(node)) {
3332
+ return;
3333
+ }
3334
+ node =
3335
+ node.parentElement ||
3336
+ (node.getRootNode && node.getRootNode().host) ||
3337
+ null;
3338
+ }
3339
+ } catch (e) {
3340
+ // Defensive: fall through to the existing close path if traversal fails.
3341
+ }
3342
+
3236
3343
  // if fullscreen bib is in fullscreen mode, do not close
3237
3344
  if (element.bib.hasAttribute("isfullscreen")) {
3238
3345
  return;
3239
3346
  }
3240
3347
 
3241
- this.hideBib("keydown");
3348
+ // eventType "focusloss" distinguishes a Tab/click-driven close from an
3349
+ // Escape keydown close. Consumers use this to decide whether to restore
3350
+ // focus to the trigger (Escape) or let it advance naturally (Tab).
3351
+ this.hideBib("focusloss");
3242
3352
  }
3243
3353
 
3244
3354
  setupHideHandlers() {
@@ -3908,199 +4018,6 @@ function getFocusableElements(container) {
3908
4018
  return tabIndexedUniqueElements;
3909
4019
  }
3910
4020
 
3911
- /**
3912
- * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
3913
- * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
3914
- */
3915
- class FocusTrap {
3916
- /**
3917
- * Creates a new FocusTrap instance for the given container element.
3918
- * Initializes event listeners and prepares the container for focus management.
3919
- *
3920
- * @param {HTMLElement} container The DOM element to trap focus within.
3921
- * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
3922
- * @throws {Error} If the provided container is not a valid HTMLElement.
3923
- */
3924
- constructor(container, controlTabOrder = false) {
3925
- if (!container || !(container instanceof HTMLElement)) {
3926
- throw new Error("FocusTrap requires a valid HTMLElement.");
3927
- }
3928
-
3929
- this.container = container;
3930
- this.tabDirection = "forward"; // or 'backward';
3931
- this.controlTabOrder = controlTabOrder;
3932
-
3933
- this._init();
3934
- }
3935
-
3936
- /**
3937
- * Initializes the focus trap by setting up event listeners and attributes on the container.
3938
- * Prepares the container for focus management, including support for shadow DOM and inert attributes.
3939
- *
3940
- * @private
3941
- */
3942
- _init() {
3943
- // Add inert attribute to prevent focusing programmatically as well (if supported)
3944
- if ("inert" in HTMLElement.prototype) {
3945
- this.container.inert = false; // Ensure the container isn't inert
3946
- this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
3947
- }
3948
-
3949
- // Track tab direction
3950
- this.container.addEventListener("keydown", this._onKeydown);
3951
- }
3952
-
3953
- /**
3954
- * Gets an array of currently active (focused) elements in the document and shadow DOM.
3955
- * @returns {Array<HTMLElement>} An array of focusable elements within the container.
3956
- * @private
3957
- */
3958
- _getActiveElements() {
3959
- // Get the active element(s) in the document and shadow root
3960
- // This will include the active element in the shadow DOM if it exists
3961
- // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
3962
- let { activeElement } = document;
3963
- const actives = [activeElement];
3964
- while (activeElement?.shadowRoot?.activeElement) {
3965
- actives.push(activeElement.shadowRoot.activeElement);
3966
- activeElement = activeElement.shadowRoot.activeElement;
3967
- }
3968
- return actives;
3969
- }
3970
-
3971
- /**
3972
- * Gets the next focus index based on the current index and focusable elements.
3973
- * @param {number} currentIndex The current index of the focused element.
3974
- * @param {Array<HTMLElement>} focusables The array of focusable elements.
3975
- * @returns {number|null} The next focus index or null if not determined.
3976
- */
3977
- _getNextFocusIndex(currentIndex, focusables, actives) {
3978
- if (this.controlTabOrder) {
3979
- // Calculate the new index based on the current index and tab direction
3980
- let newFocusIndex =
3981
- currentIndex + (this.tabDirection === "forward" ? 1 : -1);
3982
-
3983
- // Wrap-around logic
3984
- if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
3985
- if (newFocusIndex >= focusables.length) newFocusIndex = 0;
3986
-
3987
- // Early return with the new index
3988
- return newFocusIndex;
3989
- }
3990
-
3991
- // Determine if we need to wrap
3992
- const atFirst =
3993
- actives.includes(focusables[0]) || actives.includes(this.container);
3994
- const atLast = actives.includes(focusables[focusables.length - 1]);
3995
-
3996
- // Only wrap if at the ends
3997
- if (this.tabDirection === "backward" && atFirst) {
3998
- return focusables.length - 1;
3999
- }
4000
-
4001
- if (this.tabDirection === "forward" && atLast) {
4002
- return 0;
4003
- }
4004
-
4005
- // No wrap, so don't change focus, return early
4006
- return null;
4007
- }
4008
-
4009
- /**
4010
- * Handles the Tab key press event to manage focus within the container.
4011
- * @param {KeyboardEvent} e The keyboard event triggered by the user.
4012
- * @returns {void}
4013
- */
4014
- _handleTabKey(e) {
4015
- // Update the focusable elements
4016
- const focusables = this._getFocusableElements();
4017
-
4018
- // If there are no focusable elements, exit
4019
- if (!focusables.length) return;
4020
-
4021
- // Set the tab direction based on the key pressed
4022
- this.tabDirection = e.shiftKey ? "backward" : "forward";
4023
-
4024
- // Get the active elements that are currently focused
4025
- const actives = this._getActiveElements();
4026
-
4027
- // If we're at either end of the focusable elements, wrap around to the other end
4028
- let focusIndex = focusables.findIndex((el) => actives.includes(el));
4029
-
4030
- // Fallback if we have no focused element
4031
- if (focusIndex === -1) focusIndex = 0;
4032
-
4033
- // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
4034
- // Is null if no new focus index is determined
4035
- const newFocusIndex = this._getNextFocusIndex(
4036
- focusIndex,
4037
- focusables,
4038
- actives,
4039
- );
4040
-
4041
- // If we have a new focus index, set focus to that element
4042
- if (newFocusIndex !== null) {
4043
- e.preventDefault();
4044
- focusables[newFocusIndex].focus();
4045
- }
4046
- }
4047
-
4048
- /**
4049
- * Catches the keydown event
4050
- * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
4051
- * @private
4052
- */
4053
- _onKeydown = (e) => {
4054
- // Handle tab
4055
- if (e.key === "Tab") this._handleTabKey(e);
4056
- };
4057
-
4058
- /**
4059
- * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
4060
- * Returns a unique, ordered array of elements that can receive focus.
4061
- *
4062
- * @returns {Array<HTMLElement>} An array of focusable elements within the container.
4063
- * @private
4064
- */
4065
- _getFocusableElements() {
4066
- // Use the imported utility function to get focusable elements
4067
- const elements = getFocusableElements(this.container);
4068
-
4069
- // Return the elements found
4070
- return elements;
4071
- }
4072
-
4073
- /**
4074
- * Moves focus to the first focusable element within the container.
4075
- * Useful for setting initial focus when activating the focus trap.
4076
- */
4077
- focusFirstElement() {
4078
- const focusables = this._getFocusableElements();
4079
- if (focusables.length) focusables[0].focus();
4080
- }
4081
-
4082
- /**
4083
- * Moves focus to the last focusable element within the container.
4084
- * Useful for setting focus when deactivating or cycling focus in reverse.
4085
- */
4086
- focusLastElement() {
4087
- const focusables = this._getFocusableElements();
4088
- if (focusables.length) focusables[focusables.length - 1].focus();
4089
- }
4090
-
4091
- /**
4092
- * Removes event listeners and attributes added by the focus trap.
4093
- * Call this method to clean up when the focus trap is no longer needed.
4094
- */
4095
- disconnect() {
4096
- if (this.container.hasAttribute("data-focus-trap-container")) {
4097
- this.container.removeAttribute("data-focus-trap-container");
4098
- }
4099
-
4100
- this.container.removeEventListener("keydown", this._onKeydown);
4101
- }
4102
- }
4103
-
4104
4021
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
4105
4022
  // See LICENSE in the project root for license information.
4106
4023
 
@@ -4601,7 +4518,7 @@ class AuroDropdownBib extends LitElement {
4601
4518
  classes[`shape-${this.shape}`] = true;
4602
4519
 
4603
4520
  return html`
4604
- <dialog class="${classMap(classes)}" part="bibContainer" role="${ifDefined(this.dialogRole)}" aria-labelledby="${ifDefined(this.dialogLabel ? 'dialogLabel' : undefined)}">
4521
+ <dialog tabindex="-1" class="${classMap(classes)}" part="bibContainer" role="${ifDefined(this.dialogRole)}" aria-labelledby="${ifDefined(this.dialogLabel ? 'dialogLabel' : undefined)}">
4605
4522
  ${this.dialogLabel ? html`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
4606
4523
  <slot></slot>
4607
4524
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -4852,7 +4769,7 @@ let AuroHelpText$1 = class AuroHelpText extends LitElement {
4852
4769
  }
4853
4770
  };
4854
4771
 
4855
- var formkitVersion$1 = '202606191810';
4772
+ var formkitVersion$1 = '202607221815';
4856
4773
 
4857
4774
  class AuroElement extends LitElement {
4858
4775
  static get properties() {
@@ -4981,7 +4898,6 @@ class AuroDropdown extends AuroElement {
4981
4898
  static get shadowRootOptions() {
4982
4899
  return {
4983
4900
  ...AuroElement.shadowRootOptions,
4984
- delegatesFocus: true,
4985
4901
  };
4986
4902
  }
4987
4903
 
@@ -4993,6 +4909,15 @@ class AuroDropdown extends AuroElement {
4993
4909
  this.matchWidth = false;
4994
4910
  this.noHideOnThisFocusLoss = false;
4995
4911
 
4912
+ /**
4913
+ * When true, the dropdown skips its generic focus restoration on close.
4914
+ * Set by consumers (e.g. combobox) that manage their own focus routing
4915
+ * via setClearBtnFocus / setInputFocus / keyboard strategy.
4916
+ * Separate from noHideOnThisFocusLoss (which controls auto-close behavior).
4917
+ * @private
4918
+ */
4919
+ this.noFocusRestoreOnClose = false;
4920
+
4996
4921
  this.errorMessage = undefined; // TODO - check with Doug if there is still more to do here
4997
4922
 
4998
4923
  // Layout Config
@@ -5148,7 +5073,49 @@ class AuroDropdown extends AuroElement {
5148
5073
  focusables[0].focus();
5149
5074
  }
5150
5075
  } else {
5076
+ this.focusTrigger();
5077
+ }
5078
+ }
5079
+
5080
+ /**
5081
+ * Focus the trigger content. When the trigger wrapper itself is focusable
5082
+ * (has tabindex), focus it directly. Otherwise, focus the first focusable
5083
+ * element slotted into the trigger slot (e.g. the auro-input).
5084
+ * @private
5085
+ */
5086
+ focusTrigger() {
5087
+ if (this.trigger.hasAttribute('tabindex')) {
5151
5088
  this.trigger.focus();
5089
+ } else {
5090
+ // Slotted content isn't a DOM child of the trigger div, so
5091
+ // getFocusableElements can't find it. Query assigned nodes directly.
5092
+ const slot = this.trigger.querySelector('slot[name="trigger"]');
5093
+ if (slot) {
5094
+ const assigned = slot.assignedElements();
5095
+ for (const el of assigned) {
5096
+ if (el.hasAttribute('disabled')) {
5097
+ continue; // eslint-disable-line no-continue
5098
+ }
5099
+ // Try finding a focusable descendant first (handles non-focusable
5100
+ // wrappers like <div> containing a <button>). If none found, try
5101
+ // focusing the element directly (works for custom elements like
5102
+ // auro-input that have delegatesFocus or a custom focus() method).
5103
+ const descendants = getFocusableElements(el);
5104
+ if (descendants.length > 0) {
5105
+ descendants[0].focus();
5106
+ return;
5107
+ }
5108
+ el.focus();
5109
+ if (document.activeElement === el) {
5110
+ return;
5111
+ }
5112
+ }
5113
+ }
5114
+ // Fallback: try DOM children (non-slotted content)
5115
+ const focusables = getFocusableElements(this.trigger);
5116
+ if (focusables.length > 0) {
5117
+ focusables[0].focus();
5118
+ }
5152
5119
  }
5153
5120
  }
5154
5121
 
@@ -5524,10 +5491,17 @@ class AuroDropdown extends AuroElement {
5524
5491
  this.clearTriggerFocusEventBinding();
5525
5492
  }
5526
5493
 
5494
+ // eslint-disable-next-line complexity
5527
5495
  updated(changedProperties) {
5528
5496
  super.updated(changedProperties);
5529
5497
  this.floater.handleUpdate(changedProperties);
5530
5498
 
5499
+ // Close the dropdown if the disabled property is set to true
5500
+ if (changedProperties.has('disabled') && this.disabled && this.isPopoverVisible) {
5501
+ this.hide();
5502
+ this.isPopoverVisible = false;
5503
+ }
5504
+
5531
5505
  // Note: `disabled` is not a breakpoint (it is not a screen size),
5532
5506
  // so it looks like we never consume this - however, dropdownBib handles this in the setter as "undefined"
5533
5507
  if (changedProperties.has('fullscreenBreakpoint')) {
@@ -5601,8 +5575,30 @@ class AuroDropdown extends AuroElement {
5601
5575
  }
5602
5576
 
5603
5577
  const eventType = event.detail.eventType || "unknown";
5604
- if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown") {
5605
- this.trigger.focus();
5578
+ if (!this.isPopoverVisible && this.hasFocus && eventType === "keydown" && !this.noFocusRestoreOnClose) {
5579
+ this.focusTrigger();
5580
+ }
5581
+
5582
+
5583
+ // On Tab-driven close (eventType "focusloss"), let focus advance naturally
5584
+ // — restoring to the trigger would trap the user on this dropdown, forcing
5585
+ // an extra Tab to move on. Escape and outside-click still restore.
5586
+ // When noFocusRestoreOnClose is true, the consumer (e.g. combobox) manages
5587
+ // its own focus restoration — skip the generic trigger focus to avoid races.
5588
+ if (!this.isPopoverVisible && eventType !== "focusloss" && !this.noFocusRestoreOnClose) {
5589
+ // wait til the bib gets fully closed and rendered
5590
+ setTimeout(() => {
5591
+ // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
5592
+ // Restore focus to trigger when focus is still inside the bib (:focus-within) or fell to body.
5593
+ if (this.isPopoverVisible ||
5594
+ // eslint-disable-next-line no-extra-parens
5595
+ (!this.bibContent?.matches(':focus-within') &&
5596
+ document.activeElement !== document.body)) {
5597
+ return;
5598
+ }
5599
+ // Restore focus to the trigger.
5600
+ this.focusTrigger();
5601
+ });
5606
5602
  }
5607
5603
  }
5608
5604
 
@@ -5803,6 +5799,14 @@ class AuroDropdown extends AuroElement {
5803
5799
  };
5804
5800
  this.addEventListener('keydown', this._bibTabHandler);
5805
5801
 
5802
+ // Suppress AuroFloatingUI's auto-hide-on-focus-loss while the
5803
+ // desktopModal trap owns focus management. Without this, the very
5804
+ // first focus move into the bib (from the RAF below) triggers
5805
+ // handleFocusLoss → hideBib, tearing down the trap before the
5806
+ // user can press Tab.
5807
+ this._priorNoHideOnFocusLoss = this.noHideOnThisFocusLoss;
5808
+ this.noHideOnThisFocusLoss = true;
5809
+
5806
5810
  // Move initial focus into the bib content, matching FocusTrap behavior
5807
5811
  requestAnimationFrame(() => {
5808
5812
  const focusables = getFocusableElements(this.bibContent);
@@ -5811,15 +5815,16 @@ class AuroDropdown extends AuroElement {
5811
5815
  }
5812
5816
  });
5813
5817
  } else {
5814
- // Normal desktop: use FocusTrap on the bib element.
5815
- // Defer focusFirstElement to the next frame because the popover
5816
- // is positioned asynchronously by Floating UI — calling focus()
5817
- // synchronously here would target elements with zero dimensions
5818
- // and the focus call would be silently ignored.
5819
- this.focusTrap = new FocusTrap(this.bibContent);
5818
+ // Normal desktop (non-modal): move initial focus into the bib but
5819
+ // don't trap Tab. Tab should exit the bib and let the floater's
5820
+ // handleFocusLoss close it, matching native <select>/<details>
5821
+ // behavior. Deferred one frame because Floating UI positions the
5822
+ // popover asynchronously — a synchronous focus() would target
5823
+ // zero-dimension elements and be silently ignored.
5820
5824
  requestAnimationFrame(() => {
5821
- if (this.focusTrap) {
5822
- this.focusTrap.focusFirstElement();
5825
+ const focusables = getFocusableElements(this.bibContent);
5826
+ if (focusables.length) {
5827
+ focusables[0].focus();
5823
5828
  }
5824
5829
  });
5825
5830
  }
@@ -6116,6 +6121,7 @@ class AuroDropdown extends AuroElement {
6116
6121
  role="${ifDefined(this.triggerContentFocusable ? undefined : this.a11yRole)}"
6117
6122
  aria-expanded="${ifDefined(this.a11yRole === 'button' || this.triggerContentFocusable ? undefined : this.isPopoverVisible)}"
6118
6123
  aria-controls="${ifDefined(this.a11yRole === 'button' || this.triggerContentFocusable ? undefined : this.dropdownId)}"
6124
+ aria-haspopup="${ifDefined(this.a11yRole === 'combobox' && !this.triggerContentFocusable ? 'listbox' : undefined)}"
6119
6125
  aria-labelledby="${ifDefined(this.triggerContentFocusable ? undefined : 'triggerLabel')}"
6120
6126
  aria-disabled="${ifDefined(this.disabled ? 'true' : undefined)}"
6121
6127
  @focusin="${this.handleFocusin}"
@@ -6242,7 +6248,7 @@ class AuroDropdown extends AuroElement {
6242
6248
 
6243
6249
  var colorCss$1 = css`#headerContainer{box-shadow:var(--ds-auro-dropdownbib-header-boxshadow-color)}#footerContainer{background-color:var(--ds-auro-dropdownbib-footer-container-color)}`;
6244
6250
 
6245
- var styleCss$2 = css`#bibTemplate{display:flex;overflow:hidden;height:100%;max-height:100%;flex-direction:column}#headerContainer{display:flex;flex-direction:column;padding:var(--ds-size-200, 1rem);padding-top:var(--ds-size-400, 2rem);padding-bottom:0}#headerContainer .titleRow{display:flex;flex-direction:row;justify-content:space-between;gap:var(--ds-size-100, 0.5rem)}#headerContainer .header{max-width:calc(100vw - var(--ds-size-900, 4.5rem));padding-top:var(--ds-size-200, 1rem)}#headerContainer .subheader{width:100%}#closeButton [auro-icon]{--ds-auro-icon-size: var(--ds-size-500, 2.5rem)}#bodyContainer{position:relative;overflow:auto;flex:1 1 100%}:host([isfullscreen]) #bibTemplate{max-height:100dvh}:host([isfullscreen]) #bodyContainer{margin-top:var(--ds-size-100, 0.5rem)}#footerContainer{position:absolute;right:0;bottom:0;left:0;padding:var(--ds-size-200, 1rem)}`;
6251
+ var styleCss$2 = css`#bibTemplate{display:flex;overflow:hidden;height:100%;max-height:100%;flex-direction:column}#headerContainer{display:flex;flex-direction:column;padding:var(--ds-size-200, 1rem);padding-top:var(--ds-size-400, 2rem);padding-bottom:0}#headerContainer .titleRow{display:flex;flex-direction:row;justify-content:space-between;padding-bottom:var(--ds-size-200, 1rem);gap:var(--ds-size-100, 0.5rem)}#headerContainer .header{max-width:calc(100vw - var(--ds-size-900, 4.5rem))}#headerContainer .subheader{width:100%}#closeButton [auro-icon]{--ds-auro-icon-size: var(--ds-size-500, 2.5rem)}#bodyContainer{position:relative;overflow:auto;flex:1}:host([isfullscreen]) #bibTemplate{max-height:100dvh}:host([isfullscreen]) #bodyContainer{margin-top:var(--ds-size-100, 0.5rem)}#footerContainer{padding:var(--ds-size-200, 1rem)}`;
6246
6252
 
6247
6253
  var tokenCss = css`:host{--ds-auro-dropdownbib-header-boxshadow-color: var(--ds-elevation-200, 0px 0px 10px rgba(0, 0, 0, 0.15));--ds-auro-dropdownbib-footer-container-color: var(--ds-basic-color-surface-default, #ffffff)}`;
6248
6254
 
@@ -6865,9 +6871,9 @@ class AuroHelpText extends LitElement {
6865
6871
  }
6866
6872
  }
6867
6873
 
6868
- var formkitVersion = '202606191810';
6874
+ var formkitVersion = '202607221815';
6869
6875
 
6870
- var styleCss = 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}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer [slot=displayValue]{display:none}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{height:auto}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
6876
+ var styleCss = 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}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer{max-width:100%}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;box-sizing:border-box;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{overflow:hidden;height:auto;text-overflow:ellipsis;white-space:nowrap}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
6871
6877
 
6872
6878
  var emphasizedColorCss = css`:host([layout=emphasized]) [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown]:hover{--ds-auro-dropdown-trigger-hover-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}:host([layout=emphasized]) [auro-dropdown][layout*=emphasized]::part(wrapper){--ds-auro-dropdown-trigger-background-color: var(--ds-advanced-color-dropdown-emphasized-background, rgba(0, 39, 74, 0.1019607843))}`;
6873
6879
 
@@ -6970,6 +6976,16 @@ class AuroSelect extends AuroElement$1 {
6970
6976
  * @private
6971
6977
  */
6972
6978
  this.hasDisplayValueContent = false;
6979
+
6980
+ /**
6981
+ * @private
6982
+ */
6983
+ this.typeaheadBuffer = '';
6984
+
6985
+ /**
6986
+ * @private
6987
+ */
6988
+ this._typeaheadTimeout = null;
6973
6989
  }
6974
6990
 
6975
6991
  /**
@@ -6982,6 +6998,7 @@ class AuroSelect extends AuroElement$1 {
6982
6998
  this.fullscreenBreakpoint = 'sm';
6983
6999
  this.onDark = false;
6984
7000
  this.isPopoverVisible = false;
7001
+ this.typeaheadTimeoutMs = 500;
6985
7002
 
6986
7003
  // Layout Config
6987
7004
  this.layout = 'classic';
@@ -7186,14 +7203,6 @@ class AuroSelect extends AuroElement$1 {
7186
7203
  reflect: true
7187
7204
  },
7188
7205
 
7189
- /**
7190
- * @private
7191
- */
7192
- options: {
7193
- type: Array,
7194
- state: true
7195
- },
7196
-
7197
7206
  /**
7198
7207
  * Specifies the current selected menuOption. Default type is `HTMLElement`, changing to `Array<HTMLElement>` when `multiSelect` is true.
7199
7208
  * @type {HTMLElement|Array<HTMLElement>}
@@ -7285,6 +7294,16 @@ class AuroSelect extends AuroElement$1 {
7285
7294
  attribute: false
7286
7295
  },
7287
7296
 
7297
+ /**
7298
+ * Milliseconds of keyboard inactivity before the type-ahead buffer resets.
7299
+ * Increase for users who type slowly.
7300
+ * @default 500
7301
+ */
7302
+ typeaheadTimeoutMs: {
7303
+ type: Number,
7304
+ reflect: true
7305
+ },
7306
+
7288
7307
  /**
7289
7308
  * Specifies the `validityState` this element is in.
7290
7309
  */
@@ -7294,7 +7313,7 @@ class AuroSelect extends AuroElement$1 {
7294
7313
  },
7295
7314
 
7296
7315
  /**
7297
- * Value selected for the component.
7316
+ * Value selected for the component. When set programmatically or as a preset attribute, the value must match a selectable option. If it matches an option marked `disabled` or `static`, the selection is rejected: `value` is cleared to `undefined` while `optionSelected` is cleared to `undefined` in single-select or `[]` in multiSelect. `hidden` options remain selectable by value.
7298
7317
  */
7299
7318
  value: {
7300
7319
  type: String,
@@ -7416,8 +7435,11 @@ class AuroSelect extends AuroElement$1 {
7416
7435
  } else if (this.multiSelect && Array.isArray(this.optionSelected) && this.optionSelected.length > 0) {
7417
7436
  this.menu.updateActiveOption(this.optionSelected[0]);
7418
7437
  } else {
7419
- // If no activeOption has yet to be set, then make the first enabled option active by default
7420
- const firstActive = this.menu.menuService.menuOptions.find((option) => !option.disabled);
7438
+ // If no activeOption has yet to be set, make the first active option
7439
+ // (non-disabled, non-hidden, non-static) active by default. "Active" —
7440
+ // not just "enabled" — so hidden rows and static placeholders never
7441
+ // land in aria-activedescendant on open.
7442
+ const [firstActive] = getActiveOptions(this.menu);
7421
7443
  this.menu.updateActiveOption(firstActive);
7422
7444
  }
7423
7445
  }
@@ -7471,16 +7493,68 @@ class AuroSelect extends AuroElement$1 {
7471
7493
  this.dropdown.dropdownWidth = this.customBibWidth;
7472
7494
  }
7473
7495
 
7474
- // Pass label text to the dropdown bib for accessible dialog naming
7475
- const labelElement = this.querySelector('span[slot="label"]');
7476
- if (labelElement) {
7477
- this.dropdown.bibDialogLabel = labelElement.textContent.trim() || undefined;
7478
- }
7496
+ this._syncLabelText();
7479
7497
 
7480
7498
  // Exposes the CSS parts from the dropdown for styling
7481
7499
  this.dropdown.exposeCssParts();
7482
7500
  }
7483
7501
 
7502
+ /**
7503
+ * Reads the current label slot text and pushes it to the dropdown bib
7504
+ * (for dialog naming) and the menu (for listbox aria-label). Safe to call
7505
+ * before either child has been wired up — each branch self-guards.
7506
+ * @private
7507
+ */
7508
+ _syncLabelText() {
7509
+ const labelElement = this.querySelector('[slot="label"]');
7510
+ const text = labelElement ? labelElement.textContent.trim() : '';
7511
+ if (this.dropdown) {
7512
+ this.dropdown.bibDialogLabel = text || undefined;
7513
+ }
7514
+ if (this.menu) {
7515
+ if (text) {
7516
+ this.menu.setAttribute('aria-label', text);
7517
+ } else {
7518
+ this.menu.removeAttribute('aria-label');
7519
+ }
7520
+ }
7521
+ }
7522
+
7523
+ /**
7524
+ * Keeps the dialog/menu accessible names in sync when consumers mutate the
7525
+ * label slot at runtime (e.g., i18n locale swap). `slotchange` alone is
7526
+ * insufficient — it doesn't fire when textContent of an already-assigned
7527
+ * slotted node changes, which is the common case. We scope the observer to
7528
+ * the label node itself (not the whole host subtree) so option-content
7529
+ * mutations don't trigger label re-syncs, and re-target on `slotchange`
7530
+ * when consumers add or replace the label element.
7531
+ * @private
7532
+ */
7533
+ _observeLabelChanges() {
7534
+ if (this._labelObserver) return;
7535
+ this._labelObserver = new MutationObserver(() => this._syncLabelText());
7536
+
7537
+ const retarget = () => {
7538
+ this._labelObserver.disconnect();
7539
+ const labelElement = this.querySelector('[slot="label"]');
7540
+ if (labelElement) {
7541
+ this._labelObserver.observe(labelElement, {
7542
+ childList: true,
7543
+ subtree: true,
7544
+ characterData: true
7545
+ });
7546
+ }
7547
+ this._syncLabelText();
7548
+ };
7549
+
7550
+ retarget();
7551
+
7552
+ this._retargetLabelObserver = retarget;
7553
+ this.shadowRoot.querySelectorAll('slot[name="label"]').forEach((slot) => {
7554
+ slot.addEventListener('slotchange', retarget);
7555
+ });
7556
+ }
7557
+
7484
7558
  /**
7485
7559
  * This will register this element with the browser.
7486
7560
  * @param {string} [name="auro-select"] - The name of element that you want to register to.
@@ -7611,6 +7685,12 @@ class AuroSelect extends AuroElement$1 {
7611
7685
 
7612
7686
  /**
7613
7687
  * Binds all behavior needed to the menu after rendering.
7688
+ *
7689
+ * The `<auro-menu>` reference is captured once and not re-targeted on
7690
+ * `slotchange`. Runtime option mutations are covered via
7691
+ * `auroMenu-optionsChange`, so swap options inside the menu freely; do not
7692
+ * swap the `<auro-menu>` element itself under a live select — remount the
7693
+ * parent `<auro-select>` instead.
7614
7694
  * @private
7615
7695
  * @returns {void}
7616
7696
  */
@@ -7631,22 +7711,59 @@ class AuroSelect extends AuroElement$1 {
7631
7711
  this.updateMenuShapeSize();
7632
7712
  this.setMenuValue(this.value);
7633
7713
 
7634
- // Set accessible name on the menu for screen readers based on the label slot content
7635
- const labelElement = this.querySelector('[slot="label"]');
7636
- if (labelElement) {
7637
- this.menu.setAttribute('aria-label', labelElement.textContent.trim());
7638
- }
7714
+ this._syncLabelText();
7639
7715
 
7640
7716
  if (this.multiSelect) {
7641
7717
  this.menu.multiSelect = this.multiSelect;
7642
7718
  }
7643
7719
 
7644
- this.options = this.menu.options;
7720
+ // Menu's items are populated by initItems() during its firstUpdated/slotchange.
7721
+ // Since the parent select's firstUpdated runs before the child menu's, call initItems()
7722
+ // here so renderNativeSelect can render the native <option> list on first paint.
7723
+ if (typeof this.menu.initItems === 'function') {
7724
+ this.menu.initItems();
7725
+ }
7645
7726
  this.updateOptionPositions();
7727
+ // renderNativeSelect reads this.menu.options, which the parent doesn't
7728
+ // observe — request an update so the hidden native <option> list reflects
7729
+ // the menu's options after initItems populates them.
7730
+ this.requestUpdate();
7731
+
7732
+ // Keep aria-setsize/aria-posinset (and the native <option> list) in sync
7733
+ // when the menu re-initializes its items — e.g., slotchange, async/lazy
7734
+ // loads, value-triggered re-init. Without this, stale set-size is
7735
+ // announced and the native select goes stale after dynamic mutations.
7736
+ this.menu.addEventListener('auroMenu-optionsChange', () => {
7737
+ this.updateOptionPositions();
7738
+ this.requestUpdate();
7739
+ });
7740
+
7646
7741
  this.menu.addEventListener("auroMenu-loadingChange", (event) => this.handleMenuLoadingChange(event));
7647
7742
 
7648
- this.menu.addEventListener("auroMenu-deselectPrevented", () => {
7649
- this.hideBib();
7743
+ this.menu.addEventListener("auroMenu-selectValueFailure", () => {
7744
+ // Menu dispatches this from two paths: a programmatic value mismatch
7745
+ // (menu pre-clears its own optionSelected to undefined before firing)
7746
+ // and a click on an unselected valueless option (menu leaves state
7747
+ // untouched). Only mirror the clear in the first case — otherwise a
7748
+ // valueless click in multiSelect would wipe every prior pick.
7749
+ if (this.menu.optionSelected !== undefined) {
7750
+ return;
7751
+ }
7752
+ // Skip when the select is already cleared (valueless click with no
7753
+ // prior selection): value/optionSelected are already empty and there
7754
+ // is no stale trigger text to refresh, so updateDisplayedValue would
7755
+ // just churn the DOM and request a needless dropdown re-render.
7756
+ const hasStaleState = this.value !== undefined ||
7757
+ (this.multiSelect ? this.optionSelected?.length > 0 : this.optionSelected !== undefined);
7758
+ if (!hasStaleState) {
7759
+ return;
7760
+ }
7761
+ this.value = undefined;
7762
+ this.optionSelected = this.multiSelect ? [] : undefined;
7763
+ // The trigger label is rendered imperatively into #value, so a property
7764
+ // change alone won't clear it. Refresh so stale text doesn't linger when
7765
+ // a runtime value change fails to match any option.
7766
+ this.updateDisplayedValue();
7650
7767
  });
7651
7768
 
7652
7769
  this.menu.addEventListener('auroMenu-activatedOption', (evt) => {
@@ -7656,11 +7773,31 @@ class AuroSelect extends AuroElement$1 {
7656
7773
  this.dropdown.setActiveDescendant(this.optionActive);
7657
7774
  }
7658
7775
 
7659
- // Announce the active option for screen readers
7660
- if (this.optionActive) {
7776
+ // Live-region announce only for [not selected] options. For activations
7777
+ // on an already-selected option — auto-activation on bib open, arrow
7778
+ // navigation back to the selection, or click in multiSelect — rely on
7779
+ // aria-activedescendant + aria-selected="true" to convey state per the
7780
+ // WAI-ARIA listbox pattern. This is intentional, not limited to the
7781
+ // initial activation on open: it also prevents a duplicate "X, selected"
7782
+ // when Enter on the active+selected option re-fires
7783
+ // auroMenu-selectedOption (see 03b289e39).
7784
+ if (this.optionActive && !this.optionActive.hasAttribute('selected')) {
7661
7785
  const optionText = this.optionActive.textContent.trim();
7662
- const selectedState = this.optionActive.hasAttribute('selected') ? ', selected' : ', not selected';
7663
- announceToScreenReader(this._getAnnouncementRoot(), `${optionText}${selectedState}`);
7786
+ const message = `${optionText}, not selected`;
7787
+ if (this.dropdown.isPopoverVisible) {
7788
+ announceToScreenReader(this._getAnnouncementRoot(), message);
7789
+ } else {
7790
+ // Typeahead-on-closed calls updateActiveOption() before show(), so
7791
+ // this handler runs with isPopoverVisible still false. queueMicrotask
7792
+ // is safe because show() → showBib() flips isPopoverVisible and
7793
+ // dialog.showModal() both run synchronously in the same task; the
7794
+ // microtask queue only drains once _handleTypeahead unwinds, by
7795
+ // which point _getAnnouncementRoot() resolves to the bib's shadow
7796
+ // root inside the now-open modal. Do NOT switch to auroDropdown-toggled
7797
+ // — it fires before showModal(), landing the announcement in the
7798
+ // host root while the dialog is still not-yet-modal.
7799
+ queueMicrotask(() => announceToScreenReader(this._getAnnouncementRoot(), message));
7800
+ }
7664
7801
  }
7665
7802
 
7666
7803
  if (this.dropdown.isPopoverVisible) {
@@ -7668,29 +7805,53 @@ class AuroSelect extends AuroElement$1 {
7668
7805
  }
7669
7806
  });
7670
7807
 
7671
- this.menu.addEventListener('auroMenu-selectedOption', (event) => {
7808
+ this.menu.addEventListener('auroMenu-selectedOption', () => {
7809
+ const previousSelected = this.optionSelected;
7672
7810
 
7673
7811
  // Update the displayed value
7674
7812
  this.updateDisplayedValue();
7675
7813
 
7676
- const options = event.detail.options || [];
7677
-
7678
- this.value = event.detail.stringValue;
7814
+ this.value = this.menu.value;
7679
7815
 
7680
- this.optionSelected = this.multiSelect ? options : options[0];
7816
+ // Clone the multiselect array so external mutation of select.optionSelected
7817
+ // can't reach back into menu's internal state through a shared reference.
7818
+ let nextSelected = this.menu.optionSelected;
7819
+ if (this.multiSelect) {
7820
+ nextSelected = Array.isArray(nextSelected) ? [...nextSelected] : [];
7821
+ }
7822
+ this.optionSelected = nextSelected;
7681
7823
 
7682
7824
  if (this.dropdown.isPopoverVisible && !this.multiSelect) {
7683
7825
  this.dropdown.hide();
7684
7826
  this.dropdown.trigger.focus();
7685
7827
  }
7686
7828
 
7687
- // Announce the selection after the dropdown closes so it isn't
7688
- // overridden by VoiceOver's "collapsed" announcement from aria-expanded.
7689
- const selectedValue = event.detail.stringValue;
7690
- const announcementDelay = 300;
7691
- setTimeout(() => {
7692
- announceToScreenReader(this._getAnnouncementRoot(), `${selectedValue}, selected`);
7693
- }, announcementDelay);
7829
+ // Describe the actual change. In multiSelect, currentLabel is the
7830
+ // concatenated remaining list — announcing "{list}, selected" after a
7831
+ // deselect would falsely claim every remaining label was just added.
7832
+ // Diff previous vs next to recover the toggled option.
7833
+ let announcement = '';
7834
+ if (this.multiSelect) {
7835
+ const prev = Array.isArray(previousSelected) ? previousSelected : [];
7836
+ const removed = prev.find((opt) => !nextSelected.includes(opt));
7837
+ const added = nextSelected.find((opt) => !prev.includes(opt));
7838
+ if (removed) {
7839
+ announcement = `${removed.textContent.trim()}, not selected`;
7840
+ } else if (added) {
7841
+ announcement = `${added.textContent.trim()}, selected`;
7842
+ }
7843
+ } else {
7844
+ announcement = `${this.menu.currentLabel}, selected`;
7845
+ }
7846
+
7847
+ // Delay so the utterance isn't overridden by VoiceOver's "collapsed"
7848
+ // announcement from aria-expanded when the dropdown closes.
7849
+ if (announcement) {
7850
+ const announcementDelay = 300;
7851
+ setTimeout(() => {
7852
+ announceToScreenReader(this._getAnnouncementRoot(), announcement);
7853
+ }, announcementDelay);
7854
+ }
7694
7855
  });
7695
7856
  }
7696
7857
 
@@ -7709,6 +7870,7 @@ class AuroSelect extends AuroElement$1 {
7709
7870
  this.addEventListener('blur', () => {
7710
7871
  this.validate();
7711
7872
  this.hasFocus = false;
7873
+ this._clearTypeaheadBuffer();
7712
7874
  });
7713
7875
  }
7714
7876
 
@@ -7722,41 +7884,104 @@ class AuroSelect extends AuroElement$1 {
7722
7884
  }
7723
7885
  }
7724
7886
 
7887
+ /**
7888
+ * Returns the lowercase, trimmed text content of a menu option.
7889
+ * @private
7890
+ * @param {HTMLElement} option - The menu option element.
7891
+ * @returns {string}
7892
+ */
7893
+ _getOptionDisplayText(option) {
7894
+ return (option.textContent || '').trim().toLowerCase();
7895
+ }
7896
+
7897
+ /**
7898
+ * Empties the type-ahead buffer and cancels any pending reset timeout.
7899
+ * Called when focus leaves the component, when Escape closes the bib, and on disconnect
7900
+ * so a stale buffer never bridges into a fresh interaction.
7901
+ * @private
7902
+ */
7903
+ _clearTypeaheadBuffer() {
7904
+ if (this._typeaheadTimeout) {
7905
+ clearTimeout(this._typeaheadTimeout);
7906
+ this._typeaheadTimeout = null;
7907
+ }
7908
+ this.typeaheadBuffer = '';
7909
+ }
7910
+
7725
7911
  /**
7726
7912
  * Updates the active option in the menu based on keyboard input.
7913
+ *
7914
+ * Implements the WAI-ARIA APG Listbox type-ahead pattern: accumulates printable
7915
+ * keystrokes into a buffer that resets after `typeaheadTimeoutMs` of inactivity.
7916
+ * A multi-character buffer matches the first option whose displayed text starts
7917
+ * with the buffer; repeating a single character cycles through options that start
7918
+ * with that character.
7727
7919
  * @private
7728
7920
  * @param {string} _key - The key pressed by the user.
7729
7921
  * @returns {void}
7730
7922
  */
7731
7923
  updateActiveOptionBasedOnKey(_key) {
7924
+ // Ignore non-printable keys (Shift, ArrowDown, Tab, etc.)
7925
+ if (typeof _key !== 'string' || _key.length !== 1) {
7926
+ return;
7927
+ }
7732
7928
 
7733
- // Get a lowercase version of the key pressed
7734
- const key = _key.toLowerCase();
7735
-
7736
- // Calculate how many times the same letter has been pressed
7737
- this.sameLetterTimes = key === this.lastLetter ? this.sameLetterTimes + 1 : 0;
7738
-
7739
- // Set last letter for tracking
7740
- this.lastLetter = key;
7741
-
7742
- // Get all the options that start with the last letter pressed
7743
- const letterOptions = this.menu.options.filter((option) => {
7744
- const optionText = option.value || '';
7745
- return optionText.toLowerCase().startsWith(this.lastLetter);
7746
- });
7747
-
7748
- // If we have options that match the letter pressed
7749
- if (letterOptions.length) {
7750
-
7751
- // Show the dropdown if it is not already visible
7752
- this.dropdown.show();
7929
+ // No selectable options to match against — clear any stale buffer/timer so
7930
+ // Space stays a bib toggle and the next keystroke after fresh options load
7931
+ // starts cleanly. `getActiveOptions` excludes disabled, hidden, and static
7932
+ // options (e.g. `static nomatch` placeholders). Checked BEFORE mutating
7933
+ // the buffer.
7934
+ const options = getActiveOptions(this.menu);
7935
+ if (!options.length) {
7936
+ this._clearTypeaheadBuffer();
7937
+ return;
7938
+ }
7753
7939
 
7754
- // Get the index we're after based on how many times the letter has been pressed and the length of the letterOptions array
7755
- const index = this.sameLetterTimes < letterOptions.length ? this.sameLetterTimes : this.sameLetterTimes % letterOptions.length;
7940
+ const key = _key.toLowerCase();
7756
7941
 
7757
- // Select the new option in the menu
7758
- const newOption = letterOptions[index];
7759
- this.menu.updateActiveOption(newOption);
7942
+ // Reset the buffer after a period of inactivity
7943
+ if (this._typeaheadTimeout) {
7944
+ clearTimeout(this._typeaheadTimeout);
7945
+ }
7946
+ this._typeaheadTimeout = setTimeout(() => {
7947
+ this._clearTypeaheadBuffer();
7948
+ }, this.typeaheadTimeoutMs);
7949
+
7950
+ this.typeaheadBuffer += key;
7951
+
7952
+ // Prefer the literal buffer as a prefix per WAI-ARIA APG ("focus moves to the
7953
+ // next item with a name that starts with the string of characters typed").
7954
+ // Only fall back to single-char cycling when the repeated buffer has no
7955
+ // longer prefix match — e.g. "aa" cycles through ["Apple", "Apricot"] only
7956
+ // because no option starts with "aa".
7957
+ let match = options.find((option) => this._getOptionDisplayText(option).startsWith(this.typeaheadBuffer));
7958
+
7959
+ const isRepeatedChar = !match && this.typeaheadBuffer.length > 1 && new Set(this.typeaheadBuffer).size === 1;
7960
+ if (isRepeatedChar) {
7961
+ const matches = options.filter((option) => this._getOptionDisplayText(option).startsWith(key));
7962
+ if (matches.length) {
7963
+ const cycleIndex = (this.typeaheadBuffer.length - 1) % matches.length;
7964
+ match = matches[cycleIndex];
7965
+ }
7966
+ } else if (!match && this.typeaheadBuffer.length > 1) {
7967
+ // Buffer has no prefix match and isn't a repeat-char cycle (e.g. "a" then
7968
+ // "b" against [Apple, Banana]). Reset to just the new key and retry —
7969
+ // mirrors native <select>, which falls back to a single-char search when
7970
+ // accumulated input matches nothing, rather than swallowing the keystroke.
7971
+ this.typeaheadBuffer = key;
7972
+ match = options.find((option) => this._getOptionDisplayText(option).startsWith(key));
7973
+ }
7974
+
7975
+ // Intentional: no-match leaves the bib closed (deviates from APG / some native <select>).
7976
+ if (match) {
7977
+ // Pre-stash the match so the auroDropdown-toggled handler's `!optionActive`
7978
+ // guard short-circuits and skips the firstActive/selected fallback —
7979
+ // otherwise show() synchronously fires the handler, which writes
7980
+ // aria-activedescendant once before we overwrite it.
7981
+ this.menu.updateActiveOption(match);
7982
+ if (!this.dropdown.isPopoverVisible) {
7983
+ this.dropdown.show();
7984
+ }
7760
7985
  }
7761
7986
  }
7762
7987
 
@@ -7870,6 +8095,33 @@ class AuroSelect extends AuroElement$1 {
7870
8095
  }
7871
8096
  }
7872
8097
 
8098
+ disconnectedCallback() {
8099
+ super.disconnectedCallback();
8100
+ this._clearTypeaheadBuffer();
8101
+ if (this._labelObserver) {
8102
+ this._labelObserver.disconnect();
8103
+ this._labelObserver = null;
8104
+ }
8105
+ if (this._retargetLabelObserver && this.shadowRoot) {
8106
+ this.shadowRoot.querySelectorAll('slot[name="label"]').forEach((slot) => {
8107
+ slot.removeEventListener('slotchange', this._retargetLabelObserver);
8108
+ });
8109
+ this._retargetLabelObserver = null;
8110
+ }
8111
+ }
8112
+
8113
+ connectedCallback() {
8114
+ super.connectedCallback();
8115
+ // Regression guard: firstUpdated() fires once per instance, so the label
8116
+ // observer setup it triggers does NOT re-run on reconnect. After a
8117
+ // disconnect+reconnect (reparent, SPA route swap), runtime label mutations
8118
+ // would silently stop syncing menu aria-label / dropdown.bibDialogLabel
8119
+ // unless we re-wire the observer here.
8120
+ if (this.hasUpdated) {
8121
+ this._observeLabelChanges();
8122
+ }
8123
+ }
8124
+
7873
8125
  // lifecycle runs only after the element's DOM has been updated the first time
7874
8126
  firstUpdated() {
7875
8127
  // Add the tag name as an attribute if it is different than the component name
@@ -7878,11 +8130,16 @@ class AuroSelect extends AuroElement$1 {
7878
8130
  this.configureDropdown();
7879
8131
  this.configureMenu();
7880
8132
  this.configureSelect();
8133
+ this._observeLabelChanges();
7881
8134
  }
7882
8135
 
8136
+ /**
8137
+ * Sets the selected value by matching it against the menu options. Options marked `disabled` or `static` are not selectable: if the value matches one, the selection is rejected and `value` is cleared to `undefined` while `optionSelected` is cleared to `undefined` in single-select or `[]` in multiSelect. `hidden` options remain selectable.
8138
+ * @param {string} value - The value to match against the menu options.
8139
+ */
7883
8140
  setMenuValue(value) {
7884
8141
  if (!this.menu) return;
7885
- this.menu.value = value;
8142
+ this.menu.selectByValue(value);
7886
8143
  }
7887
8144
 
7888
8145
  /**
@@ -7936,6 +8193,13 @@ class AuroSelect extends AuroElement$1 {
7936
8193
  }
7937
8194
 
7938
8195
  if (changedProperties.has('value')) {
8196
+ // A value change ends the current interaction — whether it came from a
8197
+ // user commit, programmatic assignment, or reset(). Clear the buffer so
8198
+ // a stale prefix does not concatenate onto the next keystroke while the
8199
+ // host still has focus (the blur listener would otherwise be the only
8200
+ // focus-retained clear point, and hideBib() below does not blur).
8201
+ this._clearTypeaheadBuffer();
8202
+
7939
8203
  this.setMenuValue(this.value);
7940
8204
 
7941
8205
  this._updateNativeSelect();
@@ -7991,6 +8255,9 @@ class AuroSelect extends AuroElement$1 {
7991
8255
  * @returns {void}
7992
8256
  */
7993
8257
  reset() {
8258
+ // Defense-in-depth: updated()'s value-change branch also clears, but
8259
+ // reset-to-same-value (e.g. undefined → undefined) skips that path.
8260
+ this._clearTypeaheadBuffer();
7994
8261
  this.menu.reset();
7995
8262
  this.validation.reset(this);
7996
8263
  }
@@ -8010,25 +8277,23 @@ class AuroSelect extends AuroElement$1 {
8010
8277
  * @private
8011
8278
  */
8012
8279
  _handleNativeSelectChange(event) {
8280
+ // Hidden native <select> has no `multiple` attribute, so any change it fires
8281
+ // is a single raw value — applying it in multiSelect mode would collapse the
8282
+ // JSON-array `value` shape. Bfcache/autofill can reach this on a name-bearing
8283
+ // form control even with aria-hidden/tabindex=-1, so revert to the expected
8284
+ // mirror (formattedValue[0]) rather than letting the native select drift and
8285
+ // silently submit the autofilled scalar under `name`.
8286
+ if (this.multiSelect) {
8287
+ this._updateNativeSelect();
8288
+ return;
8289
+ }
8290
+
8013
8291
  const selectedOption = event.target.options[event.target.selectedIndex];
8014
8292
  if (!selectedOption) return;
8015
8293
  const selectedValue = selectedOption.value;
8016
8294
 
8017
- if (this.multiSelect) {
8018
- const currentArray = this.menu.value || [];
8019
-
8020
- if (!currentArray.includes(selectedValue)) {
8021
- this.value = JSON.stringify([
8022
- ...currentArray,
8023
- selectedValue
8024
- ]);
8025
- }
8026
- } else {
8027
- const currentValue = this.value;
8028
-
8029
- if (currentValue !== selectedValue) {
8030
- this.value = selectedValue;
8031
- }
8295
+ if (this.value !== selectedValue) {
8296
+ this.value = selectedValue;
8032
8297
  }
8033
8298
  }
8034
8299