@aurodesignsystem/auro-formkit 5.8.1 → 5.9.1

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 (61) hide show
  1. package/CHANGELOG.md +4 -15
  2. package/README.md +4 -4
  3. package/components/bibtemplate/dist/iconVersion.d.ts +1 -1
  4. package/components/bibtemplate/dist/index.js +2 -2
  5. package/components/bibtemplate/dist/registered.js +2 -2
  6. package/components/checkbox/demo/api.min.js +1 -1
  7. package/components/checkbox/demo/index.min.js +1 -1
  8. package/components/checkbox/dist/index.js +1 -1
  9. package/components/checkbox/dist/registered.js +1 -1
  10. package/components/combobox/demo/api.md +7 -6
  11. package/components/combobox/demo/api.min.js +1698 -1038
  12. package/components/combobox/demo/index.min.js +1698 -1038
  13. package/components/combobox/dist/auro-combobox.d.ts +10 -8
  14. package/components/combobox/dist/index.js +128 -149
  15. package/components/combobox/dist/registered.js +128 -149
  16. package/components/counter/demo/api.min.js +37 -61
  17. package/components/counter/demo/index.min.js +37 -61
  18. package/components/counter/dist/index.js +37 -61
  19. package/components/counter/dist/registered.js +37 -61
  20. package/components/datepicker/demo/api.min.js +55 -148
  21. package/components/datepicker/demo/index.min.js +55 -148
  22. package/components/datepicker/dist/auro-datepicker.d.ts +1 -1
  23. package/components/datepicker/dist/iconVersion.d.ts +1 -1
  24. package/components/datepicker/dist/index.js +55 -148
  25. package/components/datepicker/dist/popoverVersion.d.ts +1 -1
  26. package/components/datepicker/dist/registered.js +55 -148
  27. package/components/dropdown/demo/api.min.js +33 -57
  28. package/components/dropdown/demo/index.min.js +33 -57
  29. package/components/dropdown/dist/iconVersion.d.ts +1 -1
  30. package/components/dropdown/dist/index.js +33 -57
  31. package/components/dropdown/dist/registered.js +33 -57
  32. package/components/form/demo/working.html +1 -1
  33. package/components/input/demo/api.min.js +5 -4
  34. package/components/input/demo/index.min.js +5 -4
  35. package/components/input/dist/base-input.d.ts +1 -1
  36. package/components/input/dist/iconVersion.d.ts +1 -1
  37. package/components/input/dist/index.js +5 -4
  38. package/components/input/dist/registered.js +5 -4
  39. package/components/menu/demo/api.js +4 -0
  40. package/components/menu/demo/api.md +271 -31
  41. package/components/menu/demo/api.min.js +1609 -863
  42. package/components/menu/demo/index.html +1 -0
  43. package/components/menu/demo/index.js +2 -0
  44. package/components/menu/demo/index.md +95 -1
  45. package/components/menu/demo/index.min.js +1544 -812
  46. package/components/menu/dist/auro-menu.context.d.ts +227 -0
  47. package/components/menu/dist/auro-menu.d.ts +98 -53
  48. package/components/menu/dist/auro-menuoption.d.ts +116 -14
  49. package/components/menu/dist/index.js +1457 -796
  50. package/components/menu/dist/registered.js +1456 -807
  51. package/components/radio/demo/api.min.js +1 -1
  52. package/components/radio/demo/index.min.js +1 -1
  53. package/components/radio/dist/index.js +1 -1
  54. package/components/radio/dist/registered.js +1 -1
  55. package/components/select/demo/api.md +8 -7
  56. package/components/select/demo/api.min.js +1617 -1056
  57. package/components/select/demo/index.min.js +1617 -1056
  58. package/components/select/dist/auro-select.d.ts +11 -35
  59. package/components/select/dist/index.js +98 -218
  60. package/components/select/dist/registered.js +98 -218
  61. package/package.json +8 -2
@@ -1,6 +1,7 @@
1
1
  import { css, LitElement, html } from 'lit';
2
- import { classMap } from 'lit/directives/class-map.js';
2
+ import { ContextConsumer, createContext, ContextProvider } from '@lit/context';
3
3
  import { unsafeStatic, literal, html as html$1 } from 'lit/static-html.js';
4
+ import { classMap } from 'lit/directives/class-map.js';
4
5
  import { ifDefined } from 'lit/directives/if-defined.js';
5
6
 
6
7
  var styleCss$1 = css`:focus:not(:focus-visible){outline:3px solid transparent}.body-default{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);font-size:var(--wcss-body-default-font-size, 1rem);line-height:var(--wcss-body-default-line-height, 1.5rem)}.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);font-size:var(--wcss-body-lg-font-size, 1.125rem);line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-sm{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);font-size:var(--wcss-body-sm-font-size, 0.875rem);line-height:var(--wcss-body-sm-line-height, 1.25rem)}.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);font-size:var(--wcss-body-xs-font-size, 0.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-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-2xs-font-size, 0.625rem);line-height:var(--wcss-body-2xs-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);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);font-weight:var(--wcss-display-2xl-weight, 300);line-height:var(--wcss-display-2xl-line-height, 1.3);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem))}.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);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);font-weight:var(--wcss-display-xl-weight, 300);line-height:var(--wcss-display-xl-line-height, 1.3);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem))}.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);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);font-weight:var(--wcss-display-lg-weight, 300);line-height:var(--wcss-display-lg-line-height, 1.3);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem))}.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);letter-spacing:var(--wcss-display-md-letter-spacing, 0);font-weight:var(--wcss-display-md-weight, 300);line-height:var(--wcss-display-md-line-height, 1.3);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem))}.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);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);font-weight:var(--wcss-display-sm-weight, 300);line-height:var(--wcss-display-sm-line-height, 1.3);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem))}.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);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);font-weight:var(--wcss-display-xs-weight, 300);line-height:var(--wcss-display-xs-line-height, 1.3);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem))}.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);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);font-weight:var(--wcss-heading-xl-weight, 300);line-height:var(--wcss-heading-xl-line-height, 1.3);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem))}.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);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);font-weight:var(--wcss-heading-lg-weight, 300);line-height:var(--wcss-heading-lg-line-height, 1.3);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem))}.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);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);font-weight:var(--wcss-heading-md-weight, 300);line-height:var(--wcss-heading-md-line-height, 1.3);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem))}.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);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);font-weight:var(--wcss-heading-sm-weight, 300);line-height:var(--wcss-heading-sm-line-height, 1.3);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem))}.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);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);font-weight:var(--wcss-heading-xs-weight, 450);line-height:var(--wcss-heading-xs-line-height, 1.3);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem))}.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);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);font-weight:var(--wcss-heading-2xs-weight, 450);line-height:var(--wcss-heading-2xs-line-height, 1.3);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem))}.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);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-2xl-weight, 450);line-height:var(--wcss-accent-2xl-line-height, 1);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));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);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-xl-weight, 450);line-height:var(--wcss-accent-xl-line-height, 1.3);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);font-weight:var(--wcss-accent-lg-weight, 450);line-height:var(--wcss-accent-lg-line-height, 1.3);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));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);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);font-weight:var(--wcss-accent-md-weight, 500);line-height:var(--wcss-accent-md-line-height, 1.3);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);font-weight:var(--wcss-accent-sm-weight, 500);line-height:var(--wcss-accent-sm-line-height, 1.3);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));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);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-xs-weight, 500);line-height:var(--wcss-accent-xs-line-height, 1.3);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-2xs-weight, 450);line-height:var(--wcss-accent-2xs-line-height, 1.3);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));text-transform:uppercase}:host{display:block;vertical-align:middle;line-height:0}:host .menuWrapper{box-sizing:border-box;display:flex;flex-direction:column;width:100%;margin:0;padding:0}:host ::slotted(hr){box-sizing:content-box !important;height:0 !important;overflow:visible !important;margin:var(--ds-size-100, 0.5rem) 0 !important;border-width:0 !important;border-top-width:1px !important;border-top-style:solid !important}:host [loadingplaceholder].empty{opacity:0;position:absolute}:host [loadingplaceholder] slot[name=loadingIcon]{vertical-align:middle;display:inline-block;margin-bottom:var(--ds-size-25, 0.125rem)}:host [loadingplaceholder] slot[name=loadingIcon]::slotted(*){margin-right:var(--ds-size-150, 0.75rem)}:host([root]){overflow-y:auto}:host([root]) .menuWrapper.lg{padding:var(--ds-size-150, 0.75rem);gap:var(--ds-size-50, 0.25rem)}:host([root]) .menuWrapper.xl{padding:var(--ds-size-200, 1rem);gap:var(--ds-size-100, 0.5rem)}`;
@@ -113,6 +114,10 @@ class AuroElement extends LitElement {
113
114
  }
114
115
  }
115
116
 
117
+ var styleCss = css`.body-default{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);font-size:var(--wcss-body-default-font-size, 1rem);line-height:var(--wcss-body-default-line-height, 1.5rem)}.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);font-size:var(--wcss-body-lg-font-size, 1.125rem);line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-sm{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);font-size:var(--wcss-body-sm-font-size, 0.875rem);line-height:var(--wcss-body-sm-line-height, 1.25rem)}.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);font-size:var(--wcss-body-xs-font-size, 0.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-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-2xs-font-size, 0.625rem);line-height:var(--wcss-body-2xs-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);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);font-weight:var(--wcss-display-2xl-weight, 300);line-height:var(--wcss-display-2xl-line-height, 1.3);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem))}.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);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);font-weight:var(--wcss-display-xl-weight, 300);line-height:var(--wcss-display-xl-line-height, 1.3);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem))}.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);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);font-weight:var(--wcss-display-lg-weight, 300);line-height:var(--wcss-display-lg-line-height, 1.3);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem))}.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);letter-spacing:var(--wcss-display-md-letter-spacing, 0);font-weight:var(--wcss-display-md-weight, 300);line-height:var(--wcss-display-md-line-height, 1.3);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem))}.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);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);font-weight:var(--wcss-display-sm-weight, 300);line-height:var(--wcss-display-sm-line-height, 1.3);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem))}.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);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);font-weight:var(--wcss-display-xs-weight, 300);line-height:var(--wcss-display-xs-line-height, 1.3);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem))}.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);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);font-weight:var(--wcss-heading-xl-weight, 300);line-height:var(--wcss-heading-xl-line-height, 1.3);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem))}.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);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);font-weight:var(--wcss-heading-lg-weight, 300);line-height:var(--wcss-heading-lg-line-height, 1.3);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem))}.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);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);font-weight:var(--wcss-heading-md-weight, 300);line-height:var(--wcss-heading-md-line-height, 1.3);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem))}.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);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);font-weight:var(--wcss-heading-sm-weight, 300);line-height:var(--wcss-heading-sm-line-height, 1.3);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem))}.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);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);font-weight:var(--wcss-heading-xs-weight, 450);line-height:var(--wcss-heading-xs-line-height, 1.3);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem))}.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);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);font-weight:var(--wcss-heading-2xs-weight, 450);line-height:var(--wcss-heading-2xs-line-height, 1.3);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem))}.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);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-2xl-weight, 450);line-height:var(--wcss-accent-2xl-line-height, 1);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));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);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-xl-weight, 450);line-height:var(--wcss-accent-xl-line-height, 1.3);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);font-weight:var(--wcss-accent-lg-weight, 450);line-height:var(--wcss-accent-lg-line-height, 1.3);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));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);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);font-weight:var(--wcss-accent-md-weight, 500);line-height:var(--wcss-accent-md-line-height, 1.3);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);font-weight:var(--wcss-accent-sm-weight, 500);line-height:var(--wcss-accent-sm-line-height, 1.3);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));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);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-xs-weight, 500);line-height:var(--wcss-accent-xs-line-height, 1.3);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-2xs-weight, 450);line-height:var(--wcss-accent-2xs-line-height, 1.3);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));text-transform:uppercase}:host{cursor:pointer;user-select:none;text-overflow:ellipsis;max-width:100dvw}:host .wrapper{display:flex;align-items:center;padding-right:var(--ds-size-200, 1rem);padding-left:calc(var(--ds-size-150, 0.75rem) + var(--ds-size-300, 1.5rem) + var(--ds-size-100, 0.5rem));padding-top:var(--ds-size-50, 0.25rem);padding-bottom:var(--ds-size-50, 0.25rem);border-radius:var(--ds-size-100, 0.5rem);-webkit-tap-highlight-color:transparent}:host .wrapper[class*=shape-box]{border-radius:unset}:host .wrapper[class*=shape-snowflake]{border-radius:unset;line-height:24px}:host .wrapper[class*=shape-pill]{border-radius:30px}:host .wrapper[class*=-lg]{padding-top:var(--ds-size-75, 0.375rem);padding-bottom:var(--ds-size-75, 0.375rem);padding-right:var(--ds-size-150, 0.75rem);line-height:26px}:host .wrapper[class*=-xl]{padding-top:var(--ds-size-100, 0.5rem);padding-bottom:var(--ds-size-100, 0.5rem);padding-right:var(--ds-size-200, 1rem);line-height:26px}:host slot{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host [auro-icon]{--ds-auro-icon-size: var(--ds-size-300, 1.5rem);margin-right:var(--ds-size-150, 0.75rem);margin-left:var(--ds-size-100, 0.5rem)}:host ::slotted(.nestingSpacer){display:inline-block;width:var(--ds-size-300, 1.5rem)}[slot=displayValue]{display:none}:host([loadingplaceholder]) .wrapper{padding-left:calc(var(--ds-size-150, 0.75rem) + var(--ds-size-300, 1.5rem) + var(--ds-size-100, 0.5rem))}:host([selected]) .wrapper{padding-left:0}:host([nocheckmark]) .wrapper{padding-left:var(--ds-size-150, 0.75rem)}:host([nocheckmark]) .wrapper[class*=-lg]{padding-left:var(--ds-size-150, 0.75rem)}:host([nocheckmark]) .wrapper[class*=-xl]{padding-left:var(--ds-size-200, 1rem)}:host([hidden]){display:none}:host([static]){pointer-events:none}:host([disabled]:hover){cursor:auto}:host([disabled]){user-select:none;pointer-events:none}`;
118
+
119
+ var colorCss = css`:host .wrapper{background-color:var(--ds-auro-menuoption-container-color, transparent);box-shadow:inset 0 0 0 1px var(--ds-auro-menuoption-container-border-color, transparent);color:var(--ds-auro-menuoption-text-color)}:host svg{fill:var(--ds-auro-menuoption-icon-color)}:host([disabled]){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-menuoption-text-color: var(--ds-basic-color-texticon-disabled, #d0d0d0);--ds-auro-menuoption-icon-color: var(--ds-basic-color-texticon-disabled, #d0d0d0)}:host(:hover),:host(.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}:host(:focus){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host([selected]){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-subtle, #b4eff9);--ds-auro-menuoption-text-color: var(--ds-basic-color-texticon-default, #2a2a2a);--ds-auro-menuoption-icon-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([selected]:hover),:host([selected].active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}:host([selected]:focus){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-subtle, #b4eff9);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host(:focus:hover),:host(:focus.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host([selected]:focus:hover),:host([selected]:focus.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}`;
120
+
116
121
  // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
117
122
  // See LICENSE in the project root for license information.
118
123
 
@@ -196,6 +201,74 @@ class AuroLibraryRuntimeUtils {
196
201
  }
197
202
  }
198
203
 
204
+ // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
205
+ // See LICENSE in the project root for license information.
206
+
207
+
208
+ class AuroDependencyVersioning {
209
+
210
+ /**
211
+ * Generates a unique string to be used for child auro element naming.
212
+ * @private
213
+ * @param {string} baseName - Defines the first part of the unique element name.
214
+ * @param {string} version - Version of the component that will be appended to the baseName.
215
+ * @returns {string} - Unique string to be used for naming.
216
+ */
217
+ generateElementName(baseName, version) {
218
+ let result = baseName;
219
+
220
+ result += '-';
221
+ result += version.replace(/[.]/g, '_');
222
+
223
+ return result;
224
+ }
225
+
226
+ /**
227
+ * Generates a unique string to be used for child auro element naming.
228
+ * @param {string} baseName - Defines the first part of the unique element name.
229
+ * @param {string} version - Version of the component that will be appended to the baseName.
230
+ * @returns {string} - Unique string to be used for naming.
231
+ */
232
+ generateTag(baseName, version, tagClass) {
233
+ const elementName = this.generateElementName(baseName, version);
234
+ const tag = literal`${unsafeStatic(elementName)}`;
235
+
236
+ if (!customElements.get(elementName)) {
237
+ customElements.define(elementName, class extends tagClass {});
238
+ }
239
+
240
+ return tag;
241
+ }
242
+ }
243
+
244
+ class p{registerComponent(t,a){customElements.get(t)||customElements.define(t,class extends a{});}closestElement(t,a=this,e=(a,s=a&&a.closest(t))=>a&&a!==document&&a!==window?s||e(a.getRootNode().host):null){return e(a)}handleComponentTagRename(t,a){const e=a.toLowerCase();t.tagName.toLowerCase()!==e&&t.setAttribute(e,true);}elementMatch(t,a){const e=a.toLowerCase();return t.tagName.toLowerCase()===e||t.hasAttribute(e)}}var u='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-labelledby="error__desc" class="ico_squareLarge" data-deprecated="true" role="img" style="min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor" viewBox="0 0 24 24" part="svg"><title/><desc id="error__desc">Error alert indicator.</desc><path d="m13.047 5.599 6.786 11.586A1.207 1.207 0 0 1 18.786 19H5.214a1.207 1.207 0 0 1-1.047-1.815l6.786-11.586a1.214 1.214 0 0 1 2.094 0m-1.165.87a.23.23 0 0 0-.085.085L5.419 17.442a.232.232 0 0 0 .203.35h12.756a.234.234 0 0 0 .203-.35L12.203 6.554a.236.236 0 0 0-.321-.084M12 15.5a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5m-.024-6.22c.325 0 .589.261.589.583v4.434a.586.586 0 0 1-.589.583.586.586 0 0 1-.588-.583V9.863c0-.322.264-.583.588-.583"/></svg>';class m extends LitElement{static get properties(){return {hidden:{type:Boolean,reflect:true},hiddenVisually:{type:Boolean,reflect:true},hiddenAudible:{type:Boolean,reflect:true}}}hideAudible(t){return t?"true":"false"}}const g=new Map,f=(t,a={})=>{const e=a.responseParser||(t=>t.text());return g.has(t)||g.set(t,fetch(t).then(e)),g.get(t)};var w=css`:focus:not(:focus-visible){outline:3px solid transparent}.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock,:host{display:block}.util_displayFlex{display:flex}.util_displayHidden,:host([hidden]:not(:focus):not(:active)){display:none}.util_displayHiddenVisually,:host([hiddenVisually]:not(:focus):not(:active)){position:absolute;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;padding:0;border:0}.ico_squareLarge{fill:currentColor;height:var(--auro-size-lg, var(--ds-size-300, 1.5rem))}.ico_squareSmall{fill:currentColor;height:.6rem}.ico_squareMed{fill:currentColor;height:var(--auro-size-md, var(--ds-size-200, 1rem))}.ico_squareSml{fill:currentColor;height:var(--auro-size-sm, var(--ds-size-150, .75rem))}:host{color:currentColor;vertical-align:middle;display:inline-block}svg{min-width:var(--ds-auro-icon-size, 1.5rem)!important;width:var(--ds-auro-icon-size, 1.5rem)!important;height:var(--ds-auro-icon-size, 1.5rem)!important}.componentWrapper{display:flex;line-height:var(--ds-auro-icon-size)}.svgWrapper{height:var(--ds-auro-icon-size);width:var(--ds-auro-icon-size)}.svgWrapper [part=svg]{display:flex}.labelWrapper{margin-left:var(--ds-size-50, .25rem)}.labelWrapper ::slotted(*){line-height:inherit!important}
245
+ `;class z extends m{constructor(){super(),this.onDark=false,this.appearance="default";}static get properties(){return {...m.properties,onDark:{type:Boolean,reflect:true},appearance:{type:String,reflect:true},svg:{attribute:false,reflect:true}}}static get styles(){return w}async fetchIcon(t,a){let e="";e="logos"===t?await f(`${this.uri}/${t}/${a}.svg`):await f(`${this.uri}/icons/${t}/${a}.svg`);return (new DOMParser).parseFromString(e,"text/html").body.querySelector("svg")}async firstUpdated(){try{if(!this.customSvg){const t=await this.fetchIcon(this.category,this.name);if(t)this.svg=t;else if(!t){const t=(new DOMParser).parseFromString(u,"text/html");this.svg=t.body.firstChild;}}}catch(t){this.svg=void 0;}}}css`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock,:host{display:block}.util_displayFlex{display:flex}.util_displayHidden,:host([hidden]:not(:focus):not(:active)){display:none}.util_displayHiddenVisually,:host([hiddenVisually]:not(:focus):not(:active)){position:absolute;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;padding:0;border:0}:host{display:inline-block;--ds-auro-icon-size: 100%;width:100%;height:100%}:host .logo{color:var(--ds-auro-alaska-color)}:host([onDark]),:host([appearance=inverse]){--ds-auro-alaska-color: #FFF}
246
+ `;var y=css`:host{--ds-auro-icon-color: var(--ds-basic-color-texticon-default, #2a2a2a);--ds-auro-alaska-color: #02426D;--ds-auro-icon-size: var(--ds-size-300, 1.5rem)}
247
+ `;var k=css`:host{color:var(--ds-auro-icon-color)}:host([customColor]){color:inherit}:host(:not([onDark])[variant=accent1]),:host(:not([appearance=inverse])[variant=accent1]){--ds-auro-icon-color: var(--ds-basic-color-texticon-accent1, #265688)}:host(:not([onDark])[variant=disabled]),:host(:not([appearance=inverse])[variant=disabled]){--ds-auro-icon-color: var(--ds-basic-color-texticon-disabled, #d0d0d0)}:host(:not([onDark])[variant=muted]),:host(:not([appearance=inverse])[variant=muted]){--ds-auro-icon-color: var(--ds-basic-color-texticon-muted, #676767)}:host(:not([onDark])[variant=statusDefault]),:host(:not([appearance=inverse])[variant=statusDefault]){--ds-auro-icon-color: var(--ds-basic-color-status-default, #afb9c6)}:host(:not([onDark])[variant=statusInfo]),:host(:not([appearance=inverse])[variant=statusInfo]){--ds-auro-icon-color: var(--ds-basic-color-status-info, #01426a)}:host(:not([onDark])[variant=statusSuccess]),:host(:not([appearance=inverse])[variant=statusSuccess]){--ds-auro-icon-color: var(--ds-basic-color-status-success, #447a1f)}:host(:not([onDark])[variant=statusWarning]),:host(:not([appearance=inverse])[variant=statusWarning]){--ds-auro-icon-color: var(--ds-basic-color-status-warning, #fac200)}:host(:not([onDark])[variant=statusError]),:host(:not([appearance=inverse])[variant=statusError]){--ds-auro-icon-color: var(--ds-basic-color-status-error, #e31f26)}:host(:not([onDark])[variant=statusInfoSubtle]),:host(:not([appearance=inverse])[variant=statusInfoSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-info-subtle, #ebf3f9)}:host(:not([onDark])[variant=statusSuccessSubtle]),:host(:not([appearance=inverse])[variant=statusSuccessSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-success-subtle, #d6eac7)}:host(:not([onDark])[variant=statusWarningSubtle]),:host(:not([appearance=inverse])[variant=statusWarningSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-warning-subtle, #fff0b2)}:host(:not([onDark])[variant=statusErrorSubtle]),:host(:not([appearance=inverse])[variant=statusErrorSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-error-subtle, #fbc6c6)}:host(:not([onDark])[variant=fareBasicEconomy]),:host(:not([appearance=inverse])[variant=fareBasicEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-basiceconomy, #97eaf8)}:host(:not([onDark])[variant=fareBusiness]),:host(:not([appearance=inverse])[variant=fareBusiness]){--ds-auro-icon-color: var(--ds-basic-color-fare-business, #01426a)}:host(:not([onDark])[variant=fareEconomy]),:host(:not([appearance=inverse])[variant=fareEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-economy, #0074ca)}:host(:not([onDark])[variant=fareFirst]),:host(:not([appearance=inverse])[variant=fareFirst]){--ds-auro-icon-color: var(--ds-basic-color-fare-first, #00274a)}:host(:not([onDark])[variant=farePremiumEconomy]),:host(:not([appearance=inverse])[variant=farePremiumEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-premiumeconomy, #005154)}:host(:not([onDark])[variant=tierOneWorldEmerald]),:host(:not([appearance=inverse])[variant=tierOneWorldEmerald]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-emerald, #139142)}:host(:not([onDark])[variant=tierOneWorldSapphire]),:host(:not([appearance=inverse])[variant=tierOneWorldSapphire]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-sapphire, #015daa)}:host(:not([onDark])[variant=tierOneWorldRuby]),:host(:not([appearance=inverse])[variant=tierOneWorldRuby]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-ruby, #a41d4a)}:host([onDark]),:host([appearance=inverse]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse, #ffffff)}:host([onDark][variant=disabled]),:host([appearance=inverse][variant=disabled]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse-disabled, #7e8894)}:host([onDark][variant=muted]),:host([appearance=inverse][variant=muted]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse-muted, #ccd2db)}:host([onDark][variant=statusError]),:host([appearance=inverse][variant=statusError]){--ds-auro-icon-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8)}
248
+ `;class x extends z{constructor(){super(),this.variant=void 0,this.privateDefaults();}privateDefaults(){this.uri="https://cdn.jsdelivr.net/npm/@alaskaairux/icons@latest/dist",this.runtimeUtils=new p;}static get properties(){return {...z.properties,ariaHidden:{type:String,reflect:true},category:{type:String,reflect:true},customColor:{type:Boolean,reflect:true},customSvg:{type:Boolean},label:{type:Boolean,reflect:true},name:{type:String,reflect:true},variant:{type:String,reflect:true}}}static get styles(){return [z.styles,y,w,k]}static register(t="auro-icon"){p.prototype.registerComponent(t,x);}connectedCallback(){super.connectedCallback(),this.runtimeUtils.handleComponentTagRename(this,"auro-icon");}exposeCssParts(){this.setAttribute("exportparts","svg:iconSvg");}async firstUpdated(){if(await super.firstUpdated(),this.hasAttribute("ariaHidden")&&this.svg){const t=this.svg.querySelector("desc");t&&(t.remove(),this.svg.removeAttribute("aria-labelledby"));}}render(){const t={labelWrapper:true,util_displayHiddenVisually:!this.label};return html`
249
+ <div class="componentWrapper">
250
+ <div
251
+ class="${classMap({svgWrapper:true})}"
252
+ title="${ifDefined(this.title||void 0)}">
253
+ <span aria-hidden="${ifDefined(this.ariaHidden||true)}" part="svg">
254
+ ${this.customSvg?html`
255
+ <slot name="svg"></slot>
256
+ `:html`
257
+ ${this.svg}
258
+ `}
259
+ </span>
260
+ </div>
261
+
262
+ <div class="${classMap(t)}" part="label">
263
+ <slot></slot>
264
+ </div>
265
+ </div>
266
+ `}}
267
+
268
+ var iconVersion = '9.1.0';
269
+
270
+ var checkmarkIcon = {"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-labelledby=\"checkmark-sm__desc\" class=\"ico_squareLarge\" role=\"img\" style=\"min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor\" viewBox=\"0 0 24 24\" part=\"svg\"><title/><desc id=\"checkmark-sm__desc\">a small check mark.</desc><path d=\"M8.461 11.84a.625.625 0 1 0-.922.844l2.504 2.738c.247.27.674.27.922 0l5.496-6a.625.625 0 1 0-.922-.844l-5.035 5.496z\"/></svg>"};
271
+
199
272
  // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
200
273
  // See LICENSE in the project root for license information.
201
274
 
@@ -273,755 +346,1590 @@ function dispatchMenuEvent(element, eventName, detail = null) {
273
346
  element.dispatchEvent(new CustomEvent(eventName, eventConfig));
274
347
  }
275
348
 
276
- // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
349
+ // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
277
350
  // See LICENSE in the project root for license information.
278
351
 
279
352
 
280
-
281
- // See https://git.io/JJ6SJ for "How to document your components using JSDoc"
282
353
  /**
283
- * The auro-menu element provides users a way to select from a list of options.
284
- * @attr {HTMLElement|Array<HTMLElement>} optionSelected - An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
285
- * @attr {object} optionactive - Specifies the current active menuOption.
286
- * @attr {string} matchword - Specifies a string used to highlight matched string parts in options.
287
- * @attr {boolean} disabled - When true, the entire menu and all options are disabled;
288
- * @attr {boolean} nocheckmark - When true, selected option will not show the checkmark.
289
- * @attr {boolean} loading - When true, displays a loading state using the loadingIcon and loadingText slots if provided.
290
- * @attr {boolean} multiselect - When true, the selected option can be multiple options.
291
- * @prop {boolean} hasLoadingPlaceholder - Indicates whether the menu has a loadingIcon or loadingText to render when in a loading state.
292
- * @event {CustomEvent<Element>} auroMenu-activatedOption - Notifies that a menuoption has been made `active`.
293
- * @event {CustomEvent<any>} auroMenu-customEventFired - Notifies that a custom event has been fired.
294
- * @event {CustomEvent<{ loading: boolean; hasLoadingPlaceholder: boolean; }>} auroMenu-loadingChange - Notifies when the loading attribute is changed.
295
- * @event {CustomEvent<any>} auroMenu-selectValueFailure - Notifies that an attempt to select a menuoption by matching a value has failed.
296
- * @event {CustomEvent<any>} auroMenu-selectValueReset - Notifies that the component value has been reset.
297
- * @event {CustomEvent<any>} auroMenu-selectedOption - Notifies that a new menuoption selection has been made.
298
- * @slot loadingText - Text to show while loading attribute is set
299
- * @slot loadingIcon - Icon to show while loading attribute is set
300
- * @slot - Slot for insertion of menu options.
354
+ * The auro-menu element provides users a way to define a menu option.
355
+ *
356
+ * @attr {String} value - Specifies the value to be sent to a server.
357
+ * @attr {String} noCheckmark - When true, selected option will not show the checkmark.
358
+ * @attr {Boolean} disabled - When true specifies that the menuoption is disabled.
359
+ * @attr {Boolean} selected - Specifies that an option is selected.
360
+ * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
361
+ * @slot - Specifies text for an option, but is not the value.
301
362
  */
363
+ class AuroMenuOption extends AuroElement {
302
364
 
303
- /* eslint-disable no-magic-numbers, max-lines, no-extra-parens */
365
+ /**
366
+ * This will register this element with the browser.
367
+ * @param {string} [name="auro-menuoption"] - The name of element that you want to register to.
368
+ *
369
+ * @example
370
+ * AuroMenuOption.register("custom-menuoption") // this will register this element to <custom-menuoption/>
371
+ *
372
+ */
373
+ static register(name = "auro-menuoption") {
374
+ AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroMenuOption);
375
+ }
376
+
377
+ /**
378
+ * Returns whether the menu option is currently active and selectable.
379
+ * An option is considered active if it is not hidden, not disabled, and not static.
380
+ * @returns {boolean} True if the option is active, false otherwise.
381
+ */
382
+ get isActive() {
383
+ return !this.hasAttribute('hidden') &&
384
+ !this.disabled &&
385
+ !this.hasAttribute('static');
386
+ }
304
387
 
305
- class AuroMenu extends AuroElement {
306
388
  constructor() {
307
389
  super();
308
390
 
309
- // State properties (reactive)
310
-
311
- /**
312
- * @private
313
- */
314
- this.shape = "box";
391
+ this.bindEvents();
315
392
 
316
393
  /**
317
394
  * @private
318
395
  */
319
- this.size = "sm";
320
-
321
- // Value of the selected options
322
- this.value = undefined;
323
- // Currently selected option
324
- this.optionSelected = undefined;
325
- // String used for highlighting/filtering
326
- this.matchWord = undefined;
327
- // Hide the checkmark icon on selected options
328
- this.noCheckmark = false;
329
- // Currently active option
330
- this.optionActive = undefined;
331
- // Loading state
332
- this.loading = false;
333
- // Multi-select mode
334
- this.multiSelect = false;
335
-
336
- // Event Bindings
396
+ this.shape = undefined;
337
397
 
338
398
  /**
339
399
  * @private
340
400
  */
341
- this.handleKeyDown = this.handleKeyDown.bind(this);
401
+ this.size = undefined;
342
402
 
343
403
  /**
344
- * @private
404
+ * Generate unique names for dependency components.
345
405
  */
346
- this.handleMouseSelect = this.handleMouseSelect.bind(this);
406
+ const versioning = new AuroDependencyVersioning();
407
+ this.iconTag = versioning.generateTag('auro-formkit-menuoption-icon', iconVersion, x);
347
408
 
348
- /**
349
- * @private
350
- */
351
- this.handleOptionHover = this.handleOptionHover.bind(this);
409
+ this.selected = false;
410
+ this.noCheckmark = false;
411
+ this.disabled = false;
352
412
 
353
413
  /**
354
414
  * @private
355
415
  */
356
- this.handleSlotChange = this.handleSlotChange.bind(this);
416
+ this.runtimeUtils = new AuroLibraryRuntimeUtils();
357
417
 
358
- // Instance properties (non-reactive)
418
+ // Initialize context-related properties
419
+ this.menuService = null;
420
+ this.unsubscribe = null;
359
421
 
360
422
  /**
361
423
  * @private
362
424
  */
363
- Object.assign(this, {
364
- // Root-level menu (true) or a nested submenu (false)
365
- rootMenu: true,
366
- // Currently focused/active menu item index
367
- index: -1,
368
- // Nested menu spacer
369
- nestingSpacer: '<span class="nestingSpacer"></span>',
370
- // Loading indicator for slot elements
371
- loadingSlots: null,
372
- // Store for menu items
373
- items: [],
374
- });
425
+ this.handleMenuChange = this.handleMenuChange.bind(this);
375
426
  }
376
427
 
377
428
  static get properties() {
378
429
  return {
379
430
  ...super.properties,
380
- noCheckmark: {
381
- type: Boolean,
382
- reflect: true,
383
- attribute: 'nocheckmark'
384
- },
385
431
  disabled: {
386
432
  type: Boolean,
387
433
  reflect: true
388
434
  },
389
- loading: {
390
- type: Boolean,
435
+ event: {
436
+ type: String,
391
437
  reflect: true
392
438
  },
393
- optionSelected: {
394
- // Allow HTMLElement, HTMLElement[] arrays and undefined
395
- type: Object
439
+ key: {
440
+ type: String,
441
+ reflect: true
396
442
  },
397
- optionActive: {
443
+ menuService: {
398
444
  type: Object,
399
- attribute: 'optionactive'
445
+ state: true
400
446
  },
401
447
  matchWord: {
402
448
  type: String,
403
- attribute: 'matchword'
449
+ state: true
404
450
  },
405
- multiSelect: {
451
+ noCheckmark: {
406
452
  type: Boolean,
407
- reflect: true,
408
- attribute: 'multiselect'
453
+ reflect: true
454
+ },
455
+ selected: {
456
+ type: Boolean,
457
+ reflect: true
458
+ },
459
+ tabIndex: {
460
+ type: Number,
461
+ reflect: true
409
462
  },
410
-
411
- /**
412
- * Value selected for the component.
413
- */
414
463
  value: {
415
464
  type: String,
416
- reflect: true,
417
- attribute: 'value'
465
+ reflect: true
418
466
  },
419
-
420
- /**
421
- * Indent level for submenus.
422
- * @private
423
- */
424
- level: {
425
- type: Number,
426
- reflect: false,
427
- attribute: false
428
- }
429
467
  };
430
468
  }
431
469
 
432
470
  static get styles() {
433
471
  return [
434
- styleCss$1,
435
- colorCss$1,
472
+ styleCss,
473
+ colorCss,
436
474
  tokensCss
437
475
  ];
438
476
  }
439
477
 
440
- /**
441
- * This will register this element with the browser.
442
- * @param {string} [name="auro-menu"] - The name of element that you want to register to.
443
- *
444
- * @example
445
- * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
446
- *
447
- */
448
- static register(name = "auro-menu") {
449
- AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroMenu);
450
- }
451
-
452
- /**
453
- * Formatted value based on `multiSelect` state.
454
- * Default type is `String`, changing to `Array<String>` when `multiSelect` is true.
455
- * @private
456
- * @returns {String|Array<String>}
457
- */
458
- get formattedValue() {
459
- if (this.multiSelect) {
460
- if (!this.value) {
461
- return undefined;
462
- }
463
- if (this.value.startsWith("[")) {
464
- return JSON.parse(this.value);
465
- }
466
- return [this.value];
467
- }
468
- return this.value;
469
- }
470
-
471
- // Lifecycle Methods
472
-
473
478
  connectedCallback() {
474
479
  super.connectedCallback();
475
480
 
476
- this.addEventListener('keydown', this.handleKeyDown);
477
- this.addEventListener('mousedown', this.handleMouseSelect);
478
- this.addEventListener('auroMenuOption-mouseover', this.handleOptionHover);
479
- this.addEventListener('slotchange', this.handleSlotChange);
480
- this.setTagAttribute("auro-menu");
481
+ // Add the tag name as an attribute if it is different than the component name
482
+ // Add this step soon as this node gets attached to the DOM to avoid racing condition with menu's value setting logic.
483
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
484
+
485
+ // Set up context consumption in connectedCallback
486
+ this._contextConsumer = new ContextConsumer(this, {
487
+ context: MenuContext,
488
+ callback: this.attachTo.bind(this),
489
+ subscribe: true
490
+ });
491
+
492
+ // Establish the key property as early as possible
493
+ const valueAttr = this.getAttribute('value');
494
+ const keyAttr = this.getAttribute('key');
495
+ this.key = keyAttr !== null ? keyAttr : valueAttr;
481
496
  }
482
497
 
483
- disconnectedCallback() {
484
- this.removeEventListener('keydown', this.handleKeyDown);
485
- this.removeEventListener('mousedown', this.handleMouseSelect);
486
- this.removeEventListener('auroMenuOption-mouseover', this.handleOptionHover);
487
- this.removeEventListener('slotchange', this.handleSlotChange);
498
+ firstUpdated() {
499
+ // Add the tag name as an attribute if it is different than the component name
500
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
488
501
 
489
- super.disconnectedCallback();
502
+ this.setAttribute('role', 'option');
503
+ this.setAttribute('aria-selected', 'false');
504
+
505
+ this.addEventListener('mouseover', () => {
506
+ this.dispatchEvent(new CustomEvent('auroMenuOption-mouseover', {
507
+ bubbles: true,
508
+ cancelable: false,
509
+ composed: true,
510
+ detail: this
511
+ }));
512
+ });
490
513
  }
491
514
 
492
- firstUpdated() {
493
- AuroLibraryRuntimeUtils.prototype.handleComponentTagRename(this, 'auro-menu');
515
+ updated(changedProperties) {
516
+ super.updated(changedProperties);
494
517
 
495
- this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
496
- this.initializeMenu();
518
+ // Update aria-selected attribute if selected changed
519
+ if (changedProperties.has('selected')) {
520
+
521
+ // Update aria-selected attribute
522
+ this.setAttribute('aria-selected', this.selected.toString());
523
+
524
+ // Update menu service selection state if this isn't an internal update
525
+ if (this.internalUpdateInProgress !== true) {
526
+ this.menuService[this.selected ? 'selectOption' : 'deselectOption'](this);
527
+ }
528
+ }
529
+
530
+ if (changedProperties.has('active')) {
531
+ this.updateActiveClasses();
532
+ }
533
+
534
+ // Update text highlight if matchWord changed
535
+ if (changedProperties.has('matchWord')) {
536
+ this.updateTextHighlight();
537
+ }
538
+
539
+ // Set the key to be the passed value if no key is provided
540
+ if (changedProperties.has('value') && this.key === undefined) {
541
+ this.key = this.value;
542
+ }
543
+ }
544
+
545
+ disconnectedCallback() {
546
+ if (this.menuService) {
547
+ this.menuService.unsubscribe(this.handleMenuChange);
548
+ this.menuService.removeMenuOption(this);
549
+ }
497
550
  }
498
551
 
499
552
  /**
500
- * Sets an attribute that matches the default tag name if the tag name is not the default.
501
- * @param {string} tagName - The tag name to set as an attribute.
502
- * @private
553
+ * Sets up event listeners for user interaction with the menu option.
554
+ * This function enables click and mouse enter events to trigger selection and highlighting logic.
503
555
  */
504
- setTagAttribute(tagName) {
505
- if (this.tagName.toLowerCase() !== tagName) {
506
- this.setAttribute(tagName, true);
556
+ bindEvents() {
557
+ this.addEventListener('click', this.handleClick.bind(this));
558
+ this.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
559
+ }
560
+
561
+ /**
562
+ * Attaches this menu option to a menu service and subscribes to its events.
563
+ * This method enables the option to participate in menu selection and highlighting logic.
564
+ * @param {Object} service - The menu service instance to attach to.
565
+ */
566
+ attachTo(service) {
567
+ if (!service) {
568
+ return;
507
569
  }
570
+ this.menuService = service;
571
+ this.menuService.addMenuOption(this);
572
+ this.menuService.subscribe(this.handleMenuChange);
508
573
  }
509
574
 
510
- // eslint-disable-next-line complexity
511
- updated(changedProperties) {
512
- super.updated(changedProperties);
575
+ /**
576
+ * Handles changes from the menu service and updates the option's state.
577
+ * This function synchronizes the option's properties and selection/highlight state with menu events.
578
+ * @param {Object} event - The event object from the menu service.
579
+ */
580
+ handleMenuChange(event) {
513
581
 
514
- if (changedProperties.has('optionSelected')) {
515
- const old = changedProperties.get('optionSelected');
516
- if ((old && this.optionSelected && old.value !== this.optionSelected.value) ||
517
- (!old && this.optionSelected) ||
518
- (old && !this.optionSelected)) {
519
- this.notifySelectionChange();
520
- }
582
+ // Ignore events without a type or property
583
+ if (!event || (!event.type && !event.property)) {
584
+ return;
521
585
  }
522
586
 
523
- if (changedProperties.has('multiSelect') && !changedProperties.has("value")) {
524
- // Reset selection if multiSelect mode changes
525
- this.clearSelection();
587
+ // Update reactive properties based on event type
588
+ if (event.property && Object.keys(AuroMenuOption.properties).includes(event.property)) {
589
+ this[event.property] = event.value;
526
590
  }
527
591
 
592
+ // Handle highlight changes
593
+ if (event.type === 'highlightChange') {
594
+ const isActive = event.option === this;
595
+ this.active = isActive;
596
+ this.updateActiveClasses();
597
+ }
528
598
 
529
- if (changedProperties.has("value")) {
530
- // Handle null/undefined case
531
- if (this.value === undefined || this.value === null) {
532
- this.clearSelection();
533
- } else {
534
- if (this.multiSelect) {
535
- // In multiselect mode, this.value should be an array of strings
536
- const valueArray = this.formattedValue;
537
- const matchingOptions = this.items.filter((item) => valueArray.includes(item.value));
538
-
539
- this.optionSelected = matchingOptions.length > 0 ? matchingOptions : undefined;
540
- } else {
541
- // In single-select mode, this.value should be a string
542
- const matchingOptions = this.items.find((item) => item.value === this.value);
543
-
544
- if (matchingOptions) {
545
- this.optionSelected = matchingOptions;
546
- this.index = this.items.indexOf(matchingOptions);
547
- } else {
548
- // If no matching option found, reset selection
549
- this.optionSelected = undefined;
550
- this.index = -1;
551
- }
552
- }
599
+ if (event.type === 'stateChange') {
600
+ const isSelected = event.selectedOptions.includes(this);
601
+ this.setInternalSelected(isSelected);
602
+ }
603
+ }
553
604
 
554
- // If no matching options were found in either mode
555
- if (!this.optionSelected || (Array.isArray(this.optionSelected) && this.optionSelected.length === 0)) {
556
- dispatchMenuEvent(this, 'auroMenu-selectValueFailure');
557
- this.optionSelected = undefined;
558
- this.index = -1;
559
- }
560
- }
605
+ /**
606
+ * Updates the internal selected state of the menu option bypassing 'updated' and triggers custom events if selected.
607
+ * This function ensures the option's selection state is synchronized with menu logic and notifies listeners.
608
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
609
+ */
610
+ setInternalSelected(isSelected) {
611
+ this.internalUpdateInProgress = true;
612
+ this.selected = isSelected;
561
613
 
562
- // Update UI state
563
- this.updateItemsState(new Map([
564
- [
565
- 'optionSelected',
566
- true
567
- ]
568
- ]));
569
-
570
- // Notify of changes
571
- if (this.optionSelected !== undefined) {
572
- this.notifySelectionChange();
573
- }
614
+ // Fire custom event if selected
615
+ if (isSelected) {
616
+ this.handleCustomEvent();
574
617
  }
575
618
 
576
- // Process all other UI updates
577
- this.updateItemsState(changedProperties);
619
+ setTimeout(() => {
620
+ this.internalUpdateInProgress = false;
621
+ }, 0);
622
+ }
623
+
624
+ /**
625
+ * Sets the selected state of the menu option.
626
+ * This function updates whether the option is currently selected.
627
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
628
+ * @deprecated Simply modify the `selected` property directly instead.
629
+ */
630
+ setSelected(isSelected) {
631
+ this.selected = isSelected;
632
+ }
633
+
634
+ /**
635
+ * Updates the active state and visual highlighting of the menu option.
636
+ * This function toggles the option's active status and applies or removes the active CSS class.
637
+ * @param {boolean} isActive - Whether the option should be marked as active.
638
+ * @deprecated Simply modify the `active` property directly instead.
639
+ */
640
+ updateActive(isActive) {
641
+
642
+ // Set active state
643
+ this.active = isActive;
644
+ this.updateActiveClasses();
578
645
  }
579
646
 
580
647
  /**
581
- * Updates the UI state and appearance of menu items based on changed properties.
648
+ * Updates the CSS class for the menu option based on its active state.
649
+ * This function adds or removes the 'active' class to visually indicate the option's active status.
582
650
  * @private
583
- * @param {Map<string, boolean>} changedProperties - LitElement's changed properties map.
584
651
  */
585
- updateItemsState(changedProperties) {
586
- if (!this.items) {
587
- return;
588
- }
652
+ updateActiveClasses() {
653
+ // Update class based on active state
654
+ if (this.active) this.classList.add('active');
655
+ else this.classList.remove('active');
656
+ }
589
657
 
590
- // Handle noCheckmark propagation to all menus and options
591
- if (changedProperties.has('noCheckmark') && this.noCheckmark) {
592
- // Update both menus and options
593
- this.querySelectorAll('auro-menu, [auro-menu], auro-menuoption, [auro-menuoption]').forEach((element) => element.setAttribute('noCheckmark', ''));
594
- }
595
658
 
596
- // Handle layout propagation to all menus and options
597
- const propagationTargets = this.querySelectorAll('auro-menu, [auro-menu], auro-menuoption, [auro-menuoption]');
598
- [
599
- 'size',
600
- 'shape'
601
- ].forEach((prop) => {
602
- if (changedProperties.has(prop)) {
603
- propagationTargets.forEach((el) => {
604
- el.setAttribute(prop, this[prop]);
605
- });
606
- }
607
- });
659
+ /**
660
+ * Updates the visual highlighting of text within the menu option based on the current match word.
661
+ * This function highlights matching text segments and manages nested spacers for display formatting.
662
+ * @private
663
+ */
664
+ updateTextHighlight() {
608
665
 
609
666
  // Regex for matchWord if needed
610
667
  let regexWord = null;
611
668
 
612
- if (changedProperties.has('matchWord') && this.matchWord && this.matchWord.length) {
669
+ if (this.matchWord && this.matchWord.length) {
613
670
  const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
614
671
  regexWord = new RegExp(escapedWord, 'giu');
615
672
  }
616
673
 
617
- // Handle direct item updates
618
- this.items.forEach((option) => {
619
- // Update selection if option or value changed
620
- if (changedProperties.has('optionSelected') || changedProperties.has('value')) {
621
- const isSelected = this.isOptionSelected(option);
622
- option.setAttribute('aria-selected', isSelected ? 'true' : 'false');
623
-
624
- // Add/remove selected attribute based on state
625
- if (isSelected) {
626
- option.setAttribute('selected', '');
627
- } else {
628
- option.removeAttribute('selected');
629
- }
630
- }
631
-
632
- // Update text highlighting if matchWord changed
633
- if (changedProperties.has('matchWord') && regexWord &&
634
- isOptionInteractive(option) && !option.hasAttribute('persistent')) {
635
- const nested = option.querySelectorAll('.nestingSpacer');
636
-
637
- const displayValueEl = option.querySelector('[slot="displayValue"]');
638
- if (displayValueEl) {
639
- option.removeChild(displayValueEl);
640
- }
674
+ // Update text highlighting if matchWord changed
675
+ if (regexWord &&
676
+ this.isActive && !this.hasAttribute('persistent')) {
677
+ const nested = this.querySelectorAll('.nestingSpacer');
641
678
 
642
- // Create nested spacers
643
- const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
644
-
645
- // Update with spacers and matchWord
646
- option.innerHTML = nestingSpacerBundle +
647
- option.textContent.replace(
648
- regexWord,
649
- (match) => `<strong>${match}</strong>`
650
- );
651
- if (displayValueEl) {
652
- option.append(displayValueEl);
653
- }
679
+ const displayValueEl = this.querySelector('[slot="displayValue"]');
680
+ if (displayValueEl) {
681
+ this.removeChild(displayValueEl);
654
682
  }
655
683
 
656
- // Update disabled state
657
- if (changedProperties.has('disabled')) {
658
- option.disabled = this.disabled;
684
+ // Create nested spacers
685
+ const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
686
+
687
+ // Update with spacers and matchWord
688
+ this.innerHTML = nestingSpacerBundle +
689
+ this.textContent.replace(
690
+ regexWord,
691
+ (match) => `<strong>${match}</strong>`
692
+ );
693
+ if (displayValueEl) {
694
+ this.append(displayValueEl);
659
695
  }
660
- });
661
-
662
- // Handle loading state changes
663
- if (changedProperties.has('loading')) {
664
- this.setAttribute("aria-busy", this.loading);
665
- dispatchMenuEvent(this, "auroMenu-loadingChange", {
666
- loading: this.loading,
667
- hasLoadingPlaceholder: this.hasLoadingPlaceholder
668
- });
669
696
  }
670
697
  }
671
698
 
672
- // Init Methods
673
-
674
699
  /**
675
- * Initializes the menu's state and structure.
700
+ * Handles click events on the menu option, toggling its selected state.
701
+ * This function dispatches a click event and updates selection if the option is not disabled.
676
702
  * @private
677
703
  */
678
- initializeMenu() {
679
- this.initItems();
680
- if (this.rootMenu) {
681
- this.setAttribute('role', 'listbox');
682
- this.setAttribute('root', '');
683
- this.handleNestedMenus(this);
704
+ handleClick() {
705
+ if (!this.disabled) {
706
+ this.dispatchClickEvent();
707
+ this.selected = !this.selected;
684
708
  }
685
709
  }
686
710
 
687
711
  /**
688
- * Initializes menu items and their attributes.
712
+ * Handles mouse enter events to highlight the menu option.
713
+ * This function updates the menu service to set this option as the currently highlighted item if not disabled.
689
714
  * @private
690
715
  */
691
- initItems() {
692
- this.items = Array.from(this.querySelectorAll('auro-menuoption, [auro-menuoption]'));
693
- if (this.noCheckmark) {
694
- this.updateItemsState(new Map([
695
- [
696
- 'noCheckmark',
697
- true
698
- ]
699
- ]));
716
+ handleMouseEnter() {
717
+ if (!this.disabled) {
718
+ this.menuService.setHighlightedOption(this);
700
719
  }
701
720
  }
702
721
 
703
- // Logic Methods
704
-
705
722
  /**
706
- * Updates menu state when an option is selected.
723
+ * Dispatches custom events defined for this menu option.
724
+ * This function notifies listeners when a custom event is triggered by the option.
707
725
  * @private
708
- * @param {HTMLElement} option - The option element to select.
709
726
  */
710
- handleSelectState(option) {
711
- if (this.multiSelect) {
712
- const currentValue = this.formattedValue || [];
713
- const currentSelected = this.optionSelected || [];
714
-
715
- if (!currentValue.includes(option.value)) {
716
- this.value = JSON.stringify([
717
- ...currentValue,
718
- option.value
719
- ]);
720
- }
721
- if (!currentSelected.includes(option)) {
722
- this.optionSelected = [
723
- ...currentSelected,
724
- option
725
- ];
726
- }
727
- } else {
728
- // Single select - use arrays with single values
729
- this.value = option.value;
730
- this.optionSelected = option;
727
+ handleCustomEvent() {
728
+ if (this.event) {
729
+ dispatchMenuEvent(this, this.event, { option: this });
730
+ dispatchMenuEvent(this, 'auroMenu-customEventFired', { option: this });
731
731
  }
732
+ }
732
733
 
733
- this.index = this.items.indexOf(option);
734
+ /**
735
+ * Dispatches a click event for this menu option.
736
+ * This function notifies listeners that the option has been clicked.
737
+ * @private
738
+ */
739
+ dispatchClickEvent() {
740
+ this.dispatchEvent(new CustomEvent('auroMenuOption-click', {
741
+ bubbles: true,
742
+ cancelable: false,
743
+ composed: true,
744
+ detail: this
745
+ }));
734
746
  }
735
747
 
736
748
  /**
737
- * Deselects a menu option and updates related state.
749
+ * Generates an HTML element containing an SVG icon based on the provided `svgContent`.
750
+ *
738
751
  * @private
739
- * @param {HTMLElement} option - The menuoption to be deselected.
752
+ * @param {string} svgContent - The SVG content to be embedded.
753
+ * @returns {Element} The HTML element containing the SVG icon.
740
754
  */
741
- handleDeselectState(option) {
742
- if (this.multiSelect) {
743
- // Remove this option from array
744
- const newFormattedValue = (this.formattedValue || []).filter((val) => val !== option.value);
755
+ generateIconHtml(svgContent) {
756
+ const dom = new DOMParser().parseFromString(svgContent, 'text/html');
757
+ const svg = dom.body.firstChild;
745
758
 
746
- // If array is empty after removal, set back to undefined
747
- if (newFormattedValue && newFormattedValue.length === 0) {
748
- this.value = undefined;
749
- } else {
750
- this.value = JSON.stringify(newFormattedValue);
751
- }
759
+ svg.setAttribute('slot', 'svg');
752
760
 
753
- this.optionSelected = this.optionSelected.filter((val) => val !== option);
754
- if (this.optionSelected.length === 0) {
755
- this.optionSelected = undefined;
756
- }
757
- } else {
758
- // For single-select: Back to undefined when deselected
759
- this.value = undefined;
760
- this.optionSelected = undefined;
761
- }
761
+ return html$1`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
762
+ }
763
+
764
+ /**
765
+ * Logic to determine the layout of the component.
766
+ * @protected
767
+ * @returns {void}
768
+ */
769
+ renderLayout() {
762
770
 
763
- // Update the index tracking
764
- this.index = this.items.indexOf(option);
771
+ const fontClassMap = {
772
+ xs: 'body-sm',
773
+ sm: 'body-default',
774
+ md: 'body-default',
775
+ lg: 'body-lg',
776
+ xl: 'body-lg'
777
+ };
765
778
 
766
- // Update UI to reflect changes
767
- this.updateItemsState(new Map([
768
- [
769
- 'optionSelected',
770
- true
771
- ]
772
- ]));
779
+ const classes = classMap({
780
+ 'wrapper': true,
781
+ [this.size ? fontClassMap[this.size] : 'body-sm']: true,
782
+ });
773
783
 
774
- // Notify of selection change
775
- this.notifySelectionChange();
784
+ return html$1`
785
+ <div class="${classes}">
786
+ ${this.selected && !this.noCheckmark
787
+ ? this.generateIconHtml(checkmarkIcon.svg)
788
+ : undefined}
789
+ <slot></slot>
790
+ </div>
791
+ `;
776
792
  }
793
+ }
794
+
795
+ /* eslint-disable */
796
+
797
+ class MenuService {
777
798
 
778
799
  /**
779
- * Resets all options to their default state.
780
- * @private
800
+ * PROPERTIES AND GETTERS
781
801
  */
782
- clearSelection() {
783
- this.optionSelected = undefined;
784
- this.value = undefined;
785
- this.index = -1;
802
+
803
+ /**
804
+ * Gets the list of registered menu options.
805
+ * @returns {AuroMenuOption[]}
806
+ */
807
+ get menuOptions() {
808
+ return this._menuOptions;
786
809
  }
787
810
 
788
811
  /**
789
- * Resets the menu to its initial state.
790
- * This is the only way to return value to undefined.
791
- * @public
812
+ * Gets the currently highlighted option.
813
+ * @returns {AuroMenuOption|null}
792
814
  */
793
- reset() {
794
- // Reset to undefined - initial state
795
- this.value = undefined;
796
- this.optionSelected = undefined;
797
- this.index = -1;
815
+ get highlightedOption() {
816
+ return this._menuOptions[this.highlightedIndex] || null;
817
+ }
798
818
 
799
- // Reset UI state
800
- this.updateItemsState(new Map([
801
- [
802
- 'optionSelected',
803
- true
804
- ]
805
- ]));
819
+ /**
820
+ * Gets the current value(s) of the selected option(s).
821
+ * @returns {string|string[]|undefined}
822
+ */
823
+ get currentValue() {
824
+ const values = (this.selectedOptions || []).map(option => option.value);
825
+ return this.multiSelect ? values : values[0];
826
+ }
806
827
 
807
- // Dispatch reset event
808
- dispatchMenuEvent(this, 'auroMenu-selectValueReset');
828
+ /**
829
+ * Gets the label(s) of the currently selected option(s).
830
+ * @returns {string}
831
+ */
832
+ get currentLabel() {
833
+ const labels = (this.selectedOptions || []).map(option => option.textContent);
834
+ return this.multiSelect ? labels.join(", ") : labels[0] || '';
809
835
  }
810
836
 
811
837
  /**
812
- * Handles nested menu structure.
813
- * @private
814
- * @param {HTMLElement} menu - Root menu element.
838
+ * Gets the string representation of the current value(s).
839
+ * For multi-select, this is a JSON stringified array.
840
+ * @returns {string|undefined}
815
841
  */
816
- handleNestedMenus(menu) {
817
- menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
842
+ get stringValue() {
843
+ const { currentValue } = this;
818
844
 
819
- if (menu.level > 0) {
820
- menu.setAttribute('role', 'group');
821
- menu.removeAttribute("root");
822
- if (!menu.hasAttribute('aria-label')) {
823
- menu.setAttribute('aria-label', 'submenu');
845
+ if (Array.isArray(currentValue)) {
846
+ if (currentValue.length > 0) {
847
+ return JSON.stringify(currentValue);
824
848
  }
849
+ return undefined;
825
850
  }
826
851
 
827
- const options = menu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption]');
828
- options.forEach((option) => {
829
- const regex = new RegExp(this.nestingSpacer, "gu");
830
- option.innerHTML = this.nestingSpacer.repeat(menu.level) + option.innerHTML.replace(regex, '');
831
- });
832
- }
852
+ if (typeof currentValue === 'string') {
853
+ if (currentValue.length > 0) {
854
+ return currentValue;
855
+ }
856
+ return undefined;
857
+ }
833
858
 
834
- // Event Handlers
859
+ // Future: handle other types here (e.g., number, object, etc.)
860
+ return undefined;
861
+ }
835
862
 
836
863
  /**
837
- * Handles keyboard navigation.
838
- * @private
839
- * @param {KeyboardEvent} event - Event object from the browser.
864
+ * Gets the key(s) of the currently selected option(s).
865
+ * @returns {string|string[]|undefined}
840
866
  */
841
- handleKeyDown(event) {
842
- event.preventDefault();
843
- switch (event.key) {
844
- case "ArrowDown":
845
- this.navigateOptions('down');
846
- break;
847
- case "ArrowUp":
848
- this.navigateOptions('up');
849
- break;
850
- case "Tab":
851
- this.makeSelection();
852
- break;
853
- case "Enter":
854
- this.makeSelection();
855
- break;
856
- }
867
+ get currentKeys() {
868
+ const keys = (this.selectedOptions || []).map(option => option.key);
869
+ return this.multiSelect ? keys : keys[0];
857
870
  }
858
871
 
859
872
  /**
860
- * Makes a selection based on the current index or clicked option.
861
- * @private
873
+ * CONSTRUCTOR
862
874
  */
863
- makeSelection() {
864
- if (!this.items) {
865
- this.initItems();
866
- }
867
875
 
868
- // Get currently selected menu option based on index
869
- const option = this.items[this.index];
876
+ /**
877
+ * Creates a new MenuService instance.
878
+ * @param {Object} options - The options object.
879
+ * @param {AuroMenu} options.host - The host element that this service will control. Required.
880
+ * @throws {Error} If the host is not provided.
881
+ */
882
+ constructor({ host } = {}) {
870
883
 
871
- // Return early if option is not interactive
872
- if (!option || !isOptionInteractive(option)) {
873
- return;
884
+ // Ensure a host was passed
885
+ if (!host) {
886
+ throw new Error("MenuService requires a host element.");
874
887
  }
875
888
 
876
- // Handle custom events first
877
- if (option.hasAttribute('event')) {
878
- this.handleCustomEvent(option);
879
- return;
880
- }
889
+ // Attach the service to the host
890
+ this.host = host;
891
+ this.host.addController(this);
881
892
 
882
- if (this.multiSelect) {
883
- // In multiselect, toggle individual selections
884
- this.toggleOption(option);
885
- // In single select, only handle selection of new options
886
- } else if (this.option !== this.optionSelected || !this.isOptionSelected(option)) {
887
- this.clearSelection();
888
- this.handleSelectState(option);
889
- }
893
+ // Set default properties
894
+ this.size = undefined;
895
+ this.shape = undefined;
896
+ this.noCheckmark = undefined;
897
+ this.disabled = undefined;
898
+ this.matchWord = undefined;
899
+ this.multiSelect = undefined;
900
+ this.allowDeselect = undefined;
901
+ this.selectAllMatchingOptions = undefined;
890
902
 
891
- this.notifySelectionChange();
903
+ this.highlightedIndex = -1;
904
+
905
+ this._menuOptions = [];
906
+ this._subscribers = [];
907
+ this.internalUpdateInProgress = false;
908
+ this.selectedOptions = [];
892
909
  }
893
910
 
894
911
  /**
895
- * Toggle the selection state of the menuoption.
896
- * @private
897
- * @param {HTMLElement} option - The menuoption to toggle.
912
+ * PROPERTY SYNCING
898
913
  */
899
- toggleOption(option) {
900
- const isCurrentlySelected = this.isOptionSelected(option);
901
-
902
- if (isCurrentlySelected) {
903
- this.handleDeselectState(option);
904
- } else if (option.value === undefined || option.value === '') {
905
- dispatchMenuEvent(this, 'auroMenu-selectValueFailure');
906
- } else {
907
- this.handleSelectState(option);
908
- }
909
- }
910
914
 
911
915
  /**
912
- * Handles option selection via mouse.
913
- * @private
914
- * @param {MouseEvent} event - Event object from the browser.
916
+ * Handles host updates.
917
+ * This is a lit reactive lifecycle method.
918
+ * This comes from the Lit controller interface provided by adding this service as a controller to the host.
919
+ * See constructor for `this.host.addController(this)`
920
+ * You can read more about Lit reactive controllers here: https://lit.dev/docs/composition/controllers/
915
921
  */
916
- handleMouseSelect(event) {
917
- if (!this.rootMenu || event.target === this) {
918
- return;
919
- }
922
+ hostUpdated() {
920
923
 
921
- const option = event.target.closest('auro-menuoption, [auro-menuoption]');
922
- if (option) {
923
- this.index = this.items.indexOf(option);
924
- this.makeSelection();
924
+ // Reset selection if multiSelect mode changes
925
+ if (this.host.multiSelect !== this.multiSelect) {
926
+ this.selectedOptions = [];
925
927
  }
928
+
929
+ // Update properties on host update
930
+ this.setProperties({
931
+ size: this.host.size,
932
+ shape: this.host.shape,
933
+ noCheckmark: this.host.noCheckmark,
934
+ disabled: this.host.disabled,
935
+ matchWord: this.host.matchWord,
936
+ multiSelect: this.host.multiSelect,
937
+ allowDeselect: this.host.allowDeselect,
938
+ selectAllMatchingOptions: this.host.selectAllMatchingOptions
939
+ });
926
940
  }
927
941
 
928
942
  /**
929
- * Handles option hover events.
930
- * @private
931
- * @param {CustomEvent} event - Event object from the browser.
943
+ * Handles host disconnection and memory cleanup.
932
944
  */
933
- handleOptionHover(event) {
934
- const option = event.target;
935
- this.index = this.items.indexOf(option);
936
- this.updateActiveOption(this.index);
945
+ hostDisconnected() {
946
+ this._subscribers = [];
947
+ this._menuOptions = [];
937
948
  }
938
949
 
939
950
  /**
940
- * Handles slot change events.
941
- * @private
951
+ * Sets a property value if it exists on the instance and the value has changed.
952
+ * @param {string} property
953
+ * @param {any} value
942
954
  */
943
- handleSlotChange() {
944
- if (this.parentElement && this.parentElement.closest('auro-menu, [auro-menu]')) {
945
- this.rootMenu = false;
946
- }
955
+ setProperty(property, value) {
947
956
 
948
- if (this.rootMenu) {
949
- this.initializeMenu();
950
- } else if (this.noCheckmark) {
951
- this.updateItemsState(new Map([
952
- [
953
- 'noCheckmark',
954
- true
955
- ]
956
- ]));
957
+ // Only update if we are tracking the property in this service
958
+ if (this.hasOwnProperty(property)) {
959
+
960
+ // Check if the value has changed
961
+ const valueChanged = this[property] !== value;
962
+
963
+ // Update and notify if changed
964
+ if (valueChanged) {
965
+ this[property] = value;
966
+ this.notify({ property, value });
967
+ }
957
968
  }
958
969
  }
959
970
 
960
971
  /**
961
- * Navigates through options using keyboard.
962
- * @private
963
- * @param {string} direction - 'up' or 'down'.
972
+ * Sets multiple properties on the instance.
973
+ * @param {Object} properties - Key-value pairs of properties to set.
964
974
  */
965
- navigateOptions(direction) {
966
- // Return early if no items exist
967
- if (!this.items || !this.items.length) {
968
- return;
975
+ setProperties(properties) {
976
+ for (const [key, value] of Object.entries(properties)) {
977
+ this.setProperty(key, value);
969
978
  }
979
+ }
970
980
 
971
- let newIndex = this.index;
972
- const increment = direction === 'down' ? 1 : -1;
973
- const maxIterations = this.items.length;
974
- let iterations = 0;
975
- let foundInteractiveOption = false;
981
+ /**
982
+ * MENU OPTION HIGHLIGHTING
983
+ */
984
+
985
+ /**
986
+ * Highlights the next active option in the menu.
987
+ */
988
+ highlightNext() {
989
+ this.moveHighlightedOption("next");
990
+ }
991
+
992
+ /**
993
+ * Highlights the previous active option in the menu.
994
+ */
995
+ highlightPrevious() {
996
+ this.moveHighlightedOption("previous");
997
+ }
998
+
999
+ /**
1000
+ * Moves the highlighted option in the specified direction.
1001
+ * @param {string} direction - The direction to move the highlight ("next" or "previous").
1002
+ */
1003
+ moveHighlightedOption(direction) {
1004
+
1005
+ // Get the active options
1006
+ const activeOptions = this._menuOptions.filter(option => option.isActive);
1007
+
1008
+ // Get the currently active option
1009
+ const currentActiveOption = activeOptions[activeOptions.indexOf(this.highlightedOption)];
1010
+
1011
+ // Determine the new index based on the currently active option and direction
1012
+ let newIndex = currentActiveOption
1013
+ ? direction === "previous"
1014
+ ? activeOptions.indexOf(currentActiveOption) - 1
1015
+ : activeOptions.indexOf(currentActiveOption) + 1
1016
+ : direction === "previous"
1017
+ ? activeOptions.length - 1
1018
+ : 0;
1019
+
1020
+ // Wrap around the index if needed
1021
+ newIndex = newIndex < 0 ? activeOptions.length - 1 : newIndex >= activeOptions.length ? 0 : newIndex;
1022
+
1023
+ // Get the new active option and set it as highlighted
1024
+ const newActiveOption = activeOptions[newIndex];
1025
+ this.setHighlightedOption(newActiveOption);
1026
+ }
1027
+
1028
+ /**
1029
+ * Sets the highlighted index to the specified option.
1030
+ * @param {AuroMenuOption} option - The option to highlight.
1031
+ */
1032
+ setHighlightedOption(option) {
1033
+
1034
+ if (!option) return;
1035
+
1036
+ // Get the index of the option to highlight
1037
+ const index = this._menuOptions.indexOf(option);
1038
+
1039
+ // Update highlighted index
1040
+ this.highlightedIndex = index;
1041
+
1042
+ // Notify subscribers of highlight change
1043
+ this.notify({ type: 'highlightChange', option, index: this.highlightedIndex });
1044
+
1045
+ // Dispatch the change event
1046
+ this.dispatchChangeEvent('auroMenu-activatedOption', option);
1047
+ }
1048
+
1049
+ /**
1050
+ * Sets the highlighted option to the option at the specified index if it exists.
1051
+ * @param {number} index
1052
+ */
1053
+ setHighlightedIndex(index) {
1054
+ const option = this._menuOptions[index] || null;
1055
+ this.setHighlightedOption(option);
1056
+ }
1057
+
1058
+ /**
1059
+ * Selects the currently highlighted option.
1060
+ */
1061
+ selectHighlightedOption() {
1062
+ if (this.highlightedOption) {
1063
+ this.toggleOption(this.highlightedOption);
1064
+ }
1065
+ }
1066
+
1067
+ /**
1068
+ * SELECTION AND DESELECTION METHODS
1069
+ */
1070
+
1071
+ /**
1072
+ * Selects one or more options in a batch operation
1073
+ * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to select
1074
+ */
1075
+ selectOptions(options) {
1076
+ let optionsToSelect = Array.isArray(options) ? options : [options];
1077
+
1078
+ // Filter out options that are inactive
1079
+ optionsToSelect = optionsToSelect.filter(option => option.isActive);
1080
+
1081
+ if (!optionsToSelect.length) return;
1082
+
1083
+ if (this.multiSelect) {
1084
+ this.selectedOptions = [...(this.selectedOptions || []), ...optionsToSelect];
1085
+ } else {
1086
+ // In single select mode, only take the last option
1087
+ this.selectedOptions = [optionsToSelect[optionsToSelect.length - 1]];
1088
+ }
1089
+
1090
+ this.stageUpdate();
1091
+ }
1092
+
1093
+ /**
1094
+ * Deselects one or more options in a batch operation
1095
+ * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to deselect
1096
+ */
1097
+ deselectOptions(options) {
1098
+ const optionsToDeselect = Array.isArray(options) ? options : [options];
1099
+
1100
+ if (!optionsToDeselect.length) return;
1101
+
1102
+ // Check if deselection should be prevented
1103
+ const shouldPreventDeselect = !this.allowDeselect && !this.multiSelect;
1104
+ const isOnlySelectedOption = this.selectedOptions.length === 1 && optionsToDeselect.includes(this.selectedOptions[0]);
1105
+
1106
+ // Prevent deselecting the only selected option if not allowed
1107
+ if (shouldPreventDeselect && isOnlySelectedOption) return;
1108
+
1109
+ const optionsSet = new Set(optionsToDeselect);
1110
+ this.selectedOptions = (this.selectedOptions || [])
1111
+ .filter(opt => !optionsSet.has(opt));
1112
+
1113
+ this.stageUpdate();
1114
+ }
1115
+
1116
+ /**
1117
+ * Selects a single option.
1118
+ * @param {AuroMenuOption} option
1119
+ */
1120
+ selectOption(option) {
1121
+ this.selectOptions(option);
1122
+ }
1123
+
1124
+ /**
1125
+ * Deselects a single option.
1126
+ * @param {AuroMenuOption} option
1127
+ */
1128
+ deselectOption(option) {
1129
+ this.deselectOptions(option);
1130
+ }
1131
+
1132
+ /**
1133
+ * Toggles the selection state of a single option.
1134
+ * @param {AuroMenuOption} option
1135
+ */
1136
+ toggleOption(option) {
1137
+ if (option.selected) {
1138
+ this.deselectOption(option);
1139
+ } else {
1140
+ this.selectOption(option);
1141
+ }
1142
+ }
1143
+
1144
+ /**
1145
+ * Selects options based on their value(s) when compared to a passed value or values.
1146
+ * Value or values are normalized to an array of strings that can be matched to option keys.
1147
+ * @param {string|number|Array<string|number>} value - The value(s) to select.
1148
+ */
1149
+ selectByValue(value) {
1150
+ // Early exit for invalid/empty values or internal updates
1151
+ if (this.internalUpdateInProgress ||
1152
+ this.host.internalUpdateInProgress ||
1153
+ value === undefined ||
1154
+ value === null ||
1155
+ (Array.isArray(value) && value.length === 0) ||
1156
+ (typeof value === 'string' && value.trim() === '')) {
1157
+ return;
1158
+ }
1159
+
1160
+ this.reset();
1161
+
1162
+ // Normalize values to array of strings
1163
+ const normalizedValues = this._getNormalizedValues(value);
1164
+
1165
+ // Validate for single-select mode
1166
+ let validatedValues = normalizedValues;
1167
+ if (normalizedValues.length > 1 && !this.multiSelect) {
1168
+ console.warn("MenuService - Multiple values provided for single-select menu. Only the first value will be selected.");
1169
+ validatedValues = [normalizedValues[0]];
1170
+ }
1171
+
1172
+ // Find matching options by comparing available options to validated values
1173
+ const trackedKeys = new Set();
1174
+ const optionsToSelect = this._menuOptions.filter(option => {
1175
+ const passesFilter = validatedValues.includes(option.key);
1176
+ const alreadyTracked = trackedKeys.has(option.key);
1177
+
1178
+ trackedKeys.add(option.key);
1179
+
1180
+ // Include the option in the options to be selected if it passes the filter check and
1181
+ // either hasn't been tracked yet or selectAllMatchingOptions is true
1182
+ return passesFilter && (!alreadyTracked || (alreadyTracked && this.selectAllMatchingOptions));
1183
+ });
1184
+
1185
+ // Handle selection result
1186
+ if (optionsToSelect.length && !this.optionsArraysMatch(optionsToSelect, this.selectedOptions)) {
1187
+ this.selectOptions(optionsToSelect);
1188
+ } else {
1189
+ this.stageUpdate();
1190
+ }
1191
+
1192
+ // Dispatch failure event if no matches found
1193
+ if (!optionsToSelect.length && validatedValues.length) {
1194
+ this.dispatchChangeEvent('auroMenu-selectValueFailure', {
1195
+ message: 'No matching options found for the provided value(s).',
1196
+ values: validatedValues
1197
+ });
1198
+ }
1199
+ }
1200
+
1201
+ /**
1202
+ * Resets the selected options to an empty array.
1203
+ */
1204
+ reset() {
1205
+ const previousOptions = [...this.selectedOptions];
1206
+ this.selectedOptions = [];
1207
+
1208
+ // Single update after clearing all
1209
+ if (previousOptions.length) {
1210
+ this.stageUpdate();
1211
+ }
1212
+ }
1213
+
1214
+ /**
1215
+ * SUBSCRIPTION, NOTIFICATION AND EVENT DISPATCH METHODS
1216
+ */
1217
+
1218
+ /**
1219
+ * Subscribes a callback to menu service events.
1220
+ * @param {Function} callback - The callback to invoke on events.
1221
+ */
1222
+ subscribe(callback) {
1223
+ this._subscribers.push(callback);
1224
+ }
1225
+
1226
+ /**
1227
+ * Remove a previously subscribed callback from menu service events.
1228
+ * @param {Function} callback
1229
+ */
1230
+ unsubscribe(callback) {
1231
+ this._subscribers = this._subscribers.filter(cb => cb !== callback);
1232
+ }
1233
+
1234
+ /**
1235
+ * Stages an update to notify subscribers of state and value changes.
1236
+ */
1237
+ stageUpdate() {
1238
+ this.notifyStateChange();
1239
+ this.notifyValueChange();
1240
+ }
1241
+
1242
+ /**
1243
+ * Notifies subscribers of a menu service event.
1244
+ * All notifications are sent to all subscribers.
1245
+ * @param {string} event - The event to send to subscribers.
1246
+ */
1247
+ notify(event) {
1248
+ this._subscribers.forEach(callback => callback(event));
1249
+ }
1250
+
1251
+ /**
1252
+ * Notifies subscribers of a state change (selected options has changed).
1253
+ */
1254
+ notifyStateChange() {
1255
+ this.notify({ type: 'stateChange', selectedOptions: this.selectedOptions });
1256
+ }
1257
+
1258
+ /**
1259
+ * Notifies subscribers of a value change (current value has changed).
1260
+ */
1261
+ notifyValueChange() {
1262
+
1263
+ // Prepare details for the event
1264
+ const details = {
1265
+ value: this.currentValue,
1266
+ stringValue: this.stringValue,
1267
+ keys: this.currentKeys,
1268
+ options: this.selectedOptions,
1269
+ label: this.currentLabel
1270
+ };
1271
+
1272
+ // If only one option is selected, include its index
1273
+ if (this.selectedOptions.length === 1) details.index = this._menuOptions.indexOf(this.selectedOptions[0]);
1274
+
1275
+ this.notify({
1276
+ type: 'valueChange',
1277
+ ...details
1278
+ });
1279
+
1280
+ this.dispatchChangeEvent('auroMenu-selectedOption', details);
1281
+ }
1282
+
1283
+ /**
1284
+ * Dispatches a custom event from the host element.
1285
+ * @param {string} eventName
1286
+ * @param {any} detail
1287
+ */
1288
+ dispatchChangeEvent(eventName, detail) {
1289
+ this.host.dispatchEvent(new CustomEvent(eventName, {
1290
+ bubbles: true,
1291
+ cancelable: false,
1292
+ composed: true,
1293
+ detail
1294
+ }));
1295
+ }
1296
+
1297
+ /**
1298
+ * MENU OPTION MANAGEMENT METHODS
1299
+ */
1300
+
1301
+ /**
1302
+ * Adds a menu option to the service's list.
1303
+ * @param {AuroMenuOption} option - the option to track
1304
+ */
1305
+ addMenuOption(option) {
1306
+ this._menuOptions.push(option);
1307
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
1308
+ }
1309
+
1310
+ /**
1311
+ * Removes a menu option from the service's list.
1312
+ * @param {AuroMenuOption} option - the option to remove
1313
+ */
1314
+ removeMenuOption(option) {
1315
+ this._menuOptions = this._menuOptions.filter(opt => opt !== option);
1316
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
1317
+ }
1318
+
1319
+ /**
1320
+ * UTILITIES
1321
+ */
1322
+
1323
+ /**
1324
+ * Normalizes a value or array of values into an array of strings for option selection.
1325
+ * This function ensures that input values are consistently formatted for matching menu options.
1326
+ *
1327
+ * @param {string|number|Array<string|number>} value - The value(s) to normalize.
1328
+ * @returns {Array<string>} An array of string values suitable for option matching.
1329
+ * @throws {Error} If any value is not a string or number.
1330
+ */
1331
+ _getNormalizedValues(value) {
1332
+ let values = value;
1333
+
1334
+ // Handle JSON string and single value string input
1335
+ if (!Array.isArray(values) && typeof values === 'string') {
1336
+
1337
+ // Attempt to parse as JSON array
1338
+ try {
1339
+
1340
+ // Normalize single quotes to double quotes for JSON parsing
1341
+ // This will not handle complex cases but will cover basic usage
1342
+ const parseValue = values.replace(/'([^']*?)'/g, '"$1"');
1343
+
1344
+ // Attempt parse
1345
+ const parsed = JSON.parse(parseValue);
1346
+
1347
+ // Ensure parsed value is an array
1348
+ if (!Array.isArray(parsed)) throw new Error('Not an array');
1349
+
1350
+ // Set values to parsed array
1351
+ values = parsed;
1352
+ } catch (err) {
1353
+
1354
+ // If parsing fails, treat as single value
1355
+ values = [value];
1356
+ }
1357
+ }
1358
+
1359
+ // Handle a single number being passed
1360
+ if (typeof values === 'number') {
1361
+ values = [String(values)];
1362
+ }
1363
+
1364
+ // Coerce each value to string and validate types
1365
+ values.forEach((val, index) => {
1366
+
1367
+ // Throw an error for invalid value types
1368
+ if (typeof val !== 'string' && typeof val !== 'number') {
1369
+ throw new Error('Value contains invalid value type. Supported types are string and number.');
1370
+ }
1371
+
1372
+ // Convert numbers to strings for consistency
1373
+ if (typeof val === 'number') {
1374
+ values[index] = String(val);
1375
+ }
1376
+ });
1377
+
1378
+ // Return the resulting array of string values
1379
+ return values;
1380
+ }
1381
+
1382
+ /**
1383
+ * Returns whether two arrays of options contain the same elements.
1384
+ * @param {AuroMenuOption[]} arr1 - First array of options.
1385
+ * @param {AuroMenuOption[]} arr2 - Second array of options.
1386
+ * @returns {boolean} True if arrays match, false otherwise.
1387
+ */
1388
+ optionsArraysMatch(arr1, arr2) {
1389
+ if (arr1.length !== arr2.length) return false;
1390
+
1391
+ const set1 = new Set(arr1);
1392
+ const set2 = new Set(arr2);
1393
+
1394
+ for (let item of set1) {
1395
+ if (!set2.has(item)) {
1396
+ return false;
1397
+ }
1398
+ }
1399
+
1400
+ return true;
1401
+ }
1402
+ }
1403
+
1404
+ const MenuContext = createContext('menu-context');
1405
+
1406
+ /* eslint-disable no-underscore-dangle, curly */
1407
+ // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1408
+ // See LICENSE in the project root for license information.
1409
+
1410
+
1411
+
1412
+ /**
1413
+ * The auro-menu element provides users a way to select from a list of options.
1414
+ * @attr {HTMLElement|Array<HTMLElement>} optionSelected - An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
1415
+ * @attr {object} optionactive - Specifies the current active menuOption.
1416
+ * @attr {string} matchword - Specifies a string used to highlight matched string parts in options.
1417
+ * @attr {boolean} disabled - When true, the entire menu and all options are disabled;
1418
+ * @attr {boolean} nocheckmark - When true, selected option will not show the checkmark.
1419
+ * @attr {boolean} loading - When true, displays a loading state using the loadingIcon and loadingText slots if provided.
1420
+ * @attr {boolean} multiselect - When true, the selected option can be multiple options.
1421
+ * @attr {boolean} selectAllMatchingOptions - When true, selects all options that match the provided value/key when setting value and multiselect is enabled.
1422
+ * @attr {string} value - The value of the selected option. In multi-select mode, this is a JSON stringified array of selected option values.
1423
+ * @prop {string} size - Sets the size of the menu. Accepted values are 'sm' and 'md'. Default is 'sm'.
1424
+ * @prop {string} shape - Sets the shape of the menu options. Accepted values are 'box' and 'round'. Default is 'box'.
1425
+ * @prop {boolean} hasLoadingPlaceholder - Indicates whether the menu has a loadingIcon or loadingText to render when in a loading state.
1426
+ * @event {CustomEvent<Element>} auroMenu-activatedOption - Notifies that a menuoption has been made `active`.
1427
+ * @event {CustomEvent<any>} auroMenu-customEventFired - Notifies that a custom event has been fired.
1428
+ * @event {CustomEvent<{ loading: boolean; hasLoadingPlaceholder: boolean; }>} auroMenu-loadingChange - Notifies when the loading attribute is changed.
1429
+ * @event {CustomEvent<any>} auroMenu-selectValueFailure - Notifies that an attempt to select a menuoption by matching a value has failed.
1430
+ * @event {CustomEvent<any>} auroMenu-selectValueReset - Notifies that the component value has been reset.
1431
+ * @event {CustomEvent<any>} auroMenu-selectedOption - Notifies that a new menuoption selection has been made.
1432
+ * @slot loadingText - Text to show while loading attribute is set
1433
+ * @slot loadingIcon - Icon to show while loading attribute is set
1434
+ * @slot - Slot for insertion of menu options.
1435
+ */
1436
+
1437
+ /* eslint-disable no-magic-numbers, max-lines, no-extra-parens */
1438
+
1439
+ class AuroMenu extends AuroElement {
1440
+
1441
+ constructor() {
1442
+ super();
1443
+
1444
+ // State properties (reactive)
1445
+
1446
+ /**
1447
+ * @private
1448
+ */
1449
+ this.shape = "box";
1450
+
1451
+ /**
1452
+ * @private
1453
+ */
1454
+ this.size = "sm";
1455
+
1456
+ // Value of the selected options
1457
+ this.value = undefined;
1458
+ // Currently selected option
1459
+ this.optionSelected = undefined;
1460
+ // String used for highlighting/filtering
1461
+ this.matchWord = undefined;
1462
+ // Hide the checkmark icon on selected options
1463
+ this.noCheckmark = false;
1464
+ // Currently active option
1465
+ this.optionActive = undefined;
1466
+ // Loading state
1467
+ this.loading = false;
1468
+ // Multi-select mode
1469
+ this.multiSelect = false;
1470
+ // Allow deselecting of menu options
1471
+ this.allowDeselect = false;
1472
+ // Select all matching options when setting value in multi-select mode
1473
+ this.selectAllMatchingOptions = false;
1474
+
1475
+ // Event Bindings
1476
+
1477
+ /**
1478
+ * @private
1479
+ */
1480
+ this.handleKeyDown = this.handleKeyDown.bind(this);
1481
+
1482
+
1483
+ /**
1484
+ * @private
1485
+ */
1486
+ this.handleSlotChange = this.handleSlotChange.bind(this);
1487
+
1488
+ // Instance properties (non-reactive)
1489
+
1490
+ /**
1491
+ * @private
1492
+ */
1493
+ Object.assign(this, {
1494
+ // Root-level menu (true) or a nested submenu (false)
1495
+ rootMenu: true,
1496
+ // Currently focused/active menu item index
1497
+ _index: -1,
1498
+ // Nested menu spacer
1499
+ nestingSpacer: '<span class="nestingSpacer"></span>',
1500
+ // Loading indicator for slot elements
1501
+ loadingSlots: null,
1502
+ });
1503
+ }
1504
+
1505
+ static get properties() {
1506
+ return {
1507
+ ...super.properties,
1508
+
1509
+ /**
1510
+ * Allows deselecting an already selected option when clicked again in single-select mode.
1511
+ */
1512
+ allowDeselect: {
1513
+ type: Boolean,
1514
+ reflect: true,
1515
+ },
1516
+ noCheckmark: {
1517
+ type: Boolean,
1518
+ reflect: true,
1519
+ attribute: 'nocheckmark'
1520
+ },
1521
+ disabled: {
1522
+ type: Boolean,
1523
+ reflect: true
1524
+ },
1525
+ loading: {
1526
+ type: Boolean,
1527
+ reflect: true
1528
+ },
1529
+ optionSelected: {
1530
+ // Allow HTMLElement, HTMLElement[] arrays and undefined
1531
+ type: Object
1532
+ },
1533
+ optionActive: {
1534
+ type: Object,
1535
+ attribute: 'optionactive'
1536
+ },
1537
+ matchWord: {
1538
+ type: String,
1539
+ attribute: 'matchword'
1540
+ },
1541
+ multiSelect: {
1542
+ type: Boolean,
1543
+ reflect: true,
1544
+ attribute: 'multiselect'
1545
+ },
1546
+ selectAllMatchingOptions: {
1547
+ type: Boolean,
1548
+ reflect: true,
1549
+ },
976
1550
 
977
- do {
978
- newIndex = (newIndex + increment + this.items.length) % this.items.length;
979
- iterations += 1;
1551
+ /**
1552
+ * Value selected for the component.
1553
+ */
1554
+ value: {
1555
+ type: String,
1556
+ reflect: true,
1557
+ attribute: 'value'
1558
+ },
980
1559
 
981
- // Check if current option is interactive
982
- const currentOption = this.items[newIndex];
983
- if (isOptionInteractive(currentOption)) {
984
- foundInteractiveOption = true;
985
- break;
986
- }
1560
+ /**
1561
+ * Indent level for submenus.
1562
+ * @private
1563
+ */
1564
+ level: {
1565
+ type: Number,
1566
+ reflect: false,
1567
+ attribute: false
1568
+ },
987
1569
 
988
- // Break if all options were checked
989
- if (iterations >= maxIterations) {
990
- break;
1570
+ /**
1571
+ * Available menu options
1572
+ * @readonly
1573
+ */
1574
+ options: {
1575
+ type: Array,
1576
+ reflect: false,
1577
+ attribute: false
991
1578
  }
992
- } while (iterations < maxIterations);
1579
+ };
1580
+ }
993
1581
 
994
- // Handle the results of the search
995
- if (foundInteractiveOption) {
996
- // Update only if an interactive option was found
997
- this.index = newIndex;
998
- this.updateActiveOption(this.index);
999
- } else {
1000
- // All options are disabled or non-interactive
1001
- // Keep the current index unchanged
1002
- dispatchMenuEvent(this, 'auroMenu-navigateFailure', {
1003
- reason: 'No interactive options available',
1004
- direction,
1005
- currentIndex: this.index
1582
+ static get styles() {
1583
+ return [
1584
+ styleCss$1,
1585
+ colorCss$1,
1586
+ tokensCss
1587
+ ];
1588
+ }
1589
+
1590
+ /**
1591
+ * @readonly
1592
+ * @returns {string} - Returns the label of the currently selected option(s).
1593
+ */
1594
+ get currentLabel() {
1595
+ return this.menuService.currentLabel;
1596
+ };
1597
+
1598
+ /**
1599
+ * @readonly
1600
+ * @returns {Array<HTMLElement>} - Returns the array of available menu options.
1601
+ * @deprecated use `options` property instead.
1602
+ */
1603
+ get items() {
1604
+ return this.options;
1605
+ }
1606
+
1607
+ /**
1608
+ * @returns {number} - Returns the index of the currently active option.
1609
+ */
1610
+ get index() {
1611
+ return this._index;
1612
+ }
1613
+
1614
+ /**
1615
+ * @param {number} value - Sets the index of the currently active option.
1616
+ */
1617
+ set index(value) {
1618
+ this.menuService.setHighlightedIndex(value);
1619
+ }
1620
+
1621
+ /**
1622
+ * This will register this element with the browser.
1623
+ * @param {string} [name="auro-menu"] - The name of element that you want to register to.
1624
+ *
1625
+ * @example
1626
+ * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
1627
+ *
1628
+ */
1629
+ static register(name = "auro-menu") {
1630
+ AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroMenu);
1631
+ }
1632
+
1633
+ /**
1634
+ * Formatted value based on `multiSelect` state.
1635
+ * Default type is `String`, changing to `Array<String>` when `multiSelect` is true.
1636
+ * @private
1637
+ * @returns {String|Array<String>}
1638
+ */
1639
+ get formattedValue() {
1640
+ return this.menuService.currentValue;
1641
+ }
1642
+
1643
+ /**
1644
+ * Gets the current property values for the menu service.
1645
+ * @private
1646
+ * @returns {Object}
1647
+ */
1648
+ get propertyValues() {
1649
+ return {
1650
+ size: this.size,
1651
+ shape: this.shape,
1652
+ noCheckmark: this.nocheckmark,
1653
+ disabled: this.disabled
1654
+ };
1655
+ }
1656
+
1657
+ /**
1658
+ * Provides the menu context to child components.
1659
+ * Initializes the MenuService and subscribes to menu changes.
1660
+ * @protected
1661
+ */
1662
+ provideContext() {
1663
+ this.menuService = new MenuService({host: this});
1664
+ this.menuService.setProperties(this.propertyValues);
1665
+ this.menuService.subscribe(this.handleMenuChange.bind(this));
1666
+ this._contextProvider = new ContextProvider(this, {
1667
+ context: MenuContext,
1668
+ initialValue: this.menuService
1669
+ });
1670
+ }
1671
+
1672
+ /**
1673
+ * Updates the currently active option in the menu.
1674
+ * @param {HTMLElement} option - The option to set as active.
1675
+ */
1676
+ updateActiveOption(option) {
1677
+ this.menuService.setHighlightedOption(option);
1678
+ }
1679
+
1680
+ /**
1681
+ * Sets the internal value and manages update state.
1682
+ * @param {String|Array<String>} value - The value to set.
1683
+ * @protected
1684
+ */
1685
+ setInternalValue(value) {
1686
+ if (this.value !== value) {
1687
+ this.internalUpdateInProgress = true;
1688
+ this.value = value;
1689
+
1690
+ setTimeout(() => {
1691
+ this.internalUpdateInProgress = false;
1006
1692
  });
1007
1693
  }
1008
1694
  }
1009
1695
 
1010
1696
  /**
1011
- * Updates the active option state and dispatches events.
1012
- * @param {number} index - Index of the option to make active.
1697
+ * Handles changes from the menu service and updates component state.
1698
+ * @param {Object} event - The event object from the menu service.
1699
+ * @protected
1700
+ */
1701
+ handleMenuChange(event) {
1702
+ if (event.type === 'valueChange') {
1703
+
1704
+ // New option is array value or first option with fallback to undefined for empty array in all cases
1705
+ const newOption = this.multiSelect && event.options.length ? event.options : event.options[0] || undefined;
1706
+ const newValue = event.stringValue;
1707
+
1708
+ // Check if the option or value has actually changed
1709
+ if (newValue === undefined || (this.optionSelected !== newOption || this.stringValue !== newValue)) {
1710
+ this.optionSelected = newOption;
1711
+ this.setInternalValue(newValue);
1712
+ }
1713
+
1714
+ // Notify components of selection change
1715
+ this.notifySelectionChange(event);
1716
+ }
1717
+
1718
+ if (event.type === 'highlightChange') {
1719
+ this.optionActive = event.option;
1720
+ this._index = event.index;
1721
+ }
1722
+
1723
+ if (event.type === 'optionsChange') {
1724
+ this.options = event.options;
1725
+ this.dispatchEvent(new CustomEvent('auroMenu-optionsChange', {
1726
+ detail: {
1727
+ options: event.options
1728
+ }
1729
+ }));
1730
+ }
1731
+ }
1732
+
1733
+ /**
1734
+ * Gets the currently selected options.
1735
+ * @returns {Array<HTMLElement>}
1736
+ */
1737
+ get selectedOptions() {
1738
+ return this.menuService ? this.menuService.selectedOptions : [];
1739
+ }
1740
+
1741
+ /**
1742
+ * Gets the first selected option, or null if none.
1743
+ * @returns {HTMLElement|null}
1744
+ */
1745
+ get selectedOption() {
1746
+ return this.menuService ? this.menuService.selectedOptions[0] : null;
1747
+ }
1748
+
1749
+ // Lifecycle Methods
1750
+
1751
+ connectedCallback() {
1752
+ super.connectedCallback();
1753
+
1754
+ this.provideContext();
1755
+
1756
+ this.addEventListener('keydown', this.handleKeyDown);
1757
+ this.addEventListener('auroMenuOption-click', this.handleMouseSelect);
1758
+ this.addEventListener('auroMenuOption-mouseover', this.handleOptionHover);
1759
+ this.addEventListener('slotchange', this.handleSlotChange);
1760
+ this.setTagAttribute("auro-menu");
1761
+ }
1762
+
1763
+ disconnectedCallback() {
1764
+ this.removeEventListener('keydown', this.handleKeyDown);
1765
+ this.removeEventListener('auroMenuOption-click', this.handleMouseSelect);
1766
+ this.removeEventListener('auroMenuOption-mouseover', this.handleOptionHover);
1767
+ this.removeEventListener('slotchange', this.handleSlotChange);
1768
+
1769
+ super.disconnectedCallback();
1770
+ }
1771
+
1772
+ firstUpdated() {
1773
+ AuroLibraryRuntimeUtils.prototype.handleComponentTagRename(this, 'auro-menu');
1774
+
1775
+ this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
1776
+ this.initializeMenu();
1777
+ }
1778
+
1779
+
1780
+ updated(changedProperties) {
1781
+ super.updated(changedProperties);
1782
+
1783
+ // Update menu service properties on host update
1784
+ if (changedProperties.has('value')) {
1785
+ this.menuService.selectByValue(this.value);
1786
+ }
1787
+
1788
+ // Handle loading state changes
1789
+ if (changedProperties.has('loading')) {
1790
+ this.setLoadingState(this.loading);
1791
+ }
1792
+ }
1793
+
1794
+ /**
1795
+ * Sets an attribute that matches the default tag name if the tag name is not the default.
1796
+ * @param {string} tagName - The tag name to set as an attribute.
1797
+ * @private
1798
+ */
1799
+ setTagAttribute(tagName) {
1800
+ if (this.tagName.toLowerCase() !== tagName) {
1801
+ this.setAttribute(tagName, true);
1802
+ }
1803
+ }
1804
+
1805
+ /**
1806
+ * Sets the loading state and dispatches a loading change event.
1807
+ * @param {boolean} isLoading - Whether the menu is loading.
1808
+ * @protected
1809
+ */
1810
+ setLoadingState(isLoading) {
1811
+ this.setAttribute("aria-busy", isLoading);
1812
+ dispatchMenuEvent(this, "auroMenu-loadingChange", {
1813
+ loading: isLoading,
1814
+ hasLoadingPlaceholder: this.hasLoadingPlaceholder
1815
+ });
1816
+ }
1817
+
1818
+ // Init Methods
1819
+
1820
+ /**
1821
+ * Initializes the menu's state and structure.
1822
+ * @private
1823
+ */
1824
+ initializeMenu() {
1825
+ if (this.rootMenu) {
1826
+ this.setAttribute('role', 'listbox');
1827
+ this.setAttribute('root', '');
1828
+ this.handleNestedMenus(this);
1829
+ }
1830
+ }
1831
+
1832
+ /**
1833
+ * Selects the currently highlighted option.
1834
+ * @protected
1835
+ */
1836
+ makeSelection() {
1837
+ this.menuService.selectHighlightedOption();
1838
+ }
1839
+
1840
+ /**
1841
+ * Resets all options to their default state.
1842
+ * @private
1843
+ */
1844
+ clearSelection() {
1845
+ this.optionSelected = undefined;
1846
+ this.value = undefined;
1847
+ this._index = -1;
1848
+ }
1849
+
1850
+ /**
1851
+ * Resets the menu to its initial state.
1852
+ * This is the only way to return value to undefined.
1853
+ * @public
1854
+ */
1855
+ reset() {
1856
+ this.menuService.reset();
1857
+
1858
+ // Dispatch reset event
1859
+ dispatchMenuEvent(this, 'auroMenu-selectValueReset');
1860
+ }
1861
+
1862
+ /**
1863
+ * Handles nested menu structure.
1864
+ * @private
1865
+ * @param {HTMLElement} menu - Root menu element.
1866
+ */
1867
+ handleNestedMenus(menu) {
1868
+ menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
1869
+
1870
+ if (menu.level > 0) {
1871
+ menu.setAttribute('role', 'group');
1872
+ menu.removeAttribute("root");
1873
+ if (!menu.hasAttribute('aria-label')) {
1874
+ menu.setAttribute('aria-label', 'submenu');
1875
+ }
1876
+ }
1877
+
1878
+ const options = menu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption]');
1879
+ options.forEach((option) => {
1880
+ const regex = new RegExp(this.nestingSpacer, "gu");
1881
+ option.innerHTML = this.nestingSpacer.repeat(menu.level) + option.innerHTML.replace(regex, '');
1882
+ });
1883
+ }
1884
+
1885
+ // Event Handlers
1886
+
1887
+ /**
1888
+ * Handles keyboard navigation.
1889
+ * @private
1890
+ * @param {KeyboardEvent} event - Event object from the browser.
1891
+ */
1892
+ handleKeyDown(event) {
1893
+ event.preventDefault();
1894
+ switch (event.key) {
1895
+ case "ArrowDown":
1896
+ this.menuService.highlightNext();
1897
+ break;
1898
+ case "ArrowUp":
1899
+ this.menuService.highlightPrevious();
1900
+ break;
1901
+ case "Tab":
1902
+ case "Enter":
1903
+ this.menuService.selectHighlightedOption();
1904
+ break;
1905
+ }
1906
+ }
1907
+
1908
+ /**
1909
+ * Navigates the menu options in the specified direction.
1910
+ * @param {'up'|'down'} direction - The direction to navigate.
1911
+ * @protected
1013
1912
  */
1014
- updateActiveOption(index) {
1015
- if (!this.items || !this.items[index]) {
1016
- return;
1913
+ navigateOptions(direction) {
1914
+ if (direction === 'up') {
1915
+ this.menuService.highlightPrevious();
1916
+ } else if (direction === 'down') {
1917
+ this.menuService.highlightNext();
1017
1918
  }
1919
+ }
1018
1920
 
1019
- this.items.forEach((item) => item.classList.remove('active'));
1020
- this.items[index].classList.add('active');
1021
- this.optionActive = this.items[index];
1022
- this.index = index;
1921
+ /**
1922
+ * Handles slot change events.
1923
+ * @private
1924
+ */
1925
+ handleSlotChange() {
1926
+ if (this.parentElement && this.parentElement.closest('auro-menu, [auro-menu]')) {
1927
+ this.rootMenu = false;
1928
+ }
1023
1929
 
1024
- dispatchMenuEvent(this, 'auroMenu-activatedOption', this.items[index]);
1930
+ if (this.rootMenu) {
1931
+ this.initializeMenu();
1932
+ }
1025
1933
  }
1026
1934
 
1027
1935
  /**
@@ -1040,8 +1948,13 @@ class AuroMenu extends AuroElement {
1040
1948
  * @param {any} source - The source that triggers this event.
1041
1949
  * @private
1042
1950
  */
1043
- notifySelectionChange(source = undefined) {
1044
- dispatchMenuEvent(this, 'auroMenu-selectedOption', { source });
1951
+ notifySelectionChange({value, stringValue, keys, options} = {}) {
1952
+ dispatchMenuEvent(this, 'auroMenu-selectedOption', {
1953
+ value,
1954
+ stringValue,
1955
+ keys,
1956
+ options
1957
+ });
1045
1958
  }
1046
1959
 
1047
1960
  /**
@@ -1114,256 +2027,4 @@ class AuroMenu extends AuroElement {
1114
2027
  }
1115
2028
  }
1116
2029
 
1117
- var styleCss = css`.body-default{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);font-size:var(--wcss-body-default-font-size, 1rem);line-height:var(--wcss-body-default-line-height, 1.5rem)}.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);font-size:var(--wcss-body-lg-font-size, 1.125rem);line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-sm{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);font-size:var(--wcss-body-sm-font-size, 0.875rem);line-height:var(--wcss-body-sm-line-height, 1.25rem)}.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);font-size:var(--wcss-body-xs-font-size, 0.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-weight:var(--wcss-body-weight, 450);letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-2xs-font-size, 0.625rem);line-height:var(--wcss-body-2xs-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);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);font-weight:var(--wcss-display-2xl-weight, 300);line-height:var(--wcss-display-2xl-line-height, 1.3);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem))}.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);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);font-weight:var(--wcss-display-xl-weight, 300);line-height:var(--wcss-display-xl-line-height, 1.3);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem))}.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);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);font-weight:var(--wcss-display-lg-weight, 300);line-height:var(--wcss-display-lg-line-height, 1.3);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem))}.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);letter-spacing:var(--wcss-display-md-letter-spacing, 0);font-weight:var(--wcss-display-md-weight, 300);line-height:var(--wcss-display-md-line-height, 1.3);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem))}.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);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);font-weight:var(--wcss-display-sm-weight, 300);line-height:var(--wcss-display-sm-line-height, 1.3);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem))}.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);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);font-weight:var(--wcss-display-xs-weight, 300);line-height:var(--wcss-display-xs-line-height, 1.3);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem))}.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);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);font-weight:var(--wcss-heading-xl-weight, 300);line-height:var(--wcss-heading-xl-line-height, 1.3);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem))}.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);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);font-weight:var(--wcss-heading-lg-weight, 300);line-height:var(--wcss-heading-lg-line-height, 1.3);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem))}.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);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);font-weight:var(--wcss-heading-md-weight, 300);line-height:var(--wcss-heading-md-line-height, 1.3);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem))}.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);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);font-weight:var(--wcss-heading-sm-weight, 300);line-height:var(--wcss-heading-sm-line-height, 1.3);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem))}.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);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);font-weight:var(--wcss-heading-xs-weight, 450);line-height:var(--wcss-heading-xs-line-height, 1.3);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem))}.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);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);font-weight:var(--wcss-heading-2xs-weight, 450);line-height:var(--wcss-heading-2xs-line-height, 1.3);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem))}.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);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-2xl-weight, 450);line-height:var(--wcss-accent-2xl-line-height, 1);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));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);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);font-weight:var(--wcss-accent-xl-weight, 450);line-height:var(--wcss-accent-xl-line-height, 1.3);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);font-weight:var(--wcss-accent-lg-weight, 450);line-height:var(--wcss-accent-lg-line-height, 1.3);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));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);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);font-weight:var(--wcss-accent-md-weight, 500);line-height:var(--wcss-accent-md-line-height, 1.3);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);font-weight:var(--wcss-accent-sm-weight, 500);line-height:var(--wcss-accent-sm-line-height, 1.3);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));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);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-xs-weight, 500);line-height:var(--wcss-accent-xs-line-height, 1.3);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));text-transform:uppercase}.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);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);font-weight:var(--wcss-accent-2xs-weight, 450);line-height:var(--wcss-accent-2xs-line-height, 1.3);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));text-transform:uppercase}:host{cursor:pointer;user-select:none;text-overflow:ellipsis;max-width:100dvw}:host .wrapper{display:flex;align-items:center;padding-right:var(--ds-size-200, 1rem);padding-left:calc(var(--ds-size-150, 0.75rem) + var(--ds-size-300, 1.5rem) + var(--ds-size-100, 0.5rem));padding-top:var(--ds-size-50, 0.25rem);padding-bottom:var(--ds-size-50, 0.25rem);border-radius:var(--ds-size-100, 0.5rem);-webkit-tap-highlight-color:transparent}:host .wrapper[class*=shape-box]{border-radius:unset}:host .wrapper[class*=shape-snowflake]{border-radius:unset;line-height:24px}:host .wrapper[class*=shape-pill]{border-radius:30px}:host .wrapper[class*=-lg]{padding-top:var(--ds-size-75, 0.375rem);padding-bottom:var(--ds-size-75, 0.375rem);padding-right:var(--ds-size-150, 0.75rem);line-height:26px}:host .wrapper[class*=-xl]{padding-top:var(--ds-size-100, 0.5rem);padding-bottom:var(--ds-size-100, 0.5rem);padding-right:var(--ds-size-200, 1rem);line-height:26px}:host slot{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host [auro-icon]{--ds-auro-icon-size: var(--ds-size-300, 1.5rem);margin-right:var(--ds-size-150, 0.75rem);margin-left:var(--ds-size-100, 0.5rem)}:host ::slotted(.nestingSpacer){display:inline-block;width:var(--ds-size-300, 1.5rem)}[slot=displayValue]{display:none}:host([loadingplaceholder]) .wrapper{padding-left:calc(var(--ds-size-150, 0.75rem) + var(--ds-size-300, 1.5rem) + var(--ds-size-100, 0.5rem))}:host([selected]) .wrapper{padding-left:0}:host([nocheckmark]) .wrapper{padding-left:var(--ds-size-150, 0.75rem)}:host([nocheckmark]) .wrapper[class*=-lg]{padding-left:var(--ds-size-150, 0.75rem)}:host([nocheckmark]) .wrapper[class*=-xl]{padding-left:var(--ds-size-200, 1rem)}:host([hidden]){display:none}:host([static]){pointer-events:none}:host([disabled]:hover){cursor:auto}:host([disabled]){user-select:none;pointer-events:none}`;
1118
-
1119
- var colorCss = css`:host .wrapper{background-color:var(--ds-auro-menuoption-container-color, transparent);box-shadow:inset 0 0 0 1px var(--ds-auro-menuoption-container-border-color, transparent);color:var(--ds-auro-menuoption-text-color)}:host svg{fill:var(--ds-auro-menuoption-icon-color)}:host([disabled]){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-menuoption-text-color: var(--ds-basic-color-texticon-disabled, #d0d0d0);--ds-auro-menuoption-icon-color: var(--ds-basic-color-texticon-disabled, #d0d0d0)}:host(:hover),:host(.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}:host(:focus){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-default, #ffffff);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host([selected]){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-subtle, #b4eff9);--ds-auro-menuoption-text-color: var(--ds-basic-color-texticon-default, #2a2a2a);--ds-auro-menuoption-icon-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([selected]:hover),:host([selected].active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}:host([selected]:focus){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-subtle, #b4eff9);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host(:focus:hover),:host(:focus.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}:host([selected]:focus:hover),:host([selected]:focus.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd);--ds-auro-menuoption-container-border-color: var(--ds-basic-color-border-brand, #00274a)}`;
1120
-
1121
- // Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license
1122
- // See LICENSE in the project root for license information.
1123
-
1124
-
1125
- class AuroDependencyVersioning {
1126
-
1127
- /**
1128
- * Generates a unique string to be used for child auro element naming.
1129
- * @private
1130
- * @param {string} baseName - Defines the first part of the unique element name.
1131
- * @param {string} version - Version of the component that will be appended to the baseName.
1132
- * @returns {string} - Unique string to be used for naming.
1133
- */
1134
- generateElementName(baseName, version) {
1135
- let result = baseName;
1136
-
1137
- result += '-';
1138
- result += version.replace(/[.]/g, '_');
1139
-
1140
- return result;
1141
- }
1142
-
1143
- /**
1144
- * Generates a unique string to be used for child auro element naming.
1145
- * @param {string} baseName - Defines the first part of the unique element name.
1146
- * @param {string} version - Version of the component that will be appended to the baseName.
1147
- * @returns {string} - Unique string to be used for naming.
1148
- */
1149
- generateTag(baseName, version, tagClass) {
1150
- const elementName = this.generateElementName(baseName, version);
1151
- const tag = literal`${unsafeStatic(elementName)}`;
1152
-
1153
- if (!customElements.get(elementName)) {
1154
- customElements.define(elementName, class extends tagClass {});
1155
- }
1156
-
1157
- return tag;
1158
- }
1159
- }
1160
-
1161
- class p{registerComponent(t,a){customElements.get(t)||customElements.define(t,class extends a{});}closestElement(t,a=this,e=(a,s=a&&a.closest(t))=>a&&a!==document&&a!==window?s||e(a.getRootNode().host):null){return e(a)}handleComponentTagRename(t,a){const e=a.toLowerCase();t.tagName.toLowerCase()!==e&&t.setAttribute(e,true);}elementMatch(t,a){const e=a.toLowerCase();return t.tagName.toLowerCase()===e||t.hasAttribute(e)}}var u='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-labelledby="error__desc" class="ico_squareLarge" data-deprecated="true" role="img" style="min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor" viewBox="0 0 24 24" part="svg"><title/><desc id="error__desc">Error alert indicator.</desc><path d="m13.047 5.599 6.786 11.586A1.207 1.207 0 0 1 18.786 19H5.214a1.207 1.207 0 0 1-1.047-1.815l6.786-11.586a1.214 1.214 0 0 1 2.094 0m-1.165.87a.23.23 0 0 0-.085.085L5.419 17.442a.232.232 0 0 0 .203.35h12.756a.234.234 0 0 0 .203-.35L12.203 6.554a.236.236 0 0 0-.321-.084M12 15.5a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5m-.024-6.22c.325 0 .589.261.589.583v4.434a.586.586 0 0 1-.589.583.586.586 0 0 1-.588-.583V9.863c0-.322.264-.583.588-.583"/></svg>';class m extends LitElement{static get properties(){return {hidden:{type:Boolean,reflect:true},hiddenVisually:{type:Boolean,reflect:true},hiddenAudible:{type:Boolean,reflect:true}}}hideAudible(t){return t?"true":"false"}}const g=new Map,f=(t,a={})=>{const e=a.responseParser||(t=>t.text());return g.has(t)||g.set(t,fetch(t).then(e)),g.get(t)};var w=css`:focus:not(:focus-visible){outline:3px solid transparent}.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock,:host{display:block}.util_displayFlex{display:flex}.util_displayHidden,:host([hidden]:not(:focus):not(:active)){display:none}.util_displayHiddenVisually,:host([hiddenVisually]:not(:focus):not(:active)){position:absolute;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;padding:0;border:0}.ico_squareLarge{fill:currentColor;height:var(--auro-size-lg, var(--ds-size-300, 1.5rem))}.ico_squareSmall{fill:currentColor;height:.6rem}.ico_squareMed{fill:currentColor;height:var(--auro-size-md, var(--ds-size-200, 1rem))}.ico_squareSml{fill:currentColor;height:var(--auro-size-sm, var(--ds-size-150, .75rem))}:host{color:currentColor;vertical-align:middle;line-height:1;display:inline-block}svg{min-width:var(--ds-auro-icon-size, 1.5rem)!important;width:var(--ds-auro-icon-size, 1.5rem)!important;height:var(--ds-auro-icon-size, 1.5rem)!important}.componentWrapper{display:flex}.svgWrapper{height:var(--ds-auro-icon-size);width:var(--ds-auro-icon-size)}.labelWrapper{margin-left:var(--ds-size-50, .25rem);line-height:1.8}
1162
- `;class z extends m{constructor(){super(),this.onDark=false,this.appearance="default";}static get properties(){return {...m.properties,onDark:{type:Boolean,reflect:true},appearance:{type:String,reflect:true},svg:{attribute:false,reflect:true}}}static get styles(){return w}async fetchIcon(t,a){let e="";e="logos"===t?await f(`${this.uri}/${t}/${a}.svg`):await f(`${this.uri}/icons/${t}/${a}.svg`);return (new DOMParser).parseFromString(e,"text/html").body.querySelector("svg")}async firstUpdated(){try{if(!this.customSvg){const t=await this.fetchIcon(this.category,this.name);if(t)this.svg=t;else if(!t){const t=(new DOMParser).parseFromString(u,"text/html");this.svg=t.body.firstChild;}}}catch(t){this.svg=void 0;}}}css`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock,:host{display:block}.util_displayFlex{display:flex}.util_displayHidden,:host([hidden]:not(:focus):not(:active)){display:none}.util_displayHiddenVisually,:host([hiddenVisually]:not(:focus):not(:active)){position:absolute;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;padding:0;border:0}:host{display:inline-block;--ds-auro-icon-size: 100%;width:100%;height:100%}:host .logo{color:var(--ds-auro-alaska-color)}:host([onDark]),:host([appearance=inverse]){--ds-auro-alaska-color: #FFF}
1163
- `;var y=css`:host{--ds-auro-icon-color: var(--ds-basic-color-texticon-default, #2a2a2a);--ds-auro-alaska-color: #02426D;--ds-auro-icon-size: var(--ds-size-300, 1.5rem)}
1164
- `;var k=css`:host{color:var(--ds-auro-icon-color)}:host([customColor]){color:inherit}:host(:not([onDark])[variant=accent1]),:host(:not([appearance=inverse])[variant=accent1]){--ds-auro-icon-color: var(--ds-basic-color-texticon-accent1, #265688)}:host(:not([onDark])[variant=disabled]),:host(:not([appearance=inverse])[variant=disabled]){--ds-auro-icon-color: var(--ds-basic-color-texticon-disabled, #d0d0d0)}:host(:not([onDark])[variant=muted]),:host(:not([appearance=inverse])[variant=muted]){--ds-auro-icon-color: var(--ds-basic-color-texticon-muted, #676767)}:host(:not([onDark])[variant=statusDefault]),:host(:not([appearance=inverse])[variant=statusDefault]){--ds-auro-icon-color: var(--ds-basic-color-status-default, #afb9c6)}:host(:not([onDark])[variant=statusInfo]),:host(:not([appearance=inverse])[variant=statusInfo]){--ds-auro-icon-color: var(--ds-basic-color-status-info, #01426a)}:host(:not([onDark])[variant=statusSuccess]),:host(:not([appearance=inverse])[variant=statusSuccess]){--ds-auro-icon-color: var(--ds-basic-color-status-success, #447a1f)}:host(:not([onDark])[variant=statusWarning]),:host(:not([appearance=inverse])[variant=statusWarning]){--ds-auro-icon-color: var(--ds-basic-color-status-warning, #fac200)}:host(:not([onDark])[variant=statusError]),:host(:not([appearance=inverse])[variant=statusError]){--ds-auro-icon-color: var(--ds-basic-color-status-error, #e31f26)}:host(:not([onDark])[variant=statusInfoSubtle]),:host(:not([appearance=inverse])[variant=statusInfoSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-info-subtle, #ebf3f9)}:host(:not([onDark])[variant=statusSuccessSubtle]),:host(:not([appearance=inverse])[variant=statusSuccessSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-success-subtle, #d6eac7)}:host(:not([onDark])[variant=statusWarningSubtle]),:host(:not([appearance=inverse])[variant=statusWarningSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-warning-subtle, #fff0b2)}:host(:not([onDark])[variant=statusErrorSubtle]),:host(:not([appearance=inverse])[variant=statusErrorSubtle]){--ds-auro-icon-color: var(--ds-basic-color-status-error-subtle, #fbc6c6)}:host(:not([onDark])[variant=fareBasicEconomy]),:host(:not([appearance=inverse])[variant=fareBasicEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-basiceconomy, #97eaf8)}:host(:not([onDark])[variant=fareBusiness]),:host(:not([appearance=inverse])[variant=fareBusiness]){--ds-auro-icon-color: var(--ds-basic-color-fare-business, #01426a)}:host(:not([onDark])[variant=fareEconomy]),:host(:not([appearance=inverse])[variant=fareEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-economy, #0074ca)}:host(:not([onDark])[variant=fareFirst]),:host(:not([appearance=inverse])[variant=fareFirst]){--ds-auro-icon-color: var(--ds-basic-color-fare-first, #00274a)}:host(:not([onDark])[variant=farePremiumEconomy]),:host(:not([appearance=inverse])[variant=farePremiumEconomy]){--ds-auro-icon-color: var(--ds-basic-color-fare-premiumeconomy, #005154)}:host(:not([onDark])[variant=tierOneWorldEmerald]),:host(:not([appearance=inverse])[variant=tierOneWorldEmerald]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-emerald, #139142)}:host(:not([onDark])[variant=tierOneWorldSapphire]),:host(:not([appearance=inverse])[variant=tierOneWorldSapphire]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-sapphire, #015daa)}:host(:not([onDark])[variant=tierOneWorldRuby]),:host(:not([appearance=inverse])[variant=tierOneWorldRuby]){--ds-auro-icon-color: var(--ds-basic-color-tier-program-oneworld-ruby, #a41d4a)}:host([onDark]),:host([appearance=inverse]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse, #ffffff)}:host([onDark][variant=disabled]),:host([appearance=inverse][variant=disabled]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse-disabled, #7e8894)}:host([onDark][variant=muted]),:host([appearance=inverse][variant=muted]){--ds-auro-icon-color: var(--ds-basic-color-texticon-inverse-muted, #ccd2db)}:host([onDark][variant=statusError]),:host([appearance=inverse][variant=statusError]){--ds-auro-icon-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8)}
1165
- `;class x extends z{constructor(){super(),this.variant=void 0,this.privateDefaults();}privateDefaults(){this.uri="https://cdn.jsdelivr.net/npm/@alaskaairux/icons@latest/dist",this.runtimeUtils=new p;}static get properties(){return {...z.properties,ariaHidden:{type:String,reflect:true},category:{type:String,reflect:true},customColor:{type:Boolean,reflect:true},customSvg:{type:Boolean},label:{type:Boolean,reflect:true},name:{type:String,reflect:true},variant:{type:String,reflect:true}}}static get styles(){return [z.styles,y,w,k]}static register(t="auro-icon"){p.prototype.registerComponent(t,x);}connectedCallback(){super.connectedCallback(),this.runtimeUtils.handleComponentTagRename(this,"auro-icon");}exposeCssParts(){this.setAttribute("exportparts","svg:iconSvg");}async firstUpdated(){if(await super.firstUpdated(),this.hasAttribute("ariaHidden")&&this.svg){const t=this.svg.querySelector("desc");t&&(t.remove(),this.svg.removeAttribute("aria-labelledby"));}}render(){const t={labelWrapper:true,util_displayHiddenVisually:!this.label};return html`
1166
- <div class="componentWrapper">
1167
- <div
1168
- class="${classMap({svgWrapper:true})}"
1169
- title="${ifDefined(this.title||void 0)}">
1170
- <span aria-hidden="${ifDefined(this.ariaHidden||true)}" part="svg">
1171
- ${this.customSvg?html`
1172
- <slot name="svg"></slot>
1173
- `:html`
1174
- ${this.svg}
1175
- `}
1176
- </span>
1177
- </div>
1178
-
1179
- <div class="${classMap(t)}" part="label">
1180
- <slot></slot>
1181
- </div>
1182
- </div>
1183
- `}}
1184
-
1185
- var iconVersion = '9.1.0';
1186
-
1187
- var checkmarkIcon = {"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-labelledby=\"checkmark-sm__desc\" class=\"ico_squareLarge\" role=\"img\" style=\"min-width:var(--auro-size-lg, var(--ds-size-300, 1.5rem));height:var(--auro-size-lg, var(--ds-size-300, 1.5rem));fill:currentColor\" viewBox=\"0 0 24 24\" part=\"svg\"><title/><desc id=\"checkmark-sm__desc\">a small check mark.</desc><path d=\"M8.461 11.84a.625.625 0 1 0-.922.844l2.504 2.738c.247.27.674.27.922 0l5.496-6a.625.625 0 1 0-.922-.844l-5.035 5.496z\"/></svg>"};
1188
-
1189
- // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
1190
- // See LICENSE in the project root for license information.
1191
-
1192
-
1193
- /**
1194
- * The auro-menu element provides users a way to define a menu option.
1195
- *
1196
- * @attr {String} value - Specifies the value to be sent to a server.
1197
- * @attr {String} noCheckmark - When true, selected option will not show the checkmark.
1198
- * @attr {Boolean} disabled - When true specifies that the menuoption is disabled.
1199
- * @attr {Boolean} selected - Specifies that an option is selected.
1200
- * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
1201
- * @slot - Specifies text for an option, but is not the value.
1202
- */
1203
- class AuroMenuOption extends AuroElement {
1204
- constructor() {
1205
- super();
1206
-
1207
- /**
1208
- * @private
1209
- */
1210
- this.shape = undefined;
1211
-
1212
- /**
1213
- * @private
1214
- */
1215
- this.size = undefined;
1216
-
1217
- /**
1218
- * Generate unique names for dependency components.
1219
- */
1220
- const versioning = new AuroDependencyVersioning();
1221
- this.iconTag = versioning.generateTag('auro-formkit-menuoption-icon', iconVersion, x);
1222
-
1223
- this.selected = false;
1224
- this.nocheckmark = false;
1225
- this.disabled = false;
1226
-
1227
- /**
1228
- * @private
1229
- */
1230
- this.tabIndex = -1;
1231
-
1232
- /**
1233
- * @private
1234
- */
1235
- this.runtimeUtils = new AuroLibraryRuntimeUtils();
1236
- }
1237
-
1238
- static get properties() {
1239
- return {
1240
- ...super.properties,
1241
- nocheckmark: {
1242
- type: Boolean,
1243
- reflect: true
1244
- },
1245
- selected: {
1246
- type: Boolean,
1247
- reflect: true
1248
- },
1249
- disabled: {
1250
- type: Boolean,
1251
- reflect: true
1252
- },
1253
- value: {
1254
- type: String,
1255
- reflect: true
1256
- },
1257
- tabIndex: {
1258
- type: Number,
1259
- reflect: true
1260
- }
1261
- };
1262
- }
1263
-
1264
- static get styles() {
1265
- return [
1266
- styleCss,
1267
- colorCss,
1268
- tokensCss
1269
- ];
1270
- }
1271
-
1272
- /**
1273
- * This will register this element with the browser.
1274
- * @param {string} [name="auro-menuoption"] - The name of element that you want to register to.
1275
- *
1276
- * @example
1277
- * AuroMenuOption.register("custom-menuoption") // this will register this element to <custom-menuoption/>
1278
- *
1279
- */
1280
- static register(name = "auro-menuoption") {
1281
- AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroMenuOption);
1282
- }
1283
-
1284
- connectedCallback() {
1285
- super.connectedCallback();
1286
-
1287
- // Add the tag name as an attribute if it is different than the component name
1288
- // Add this step soon as this node gets attached to the DOM to avoid racing condition with menu's value setting logic.
1289
- this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
1290
- }
1291
-
1292
- firstUpdated() {
1293
- if (!this.hasAttribute('size')) {
1294
- this.size = this.parentElement.getAttribute('size') || 'sm';
1295
- }
1296
- if (!this.hasAttribute('shape')) {
1297
- this.shape = this.parentElement.getAttribute('shape') || 'box';
1298
- }
1299
-
1300
- this.setAttribute('role', 'option');
1301
- this.setAttribute('aria-selected', 'false');
1302
-
1303
- this.addEventListener('mouseover', () => {
1304
- this.dispatchEvent(new CustomEvent('auroMenuOption-mouseover', {
1305
- bubbles: true,
1306
- cancelable: false,
1307
- composed: true,
1308
- detail: this
1309
- }));
1310
- });
1311
- }
1312
-
1313
- // observer for selected property changes
1314
- updated(changedProperties) {
1315
- super.updated(changedProperties);
1316
-
1317
- if (changedProperties.has('selected')) {
1318
- this.setAttribute('aria-selected', this.selected.toString());
1319
- }
1320
- }
1321
-
1322
- /**
1323
- * Generates an HTML element containing an SVG icon based on the provided `svgContent`.
1324
- *
1325
- * @private
1326
- * @param {string} svgContent - The SVG content to be embedded.
1327
- * @returns {Element} The HTML element containing the SVG icon.
1328
- */
1329
- generateIconHtml(svgContent) {
1330
- const dom = new DOMParser().parseFromString(svgContent, 'text/html');
1331
- const svg = dom.body.firstChild;
1332
-
1333
- svg.setAttribute('slot', 'svg');
1334
-
1335
- return html$1`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
1336
- }
1337
-
1338
- /**
1339
- * Logic to determine the layout of the component.
1340
- * @protected
1341
- * @returns {void}
1342
- */
1343
- renderLayout() {
1344
-
1345
- const fontClassMap = {
1346
- xs: 'body-sm',
1347
- sm: 'body-default',
1348
- md: 'body-default',
1349
- lg: 'body-lg',
1350
- xl: 'body-lg'
1351
- };
1352
-
1353
- const classes = classMap({
1354
- 'wrapper': true,
1355
- [this.size ? fontClassMap[this.size] : 'body-sm']: true,
1356
- });
1357
-
1358
- return html$1`
1359
- <div class="${classes}">
1360
- ${this.selected && !this.nocheckmark
1361
- ? this.generateIconHtml(checkmarkIcon.svg)
1362
- : undefined}
1363
- <slot></slot>
1364
- </div>
1365
- `;
1366
- }
1367
- }
1368
-
1369
2030
  export { AuroMenu, AuroMenuOption, arrayConverter, dispatchMenuEvent, isOptionInteractive };