@aurodesignsystem-dev/auro-formkit 0.0.0-pr1551.0 → 0.0.0-pr1552.0

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 (43) hide show
  1. package/components/checkbox/demo/customize.min.js +1 -1
  2. package/components/checkbox/demo/getting-started.min.js +1 -1
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/customize.min.js +207 -46
  7. package/components/combobox/demo/getting-started.min.js +207 -46
  8. package/components/combobox/demo/index.min.js +207 -46
  9. package/components/combobox/dist/index.js +207 -46
  10. package/components/combobox/dist/registered.js +207 -46
  11. package/components/counter/demo/customize.min.js +206 -45
  12. package/components/counter/demo/index.min.js +206 -45
  13. package/components/counter/dist/index.js +206 -45
  14. package/components/counter/dist/registered.js +206 -45
  15. package/components/datepicker/demo/customize.min.js +207 -46
  16. package/components/datepicker/demo/index.min.js +207 -46
  17. package/components/datepicker/dist/index.js +207 -46
  18. package/components/datepicker/dist/registered.js +207 -46
  19. package/components/dropdown/demo/customize.min.js +205 -44
  20. package/components/dropdown/demo/getting-started.min.js +205 -44
  21. package/components/dropdown/demo/index.min.js +205 -44
  22. package/components/dropdown/dist/index.js +205 -44
  23. package/components/dropdown/dist/registered.js +205 -44
  24. package/components/form/demo/customize.min.js +829 -185
  25. package/components/form/demo/getting-started.min.js +829 -185
  26. package/components/form/demo/index.min.js +829 -185
  27. package/components/form/demo/registerDemoDeps.min.js +829 -185
  28. package/components/input/demo/customize.min.js +1 -1
  29. package/components/input/demo/getting-started.min.js +1 -1
  30. package/components/input/demo/index.min.js +1 -1
  31. package/components/input/dist/index.js +1 -1
  32. package/components/input/dist/registered.js +1 -1
  33. package/components/radio/demo/customize.min.js +1 -1
  34. package/components/radio/demo/getting-started.min.js +1 -1
  35. package/components/radio/demo/index.min.js +1 -1
  36. package/components/radio/dist/index.js +1 -1
  37. package/components/radio/dist/registered.js +1 -1
  38. package/components/select/demo/customize.min.js +206 -45
  39. package/components/select/demo/getting-started.min.js +206 -45
  40. package/components/select/demo/index.min.js +206 -45
  41. package/components/select/dist/index.js +206 -45
  42. package/components/select/dist/registered.js +206 -45
  43. package/package.json +2 -2
@@ -12338,7 +12338,7 @@ let AuroHelpText$8 = class AuroHelpText extends i$2 {
12338
12338
  }
12339
12339
  };
12340
12340
 
12341
- var formkitVersion$8 = '202607100029';
12341
+ var formkitVersion$8 = '202607092329';
12342
12342
 
12343
12343
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
12344
12344
  // See LICENSE in the project root for license information.
@@ -26735,7 +26735,7 @@ let AuroBibtemplate$3 = class AuroBibtemplate extends i$2 {
26735
26735
  }
26736
26736
  };
26737
26737
 
26738
- var formkitVersion$2$1 = '202607100029';
26738
+ var formkitVersion$2$1 = '202607092329';
26739
26739
 
26740
26740
  let l$1$2 = class l{generateElementName(t,e){let o=t;return o+="-",o+=e.replace(/[.]/g,"_"),o}generateTag(o,s,a){const r=this.generateElementName(o,s),i=i$5`${s$5(r)}`;return customElements.get(r)||customElements.define(r,class extends a{}),i}};let d$1$2 = class d{registerComponent(t,e){customElements.get(t)||customElements.define(t,class extends e{});}closestElement(t,e=this,o=(e,s=e&&e.closest(t))=>e&&e!==document&&e!==window?s||o(e.getRootNode().host):null){return o(e)}handleComponentTagRename(t,e){const o=e.toLowerCase();t.tagName.toLowerCase()!==o&&t.setAttribute(o,true);}elementMatch(t,e){const o=e.toLowerCase();return t.tagName.toLowerCase()===o||t.hasAttribute(o)}getSlotText(t,e){const o=t.shadowRoot?.querySelector(`slot[name="${e}"]`),s=(o?.assignedNodes({flatten:true})||[]).map(t=>t.textContent?.trim()).join(" ").trim();return s||null}};let h$1$2 = class h{registerComponent(t,e){customElements.get(t)||customElements.define(t,class extends e{});}closestElement(t,e=this,o=(e,s=e&&e.closest(t))=>e&&e!==document&&e!==window?s||o(e.getRootNode().host):null){return o(e)}handleComponentTagRename(t,e){const o=e.toLowerCase();t.tagName.toLowerCase()!==o&&t.setAttribute(o,true);}elementMatch(t,e){const o=e.toLowerCase();return t.tagName.toLowerCase()===o||t.hasAttribute(o)}};var c$1$3=i$4`:host{color:var(--ds-auro-loader-color)}:host>span{background-color:var(--ds-auro-loader-background-color);border-color:var(--ds-auro-loader-border-color)}:host([onlight]),:host([appearance=brand]){--ds-auro-loader-color: var(--ds-basic-color-brand-primary, #01426a)}:host([ondark]),:host([appearance=inverse]){--ds-auro-loader-color: var(--ds-basic-color-texticon-inverse, #ffffff)}:host([orbit])>span{--ds-auro-loader-background-color: transparent}:host([orbit])>span:nth-child(1){--ds-auro-loader-border-color: currentcolor;opacity:.25}:host([orbit])>span:nth-child(2){--ds-auro-loader-border-color: currentcolor;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}
26741
26741
  `,u$4$2=i$4`.body-default{font-size:var(--wcss-body-default-font-size, 1rem);line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-lg{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, .875rem);line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-xs{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs{font-size:var(--wcss-body-xs-font-size, .75rem);line-height:var(--wcss-body-xs-line-height, 1rem)}.body-2xs{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:var(--wcss-body-2xs-font-size, .625rem);font-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0);line-height:var(--wcss-body-2xs-line-height, .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, 450);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, 450);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, .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, .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, .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, .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, .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, .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(.875rem, 1.1666666667vw, .875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, .1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}:focus:not(:focus-visible){outline:3px solid transparent}:host,:host>span{position:relative}:host{width:2rem;height:2rem;display:inline-block;font-size:0}:host>span{position:absolute;display:inline-block;float:none;top:0;left:0;width:2rem;height:2rem;border-radius:100%;border-style:solid;border-width:0;box-sizing:border-box}:host([xs]),:host([xs])>span{width:1.2rem;height:1.2rem}:host([sm]),:host([sm])>span{width:3rem;height:3rem}:host([md]),:host([md])>span{width:5rem;height:5rem}:host([lg]),:host([lg])>span{width:8rem;height:8rem}:host{--margin: .375rem;--margin-xs: .2rem;--margin-sm: .5rem;--margin-md: .75rem;--margin-lg: 1rem}:host([pulse]),:host([pulse])>span{position:relative}:host([pulse]){width:calc(3rem + var(--margin) * 6);height:calc(1rem + var(--margin) * 2)}:host([pulse])>span{width:1rem;height:1rem;margin:var(--margin);animation:pulse 1.5s ease infinite}:host([pulse][xs]){width:calc(1.95rem + var(--margin-xs) * 6);height:calc(.65rem + var(--margin-xs) * 2)}:host([pulse][xs])>span{margin:var(--margin-xs);width:.65rem;height:.65rem}:host([pulse][sm]){width:calc(6rem + var(--margin-sm) * 6);height:calc(2rem + var(--margin-sm) * 2)}:host([pulse][sm])>span{margin:var(--margin-sm);width:2rem;height:2rem}:host([pulse][md]){width:calc(9rem + var(--margin-md) * 6);height:calc(3rem + var(--margin-md) * 2)}:host([pulse][md])>span{margin:var(--margin-md);width:3rem;height:3rem}:host([pulse][lg]){width:calc(15rem + var(--margin-lg) * 6);height:calc(5rem + var(--margin-lg) * 2)}:host([pulse][lg])>span{margin:var(--margin-lg);width:5rem;height:5rem}:host([pulse])>span:nth-child(1){animation-delay:-.4s}:host([pulse])>span:nth-child(2){animation-delay:-.2s}:host([pulse])>span:nth-child(3){animation-delay:0ms}@keyframes pulse{0%,to{opacity:.1;transform:scale(.9)}50%{opacity:1;transform:scale(1.1)}}:host([orbit]),:host([orbit])>span{opacity:1}:host([orbit])>span{border-width:5px}:host([orbit])>span:nth-child(2){animation:orbit 2s linear infinite}:host([orbit][sm])>span{border-width:8px}:host([orbit][md])>span{border-width:13px}:host([orbit][lg])>span{border-width:21px}@keyframes orbit{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:host([ringworm])>svg{animation:rotate 2s linear infinite;height:100%;width:100%;stroke:currentcolor;stroke-width:8}:host([ringworm]) .path{stroke-dashoffset:0;animation:ringworm 1.5s ease-in-out infinite;stroke-linecap:round}@keyframes rotate{to{transform:rotate(360deg)}}@keyframes ringworm{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}to{stroke-dasharray:89,200;stroke-dashoffset:-124px}}:host([laser]){position:static;width:100%;display:block;height:0;overflow:hidden;font-size:unset}:host([laser])>span{position:fixed;width:100%;height:.25rem;border-radius:0;z-index:100}:host([laser])>span:nth-child(1){border-color:currentcolor;opacity:.25}:host([laser])>span:nth-child(2){border-color:currentcolor;animation:laser 2s linear infinite;opacity:1;width:50%}:host([laser][sm])>span:nth-child(2){width:20%}:host([laser][md])>span:nth-child(2){width:30%}:host([laser][lg])>span:nth-child(2){width:50%;animation-duration:1.5s}:host([laser][xl])>span:nth-child(2){width:80%;animation-duration:1.5s}@keyframes laser{0%{left:-100%}to{left:110%}}:host>.no-animation{display:none}@media (prefers-reduced-motion: reduce){:host{display:flex;align-items:center;justify-content:center}:host>span{opacity:1}:host>.loader{display:none}:host>svg{display:none}:host>.no-animation{display:block}}
@@ -31012,40 +31012,12 @@ let AuroFloatingUI$3 = class AuroFloatingUI {
31012
31012
  return;
31013
31013
  }
31014
31014
 
31015
- // Chrome-specific: during popover top-layer promotion after a click on a
31016
- // slotted focusable, :focus-within can briefly evaluate false while the
31017
- // active element is still structurally inside the trigger/bib. Fall back
31018
- // to a shadow-piercing ancestry walk from the deep active element before
31019
- // treating this as a real focus loss.
31020
- try {
31021
- let active = document.activeElement;
31022
- while (active && active.shadowRoot && active.shadowRoot.activeElement) {
31023
- active = active.shadowRoot.activeElement;
31024
- }
31025
- const targets = [element, element.trigger, element.bib].filter(Boolean);
31026
- let node = active;
31027
- while (node) {
31028
- if (targets.includes(node)) {
31029
- return;
31030
- }
31031
- node =
31032
- node.parentElement ||
31033
- (node.getRootNode && node.getRootNode().host) ||
31034
- null;
31035
- }
31036
- } catch (e) {
31037
- // Defensive: fall through to the existing close path if traversal fails.
31038
- }
31039
-
31040
31015
  // if fullscreen bib is in fullscreen mode, do not close
31041
31016
  if (element.bib.hasAttribute("isfullscreen")) {
31042
31017
  return;
31043
31018
  }
31044
31019
 
31045
- // eventType "focusloss" distinguishes a Tab/click-driven close from an
31046
- // Escape keydown close. Consumers use this to decide whether to restore
31047
- // focus to the trigger (Escape) or let it advance naturally (Tab).
31048
- this.hideBib("focusloss");
31020
+ this.hideBib("keydown");
31049
31021
  }
31050
31022
 
31051
31023
  setupHideHandlers() {
@@ -31715,6 +31687,199 @@ function getFocusableElements$4(container) {
31715
31687
  return tabIndexedUniqueElements;
31716
31688
  }
31717
31689
 
31690
+ /**
31691
+ * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
31692
+ * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
31693
+ */
31694
+ let FocusTrap$3 = class FocusTrap {
31695
+ /**
31696
+ * Creates a new FocusTrap instance for the given container element.
31697
+ * Initializes event listeners and prepares the container for focus management.
31698
+ *
31699
+ * @param {HTMLElement} container The DOM element to trap focus within.
31700
+ * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
31701
+ * @throws {Error} If the provided container is not a valid HTMLElement.
31702
+ */
31703
+ constructor(container, controlTabOrder = false) {
31704
+ if (!container || !(container instanceof HTMLElement)) {
31705
+ throw new Error("FocusTrap requires a valid HTMLElement.");
31706
+ }
31707
+
31708
+ this.container = container;
31709
+ this.tabDirection = "forward"; // or 'backward';
31710
+ this.controlTabOrder = controlTabOrder;
31711
+
31712
+ this._init();
31713
+ }
31714
+
31715
+ /**
31716
+ * Initializes the focus trap by setting up event listeners and attributes on the container.
31717
+ * Prepares the container for focus management, including support for shadow DOM and inert attributes.
31718
+ *
31719
+ * @private
31720
+ */
31721
+ _init() {
31722
+ // Add inert attribute to prevent focusing programmatically as well (if supported)
31723
+ if ("inert" in HTMLElement.prototype) {
31724
+ this.container.inert = false; // Ensure the container isn't inert
31725
+ this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
31726
+ }
31727
+
31728
+ // Track tab direction
31729
+ this.container.addEventListener("keydown", this._onKeydown);
31730
+ }
31731
+
31732
+ /**
31733
+ * Gets an array of currently active (focused) elements in the document and shadow DOM.
31734
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
31735
+ * @private
31736
+ */
31737
+ _getActiveElements() {
31738
+ // Get the active element(s) in the document and shadow root
31739
+ // This will include the active element in the shadow DOM if it exists
31740
+ // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
31741
+ let { activeElement } = document;
31742
+ const actives = [activeElement];
31743
+ while (activeElement?.shadowRoot?.activeElement) {
31744
+ actives.push(activeElement.shadowRoot.activeElement);
31745
+ activeElement = activeElement.shadowRoot.activeElement;
31746
+ }
31747
+ return actives;
31748
+ }
31749
+
31750
+ /**
31751
+ * Gets the next focus index based on the current index and focusable elements.
31752
+ * @param {number} currentIndex The current index of the focused element.
31753
+ * @param {Array<HTMLElement>} focusables The array of focusable elements.
31754
+ * @returns {number|null} The next focus index or null if not determined.
31755
+ */
31756
+ _getNextFocusIndex(currentIndex, focusables, actives) {
31757
+ if (this.controlTabOrder) {
31758
+ // Calculate the new index based on the current index and tab direction
31759
+ let newFocusIndex =
31760
+ currentIndex + (this.tabDirection === "forward" ? 1 : -1);
31761
+
31762
+ // Wrap-around logic
31763
+ if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
31764
+ if (newFocusIndex >= focusables.length) newFocusIndex = 0;
31765
+
31766
+ // Early return with the new index
31767
+ return newFocusIndex;
31768
+ }
31769
+
31770
+ // Determine if we need to wrap
31771
+ const atFirst =
31772
+ actives.includes(focusables[0]) || actives.includes(this.container);
31773
+ const atLast = actives.includes(focusables[focusables.length - 1]);
31774
+
31775
+ // Only wrap if at the ends
31776
+ if (this.tabDirection === "backward" && atFirst) {
31777
+ return focusables.length - 1;
31778
+ }
31779
+
31780
+ if (this.tabDirection === "forward" && atLast) {
31781
+ return 0;
31782
+ }
31783
+
31784
+ // No wrap, so don't change focus, return early
31785
+ return null;
31786
+ }
31787
+
31788
+ /**
31789
+ * Handles the Tab key press event to manage focus within the container.
31790
+ * @param {KeyboardEvent} e The keyboard event triggered by the user.
31791
+ * @returns {void}
31792
+ */
31793
+ _handleTabKey(e) {
31794
+ // Update the focusable elements
31795
+ const focusables = this._getFocusableElements();
31796
+
31797
+ // If there are no focusable elements, exit
31798
+ if (!focusables.length) return;
31799
+
31800
+ // Set the tab direction based on the key pressed
31801
+ this.tabDirection = e.shiftKey ? "backward" : "forward";
31802
+
31803
+ // Get the active elements that are currently focused
31804
+ const actives = this._getActiveElements();
31805
+
31806
+ // If we're at either end of the focusable elements, wrap around to the other end
31807
+ let focusIndex = focusables.findIndex((el) => actives.includes(el));
31808
+
31809
+ // Fallback if we have no focused element
31810
+ if (focusIndex === -1) focusIndex = 0;
31811
+
31812
+ // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
31813
+ // Is null if no new focus index is determined
31814
+ const newFocusIndex = this._getNextFocusIndex(
31815
+ focusIndex,
31816
+ focusables,
31817
+ actives,
31818
+ );
31819
+
31820
+ // If we have a new focus index, set focus to that element
31821
+ if (newFocusIndex !== null) {
31822
+ e.preventDefault();
31823
+ focusables[newFocusIndex].focus();
31824
+ }
31825
+ }
31826
+
31827
+ /**
31828
+ * Catches the keydown event
31829
+ * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
31830
+ * @private
31831
+ */
31832
+ _onKeydown = (e) => {
31833
+ // Handle tab
31834
+ if (e.key === "Tab") this._handleTabKey(e);
31835
+ };
31836
+
31837
+ /**
31838
+ * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
31839
+ * Returns a unique, ordered array of elements that can receive focus.
31840
+ *
31841
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
31842
+ * @private
31843
+ */
31844
+ _getFocusableElements() {
31845
+ // Use the imported utility function to get focusable elements
31846
+ const elements = getFocusableElements$4(this.container);
31847
+
31848
+ // Return the elements found
31849
+ return elements;
31850
+ }
31851
+
31852
+ /**
31853
+ * Moves focus to the first focusable element within the container.
31854
+ * Useful for setting initial focus when activating the focus trap.
31855
+ */
31856
+ focusFirstElement() {
31857
+ const focusables = this._getFocusableElements();
31858
+ if (focusables.length) focusables[0].focus();
31859
+ }
31860
+
31861
+ /**
31862
+ * Moves focus to the last focusable element within the container.
31863
+ * Useful for setting focus when deactivating or cycling focus in reverse.
31864
+ */
31865
+ focusLastElement() {
31866
+ const focusables = this._getFocusableElements();
31867
+ if (focusables.length) focusables[focusables.length - 1].focus();
31868
+ }
31869
+
31870
+ /**
31871
+ * Removes event listeners and attributes added by the focus trap.
31872
+ * Call this method to clean up when the focus trap is no longer needed.
31873
+ */
31874
+ disconnect() {
31875
+ if (this.container.hasAttribute("data-focus-trap-container")) {
31876
+ this.container.removeAttribute("data-focus-trap-container");
31877
+ }
31878
+
31879
+ this.container.removeEventListener("keydown", this._onKeydown);
31880
+ }
31881
+ };
31882
+
31718
31883
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
31719
31884
  // See LICENSE in the project root for license information.
31720
31885
 
@@ -32212,7 +32377,7 @@ let AuroDropdownBib$3 = class AuroDropdownBib extends i$2 {
32212
32377
  classes[`shape-${this.shape}`] = true;
32213
32378
 
32214
32379
  return u$d`
32215
- <dialog tabindex="-1" class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
32380
+ <dialog class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
32216
32381
  ${this.dialogLabel ? u$d`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
32217
32382
  <slot></slot>
32218
32383
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -32463,7 +32628,7 @@ let AuroHelpText$2$1 = class AuroHelpText extends i$2 {
32463
32628
  }
32464
32629
  };
32465
32630
 
32466
- var formkitVersion$1$3 = '202607100029';
32631
+ var formkitVersion$1$3 = '202607092329';
32467
32632
 
32468
32633
  let AuroElement$2$2 = class AuroElement extends i$2 {
32469
32634
  static get properties() {
@@ -33217,10 +33382,7 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
33217
33382
  }
33218
33383
 
33219
33384
 
33220
- // On Tab-driven close (eventType "focusloss"), let focus advance naturally
33221
- // — restoring to the trigger would trap the user on this dropdown, forcing
33222
- // an extra Tab to move on. Escape and outside-click still restore.
33223
- if (!this.isPopoverVisible && eventType !== "focusloss") {
33385
+ if (!this.isPopoverVisible) {
33224
33386
  // wait til the bib gets fully closed and rendered
33225
33387
  setTimeout(() => {
33226
33388
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -33450,16 +33612,15 @@ let AuroDropdown$3 = class AuroDropdown extends AuroElement$2$2 {
33450
33612
  }
33451
33613
  });
33452
33614
  } else {
33453
- // Normal desktop (non-modal): move initial focus into the bib but
33454
- // don't trap Tab. Tab should exit the bib and let the floater's
33455
- // handleFocusLoss close it, matching native <select>/<details>
33456
- // behavior. Deferred one frame because Floating UI positions the
33457
- // popover asynchronously a synchronous focus() would target
33458
- // zero-dimension elements and be silently ignored.
33615
+ // Normal desktop: use FocusTrap on the bib element.
33616
+ // Defer focusFirstElement to the next frame because the popover
33617
+ // is positioned asynchronously by Floating UI — calling focus()
33618
+ // synchronously here would target elements with zero dimensions
33619
+ // and the focus call would be silently ignored.
33620
+ this.focusTrap = new FocusTrap$3(this.bibContent);
33459
33621
  requestAnimationFrame(() => {
33460
- const focusables = getFocusableElements$4(this.bibContent);
33461
- if (focusables.length) {
33462
- focusables[0].focus();
33622
+ if (this.focusTrap) {
33623
+ this.focusTrap.focusFirstElement();
33463
33624
  }
33464
33625
  });
33465
33626
  }
@@ -46085,7 +46246,7 @@ let AuroHelpText$1$3 = class AuroHelpText extends i$2 {
46085
46246
  }
46086
46247
  };
46087
46248
 
46088
- var formkitVersion$7 = '202607100029';
46249
+ var formkitVersion$7 = '202607092329';
46089
46250
 
46090
46251
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
46091
46252
  // See LICENSE in the project root for license information.
@@ -51026,7 +51187,7 @@ let AuroHelpText$1$2 = class AuroHelpText extends i$2 {
51026
51187
  }
51027
51188
  };
51028
51189
 
51029
- var formkitVersion$1$2 = '202607100029';
51190
+ var formkitVersion$1$2 = '202607092329';
51030
51191
 
51031
51192
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
51032
51193
  // See LICENSE in the project root for license information.
@@ -53738,40 +53899,12 @@ let AuroFloatingUI$2 = class AuroFloatingUI {
53738
53899
  return;
53739
53900
  }
53740
53901
 
53741
- // Chrome-specific: during popover top-layer promotion after a click on a
53742
- // slotted focusable, :focus-within can briefly evaluate false while the
53743
- // active element is still structurally inside the trigger/bib. Fall back
53744
- // to a shadow-piercing ancestry walk from the deep active element before
53745
- // treating this as a real focus loss.
53746
- try {
53747
- let active = document.activeElement;
53748
- while (active && active.shadowRoot && active.shadowRoot.activeElement) {
53749
- active = active.shadowRoot.activeElement;
53750
- }
53751
- const targets = [element, element.trigger, element.bib].filter(Boolean);
53752
- let node = active;
53753
- while (node) {
53754
- if (targets.includes(node)) {
53755
- return;
53756
- }
53757
- node =
53758
- node.parentElement ||
53759
- (node.getRootNode && node.getRootNode().host) ||
53760
- null;
53761
- }
53762
- } catch (e) {
53763
- // Defensive: fall through to the existing close path if traversal fails.
53764
- }
53765
-
53766
53902
  // if fullscreen bib is in fullscreen mode, do not close
53767
53903
  if (element.bib.hasAttribute("isfullscreen")) {
53768
53904
  return;
53769
53905
  }
53770
53906
 
53771
- // eventType "focusloss" distinguishes a Tab/click-driven close from an
53772
- // Escape keydown close. Consumers use this to decide whether to restore
53773
- // focus to the trigger (Escape) or let it advance naturally (Tab).
53774
- this.hideBib("focusloss");
53907
+ this.hideBib("keydown");
53775
53908
  }
53776
53909
 
53777
53910
  setupHideHandlers() {
@@ -54441,6 +54574,199 @@ function getFocusableElements$3(container) {
54441
54574
  return tabIndexedUniqueElements;
54442
54575
  }
54443
54576
 
54577
+ /**
54578
+ * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
54579
+ * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
54580
+ */
54581
+ let FocusTrap$2 = class FocusTrap {
54582
+ /**
54583
+ * Creates a new FocusTrap instance for the given container element.
54584
+ * Initializes event listeners and prepares the container for focus management.
54585
+ *
54586
+ * @param {HTMLElement} container The DOM element to trap focus within.
54587
+ * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
54588
+ * @throws {Error} If the provided container is not a valid HTMLElement.
54589
+ */
54590
+ constructor(container, controlTabOrder = false) {
54591
+ if (!container || !(container instanceof HTMLElement)) {
54592
+ throw new Error("FocusTrap requires a valid HTMLElement.");
54593
+ }
54594
+
54595
+ this.container = container;
54596
+ this.tabDirection = "forward"; // or 'backward';
54597
+ this.controlTabOrder = controlTabOrder;
54598
+
54599
+ this._init();
54600
+ }
54601
+
54602
+ /**
54603
+ * Initializes the focus trap by setting up event listeners and attributes on the container.
54604
+ * Prepares the container for focus management, including support for shadow DOM and inert attributes.
54605
+ *
54606
+ * @private
54607
+ */
54608
+ _init() {
54609
+ // Add inert attribute to prevent focusing programmatically as well (if supported)
54610
+ if ("inert" in HTMLElement.prototype) {
54611
+ this.container.inert = false; // Ensure the container isn't inert
54612
+ this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
54613
+ }
54614
+
54615
+ // Track tab direction
54616
+ this.container.addEventListener("keydown", this._onKeydown);
54617
+ }
54618
+
54619
+ /**
54620
+ * Gets an array of currently active (focused) elements in the document and shadow DOM.
54621
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
54622
+ * @private
54623
+ */
54624
+ _getActiveElements() {
54625
+ // Get the active element(s) in the document and shadow root
54626
+ // This will include the active element in the shadow DOM if it exists
54627
+ // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
54628
+ let { activeElement } = document;
54629
+ const actives = [activeElement];
54630
+ while (activeElement?.shadowRoot?.activeElement) {
54631
+ actives.push(activeElement.shadowRoot.activeElement);
54632
+ activeElement = activeElement.shadowRoot.activeElement;
54633
+ }
54634
+ return actives;
54635
+ }
54636
+
54637
+ /**
54638
+ * Gets the next focus index based on the current index and focusable elements.
54639
+ * @param {number} currentIndex The current index of the focused element.
54640
+ * @param {Array<HTMLElement>} focusables The array of focusable elements.
54641
+ * @returns {number|null} The next focus index or null if not determined.
54642
+ */
54643
+ _getNextFocusIndex(currentIndex, focusables, actives) {
54644
+ if (this.controlTabOrder) {
54645
+ // Calculate the new index based on the current index and tab direction
54646
+ let newFocusIndex =
54647
+ currentIndex + (this.tabDirection === "forward" ? 1 : -1);
54648
+
54649
+ // Wrap-around logic
54650
+ if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
54651
+ if (newFocusIndex >= focusables.length) newFocusIndex = 0;
54652
+
54653
+ // Early return with the new index
54654
+ return newFocusIndex;
54655
+ }
54656
+
54657
+ // Determine if we need to wrap
54658
+ const atFirst =
54659
+ actives.includes(focusables[0]) || actives.includes(this.container);
54660
+ const atLast = actives.includes(focusables[focusables.length - 1]);
54661
+
54662
+ // Only wrap if at the ends
54663
+ if (this.tabDirection === "backward" && atFirst) {
54664
+ return focusables.length - 1;
54665
+ }
54666
+
54667
+ if (this.tabDirection === "forward" && atLast) {
54668
+ return 0;
54669
+ }
54670
+
54671
+ // No wrap, so don't change focus, return early
54672
+ return null;
54673
+ }
54674
+
54675
+ /**
54676
+ * Handles the Tab key press event to manage focus within the container.
54677
+ * @param {KeyboardEvent} e The keyboard event triggered by the user.
54678
+ * @returns {void}
54679
+ */
54680
+ _handleTabKey(e) {
54681
+ // Update the focusable elements
54682
+ const focusables = this._getFocusableElements();
54683
+
54684
+ // If there are no focusable elements, exit
54685
+ if (!focusables.length) return;
54686
+
54687
+ // Set the tab direction based on the key pressed
54688
+ this.tabDirection = e.shiftKey ? "backward" : "forward";
54689
+
54690
+ // Get the active elements that are currently focused
54691
+ const actives = this._getActiveElements();
54692
+
54693
+ // If we're at either end of the focusable elements, wrap around to the other end
54694
+ let focusIndex = focusables.findIndex((el) => actives.includes(el));
54695
+
54696
+ // Fallback if we have no focused element
54697
+ if (focusIndex === -1) focusIndex = 0;
54698
+
54699
+ // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
54700
+ // Is null if no new focus index is determined
54701
+ const newFocusIndex = this._getNextFocusIndex(
54702
+ focusIndex,
54703
+ focusables,
54704
+ actives,
54705
+ );
54706
+
54707
+ // If we have a new focus index, set focus to that element
54708
+ if (newFocusIndex !== null) {
54709
+ e.preventDefault();
54710
+ focusables[newFocusIndex].focus();
54711
+ }
54712
+ }
54713
+
54714
+ /**
54715
+ * Catches the keydown event
54716
+ * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
54717
+ * @private
54718
+ */
54719
+ _onKeydown = (e) => {
54720
+ // Handle tab
54721
+ if (e.key === "Tab") this._handleTabKey(e);
54722
+ };
54723
+
54724
+ /**
54725
+ * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
54726
+ * Returns a unique, ordered array of elements that can receive focus.
54727
+ *
54728
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
54729
+ * @private
54730
+ */
54731
+ _getFocusableElements() {
54732
+ // Use the imported utility function to get focusable elements
54733
+ const elements = getFocusableElements$3(this.container);
54734
+
54735
+ // Return the elements found
54736
+ return elements;
54737
+ }
54738
+
54739
+ /**
54740
+ * Moves focus to the first focusable element within the container.
54741
+ * Useful for setting initial focus when activating the focus trap.
54742
+ */
54743
+ focusFirstElement() {
54744
+ const focusables = this._getFocusableElements();
54745
+ if (focusables.length) focusables[0].focus();
54746
+ }
54747
+
54748
+ /**
54749
+ * Moves focus to the last focusable element within the container.
54750
+ * Useful for setting focus when deactivating or cycling focus in reverse.
54751
+ */
54752
+ focusLastElement() {
54753
+ const focusables = this._getFocusableElements();
54754
+ if (focusables.length) focusables[focusables.length - 1].focus();
54755
+ }
54756
+
54757
+ /**
54758
+ * Removes event listeners and attributes added by the focus trap.
54759
+ * Call this method to clean up when the focus trap is no longer needed.
54760
+ */
54761
+ disconnect() {
54762
+ if (this.container.hasAttribute("data-focus-trap-container")) {
54763
+ this.container.removeAttribute("data-focus-trap-container");
54764
+ }
54765
+
54766
+ this.container.removeEventListener("keydown", this._onKeydown);
54767
+ }
54768
+ };
54769
+
54444
54770
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
54445
54771
  // See LICENSE in the project root for license information.
54446
54772
 
@@ -54938,7 +55264,7 @@ let AuroDropdownBib$2 = class AuroDropdownBib extends i$2 {
54938
55264
  classes[`shape-${this.shape}`] = true;
54939
55265
 
54940
55266
  return u$d`
54941
- <dialog tabindex="-1" class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
55267
+ <dialog class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
54942
55268
  ${this.dialogLabel ? u$d`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
54943
55269
  <slot></slot>
54944
55270
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -55189,7 +55515,7 @@ let AuroHelpText$6 = class AuroHelpText extends i$2 {
55189
55515
  }
55190
55516
  };
55191
55517
 
55192
- var formkitVersion$6 = '202607100029';
55518
+ var formkitVersion$6 = '202607092329';
55193
55519
 
55194
55520
  let AuroElement$1$2 = class AuroElement extends i$2 {
55195
55521
  static get properties() {
@@ -55943,10 +56269,7 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
55943
56269
  }
55944
56270
 
55945
56271
 
55946
- // On Tab-driven close (eventType "focusloss"), let focus advance naturally
55947
- // — restoring to the trigger would trap the user on this dropdown, forcing
55948
- // an extra Tab to move on. Escape and outside-click still restore.
55949
- if (!this.isPopoverVisible && eventType !== "focusloss") {
56272
+ if (!this.isPopoverVisible) {
55950
56273
  // wait til the bib gets fully closed and rendered
55951
56274
  setTimeout(() => {
55952
56275
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -56176,16 +56499,15 @@ let AuroDropdown$2 = class AuroDropdown extends AuroElement$1$2 {
56176
56499
  }
56177
56500
  });
56178
56501
  } else {
56179
- // Normal desktop (non-modal): move initial focus into the bib but
56180
- // don't trap Tab. Tab should exit the bib and let the floater's
56181
- // handleFocusLoss close it, matching native <select>/<details>
56182
- // behavior. Deferred one frame because Floating UI positions the
56183
- // popover asynchronously a synchronous focus() would target
56184
- // zero-dimension elements and be silently ignored.
56502
+ // Normal desktop: use FocusTrap on the bib element.
56503
+ // Defer focusFirstElement to the next frame because the popover
56504
+ // is positioned asynchronously by Floating UI — calling focus()
56505
+ // synchronously here would target elements with zero dimensions
56506
+ // and the focus call would be silently ignored.
56507
+ this.focusTrap = new FocusTrap$2(this.bibContent);
56185
56508
  requestAnimationFrame(() => {
56186
- const focusables = getFocusableElements$3(this.bibContent);
56187
- if (focusables.length) {
56188
- focusables[0].focus();
56509
+ if (this.focusTrap) {
56510
+ this.focusTrap.focusFirstElement();
56189
56511
  }
56190
56512
  });
56191
56513
  }
@@ -59173,7 +59495,7 @@ let AuroHelpText$5 = class AuroHelpText extends i$2 {
59173
59495
  }
59174
59496
  };
59175
59497
 
59176
- var formkitVersion$5 = '202607100029';
59498
+ var formkitVersion$5 = '202607092329';
59177
59499
 
59178
59500
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
59179
59501
  // See LICENSE in the project root for license information.
@@ -60938,7 +61260,7 @@ let AuroHelpText$4 = class AuroHelpText extends i$2 {
60938
61260
  }
60939
61261
  };
60940
61262
 
60941
- var formkitVersion$4 = '202607100029';
61263
+ var formkitVersion$4 = '202607092329';
60942
61264
 
60943
61265
  // Copyright (c) 2026 Alaska Airlines. All rights reserved. Licensed under the Apache-2.0 license
60944
61266
  // See LICENSE in the project root for license information.
@@ -64800,40 +65122,12 @@ let AuroFloatingUI$1 = class AuroFloatingUI {
64800
65122
  return;
64801
65123
  }
64802
65124
 
64803
- // Chrome-specific: during popover top-layer promotion after a click on a
64804
- // slotted focusable, :focus-within can briefly evaluate false while the
64805
- // active element is still structurally inside the trigger/bib. Fall back
64806
- // to a shadow-piercing ancestry walk from the deep active element before
64807
- // treating this as a real focus loss.
64808
- try {
64809
- let active = document.activeElement;
64810
- while (active && active.shadowRoot && active.shadowRoot.activeElement) {
64811
- active = active.shadowRoot.activeElement;
64812
- }
64813
- const targets = [element, element.trigger, element.bib].filter(Boolean);
64814
- let node = active;
64815
- while (node) {
64816
- if (targets.includes(node)) {
64817
- return;
64818
- }
64819
- node =
64820
- node.parentElement ||
64821
- (node.getRootNode && node.getRootNode().host) ||
64822
- null;
64823
- }
64824
- } catch (e) {
64825
- // Defensive: fall through to the existing close path if traversal fails.
64826
- }
64827
-
64828
65125
  // if fullscreen bib is in fullscreen mode, do not close
64829
65126
  if (element.bib.hasAttribute("isfullscreen")) {
64830
65127
  return;
64831
65128
  }
64832
65129
 
64833
- // eventType "focusloss" distinguishes a Tab/click-driven close from an
64834
- // Escape keydown close. Consumers use this to decide whether to restore
64835
- // focus to the trigger (Escape) or let it advance naturally (Tab).
64836
- this.hideBib("focusloss");
65130
+ this.hideBib("keydown");
64837
65131
  }
64838
65132
 
64839
65133
  setupHideHandlers() {
@@ -65503,6 +65797,199 @@ function getFocusableElements$2(container) {
65503
65797
  return tabIndexedUniqueElements;
65504
65798
  }
65505
65799
 
65800
+ /**
65801
+ * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
65802
+ * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
65803
+ */
65804
+ let FocusTrap$1 = class FocusTrap {
65805
+ /**
65806
+ * Creates a new FocusTrap instance for the given container element.
65807
+ * Initializes event listeners and prepares the container for focus management.
65808
+ *
65809
+ * @param {HTMLElement} container The DOM element to trap focus within.
65810
+ * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
65811
+ * @throws {Error} If the provided container is not a valid HTMLElement.
65812
+ */
65813
+ constructor(container, controlTabOrder = false) {
65814
+ if (!container || !(container instanceof HTMLElement)) {
65815
+ throw new Error("FocusTrap requires a valid HTMLElement.");
65816
+ }
65817
+
65818
+ this.container = container;
65819
+ this.tabDirection = "forward"; // or 'backward';
65820
+ this.controlTabOrder = controlTabOrder;
65821
+
65822
+ this._init();
65823
+ }
65824
+
65825
+ /**
65826
+ * Initializes the focus trap by setting up event listeners and attributes on the container.
65827
+ * Prepares the container for focus management, including support for shadow DOM and inert attributes.
65828
+ *
65829
+ * @private
65830
+ */
65831
+ _init() {
65832
+ // Add inert attribute to prevent focusing programmatically as well (if supported)
65833
+ if ("inert" in HTMLElement.prototype) {
65834
+ this.container.inert = false; // Ensure the container isn't inert
65835
+ this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
65836
+ }
65837
+
65838
+ // Track tab direction
65839
+ this.container.addEventListener("keydown", this._onKeydown);
65840
+ }
65841
+
65842
+ /**
65843
+ * Gets an array of currently active (focused) elements in the document and shadow DOM.
65844
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
65845
+ * @private
65846
+ */
65847
+ _getActiveElements() {
65848
+ // Get the active element(s) in the document and shadow root
65849
+ // This will include the active element in the shadow DOM if it exists
65850
+ // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
65851
+ let { activeElement } = document;
65852
+ const actives = [activeElement];
65853
+ while (activeElement?.shadowRoot?.activeElement) {
65854
+ actives.push(activeElement.shadowRoot.activeElement);
65855
+ activeElement = activeElement.shadowRoot.activeElement;
65856
+ }
65857
+ return actives;
65858
+ }
65859
+
65860
+ /**
65861
+ * Gets the next focus index based on the current index and focusable elements.
65862
+ * @param {number} currentIndex The current index of the focused element.
65863
+ * @param {Array<HTMLElement>} focusables The array of focusable elements.
65864
+ * @returns {number|null} The next focus index or null if not determined.
65865
+ */
65866
+ _getNextFocusIndex(currentIndex, focusables, actives) {
65867
+ if (this.controlTabOrder) {
65868
+ // Calculate the new index based on the current index and tab direction
65869
+ let newFocusIndex =
65870
+ currentIndex + (this.tabDirection === "forward" ? 1 : -1);
65871
+
65872
+ // Wrap-around logic
65873
+ if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
65874
+ if (newFocusIndex >= focusables.length) newFocusIndex = 0;
65875
+
65876
+ // Early return with the new index
65877
+ return newFocusIndex;
65878
+ }
65879
+
65880
+ // Determine if we need to wrap
65881
+ const atFirst =
65882
+ actives.includes(focusables[0]) || actives.includes(this.container);
65883
+ const atLast = actives.includes(focusables[focusables.length - 1]);
65884
+
65885
+ // Only wrap if at the ends
65886
+ if (this.tabDirection === "backward" && atFirst) {
65887
+ return focusables.length - 1;
65888
+ }
65889
+
65890
+ if (this.tabDirection === "forward" && atLast) {
65891
+ return 0;
65892
+ }
65893
+
65894
+ // No wrap, so don't change focus, return early
65895
+ return null;
65896
+ }
65897
+
65898
+ /**
65899
+ * Handles the Tab key press event to manage focus within the container.
65900
+ * @param {KeyboardEvent} e The keyboard event triggered by the user.
65901
+ * @returns {void}
65902
+ */
65903
+ _handleTabKey(e) {
65904
+ // Update the focusable elements
65905
+ const focusables = this._getFocusableElements();
65906
+
65907
+ // If there are no focusable elements, exit
65908
+ if (!focusables.length) return;
65909
+
65910
+ // Set the tab direction based on the key pressed
65911
+ this.tabDirection = e.shiftKey ? "backward" : "forward";
65912
+
65913
+ // Get the active elements that are currently focused
65914
+ const actives = this._getActiveElements();
65915
+
65916
+ // If we're at either end of the focusable elements, wrap around to the other end
65917
+ let focusIndex = focusables.findIndex((el) => actives.includes(el));
65918
+
65919
+ // Fallback if we have no focused element
65920
+ if (focusIndex === -1) focusIndex = 0;
65921
+
65922
+ // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
65923
+ // Is null if no new focus index is determined
65924
+ const newFocusIndex = this._getNextFocusIndex(
65925
+ focusIndex,
65926
+ focusables,
65927
+ actives,
65928
+ );
65929
+
65930
+ // If we have a new focus index, set focus to that element
65931
+ if (newFocusIndex !== null) {
65932
+ e.preventDefault();
65933
+ focusables[newFocusIndex].focus();
65934
+ }
65935
+ }
65936
+
65937
+ /**
65938
+ * Catches the keydown event
65939
+ * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
65940
+ * @private
65941
+ */
65942
+ _onKeydown = (e) => {
65943
+ // Handle tab
65944
+ if (e.key === "Tab") this._handleTabKey(e);
65945
+ };
65946
+
65947
+ /**
65948
+ * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
65949
+ * Returns a unique, ordered array of elements that can receive focus.
65950
+ *
65951
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
65952
+ * @private
65953
+ */
65954
+ _getFocusableElements() {
65955
+ // Use the imported utility function to get focusable elements
65956
+ const elements = getFocusableElements$2(this.container);
65957
+
65958
+ // Return the elements found
65959
+ return elements;
65960
+ }
65961
+
65962
+ /**
65963
+ * Moves focus to the first focusable element within the container.
65964
+ * Useful for setting initial focus when activating the focus trap.
65965
+ */
65966
+ focusFirstElement() {
65967
+ const focusables = this._getFocusableElements();
65968
+ if (focusables.length) focusables[0].focus();
65969
+ }
65970
+
65971
+ /**
65972
+ * Moves focus to the last focusable element within the container.
65973
+ * Useful for setting focus when deactivating or cycling focus in reverse.
65974
+ */
65975
+ focusLastElement() {
65976
+ const focusables = this._getFocusableElements();
65977
+ if (focusables.length) focusables[focusables.length - 1].focus();
65978
+ }
65979
+
65980
+ /**
65981
+ * Removes event listeners and attributes added by the focus trap.
65982
+ * Call this method to clean up when the focus trap is no longer needed.
65983
+ */
65984
+ disconnect() {
65985
+ if (this.container.hasAttribute("data-focus-trap-container")) {
65986
+ this.container.removeAttribute("data-focus-trap-container");
65987
+ }
65988
+
65989
+ this.container.removeEventListener("keydown", this._onKeydown);
65990
+ }
65991
+ };
65992
+
65506
65993
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
65507
65994
  // See LICENSE in the project root for license information.
65508
65995
 
@@ -66000,7 +66487,7 @@ let AuroDropdownBib$1 = class AuroDropdownBib extends i$2 {
66000
66487
  classes[`shape-${this.shape}`] = true;
66001
66488
 
66002
66489
  return u$d`
66003
- <dialog tabindex="-1" class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
66490
+ <dialog class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
66004
66491
  ${this.dialogLabel ? u$d`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
66005
66492
  <slot></slot>
66006
66493
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -66251,7 +66738,7 @@ let AuroHelpText$2 = class AuroHelpText extends i$2 {
66251
66738
  }
66252
66739
  };
66253
66740
 
66254
- var formkitVersion$2 = '202607100029';
66741
+ var formkitVersion$2 = '202607092329';
66255
66742
 
66256
66743
  let AuroElement$2$1 = class AuroElement extends i$2 {
66257
66744
  static get properties() {
@@ -67005,10 +67492,7 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
67005
67492
  }
67006
67493
 
67007
67494
 
67008
- // On Tab-driven close (eventType "focusloss"), let focus advance naturally
67009
- // — restoring to the trigger would trap the user on this dropdown, forcing
67010
- // an extra Tab to move on. Escape and outside-click still restore.
67011
- if (!this.isPopoverVisible && eventType !== "focusloss") {
67495
+ if (!this.isPopoverVisible) {
67012
67496
  // wait til the bib gets fully closed and rendered
67013
67497
  setTimeout(() => {
67014
67498
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -67238,16 +67722,15 @@ let AuroDropdown$1 = class AuroDropdown extends AuroElement$2$1 {
67238
67722
  }
67239
67723
  });
67240
67724
  } else {
67241
- // Normal desktop (non-modal): move initial focus into the bib but
67242
- // don't trap Tab. Tab should exit the bib and let the floater's
67243
- // handleFocusLoss close it, matching native <select>/<details>
67244
- // behavior. Deferred one frame because Floating UI positions the
67245
- // popover asynchronously a synchronous focus() would target
67246
- // zero-dimension elements and be silently ignored.
67725
+ // Normal desktop: use FocusTrap on the bib element.
67726
+ // Defer focusFirstElement to the next frame because the popover
67727
+ // is positioned asynchronously by Floating UI — calling focus()
67728
+ // synchronously here would target elements with zero dimensions
67729
+ // and the focus call would be silently ignored.
67730
+ this.focusTrap = new FocusTrap$1(this.bibContent);
67247
67731
  requestAnimationFrame(() => {
67248
- const focusables = getFocusableElements$2(this.bibContent);
67249
- if (focusables.length) {
67250
- focusables[0].focus();
67732
+ if (this.focusTrap) {
67733
+ this.focusTrap.focusFirstElement();
67251
67734
  }
67252
67735
  });
67253
67736
  }
@@ -79873,7 +80356,7 @@ let AuroHelpText$1$1 = class AuroHelpText extends i$2 {
79873
80356
  }
79874
80357
  };
79875
80358
 
79876
- var formkitVersion$1$1 = '202607100029';
80359
+ var formkitVersion$1$1 = '202607092329';
79877
80360
 
79878
80361
  // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
79879
80362
  // See LICENSE in the project root for license information.
@@ -80994,7 +81477,7 @@ let AuroBibtemplate$1 = class AuroBibtemplate extends i$2 {
80994
81477
  }
80995
81478
  };
80996
81479
 
80997
- var formkitVersion$3 = '202607100029';
81480
+ var formkitVersion$3 = '202607092329';
80998
81481
 
80999
81482
  var styleCss$1$3 = i$4`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}:host{display:block;text-align:left}:host [auro-dropdown]{--ds-auro-dropdown-trigger-background-color: transparent}:host #inputInBib::part(wrapper){box-shadow:none}:host #inputInBib::part(accent-left){display:none}:host([layout*=classic]) [auro-input]{width:100%}:host([layout*=classic]) [auro-input]::part(helpText){display:none}:host([layout*=classic]) #slotHolder{display:none}`;
81000
81483
 
@@ -88364,40 +88847,12 @@ class AuroFloatingUI {
88364
88847
  return;
88365
88848
  }
88366
88849
 
88367
- // Chrome-specific: during popover top-layer promotion after a click on a
88368
- // slotted focusable, :focus-within can briefly evaluate false while the
88369
- // active element is still structurally inside the trigger/bib. Fall back
88370
- // to a shadow-piercing ancestry walk from the deep active element before
88371
- // treating this as a real focus loss.
88372
- try {
88373
- let active = document.activeElement;
88374
- while (active && active.shadowRoot && active.shadowRoot.activeElement) {
88375
- active = active.shadowRoot.activeElement;
88376
- }
88377
- const targets = [element, element.trigger, element.bib].filter(Boolean);
88378
- let node = active;
88379
- while (node) {
88380
- if (targets.includes(node)) {
88381
- return;
88382
- }
88383
- node =
88384
- node.parentElement ||
88385
- (node.getRootNode && node.getRootNode().host) ||
88386
- null;
88387
- }
88388
- } catch (e) {
88389
- // Defensive: fall through to the existing close path if traversal fails.
88390
- }
88391
-
88392
88850
  // if fullscreen bib is in fullscreen mode, do not close
88393
88851
  if (element.bib.hasAttribute("isfullscreen")) {
88394
88852
  return;
88395
88853
  }
88396
88854
 
88397
- // eventType "focusloss" distinguishes a Tab/click-driven close from an
88398
- // Escape keydown close. Consumers use this to decide whether to restore
88399
- // focus to the trigger (Escape) or let it advance naturally (Tab).
88400
- this.hideBib("focusloss");
88855
+ this.hideBib("keydown");
88401
88856
  }
88402
88857
 
88403
88858
  setupHideHandlers() {
@@ -89067,6 +89522,199 @@ function getFocusableElements(container) {
89067
89522
  return tabIndexedUniqueElements;
89068
89523
  }
89069
89524
 
89525
+ /**
89526
+ * FocusTrap manages keyboard focus within a specified container element, ensuring that focus does not leave the container when tabbing.
89527
+ * It is commonly used for modal dialogs or overlays to improve accessibility by trapping focus within interactive UI components.
89528
+ */
89529
+ class FocusTrap {
89530
+ /**
89531
+ * Creates a new FocusTrap instance for the given container element.
89532
+ * Initializes event listeners and prepares the container for focus management.
89533
+ *
89534
+ * @param {HTMLElement} container The DOM element to trap focus within.
89535
+ * @param {boolean} [controlTabOrder=false] If true enables manual control of the tab order by the FocusTrap.
89536
+ * @throws {Error} If the provided container is not a valid HTMLElement.
89537
+ */
89538
+ constructor(container, controlTabOrder = false) {
89539
+ if (!container || !(container instanceof HTMLElement)) {
89540
+ throw new Error("FocusTrap requires a valid HTMLElement.");
89541
+ }
89542
+
89543
+ this.container = container;
89544
+ this.tabDirection = "forward"; // or 'backward';
89545
+ this.controlTabOrder = controlTabOrder;
89546
+
89547
+ this._init();
89548
+ }
89549
+
89550
+ /**
89551
+ * Initializes the focus trap by setting up event listeners and attributes on the container.
89552
+ * Prepares the container for focus management, including support for shadow DOM and inert attributes.
89553
+ *
89554
+ * @private
89555
+ */
89556
+ _init() {
89557
+ // Add inert attribute to prevent focusing programmatically as well (if supported)
89558
+ if ("inert" in HTMLElement.prototype) {
89559
+ this.container.inert = false; // Ensure the container isn't inert
89560
+ this.container.setAttribute("data-focus-trap-container", true); // Mark for identification
89561
+ }
89562
+
89563
+ // Track tab direction
89564
+ this.container.addEventListener("keydown", this._onKeydown);
89565
+ }
89566
+
89567
+ /**
89568
+ * Gets an array of currently active (focused) elements in the document and shadow DOM.
89569
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
89570
+ * @private
89571
+ */
89572
+ _getActiveElements() {
89573
+ // Get the active element(s) in the document and shadow root
89574
+ // This will include the active element in the shadow DOM if it exists
89575
+ // Active element may be inside the shadow DOM depending on delegatesFocus, so we need to check both
89576
+ let { activeElement } = document;
89577
+ const actives = [activeElement];
89578
+ while (activeElement?.shadowRoot?.activeElement) {
89579
+ actives.push(activeElement.shadowRoot.activeElement);
89580
+ activeElement = activeElement.shadowRoot.activeElement;
89581
+ }
89582
+ return actives;
89583
+ }
89584
+
89585
+ /**
89586
+ * Gets the next focus index based on the current index and focusable elements.
89587
+ * @param {number} currentIndex The current index of the focused element.
89588
+ * @param {Array<HTMLElement>} focusables The array of focusable elements.
89589
+ * @returns {number|null} The next focus index or null if not determined.
89590
+ */
89591
+ _getNextFocusIndex(currentIndex, focusables, actives) {
89592
+ if (this.controlTabOrder) {
89593
+ // Calculate the new index based on the current index and tab direction
89594
+ let newFocusIndex =
89595
+ currentIndex + (this.tabDirection === "forward" ? 1 : -1);
89596
+
89597
+ // Wrap-around logic
89598
+ if (newFocusIndex < 0) newFocusIndex = focusables.length - 1;
89599
+ if (newFocusIndex >= focusables.length) newFocusIndex = 0;
89600
+
89601
+ // Early return with the new index
89602
+ return newFocusIndex;
89603
+ }
89604
+
89605
+ // Determine if we need to wrap
89606
+ const atFirst =
89607
+ actives.includes(focusables[0]) || actives.includes(this.container);
89608
+ const atLast = actives.includes(focusables[focusables.length - 1]);
89609
+
89610
+ // Only wrap if at the ends
89611
+ if (this.tabDirection === "backward" && atFirst) {
89612
+ return focusables.length - 1;
89613
+ }
89614
+
89615
+ if (this.tabDirection === "forward" && atLast) {
89616
+ return 0;
89617
+ }
89618
+
89619
+ // No wrap, so don't change focus, return early
89620
+ return null;
89621
+ }
89622
+
89623
+ /**
89624
+ * Handles the Tab key press event to manage focus within the container.
89625
+ * @param {KeyboardEvent} e The keyboard event triggered by the user.
89626
+ * @returns {void}
89627
+ */
89628
+ _handleTabKey(e) {
89629
+ // Update the focusable elements
89630
+ const focusables = this._getFocusableElements();
89631
+
89632
+ // If there are no focusable elements, exit
89633
+ if (!focusables.length) return;
89634
+
89635
+ // Set the tab direction based on the key pressed
89636
+ this.tabDirection = e.shiftKey ? "backward" : "forward";
89637
+
89638
+ // Get the active elements that are currently focused
89639
+ const actives = this._getActiveElements();
89640
+
89641
+ // If we're at either end of the focusable elements, wrap around to the other end
89642
+ let focusIndex = focusables.findIndex((el) => actives.includes(el));
89643
+
89644
+ // Fallback if we have no focused element
89645
+ if (focusIndex === -1) focusIndex = 0;
89646
+
89647
+ // Get the next focus index based on the current focus index, tab direction, and controlTabOrder setting
89648
+ // Is null if no new focus index is determined
89649
+ const newFocusIndex = this._getNextFocusIndex(
89650
+ focusIndex,
89651
+ focusables,
89652
+ actives,
89653
+ );
89654
+
89655
+ // If we have a new focus index, set focus to that element
89656
+ if (newFocusIndex !== null) {
89657
+ e.preventDefault();
89658
+ focusables[newFocusIndex].focus();
89659
+ }
89660
+ }
89661
+
89662
+ /**
89663
+ * Catches the keydown event
89664
+ * @param {KeyboardEvent} e The keyboard event triggered by user interaction.
89665
+ * @private
89666
+ */
89667
+ _onKeydown = (e) => {
89668
+ // Handle tab
89669
+ if (e.key === "Tab") this._handleTabKey(e);
89670
+ };
89671
+
89672
+ /**
89673
+ * Retrieves all focusable elements within the container in DOM order, including those in shadow DOM and slots.
89674
+ * Returns a unique, ordered array of elements that can receive focus.
89675
+ *
89676
+ * @returns {Array<HTMLElement>} An array of focusable elements within the container.
89677
+ * @private
89678
+ */
89679
+ _getFocusableElements() {
89680
+ // Use the imported utility function to get focusable elements
89681
+ const elements = getFocusableElements(this.container);
89682
+
89683
+ // Return the elements found
89684
+ return elements;
89685
+ }
89686
+
89687
+ /**
89688
+ * Moves focus to the first focusable element within the container.
89689
+ * Useful for setting initial focus when activating the focus trap.
89690
+ */
89691
+ focusFirstElement() {
89692
+ const focusables = this._getFocusableElements();
89693
+ if (focusables.length) focusables[0].focus();
89694
+ }
89695
+
89696
+ /**
89697
+ * Moves focus to the last focusable element within the container.
89698
+ * Useful for setting focus when deactivating or cycling focus in reverse.
89699
+ */
89700
+ focusLastElement() {
89701
+ const focusables = this._getFocusableElements();
89702
+ if (focusables.length) focusables[focusables.length - 1].focus();
89703
+ }
89704
+
89705
+ /**
89706
+ * Removes event listeners and attributes added by the focus trap.
89707
+ * Call this method to clean up when the focus trap is no longer needed.
89708
+ */
89709
+ disconnect() {
89710
+ if (this.container.hasAttribute("data-focus-trap-container")) {
89711
+ this.container.removeAttribute("data-focus-trap-container");
89712
+ }
89713
+
89714
+ this.container.removeEventListener("keydown", this._onKeydown);
89715
+ }
89716
+ }
89717
+
89070
89718
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
89071
89719
  // See LICENSE in the project root for license information.
89072
89720
 
@@ -89564,7 +90212,7 @@ class AuroDropdownBib extends i$2 {
89564
90212
  classes[`shape-${this.shape}`] = true;
89565
90213
 
89566
90214
  return u$d`
89567
- <dialog tabindex="-1" class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
90215
+ <dialog class="${e$2(classes)}" part="bibContainer" role="${o$4(this.dialogRole)}" aria-labelledby="${o$4(this.dialogLabel ? 'dialogLabel' : undefined)}">
89568
90216
  ${this.dialogLabel ? u$d`<span id="dialogLabel" class="util_displayHiddenVisually">${this.dialogLabel}</span>` : ''}
89569
90217
  <slot></slot>
89570
90218
  <span id="srAnnouncement" class="util_displayHiddenVisually" aria-live="polite" role="status"></span>
@@ -89815,7 +90463,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$2 {
89815
90463
  }
89816
90464
  };
89817
90465
 
89818
- var formkitVersion$1 = '202607100029';
90466
+ var formkitVersion$1 = '202607092329';
89819
90467
 
89820
90468
  class AuroElement extends i$2 {
89821
90469
  static get properties() {
@@ -90569,10 +91217,7 @@ class AuroDropdown extends AuroElement {
90569
91217
  }
90570
91218
 
90571
91219
 
90572
- // On Tab-driven close (eventType "focusloss"), let focus advance naturally
90573
- // — restoring to the trigger would trap the user on this dropdown, forcing
90574
- // an extra Tab to move on. Escape and outside-click still restore.
90575
- if (!this.isPopoverVisible && eventType !== "focusloss") {
91220
+ if (!this.isPopoverVisible) {
90576
91221
  // wait til the bib gets fully closed and rendered
90577
91222
  setTimeout(() => {
90578
91223
  // Skip if the bib re-opened, or if focus moved intentionally outside the dropdown (not to body).
@@ -90802,16 +91447,15 @@ class AuroDropdown extends AuroElement {
90802
91447
  }
90803
91448
  });
90804
91449
  } else {
90805
- // Normal desktop (non-modal): move initial focus into the bib but
90806
- // don't trap Tab. Tab should exit the bib and let the floater's
90807
- // handleFocusLoss close it, matching native <select>/<details>
90808
- // behavior. Deferred one frame because Floating UI positions the
90809
- // popover asynchronously a synchronous focus() would target
90810
- // zero-dimension elements and be silently ignored.
91450
+ // Normal desktop: use FocusTrap on the bib element.
91451
+ // Defer focusFirstElement to the next frame because the popover
91452
+ // is positioned asynchronously by Floating UI — calling focus()
91453
+ // synchronously here would target elements with zero dimensions
91454
+ // and the focus call would be silently ignored.
91455
+ this.focusTrap = new FocusTrap(this.bibContent);
90811
91456
  requestAnimationFrame(() => {
90812
- const focusables = getFocusableElements(this.bibContent);
90813
- if (focusables.length) {
90814
- focusables[0].focus();
91457
+ if (this.focusTrap) {
91458
+ this.focusTrap.focusFirstElement();
90815
91459
  }
90816
91460
  });
90817
91461
  }
@@ -91858,7 +92502,7 @@ class AuroHelpText extends i$2 {
91858
92502
  }
91859
92503
  }
91860
92504
 
91861
- var formkitVersion = '202607100029';
92505
+ var formkitVersion = '202607092329';
91862
92506
 
91863
92507
  var styleCss = i$4`.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}`;
91864
92508