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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/components/checkbox/demo/api.html +4 -26
  2. package/components/checkbox/demo/getting-started.md +5 -6
  3. package/components/checkbox/demo/index.min.js +1 -1
  4. package/components/checkbox/dist/index.js +1 -1
  5. package/components/checkbox/dist/registered.js +1 -1
  6. package/components/combobox/demo/api.html +4 -25
  7. package/components/combobox/demo/getting-started.md +76 -27
  8. package/components/combobox/demo/index.min.js +15 -1
  9. package/components/combobox/demo/registered.min.js +1517 -1509
  10. package/components/combobox/dist/auro-combobox.d.ts +1 -1
  11. package/components/combobox/dist/index.js +18 -11
  12. package/components/combobox/dist/registered.js +18 -11
  13. package/components/counter/demo/api.html +5 -29
  14. package/components/counter/demo/getting-started.md +4 -3
  15. package/components/counter/demo/index.min.js +8392 -1
  16. package/components/counter/dist/index.js +53 -5284
  17. package/components/counter/dist/registered.js +106 -5110
  18. package/components/datepicker/demo/accessibility.html +0 -1
  19. package/components/datepicker/demo/api.html +4 -29
  20. package/components/datepicker/demo/getting-started.md +25 -2
  21. package/components/datepicker/demo/index.min.js +24612 -1
  22. package/components/datepicker/demo/readme.html +2 -10
  23. package/components/datepicker/dist/index.js +10 -10
  24. package/components/datepicker/dist/registered.js +10 -10
  25. package/components/dropdown/demo/api.html +5 -31
  26. package/components/dropdown/demo/getting-started.md +34 -2
  27. package/components/dropdown/demo/index.min.js +5097 -1
  28. package/components/dropdown/dist/index.js +1 -1
  29. package/components/dropdown/dist/registered.js +1 -1
  30. package/components/form/demo/api.html +5 -27
  31. package/components/form/demo/getting-started.md +5 -6
  32. package/components/form/demo/index.min.js +719 -2
  33. package/components/form/demo/keyboard-behavior.md +38 -0
  34. package/components/form/demo/pages.json +1 -1
  35. package/components/form/demo/registerDemoDeps.min.js +11842 -60908
  36. package/components/input/demo/accessibility.md +1 -1
  37. package/components/input/demo/api.html +15 -26
  38. package/components/input/demo/auro-input.min.js +1 -1
  39. package/components/input/demo/getting-started.md +1 -1
  40. package/components/input/demo/readme.html +2 -10
  41. package/components/input/dist/index.js +1 -1
  42. package/components/input/dist/registered.js +1 -1
  43. package/components/menu/demo/api.html +5 -30
  44. package/components/menu/demo/api.md +1 -1
  45. package/components/menu/demo/getting-started.md +1 -1
  46. package/components/menu/demo/index.min.js +1574 -1573
  47. package/components/menu/dist/auro-menu.context.d.ts +0 -1
  48. package/components/menu/dist/auro-menu.d.ts +1 -1
  49. package/components/menu/dist/index.js +1609 -1608
  50. package/components/menu/dist/registered.js +1553 -1552
  51. package/components/radio/demo/api.html +7 -28
  52. package/components/radio/demo/getting-started.md +27 -2
  53. package/components/radio/demo/index.md +1 -3
  54. package/components/radio/demo/index.min.js +1 -1
  55. package/components/radio/demo/readme.md +0 -2
  56. package/components/radio/dist/index.js +1 -1
  57. package/components/radio/dist/registered.js +1 -1
  58. package/components/select/demo/api.html +5 -42
  59. package/components/select/demo/getting-started.md +39 -5
  60. package/components/select/demo/registered.min.js +1503 -1502
  61. package/components/select/dist/index.js +2 -2
  62. package/components/select/dist/registered.js +2 -2
  63. package/custom-elements.json +1487 -1489
  64. package/package.json +37 -4
  65. package/components/combobox/demo/api.js +0 -39
  66. package/components/combobox/demo/api.min.js +0 -106
  67. package/components/combobox/demo/install.html +0 -50
  68. package/components/combobox/demo/styles.css +0 -974
  69. package/components/combobox/demo/swap-value.min.js +0 -16
  70. package/components/counter/demo/api.js +0 -24
  71. package/components/counter/demo/api.min.js +0 -52
  72. package/components/counter/demo/auro-counter-group.min.js +0 -8394
  73. package/components/datepicker/demo/api.js +0 -37
  74. package/components/datepicker/demo/api.min.js +0 -300
  75. package/components/datepicker/demo/auro-datepicker.min.js +0 -24614
  76. package/components/dropdown/demo/api.js +0 -26
  77. package/components/dropdown/demo/api.min.js +0 -109
  78. package/components/dropdown/demo/auro-dropdown.min.js +0 -5099
  79. package/components/form/demo/api.js +0 -5
  80. package/components/form/demo/api.min.js +0 -5
  81. package/components/form/demo/auro-form.min.js +0 -718
  82. package/components/form/demo/autocomplete.html +0 -31
  83. package/components/radio/demo/api.js +0 -19
  84. package/components/radio/demo/api.min.js +0 -44
  85. package/components/select/demo/keyboardBehavior.html +0 -48
@@ -5333,7 +5333,7 @@ let AuroHelpText$1 = class AuroHelpText extends i$3 {
5333
5333
  }
5334
5334
  };
5335
5335
 
5336
- var formkitVersion$1 = '202605070044';
5336
+ var formkitVersion$1 = '202605081752';
5337
5337
 
5338
5338
  class AuroElement extends i$3 {
5339
5339
  static get properties() {
@@ -7086,7 +7086,7 @@ class AuroHelpText extends i$3 {
7086
7086
  }
7087
7087
  }
7088
7088
 
7089
- var formkitVersion = '202605070044';
7089
+ var formkitVersion = '202605081752';
7090
7090
 
7091
7091
  var styleCss$2 = i$6`.util_displayInline{display:inline}.util_displayInlineBlock{display:inline-block}.util_displayBlock{display:block}.util_displayFlex{display:flex}.util_displayHidden{display:none}.util_displayHiddenVisually{position:absolute;overflow:hidden;clip:rect(1px, 1px, 1px, 1px);width:1px;height:1px;padding:0;border:0}.body-default{font-size:var(--wcss-body-default-font-size, 1rem);font-weight:var(--wcss-body-default-weight, );line-height:var(--wcss-body-default-line-height, 1.5rem)}.body-default,.body-default-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-default-emphasized{font-size:var(--wcss-body-default-emphasized-font-size, 1rem);font-weight:var(--wcss-body-default-emphasized-weight, );line-height:var(--wcss-body-default-emphasized-line-height, 1.5rem)}.body-lg{font-size:var(--wcss-body-lg-font-size, 1.125rem);font-weight:var(--wcss-body-lg-weight, );line-height:var(--wcss-body-lg-line-height, 1.625rem)}.body-lg,.body-lg-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-lg-emphasized{font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);font-weight:var(--wcss-body-lg-emphasized-weight, );line-height:var(--wcss-body-lg-emphasized-line-height, 1.625rem)}.body-sm{font-size:var(--wcss-body-sm-font-size, 0.875rem);font-weight:var(--wcss-body-sm-weight, );line-height:var(--wcss-body-sm-line-height, 1.25rem)}.body-sm,.body-sm-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-sm-emphasized{font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);font-weight:var(--wcss-body-sm-emphasized-weight, );line-height:var(--wcss-body-sm-emphasized-line-height, 1.25rem)}.body-xs{font-size:var(--wcss-body-xs-font-size, 0.75rem);font-weight:var(--wcss-body-xs-weight, );line-height:var(--wcss-body-xs-line-height, 1rem)}.body-xs,.body-xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-xs-emphasized{font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);font-weight:var(--wcss-body-xs-emphasized-weight, );line-height:var(--wcss-body-xs-emphasized-line-height, 1rem)}.body-2xs{font-size:var(--wcss-body-2xs-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-weight, );line-height:var(--wcss-body-2xs-line-height, 0.875rem)}.body-2xs,.body-2xs-emphasized{font-family:var(--wcss-body-family, "AS Circular"),system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;letter-spacing:var(--wcss-body-letter-spacing, 0)}.body-2xs-emphasized{font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);font-weight:var(--wcss-body-2xs-emphasized-weight, );line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-2xl-font-size, clamp(3.5rem, 6vw, 5.375rem));font-weight:var(--wcss-display-2xl-weight, 300);letter-spacing:var(--wcss-display-2xl-letter-spacing, 0);line-height:var(--wcss-display-2xl-line-height, 1.3)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xl-font-size, clamp(3rem, 5.3333333333vw, 4.5rem));font-weight:var(--wcss-display-xl-weight, 300);letter-spacing:var(--wcss-display-xl-letter-spacing, 0);line-height:var(--wcss-display-xl-line-height, 1.3)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-lg-font-size, clamp(2.75rem, 4.6666666667vw, 4rem));font-weight:var(--wcss-display-lg-weight, 300);letter-spacing:var(--wcss-display-lg-letter-spacing, 0);line-height:var(--wcss-display-lg-line-height, 1.3)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-md-font-size, clamp(2.5rem, 4vw, 3.5rem));font-weight:var(--wcss-display-md-weight, 300);letter-spacing:var(--wcss-display-md-letter-spacing, 0);line-height:var(--wcss-display-md-line-height, 1.3)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-sm-font-size, clamp(2rem, 3.6666666667vw, 3rem));font-weight:var(--wcss-display-sm-weight, 300);letter-spacing:var(--wcss-display-sm-letter-spacing, 0);line-height:var(--wcss-display-sm-line-height, 1.3)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-display-xs-font-size, clamp(1.75rem, 3vw, 2.375rem));font-weight:var(--wcss-display-xs-weight, 300);letter-spacing:var(--wcss-display-xs-letter-spacing, 0);line-height:var(--wcss-display-xs-line-height, 1.3)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xl-font-size, clamp(2rem, 3vw, 2.5rem));font-weight:var(--wcss-heading-xl-weight, 300);letter-spacing:var(--wcss-heading-xl-letter-spacing, 0);line-height:var(--wcss-heading-xl-line-height, 1.3)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-lg-font-size, clamp(1.75rem, 2.6666666667vw, 2.25rem));font-weight:var(--wcss-heading-lg-weight, 300);letter-spacing:var(--wcss-heading-lg-letter-spacing, 0);line-height:var(--wcss-heading-lg-line-height, 1.3)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-md-font-size, clamp(1.625rem, 2.3333333333vw, 1.75rem));font-weight:var(--wcss-heading-md-weight, 300);letter-spacing:var(--wcss-heading-md-letter-spacing, 0);line-height:var(--wcss-heading-md-line-height, 1.3)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-sm-font-size, clamp(1.375rem, 2vw, 1.5rem));font-weight:var(--wcss-heading-sm-weight, 300);letter-spacing:var(--wcss-heading-sm-letter-spacing, 0);line-height:var(--wcss-heading-sm-line-height, 1.3)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-xs-font-size, clamp(1.25rem, 1.6666666667vw, 1.25rem));font-weight:var(--wcss-heading-xs-weight, 300);letter-spacing:var(--wcss-heading-xs-letter-spacing, 0);line-height:var(--wcss-heading-xs-line-height, 1.3)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-heading-2xs-font-size, clamp(1.125rem, 1.5vw, 1.125rem));font-weight:var(--wcss-heading-2xs-weight, 300);letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0);line-height:var(--wcss-heading-2xs-line-height, 1.3)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xl-font-size, clamp(2rem, 3.1666666667vw, 2.375rem));font-weight:var(--wcss-accent-2xl-weight, 450);letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-2xl-line-height, 1)}.accent-2xl,.accent-xl{text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xl-font-size, clamp(1.625rem, 2.3333333333vw, 2rem));font-weight:var(--wcss-accent-xl-weight, 450);letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);line-height:var(--wcss-accent-xl-line-height, 1.3)}.accent-lg{font-family:var(--wcss-accent-lg-family, "Good OT"),var(--wcss-accent-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-lg-font-size, clamp(1.5rem, 2.1666666667vw, 1.75rem));font-weight:var(--wcss-accent-lg-weight, 450);letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);line-height:var(--wcss-accent-lg-line-height, 1.3)}.accent-lg,.accent-md{text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-md-font-size, clamp(1.375rem, 1.8333333333vw, 1.5rem));font-weight:var(--wcss-accent-md-weight, 500);letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);line-height:var(--wcss-accent-md-line-height, 1.3)}.accent-sm{font-family:var(--wcss-accent-sm-family, "Good OT"),var(--wcss-accent-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-sm-font-size, clamp(1.125rem, 1.5vw, 1.25rem));font-weight:var(--wcss-accent-sm-weight, 500);letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);line-height:var(--wcss-accent-sm-line-height, 1.3)}.accent-sm,.accent-xs{text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-xs-font-size, clamp(1rem, 1.3333333333vw, 1rem));font-weight:var(--wcss-accent-xs-weight, 500);letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-xs-line-height, 1.3)}.accent-2xs{font-family:var(--wcss-accent-2xs-family, "Good OT"),var(--wcss-accent-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-size:var(--wcss-accent-2xs-font-size, clamp(0.875rem, 1.1666666667vw, 0.875rem));font-weight:var(--wcss-accent-2xs-weight, 450);letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);line-height:var(--wcss-accent-2xs-line-height, 1.3);text-transform:uppercase}[auro-dropdown]{--ds-auro-dropdown-trigger-border-color: var(--ds-auro-select-border-color);--ds-auro-dropdown-trigger-background-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-container-color: var(--ds-auro-select-background-color);--ds-auro-dropdown-trigger-outline-color: var(--ds-auro-select-outline-color)}:host{display:inline-block;text-align:left;vertical-align:top}:host([layout*=emphasized]) [auro-dropdown],:host([layout*=snowflake]) [auro-dropdown]{--ds-auro-select-border-color: transparent}:host([layout*=emphasized]) .mainContent,:host([layout*=snowflake]) .mainContent{text-align:center}.mainContent{position:relative;display:flex;overflow:hidden;flex:1;flex-direction:column;align-items:center;justify-content:center}.valueContainer [slot=displayValue]{display:none}.accents{display:flex;flex-direction:row;align-items:center;justify-content:center}::slotted([slot=typeIcon]){margin-right:var(--ds-size-100, 0.5rem)}.displayValue{display:block}.displayValue:not(.force){display:none}.displayValue:not(.force).hasContent:is(.withValue):not(.hasFocus){display:block}.triggerContent{display:flex;width:100%;align-items:center;justify-content:center}:host([layout*=emphasized]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-300, 1.5rem)}:host([layout*=snowflake]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem) 0 var(--ds-size-200, 1rem)}:host([layout*=snowflake]) label{padding-block:var(--ds-size-25, 0.125rem)}:host([layout*=classic]) .triggerContent{padding:0 var(--ds-size-100, 0.5rem)}:host([layout*=classic]) .mainContent{align-items:start}:host([layout*=classic]) label{overflow:hidden;cursor:text;text-overflow:ellipsis;white-space:nowrap}:host([layout*=classic]) .value{height:auto}label{color:var(--ds-auro-select-label-text-color)}:host(:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-select-outline-color: var(--ds-basic-color-status-error, #e31f26);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-default, #2a2a2a)}:host([ondark]:is([validity]:not([validity=valid]))) [auro-dropdown],:host([appearance=inverse]:is([validity]:not([validity=valid]))) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-select-outline-color: var(--ds-advanced-color-state-error-inverse, #f9a4a8);--ds-auro-dropdown-helptext-text-color: var(--ds-basic-color-texticon-inverse, #ffffff)}#slotHolder{display:none}:host([fluid]){width:100%}:host([disabled]){pointer-events:none;user-select:none}:host([disabled]:not([ondark])) [auro-dropdown],:host([disabled]:not([appearance=inverse])) [auro-dropdown]{--ds-auro-select-border-color: var(--ds-basic-color-border-subtle, #dddddd)}:host(:not([layout*=classic])[disabled][ondark]) [auro-dropdown],:host(:not([layout*=classic])[disabled][appearance=inverse]) [auro-dropdown]{--ds-auro-select-border-color: transparent}`;
7092
7092
 
@@ -8649,1943 +8649,1944 @@ class s{get value(){return this.o}set value(s){this.setValue(s);}setValue(s,t=fa
8649
8649
  * SPDX-License-Identifier: BSD-3-Clause
8650
8650
  */class e extends Event{constructor(t,s){super("context-provider",{bubbles:true,composed:true}),this.context=t,this.contextTarget=s;}}class i extends s{constructor(s,e,i){super(void 0!==e.context?e.initialValue:i),this.onContextRequest=t=>{if(t.context!==this.context)return;const s=t.contextTarget??t.composedPath()[0];s!==this.host&&(t.stopPropagation(),this.addCallback(t.callback,s,t.subscribe));},this.onProviderRequest=s=>{if(s.context!==this.context)return;if((s.contextTarget??s.composedPath()[0])===this.host)return;const e=new Set;for(const[s,{consumerHost:i}]of this.subscriptions)e.has(s)||(e.add(s),i.dispatchEvent(new s$2(this.context,i,s,true)));s.stopPropagation();},this.host=s,void 0!==e.context?this.context=e.context:this.context=e,this.attachListeners(),this.host.addController?.(this);}attachListeners(){this.host.addEventListener("context-request",this.onContextRequest),this.host.addEventListener("context-provider",this.onProviderRequest);}hostConnected(){this.host.dispatchEvent(new e(this.context,this.host));}}
8651
8651
 
8652
- var styleCss = i$6`.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-default-weight, );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-default-emphasized{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-default-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-default-emphasized-font-size, 1rem);line-height:var(--wcss-body-default-emphasized-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-lg-weight, );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-lg-emphasized{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-lg-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);line-height:var(--wcss-body-lg-emphasized-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-sm-weight, );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-sm-emphasized{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-sm-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);line-height:var(--wcss-body-sm-emphasized-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-xs-weight, );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-xs-emphasized{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-xs-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);line-height:var(--wcss-body-xs-emphasized-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-2xs-weight, );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)}.body-2xs-emphasized{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-2xs-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-2xl-letter-spacing, 0)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-xl-letter-spacing, 0)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-lg-letter-spacing, 0)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-md-letter-spacing, 0)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-sm-letter-spacing, 0)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-xs-letter-spacing, 0)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-xl-letter-spacing, 0)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-lg-letter-spacing, 0)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-md-letter-spacing, 0)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-sm-letter-spacing, 0)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-weight:var(--wcss-heading-xs-weight, 300);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));letter-spacing:var(--wcss-heading-xs-letter-spacing, 0)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-weight:var(--wcss-heading-2xs-weight, 300);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));letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);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);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));letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);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);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));letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);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);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));letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);text-transform:uppercase}:host{cursor:pointer;user-select:none;text-overflow:ellipsis;max-width:100dvw}:host .wrapper{display:flex;align-items:center;height:var(--ds-size-400, 2rem);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));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}`;
8653
-
8654
- var colorCss = i$6`: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(.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}@media(hover: hover){:host(:hover){--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].active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}@media(hover: hover){:host([selected]:hover){--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.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)}@media(hover: hover){:host(:focus:hover){--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.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)}@media(hover: hover){:host([selected]:focus:hover){--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)}}`;
8655
-
8656
- 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)}getSlotText(t,a){const e=t.shadowRoot?.querySelector(`slot[name="${a}"]`);return (e?.assignedNodes({flatten:true})||[]).map(t=>t.textContent?.trim()).join(" ").trim()||null}}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>',g='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="min-width:100%;height:auto;fill:currentColor" viewBox="0 0 142 138" part="svg"><title id="tail-DEFAULT__title">Airplane tail default image with light gray color</title><path fill="url(#paint0_linear_9225_2069)" fill-rule="evenodd" d="M124.093 14.665a3.26 3.26 0 0 1 3.208 3.829L101.097 119.85c-.47 1.087-2.211 3.398-5.692 3.471l-.106.001-80.65.013A659230 659230 0 0 1 99.08 17.412c1.214-1.497 3.275-2.722 5.372-2.747z" clip-rule="evenodd"/><defs><linearGradient id="paint0_linear_9225_2069" x1="114.823" x2="60.061" y1="14.665" y2="123.335" gradientUnits="userSpaceOnUse"><stop offset=".5" stop-color="#707984"/><stop offset=".5" stop-color="#646E7B"/></linearGradient></defs></svg>';class m extends i$3{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 f=new Map,w=(t,a={})=>{const e=a.responseParser||(t=>t.text());return f.has(t)||f.set(t,fetch(t).then(e)),f.get(t)};var z=i$6`: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}
8657
- `;class y extends m{constructor(){super(),this._initializeDefaults();}_initializeDefaults(){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 z}async fetchIcon(t,a){let e="";e="logos"===t?await w(`${this.uri}/${t}/${a}.svg`):await w(`${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=this.name?.startsWith("tail-")?g:u;this.svg=(new DOMParser).parseFromString(t,"text/html").body.querySelector("svg");}}}catch(t){this.svg=void 0;}}}i$6`.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}
8658
- `;var M=i$6`: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)}
8659
- `;var _=i$6`: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)}
8660
- `;class k extends y{constructor(){super(),this._initializeDefaults();}_initializeDefaults(){this.variant=void 0,this.uri="https://cdn.jsdelivr.net/npm/@alaskaairux/icons@latest/dist",this.runtimeUtils=new p;}static get properties(){return {...y.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 [y.styles,M,z,_]}static register(t="auro-icon"){p.prototype.registerComponent(t,k);}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 b$1`
8661
- <div class="componentWrapper">
8662
- <div
8663
- class="${e$3({svgWrapper:true})}"
8664
- title="${o(this.title||void 0)}">
8665
- <span aria-hidden="${o(this.ariaHidden||true)}" part="svg">
8666
- ${this.customSvg?b$1`
8667
- <slot name="svg"></slot>
8668
- `:b$1`
8669
- ${this.svg}
8670
- `}
8671
- </span>
8672
- </div>
8673
-
8674
- <div class="${e$3(t)}" part="label">
8675
- <slot></slot>
8676
- </div>
8677
- </div>
8678
- `}}
8679
-
8680
- var iconVersion = '9.1.2';
8652
+ /* eslint-disable */
8681
8653
 
8682
- 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>"};
8654
+ class MenuService {
8683
8655
 
8684
- // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
8685
- // See LICENSE in the project root for license information.
8656
+ /**
8657
+ * PROPERTIES AND GETTERS
8658
+ */
8686
8659
 
8660
+ /**
8661
+ * Gets the list of registered menu options.
8662
+ * @returns {AuroMenuOption[]}
8663
+ */
8664
+ get menuOptions() {
8665
+ return this._menuOptions;
8666
+ }
8687
8667
 
8688
- /**
8689
- * Helper method to dispatch custom events.
8690
- * @param {HTMLElement} element - Element to dispatch event from.
8691
- * @param {string} eventName - Name of the event to dispatch.
8692
- * @param {Object} [detail] - Optional detail object to include with the event.
8693
- */
8694
- function dispatchMenuEvent(element, eventName, detail = null) {
8695
- const eventConfig = {
8696
- bubbles: true,
8697
- cancelable: false,
8698
- composed: true
8699
- };
8668
+ /**
8669
+ * Gets the currently highlighted option.
8670
+ * @returns {AuroMenuOption|null}
8671
+ */
8672
+ get highlightedOption() {
8673
+ return this._menuOptions[this.highlightedIndex] || null;
8674
+ }
8700
8675
 
8701
- if (detail !== null) {
8702
- eventConfig.detail = detail;
8676
+ /**
8677
+ * Gets the current value(s) of the selected option(s).
8678
+ * @returns {string|string[]|undefined}
8679
+ */
8680
+ get currentValue() {
8681
+ const values = (this.selectedOptions || []).map(option => option.value);
8682
+ return this.multiSelect ? values : values[0];
8703
8683
  }
8704
8684
 
8705
- element.dispatchEvent(new CustomEvent(eventName, eventConfig));
8706
- }
8685
+ /**
8686
+ * Gets the label(s) of the currently selected option(s).
8687
+ * @returns {string}
8688
+ */
8689
+ get currentLabel() {
8690
+ const labels = (this.selectedOptions || []).map(option => option.textContent);
8691
+ return this.multiSelect ? labels.join(", ") : labels[0] || '';
8692
+ }
8707
8693
 
8708
- // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
8709
- // See LICENSE in the project root for license information.
8694
+ /**
8695
+ * Gets the string representation of the current value(s).
8696
+ * For multi-select, this is a JSON stringified array.
8697
+ * @returns {string|undefined}
8698
+ */
8699
+ get stringValue() {
8700
+ const { currentValue } = this;
8710
8701
 
8702
+ if (Array.isArray(currentValue)) {
8703
+ if (currentValue.length > 0) {
8704
+ return JSON.stringify(currentValue);
8705
+ }
8706
+ return undefined;
8707
+ }
8711
8708
 
8712
- let menuOptionIdCounter = 0;
8709
+ if (typeof currentValue === 'string') {
8710
+ if (currentValue.length > 0) {
8711
+ return currentValue;
8712
+ }
8713
+ return undefined;
8714
+ }
8713
8715
 
8714
- /**
8715
- * The `auro-menuoption` element provides users a way to define a menu option.
8716
- * @customElement auro-menuoption
8717
- *
8718
- * @slot default - The default slot for the menu option text.
8719
- *
8720
- * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
8721
- */
8722
- class AuroMenuOption extends AuroElement$1 {
8716
+ // Future: handle other types here (e.g., number, object, etc.)
8717
+ return undefined;
8718
+ }
8723
8719
 
8724
8720
  /**
8725
- * This will register this element with the browser.
8726
- * @param {string} [name="auro-menuoption"] - The name of the element that you want to register.
8727
- *
8728
- * @example
8729
- * AuroMenuOption.register("custom-menuoption") // this will register this element to <custom-menuoption/>
8730
- *
8721
+ * Gets the key(s) of the currently selected option(s).
8722
+ * @returns {string|string[]|undefined}
8731
8723
  */
8732
- static register(name = "auro-menuoption") {
8733
- AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenuOption);
8724
+ get currentKeys() {
8725
+ const keys = (this.selectedOptions || []).map(option => option.key);
8726
+ return this.multiSelect ? keys : keys[0];
8734
8727
  }
8735
8728
 
8736
8729
  /**
8737
- * Returns whether the menu option is currently active and selectable.
8738
- * An option is considered active if it is not hidden, not disabled, and not static.
8739
- * @returns {boolean} True if the option is active, false otherwise.
8730
+ * CONSTRUCTOR
8740
8731
  */
8741
- get isActive() {
8742
- return !this.hasAttribute('hidden') &&
8743
- !this.disabled &&
8744
- !this.hasAttribute('static');
8745
- }
8746
8732
 
8747
- constructor() {
8748
- super();
8733
+ /**
8734
+ * Creates a new MenuService instance.
8735
+ * @param {Object} options - The options object.
8736
+ * @param {AuroMenu} options.host - The host element that this service will control. Required.
8737
+ * @throws {Error} If the host is not provided.
8738
+ */
8739
+ constructor({ host } = {}) {
8749
8740
 
8750
- this.bindEvents();
8741
+ // Ensure a host was passed
8742
+ if (!host) {
8743
+ throw new Error("MenuService requires a host element.");
8744
+ }
8751
8745
 
8752
- /**
8753
- * @private
8754
- */
8755
- this.shape = undefined;
8746
+ // Attach the service to the host
8747
+ this.host = host;
8748
+ this.host.addController(this);
8756
8749
 
8757
- /**
8758
- * @private
8759
- */
8750
+ // Set default properties
8760
8751
  this.size = undefined;
8752
+ this.shape = undefined;
8753
+ this.noCheckmark = undefined;
8754
+ this.disabled = undefined;
8755
+ this.matchWord = undefined;
8756
+ this.multiSelect = undefined;
8757
+ this.allowDeselect = undefined;
8758
+ this.selectAllMatchingOptions = undefined;
8761
8759
 
8762
- /**
8763
- * Generate unique names for dependency components.
8764
- */
8765
- const versioning = new AuroDependencyVersioning$2();
8766
- this.iconTag = versioning.generateTag('auro-formkit-menuoption-icon', iconVersion, k);
8760
+ this.highlightedIndex = -1;
8767
8761
 
8768
- this.selected = false;
8769
- this.noCheckmark = false;
8770
- this.disabled = false;
8771
- this.noMatch = false;
8762
+ this._menuOptions = [];
8763
+ this._subscribers = [];
8764
+ this.internalUpdateInProgress = false;
8765
+ this.selectedOptions = [];
8766
+ this._pendingValue = null;
8767
+ this._pendingRetryScheduled = false;
8768
+ this._pendingRetryCount = 0;
8769
+ }
8772
8770
 
8773
- /**
8774
- * @private
8775
- */
8776
- this.runtimeUtils = new AuroLibraryRuntimeUtils$3();
8771
+ /**
8772
+ * PROPERTY SYNCING
8773
+ */
8777
8774
 
8778
- // Initialize context-related properties
8779
- this.menuService = null;
8780
- this.unsubscribe = null;
8775
+ /**
8776
+ * Handles host updates.
8777
+ * This is a lit reactive lifecycle method.
8778
+ * This comes from the Lit controller interface provided by adding this service as a controller to the host.
8779
+ * See constructor for `this.host.addController(this)`
8780
+ * You can read more about Lit reactive controllers here: https://lit.dev/docs/composition/controllers/
8781
+ */
8782
+ hostUpdated() {
8781
8783
 
8782
- /**
8783
- * @private
8784
- */
8785
- this.handleMenuChange = this.handleMenuChange.bind(this);
8784
+ // Reset selection if multiSelect mode changes
8785
+ if (this.host.multiSelect !== this.multiSelect) {
8786
+ this.selectedOptions = [];
8787
+ }
8788
+
8789
+ // Update properties on host update
8790
+ this.setProperties({
8791
+ size: this.host.size,
8792
+ shape: this.host.shape,
8793
+ noCheckmark: this.host.noCheckmark,
8794
+ disabled: this.host.disabled,
8795
+ matchWord: this.host.matchWord,
8796
+ multiSelect: this.host.multiSelect,
8797
+ allowDeselect: this.host.allowDeselect,
8798
+ selectAllMatchingOptions: this.host.selectAllMatchingOptions
8799
+ });
8786
8800
  }
8787
8801
 
8788
- static get properties() {
8789
- return {
8790
- ...super.properties,
8802
+ /**
8803
+ * Handles host disconnection and memory cleanup.
8804
+ */
8805
+ hostDisconnected() {
8806
+ this._subscribers = [];
8807
+ this._menuOptions = [];
8808
+ this._pendingValue = null;
8809
+ this._pendingRetryScheduled = false;
8810
+ this._pendingRetryCount = 0;
8811
+ }
8791
8812
 
8792
- /**
8793
- * When true, disables the menu option.
8794
- */
8795
- disabled: {
8796
- type: Boolean,
8797
- reflect: true
8798
- },
8813
+ /**
8814
+ * Sets a property value if it exists on the instance and the value has changed.
8815
+ * @param {string} property
8816
+ * @param {any} value
8817
+ */
8818
+ setProperty(property, value) {
8799
8819
 
8800
- /**
8801
- * @private
8802
- */
8803
- event: {
8804
- type: String,
8805
- reflect: true
8806
- },
8807
-
8808
- /**
8809
- * @private
8810
- */
8811
- layout: {
8812
- type: String
8813
- },
8814
-
8815
- /**
8816
- * Allows users to set a unique key for the menu option for specified option selection. If no key is provided, the value property will be used.
8817
- */
8818
- key: {
8819
- type: String,
8820
- reflect: true
8821
- },
8822
-
8823
- /**
8824
- * @private
8825
- */
8826
- menuService: {
8827
- type: Object,
8828
- state: true
8829
- },
8830
-
8831
- /**
8832
- * @private
8833
- */
8834
- matchWord: {
8835
- type: String,
8836
- state: true
8837
- },
8838
-
8839
- /**
8840
- * @private
8841
- */
8842
- noCheckmark: {
8843
- type: Boolean,
8844
- reflect: true
8845
- },
8846
-
8847
- /**
8848
- * When true, marks this option as the "no matching results" placeholder shown by combobox when the user's input does not match any available options. Enables distinct styling and prevents the option from being treated as a selectable match.
8849
- */
8850
- noMatch: {
8851
- type: Boolean,
8852
- reflect: true,
8853
- attribute: 'nomatch'
8854
- },
8855
-
8856
- /**
8857
- * Specifies that an option is selected.
8858
- */
8859
- selected: {
8860
- type: Boolean,
8861
- reflect: true
8862
- },
8820
+ // Only update if we are tracking the property in this service
8821
+ if (this.hasOwnProperty(property)) {
8863
8822
 
8864
- /**
8865
- * Specifies the tab index of the menu option.
8866
- */
8867
- tabIndex: {
8868
- type: Number,
8869
- reflect: true
8870
- },
8823
+ // Check if the value has changed
8824
+ const valueChanged = this[property] !== value;
8871
8825
 
8872
- /**
8873
- * Specifies the value to be sent to a server.
8874
- */
8875
- value: {
8876
- type: String,
8877
- reflect: true
8878
- },
8879
- };
8826
+ // Update and notify if changed
8827
+ if (valueChanged) {
8828
+ this[property] = value;
8829
+ this.notify({ property, value });
8830
+ }
8831
+ }
8880
8832
  }
8881
8833
 
8882
- static get styles() {
8883
- return [
8884
- styleCss,
8885
- colorCss,
8886
- tokensCss
8887
- ];
8834
+ /**
8835
+ * Sets multiple properties on the instance.
8836
+ * @param {Object} properties - Key-value pairs of properties to set.
8837
+ */
8838
+ setProperties(properties) {
8839
+ for (const [key, value] of Object.entries(properties)) {
8840
+ this.setProperty(key, value);
8841
+ }
8888
8842
  }
8889
8843
 
8890
- connectedCallback() {
8891
- super.connectedCallback();
8892
-
8893
- // Add the tag name as an attribute if it is different than the component name
8894
- // Add this step soon as this node gets attached to the DOM to avoid racing condition with menu's value setting logic.
8895
- this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
8844
+ /**
8845
+ * MENU OPTION HIGHLIGHTING
8846
+ */
8896
8847
 
8897
- // Set up context consumption in connectedCallback
8898
- this._contextConsumer = new s$1(this, {
8899
- context: MenuContext,
8900
- callback: this.attachTo.bind(this),
8901
- subscribe: true
8902
- });
8848
+ /**
8849
+ * Highlights the next active option in the menu.
8850
+ */
8851
+ highlightNext() {
8852
+ this.moveHighlightedOption("next");
8853
+ }
8903
8854
 
8904
- // Establish the key property as early as possible.
8905
- // When a framework (e.g. Svelte) inserts the element into the DOM before
8906
- // setting its `value` property, both `getAttribute('value')` and
8907
- // `getAttribute('key')` return null here. Setting `this.key = null`
8908
- // would block the fallback in `updated()` that assigns key from the
8909
- // value property (the guard checked `=== undefined`). Only assign key
8910
- // if at least one source attribute is actually present so that the
8911
- // `updated()` fallback can run when the value property arrives later.
8912
- const valueAttr = this.getAttribute('value');
8913
- const keyAttr = this.getAttribute('key');
8914
- const resolvedKey = keyAttr !== null ? keyAttr : valueAttr;
8915
- if (resolvedKey !== null) {
8916
- this.key = resolvedKey;
8917
- }
8855
+ /**
8856
+ * Highlights the previous active option in the menu.
8857
+ */
8858
+ highlightPrevious() {
8859
+ this.moveHighlightedOption("previous");
8918
8860
  }
8919
8861
 
8920
- firstUpdated() {
8921
- // Add the tag name as an attribute if it is different than the component name
8922
- this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
8862
+ /**
8863
+ * Moves the highlighted option in the specified direction.
8864
+ * @param {string} direction - The direction to move the highlight ("next" or "previous").
8865
+ */
8866
+ moveHighlightedOption(direction) {
8923
8867
 
8924
- // Generate unique ID if not already set (required for aria-activedescendant)
8925
- if (!this.id) {
8926
- menuOptionIdCounter += 1;
8927
- this.id = `menuoption-${menuOptionIdCounter}`;
8928
- }
8868
+ // Get the active options
8869
+ const activeOptions = this._menuOptions.filter(option => option.isActive);
8929
8870
 
8930
- this.setAttribute('role', 'option');
8931
- this.setAttribute('aria-selected', 'false');
8871
+ // Get the currently active option
8872
+ const currentActiveOption = activeOptions[activeOptions.indexOf(this.highlightedOption)];
8932
8873
 
8933
- this.addEventListener('mouseover', () => {
8934
- this.dispatchEvent(new CustomEvent('auroMenuOption-mouseover', {
8935
- bubbles: true,
8936
- cancelable: false,
8937
- composed: true,
8938
- detail: this
8939
- }));
8940
- });
8941
- }
8874
+ // Determine the new index based on the currently active option and direction
8875
+ let newIndex = currentActiveOption
8876
+ ? direction === "previous"
8877
+ ? activeOptions.indexOf(currentActiveOption) - 1
8878
+ : activeOptions.indexOf(currentActiveOption) + 1
8879
+ : direction === "previous"
8880
+ ? activeOptions.length - 1
8881
+ : 0;
8942
8882
 
8943
- updated(changedProperties) {
8944
- super.updated(changedProperties);
8883
+ // Wrap around the index if needed
8884
+ newIndex = newIndex < 0 ? activeOptions.length - 1 : newIndex >= activeOptions.length ? 0 : newIndex;
8945
8885
 
8946
- // Update aria-selected attribute if selected changed
8947
- if (changedProperties.has('selected')) {
8886
+ // Get the new active option and set it as highlighted
8887
+ const newActiveOption = activeOptions[newIndex];
8888
+ this.setHighlightedOption(newActiveOption);
8889
+ }
8948
8890
 
8949
- // Update aria-selected attribute
8950
- this.setAttribute('aria-selected', this.selected.toString());
8891
+ /**
8892
+ * Sets the highlighted index to the specified option.
8893
+ * @param {AuroMenuOption} option - The option to highlight.
8894
+ */
8895
+ setHighlightedOption(option) {
8951
8896
 
8952
- // Update menu service selection state if this isn't an internal update
8953
- if (this.internalUpdateInProgress !== true && this.menuService) {
8954
- this.menuService[this.selected ? 'selectOption' : 'deselectOption'](this);
8955
- }
8956
- }
8897
+ if (!option) return;
8957
8898
 
8958
- if (changedProperties.has('disabled')) {
8959
- if (this.disabled) {
8960
- this.setAttribute('aria-disabled', 'true');
8961
- } else {
8962
- this.removeAttribute('aria-disabled');
8963
- }
8964
- }
8899
+ // Get the index of the option to highlight
8900
+ const index = this._menuOptions.indexOf(option);
8965
8901
 
8966
- if (changedProperties.has('active')) {
8967
- this.updateActiveClasses();
8968
- }
8902
+ // Update highlighted index
8903
+ this.highlightedIndex = index;
8969
8904
 
8970
- // Update text highlight if matchWord changed
8971
- if (changedProperties.has('matchWord')) {
8972
- this.updateTextHighlight();
8973
- }
8905
+ // Notify subscribers of highlight change
8906
+ this.notify({ type: 'highlightChange', option, index: this.highlightedIndex });
8974
8907
 
8975
- // Set the key to be the passed value if no key is provided.
8976
- // Loose equality (== null) is intentional: it catches both null AND
8977
- // undefined. When a framework (e.g. Svelte, React) inserts the element
8978
- // before setting its value property, connectedCallback skips key
8979
- // assignment because both attributes are null at that point. The Lit
8980
- // property default for `key` is undefined (not null), so strict
8981
- // === null would miss the case and the fallback would never run.
8982
- if (changedProperties.has('value') && this.key == null) { // eslint-disable-line eqeqeq, no-eq-null
8983
- this.key = this.value;
8984
- }
8908
+ // Dispatch the change event
8909
+ this.dispatchChangeEvent('auroMenu-activatedOption', option);
8985
8910
  }
8986
8911
 
8987
- disconnectedCallback() {
8988
- if (this.menuService) {
8989
- this.menuService.unsubscribe(this.handleMenuChange);
8990
- this.menuService.removeMenuOption(this);
8991
- }
8912
+ /**
8913
+ * Sets the highlighted option to the option at the specified index if it exists.
8914
+ * @param {number} index
8915
+ */
8916
+ setHighlightedIndex(index) {
8917
+ const option = this._menuOptions[index] || null;
8918
+ this.setHighlightedOption(option);
8992
8919
  }
8993
8920
 
8994
8921
  /**
8995
- * Sets up event listeners for user interaction with the menu option.
8996
- * This function enables click and mouse enter events to trigger selection and highlighting logic.
8922
+ * Selects the currently highlighted option.
8997
8923
  */
8998
- bindEvents() {
8999
- this.addEventListener('click', this.handleClick.bind(this));
9000
- this.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
8924
+ selectHighlightedOption() {
8925
+ if (this.highlightedOption) {
8926
+ this.toggleOption(this.highlightedOption);
8927
+ }
9001
8928
  }
9002
8929
 
9003
8930
  /**
9004
- * Attaches this menu option to a menu service and subscribes to its events.
9005
- * This method enables the option to participate in menu selection and highlighting logic.
9006
- * @param {Object} service - The menu service instance to attach to.
8931
+ * SELECTION AND DESELECTION METHODS
9007
8932
  */
9008
- attachTo(service) {
9009
- if (!service) {
9010
- return;
9011
- }
9012
- this.menuService = service;
9013
- this.menuService.addMenuOption(this);
9014
- this.menuService.subscribe(this.handleMenuChange);
9015
- }
9016
8933
 
9017
8934
  /**
9018
- * Handles changes from the menu service and updates the option's state.
9019
- * This function synchronizes the option's properties and selection/highlight state with menu events.
9020
- * @param {Object} event - The event object from the menu service.
8935
+ * Selects one or more options in a batch operation
8936
+ * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to select
9021
8937
  */
9022
- handleMenuChange(event) {
8938
+ selectOptions(options) {
8939
+ let optionsToSelect = Array.isArray(options) ? options : [options];
9023
8940
 
9024
- // Ignore events without a type or property
9025
- if (!event || (!event.type && !event.property)) {
9026
- return;
9027
- }
8941
+ // Filter out options that are inactive
8942
+ optionsToSelect = optionsToSelect.filter(option => option.isActive);
9028
8943
 
9029
- // Update reactive properties based on event type
9030
- if (event.property && Object.keys(AuroMenuOption.properties).includes(event.property)) {
9031
- this[event.property] = event.value;
9032
- }
8944
+ if (!optionsToSelect.length) return;
9033
8945
 
9034
- // Handle highlight changes
9035
- if (event.type === 'highlightChange') {
9036
- const isActive = event.option === this;
9037
- this.active = isActive;
9038
- this.updateActiveClasses();
8946
+ if (this.multiSelect) {
8947
+ this.selectedOptions = [...(this.selectedOptions || []), ...optionsToSelect];
8948
+ } else {
8949
+ // In single select mode, only take the last option
8950
+ this.selectedOptions = [optionsToSelect[optionsToSelect.length - 1]];
9039
8951
  }
9040
8952
 
9041
- if (event.type === 'stateChange') {
9042
- const isSelected = event.selectedOptions.includes(this);
9043
- this.setInternalSelected(isSelected);
9044
- }
8953
+ this.stageUpdate();
9045
8954
  }
9046
8955
 
9047
8956
  /**
9048
- * Updates the internal selected state of the menu option bypassing 'updated' and triggers custom events if selected.
9049
- * This function ensures the option's selection state is synchronized with menu logic and notifies listeners.
9050
- * @param {boolean} isSelected - Whether the option should be marked as selected.
8957
+ * Deselects one or more options in a batch operation
8958
+ * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to deselect
9051
8959
  */
9052
- setInternalSelected(isSelected) {
9053
- this.internalUpdateInProgress = true;
9054
- this.selected = isSelected;
8960
+ deselectOptions(options) {
8961
+ const optionsToDeselect = Array.isArray(options) ? options : [options];
9055
8962
 
9056
- // Fire custom event if selected
9057
- if (isSelected) {
9058
- this.handleCustomEvent();
8963
+ if (!optionsToDeselect.length) return;
8964
+
8965
+ // Check if deselection should be prevented
8966
+ const shouldPreventDeselect = !this.allowDeselect && !this.multiSelect;
8967
+ const isOnlySelectedOption = this.selectedOptions.length === 1 && optionsToDeselect.includes(this.selectedOptions[0]);
8968
+
8969
+ // Prevent deselecting the only selected option if not allowed
8970
+ if (shouldPreventDeselect && isOnlySelectedOption) {
8971
+ optionsToDeselect.forEach(option => {
8972
+ option.selected = true;
8973
+ });
8974
+ this.dispatchChangeEvent('auroMenu-deselectPrevented', {
8975
+ values: optionsToDeselect
8976
+ });
8977
+ return;
9059
8978
  }
9060
8979
 
9061
- setTimeout(() => {
9062
- this.internalUpdateInProgress = false;
9063
- }, 0);
8980
+ const optionsSet = new Set(optionsToDeselect);
8981
+ const previousCount = this.selectedOptions.length;
8982
+ this.selectedOptions = (this.selectedOptions || [])
8983
+ .filter(opt => !optionsSet.has(opt));
8984
+
8985
+ if (this.selectedOptions.length < previousCount) {
8986
+ this.stageUpdate();
8987
+ }
9064
8988
  }
9065
8989
 
9066
8990
  /**
9067
- * Sets the selected state of the menu option.
9068
- * This function updates whether the option is currently selected.
9069
- * @param {boolean} isSelected - Whether the option should be marked as selected.
9070
- * @deprecated Simply modify the `selected` property directly instead.
8991
+ * Selects a single option.
8992
+ * @param {AuroMenuOption} option
9071
8993
  */
9072
- setSelected(isSelected) {
9073
- this.selected = isSelected;
8994
+ selectOption(option) {
8995
+ this.selectOptions(option);
9074
8996
  }
9075
8997
 
9076
8998
  /**
9077
- * Updates the active state and visual highlighting of the menu option.
9078
- * This function toggles the option's active status and applies or removes the active CSS class.
9079
- * @param {boolean} isActive - Whether the option should be marked as active.
9080
- * @deprecated Simply modify the `active` property directly instead.
8999
+ * Deselects a single option.
9000
+ * @param {AuroMenuOption} option
9081
9001
  */
9082
- updateActive(isActive) {
9083
-
9084
- // Set active state
9085
- this.active = isActive;
9086
- this.updateActiveClasses();
9002
+ deselectOption(option) {
9003
+ this.deselectOptions(option);
9087
9004
  }
9088
9005
 
9089
9006
  /**
9090
- * Updates the CSS class for the menu option based on its active state.
9091
- * This function adds or removes the 'active' class to visually indicate the option's active status.
9092
- * @private
9007
+ * Toggles the selection state of a single option.
9008
+ * @param {AuroMenuOption} option
9093
9009
  */
9094
- updateActiveClasses() {
9095
- // Update class based on active state
9096
- if (this.active) this.classList.add('active');
9097
- else this.classList.remove('active');
9010
+ toggleOption(option) {
9011
+ if (option.selected) {
9012
+ this.deselectOption(option);
9013
+ } else {
9014
+ this.selectOption(option);
9015
+ }
9098
9016
  }
9099
9017
 
9100
-
9101
9018
  /**
9102
- * Updates the visual highlighting of text within the menu option based on the current match word.
9103
- * This function highlights matching text segments and manages nested spacers for display formatting.
9104
- * @private
9019
+ * Selects options based on their value(s) when compared to a passed value or values.
9020
+ * Value or values are normalized to an array of strings that can be matched to option keys.
9021
+ * @param {string|number|Array<string|number>} value - The value(s) to select.
9105
9022
  */
9106
- updateTextHighlight() {
9023
+ selectByValue(value) {
9024
+ const isEmptyValue = value === undefined ||
9025
+ value === null ||
9026
+ (Array.isArray(value) && value.length === 0) ||
9027
+ (typeof value === 'string' && value.trim() === '');
9107
9028
 
9108
- // Regex for matchWord if needed
9109
- let regexWord = null;
9029
+ // Early exit for invalid/empty values
9030
+ if (isEmptyValue) {
9031
+ this.selectedOptions.forEach(opt => opt.selected = false);
9032
+ this.selectedOptions = [];
9033
+ return;
9034
+ }
9110
9035
 
9111
- if (this.matchWord && this.matchWord.length) {
9112
- const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
9113
- regexWord = new RegExp(escapedWord, 'giu');
9036
+ // If an internal update cycle is still in progress, defer value application
9037
+ // rather than dropping it.
9038
+ if (this.internalUpdateInProgress || this.host.internalUpdateInProgress) {
9039
+ this.queuePendingValue(value);
9040
+ return;
9114
9041
  }
9115
9042
 
9116
- // Update text highlighting if matchWord changed
9117
- if (regexWord &&
9118
- this.isActive && !this.hasAttribute('persistent')) {
9119
- const nested = this.querySelectorAll('.nestingSpacer');
9043
+ // Normalize values to array of strings
9044
+ const normalizedValues = this._getNormalizedValues(value);
9120
9045
 
9121
- const displayValueEl = this.querySelector('[slot="displayValue"]');
9122
- if (displayValueEl) {
9123
- this.removeChild(displayValueEl);
9046
+ // Validate for single-select mode
9047
+ let validatedValues = normalizedValues;
9048
+ if (normalizedValues.length > 1 && !this.multiSelect) {
9049
+ console.warn("MenuService - Multiple values provided for single-select menu. Only the first value will be selected.");
9050
+ validatedValues = [normalizedValues[0]];
9051
+ }
9052
+
9053
+ if (this._menuOptions.length === 0) {
9054
+ this.queuePendingValue(value);
9055
+ return;
9056
+ }
9057
+
9058
+ // Find matching options by comparing available options to validated values
9059
+ const trackedKeys = new Set();
9060
+ const optionsToSelect = this._menuOptions.filter(option => {
9061
+ const passesFilter = validatedValues.includes(option.key);
9062
+ const alreadyTracked = trackedKeys.has(option.key);
9063
+ const isActive = option.isActive;
9064
+
9065
+ trackedKeys.add(option.key);
9066
+
9067
+ // Include the option in the options to be selected if it passes the filter check and
9068
+ // either hasn't been tracked yet or selectAllMatchingOptions is true
9069
+ return isActive && passesFilter && (!alreadyTracked || (alreadyTracked && this.selectAllMatchingOptions));
9070
+ });
9071
+
9072
+ // Handle no matches: clear existing selection, but do not dispatch an intermediate
9073
+ // undefined value that can overwrite the host value in parent components.
9074
+ if (!optionsToSelect.length) {
9075
+ const hasUnresolvedKeys = this._menuOptions.some((option) => option.isActive && option.key == null);
9076
+
9077
+ if (hasUnresolvedKeys) {
9078
+ this.queuePendingValue(value);
9079
+ return;
9124
9080
  }
9125
9081
 
9126
- // Create nested spacers
9127
- const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
9082
+ this.clearPendingValue();
9128
9083
 
9129
- // Update with spacers and matchWord
9130
- this.innerHTML = nestingSpacerBundle +
9131
- this.textContent.replace(
9132
- regexWord,
9133
- (match) => `<strong>${match}</strong>`
9134
- );
9135
- if (displayValueEl) {
9136
- this.append(displayValueEl);
9084
+ if (this.selectedOptions.length > 0) {
9085
+ this.selectedOptions = [];
9137
9086
  }
9138
- }
9139
- }
9140
9087
 
9141
- /**
9142
- * Handles click events on the menu option, toggling its selected state.
9143
- * This function dispatches a click event and updates selection if the option is not disabled.
9144
- * @private
9145
- */
9146
- handleClick() {
9147
- if (!this.disabled) {
9148
- this.dispatchClickEvent();
9149
- this.selected = !this.selected;
9088
+ // Always notify so the host resets any stale invalid value, even when
9089
+ // selectedOptions was already empty (e.g. double-clicking set-invalid).
9090
+ this.stageUpdate({ reason: 'no-match' });
9091
+
9092
+ // Dispatch failure event if no matches found
9093
+ if (validatedValues.length) {
9094
+ this.dispatchChangeEvent('auroMenu-selectValueFailure', {
9095
+ message: 'No matching options found for the provided value(s).',
9096
+ values: validatedValues
9097
+ });
9098
+ }
9099
+
9100
+ return;
9150
9101
  }
9151
- }
9152
9102
 
9153
- /**
9154
- * Handles mouse enter events to highlight the menu option.
9155
- * This function updates the menu service to set this option as the currently highlighted item if not disabled.
9156
- * @private
9157
- */
9158
- handleMouseEnter() {
9159
- if (!this.disabled) {
9160
- this.menuService.setHighlightedOption(this);
9103
+ this.clearPendingValue();
9104
+
9105
+ if (this.optionsArraysMatch(optionsToSelect, this.selectedOptions)) {
9106
+ return;
9161
9107
  }
9108
+
9109
+ // Apply programmatic selection as a single transaction and emit one final state.
9110
+ this.selectedOptions = optionsToSelect;
9111
+ this.stageUpdate();
9162
9112
  }
9163
9113
 
9164
9114
  /**
9165
- * Dispatches custom events defined for this menu option.
9166
- * This function notifies listeners when a custom event is triggered by the option.
9167
- * @private
9115
+ * Queues a pending value and schedules a bounded retry.
9116
+ * @param {string|number|Array<string|number>} value - The value to retry.
9168
9117
  */
9169
- handleCustomEvent() {
9170
- if (this.event) {
9171
- dispatchMenuEvent(this, this.event, { option: this });
9172
- dispatchMenuEvent(this, 'auroMenu-customEventFired', { option: this });
9173
- }
9174
- }
9118
+ queuePendingValue(value) {
9119
+ this._pendingValue = value;
9175
9120
 
9176
- /**
9177
- * Dispatches a click event for this menu option.
9178
- * This function notifies listeners that the option has been clicked.
9179
- * @private
9180
- */
9181
- dispatchClickEvent() {
9182
- this.dispatchEvent(new CustomEvent('auroMenuOption-click', {
9183
- bubbles: true,
9184
- cancelable: false,
9185
- composed: true,
9186
- detail: this
9187
- }));
9188
- }
9121
+ if (this._pendingRetryScheduled || this._pendingRetryCount >= 5) {
9122
+ return;
9123
+ }
9189
9124
 
9190
- /**
9191
- * Generates an HTML element containing an SVG icon based on the provided `svgContent`.
9192
- *
9193
- * @private
9194
- * @param {string} svgContent - The SVG content to be embedded.
9195
- * @returns {Element} The HTML element containing the SVG icon.
9196
- */
9197
- generateIconHtml(svgContent) {
9198
- const dom = new DOMParser().parseFromString(svgContent, 'text/html');
9199
- const svg = dom.body.firstChild;
9125
+ this._pendingRetryScheduled = true;
9126
+ this._pendingRetryCount += 1;
9200
9127
 
9201
- svg.setAttribute('slot', 'svg');
9128
+ setTimeout(() => {
9129
+ this._pendingRetryScheduled = false;
9202
9130
 
9203
- return u$4`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
9131
+ if (this._pendingValue == null) {
9132
+ return;
9133
+ }
9134
+
9135
+ const pendingValue = this._pendingValue;
9136
+ this.selectByValue(pendingValue);
9137
+ }, 0);
9204
9138
  }
9205
9139
 
9206
9140
  /**
9207
- * Logic to determine the layout of the component.
9208
- * @protected
9209
- * @returns {void}
9141
+ * Clears pending retry state.
9210
9142
  */
9211
- renderLayout() {
9212
-
9213
- const fontClassMap = {
9214
- xs: 'body-sm',
9215
- sm: 'body-default',
9216
- md: 'body-default',
9217
- lg: 'body-lg',
9218
- xl: 'body-lg'
9219
- };
9143
+ clearPendingValue() {
9144
+ this._pendingValue = null;
9145
+ this._pendingRetryScheduled = false;
9146
+ this._pendingRetryCount = 0;
9147
+ }
9220
9148
 
9221
- const classes = e$3({
9222
- 'wrapper': true,
9223
- [this.size ? fontClassMap[this.size] : 'body-sm']: true,
9224
- });
9149
+ /**
9150
+ * Resets the selected options to an empty array.
9151
+ */
9152
+ reset() {
9153
+ const previousOptions = [...this.selectedOptions];
9154
+ previousOptions.forEach(opt => opt.selected = false);
9155
+ this.selectedOptions = [];
9225
9156
 
9226
- return u$4`
9227
- <div class="${classes}">
9228
- ${this.selected && !this.noCheckmark
9229
- ? this.generateIconHtml(checkmarkIcon.svg)
9230
- : undefined}
9231
- <slot></slot>
9232
- </div>
9233
- `;
9157
+ // Single update after clearing all
9158
+ if (previousOptions.length) {
9159
+ this.stageUpdate();
9160
+ }
9234
9161
  }
9235
- }
9236
9162
 
9237
- /* eslint-disable */
9238
-
9239
- class MenuService {
9163
+ /**
9164
+ * SUBSCRIPTION, NOTIFICATION AND EVENT DISPATCH METHODS
9165
+ */
9240
9166
 
9241
9167
  /**
9242
- * PROPERTIES AND GETTERS
9168
+ * Subscribes a callback to menu service events.
9169
+ * @param {Function} callback - The callback to invoke on events.
9243
9170
  */
9171
+ subscribe(callback) {
9172
+ this._subscribers.push(callback);
9173
+ }
9244
9174
 
9245
9175
  /**
9246
- * Gets the list of registered menu options.
9247
- * @returns {AuroMenuOption[]}
9176
+ * Remove a previously subscribed callback from menu service events.
9177
+ * @param {Function} callback
9248
9178
  */
9249
- get menuOptions() {
9250
- return this._menuOptions;
9179
+ unsubscribe(callback) {
9180
+ this._subscribers = this._subscribers.filter(cb => cb !== callback);
9251
9181
  }
9252
9182
 
9253
9183
  /**
9254
- * Gets the currently highlighted option.
9255
- * @returns {AuroMenuOption|null}
9184
+ * Stages an update to notify subscribers of state and value changes.
9256
9185
  */
9257
- get highlightedOption() {
9258
- return this._menuOptions[this.highlightedIndex] || null;
9186
+ stageUpdate(meta = {}) {
9187
+ this.notifyStateChange(meta);
9188
+ this.notifyValueChange(meta);
9259
9189
  }
9260
9190
 
9261
9191
  /**
9262
- * Gets the current value(s) of the selected option(s).
9263
- * @returns {string|string[]|undefined}
9192
+ * Notifies subscribers of a menu service event.
9193
+ * All notifications are sent to all subscribers.
9194
+ * @param {string} event - The event to send to subscribers.
9264
9195
  */
9265
- get currentValue() {
9266
- const values = (this.selectedOptions || []).map(option => option.value);
9267
- return this.multiSelect ? values : values[0];
9196
+ notify(event) {
9197
+ this._subscribers.forEach(callback => callback(event));
9268
9198
  }
9269
9199
 
9270
9200
  /**
9271
- * Gets the label(s) of the currently selected option(s).
9272
- * @returns {string}
9201
+ * Notifies subscribers of a state change (selected options has changed).
9273
9202
  */
9274
- get currentLabel() {
9275
- const labels = (this.selectedOptions || []).map(option => option.textContent);
9276
- return this.multiSelect ? labels.join(", ") : labels[0] || '';
9203
+ notifyStateChange(meta = {}) {
9204
+ this.notify({
9205
+ type: 'stateChange',
9206
+ selectedOptions: this.selectedOptions,
9207
+ ...meta
9208
+ });
9277
9209
  }
9278
9210
 
9279
9211
  /**
9280
- * Gets the string representation of the current value(s).
9281
- * For multi-select, this is a JSON stringified array.
9282
- * @returns {string|undefined}
9212
+ * Notifies subscribers of a value change (current value has changed).
9283
9213
  */
9284
- get stringValue() {
9285
- const { currentValue } = this;
9214
+ notifyValueChange(meta = {}) {
9286
9215
 
9287
- if (Array.isArray(currentValue)) {
9288
- if (currentValue.length > 0) {
9289
- return JSON.stringify(currentValue);
9290
- }
9291
- return undefined;
9292
- }
9216
+ // Prepare details for the event
9217
+ const details = {
9218
+ value: this.currentValue,
9219
+ stringValue: this.stringValue,
9220
+ keys: this.currentKeys,
9221
+ options: this.selectedOptions,
9222
+ label: this.currentLabel
9223
+ };
9293
9224
 
9294
- if (typeof currentValue === 'string') {
9295
- if (currentValue.length > 0) {
9296
- return currentValue;
9297
- }
9298
- return undefined;
9299
- }
9225
+ // If only one option is selected, include its index
9226
+ if (this.selectedOptions.length === 1) details.index = this._menuOptions.indexOf(this.selectedOptions[0]);
9300
9227
 
9301
- // Future: handle other types here (e.g., number, object, etc.)
9302
- return undefined;
9228
+ this.notify({
9229
+ type: 'valueChange',
9230
+ ...meta,
9231
+ ...details
9232
+ });
9303
9233
  }
9304
9234
 
9305
9235
  /**
9306
- * Gets the key(s) of the currently selected option(s).
9307
- * @returns {string|string[]|undefined}
9236
+ * Dispatches a custom event from the host element.
9237
+ * @param {string} eventName
9238
+ * @param {any} detail
9308
9239
  */
9309
- get currentKeys() {
9310
- const keys = (this.selectedOptions || []).map(option => option.key);
9311
- return this.multiSelect ? keys : keys[0];
9240
+ dispatchChangeEvent(eventName, detail) {
9241
+ this.host.dispatchEvent(new CustomEvent(eventName, {
9242
+ bubbles: true,
9243
+ cancelable: false,
9244
+ composed: true,
9245
+ detail
9246
+ }));
9312
9247
  }
9313
9248
 
9314
9249
  /**
9315
- * CONSTRUCTOR
9250
+ * MENU OPTION MANAGEMENT METHODS
9316
9251
  */
9317
9252
 
9318
9253
  /**
9319
- * Creates a new MenuService instance.
9320
- * @param {Object} options - The options object.
9321
- * @param {AuroMenu} options.host - The host element that this service will control. Required.
9322
- * @throws {Error} If the host is not provided.
9254
+ * Adds a menu option to the service's list.
9255
+ * @param {AuroMenuOption} option - the option to track
9323
9256
  */
9324
- constructor({ host } = {}) {
9257
+ addMenuOption(option) {
9258
+ this._menuOptions.push(option);
9259
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
9325
9260
 
9326
- // Ensure a host was passed
9327
- if (!host) {
9328
- throw new Error("MenuService requires a host element.");
9261
+ if (this._pendingValue != null) {
9262
+ this.queuePendingValue(this._pendingValue);
9329
9263
  }
9264
+ }
9330
9265
 
9331
- // Attach the service to the host
9332
- this.host = host;
9333
- this.host.addController(this);
9334
-
9335
- // Set default properties
9336
- this.size = undefined;
9337
- this.shape = undefined;
9338
- this.noCheckmark = undefined;
9339
- this.disabled = undefined;
9340
- this.matchWord = undefined;
9341
- this.multiSelect = undefined;
9342
- this.allowDeselect = undefined;
9343
- this.selectAllMatchingOptions = undefined;
9344
-
9345
- this.highlightedIndex = -1;
9266
+ /**
9267
+ * Removes a menu option from the service's list.
9268
+ * @param {AuroMenuOption} option - the option to remove
9269
+ */
9270
+ removeMenuOption(option) {
9271
+ this._menuOptions = this._menuOptions.filter(opt => opt !== option);
9272
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
9346
9273
 
9347
- this._menuOptions = [];
9348
- this._subscribers = [];
9349
- this.internalUpdateInProgress = false;
9350
- this.selectedOptions = [];
9351
- this._pendingValue = null;
9352
- this._pendingRetryScheduled = false;
9353
- this._pendingRetryCount = 0;
9274
+ if (this._menuOptions.length === 0) {
9275
+ this.clearPendingValue();
9276
+ }
9354
9277
  }
9355
9278
 
9356
9279
  /**
9357
- * PROPERTY SYNCING
9280
+ * UTILITIES
9358
9281
  */
9359
9282
 
9360
9283
  /**
9361
- * Handles host updates.
9362
- * This is a lit reactive lifecycle method.
9363
- * This comes from the Lit controller interface provided by adding this service as a controller to the host.
9364
- * See constructor for `this.host.addController(this)`
9365
- * You can read more about Lit reactive controllers here: https://lit.dev/docs/composition/controllers/
9284
+ * Normalizes a value or array of values into an array of strings for option selection.
9285
+ * This function ensures that input values are consistently formatted for matching menu options.
9286
+ *
9287
+ * @param {string|number|Array<string|number>} value - The value(s) to normalize.
9288
+ * @returns {Array<string>} An array of string values suitable for option matching.
9289
+ * @throws {Error} If any value is not a string or number.
9366
9290
  */
9367
- hostUpdated() {
9291
+ _getNormalizedValues(value) {
9292
+ let values = value;
9368
9293
 
9369
- // Reset selection if multiSelect mode changes
9370
- if (this.host.multiSelect !== this.multiSelect) {
9371
- this.selectedOptions = [];
9372
- }
9294
+ // Handle JSON string and single value string input
9295
+ if (!Array.isArray(values) && typeof values === 'string') {
9373
9296
 
9374
- // Update properties on host update
9375
- this.setProperties({
9376
- size: this.host.size,
9377
- shape: this.host.shape,
9378
- noCheckmark: this.host.noCheckmark,
9379
- disabled: this.host.disabled,
9380
- matchWord: this.host.matchWord,
9381
- multiSelect: this.host.multiSelect,
9382
- allowDeselect: this.host.allowDeselect,
9383
- selectAllMatchingOptions: this.host.selectAllMatchingOptions
9384
- });
9385
- }
9297
+ // Attempt to parse as JSON array
9298
+ try {
9386
9299
 
9387
- /**
9388
- * Handles host disconnection and memory cleanup.
9389
- */
9390
- hostDisconnected() {
9391
- this._subscribers = [];
9392
- this._menuOptions = [];
9393
- this._pendingValue = null;
9394
- this._pendingRetryScheduled = false;
9395
- this._pendingRetryCount = 0;
9396
- }
9300
+ // Normalize single quotes to double quotes for JSON parsing
9301
+ // This will not handle complex cases but will cover basic usage
9302
+ const parseValue = values.replace(/'([^']*?)'/g, '"$1"');
9397
9303
 
9398
- /**
9399
- * Sets a property value if it exists on the instance and the value has changed.
9400
- * @param {string} property
9401
- * @param {any} value
9402
- */
9403
- setProperty(property, value) {
9304
+ // Attempt parse
9305
+ const parsed = JSON.parse(parseValue);
9404
9306
 
9405
- // Only update if we are tracking the property in this service
9406
- if (this.hasOwnProperty(property)) {
9307
+ // Ensure parsed value is an array
9308
+ if (!Array.isArray(parsed)) throw new Error('Not an array');
9407
9309
 
9408
- // Check if the value has changed
9409
- const valueChanged = this[property] !== value;
9310
+ // Set values to parsed array
9311
+ values = parsed;
9312
+ } catch (err) {
9410
9313
 
9411
- // Update and notify if changed
9412
- if (valueChanged) {
9413
- this[property] = value;
9414
- this.notify({ property, value });
9314
+ // If parsing fails, treat as single value
9315
+ values = [value];
9415
9316
  }
9416
9317
  }
9417
- }
9418
9318
 
9419
- /**
9420
- * Sets multiple properties on the instance.
9421
- * @param {Object} properties - Key-value pairs of properties to set.
9422
- */
9423
- setProperties(properties) {
9424
- for (const [key, value] of Object.entries(properties)) {
9425
- this.setProperty(key, value);
9319
+ // Handle a single number being passed
9320
+ if (typeof values === 'number') {
9321
+ values = [String(values)];
9426
9322
  }
9427
- }
9428
9323
 
9429
- /**
9430
- * MENU OPTION HIGHLIGHTING
9431
- */
9324
+ // Coerce each value to string and validate types
9325
+ values.forEach((val, index) => {
9432
9326
 
9433
- /**
9434
- * Highlights the next active option in the menu.
9435
- */
9436
- highlightNext() {
9437
- this.moveHighlightedOption("next");
9438
- }
9327
+ // Throw an error for invalid value types
9328
+ if (typeof val !== 'string' && typeof val !== 'number') {
9329
+ throw new Error('Value contains invalid value type. Supported types are string and number.');
9330
+ }
9439
9331
 
9440
- /**
9441
- * Highlights the previous active option in the menu.
9442
- */
9443
- highlightPrevious() {
9444
- this.moveHighlightedOption("previous");
9332
+ // Convert numbers to strings for consistency
9333
+ if (typeof val === 'number') {
9334
+ values[index] = String(val);
9335
+ }
9336
+ });
9337
+
9338
+ // Return the resulting array of string values
9339
+ return values;
9445
9340
  }
9446
9341
 
9447
9342
  /**
9448
- * Moves the highlighted option in the specified direction.
9449
- * @param {string} direction - The direction to move the highlight ("next" or "previous").
9343
+ * Returns whether two arrays of options contain the same elements.
9344
+ * @param {AuroMenuOption[]} arr1 - First array of options.
9345
+ * @param {AuroMenuOption[]} arr2 - Second array of options.
9346
+ * @returns {boolean} True if arrays match, false otherwise.
9450
9347
  */
9451
- moveHighlightedOption(direction) {
9452
-
9453
- // Get the active options
9454
- const activeOptions = this._menuOptions.filter(option => option.isActive);
9455
-
9456
- // Get the currently active option
9457
- const currentActiveOption = activeOptions[activeOptions.indexOf(this.highlightedOption)];
9348
+ optionsArraysMatch(arr1, arr2) {
9349
+ if (arr1.length !== arr2.length) return false;
9458
9350
 
9459
- // Determine the new index based on the currently active option and direction
9460
- let newIndex = currentActiveOption
9461
- ? direction === "previous"
9462
- ? activeOptions.indexOf(currentActiveOption) - 1
9463
- : activeOptions.indexOf(currentActiveOption) + 1
9464
- : direction === "previous"
9465
- ? activeOptions.length - 1
9466
- : 0;
9351
+ const set1 = new Set(arr1);
9352
+ const set2 = new Set(arr2);
9467
9353
 
9468
- // Wrap around the index if needed
9469
- newIndex = newIndex < 0 ? activeOptions.length - 1 : newIndex >= activeOptions.length ? 0 : newIndex;
9354
+ for (let item of set1) {
9355
+ if (!set2.has(item)) {
9356
+ return false;
9357
+ }
9358
+ }
9470
9359
 
9471
- // Get the new active option and set it as highlighted
9472
- const newActiveOption = activeOptions[newIndex];
9473
- this.setHighlightedOption(newActiveOption);
9360
+ return true;
9474
9361
  }
9362
+ }
9475
9363
 
9476
- /**
9477
- * Sets the highlighted index to the specified option.
9478
- * @param {AuroMenuOption} option - The option to highlight.
9479
- */
9480
- setHighlightedOption(option) {
9481
-
9482
- if (!option) return;
9483
-
9484
- // Get the index of the option to highlight
9485
- const index = this._menuOptions.indexOf(option);
9486
-
9487
- // Update highlighted index
9488
- this.highlightedIndex = index;
9364
+ const MenuContext = n('menu-context');
9489
9365
 
9490
- // Notify subscribers of highlight change
9491
- this.notify({ type: 'highlightChange', option, index: this.highlightedIndex });
9366
+ // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
9367
+ // See LICENSE in the project root for license information.
9492
9368
 
9493
- // Dispatch the change event
9494
- this.dispatchChangeEvent('auroMenu-activatedOption', option);
9495
- }
9496
9369
 
9497
- /**
9498
- * Sets the highlighted option to the option at the specified index if it exists.
9499
- * @param {number} index
9500
- */
9501
- setHighlightedIndex(index) {
9502
- const option = this._menuOptions[index] || null;
9503
- this.setHighlightedOption(option);
9504
- }
9370
+ /**
9371
+ * Helper method to dispatch custom events.
9372
+ * @param {HTMLElement} element - Element to dispatch event from.
9373
+ * @param {string} eventName - Name of the event to dispatch.
9374
+ * @param {Object} [detail] - Optional detail object to include with the event.
9375
+ */
9376
+ function dispatchMenuEvent(element, eventName, detail = null) {
9377
+ const eventConfig = {
9378
+ bubbles: true,
9379
+ cancelable: false,
9380
+ composed: true
9381
+ };
9505
9382
 
9506
- /**
9507
- * Selects the currently highlighted option.
9508
- */
9509
- selectHighlightedOption() {
9510
- if (this.highlightedOption) {
9511
- this.toggleOption(this.highlightedOption);
9512
- }
9383
+ if (detail !== null) {
9384
+ eventConfig.detail = detail;
9513
9385
  }
9514
9386
 
9515
- /**
9516
- * SELECTION AND DESELECTION METHODS
9517
- */
9518
-
9519
- /**
9520
- * Selects one or more options in a batch operation
9521
- * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to select
9522
- */
9523
- selectOptions(options) {
9524
- let optionsToSelect = Array.isArray(options) ? options : [options];
9387
+ element.dispatchEvent(new CustomEvent(eventName, eventConfig));
9388
+ }
9525
9389
 
9526
- // Filter out options that are inactive
9527
- optionsToSelect = optionsToSelect.filter(option => option.isActive);
9390
+ /* eslint-disable no-underscore-dangle */
9391
+ // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
9392
+ // See LICENSE in the project root for license information.
9528
9393
 
9529
- if (!optionsToSelect.length) return;
9530
9394
 
9531
- if (this.multiSelect) {
9532
- this.selectedOptions = [...(this.selectedOptions || []), ...optionsToSelect];
9533
- } else {
9534
- // In single select mode, only take the last option
9535
- this.selectedOptions = [optionsToSelect[optionsToSelect.length - 1]];
9536
- }
9537
9395
 
9538
- this.stageUpdate();
9539
- }
9396
+ /**
9397
+ * The `auro-menu` element provides users a way to select from a list of options.
9398
+ * @customElement auro-menu
9399
+ *
9400
+ * @event {CustomEvent<Element>} auroMenu-activatedOption - Notifies that a menuoption has been made `active`.
9401
+ * @event {CustomEvent<any>} auroMenu-customEventFired - Notifies that a custom event has been fired.
9402
+ * @event {CustomEvent<{ loading: boolean; hasLoadingPlaceholder: boolean; }>} auroMenu-loadingChange - Notifies when the loading attribute is changed.
9403
+ * @event {CustomEvent<any>} auroMenu-selectValueFailure - Notifies that an attempt to select a menuoption by matching a value has failed.
9404
+ * @event {CustomEvent<{ values: HTMLElement[] }>} auroMenu-deselectPrevented - Notifies that deselection was prevented and includes the affected options in `detail.values`.
9405
+ * @event {CustomEvent<any>} auroMenu-selectValueReset - Notifies that the component value has been reset.
9406
+ * @event {CustomEvent<any>} auroMenu-selectedOption - Notifies that a new menuoption selection has been made.
9407
+ * @slot loadingText - Text to show while loading attribute is set
9408
+ * @slot loadingIcon - Icon to show while loading attribute is set
9409
+ * @slot - Slot for insertion of menu options.
9410
+ */
9540
9411
 
9541
- /**
9542
- * Deselects one or more options in a batch operation
9543
- * @param {AuroMenuOption|AuroMenuOption[]} options - Single option or array of options to deselect
9544
- */
9545
- deselectOptions(options) {
9546
- const optionsToDeselect = Array.isArray(options) ? options : [options];
9412
+ /* eslint-disable max-lines */
9547
9413
 
9548
- if (!optionsToDeselect.length) return;
9414
+ class AuroMenu extends AuroElement$1 {
9549
9415
 
9550
- // Check if deselection should be prevented
9551
- const shouldPreventDeselect = !this.allowDeselect && !this.multiSelect;
9552
- const isOnlySelectedOption = this.selectedOptions.length === 1 && optionsToDeselect.includes(this.selectedOptions[0]);
9416
+ constructor() {
9417
+ super();
9553
9418
 
9554
- // Prevent deselecting the only selected option if not allowed
9555
- if (shouldPreventDeselect && isOnlySelectedOption) {
9556
- optionsToDeselect.forEach(option => {
9557
- option.selected = true;
9558
- });
9559
- this.dispatchChangeEvent('auroMenu-deselectPrevented', {
9560
- values: optionsToDeselect
9561
- });
9562
- return;
9563
- }
9419
+ // State properties (reactive)
9564
9420
 
9565
- const optionsSet = new Set(optionsToDeselect);
9566
- this.selectedOptions = (this.selectedOptions || [])
9567
- .filter(opt => !optionsSet.has(opt));
9421
+ /**
9422
+ * @private
9423
+ */
9424
+ this.shape = "box";
9568
9425
 
9569
- this.stageUpdate();
9570
- }
9426
+ /**
9427
+ * @private
9428
+ */
9429
+ this.size = "sm";
9571
9430
 
9572
- /**
9573
- * Selects a single option.
9574
- * @param {AuroMenuOption} option
9575
- */
9576
- selectOption(option) {
9577
- this.selectOptions(option);
9578
- }
9579
-
9580
- /**
9581
- * Deselects a single option.
9582
- * @param {AuroMenuOption} option
9583
- */
9584
- deselectOption(option) {
9585
- this.deselectOptions(option);
9586
- }
9587
-
9588
- /**
9589
- * Toggles the selection state of a single option.
9590
- * @param {AuroMenuOption} option
9591
- */
9592
- toggleOption(option) {
9593
- if (option.selected) {
9594
- this.deselectOption(option);
9595
- } else {
9596
- this.selectOption(option);
9597
- }
9598
- }
9599
-
9600
- /**
9601
- * Selects options based on their value(s) when compared to a passed value or values.
9602
- * Value or values are normalized to an array of strings that can be matched to option keys.
9603
- * @param {string|number|Array<string|number>} value - The value(s) to select.
9604
- */
9605
- selectByValue(value) {
9606
- const isEmptyValue = value === undefined ||
9607
- value === null ||
9608
- (Array.isArray(value) && value.length === 0) ||
9609
- (typeof value === 'string' && value.trim() === '');
9610
-
9611
- // Early exit for invalid/empty values
9612
- if (isEmptyValue) {
9613
- this.selectedOptions.forEach(opt => opt.selected = false);
9614
- this.selectedOptions = [];
9615
- return;
9616
- }
9617
-
9618
- // If an internal update cycle is still in progress, defer value application
9619
- // rather than dropping it.
9620
- if (this.internalUpdateInProgress || this.host.internalUpdateInProgress) {
9621
- this.queuePendingValue(value);
9622
- return;
9623
- }
9624
-
9625
- // Normalize values to array of strings
9626
- const normalizedValues = this._getNormalizedValues(value);
9627
-
9628
- // Validate for single-select mode
9629
- let validatedValues = normalizedValues;
9630
- if (normalizedValues.length > 1 && !this.multiSelect) {
9631
- console.warn("MenuService - Multiple values provided for single-select menu. Only the first value will be selected.");
9632
- validatedValues = [normalizedValues[0]];
9633
- }
9431
+ // Currently selected option
9432
+ this.optionSelected = undefined;
9433
+ // String used for highlighting/filtering
9434
+ this.matchWord = undefined;
9435
+ // Hide the checkmark icon on selected options
9436
+ this.noCheckmark = false;
9437
+ // Currently active option
9438
+ this.optionActive = undefined;
9439
+ // Loading state
9440
+ this.loading = false;
9441
+ // Multi-select mode
9442
+ this.multiSelect = false;
9443
+ // Allow deselecting of menu options
9444
+ this.allowDeselect = false;
9445
+ // Select all matching options when setting value in multi-select mode
9446
+ this.selectAllMatchingOptions = false;
9634
9447
 
9635
- if (this._menuOptions.length === 0) {
9636
- this.queuePendingValue(value);
9637
- return;
9638
- }
9448
+ // Event Bindings
9639
9449
 
9640
- // Find matching options by comparing available options to validated values
9641
- const trackedKeys = new Set();
9642
- const optionsToSelect = this._menuOptions.filter(option => {
9643
- const passesFilter = validatedValues.includes(option.key);
9644
- const alreadyTracked = trackedKeys.has(option.key);
9645
- const isActive = option.isActive;
9450
+ /**
9451
+ * @private
9452
+ */
9453
+ this.handleSlotChange = this.handleSlotChange.bind(this);
9646
9454
 
9647
- trackedKeys.add(option.key);
9455
+ // Instance properties (non-reactive)
9648
9456
 
9649
- // Include the option in the options to be selected if it passes the filter check and
9650
- // either hasn't been tracked yet or selectAllMatchingOptions is true
9651
- return isActive && passesFilter && (!alreadyTracked || (alreadyTracked && this.selectAllMatchingOptions));
9457
+ /**
9458
+ * @private
9459
+ */
9460
+ Object.assign(this, {
9461
+ // Root-level menu (true) or a nested submenu (false)
9462
+ rootMenu: true,
9463
+ // Currently focused/active menu item index
9464
+ _index: -1,
9465
+ // Nested menu spacer
9466
+ nestingSpacer: '<span class="nestingSpacer"></span>',
9467
+ // Loading indicator for slot elements
9468
+ loadingSlots: null,
9652
9469
  });
9470
+ }
9653
9471
 
9654
- // Handle no matches: clear existing selection, but do not dispatch an intermediate
9655
- // undefined value that can overwrite the host value in parent components.
9656
- if (!optionsToSelect.length) {
9657
- const hasUnresolvedKeys = this._menuOptions.some((option) => option.isActive && option.key == null);
9472
+ static get properties() {
9473
+ return {
9474
+ ...super.properties,
9658
9475
 
9659
- if (hasUnresolvedKeys) {
9660
- this.queuePendingValue(value);
9661
- return;
9662
- }
9476
+ /**
9477
+ * Allows deselecting an already selected option when clicked again in single-select mode.
9478
+ */
9479
+ allowDeselect: {
9480
+ type: Boolean,
9481
+ reflect: true,
9482
+ },
9663
9483
 
9664
- this.clearPendingValue();
9484
+ /**
9485
+ * When true, the entire menu and all options are disabled.
9486
+ */
9487
+ disabled: {
9488
+ type: Boolean,
9489
+ reflect: true
9490
+ },
9665
9491
 
9666
- if (this.selectedOptions.length > 0) {
9667
- this.selectedOptions = [];
9668
- }
9492
+ /**
9493
+ * Indicates whether the menu has a loadingIcon or loadingText to render when in a loading state.
9494
+ */
9495
+ hasLoadingPlaceholder: {
9496
+ type: Boolean
9497
+ },
9669
9498
 
9670
- // Always notify so the host resets any stale invalid value, even when
9671
- // selectedOptions was already empty (e.g. double-clicking set-invalid).
9672
- this.stageUpdate({ reason: 'no-match' });
9499
+ /**
9500
+ * @private
9501
+ */
9502
+ layout: {
9503
+ type: String
9504
+ },
9673
9505
 
9674
- // Dispatch failure event if no matches found
9675
- if (validatedValues.length) {
9676
- this.dispatchChangeEvent('auroMenu-selectValueFailure', {
9677
- message: 'No matching options found for the provided value(s).',
9678
- values: validatedValues
9679
- });
9680
- }
9506
+ /**
9507
+ * Indent level for submenus.
9508
+ * @private
9509
+ */
9510
+ level: {
9511
+ type: Number,
9512
+ reflect: false,
9513
+ attribute: false
9514
+ },
9681
9515
 
9682
- return;
9683
- }
9516
+ /**
9517
+ * When true, displays a loading state using the loadingIcon and loadingText slots if provided.
9518
+ */
9519
+ loading: {
9520
+ type: Boolean,
9521
+ reflect: true
9522
+ },
9684
9523
 
9685
- this.clearPendingValue();
9524
+ /**
9525
+ * Specifies a string used to highlight matched string parts in options.
9526
+ */
9527
+ matchWord: {
9528
+ type: String,
9529
+ attribute: 'matchword'
9530
+ },
9686
9531
 
9687
- if (this.optionsArraysMatch(optionsToSelect, this.selectedOptions)) {
9688
- return;
9689
- }
9532
+ /**
9533
+ * When true, the selected option can be multiple options.
9534
+ */
9535
+ multiSelect: {
9536
+ type: Boolean,
9537
+ reflect: true,
9538
+ attribute: 'multiselect'
9539
+ },
9690
9540
 
9691
- // Apply programmatic selection as a single transaction and emit one final state.
9692
- this.selectedOptions = optionsToSelect;
9693
- this.stageUpdate();
9694
- }
9541
+ /**
9542
+ * When true, selected option will not show the checkmark.
9543
+ */
9544
+ noCheckmark: {
9545
+ type: Boolean,
9546
+ reflect: true,
9547
+ attribute: 'nocheckmark'
9548
+ },
9695
9549
 
9696
- /**
9697
- * Queues a pending value and schedules a bounded retry.
9698
- * @param {string|number|Array<string|number>} value - The value to retry.
9699
- */
9700
- queuePendingValue(value) {
9701
- this._pendingValue = value;
9550
+ /**
9551
+ * Specifies the current active menuOption.
9552
+ */
9553
+ optionActive: {
9554
+ type: Object,
9555
+ attribute: 'optionactive'
9556
+ },
9702
9557
 
9703
- if (this._pendingRetryScheduled || this._pendingRetryCount >= 5) {
9704
- return;
9705
- }
9558
+ /**
9559
+ * An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
9560
+ */
9561
+ optionSelected: {
9562
+ // Allow HTMLElement, HTMLElement[] arrays and undefined
9563
+ type: Object
9564
+ },
9706
9565
 
9707
- this._pendingRetryScheduled = true;
9708
- this._pendingRetryCount += 1;
9566
+ /**
9567
+ * Available menu options.
9568
+ * @readonly
9569
+ */
9570
+ options: {
9571
+ type: Array,
9572
+ reflect: false,
9573
+ attribute: false
9574
+ },
9709
9575
 
9710
- setTimeout(() => {
9711
- this._pendingRetryScheduled = false;
9576
+ /**
9577
+ * Sets the size of the menu.
9578
+ * @type {'sm' | 'md'}
9579
+ * @default 'sm'
9580
+ */
9581
+ size: {
9582
+ type: String,
9583
+ reflect: true
9584
+ },
9712
9585
 
9713
- if (this._pendingValue == null) {
9714
- return;
9715
- }
9586
+ /**
9587
+ * When true, selects all options that match the provided value/key when setting value and multiselect is enabled.
9588
+ */
9589
+ selectAllMatchingOptions: {
9590
+ type: Boolean,
9591
+ reflect: true,
9592
+ },
9716
9593
 
9717
- const pendingValue = this._pendingValue;
9718
- this.selectByValue(pendingValue);
9719
- }, 0);
9720
- }
9594
+ /**
9595
+ * Sets the shape of the menu.
9596
+ * @type {'box' | 'round'}
9597
+ * @default 'box'
9598
+ */
9599
+ shape: {
9600
+ type: String,
9601
+ reflect: true
9602
+ },
9721
9603
 
9722
- /**
9723
- * Clears pending retry state.
9724
- */
9725
- clearPendingValue() {
9726
- this._pendingValue = null;
9727
- this._pendingRetryScheduled = false;
9728
- this._pendingRetryCount = 0;
9604
+ /**
9605
+ * The value of the selected option. In multi-select mode, this is a JSON stringified array of selected option values.
9606
+ */
9607
+ value: {
9608
+ type: String,
9609
+ reflect: true,
9610
+ attribute: 'value'
9611
+ }
9612
+ };
9729
9613
  }
9730
9614
 
9731
- /**
9732
- * Resets the selected options to an empty array.
9733
- */
9734
- reset() {
9735
- const previousOptions = [...this.selectedOptions];
9736
- previousOptions.forEach(opt => opt.selected = false);
9737
- this.selectedOptions = [];
9738
-
9739
- // Single update after clearing all
9740
- if (previousOptions.length) {
9741
- this.stageUpdate();
9742
- }
9615
+ static get styles() {
9616
+ return [
9617
+ styleCss$1,
9618
+ colorCss$1,
9619
+ tokensCss
9620
+ ];
9743
9621
  }
9744
9622
 
9745
9623
  /**
9746
- * SUBSCRIPTION, NOTIFICATION AND EVENT DISPATCH METHODS
9624
+ * @readonly
9625
+ * @returns {string} - Returns the label of the currently selected option(s).
9747
9626
  */
9627
+ get currentLabel() {
9628
+ return this.menuService.currentLabel;
9629
+ };
9748
9630
 
9749
9631
  /**
9750
- * Subscribes a callback to menu service events.
9751
- * @param {Function} callback - The callback to invoke on events.
9632
+ * @readonly
9633
+ * @returns {Array<HTMLElement>} - Returns the array of available menu options.
9634
+ * @deprecated Use `options` property instead.
9752
9635
  */
9753
- subscribe(callback) {
9754
- this._subscribers.push(callback);
9636
+ get items() {
9637
+ return this.options;
9755
9638
  }
9756
9639
 
9757
9640
  /**
9758
- * Remove a previously subscribed callback from menu service events.
9759
- * @param {Function} callback
9641
+ * @returns {number} - Returns the index of the currently active option.
9760
9642
  */
9761
- unsubscribe(callback) {
9762
- this._subscribers = this._subscribers.filter(cb => cb !== callback);
9643
+ get index() {
9644
+ return this._index;
9763
9645
  }
9764
9646
 
9765
9647
  /**
9766
- * Stages an update to notify subscribers of state and value changes.
9648
+ * @param {number} value - Sets the index of the currently active option.
9767
9649
  */
9768
- stageUpdate(meta = {}) {
9769
- this.notifyStateChange(meta);
9770
- this.notifyValueChange(meta);
9650
+ set index(value) {
9651
+ this.menuService.setHighlightedIndex(value);
9771
9652
  }
9772
9653
 
9773
9654
  /**
9774
- * Notifies subscribers of a menu service event.
9775
- * All notifications are sent to all subscribers.
9776
- * @param {string} event - The event to send to subscribers.
9655
+ * This will register this element with the browser.
9656
+ * @param {string} [name="auro-menu"] - The name of the element that you want to register.
9657
+ *
9658
+ * @example
9659
+ * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
9660
+ *
9777
9661
  */
9778
- notify(event) {
9779
- this._subscribers.forEach(callback => callback(event));
9662
+ static register(name = "auro-menu") {
9663
+ AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenu);
9780
9664
  }
9781
9665
 
9782
9666
  /**
9783
- * Notifies subscribers of a state change (selected options has changed).
9667
+ * Formatted value based on `multiSelect` state.
9668
+ * Default type is `String`, changing to `Array<String>` when `multiSelect` is true.
9669
+ * @private
9670
+ * @returns {String|Array<String>}
9784
9671
  */
9785
- notifyStateChange(meta = {}) {
9786
- this.notify({
9787
- type: 'stateChange',
9788
- selectedOptions: this.selectedOptions,
9789
- ...meta
9790
- });
9672
+ get formattedValue() {
9673
+ return this.menuService.currentValue;
9791
9674
  }
9792
9675
 
9793
9676
  /**
9794
- * Notifies subscribers of a value change (current value has changed).
9677
+ * Gets the current property values for the menu service.
9678
+ * @private
9679
+ * @returns {Object}
9795
9680
  */
9796
- notifyValueChange(meta = {}) {
9797
-
9798
- // Prepare details for the event
9799
- const details = {
9800
- value: this.currentValue,
9801
- stringValue: this.stringValue,
9802
- keys: this.currentKeys,
9803
- options: this.selectedOptions,
9804
- label: this.currentLabel
9681
+ get propertyValues() {
9682
+ return {
9683
+ size: this.size,
9684
+ shape: this.shape,
9685
+ noCheckmark: this.nocheckmark,
9686
+ disabled: this.disabled
9805
9687
  };
9806
-
9807
- // If only one option is selected, include its index
9808
- if (this.selectedOptions.length === 1) details.index = this._menuOptions.indexOf(this.selectedOptions[0]);
9809
-
9810
- this.notify({
9811
- type: 'valueChange',
9812
- ...meta,
9813
- ...details
9814
- });
9815
9688
  }
9816
9689
 
9817
9690
  /**
9818
- * Dispatches a custom event from the host element.
9819
- * @param {string} eventName
9820
- * @param {any} detail
9691
+ * Provides the menu context to child components.
9692
+ * Initializes the MenuService and subscribes to menu changes.
9693
+ * @protected
9821
9694
  */
9822
- dispatchChangeEvent(eventName, detail) {
9823
- this.host.dispatchEvent(new CustomEvent(eventName, {
9824
- bubbles: true,
9825
- cancelable: false,
9826
- composed: true,
9827
- detail
9828
- }));
9829
- }
9695
+ provideContext() {
9696
+ if (this.parentElement && this.parentElement.closest('auro-menu, [auro-menu]')) {
9697
+ this.rootMenu = false;
9698
+ this.menuService = this.parentElement.menuService;
9699
+ this._contextProvider = this.parentElement._contextProvider;
9700
+ return;
9701
+ }
9830
9702
 
9831
- /**
9832
- * MENU OPTION MANAGEMENT METHODS
9833
- */
9703
+ this.menuService = new MenuService({host: this});
9704
+ this.menuService.setProperties(this.propertyValues);
9705
+ this.menuService.subscribe(this.handleMenuChange.bind(this));
9706
+ this._contextProvider = new i(this, {
9707
+ context: MenuContext,
9708
+ initialValue: this.menuService
9709
+ });
9710
+ }
9834
9711
 
9835
9712
  /**
9836
- * Adds a menu option to the service's list.
9837
- * @param {AuroMenuOption} option - the option to track
9713
+ * Updates the currently active option in the menu.
9714
+ * @param {HTMLElement} option - The option to set as active.
9838
9715
  */
9839
- addMenuOption(option) {
9840
- this._menuOptions.push(option);
9841
- this.notify({ type: 'optionsChange', options: this._menuOptions });
9842
-
9843
- if (this._pendingValue != null) {
9844
- this.queuePendingValue(this._pendingValue);
9845
- }
9716
+ updateActiveOption(option) {
9717
+ this.menuService.setHighlightedOption(option);
9846
9718
  }
9847
9719
 
9848
9720
  /**
9849
- * Removes a menu option from the service's list.
9850
- * @param {AuroMenuOption} option - the option to remove
9721
+ * Sets the internal value and manages update state.
9722
+ * @param {String|Array<String>} value - The value to set.
9723
+ * @protected
9851
9724
  */
9852
- removeMenuOption(option) {
9853
- this._menuOptions = this._menuOptions.filter(opt => opt !== option);
9854
- this.notify({ type: 'optionsChange', options: this._menuOptions });
9725
+ setInternalValue(value) {
9726
+ if (this.value !== value) {
9727
+ this.internalUpdateInProgress = true;
9728
+ this.value = value;
9855
9729
 
9856
- if (this._menuOptions.length === 0) {
9857
- this.clearPendingValue();
9730
+ setTimeout(() => {
9731
+ this.internalUpdateInProgress = false;
9732
+ });
9858
9733
  }
9859
9734
  }
9860
9735
 
9861
9736
  /**
9862
- * UTILITIES
9863
- */
9864
-
9865
- /**
9866
- * Normalizes a value or array of values into an array of strings for option selection.
9867
- * This function ensures that input values are consistently formatted for matching menu options.
9868
- *
9869
- * @param {string|number|Array<string|number>} value - The value(s) to normalize.
9870
- * @returns {Array<string>} An array of string values suitable for option matching.
9871
- * @throws {Error} If any value is not a string or number.
9737
+ * Handles changes from the menu service and updates component state.
9738
+ * @param {Object} event - The event object from the menu service.
9739
+ * @protected
9872
9740
  */
9873
- _getNormalizedValues(value) {
9874
- let values = value;
9875
-
9876
- // Handle JSON string and single value string input
9877
- if (!Array.isArray(values) && typeof values === 'string') {
9878
-
9879
- // Attempt to parse as JSON array
9880
- try {
9881
-
9882
- // Normalize single quotes to double quotes for JSON parsing
9883
- // This will not handle complex cases but will cover basic usage
9884
- const parseValue = values.replace(/'([^']*?)'/g, '"$1"');
9885
-
9886
- // Attempt parse
9887
- const parsed = JSON.parse(parseValue);
9888
-
9889
- // Ensure parsed value is an array
9890
- if (!Array.isArray(parsed)) throw new Error('Not an array');
9741
+ handleMenuChange(event) {
9742
+ if (event.type === 'valueChange') {
9891
9743
 
9892
- // Set values to parsed array
9893
- values = parsed;
9894
- } catch (err) {
9744
+ // New option is array value or first option with fallback to undefined for empty array in all cases
9745
+ const newOption = this.multiSelect && event.options.length ? event.options : event.options[0] || undefined;
9746
+ const newValue = event.stringValue;
9895
9747
 
9896
- // If parsing fails, treat as single value
9897
- values = [value];
9748
+ // Check if the option or value has actually changed
9749
+ if (this.optionSelected !== newOption || this.stringValue !== newValue) {
9750
+ this.optionSelected = newOption;
9751
+ this.setInternalValue(newValue);
9898
9752
  }
9899
- }
9900
9753
 
9901
- // Handle a single number being passed
9902
- if (typeof values === 'number') {
9903
- values = [String(values)];
9754
+ // Notify components of selection change
9755
+ this.notifySelectionChange(event);
9904
9756
  }
9905
9757
 
9906
- // Coerce each value to string and validate types
9907
- values.forEach((val, index) => {
9908
-
9909
- // Throw an error for invalid value types
9910
- if (typeof val !== 'string' && typeof val !== 'number') {
9911
- throw new Error('Value contains invalid value type. Supported types are string and number.');
9912
- }
9913
-
9914
- // Convert numbers to strings for consistency
9915
- if (typeof val === 'number') {
9916
- values[index] = String(val);
9917
- }
9918
- });
9758
+ if (event.type === 'highlightChange') {
9759
+ this.optionActive = event.option;
9760
+ this._index = event.index;
9761
+ }
9919
9762
 
9920
- // Return the resulting array of string values
9921
- return values;
9763
+ if (event.type === 'optionsChange') {
9764
+ this.options = event.options;
9765
+ this.dispatchEvent(new CustomEvent('auroMenu-optionsChange', {
9766
+ detail: {
9767
+ options: event.options
9768
+ }
9769
+ }));
9770
+ }
9922
9771
  }
9923
9772
 
9924
9773
  /**
9925
- * Returns whether two arrays of options contain the same elements.
9926
- * @param {AuroMenuOption[]} arr1 - First array of options.
9927
- * @param {AuroMenuOption[]} arr2 - Second array of options.
9928
- * @returns {boolean} True if arrays match, false otherwise.
9774
+ * Gets the currently selected options.
9775
+ * @returns {Array<HTMLElement>}
9929
9776
  */
9930
- optionsArraysMatch(arr1, arr2) {
9931
- if (arr1.length !== arr2.length) return false;
9932
-
9933
- const set1 = new Set(arr1);
9934
- const set2 = new Set(arr2);
9935
-
9936
- for (let item of set1) {
9937
- if (!set2.has(item)) {
9938
- return false;
9939
- }
9940
- }
9941
-
9942
- return true;
9777
+ get selectedOptions() {
9778
+ return this.menuService ? this.menuService.selectedOptions : [];
9943
9779
  }
9944
- }
9945
9780
 
9946
- const MenuContext = n('menu-context');
9781
+ /**
9782
+ * Gets the first selected option, or null if none.
9783
+ * @returns {HTMLElement|null}
9784
+ */
9785
+ get selectedOption() {
9786
+ return this.menuService ? this.menuService.selectedOptions[0] : null;
9787
+ }
9947
9788
 
9948
- /* eslint-disable no-underscore-dangle */
9949
- // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
9950
- // See LICENSE in the project root for license information.
9789
+ // Lifecycle Methods
9951
9790
 
9791
+ connectedCallback() {
9792
+ super.connectedCallback();
9952
9793
 
9794
+ this.provideContext();
9953
9795
 
9954
- /**
9955
- * The `auro-menu` element provides users a way to select from a list of options.
9956
- * @customElement auro-menu
9957
- *
9958
- * @event {CustomEvent<Element>} auroMenu-activatedOption - Notifies that a menuoption has been made `active`.
9959
- * @event {CustomEvent<any>} auroMenu-customEventFired - Notifies that a custom event has been fired.
9960
- * @event {CustomEvent<{ loading: boolean; hasLoadingPlaceholder: boolean; }>} auroMenu-loadingChange - Notifies when the loading attribute is changed.
9961
- * @event {CustomEvent<any>} auroMenu-selectValueFailure - Notifies that an attempt to select a menuoption by matching a value has failed.
9962
- * @event {CustomEvent<{ values: HTMLElement[] }>} auroMenu-deselectPrevented - Notifies that deselection was prevented and includes the affected options in `detail.values`.
9963
- * @event {CustomEvent<any>} auroMenu-selectValueReset - Notifies that the component value has been reset.
9964
- * @event {CustomEvent<any>} auroMenu-selectedOption - Notifies that a new menuoption selection has been made.
9965
- * @slot loadingText - Text to show while loading attribute is set
9966
- * @slot loadingIcon - Icon to show while loading attribute is set
9967
- * @slot - Slot for insertion of menu options.
9968
- */
9796
+ // this.addEventListener('keydown', this.handleKeyDown);
9797
+ this.addEventListener('auroMenuOption-click', this.handleMouseSelect);
9798
+ this.addEventListener('auroMenuOption-mouseover', this.handleOptionHover);
9799
+ this.addEventListener('slotchange', this.handleSlotChange);
9800
+ this.setTagAttribute("auro-menu");
9801
+ }
9969
9802
 
9970
- /* eslint-disable max-lines */
9803
+ disconnectedCallback() {
9804
+ // this.removeEventListener('keydown', this.handleKeyDown);
9805
+ this.removeEventListener('auroMenuOption-click', this.handleMouseSelect);
9806
+ this.removeEventListener('auroMenuOption-mouseover', this.handleOptionHover);
9807
+ this.removeEventListener('slotchange', this.handleSlotChange);
9971
9808
 
9972
- class AuroMenu extends AuroElement$1 {
9809
+ super.disconnectedCallback();
9810
+ }
9973
9811
 
9974
- constructor() {
9975
- super();
9812
+ firstUpdated() {
9813
+ AuroLibraryRuntimeUtils$3.prototype.handleComponentTagRename(this, 'auro-menu');
9976
9814
 
9977
- // State properties (reactive)
9815
+ this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
9816
+ this.initializeMenu();
9817
+ }
9978
9818
 
9979
- /**
9980
- * @private
9981
- */
9982
- this.shape = "box";
9983
9819
 
9984
- /**
9985
- * @private
9986
- */
9987
- this.size = "sm";
9820
+ updated(changedProperties) {
9821
+ super.updated(changedProperties);
9988
9822
 
9989
- // Value of the selected options
9990
- this.value = undefined;
9991
- // Currently selected option
9992
- this.optionSelected = undefined;
9993
- // String used for highlighting/filtering
9994
- this.matchWord = undefined;
9995
- // Hide the checkmark icon on selected options
9996
- this.noCheckmark = false;
9997
- // Currently active option
9998
- this.optionActive = undefined;
9999
- // Loading state
10000
- this.loading = false;
10001
- // Multi-select mode
10002
- this.multiSelect = false;
10003
- // Allow deselecting of menu options
10004
- this.allowDeselect = false;
10005
- // Select all matching options when setting value in multi-select mode
10006
- this.selectAllMatchingOptions = false;
9823
+ // Apply value selection synchronously so that static-HTML fixtures
9824
+ // resolve within a single update cycle. The refactored selectByValue
9825
+ // no longer calls reset() first, so the destructive intermediate-event
9826
+ // cascade that originally required deferral is eliminated. If option
9827
+ // keys are not yet resolved (framework mount-order race), selectByValue
9828
+ // queues a bounded retry automatically via queuePendingValue.
9829
+ if (changedProperties.has('value') && !this.internalUpdateInProgress) {
9830
+ this.menuService.selectByValue(this.value);
9831
+ }
10007
9832
 
10008
- // Event Bindings
9833
+ // Handle loading state changes
9834
+ if (changedProperties.has('loading')) {
9835
+ this.setLoadingState(this.loading);
9836
+ }
10009
9837
 
10010
- /**
10011
- * @private
10012
- */
10013
- this.handleSlotChange = this.handleSlotChange.bind(this);
9838
+ if (changedProperties.has('multiSelect') && this.rootMenu) {
9839
+ if (this.multiSelect) {
9840
+ this.setAttribute('aria-multiselectable', 'true');
9841
+ } else {
9842
+ this.removeAttribute('aria-multiselectable');
9843
+ }
9844
+ }
9845
+ }
10014
9846
 
10015
- // Instance properties (non-reactive)
9847
+ /**
9848
+ * Sets an attribute that matches the default tag name if the tag name is not the default.
9849
+ * @param {string} tagName - The tag name to set as an attribute.
9850
+ * @private
9851
+ */
9852
+ setTagAttribute(tagName) {
9853
+ if (this.tagName.toLowerCase() !== tagName) {
9854
+ this.setAttribute(tagName, true);
9855
+ }
9856
+ }
10016
9857
 
10017
- /**
10018
- * @private
10019
- */
10020
- Object.assign(this, {
10021
- // Root-level menu (true) or a nested submenu (false)
10022
- rootMenu: true,
10023
- // Currently focused/active menu item index
10024
- _index: -1,
10025
- // Nested menu spacer
10026
- nestingSpacer: '<span class="nestingSpacer"></span>',
10027
- // Loading indicator for slot elements
10028
- loadingSlots: null,
9858
+ /**
9859
+ * Sets the loading state and dispatches a loading change event.
9860
+ * @param {boolean} isLoading - Whether the menu is loading.
9861
+ * @protected
9862
+ */
9863
+ setLoadingState(isLoading) {
9864
+ this.setAttribute("aria-busy", isLoading);
9865
+ dispatchMenuEvent(this, "auroMenu-loadingChange", {
9866
+ loading: isLoading,
9867
+ hasLoadingPlaceholder: this.hasLoadingPlaceholder
10029
9868
  });
10030
9869
  }
10031
9870
 
10032
- static get properties() {
10033
- return {
10034
- ...super.properties,
10035
-
10036
- /**
10037
- * Allows deselecting an already selected option when clicked again in single-select mode.
10038
- */
10039
- allowDeselect: {
10040
- type: Boolean,
10041
- reflect: true,
10042
- },
10043
-
10044
- /**
10045
- * When true, the entire menu and all options are disabled.
10046
- */
10047
- disabled: {
10048
- type: Boolean,
10049
- reflect: true
10050
- },
10051
-
10052
- /**
10053
- * Indicates whether the menu has a loadingIcon or loadingText to render when in a loading state.
10054
- */
10055
- hasLoadingPlaceholder: {
10056
- type: Boolean
10057
- },
9871
+ // Init Methods
10058
9872
 
10059
- /**
10060
- * @private
10061
- */
10062
- layout: {
10063
- type: String
10064
- },
9873
+ /**
9874
+ * Initializes the menu's state and structure.
9875
+ * @private
9876
+ */
9877
+ initializeMenu() {
9878
+ if (this.rootMenu) {
9879
+ this.setAttribute('role', 'listbox');
9880
+ this.setAttribute('root', '');
10065
9881
 
10066
- /**
10067
- * Indent level for submenus.
10068
- * @private
10069
- */
10070
- level: {
10071
- type: Number,
10072
- reflect: false,
10073
- attribute: false
10074
- },
9882
+ if (this.multiSelect) {
9883
+ this.setAttribute('aria-multiselectable', 'true');
9884
+ }
9885
+ }
10075
9886
 
10076
- /**
10077
- * When true, displays a loading state using the loadingIcon and loadingText slots if provided.
10078
- */
10079
- loading: {
10080
- type: Boolean,
10081
- reflect: true
10082
- },
9887
+ this.handleNestedMenus(this);
9888
+ }
10083
9889
 
10084
- /**
10085
- * Specifies a string used to highlight matched string parts in options.
10086
- */
10087
- matchWord: {
10088
- type: String,
10089
- attribute: 'matchword'
10090
- },
9890
+ /**
9891
+ * Selects the currently highlighted option.
9892
+ * @protected
9893
+ */
9894
+ makeSelection() {
9895
+ this.menuService.selectHighlightedOption();
9896
+ }
10091
9897
 
10092
- /**
10093
- * When true, the selected option can be multiple options.
10094
- */
10095
- multiSelect: {
10096
- type: Boolean,
10097
- reflect: true,
10098
- attribute: 'multiselect'
10099
- },
9898
+ /**
9899
+ * Resets all options to their default state.
9900
+ * @private
9901
+ */
9902
+ clearSelection() {
9903
+ this.optionSelected = undefined;
9904
+ this.value = undefined;
9905
+ this._index = -1;
9906
+ }
10100
9907
 
10101
- /**
10102
- * When true, selected option will not show the checkmark.
10103
- */
10104
- noCheckmark: {
10105
- type: Boolean,
10106
- reflect: true,
10107
- attribute: 'nocheckmark'
10108
- },
9908
+ /**
9909
+ * Resets the menu to its initial state.
9910
+ * This is the only way to return value to undefined.
9911
+ * @public
9912
+ */
9913
+ reset() {
9914
+ this.menuService.reset();
10109
9915
 
10110
- /**
10111
- * Specifies the current active menuOption.
10112
- */
10113
- optionActive: {
10114
- type: Object,
10115
- attribute: 'optionactive'
10116
- },
9916
+ // Dispatch reset event
9917
+ dispatchMenuEvent(this, 'auroMenu-selectValueReset');
9918
+ }
10117
9919
 
10118
- /**
10119
- * An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
10120
- */
10121
- optionSelected: {
10122
- // Allow HTMLElement, HTMLElement[] arrays and undefined
10123
- type: Object
10124
- },
9920
+ /**
9921
+ * Handles nested menu structure.
9922
+ * @private
9923
+ * @param {HTMLElement} menu - Root menu element.
9924
+ */
9925
+ handleNestedMenus(menu) {
9926
+ menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
10125
9927
 
10126
- /**
10127
- * Available menu options.
10128
- * @readonly
10129
- */
10130
- options: {
10131
- type: Array,
10132
- reflect: false,
10133
- attribute: false
10134
- },
9928
+ if (menu.level > 0) {
9929
+ menu.setAttribute('role', 'group');
9930
+ menu.removeAttribute("root");
9931
+ if (!menu.hasAttribute('aria-label')) {
9932
+ menu.setAttribute('aria-label', 'submenu');
9933
+ }
9934
+ }
10135
9935
 
10136
- /**
10137
- * Sets the size of the menu.
10138
- * @type {'sm' | 'md'}
10139
- * @default 'sm'
10140
- */
10141
- size: {
10142
- type: String,
10143
- reflect: true
10144
- },
9936
+ const options = menu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption]');
9937
+ options.forEach((option) => {
9938
+ const regex = new RegExp(this.nestingSpacer, "gu");
9939
+ option.innerHTML = this.nestingSpacer.repeat(menu.level) + option.innerHTML.replace(regex, '');
9940
+ });
9941
+ }
10145
9942
 
10146
- /**
10147
- * When true, selects all options that match the provided value/key when setting value and multiselect is enabled.
10148
- */
10149
- selectAllMatchingOptions: {
10150
- type: Boolean,
10151
- reflect: true,
10152
- },
9943
+ /**
9944
+ * Navigates the menu options in the specified direction.
9945
+ * @param {'up'|'down'} direction - The direction to navigate.
9946
+ * @protected
9947
+ */
9948
+ navigateOptions(direction) {
9949
+ if (direction === 'up') {
9950
+ this.menuService.highlightPrevious();
9951
+ } else if (direction === 'down') {
9952
+ this.menuService.highlightNext();
9953
+ }
9954
+ }
10153
9955
 
10154
- /**
10155
- * Sets the shape of the menu.
10156
- * @type {'box' | 'round'}
10157
- * @default 'box'
10158
- */
10159
- shape: {
10160
- type: String,
10161
- reflect: true
10162
- },
9956
+ /**
9957
+ * Handles slot change events.
9958
+ * @private
9959
+ */
9960
+ handleSlotChange() {
9961
+ if (this.rootMenu) {
9962
+ this.initializeMenu();
9963
+ }
9964
+ }
10163
9965
 
10164
- /**
10165
- * The value of the selected option. In multi-select mode, this is a JSON stringified array of selected option values.
10166
- */
10167
- value: {
10168
- type: String,
10169
- reflect: true,
10170
- attribute: 'value'
10171
- }
10172
- };
9966
+ /**
9967
+ * Handles custom events defined on options.
9968
+ * @private
9969
+ * @param {HTMLElement} option - Option with custom event.
9970
+ */
9971
+ handleCustomEvent(option) {
9972
+ const eventName = option.getAttribute('event');
9973
+ dispatchMenuEvent(this, eventName);
9974
+ dispatchMenuEvent(this, 'auroMenu-customEventFired');
10173
9975
  }
10174
9976
 
10175
- static get styles() {
10176
- return [
10177
- styleCss$1,
10178
- colorCss$1,
10179
- tokensCss
10180
- ];
9977
+ /**
9978
+ * Notifies selection change to parent components.
9979
+ * @param {any} source - The source that triggers this event.
9980
+ * @private
9981
+ */
9982
+ notifySelectionChange({value, stringValue, keys, options, reason} = {}) {
9983
+ dispatchMenuEvent(this, 'auroMenu-selectedOption', {
9984
+ value,
9985
+ stringValue,
9986
+ keys,
9987
+ options,
9988
+ reason
9989
+ });
10181
9990
  }
10182
9991
 
10183
9992
  /**
10184
- * @readonly
10185
- * @returns {string} - Returns the label of the currently selected option(s).
9993
+ * Checks if an option is currently selected.
9994
+ * @private
9995
+ * @param {HTMLElement} option - The option to check.
9996
+ * @returns {boolean}
10186
9997
  */
10187
- get currentLabel() {
10188
- return this.menuService.currentLabel;
10189
- };
9998
+ isOptionSelected(option) {
9999
+ if (!this.optionSelected) {
10000
+ return false;
10001
+ }
10002
+
10003
+ if (this.multiSelect) {
10004
+ // In multi-select mode, check if the option is in the selected array
10005
+ return Array.isArray(this.optionSelected) && this.optionSelected.some((selectedOption) => selectedOption === option);
10006
+ }
10007
+
10008
+ return this.optionSelected === option;
10009
+ }
10190
10010
 
10191
10011
  /**
10192
- * @readonly
10193
- * @returns {Array<HTMLElement>} - Returns the array of available menu options.
10194
- * @deprecated Use `options` property instead.
10012
+ * Getter for loading placeholder state.
10013
+ * @returns {boolean} - True if loading slots are present and non-empty.
10195
10014
  */
10196
- get items() {
10197
- return this.options;
10015
+ get hasLoadingPlaceholder() {
10016
+ return this.loadingSlots && this.loadingSlots.length > 0;
10198
10017
  }
10199
10018
 
10200
10019
  /**
10201
- * @returns {number} - Returns the index of the currently active option.
10020
+ * Getter for wrapper classes based on size.
10021
+ * @returns {Object} - Class map for the wrapper element.
10022
+ * @private
10202
10023
  */
10203
- get index() {
10204
- return this._index;
10024
+ get wrapperClasses() {
10025
+ return e$3({
10026
+ 'menuWrapper': true,
10027
+ [this.size]: true,
10028
+ });
10205
10029
  }
10206
10030
 
10207
10031
  /**
10208
- * @param {number} value - Sets the index of the currently active option.
10032
+ * Logic to determine the layout of the component.
10033
+ * @protected
10034
+ * @returns {void}
10209
10035
  */
10210
- set index(value) {
10211
- this.menuService.setHighlightedIndex(value);
10036
+ renderLayout() {
10037
+ if (this.loading) {
10038
+ return b$1`
10039
+ <div class="${this.wrapperClasses}">
10040
+ <auro-menuoption
10041
+ disabled
10042
+ loadingplaceholder
10043
+ class="${this.hasLoadingPlaceholder ? "" : "empty"}"
10044
+ >
10045
+ <div>
10046
+ <slot name="loadingIcon" class="body-lg"></slot>
10047
+ <slot name="loadingText"></slot>
10048
+ </div>
10049
+ </auro-menuoption>
10050
+ </div>
10051
+ `;
10052
+ }
10053
+
10054
+ return b$1`
10055
+ <div class="${this.wrapperClasses}">
10056
+ <slot @slotchange=${this.handleSlotChange}></slot>
10057
+ </div>
10058
+ `;
10212
10059
  }
10060
+ }
10061
+
10062
+ var styleCss = i$6`.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-default-weight, );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-default-emphasized{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-default-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-default-emphasized-font-size, 1rem);line-height:var(--wcss-body-default-emphasized-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-lg-weight, );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-lg-emphasized{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-lg-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-lg-emphasized-font-size, 1.125rem);line-height:var(--wcss-body-lg-emphasized-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-sm-weight, );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-sm-emphasized{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-sm-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-sm-emphasized-font-size, 0.875rem);line-height:var(--wcss-body-sm-emphasized-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-xs-weight, );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-xs-emphasized{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-xs-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-xs-emphasized-font-size, 0.75rem);line-height:var(--wcss-body-xs-emphasized-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-2xs-weight, );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)}.body-2xs-emphasized{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-2xs-emphasized-weight, );letter-spacing:var(--wcss-body-letter-spacing, 0);font-size:var(--wcss-body-2xs-emphasized-font-size, 0.625rem);line-height:var(--wcss-body-2xs-emphasized-line-height, 0.875rem)}.display-2xl{font-family:var(--wcss-display-2xl-family, "AS Circular"),var(--wcss-display-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-2xl-letter-spacing, 0)}.display-xl{font-family:var(--wcss-display-xl-family, "AS Circular"),var(--wcss-display-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-xl-letter-spacing, 0)}.display-lg{font-family:var(--wcss-display-lg-family, "AS Circular"),var(--wcss-display-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-lg-letter-spacing, 0)}.display-md{font-family:var(--wcss-display-md-family, "AS Circular"),var(--wcss-display-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-md-letter-spacing, 0)}.display-sm{font-family:var(--wcss-display-sm-family, "AS Circular"),var(--wcss-display-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-sm-letter-spacing, 0)}.display-xs{font-family:var(--wcss-display-xs-family, "AS Circular"),var(--wcss-display-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-display-xs-letter-spacing, 0)}.heading-xl{font-family:var(--wcss-heading-xl-family, "AS Circular"),var(--wcss-heading-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-xl-letter-spacing, 0)}.heading-lg{font-family:var(--wcss-heading-lg-family, "AS Circular"),var(--wcss-heading-lg-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-lg-letter-spacing, 0)}.heading-md{font-family:var(--wcss-heading-md-family, "AS Circular"),var(--wcss-heading-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-md-letter-spacing, 0)}.heading-sm{font-family:var(--wcss-heading-sm-family, "AS Circular"),var(--wcss-heading-sm-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-heading-sm-letter-spacing, 0)}.heading-xs{font-family:var(--wcss-heading-xs-family, "AS Circular"),var(--wcss-heading-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-weight:var(--wcss-heading-xs-weight, 300);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));letter-spacing:var(--wcss-heading-xs-letter-spacing, 0)}.heading-2xs{font-family:var(--wcss-heading-2xs-family, "AS Circular"),var(--wcss-heading-2xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-weight:var(--wcss-heading-2xs-weight, 300);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));letter-spacing:var(--wcss-heading-2xs-letter-spacing, 0)}.accent-2xl{font-family:var(--wcss-accent-2xl-family, "Good OT"),var(--wcss-accent-2xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-2xl-letter-spacing, 0.05em);text-transform:uppercase}.accent-xl{font-family:var(--wcss-accent-xl-family, "Good OT"),var(--wcss-accent-xl-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-xl-letter-spacing, 0.05em);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);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));letter-spacing:var(--wcss-accent-lg-letter-spacing, 0.05em);text-transform:uppercase}.accent-md{font-family:var(--wcss-accent-md-family, "Good OT"),var(--wcss-accent-md-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-md-letter-spacing, 0.05em);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);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));letter-spacing:var(--wcss-accent-sm-letter-spacing, 0.05em);text-transform:uppercase}.accent-xs{font-family:var(--wcss-accent-xs-family, "Good OT"),var(--wcss-accent-xs-family-fallback, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);font-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));letter-spacing:var(--wcss-accent-xs-letter-spacing, 0.1em);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);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));letter-spacing:var(--wcss-accent-2xs-letter-spacing, 0.1em);text-transform:uppercase}:host{cursor:pointer;user-select:none;text-overflow:ellipsis;max-width:100dvw}:host .wrapper{display:flex;align-items:center;height:var(--ds-size-400, 2rem);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));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}`;
10063
+
10064
+ var colorCss = i$6`: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(.active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}@media(hover: hover){:host(:hover){--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].active){--ds-auro-menuoption-container-color: var(--ds-basic-color-surface-accent1-muted, #ebfafd)}@media(hover: hover){:host([selected]:hover){--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.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)}@media(hover: hover){:host(:focus:hover){--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.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)}@media(hover: hover){:host([selected]:focus:hover){--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)}}`;
10065
+
10066
+ 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)}getSlotText(t,a){const e=t.shadowRoot?.querySelector(`slot[name="${a}"]`);return (e?.assignedNodes({flatten:true})||[]).map(t=>t.textContent?.trim()).join(" ").trim()||null}}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>',g='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="min-width:100%;height:auto;fill:currentColor" viewBox="0 0 142 138" part="svg"><title id="tail-DEFAULT__title">Airplane tail default image with light gray color</title><path fill="url(#paint0_linear_9225_2069)" fill-rule="evenodd" d="M124.093 14.665a3.26 3.26 0 0 1 3.208 3.829L101.097 119.85c-.47 1.087-2.211 3.398-5.692 3.471l-.106.001-80.65.013A659230 659230 0 0 1 99.08 17.412c1.214-1.497 3.275-2.722 5.372-2.747z" clip-rule="evenodd"/><defs><linearGradient id="paint0_linear_9225_2069" x1="114.823" x2="60.061" y1="14.665" y2="123.335" gradientUnits="userSpaceOnUse"><stop offset=".5" stop-color="#707984"/><stop offset=".5" stop-color="#646E7B"/></linearGradient></defs></svg>';class m extends i$3{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 f=new Map,w=(t,a={})=>{const e=a.responseParser||(t=>t.text());return f.has(t)||f.set(t,fetch(t).then(e)),f.get(t)};var z=i$6`: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}
10067
+ `;class y extends m{constructor(){super(),this._initializeDefaults();}_initializeDefaults(){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 z}async fetchIcon(t,a){let e="";e="logos"===t?await w(`${this.uri}/${t}/${a}.svg`):await w(`${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=this.name?.startsWith("tail-")?g:u;this.svg=(new DOMParser).parseFromString(t,"text/html").body.querySelector("svg");}}}catch(t){this.svg=void 0;}}}i$6`.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}
10068
+ `;var M=i$6`: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)}
10069
+ `;var _=i$6`: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)}
10070
+ `;class k extends y{constructor(){super(),this._initializeDefaults();}_initializeDefaults(){this.variant=void 0,this.uri="https://cdn.jsdelivr.net/npm/@alaskaairux/icons@latest/dist",this.runtimeUtils=new p;}static get properties(){return {...y.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 [y.styles,M,z,_]}static register(t="auro-icon"){p.prototype.registerComponent(t,k);}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 b$1`
10071
+ <div class="componentWrapper">
10072
+ <div
10073
+ class="${e$3({svgWrapper:true})}"
10074
+ title="${o(this.title||void 0)}">
10075
+ <span aria-hidden="${o(this.ariaHidden||true)}" part="svg">
10076
+ ${this.customSvg?b$1`
10077
+ <slot name="svg"></slot>
10078
+ `:b$1`
10079
+ ${this.svg}
10080
+ `}
10081
+ </span>
10082
+ </div>
10083
+
10084
+ <div class="${e$3(t)}" part="label">
10085
+ <slot></slot>
10086
+ </div>
10087
+ </div>
10088
+ `}}
10089
+
10090
+ var iconVersion = '9.1.2';
10091
+
10092
+ 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>"};
10093
+
10094
+ // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
10095
+ // See LICENSE in the project root for license information.
10096
+
10097
+
10098
+ let menuOptionIdCounter = 0;
10099
+
10100
+ /**
10101
+ * The `auro-menuoption` element provides users a way to define a menu option.
10102
+ * @customElement auro-menuoption
10103
+ *
10104
+ * @slot default - The default slot for the menu option text.
10105
+ *
10106
+ * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
10107
+ */
10108
+ class AuroMenuOption extends AuroElement$1 {
10213
10109
 
10214
10110
  /**
10215
10111
  * This will register this element with the browser.
10216
- * @param {string} [name="auro-menu"] - The name of the element that you want to register.
10112
+ * @param {string} [name="auro-menuoption"] - The name of the element that you want to register.
10217
10113
  *
10218
10114
  * @example
10219
- * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
10115
+ * AuroMenuOption.register("custom-menuoption") // this will register this element to <custom-menuoption/>
10220
10116
  *
10221
10117
  */
10222
- static register(name = "auro-menu") {
10223
- AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenu);
10118
+ static register(name = "auro-menuoption") {
10119
+ AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenuOption);
10224
10120
  }
10225
10121
 
10226
10122
  /**
10227
- * Formatted value based on `multiSelect` state.
10228
- * Default type is `String`, changing to `Array<String>` when `multiSelect` is true.
10229
- * @private
10230
- * @returns {String|Array<String>}
10123
+ * Returns whether the menu option is currently active and selectable.
10124
+ * An option is considered active if it is not hidden, not disabled, and not static.
10125
+ * @returns {boolean} True if the option is active, false otherwise.
10231
10126
  */
10232
- get formattedValue() {
10233
- return this.menuService.currentValue;
10127
+ get isActive() {
10128
+ return !this.hasAttribute('hidden') &&
10129
+ !this.disabled &&
10130
+ !this.hasAttribute('static');
10234
10131
  }
10235
10132
 
10236
- /**
10237
- * Gets the current property values for the menu service.
10238
- * @private
10239
- * @returns {Object}
10240
- */
10241
- get propertyValues() {
10242
- return {
10243
- size: this.size,
10244
- shape: this.shape,
10245
- noCheckmark: this.nocheckmark,
10246
- disabled: this.disabled
10247
- };
10248
- }
10133
+ constructor() {
10134
+ super();
10249
10135
 
10250
- /**
10251
- * Provides the menu context to child components.
10252
- * Initializes the MenuService and subscribes to menu changes.
10253
- * @protected
10254
- */
10255
- provideContext() {
10256
- if (this.parentElement && this.parentElement.closest('auro-menu, [auro-menu]')) {
10257
- this.rootMenu = false;
10258
- this.menuService = this.parentElement.menuService;
10259
- this._contextProvider = this.parentElement._contextProvider;
10260
- return;
10261
- }
10136
+ this.bindEvents();
10262
10137
 
10263
- this.menuService = new MenuService({host: this});
10264
- this.menuService.setProperties(this.propertyValues);
10265
- this.menuService.subscribe(this.handleMenuChange.bind(this));
10266
- this._contextProvider = new i(this, {
10267
- context: MenuContext,
10268
- initialValue: this.menuService
10269
- });
10270
- }
10138
+ /**
10139
+ * @private
10140
+ */
10141
+ this.shape = undefined;
10271
10142
 
10272
- /**
10273
- * Updates the currently active option in the menu.
10274
- * @param {HTMLElement} option - The option to set as active.
10275
- */
10276
- updateActiveOption(option) {
10277
- this.menuService.setHighlightedOption(option);
10278
- }
10143
+ /**
10144
+ * @private
10145
+ */
10146
+ this.size = undefined;
10279
10147
 
10280
- /**
10281
- * Sets the internal value and manages update state.
10282
- * @param {String|Array<String>} value - The value to set.
10283
- * @protected
10284
- */
10285
- setInternalValue(value) {
10286
- if (this.value !== value) {
10287
- this.internalUpdateInProgress = true;
10288
- this.value = value;
10148
+ /**
10149
+ * Generate unique names for dependency components.
10150
+ */
10151
+ const versioning = new AuroDependencyVersioning$2();
10152
+ this.iconTag = versioning.generateTag('auro-formkit-menuoption-icon', iconVersion, k);
10289
10153
 
10290
- setTimeout(() => {
10291
- this.internalUpdateInProgress = false;
10292
- });
10293
- }
10154
+ this.selected = false;
10155
+ this.noCheckmark = false;
10156
+ this.disabled = false;
10157
+ this.noMatch = false;
10158
+
10159
+ /**
10160
+ * @private
10161
+ */
10162
+ this.runtimeUtils = new AuroLibraryRuntimeUtils$3();
10163
+
10164
+ // Initialize context-related properties
10165
+ this.menuService = null;
10166
+ this.unsubscribe = null;
10167
+
10168
+ /**
10169
+ * @private
10170
+ */
10171
+ this.handleMenuChange = this.handleMenuChange.bind(this);
10294
10172
  }
10295
10173
 
10296
- /**
10297
- * Handles changes from the menu service and updates component state.
10298
- * @param {Object} event - The event object from the menu service.
10299
- * @protected
10300
- */
10301
- handleMenuChange(event) {
10302
- if (event.type === 'valueChange') {
10174
+ static get properties() {
10175
+ return {
10176
+ ...super.properties,
10177
+
10178
+ /**
10179
+ * When true, disables the menu option.
10180
+ */
10181
+ disabled: {
10182
+ type: Boolean,
10183
+ reflect: true
10184
+ },
10185
+
10186
+ /**
10187
+ * @private
10188
+ */
10189
+ event: {
10190
+ type: String,
10191
+ reflect: true
10192
+ },
10193
+
10194
+ /**
10195
+ * @private
10196
+ */
10197
+ layout: {
10198
+ type: String
10199
+ },
10200
+
10201
+ /**
10202
+ * Allows users to set a unique key for the menu option for specified option selection. If no key is provided, the value property will be used.
10203
+ */
10204
+ key: {
10205
+ type: String,
10206
+ reflect: true
10207
+ },
10208
+
10209
+ /**
10210
+ * @private
10211
+ */
10212
+ menuService: {
10213
+ type: Object,
10214
+ state: true
10215
+ },
10303
10216
 
10304
- // New option is array value or first option with fallback to undefined for empty array in all cases
10305
- const newOption = this.multiSelect && event.options.length ? event.options : event.options[0] || undefined;
10306
- const newValue = event.stringValue;
10217
+ /**
10218
+ * @private
10219
+ */
10220
+ matchWord: {
10221
+ type: String,
10222
+ state: true
10223
+ },
10307
10224
 
10308
- // Check if the option or value has actually changed
10309
- if (this.optionSelected !== newOption || this.stringValue !== newValue) {
10310
- this.optionSelected = newOption;
10311
- this.setInternalValue(newValue);
10312
- }
10225
+ /**
10226
+ * @private
10227
+ */
10228
+ noCheckmark: {
10229
+ type: Boolean,
10230
+ reflect: true
10231
+ },
10313
10232
 
10314
- // Notify components of selection change
10315
- this.notifySelectionChange(event);
10316
- }
10233
+ /**
10234
+ * When true, marks this option as the "no matching results" placeholder shown by combobox when the user's input does not match any available options. Enables distinct styling and prevents the option from being treated as a selectable match.
10235
+ */
10236
+ noMatch: {
10237
+ type: Boolean,
10238
+ reflect: true,
10239
+ attribute: 'nomatch'
10240
+ },
10317
10241
 
10318
- if (event.type === 'highlightChange') {
10319
- this.optionActive = event.option;
10320
- this._index = event.index;
10321
- }
10242
+ /**
10243
+ * Specifies that an option is selected.
10244
+ */
10245
+ selected: {
10246
+ type: Boolean,
10247
+ reflect: true
10248
+ },
10322
10249
 
10323
- if (event.type === 'optionsChange') {
10324
- this.options = event.options;
10325
- this.dispatchEvent(new CustomEvent('auroMenu-optionsChange', {
10326
- detail: {
10327
- options: event.options
10328
- }
10329
- }));
10330
- }
10331
- }
10250
+ /**
10251
+ * Specifies the tab index of the menu option.
10252
+ */
10253
+ tabIndex: {
10254
+ type: Number,
10255
+ reflect: true
10256
+ },
10332
10257
 
10333
- /**
10334
- * Gets the currently selected options.
10335
- * @returns {Array<HTMLElement>}
10336
- */
10337
- get selectedOptions() {
10338
- return this.menuService ? this.menuService.selectedOptions : [];
10258
+ /**
10259
+ * Specifies the value to be sent to a server.
10260
+ */
10261
+ value: {
10262
+ type: String,
10263
+ reflect: true
10264
+ },
10265
+ };
10339
10266
  }
10340
10267
 
10341
- /**
10342
- * Gets the first selected option, or null if none.
10343
- * @returns {HTMLElement|null}
10344
- */
10345
- get selectedOption() {
10346
- return this.menuService ? this.menuService.selectedOptions[0] : null;
10268
+ static get styles() {
10269
+ return [
10270
+ styleCss,
10271
+ colorCss,
10272
+ tokensCss
10273
+ ];
10347
10274
  }
10348
10275
 
10349
- // Lifecycle Methods
10350
-
10351
10276
  connectedCallback() {
10352
10277
  super.connectedCallback();
10353
10278
 
10354
- this.provideContext();
10355
-
10356
- // this.addEventListener('keydown', this.handleKeyDown);
10357
- this.addEventListener('auroMenuOption-click', this.handleMouseSelect);
10358
- this.addEventListener('auroMenuOption-mouseover', this.handleOptionHover);
10359
- this.addEventListener('slotchange', this.handleSlotChange);
10360
- this.setTagAttribute("auro-menu");
10361
- }
10279
+ // Add the tag name as an attribute if it is different than the component name
10280
+ // Add this step soon as this node gets attached to the DOM to avoid racing condition with menu's value setting logic.
10281
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
10362
10282
 
10363
- disconnectedCallback() {
10364
- // this.removeEventListener('keydown', this.handleKeyDown);
10365
- this.removeEventListener('auroMenuOption-click', this.handleMouseSelect);
10366
- this.removeEventListener('auroMenuOption-mouseover', this.handleOptionHover);
10367
- this.removeEventListener('slotchange', this.handleSlotChange);
10283
+ // Set up context consumption in connectedCallback
10284
+ this._contextConsumer = new s$1(this, {
10285
+ context: MenuContext,
10286
+ callback: this.attachTo.bind(this),
10287
+ subscribe: true
10288
+ });
10368
10289
 
10369
- super.disconnectedCallback();
10290
+ // Establish the key property as early as possible.
10291
+ // When a framework (e.g. Svelte) inserts the element into the DOM before
10292
+ // setting its `value` property, both `getAttribute('value')` and
10293
+ // `getAttribute('key')` return null here. Setting `this.key = null`
10294
+ // would block the fallback in `updated()` that assigns key from the
10295
+ // value property (the guard checked `=== undefined`). Only assign key
10296
+ // if at least one source attribute is actually present so that the
10297
+ // `updated()` fallback can run when the value property arrives later.
10298
+ const valueAttr = this.getAttribute('value');
10299
+ const keyAttr = this.getAttribute('key');
10300
+ const resolvedKey = keyAttr !== null ? keyAttr : valueAttr;
10301
+ if (resolvedKey !== null) {
10302
+ this.key = resolvedKey;
10303
+ }
10370
10304
  }
10371
10305
 
10372
10306
  firstUpdated() {
10373
- AuroLibraryRuntimeUtils$3.prototype.handleComponentTagRename(this, 'auro-menu');
10307
+ // Add the tag name as an attribute if it is different than the component name
10308
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
10374
10309
 
10375
- this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
10376
- this.initializeMenu();
10377
- }
10310
+ // Generate unique ID if not already set (required for aria-activedescendant)
10311
+ if (!this.id) {
10312
+ menuOptionIdCounter += 1;
10313
+ this.id = `menuoption-${menuOptionIdCounter}`;
10314
+ }
10315
+
10316
+ this.setAttribute('role', 'option');
10317
+ this.setAttribute('aria-selected', 'false');
10378
10318
 
10319
+ this.addEventListener('mouseover', () => {
10320
+ this.dispatchEvent(new CustomEvent('auroMenuOption-mouseover', {
10321
+ bubbles: true,
10322
+ cancelable: false,
10323
+ composed: true,
10324
+ detail: this
10325
+ }));
10326
+ });
10327
+ }
10379
10328
 
10380
10329
  updated(changedProperties) {
10381
10330
  super.updated(changedProperties);
10382
10331
 
10383
- // Apply value selection synchronously so that static-HTML fixtures
10384
- // resolve within a single update cycle. The refactored selectByValue
10385
- // no longer calls reset() first, so the destructive intermediate-event
10386
- // cascade that originally required deferral is eliminated. If option
10387
- // keys are not yet resolved (framework mount-order race), selectByValue
10388
- // queues a bounded retry automatically via queuePendingValue.
10389
- if (changedProperties.has('value') && !this.internalUpdateInProgress) {
10390
- this.menuService.selectByValue(this.value);
10391
- }
10332
+ // Update aria-selected attribute if selected changed
10333
+ if (changedProperties.has('selected')) {
10392
10334
 
10393
- // Handle loading state changes
10394
- if (changedProperties.has('loading')) {
10395
- this.setLoadingState(this.loading);
10335
+ // Update aria-selected attribute
10336
+ this.setAttribute('aria-selected', this.selected.toString());
10337
+
10338
+ // Update menu service selection state if this isn't an internal update
10339
+ if (this.internalUpdateInProgress !== true && this.menuService) {
10340
+ this.menuService[this.selected ? 'selectOption' : 'deselectOption'](this);
10341
+ }
10396
10342
  }
10397
10343
 
10398
- if (changedProperties.has('multiSelect') && this.rootMenu) {
10399
- if (this.multiSelect) {
10400
- this.setAttribute('aria-multiselectable', 'true');
10344
+ if (changedProperties.has('disabled')) {
10345
+ if (this.disabled) {
10346
+ this.setAttribute('aria-disabled', 'true');
10401
10347
  } else {
10402
- this.removeAttribute('aria-multiselectable');
10348
+ this.removeAttribute('aria-disabled');
10403
10349
  }
10404
10350
  }
10351
+
10352
+ if (changedProperties.has('active')) {
10353
+ this.updateActiveClasses();
10354
+ }
10355
+
10356
+ // Update text highlight if matchWord changed
10357
+ if (changedProperties.has('matchWord')) {
10358
+ this.updateTextHighlight();
10359
+ }
10360
+
10361
+ // Set the key to be the passed value if no key is provided.
10362
+ // Loose equality (== null) is intentional: it catches both null AND
10363
+ // undefined. When a framework (e.g. Svelte, React) inserts the element
10364
+ // before setting its value property, connectedCallback skips key
10365
+ // assignment because both attributes are null at that point. The Lit
10366
+ // property default for `key` is undefined (not null), so strict
10367
+ // === null would miss the case and the fallback would never run.
10368
+ if (changedProperties.has('value') && this.key == null) { // eslint-disable-line eqeqeq, no-eq-null
10369
+ this.key = this.value;
10370
+ }
10371
+ }
10372
+
10373
+ disconnectedCallback() {
10374
+ if (this.menuService) {
10375
+ this.menuService.unsubscribe(this.handleMenuChange);
10376
+ this.menuService.removeMenuOption(this);
10377
+ }
10405
10378
  }
10406
10379
 
10407
10380
  /**
10408
- * Sets an attribute that matches the default tag name if the tag name is not the default.
10409
- * @param {string} tagName - The tag name to set as an attribute.
10410
- * @private
10381
+ * Sets up event listeners for user interaction with the menu option.
10382
+ * This function enables click and mouse enter events to trigger selection and highlighting logic.
10411
10383
  */
10412
- setTagAttribute(tagName) {
10413
- if (this.tagName.toLowerCase() !== tagName) {
10414
- this.setAttribute(tagName, true);
10415
- }
10384
+ bindEvents() {
10385
+ this.addEventListener('click', this.handleClick.bind(this));
10386
+ this.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
10416
10387
  }
10417
10388
 
10418
10389
  /**
10419
- * Sets the loading state and dispatches a loading change event.
10420
- * @param {boolean} isLoading - Whether the menu is loading.
10421
- * @protected
10390
+ * Attaches this menu option to a menu service and subscribes to its events.
10391
+ * This method enables the option to participate in menu selection and highlighting logic.
10392
+ * @param {Object} service - The menu service instance to attach to.
10422
10393
  */
10423
- setLoadingState(isLoading) {
10424
- this.setAttribute("aria-busy", isLoading);
10425
- dispatchMenuEvent(this, "auroMenu-loadingChange", {
10426
- loading: isLoading,
10427
- hasLoadingPlaceholder: this.hasLoadingPlaceholder
10428
- });
10394
+ attachTo(service) {
10395
+ if (!service) {
10396
+ return;
10397
+ }
10398
+ this.menuService = service;
10399
+ this.menuService.addMenuOption(this);
10400
+ this.menuService.subscribe(this.handleMenuChange);
10429
10401
  }
10430
10402
 
10431
- // Init Methods
10403
+ /**
10404
+ * Handles changes from the menu service and updates the option's state.
10405
+ * This function synchronizes the option's properties and selection/highlight state with menu events.
10406
+ * @param {Object} event - The event object from the menu service.
10407
+ */
10408
+ handleMenuChange(event) {
10409
+
10410
+ // Ignore events without a type or property
10411
+ if (!event || (!event.type && !event.property)) {
10412
+ return;
10413
+ }
10414
+
10415
+ // Update reactive properties based on event type
10416
+ if (event.property && Object.keys(AuroMenuOption.properties).includes(event.property)) {
10417
+ this[event.property] = event.value;
10418
+ }
10419
+
10420
+ // Handle highlight changes
10421
+ if (event.type === 'highlightChange') {
10422
+ const isActive = event.option === this;
10423
+ this.active = isActive;
10424
+ this.updateActiveClasses();
10425
+ }
10426
+
10427
+ if (event.type === 'stateChange') {
10428
+ const isSelected = event.selectedOptions.includes(this);
10429
+ this.setInternalSelected(isSelected);
10430
+ }
10431
+ }
10432
10432
 
10433
10433
  /**
10434
- * Initializes the menu's state and structure.
10435
- * @private
10434
+ * Updates the internal selected state of the menu option bypassing 'updated' and triggers custom events if selected.
10435
+ * This function ensures the option's selection state is synchronized with menu logic and notifies listeners.
10436
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
10436
10437
  */
10437
- initializeMenu() {
10438
- if (this.rootMenu) {
10439
- this.setAttribute('role', 'listbox');
10440
- this.setAttribute('root', '');
10438
+ setInternalSelected(isSelected) {
10439
+ this.internalUpdateInProgress = true;
10440
+ this.selected = isSelected;
10441
10441
 
10442
- if (this.multiSelect) {
10443
- this.setAttribute('aria-multiselectable', 'true');
10444
- }
10442
+ // Fire custom event if selected
10443
+ if (isSelected) {
10444
+ this.handleCustomEvent();
10445
10445
  }
10446
10446
 
10447
- this.handleNestedMenus(this);
10447
+ setTimeout(() => {
10448
+ this.internalUpdateInProgress = false;
10449
+ }, 0);
10448
10450
  }
10449
10451
 
10450
10452
  /**
10451
- * Selects the currently highlighted option.
10452
- * @protected
10453
+ * Sets the selected state of the menu option.
10454
+ * This function updates whether the option is currently selected.
10455
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
10456
+ * @deprecated Simply modify the `selected` property directly instead.
10453
10457
  */
10454
- makeSelection() {
10455
- this.menuService.selectHighlightedOption();
10458
+ setSelected(isSelected) {
10459
+ this.selected = isSelected;
10456
10460
  }
10457
10461
 
10458
10462
  /**
10459
- * Resets all options to their default state.
10460
- * @private
10463
+ * Updates the active state and visual highlighting of the menu option.
10464
+ * This function toggles the option's active status and applies or removes the active CSS class.
10465
+ * @param {boolean} isActive - Whether the option should be marked as active.
10466
+ * @deprecated Simply modify the `active` property directly instead.
10461
10467
  */
10462
- clearSelection() {
10463
- this.optionSelected = undefined;
10464
- this.value = undefined;
10465
- this._index = -1;
10468
+ updateActive(isActive) {
10469
+
10470
+ // Set active state
10471
+ this.active = isActive;
10472
+ this.updateActiveClasses();
10466
10473
  }
10467
10474
 
10468
10475
  /**
10469
- * Resets the menu to its initial state.
10470
- * This is the only way to return value to undefined.
10471
- * @public
10476
+ * Updates the CSS class for the menu option based on its active state.
10477
+ * This function adds or removes the 'active' class to visually indicate the option's active status.
10478
+ * @private
10472
10479
  */
10473
- reset() {
10474
- this.menuService.reset();
10475
-
10476
- // Dispatch reset event
10477
- dispatchMenuEvent(this, 'auroMenu-selectValueReset');
10480
+ updateActiveClasses() {
10481
+ // Update class based on active state
10482
+ if (this.active) this.classList.add('active');
10483
+ else this.classList.remove('active');
10478
10484
  }
10479
10485
 
10486
+
10480
10487
  /**
10481
- * Handles nested menu structure.
10488
+ * Updates the visual highlighting of text within the menu option based on the current match word.
10489
+ * This function highlights matching text segments and manages nested spacers for display formatting.
10482
10490
  * @private
10483
- * @param {HTMLElement} menu - Root menu element.
10484
10491
  */
10485
- handleNestedMenus(menu) {
10486
- menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
10492
+ updateTextHighlight() {
10487
10493
 
10488
- if (menu.level > 0) {
10489
- menu.setAttribute('role', 'group');
10490
- menu.removeAttribute("root");
10491
- if (!menu.hasAttribute('aria-label')) {
10492
- menu.setAttribute('aria-label', 'submenu');
10493
- }
10494
+ // Regex for matchWord if needed
10495
+ let regexWord = null;
10496
+
10497
+ if (this.matchWord && this.matchWord.length) {
10498
+ const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
10499
+ regexWord = new RegExp(escapedWord, 'giu');
10494
10500
  }
10495
10501
 
10496
- const options = menu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption]');
10497
- options.forEach((option) => {
10498
- const regex = new RegExp(this.nestingSpacer, "gu");
10499
- option.innerHTML = this.nestingSpacer.repeat(menu.level) + option.innerHTML.replace(regex, '');
10500
- });
10501
- }
10502
+ // Update text highlighting if matchWord changed
10503
+ if (regexWord &&
10504
+ this.isActive && !this.hasAttribute('persistent')) {
10505
+ const nested = this.querySelectorAll('.nestingSpacer');
10502
10506
 
10503
- /**
10504
- * Navigates the menu options in the specified direction.
10505
- * @param {'up'|'down'} direction - The direction to navigate.
10506
- * @protected
10507
- */
10508
- navigateOptions(direction) {
10509
- if (direction === 'up') {
10510
- this.menuService.highlightPrevious();
10511
- } else if (direction === 'down') {
10512
- this.menuService.highlightNext();
10513
- }
10514
- }
10507
+ const displayValueEl = this.querySelector('[slot="displayValue"]');
10508
+ if (displayValueEl) {
10509
+ this.removeChild(displayValueEl);
10510
+ }
10515
10511
 
10516
- /**
10517
- * Handles slot change events.
10518
- * @private
10519
- */
10520
- handleSlotChange() {
10521
- if (this.rootMenu) {
10522
- this.initializeMenu();
10512
+ // Create nested spacers
10513
+ const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
10514
+
10515
+ // Update with spacers and matchWord
10516
+ this.innerHTML = nestingSpacerBundle +
10517
+ this.textContent.replace(
10518
+ regexWord,
10519
+ (match) => `<strong>${match}</strong>`
10520
+ );
10521
+ if (displayValueEl) {
10522
+ this.append(displayValueEl);
10523
+ }
10523
10524
  }
10524
10525
  }
10525
10526
 
10526
10527
  /**
10527
- * Handles custom events defined on options.
10528
+ * Handles click events on the menu option, toggling its selected state.
10529
+ * This function dispatches a click event and updates selection if the option is not disabled.
10528
10530
  * @private
10529
- * @param {HTMLElement} option - Option with custom event.
10530
10531
  */
10531
- handleCustomEvent(option) {
10532
- const eventName = option.getAttribute('event');
10533
- dispatchMenuEvent(this, eventName);
10534
- dispatchMenuEvent(this, 'auroMenu-customEventFired');
10532
+ handleClick() {
10533
+ if (!this.disabled && !this.menuService?.disabled) {
10534
+ this.dispatchClickEvent();
10535
+ this.selected = !this.selected;
10536
+ }
10535
10537
  }
10536
10538
 
10537
10539
  /**
10538
- * Notifies selection change to parent components.
10539
- * @param {any} source - The source that triggers this event.
10540
+ * Handles mouse enter events to highlight the menu option.
10541
+ * This function updates the menu service to set this option as the currently highlighted item if not disabled.
10540
10542
  * @private
10541
10543
  */
10542
- notifySelectionChange({value, stringValue, keys, options, reason} = {}) {
10543
- dispatchMenuEvent(this, 'auroMenu-selectedOption', {
10544
- value,
10545
- stringValue,
10546
- keys,
10547
- options,
10548
- reason
10549
- });
10544
+ handleMouseEnter() {
10545
+ if (!this.disabled) {
10546
+ this.menuService.setHighlightedOption(this);
10547
+ }
10550
10548
  }
10551
10549
 
10552
10550
  /**
10553
- * Checks if an option is currently selected.
10551
+ * Dispatches custom events defined for this menu option.
10552
+ * This function notifies listeners when a custom event is triggered by the option.
10554
10553
  * @private
10555
- * @param {HTMLElement} option - The option to check.
10556
- * @returns {boolean}
10557
10554
  */
10558
- isOptionSelected(option) {
10559
- if (!this.optionSelected) {
10560
- return false;
10561
- }
10562
-
10563
- if (this.multiSelect) {
10564
- // In multi-select mode, check if the option is in the selected array
10565
- return Array.isArray(this.optionSelected) && this.optionSelected.some((selectedOption) => selectedOption === option);
10555
+ handleCustomEvent() {
10556
+ if (this.event) {
10557
+ dispatchMenuEvent(this, this.event, { option: this });
10558
+ dispatchMenuEvent(this, 'auroMenu-customEventFired', { option: this });
10566
10559
  }
10567
-
10568
- return this.optionSelected === option;
10569
10560
  }
10570
10561
 
10571
10562
  /**
10572
- * Getter for loading placeholder state.
10573
- * @returns {boolean} - True if loading slots are present and non-empty.
10563
+ * Dispatches a click event for this menu option.
10564
+ * This function notifies listeners that the option has been clicked.
10565
+ * @private
10574
10566
  */
10575
- get hasLoadingPlaceholder() {
10576
- return this.loadingSlots && this.loadingSlots.length > 0;
10567
+ dispatchClickEvent() {
10568
+ this.dispatchEvent(new CustomEvent('auroMenuOption-click', {
10569
+ bubbles: true,
10570
+ cancelable: false,
10571
+ composed: true,
10572
+ detail: this
10573
+ }));
10577
10574
  }
10578
10575
 
10579
10576
  /**
10580
- * Getter for wrapper classes based on size.
10581
- * @returns {Object} - Class map for the wrapper element.
10577
+ * Generates an HTML element containing an SVG icon based on the provided `svgContent`.
10578
+ *
10582
10579
  * @private
10580
+ * @param {string} svgContent - The SVG content to be embedded.
10581
+ * @returns {Element} The HTML element containing the SVG icon.
10583
10582
  */
10584
- get wrapperClasses() {
10585
- return e$3({
10586
- 'menuWrapper': true,
10587
- [this.size]: true,
10588
- });
10583
+ generateIconHtml(svgContent) {
10584
+ const dom = new DOMParser().parseFromString(svgContent, 'text/html');
10585
+ const svg = dom.body.firstChild;
10586
+
10587
+ svg.setAttribute('slot', 'svg');
10588
+
10589
+ return u$4`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
10589
10590
  }
10590
10591
 
10591
10592
  /**
@@ -10594,26 +10595,26 @@ class AuroMenu extends AuroElement$1 {
10594
10595
  * @returns {void}
10595
10596
  */
10596
10597
  renderLayout() {
10597
- if (this.loading) {
10598
- return b$1`
10599
- <div class="${this.wrapperClasses}">
10600
- <auro-menuoption
10601
- disabled
10602
- loadingplaceholder
10603
- class="${this.hasLoadingPlaceholder ? "" : "empty"}"
10604
- >
10605
- <div>
10606
- <slot name="loadingIcon" class="body-lg"></slot>
10607
- <slot name="loadingText"></slot>
10608
- </div>
10609
- </auro-menuoption>
10610
- </div>
10611
- `;
10612
- }
10613
10598
 
10614
- return b$1`
10615
- <div class="${this.wrapperClasses}">
10616
- <slot @slotchange=${this.handleSlotChange}></slot>
10599
+ const fontClassMap = {
10600
+ xs: 'body-sm',
10601
+ sm: 'body-default',
10602
+ md: 'body-default',
10603
+ lg: 'body-lg',
10604
+ xl: 'body-lg'
10605
+ };
10606
+
10607
+ const classes = e$3({
10608
+ 'wrapper': true,
10609
+ [this.size ? fontClassMap[this.size] : 'body-sm']: true,
10610
+ });
10611
+
10612
+ return u$4`
10613
+ <div class="${classes}">
10614
+ ${this.selected && !this.noCheckmark
10615
+ ? this.generateIconHtml(checkmarkIcon.svg)
10616
+ : undefined}
10617
+ <slot></slot>
10617
10618
  </div>
10618
10619
  `;
10619
10620
  }