@aurodesignsystem-dev/auro-formkit 0.0.0-pr1460.2 → 0.0.0-pr1462.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 (80) 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 +1506 -1506
  10. package/components/combobox/dist/index.js +3 -3
  11. package/components/combobox/dist/registered.js +3 -3
  12. package/components/counter/demo/api.html +5 -29
  13. package/components/counter/demo/getting-started.md +4 -3
  14. package/components/counter/demo/index.min.js +8392 -1
  15. package/components/counter/dist/index.js +106 -5110
  16. package/components/counter/dist/registered.js +106 -5110
  17. package/components/datepicker/demo/accessibility.html +0 -1
  18. package/components/datepicker/demo/api.html +4 -29
  19. package/components/datepicker/demo/getting-started.md +25 -2
  20. package/components/datepicker/demo/index.min.js +24612 -1
  21. package/components/datepicker/demo/readme.html +2 -10
  22. package/components/datepicker/dist/index.js +3 -3
  23. package/components/datepicker/dist/registered.js +3 -3
  24. package/components/dropdown/demo/api.html +5 -31
  25. package/components/dropdown/demo/getting-started.md +34 -2
  26. package/components/dropdown/demo/index.min.js +5097 -1
  27. package/components/dropdown/dist/index.js +1 -1
  28. package/components/dropdown/dist/registered.js +1 -1
  29. package/components/form/demo/api.html +5 -27
  30. package/components/form/demo/getting-started.md +5 -6
  31. package/components/form/demo/index.min.js +719 -2
  32. package/components/form/demo/keyboard-behavior.md +38 -0
  33. package/components/form/demo/pages.json +1 -1
  34. package/components/form/demo/registerDemoDeps.min.js +11590 -60657
  35. package/components/input/demo/accessibility.md +1 -1
  36. package/components/input/demo/api.html +15 -26
  37. package/components/input/demo/auro-input.min.js +1 -1
  38. package/components/input/demo/getting-started.md +1 -1
  39. package/components/input/demo/readme.html +2 -10
  40. package/components/input/dist/index.js +1 -1
  41. package/components/input/dist/registered.js +1 -1
  42. package/components/menu/demo/api.html +5 -30
  43. package/components/menu/demo/getting-started.md +1 -1
  44. package/components/menu/demo/index.min.js +1572 -1572
  45. package/components/menu/dist/auro-menu.context.d.ts +0 -1
  46. package/components/menu/dist/index.js +1607 -1607
  47. package/components/menu/dist/registered.js +1556 -1556
  48. package/components/radio/demo/api.html +7 -28
  49. package/components/radio/demo/getting-started.md +27 -2
  50. package/components/radio/demo/index.min.js +1 -1
  51. package/components/radio/dist/index.js +1 -1
  52. package/components/radio/dist/registered.js +1 -1
  53. package/components/select/demo/api.html +5 -42
  54. package/components/select/demo/getting-started.md +39 -5
  55. package/components/select/demo/registered.min.js +1505 -1505
  56. package/components/select/dist/index.js +2 -2
  57. package/components/select/dist/registered.js +2 -2
  58. package/custom-elements.json +1489 -1489
  59. package/package.json +38 -4
  60. package/components/combobox/demo/api.js +0 -39
  61. package/components/combobox/demo/api.min.js +0 -106
  62. package/components/combobox/demo/install.html +0 -50
  63. package/components/combobox/demo/styles.css +0 -974
  64. package/components/combobox/demo/swap-value.min.js +0 -16
  65. package/components/counter/demo/api.js +0 -24
  66. package/components/counter/demo/api.min.js +0 -52
  67. package/components/counter/demo/auro-counter-group.min.js +0 -8394
  68. package/components/datepicker/demo/api.js +0 -37
  69. package/components/datepicker/demo/api.min.js +0 -300
  70. package/components/datepicker/demo/auro-datepicker.min.js +0 -24614
  71. package/components/dropdown/demo/api.js +0 -26
  72. package/components/dropdown/demo/api.min.js +0 -109
  73. package/components/dropdown/demo/auro-dropdown.min.js +0 -5099
  74. package/components/form/demo/api.js +0 -5
  75. package/components/form/demo/api.min.js +0 -5
  76. package/components/form/demo/auro-form.min.js +0 -718
  77. package/components/form/demo/autocomplete.html +0 -31
  78. package/components/radio/demo/api.js +0 -19
  79. package/components/radio/demo/api.min.js +0 -44
  80. 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 = '202605071937';
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 = '202605071937';
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,1943 @@ 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
+ this.selectedOptions = (this.selectedOptions || [])
8982
+ .filter(opt => !optionsSet.has(opt));
8983
+
8984
+ this.stageUpdate();
9064
8985
  }
9065
8986
 
9066
8987
  /**
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.
8988
+ * Selects a single option.
8989
+ * @param {AuroMenuOption} option
9071
8990
  */
9072
- setSelected(isSelected) {
9073
- this.selected = isSelected;
8991
+ selectOption(option) {
8992
+ this.selectOptions(option);
9074
8993
  }
9075
8994
 
9076
8995
  /**
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.
8996
+ * Deselects a single option.
8997
+ * @param {AuroMenuOption} option
9081
8998
  */
9082
- updateActive(isActive) {
9083
-
9084
- // Set active state
9085
- this.active = isActive;
9086
- this.updateActiveClasses();
8999
+ deselectOption(option) {
9000
+ this.deselectOptions(option);
9087
9001
  }
9088
9002
 
9089
9003
  /**
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
9004
+ * Toggles the selection state of a single option.
9005
+ * @param {AuroMenuOption} option
9093
9006
  */
9094
- updateActiveClasses() {
9095
- // Update class based on active state
9096
- if (this.active) this.classList.add('active');
9097
- else this.classList.remove('active');
9007
+ toggleOption(option) {
9008
+ if (option.selected) {
9009
+ this.deselectOption(option);
9010
+ } else {
9011
+ this.selectOption(option);
9012
+ }
9098
9013
  }
9099
9014
 
9100
-
9101
9015
  /**
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
9016
+ * Selects options based on their value(s) when compared to a passed value or values.
9017
+ * Value or values are normalized to an array of strings that can be matched to option keys.
9018
+ * @param {string|number|Array<string|number>} value - The value(s) to select.
9105
9019
  */
9106
- updateTextHighlight() {
9020
+ selectByValue(value) {
9021
+ const isEmptyValue = value === undefined ||
9022
+ value === null ||
9023
+ (Array.isArray(value) && value.length === 0) ||
9024
+ (typeof value === 'string' && value.trim() === '');
9107
9025
 
9108
- // Regex for matchWord if needed
9109
- let regexWord = null;
9026
+ // Early exit for invalid/empty values
9027
+ if (isEmptyValue) {
9028
+ this.selectedOptions.forEach(opt => opt.selected = false);
9029
+ this.selectedOptions = [];
9030
+ return;
9031
+ }
9110
9032
 
9111
- if (this.matchWord && this.matchWord.length) {
9112
- const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
9113
- regexWord = new RegExp(escapedWord, 'giu');
9033
+ // If an internal update cycle is still in progress, defer value application
9034
+ // rather than dropping it.
9035
+ if (this.internalUpdateInProgress || this.host.internalUpdateInProgress) {
9036
+ this.queuePendingValue(value);
9037
+ return;
9114
9038
  }
9115
9039
 
9116
- // Update text highlighting if matchWord changed
9117
- if (regexWord &&
9118
- this.isActive && !this.hasAttribute('persistent')) {
9119
- const nested = this.querySelectorAll('.nestingSpacer');
9040
+ // Normalize values to array of strings
9041
+ const normalizedValues = this._getNormalizedValues(value);
9120
9042
 
9121
- const displayValueEl = this.querySelector('[slot="displayValue"]');
9122
- if (displayValueEl) {
9123
- this.removeChild(displayValueEl);
9043
+ // Validate for single-select mode
9044
+ let validatedValues = normalizedValues;
9045
+ if (normalizedValues.length > 1 && !this.multiSelect) {
9046
+ console.warn("MenuService - Multiple values provided for single-select menu. Only the first value will be selected.");
9047
+ validatedValues = [normalizedValues[0]];
9048
+ }
9049
+
9050
+ if (this._menuOptions.length === 0) {
9051
+ this.queuePendingValue(value);
9052
+ return;
9053
+ }
9054
+
9055
+ // Find matching options by comparing available options to validated values
9056
+ const trackedKeys = new Set();
9057
+ const optionsToSelect = this._menuOptions.filter(option => {
9058
+ const passesFilter = validatedValues.includes(option.key);
9059
+ const alreadyTracked = trackedKeys.has(option.key);
9060
+ const isActive = option.isActive;
9061
+
9062
+ trackedKeys.add(option.key);
9063
+
9064
+ // Include the option in the options to be selected if it passes the filter check and
9065
+ // either hasn't been tracked yet or selectAllMatchingOptions is true
9066
+ return isActive && passesFilter && (!alreadyTracked || (alreadyTracked && this.selectAllMatchingOptions));
9067
+ });
9068
+
9069
+ // Handle no matches: clear existing selection, but do not dispatch an intermediate
9070
+ // undefined value that can overwrite the host value in parent components.
9071
+ if (!optionsToSelect.length) {
9072
+ const hasUnresolvedKeys = this._menuOptions.some((option) => option.isActive && option.key == null);
9073
+
9074
+ if (hasUnresolvedKeys) {
9075
+ this.queuePendingValue(value);
9076
+ return;
9124
9077
  }
9125
9078
 
9126
- // Create nested spacers
9127
- const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
9079
+ this.clearPendingValue();
9128
9080
 
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);
9081
+ if (this.selectedOptions.length > 0) {
9082
+ this.selectedOptions = [];
9137
9083
  }
9138
- }
9139
- }
9140
9084
 
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;
9085
+ // Always notify so the host resets any stale invalid value, even when
9086
+ // selectedOptions was already empty (e.g. double-clicking set-invalid).
9087
+ this.stageUpdate({ reason: 'no-match' });
9088
+
9089
+ // Dispatch failure event if no matches found
9090
+ if (validatedValues.length) {
9091
+ this.dispatchChangeEvent('auroMenu-selectValueFailure', {
9092
+ message: 'No matching options found for the provided value(s).',
9093
+ values: validatedValues
9094
+ });
9095
+ }
9096
+
9097
+ return;
9150
9098
  }
9151
- }
9152
9099
 
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);
9100
+ this.clearPendingValue();
9101
+
9102
+ if (this.optionsArraysMatch(optionsToSelect, this.selectedOptions)) {
9103
+ return;
9161
9104
  }
9105
+
9106
+ // Apply programmatic selection as a single transaction and emit one final state.
9107
+ this.selectedOptions = optionsToSelect;
9108
+ this.stageUpdate();
9162
9109
  }
9163
9110
 
9164
9111
  /**
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
9112
+ * Queues a pending value and schedules a bounded retry.
9113
+ * @param {string|number|Array<string|number>} value - The value to retry.
9168
9114
  */
9169
- handleCustomEvent() {
9170
- if (this.event) {
9171
- dispatchMenuEvent(this, this.event, { option: this });
9172
- dispatchMenuEvent(this, 'auroMenu-customEventFired', { option: this });
9115
+ queuePendingValue(value) {
9116
+ this._pendingValue = value;
9117
+
9118
+ if (this._pendingRetryScheduled || this._pendingRetryCount >= 5) {
9119
+ return;
9173
9120
  }
9174
- }
9175
9121
 
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
- }
9122
+ this._pendingRetryScheduled = true;
9123
+ this._pendingRetryCount += 1;
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
+ setTimeout(() => {
9126
+ this._pendingRetryScheduled = false;
9200
9127
 
9201
- svg.setAttribute('slot', 'svg');
9128
+ if (this._pendingValue == null) {
9129
+ return;
9130
+ }
9202
9131
 
9203
- return u$4`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
9132
+ const pendingValue = this._pendingValue;
9133
+ this.selectByValue(pendingValue);
9134
+ }, 0);
9204
9135
  }
9205
9136
 
9206
9137
  /**
9207
- * Logic to determine the layout of the component.
9208
- * @protected
9209
- * @returns {void}
9138
+ * Clears pending retry state.
9210
9139
  */
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
- };
9140
+ clearPendingValue() {
9141
+ this._pendingValue = null;
9142
+ this._pendingRetryScheduled = false;
9143
+ this._pendingRetryCount = 0;
9144
+ }
9220
9145
 
9221
- const classes = e$3({
9222
- 'wrapper': true,
9223
- [this.size ? fontClassMap[this.size] : 'body-sm']: true,
9224
- });
9146
+ /**
9147
+ * Resets the selected options to an empty array.
9148
+ */
9149
+ reset() {
9150
+ const previousOptions = [...this.selectedOptions];
9151
+ previousOptions.forEach(opt => opt.selected = false);
9152
+ this.selectedOptions = [];
9225
9153
 
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
- `;
9154
+ // Single update after clearing all
9155
+ if (previousOptions.length) {
9156
+ this.stageUpdate();
9157
+ }
9234
9158
  }
9235
- }
9236
-
9237
- /* eslint-disable */
9238
9159
 
9239
- class MenuService {
9160
+ /**
9161
+ * SUBSCRIPTION, NOTIFICATION AND EVENT DISPATCH METHODS
9162
+ */
9240
9163
 
9241
9164
  /**
9242
- * PROPERTIES AND GETTERS
9165
+ * Subscribes a callback to menu service events.
9166
+ * @param {Function} callback - The callback to invoke on events.
9243
9167
  */
9168
+ subscribe(callback) {
9169
+ this._subscribers.push(callback);
9170
+ }
9244
9171
 
9245
9172
  /**
9246
- * Gets the list of registered menu options.
9247
- * @returns {AuroMenuOption[]}
9173
+ * Remove a previously subscribed callback from menu service events.
9174
+ * @param {Function} callback
9248
9175
  */
9249
- get menuOptions() {
9250
- return this._menuOptions;
9176
+ unsubscribe(callback) {
9177
+ this._subscribers = this._subscribers.filter(cb => cb !== callback);
9251
9178
  }
9252
9179
 
9253
9180
  /**
9254
- * Gets the currently highlighted option.
9255
- * @returns {AuroMenuOption|null}
9181
+ * Stages an update to notify subscribers of state and value changes.
9256
9182
  */
9257
- get highlightedOption() {
9258
- return this._menuOptions[this.highlightedIndex] || null;
9183
+ stageUpdate(meta = {}) {
9184
+ this.notifyStateChange(meta);
9185
+ this.notifyValueChange(meta);
9259
9186
  }
9260
9187
 
9261
9188
  /**
9262
- * Gets the current value(s) of the selected option(s).
9263
- * @returns {string|string[]|undefined}
9189
+ * Notifies subscribers of a menu service event.
9190
+ * All notifications are sent to all subscribers.
9191
+ * @param {string} event - The event to send to subscribers.
9264
9192
  */
9265
- get currentValue() {
9266
- const values = (this.selectedOptions || []).map(option => option.value);
9267
- return this.multiSelect ? values : values[0];
9193
+ notify(event) {
9194
+ this._subscribers.forEach(callback => callback(event));
9268
9195
  }
9269
9196
 
9270
9197
  /**
9271
- * Gets the label(s) of the currently selected option(s).
9272
- * @returns {string}
9198
+ * Notifies subscribers of a state change (selected options has changed).
9273
9199
  */
9274
- get currentLabel() {
9275
- const labels = (this.selectedOptions || []).map(option => option.textContent);
9276
- return this.multiSelect ? labels.join(", ") : labels[0] || '';
9200
+ notifyStateChange(meta = {}) {
9201
+ this.notify({
9202
+ type: 'stateChange',
9203
+ selectedOptions: this.selectedOptions,
9204
+ ...meta
9205
+ });
9277
9206
  }
9278
9207
 
9279
9208
  /**
9280
- * Gets the string representation of the current value(s).
9281
- * For multi-select, this is a JSON stringified array.
9282
- * @returns {string|undefined}
9209
+ * Notifies subscribers of a value change (current value has changed).
9283
9210
  */
9284
- get stringValue() {
9285
- const { currentValue } = this;
9211
+ notifyValueChange(meta = {}) {
9286
9212
 
9287
- if (Array.isArray(currentValue)) {
9288
- if (currentValue.length > 0) {
9289
- return JSON.stringify(currentValue);
9290
- }
9291
- return undefined;
9292
- }
9213
+ // Prepare details for the event
9214
+ const details = {
9215
+ value: this.currentValue,
9216
+ stringValue: this.stringValue,
9217
+ keys: this.currentKeys,
9218
+ options: this.selectedOptions,
9219
+ label: this.currentLabel
9220
+ };
9293
9221
 
9294
- if (typeof currentValue === 'string') {
9295
- if (currentValue.length > 0) {
9296
- return currentValue;
9297
- }
9298
- return undefined;
9299
- }
9222
+ // If only one option is selected, include its index
9223
+ if (this.selectedOptions.length === 1) details.index = this._menuOptions.indexOf(this.selectedOptions[0]);
9300
9224
 
9301
- // Future: handle other types here (e.g., number, object, etc.)
9302
- return undefined;
9225
+ this.notify({
9226
+ type: 'valueChange',
9227
+ ...meta,
9228
+ ...details
9229
+ });
9303
9230
  }
9304
9231
 
9305
9232
  /**
9306
- * Gets the key(s) of the currently selected option(s).
9307
- * @returns {string|string[]|undefined}
9233
+ * Dispatches a custom event from the host element.
9234
+ * @param {string} eventName
9235
+ * @param {any} detail
9308
9236
  */
9309
- get currentKeys() {
9310
- const keys = (this.selectedOptions || []).map(option => option.key);
9311
- return this.multiSelect ? keys : keys[0];
9237
+ dispatchChangeEvent(eventName, detail) {
9238
+ this.host.dispatchEvent(new CustomEvent(eventName, {
9239
+ bubbles: true,
9240
+ cancelable: false,
9241
+ composed: true,
9242
+ detail
9243
+ }));
9312
9244
  }
9313
9245
 
9314
9246
  /**
9315
- * CONSTRUCTOR
9247
+ * MENU OPTION MANAGEMENT METHODS
9316
9248
  */
9317
9249
 
9318
9250
  /**
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.
9251
+ * Adds a menu option to the service's list.
9252
+ * @param {AuroMenuOption} option - the option to track
9323
9253
  */
9324
- constructor({ host } = {}) {
9254
+ addMenuOption(option) {
9255
+ this._menuOptions.push(option);
9256
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
9325
9257
 
9326
- // Ensure a host was passed
9327
- if (!host) {
9328
- throw new Error("MenuService requires a host element.");
9258
+ if (this._pendingValue != null) {
9259
+ this.queuePendingValue(this._pendingValue);
9329
9260
  }
9261
+ }
9330
9262
 
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;
9263
+ /**
9264
+ * Removes a menu option from the service's list.
9265
+ * @param {AuroMenuOption} option - the option to remove
9266
+ */
9267
+ removeMenuOption(option) {
9268
+ this._menuOptions = this._menuOptions.filter(opt => opt !== option);
9269
+ this.notify({ type: 'optionsChange', options: this._menuOptions });
9346
9270
 
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;
9271
+ if (this._menuOptions.length === 0) {
9272
+ this.clearPendingValue();
9273
+ }
9354
9274
  }
9355
9275
 
9356
9276
  /**
9357
- * PROPERTY SYNCING
9277
+ * UTILITIES
9358
9278
  */
9359
9279
 
9360
9280
  /**
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/
9281
+ * Normalizes a value or array of values into an array of strings for option selection.
9282
+ * This function ensures that input values are consistently formatted for matching menu options.
9283
+ *
9284
+ * @param {string|number|Array<string|number>} value - The value(s) to normalize.
9285
+ * @returns {Array<string>} An array of string values suitable for option matching.
9286
+ * @throws {Error} If any value is not a string or number.
9366
9287
  */
9367
- hostUpdated() {
9288
+ _getNormalizedValues(value) {
9289
+ let values = value;
9368
9290
 
9369
- // Reset selection if multiSelect mode changes
9370
- if (this.host.multiSelect !== this.multiSelect) {
9371
- this.selectedOptions = [];
9372
- }
9291
+ // Handle JSON string and single value string input
9292
+ if (!Array.isArray(values) && typeof values === 'string') {
9373
9293
 
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
- }
9294
+ // Attempt to parse as JSON array
9295
+ try {
9386
9296
 
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
- }
9297
+ // Normalize single quotes to double quotes for JSON parsing
9298
+ // This will not handle complex cases but will cover basic usage
9299
+ const parseValue = values.replace(/'([^']*?)'/g, '"$1"');
9397
9300
 
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) {
9301
+ // Attempt parse
9302
+ const parsed = JSON.parse(parseValue);
9404
9303
 
9405
- // Only update if we are tracking the property in this service
9406
- if (this.hasOwnProperty(property)) {
9304
+ // Ensure parsed value is an array
9305
+ if (!Array.isArray(parsed)) throw new Error('Not an array');
9407
9306
 
9408
- // Check if the value has changed
9409
- const valueChanged = this[property] !== value;
9307
+ // Set values to parsed array
9308
+ values = parsed;
9309
+ } catch (err) {
9410
9310
 
9411
- // Update and notify if changed
9412
- if (valueChanged) {
9413
- this[property] = value;
9414
- this.notify({ property, value });
9311
+ // If parsing fails, treat as single value
9312
+ values = [value];
9415
9313
  }
9416
9314
  }
9417
- }
9418
9315
 
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);
9316
+ // Handle a single number being passed
9317
+ if (typeof values === 'number') {
9318
+ values = [String(values)];
9426
9319
  }
9427
- }
9428
9320
 
9429
- /**
9430
- * MENU OPTION HIGHLIGHTING
9431
- */
9321
+ // Coerce each value to string and validate types
9322
+ values.forEach((val, index) => {
9432
9323
 
9433
- /**
9434
- * Highlights the next active option in the menu.
9435
- */
9436
- highlightNext() {
9437
- this.moveHighlightedOption("next");
9438
- }
9324
+ // Throw an error for invalid value types
9325
+ if (typeof val !== 'string' && typeof val !== 'number') {
9326
+ throw new Error('Value contains invalid value type. Supported types are string and number.');
9327
+ }
9439
9328
 
9440
- /**
9441
- * Highlights the previous active option in the menu.
9442
- */
9443
- highlightPrevious() {
9444
- this.moveHighlightedOption("previous");
9329
+ // Convert numbers to strings for consistency
9330
+ if (typeof val === 'number') {
9331
+ values[index] = String(val);
9332
+ }
9333
+ });
9334
+
9335
+ // Return the resulting array of string values
9336
+ return values;
9445
9337
  }
9446
9338
 
9447
9339
  /**
9448
- * Moves the highlighted option in the specified direction.
9449
- * @param {string} direction - The direction to move the highlight ("next" or "previous").
9340
+ * Returns whether two arrays of options contain the same elements.
9341
+ * @param {AuroMenuOption[]} arr1 - First array of options.
9342
+ * @param {AuroMenuOption[]} arr2 - Second array of options.
9343
+ * @returns {boolean} True if arrays match, false otherwise.
9450
9344
  */
9451
- moveHighlightedOption(direction) {
9345
+ optionsArraysMatch(arr1, arr2) {
9346
+ if (arr1.length !== arr2.length) return false;
9452
9347
 
9453
- // Get the active options
9454
- const activeOptions = this._menuOptions.filter(option => option.isActive);
9348
+ const set1 = new Set(arr1);
9349
+ const set2 = new Set(arr2);
9455
9350
 
9456
- // Get the currently active option
9457
- const currentActiveOption = activeOptions[activeOptions.indexOf(this.highlightedOption)];
9351
+ for (let item of set1) {
9352
+ if (!set2.has(item)) {
9353
+ return false;
9354
+ }
9355
+ }
9458
9356
 
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;
9357
+ return true;
9358
+ }
9359
+ }
9467
9360
 
9468
- // Wrap around the index if needed
9469
- newIndex = newIndex < 0 ? activeOptions.length - 1 : newIndex >= activeOptions.length ? 0 : newIndex;
9361
+ const MenuContext = n('menu-context');
9470
9362
 
9471
- // Get the new active option and set it as highlighted
9472
- const newActiveOption = activeOptions[newIndex];
9473
- this.setHighlightedOption(newActiveOption);
9474
- }
9363
+ // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
9364
+ // See LICENSE in the project root for license information.
9475
9365
 
9476
- /**
9477
- * Sets the highlighted index to the specified option.
9478
- * @param {AuroMenuOption} option - The option to highlight.
9479
- */
9480
- setHighlightedOption(option) {
9481
9366
 
9482
- if (!option) return;
9367
+ /**
9368
+ * Helper method to dispatch custom events.
9369
+ * @param {HTMLElement} element - Element to dispatch event from.
9370
+ * @param {string} eventName - Name of the event to dispatch.
9371
+ * @param {Object} [detail] - Optional detail object to include with the event.
9372
+ */
9373
+ function dispatchMenuEvent(element, eventName, detail = null) {
9374
+ const eventConfig = {
9375
+ bubbles: true,
9376
+ cancelable: false,
9377
+ composed: true
9378
+ };
9483
9379
 
9484
- // Get the index of the option to highlight
9485
- const index = this._menuOptions.indexOf(option);
9380
+ if (detail !== null) {
9381
+ eventConfig.detail = detail;
9382
+ }
9486
9383
 
9487
- // Update highlighted index
9488
- this.highlightedIndex = index;
9384
+ element.dispatchEvent(new CustomEvent(eventName, eventConfig));
9385
+ }
9489
9386
 
9490
- // Notify subscribers of highlight change
9491
- this.notify({ type: 'highlightChange', option, index: this.highlightedIndex });
9387
+ /* eslint-disable no-underscore-dangle */
9388
+ // Copyright (c) 2025 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
9389
+ // See LICENSE in the project root for license information.
9492
9390
 
9493
- // Dispatch the change event
9494
- this.dispatchChangeEvent('auroMenu-activatedOption', option);
9495
- }
9496
9391
 
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
- }
9505
9392
 
9506
- /**
9507
- * Selects the currently highlighted option.
9508
- */
9509
- selectHighlightedOption() {
9510
- if (this.highlightedOption) {
9511
- this.toggleOption(this.highlightedOption);
9512
- }
9513
- }
9393
+ /**
9394
+ * The `auro-menu` element provides users a way to select from a list of options.
9395
+ * @customElement auro-menu
9396
+ *
9397
+ * @event {CustomEvent<Element>} auroMenu-activatedOption - Notifies that a menuoption has been made `active`.
9398
+ * @event {CustomEvent<any>} auroMenu-customEventFired - Notifies that a custom event has been fired.
9399
+ * @event {CustomEvent<{ loading: boolean; hasLoadingPlaceholder: boolean; }>} auroMenu-loadingChange - Notifies when the loading attribute is changed.
9400
+ * @event {CustomEvent<any>} auroMenu-selectValueFailure - Notifies that an attempt to select a menuoption by matching a value has failed.
9401
+ * @event {CustomEvent<{ values: HTMLElement[] }>} auroMenu-deselectPrevented - Notifies that deselection was prevented and includes the affected options in `detail.values`.
9402
+ * @event {CustomEvent<any>} auroMenu-selectValueReset - Notifies that the component value has been reset.
9403
+ * @event {CustomEvent<any>} auroMenu-selectedOption - Notifies that a new menuoption selection has been made.
9404
+ * @slot loadingText - Text to show while loading attribute is set
9405
+ * @slot loadingIcon - Icon to show while loading attribute is set
9406
+ * @slot - Slot for insertion of menu options.
9407
+ */
9514
9408
 
9515
- /**
9516
- * SELECTION AND DESELECTION METHODS
9517
- */
9409
+ /* eslint-disable max-lines */
9518
9410
 
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];
9411
+ class AuroMenu extends AuroElement$1 {
9525
9412
 
9526
- // Filter out options that are inactive
9527
- optionsToSelect = optionsToSelect.filter(option => option.isActive);
9413
+ constructor() {
9414
+ super();
9528
9415
 
9529
- if (!optionsToSelect.length) return;
9416
+ // State properties (reactive)
9530
9417
 
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
- }
9418
+ /**
9419
+ * @private
9420
+ */
9421
+ this.shape = "box";
9537
9422
 
9538
- this.stageUpdate();
9539
- }
9423
+ /**
9424
+ * @private
9425
+ */
9426
+ this.size = "sm";
9540
9427
 
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];
9428
+ // Value of the selected options
9429
+ this.value = undefined;
9430
+ // Currently selected option
9431
+ this.optionSelected = undefined;
9432
+ // String used for highlighting/filtering
9433
+ this.matchWord = undefined;
9434
+ // Hide the checkmark icon on selected options
9435
+ this.noCheckmark = false;
9436
+ // Currently active option
9437
+ this.optionActive = undefined;
9438
+ // Loading state
9439
+ this.loading = false;
9440
+ // Multi-select mode
9441
+ this.multiSelect = false;
9442
+ // Allow deselecting of menu options
9443
+ this.allowDeselect = false;
9444
+ // Select all matching options when setting value in multi-select mode
9445
+ this.selectAllMatchingOptions = false;
9547
9446
 
9548
- if (!optionsToDeselect.length) return;
9447
+ // Event Bindings
9549
9448
 
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]);
9449
+ /**
9450
+ * @private
9451
+ */
9452
+ this.handleSlotChange = this.handleSlotChange.bind(this);
9553
9453
 
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
- }
9564
-
9565
- const optionsSet = new Set(optionsToDeselect);
9566
- this.selectedOptions = (this.selectedOptions || [])
9567
- .filter(opt => !optionsSet.has(opt));
9568
-
9569
- this.stageUpdate();
9570
- }
9571
-
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
- }
9454
+ // Instance properties (non-reactive)
9587
9455
 
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
- }
9456
+ /**
9457
+ * @private
9458
+ */
9459
+ Object.assign(this, {
9460
+ // Root-level menu (true) or a nested submenu (false)
9461
+ rootMenu: true,
9462
+ // Currently focused/active menu item index
9463
+ _index: -1,
9464
+ // Nested menu spacer
9465
+ nestingSpacer: '<span class="nestingSpacer"></span>',
9466
+ // Loading indicator for slot elements
9467
+ loadingSlots: null,
9468
+ });
9598
9469
  }
9599
9470
 
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
- }
9634
-
9635
- if (this._menuOptions.length === 0) {
9636
- this.queuePendingValue(value);
9637
- return;
9638
- }
9639
-
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;
9646
-
9647
- trackedKeys.add(option.key);
9471
+ static get properties() {
9472
+ return {
9473
+ ...super.properties,
9648
9474
 
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));
9652
- });
9475
+ /**
9476
+ * Allows deselecting an already selected option when clicked again in single-select mode.
9477
+ */
9478
+ allowDeselect: {
9479
+ type: Boolean,
9480
+ reflect: true,
9481
+ },
9653
9482
 
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);
9483
+ /**
9484
+ * When true, the entire menu and all options are disabled.
9485
+ */
9486
+ disabled: {
9487
+ type: Boolean,
9488
+ reflect: true
9489
+ },
9658
9490
 
9659
- if (hasUnresolvedKeys) {
9660
- this.queuePendingValue(value);
9661
- return;
9662
- }
9491
+ /**
9492
+ * Indicates whether the menu has a loadingIcon or loadingText to render when in a loading state.
9493
+ */
9494
+ hasLoadingPlaceholder: {
9495
+ type: Boolean
9496
+ },
9663
9497
 
9664
- this.clearPendingValue();
9498
+ /**
9499
+ * @private
9500
+ */
9501
+ layout: {
9502
+ type: String
9503
+ },
9665
9504
 
9666
- if (this.selectedOptions.length > 0) {
9667
- this.selectedOptions = [];
9668
- }
9505
+ /**
9506
+ * Indent level for submenus.
9507
+ * @private
9508
+ */
9509
+ level: {
9510
+ type: Number,
9511
+ reflect: false,
9512
+ attribute: false
9513
+ },
9669
9514
 
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' });
9515
+ /**
9516
+ * When true, displays a loading state using the loadingIcon and loadingText slots if provided.
9517
+ */
9518
+ loading: {
9519
+ type: Boolean,
9520
+ reflect: true
9521
+ },
9673
9522
 
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
- }
9523
+ /**
9524
+ * Specifies a string used to highlight matched string parts in options.
9525
+ */
9526
+ matchWord: {
9527
+ type: String,
9528
+ attribute: 'matchword'
9529
+ },
9681
9530
 
9682
- return;
9683
- }
9531
+ /**
9532
+ * When true, the selected option can be multiple options.
9533
+ */
9534
+ multiSelect: {
9535
+ type: Boolean,
9536
+ reflect: true,
9537
+ attribute: 'multiselect'
9538
+ },
9684
9539
 
9685
- this.clearPendingValue();
9540
+ /**
9541
+ * When true, selected option will not show the checkmark.
9542
+ */
9543
+ noCheckmark: {
9544
+ type: Boolean,
9545
+ reflect: true,
9546
+ attribute: 'nocheckmark'
9547
+ },
9686
9548
 
9687
- if (this.optionsArraysMatch(optionsToSelect, this.selectedOptions)) {
9688
- return;
9689
- }
9549
+ /**
9550
+ * Specifies the current active menuOption.
9551
+ */
9552
+ optionActive: {
9553
+ type: Object,
9554
+ attribute: 'optionactive'
9555
+ },
9690
9556
 
9691
- // Apply programmatic selection as a single transaction and emit one final state.
9692
- this.selectedOptions = optionsToSelect;
9693
- this.stageUpdate();
9694
- }
9557
+ /**
9558
+ * An array of currently selected menu options, type `HTMLElement` by default. In multi-select mode, `optionSelected` is an array of HTML elements.
9559
+ */
9560
+ optionSelected: {
9561
+ // Allow HTMLElement, HTMLElement[] arrays and undefined
9562
+ type: Object
9563
+ },
9695
9564
 
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;
9565
+ /**
9566
+ * Available menu options.
9567
+ * @readonly
9568
+ */
9569
+ options: {
9570
+ type: Array,
9571
+ reflect: false,
9572
+ attribute: false
9573
+ },
9702
9574
 
9703
- if (this._pendingRetryScheduled || this._pendingRetryCount >= 5) {
9704
- return;
9705
- }
9575
+ /**
9576
+ * Sets the size of the menu.
9577
+ * @type {'sm' | 'md'}
9578
+ * @default 'sm'
9579
+ */
9580
+ size: {
9581
+ type: String,
9582
+ reflect: true
9583
+ },
9706
9584
 
9707
- this._pendingRetryScheduled = true;
9708
- this._pendingRetryCount += 1;
9585
+ /**
9586
+ * When true, selects all options that match the provided value/key when setting value and multiselect is enabled.
9587
+ */
9588
+ selectAllMatchingOptions: {
9589
+ type: Boolean,
9590
+ reflect: true,
9591
+ },
9709
9592
 
9710
- setTimeout(() => {
9711
- this._pendingRetryScheduled = false;
9593
+ /**
9594
+ * Sets the shape of the menu.
9595
+ * @type {'box' | 'round'}
9596
+ * @default 'box'
9597
+ */
9598
+ shape: {
9599
+ type: String,
9600
+ reflect: true
9601
+ },
9712
9602
 
9713
- if (this._pendingValue == null) {
9714
- return;
9603
+ /**
9604
+ * The value of the selected option. In multi-select mode, this is a JSON stringified array of selected option values.
9605
+ */
9606
+ value: {
9607
+ type: String,
9608
+ reflect: true,
9609
+ attribute: 'value'
9715
9610
  }
9716
-
9717
- const pendingValue = this._pendingValue;
9718
- this.selectByValue(pendingValue);
9719
- }, 0);
9720
- }
9721
-
9722
- /**
9723
- * Clears pending retry state.
9724
- */
9725
- clearPendingValue() {
9726
- this._pendingValue = null;
9727
- this._pendingRetryScheduled = false;
9728
- this._pendingRetryCount = 0;
9611
+ };
9729
9612
  }
9730
9613
 
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
- }
9614
+ static get styles() {
9615
+ return [
9616
+ styleCss$1,
9617
+ colorCss$1,
9618
+ tokensCss
9619
+ ];
9743
9620
  }
9744
9621
 
9745
9622
  /**
9746
- * SUBSCRIPTION, NOTIFICATION AND EVENT DISPATCH METHODS
9623
+ * @readonly
9624
+ * @returns {string} - Returns the label of the currently selected option(s).
9747
9625
  */
9626
+ get currentLabel() {
9627
+ return this.menuService.currentLabel;
9628
+ };
9748
9629
 
9749
9630
  /**
9750
- * Subscribes a callback to menu service events.
9751
- * @param {Function} callback - The callback to invoke on events.
9631
+ * @readonly
9632
+ * @returns {Array<HTMLElement>} - Returns the array of available menu options.
9633
+ * @deprecated Use `options` property instead.
9752
9634
  */
9753
- subscribe(callback) {
9754
- this._subscribers.push(callback);
9635
+ get items() {
9636
+ return this.options;
9755
9637
  }
9756
9638
 
9757
9639
  /**
9758
- * Remove a previously subscribed callback from menu service events.
9759
- * @param {Function} callback
9640
+ * @returns {number} - Returns the index of the currently active option.
9760
9641
  */
9761
- unsubscribe(callback) {
9762
- this._subscribers = this._subscribers.filter(cb => cb !== callback);
9642
+ get index() {
9643
+ return this._index;
9763
9644
  }
9764
9645
 
9765
9646
  /**
9766
- * Stages an update to notify subscribers of state and value changes.
9647
+ * @param {number} value - Sets the index of the currently active option.
9767
9648
  */
9768
- stageUpdate(meta = {}) {
9769
- this.notifyStateChange(meta);
9770
- this.notifyValueChange(meta);
9649
+ set index(value) {
9650
+ this.menuService.setHighlightedIndex(value);
9771
9651
  }
9772
9652
 
9773
9653
  /**
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.
9654
+ * This will register this element with the browser.
9655
+ * @param {string} [name="auro-menu"] - The name of the element that you want to register.
9656
+ *
9657
+ * @example
9658
+ * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
9659
+ *
9777
9660
  */
9778
- notify(event) {
9779
- this._subscribers.forEach(callback => callback(event));
9661
+ static register(name = "auro-menu") {
9662
+ AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenu);
9780
9663
  }
9781
9664
 
9782
9665
  /**
9783
- * Notifies subscribers of a state change (selected options has changed).
9666
+ * Formatted value based on `multiSelect` state.
9667
+ * Default type is `String`, changing to `Array<String>` when `multiSelect` is true.
9668
+ * @private
9669
+ * @returns {String|Array<String>}
9784
9670
  */
9785
- notifyStateChange(meta = {}) {
9786
- this.notify({
9787
- type: 'stateChange',
9788
- selectedOptions: this.selectedOptions,
9789
- ...meta
9790
- });
9671
+ get formattedValue() {
9672
+ return this.menuService.currentValue;
9791
9673
  }
9792
9674
 
9793
9675
  /**
9794
- * Notifies subscribers of a value change (current value has changed).
9676
+ * Gets the current property values for the menu service.
9677
+ * @private
9678
+ * @returns {Object}
9795
9679
  */
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
9680
+ get propertyValues() {
9681
+ return {
9682
+ size: this.size,
9683
+ shape: this.shape,
9684
+ noCheckmark: this.nocheckmark,
9685
+ disabled: this.disabled
9805
9686
  };
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
- }
9816
-
9817
- /**
9818
- * Dispatches a custom event from the host element.
9819
- * @param {string} eventName
9820
- * @param {any} detail
9821
- */
9822
- dispatchChangeEvent(eventName, detail) {
9823
- this.host.dispatchEvent(new CustomEvent(eventName, {
9824
- bubbles: true,
9825
- cancelable: false,
9826
- composed: true,
9827
- detail
9828
- }));
9829
9687
  }
9830
9688
 
9831
9689
  /**
9832
- * MENU OPTION MANAGEMENT METHODS
9833
- */
9834
-
9835
- /**
9836
- * Adds a menu option to the service's list.
9837
- * @param {AuroMenuOption} option - the option to track
9690
+ * Provides the menu context to child components.
9691
+ * Initializes the MenuService and subscribes to menu changes.
9692
+ * @protected
9838
9693
  */
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);
9694
+ provideContext() {
9695
+ if (this.parentElement && this.parentElement.closest('auro-menu, [auro-menu]')) {
9696
+ this.rootMenu = false;
9697
+ this.menuService = this.parentElement.menuService;
9698
+ this._contextProvider = this.parentElement._contextProvider;
9699
+ return;
9845
9700
  }
9846
- }
9847
9701
 
9848
- /**
9849
- * Removes a menu option from the service's list.
9850
- * @param {AuroMenuOption} option - the option to remove
9851
- */
9852
- removeMenuOption(option) {
9853
- this._menuOptions = this._menuOptions.filter(opt => opt !== option);
9854
- this.notify({ type: 'optionsChange', options: this._menuOptions });
9855
-
9856
- if (this._menuOptions.length === 0) {
9857
- this.clearPendingValue();
9858
- }
9702
+ this.menuService = new MenuService({host: this});
9703
+ this.menuService.setProperties(this.propertyValues);
9704
+ this.menuService.subscribe(this.handleMenuChange.bind(this));
9705
+ this._contextProvider = new i(this, {
9706
+ context: MenuContext,
9707
+ initialValue: this.menuService
9708
+ });
9859
9709
  }
9860
9710
 
9861
9711
  /**
9862
- * UTILITIES
9712
+ * Updates the currently active option in the menu.
9713
+ * @param {HTMLElement} option - The option to set as active.
9863
9714
  */
9715
+ updateActiveOption(option) {
9716
+ this.menuService.setHighlightedOption(option);
9717
+ }
9864
9718
 
9865
9719
  /**
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.
9720
+ * Sets the internal value and manages update state.
9721
+ * @param {String|Array<String>} value - The value to set.
9722
+ * @protected
9872
9723
  */
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"');
9724
+ setInternalValue(value) {
9725
+ if (this.value !== value) {
9726
+ this.internalUpdateInProgress = true;
9727
+ this.value = value;
9885
9728
 
9886
- // Attempt parse
9887
- const parsed = JSON.parse(parseValue);
9729
+ setTimeout(() => {
9730
+ this.internalUpdateInProgress = false;
9731
+ });
9732
+ }
9733
+ }
9888
9734
 
9889
- // Ensure parsed value is an array
9890
- if (!Array.isArray(parsed)) throw new Error('Not an array');
9735
+ /**
9736
+ * Handles changes from the menu service and updates component state.
9737
+ * @param {Object} event - The event object from the menu service.
9738
+ * @protected
9739
+ */
9740
+ handleMenuChange(event) {
9741
+ if (event.type === 'valueChange') {
9891
9742
 
9892
- // Set values to parsed array
9893
- values = parsed;
9894
- } catch (err) {
9743
+ // New option is array value or first option with fallback to undefined for empty array in all cases
9744
+ const newOption = this.multiSelect && event.options.length ? event.options : event.options[0] || undefined;
9745
+ const newValue = event.stringValue;
9895
9746
 
9896
- // If parsing fails, treat as single value
9897
- values = [value];
9747
+ // Check if the option or value has actually changed
9748
+ if (this.optionSelected !== newOption || this.stringValue !== newValue) {
9749
+ this.optionSelected = newOption;
9750
+ this.setInternalValue(newValue);
9898
9751
  }
9899
- }
9900
9752
 
9901
- // Handle a single number being passed
9902
- if (typeof values === 'number') {
9903
- values = [String(values)];
9753
+ // Notify components of selection change
9754
+ this.notifySelectionChange(event);
9904
9755
  }
9905
9756
 
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
- });
9757
+ if (event.type === 'highlightChange') {
9758
+ this.optionActive = event.option;
9759
+ this._index = event.index;
9760
+ }
9919
9761
 
9920
- // Return the resulting array of string values
9921
- return values;
9762
+ if (event.type === 'optionsChange') {
9763
+ this.options = event.options;
9764
+ this.dispatchEvent(new CustomEvent('auroMenu-optionsChange', {
9765
+ detail: {
9766
+ options: event.options
9767
+ }
9768
+ }));
9769
+ }
9922
9770
  }
9923
9771
 
9924
9772
  /**
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.
9773
+ * Gets the currently selected options.
9774
+ * @returns {Array<HTMLElement>}
9929
9775
  */
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;
9776
+ get selectedOptions() {
9777
+ return this.menuService ? this.menuService.selectedOptions : [];
9943
9778
  }
9944
- }
9945
9779
 
9946
- const MenuContext = n('menu-context');
9780
+ /**
9781
+ * Gets the first selected option, or null if none.
9782
+ * @returns {HTMLElement|null}
9783
+ */
9784
+ get selectedOption() {
9785
+ return this.menuService ? this.menuService.selectedOptions[0] : null;
9786
+ }
9947
9787
 
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.
9788
+ // Lifecycle Methods
9951
9789
 
9790
+ connectedCallback() {
9791
+ super.connectedCallback();
9952
9792
 
9793
+ this.provideContext();
9953
9794
 
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
- */
9795
+ // this.addEventListener('keydown', this.handleKeyDown);
9796
+ this.addEventListener('auroMenuOption-click', this.handleMouseSelect);
9797
+ this.addEventListener('auroMenuOption-mouseover', this.handleOptionHover);
9798
+ this.addEventListener('slotchange', this.handleSlotChange);
9799
+ this.setTagAttribute("auro-menu");
9800
+ }
9969
9801
 
9970
- /* eslint-disable max-lines */
9802
+ disconnectedCallback() {
9803
+ // this.removeEventListener('keydown', this.handleKeyDown);
9804
+ this.removeEventListener('auroMenuOption-click', this.handleMouseSelect);
9805
+ this.removeEventListener('auroMenuOption-mouseover', this.handleOptionHover);
9806
+ this.removeEventListener('slotchange', this.handleSlotChange);
9971
9807
 
9972
- class AuroMenu extends AuroElement$1 {
9808
+ super.disconnectedCallback();
9809
+ }
9973
9810
 
9974
- constructor() {
9975
- super();
9811
+ firstUpdated() {
9812
+ AuroLibraryRuntimeUtils$3.prototype.handleComponentTagRename(this, 'auro-menu');
9976
9813
 
9977
- // State properties (reactive)
9814
+ this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
9815
+ this.initializeMenu();
9816
+ }
9978
9817
 
9979
- /**
9980
- * @private
9981
- */
9982
- this.shape = "box";
9983
9818
 
9984
- /**
9985
- * @private
9986
- */
9987
- this.size = "sm";
9819
+ updated(changedProperties) {
9820
+ super.updated(changedProperties);
9988
9821
 
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;
9822
+ // Apply value selection synchronously so that static-HTML fixtures
9823
+ // resolve within a single update cycle. The refactored selectByValue
9824
+ // no longer calls reset() first, so the destructive intermediate-event
9825
+ // cascade that originally required deferral is eliminated. If option
9826
+ // keys are not yet resolved (framework mount-order race), selectByValue
9827
+ // queues a bounded retry automatically via queuePendingValue.
9828
+ if (changedProperties.has('value') && !this.internalUpdateInProgress) {
9829
+ this.menuService.selectByValue(this.value);
9830
+ }
10007
9831
 
10008
- // Event Bindings
9832
+ // Handle loading state changes
9833
+ if (changedProperties.has('loading')) {
9834
+ this.setLoadingState(this.loading);
9835
+ }
10009
9836
 
10010
- /**
10011
- * @private
10012
- */
10013
- this.handleSlotChange = this.handleSlotChange.bind(this);
9837
+ if (changedProperties.has('multiSelect') && this.rootMenu) {
9838
+ if (this.multiSelect) {
9839
+ this.setAttribute('aria-multiselectable', 'true');
9840
+ } else {
9841
+ this.removeAttribute('aria-multiselectable');
9842
+ }
9843
+ }
9844
+ }
10014
9845
 
10015
- // Instance properties (non-reactive)
9846
+ /**
9847
+ * Sets an attribute that matches the default tag name if the tag name is not the default.
9848
+ * @param {string} tagName - The tag name to set as an attribute.
9849
+ * @private
9850
+ */
9851
+ setTagAttribute(tagName) {
9852
+ if (this.tagName.toLowerCase() !== tagName) {
9853
+ this.setAttribute(tagName, true);
9854
+ }
9855
+ }
10016
9856
 
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,
9857
+ /**
9858
+ * Sets the loading state and dispatches a loading change event.
9859
+ * @param {boolean} isLoading - Whether the menu is loading.
9860
+ * @protected
9861
+ */
9862
+ setLoadingState(isLoading) {
9863
+ this.setAttribute("aria-busy", isLoading);
9864
+ dispatchMenuEvent(this, "auroMenu-loadingChange", {
9865
+ loading: isLoading,
9866
+ hasLoadingPlaceholder: this.hasLoadingPlaceholder
10029
9867
  });
10030
9868
  }
10031
9869
 
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
- },
9870
+ // Init Methods
10058
9871
 
10059
- /**
10060
- * @private
10061
- */
10062
- layout: {
10063
- type: String
10064
- },
9872
+ /**
9873
+ * Initializes the menu's state and structure.
9874
+ * @private
9875
+ */
9876
+ initializeMenu() {
9877
+ if (this.rootMenu) {
9878
+ this.setAttribute('role', 'listbox');
9879
+ this.setAttribute('root', '');
10065
9880
 
10066
- /**
10067
- * Indent level for submenus.
10068
- * @private
10069
- */
10070
- level: {
10071
- type: Number,
10072
- reflect: false,
10073
- attribute: false
10074
- },
9881
+ if (this.multiSelect) {
9882
+ this.setAttribute('aria-multiselectable', 'true');
9883
+ }
9884
+ }
10075
9885
 
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
- },
9886
+ this.handleNestedMenus(this);
9887
+ }
10083
9888
 
10084
- /**
10085
- * Specifies a string used to highlight matched string parts in options.
10086
- */
10087
- matchWord: {
10088
- type: String,
10089
- attribute: 'matchword'
10090
- },
9889
+ /**
9890
+ * Selects the currently highlighted option.
9891
+ * @protected
9892
+ */
9893
+ makeSelection() {
9894
+ this.menuService.selectHighlightedOption();
9895
+ }
10091
9896
 
10092
- /**
10093
- * When true, the selected option can be multiple options.
10094
- */
10095
- multiSelect: {
10096
- type: Boolean,
10097
- reflect: true,
10098
- attribute: 'multiselect'
10099
- },
9897
+ /**
9898
+ * Resets all options to their default state.
9899
+ * @private
9900
+ */
9901
+ clearSelection() {
9902
+ this.optionSelected = undefined;
9903
+ this.value = undefined;
9904
+ this._index = -1;
9905
+ }
10100
9906
 
10101
- /**
10102
- * When true, selected option will not show the checkmark.
10103
- */
10104
- noCheckmark: {
10105
- type: Boolean,
10106
- reflect: true,
10107
- attribute: 'nocheckmark'
10108
- },
9907
+ /**
9908
+ * Resets the menu to its initial state.
9909
+ * This is the only way to return value to undefined.
9910
+ * @public
9911
+ */
9912
+ reset() {
9913
+ this.menuService.reset();
10109
9914
 
10110
- /**
10111
- * Specifies the current active menuOption.
10112
- */
10113
- optionActive: {
10114
- type: Object,
10115
- attribute: 'optionactive'
10116
- },
9915
+ // Dispatch reset event
9916
+ dispatchMenuEvent(this, 'auroMenu-selectValueReset');
9917
+ }
10117
9918
 
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
- },
9919
+ /**
9920
+ * Handles nested menu structure.
9921
+ * @private
9922
+ * @param {HTMLElement} menu - Root menu element.
9923
+ */
9924
+ handleNestedMenus(menu) {
9925
+ menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
10125
9926
 
10126
- /**
10127
- * Available menu options.
10128
- * @readonly
10129
- */
10130
- options: {
10131
- type: Array,
10132
- reflect: false,
10133
- attribute: false
10134
- },
9927
+ if (menu.level > 0) {
9928
+ menu.setAttribute('role', 'group');
9929
+ menu.removeAttribute("root");
9930
+ if (!menu.hasAttribute('aria-label')) {
9931
+ menu.setAttribute('aria-label', 'submenu');
9932
+ }
9933
+ }
10135
9934
 
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
- },
9935
+ const options = menu.querySelectorAll(':scope > auro-menuoption, :scope > [auro-menuoption]');
9936
+ options.forEach((option) => {
9937
+ const regex = new RegExp(this.nestingSpacer, "gu");
9938
+ option.innerHTML = this.nestingSpacer.repeat(menu.level) + option.innerHTML.replace(regex, '');
9939
+ });
9940
+ }
10145
9941
 
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
- },
9942
+ /**
9943
+ * Navigates the menu options in the specified direction.
9944
+ * @param {'up'|'down'} direction - The direction to navigate.
9945
+ * @protected
9946
+ */
9947
+ navigateOptions(direction) {
9948
+ if (direction === 'up') {
9949
+ this.menuService.highlightPrevious();
9950
+ } else if (direction === 'down') {
9951
+ this.menuService.highlightNext();
9952
+ }
9953
+ }
10153
9954
 
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
- },
9955
+ /**
9956
+ * Handles slot change events.
9957
+ * @private
9958
+ */
9959
+ handleSlotChange() {
9960
+ if (this.rootMenu) {
9961
+ this.initializeMenu();
9962
+ }
9963
+ }
10163
9964
 
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
- };
9965
+ /**
9966
+ * Handles custom events defined on options.
9967
+ * @private
9968
+ * @param {HTMLElement} option - Option with custom event.
9969
+ */
9970
+ handleCustomEvent(option) {
9971
+ const eventName = option.getAttribute('event');
9972
+ dispatchMenuEvent(this, eventName);
9973
+ dispatchMenuEvent(this, 'auroMenu-customEventFired');
10173
9974
  }
10174
9975
 
10175
- static get styles() {
10176
- return [
10177
- styleCss$1,
10178
- colorCss$1,
10179
- tokensCss
10180
- ];
9976
+ /**
9977
+ * Notifies selection change to parent components.
9978
+ * @param {any} source - The source that triggers this event.
9979
+ * @private
9980
+ */
9981
+ notifySelectionChange({value, stringValue, keys, options, reason} = {}) {
9982
+ dispatchMenuEvent(this, 'auroMenu-selectedOption', {
9983
+ value,
9984
+ stringValue,
9985
+ keys,
9986
+ options,
9987
+ reason
9988
+ });
10181
9989
  }
10182
9990
 
10183
9991
  /**
10184
- * @readonly
10185
- * @returns {string} - Returns the label of the currently selected option(s).
9992
+ * Checks if an option is currently selected.
9993
+ * @private
9994
+ * @param {HTMLElement} option - The option to check.
9995
+ * @returns {boolean}
10186
9996
  */
10187
- get currentLabel() {
10188
- return this.menuService.currentLabel;
10189
- };
9997
+ isOptionSelected(option) {
9998
+ if (!this.optionSelected) {
9999
+ return false;
10000
+ }
10001
+
10002
+ if (this.multiSelect) {
10003
+ // In multi-select mode, check if the option is in the selected array
10004
+ return Array.isArray(this.optionSelected) && this.optionSelected.some((selectedOption) => selectedOption === option);
10005
+ }
10006
+
10007
+ return this.optionSelected === option;
10008
+ }
10190
10009
 
10191
10010
  /**
10192
- * @readonly
10193
- * @returns {Array<HTMLElement>} - Returns the array of available menu options.
10194
- * @deprecated Use `options` property instead.
10011
+ * Getter for loading placeholder state.
10012
+ * @returns {boolean} - True if loading slots are present and non-empty.
10195
10013
  */
10196
- get items() {
10197
- return this.options;
10014
+ get hasLoadingPlaceholder() {
10015
+ return this.loadingSlots && this.loadingSlots.length > 0;
10198
10016
  }
10199
10017
 
10200
10018
  /**
10201
- * @returns {number} - Returns the index of the currently active option.
10019
+ * Getter for wrapper classes based on size.
10020
+ * @returns {Object} - Class map for the wrapper element.
10021
+ * @private
10202
10022
  */
10203
- get index() {
10204
- return this._index;
10023
+ get wrapperClasses() {
10024
+ return e$3({
10025
+ 'menuWrapper': true,
10026
+ [this.size]: true,
10027
+ });
10205
10028
  }
10206
10029
 
10207
10030
  /**
10208
- * @param {number} value - Sets the index of the currently active option.
10031
+ * Logic to determine the layout of the component.
10032
+ * @protected
10033
+ * @returns {void}
10209
10034
  */
10210
- set index(value) {
10211
- this.menuService.setHighlightedIndex(value);
10035
+ renderLayout() {
10036
+ if (this.loading) {
10037
+ return b$1`
10038
+ <div class="${this.wrapperClasses}">
10039
+ <auro-menuoption
10040
+ disabled
10041
+ loadingplaceholder
10042
+ class="${this.hasLoadingPlaceholder ? "" : "empty"}"
10043
+ >
10044
+ <div>
10045
+ <slot name="loadingIcon" class="body-lg"></slot>
10046
+ <slot name="loadingText"></slot>
10047
+ </div>
10048
+ </auro-menuoption>
10049
+ </div>
10050
+ `;
10051
+ }
10052
+
10053
+ return b$1`
10054
+ <div class="${this.wrapperClasses}">
10055
+ <slot @slotchange=${this.handleSlotChange}></slot>
10056
+ </div>
10057
+ `;
10212
10058
  }
10059
+ }
10060
+
10061
+ 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}`;
10062
+
10063
+ 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)}}`;
10064
+
10065
+ 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}
10066
+ `;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}
10067
+ `;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)}
10068
+ `;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)}
10069
+ `;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`
10070
+ <div class="componentWrapper">
10071
+ <div
10072
+ class="${e$3({svgWrapper:true})}"
10073
+ title="${o(this.title||void 0)}">
10074
+ <span aria-hidden="${o(this.ariaHidden||true)}" part="svg">
10075
+ ${this.customSvg?b$1`
10076
+ <slot name="svg"></slot>
10077
+ `:b$1`
10078
+ ${this.svg}
10079
+ `}
10080
+ </span>
10081
+ </div>
10082
+
10083
+ <div class="${e$3(t)}" part="label">
10084
+ <slot></slot>
10085
+ </div>
10086
+ </div>
10087
+ `}}
10088
+
10089
+ var iconVersion = '9.1.2';
10090
+
10091
+ 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>"};
10092
+
10093
+ // Copyright (c) 2021 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license
10094
+ // See LICENSE in the project root for license information.
10095
+
10096
+
10097
+ let menuOptionIdCounter = 0;
10098
+
10099
+ /**
10100
+ * The `auro-menuoption` element provides users a way to define a menu option.
10101
+ * @customElement auro-menuoption
10102
+ *
10103
+ * @slot default - The default slot for the menu option text.
10104
+ *
10105
+ * @event auroMenuOption-mouseover - Notifies that this option has been hovered over.
10106
+ */
10107
+ class AuroMenuOption extends AuroElement$1 {
10213
10108
 
10214
10109
  /**
10215
10110
  * This will register this element with the browser.
10216
- * @param {string} [name="auro-menu"] - The name of the element that you want to register.
10111
+ * @param {string} [name="auro-menuoption"] - The name of the element that you want to register.
10217
10112
  *
10218
10113
  * @example
10219
- * AuroMenu.register("custom-menu") // this will register this element to <custom-menu/>
10114
+ * AuroMenuOption.register("custom-menuoption") // this will register this element to <custom-menuoption/>
10220
10115
  *
10221
10116
  */
10222
- static register(name = "auro-menu") {
10223
- AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenu);
10117
+ static register(name = "auro-menuoption") {
10118
+ AuroLibraryRuntimeUtils$3.prototype.registerComponent(name, AuroMenuOption);
10224
10119
  }
10225
10120
 
10226
10121
  /**
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>}
10122
+ * Returns whether the menu option is currently active and selectable.
10123
+ * An option is considered active if it is not hidden, not disabled, and not static.
10124
+ * @returns {boolean} True if the option is active, false otherwise.
10231
10125
  */
10232
- get formattedValue() {
10233
- return this.menuService.currentValue;
10126
+ get isActive() {
10127
+ return !this.hasAttribute('hidden') &&
10128
+ !this.disabled &&
10129
+ !this.hasAttribute('static');
10234
10130
  }
10235
10131
 
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
- }
10132
+ constructor() {
10133
+ super();
10249
10134
 
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
- }
10135
+ this.bindEvents();
10262
10136
 
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
- }
10137
+ /**
10138
+ * @private
10139
+ */
10140
+ this.shape = undefined;
10271
10141
 
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
- }
10142
+ /**
10143
+ * @private
10144
+ */
10145
+ this.size = undefined;
10279
10146
 
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;
10147
+ /**
10148
+ * Generate unique names for dependency components.
10149
+ */
10150
+ const versioning = new AuroDependencyVersioning$2();
10151
+ this.iconTag = versioning.generateTag('auro-formkit-menuoption-icon', iconVersion, k);
10289
10152
 
10290
- setTimeout(() => {
10291
- this.internalUpdateInProgress = false;
10292
- });
10293
- }
10153
+ this.selected = false;
10154
+ this.noCheckmark = false;
10155
+ this.disabled = false;
10156
+ this.noMatch = false;
10157
+
10158
+ /**
10159
+ * @private
10160
+ */
10161
+ this.runtimeUtils = new AuroLibraryRuntimeUtils$3();
10162
+
10163
+ // Initialize context-related properties
10164
+ this.menuService = null;
10165
+ this.unsubscribe = null;
10166
+
10167
+ /**
10168
+ * @private
10169
+ */
10170
+ this.handleMenuChange = this.handleMenuChange.bind(this);
10294
10171
  }
10295
10172
 
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') {
10173
+ static get properties() {
10174
+ return {
10175
+ ...super.properties,
10176
+
10177
+ /**
10178
+ * When true, disables the menu option.
10179
+ */
10180
+ disabled: {
10181
+ type: Boolean,
10182
+ reflect: true
10183
+ },
10184
+
10185
+ /**
10186
+ * @private
10187
+ */
10188
+ event: {
10189
+ type: String,
10190
+ reflect: true
10191
+ },
10192
+
10193
+ /**
10194
+ * @private
10195
+ */
10196
+ layout: {
10197
+ type: String
10198
+ },
10199
+
10200
+ /**
10201
+ * 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.
10202
+ */
10203
+ key: {
10204
+ type: String,
10205
+ reflect: true
10206
+ },
10207
+
10208
+ /**
10209
+ * @private
10210
+ */
10211
+ menuService: {
10212
+ type: Object,
10213
+ state: true
10214
+ },
10303
10215
 
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;
10216
+ /**
10217
+ * @private
10218
+ */
10219
+ matchWord: {
10220
+ type: String,
10221
+ state: true
10222
+ },
10307
10223
 
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
- }
10224
+ /**
10225
+ * @private
10226
+ */
10227
+ noCheckmark: {
10228
+ type: Boolean,
10229
+ reflect: true
10230
+ },
10313
10231
 
10314
- // Notify components of selection change
10315
- this.notifySelectionChange(event);
10316
- }
10232
+ /**
10233
+ * 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.
10234
+ */
10235
+ noMatch: {
10236
+ type: Boolean,
10237
+ reflect: true,
10238
+ attribute: 'nomatch'
10239
+ },
10317
10240
 
10318
- if (event.type === 'highlightChange') {
10319
- this.optionActive = event.option;
10320
- this._index = event.index;
10321
- }
10241
+ /**
10242
+ * Specifies that an option is selected.
10243
+ */
10244
+ selected: {
10245
+ type: Boolean,
10246
+ reflect: true
10247
+ },
10322
10248
 
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
- }
10249
+ /**
10250
+ * Specifies the tab index of the menu option.
10251
+ */
10252
+ tabIndex: {
10253
+ type: Number,
10254
+ reflect: true
10255
+ },
10332
10256
 
10333
- /**
10334
- * Gets the currently selected options.
10335
- * @returns {Array<HTMLElement>}
10336
- */
10337
- get selectedOptions() {
10338
- return this.menuService ? this.menuService.selectedOptions : [];
10257
+ /**
10258
+ * Specifies the value to be sent to a server.
10259
+ */
10260
+ value: {
10261
+ type: String,
10262
+ reflect: true
10263
+ },
10264
+ };
10339
10265
  }
10340
10266
 
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;
10267
+ static get styles() {
10268
+ return [
10269
+ styleCss,
10270
+ colorCss,
10271
+ tokensCss
10272
+ ];
10347
10273
  }
10348
10274
 
10349
- // Lifecycle Methods
10350
-
10351
10275
  connectedCallback() {
10352
10276
  super.connectedCallback();
10353
10277
 
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
- }
10278
+ // Add the tag name as an attribute if it is different than the component name
10279
+ // Add this step soon as this node gets attached to the DOM to avoid racing condition with menu's value setting logic.
10280
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
10362
10281
 
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);
10282
+ // Set up context consumption in connectedCallback
10283
+ this._contextConsumer = new s$1(this, {
10284
+ context: MenuContext,
10285
+ callback: this.attachTo.bind(this),
10286
+ subscribe: true
10287
+ });
10368
10288
 
10369
- super.disconnectedCallback();
10289
+ // Establish the key property as early as possible.
10290
+ // When a framework (e.g. Svelte) inserts the element into the DOM before
10291
+ // setting its `value` property, both `getAttribute('value')` and
10292
+ // `getAttribute('key')` return null here. Setting `this.key = null`
10293
+ // would block the fallback in `updated()` that assigns key from the
10294
+ // value property (the guard checked `=== undefined`). Only assign key
10295
+ // if at least one source attribute is actually present so that the
10296
+ // `updated()` fallback can run when the value property arrives later.
10297
+ const valueAttr = this.getAttribute('value');
10298
+ const keyAttr = this.getAttribute('key');
10299
+ const resolvedKey = keyAttr !== null ? keyAttr : valueAttr;
10300
+ if (resolvedKey !== null) {
10301
+ this.key = resolvedKey;
10302
+ }
10370
10303
  }
10371
10304
 
10372
10305
  firstUpdated() {
10373
- AuroLibraryRuntimeUtils$3.prototype.handleComponentTagRename(this, 'auro-menu');
10306
+ // Add the tag name as an attribute if it is different than the component name
10307
+ this.runtimeUtils.handleComponentTagRename(this, 'auro-menuoption');
10374
10308
 
10375
- this.loadingSlots = this.querySelectorAll("[slot='loadingText'], [slot='loadingIcon']");
10376
- this.initializeMenu();
10377
- }
10309
+ // Generate unique ID if not already set (required for aria-activedescendant)
10310
+ if (!this.id) {
10311
+ menuOptionIdCounter += 1;
10312
+ this.id = `menuoption-${menuOptionIdCounter}`;
10313
+ }
10314
+
10315
+ this.setAttribute('role', 'option');
10316
+ this.setAttribute('aria-selected', 'false');
10378
10317
 
10318
+ this.addEventListener('mouseover', () => {
10319
+ this.dispatchEvent(new CustomEvent('auroMenuOption-mouseover', {
10320
+ bubbles: true,
10321
+ cancelable: false,
10322
+ composed: true,
10323
+ detail: this
10324
+ }));
10325
+ });
10326
+ }
10379
10327
 
10380
10328
  updated(changedProperties) {
10381
10329
  super.updated(changedProperties);
10382
10330
 
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
- }
10331
+ // Update aria-selected attribute if selected changed
10332
+ if (changedProperties.has('selected')) {
10392
10333
 
10393
- // Handle loading state changes
10394
- if (changedProperties.has('loading')) {
10395
- this.setLoadingState(this.loading);
10334
+ // Update aria-selected attribute
10335
+ this.setAttribute('aria-selected', this.selected.toString());
10336
+
10337
+ // Update menu service selection state if this isn't an internal update
10338
+ if (this.internalUpdateInProgress !== true && this.menuService) {
10339
+ this.menuService[this.selected ? 'selectOption' : 'deselectOption'](this);
10340
+ }
10396
10341
  }
10397
10342
 
10398
- if (changedProperties.has('multiSelect') && this.rootMenu) {
10399
- if (this.multiSelect) {
10400
- this.setAttribute('aria-multiselectable', 'true');
10343
+ if (changedProperties.has('disabled')) {
10344
+ if (this.disabled) {
10345
+ this.setAttribute('aria-disabled', 'true');
10401
10346
  } else {
10402
- this.removeAttribute('aria-multiselectable');
10347
+ this.removeAttribute('aria-disabled');
10403
10348
  }
10404
10349
  }
10350
+
10351
+ if (changedProperties.has('active')) {
10352
+ this.updateActiveClasses();
10353
+ }
10354
+
10355
+ // Update text highlight if matchWord changed
10356
+ if (changedProperties.has('matchWord')) {
10357
+ this.updateTextHighlight();
10358
+ }
10359
+
10360
+ // Set the key to be the passed value if no key is provided.
10361
+ // Loose equality (== null) is intentional: it catches both null AND
10362
+ // undefined. When a framework (e.g. Svelte, React) inserts the element
10363
+ // before setting its value property, connectedCallback skips key
10364
+ // assignment because both attributes are null at that point. The Lit
10365
+ // property default for `key` is undefined (not null), so strict
10366
+ // === null would miss the case and the fallback would never run.
10367
+ if (changedProperties.has('value') && this.key == null) { // eslint-disable-line eqeqeq, no-eq-null
10368
+ this.key = this.value;
10369
+ }
10370
+ }
10371
+
10372
+ disconnectedCallback() {
10373
+ if (this.menuService) {
10374
+ this.menuService.unsubscribe(this.handleMenuChange);
10375
+ this.menuService.removeMenuOption(this);
10376
+ }
10405
10377
  }
10406
10378
 
10407
10379
  /**
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
10380
+ * Sets up event listeners for user interaction with the menu option.
10381
+ * This function enables click and mouse enter events to trigger selection and highlighting logic.
10411
10382
  */
10412
- setTagAttribute(tagName) {
10413
- if (this.tagName.toLowerCase() !== tagName) {
10414
- this.setAttribute(tagName, true);
10415
- }
10383
+ bindEvents() {
10384
+ this.addEventListener('click', this.handleClick.bind(this));
10385
+ this.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
10416
10386
  }
10417
10387
 
10418
10388
  /**
10419
- * Sets the loading state and dispatches a loading change event.
10420
- * @param {boolean} isLoading - Whether the menu is loading.
10421
- * @protected
10389
+ * Attaches this menu option to a menu service and subscribes to its events.
10390
+ * This method enables the option to participate in menu selection and highlighting logic.
10391
+ * @param {Object} service - The menu service instance to attach to.
10422
10392
  */
10423
- setLoadingState(isLoading) {
10424
- this.setAttribute("aria-busy", isLoading);
10425
- dispatchMenuEvent(this, "auroMenu-loadingChange", {
10426
- loading: isLoading,
10427
- hasLoadingPlaceholder: this.hasLoadingPlaceholder
10428
- });
10393
+ attachTo(service) {
10394
+ if (!service) {
10395
+ return;
10396
+ }
10397
+ this.menuService = service;
10398
+ this.menuService.addMenuOption(this);
10399
+ this.menuService.subscribe(this.handleMenuChange);
10429
10400
  }
10430
10401
 
10431
- // Init Methods
10402
+ /**
10403
+ * Handles changes from the menu service and updates the option's state.
10404
+ * This function synchronizes the option's properties and selection/highlight state with menu events.
10405
+ * @param {Object} event - The event object from the menu service.
10406
+ */
10407
+ handleMenuChange(event) {
10408
+
10409
+ // Ignore events without a type or property
10410
+ if (!event || (!event.type && !event.property)) {
10411
+ return;
10412
+ }
10413
+
10414
+ // Update reactive properties based on event type
10415
+ if (event.property && Object.keys(AuroMenuOption.properties).includes(event.property)) {
10416
+ this[event.property] = event.value;
10417
+ }
10418
+
10419
+ // Handle highlight changes
10420
+ if (event.type === 'highlightChange') {
10421
+ const isActive = event.option === this;
10422
+ this.active = isActive;
10423
+ this.updateActiveClasses();
10424
+ }
10425
+
10426
+ if (event.type === 'stateChange') {
10427
+ const isSelected = event.selectedOptions.includes(this);
10428
+ this.setInternalSelected(isSelected);
10429
+ }
10430
+ }
10432
10431
 
10433
10432
  /**
10434
- * Initializes the menu's state and structure.
10435
- * @private
10433
+ * Updates the internal selected state of the menu option bypassing 'updated' and triggers custom events if selected.
10434
+ * This function ensures the option's selection state is synchronized with menu logic and notifies listeners.
10435
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
10436
10436
  */
10437
- initializeMenu() {
10438
- if (this.rootMenu) {
10439
- this.setAttribute('role', 'listbox');
10440
- this.setAttribute('root', '');
10437
+ setInternalSelected(isSelected) {
10438
+ this.internalUpdateInProgress = true;
10439
+ this.selected = isSelected;
10441
10440
 
10442
- if (this.multiSelect) {
10443
- this.setAttribute('aria-multiselectable', 'true');
10444
- }
10441
+ // Fire custom event if selected
10442
+ if (isSelected) {
10443
+ this.handleCustomEvent();
10445
10444
  }
10446
10445
 
10447
- this.handleNestedMenus(this);
10446
+ setTimeout(() => {
10447
+ this.internalUpdateInProgress = false;
10448
+ }, 0);
10448
10449
  }
10449
10450
 
10450
10451
  /**
10451
- * Selects the currently highlighted option.
10452
- * @protected
10452
+ * Sets the selected state of the menu option.
10453
+ * This function updates whether the option is currently selected.
10454
+ * @param {boolean} isSelected - Whether the option should be marked as selected.
10455
+ * @deprecated Simply modify the `selected` property directly instead.
10453
10456
  */
10454
- makeSelection() {
10455
- this.menuService.selectHighlightedOption();
10457
+ setSelected(isSelected) {
10458
+ this.selected = isSelected;
10456
10459
  }
10457
10460
 
10458
10461
  /**
10459
- * Resets all options to their default state.
10460
- * @private
10462
+ * Updates the active state and visual highlighting of the menu option.
10463
+ * This function toggles the option's active status and applies or removes the active CSS class.
10464
+ * @param {boolean} isActive - Whether the option should be marked as active.
10465
+ * @deprecated Simply modify the `active` property directly instead.
10461
10466
  */
10462
- clearSelection() {
10463
- this.optionSelected = undefined;
10464
- this.value = undefined;
10465
- this._index = -1;
10467
+ updateActive(isActive) {
10468
+
10469
+ // Set active state
10470
+ this.active = isActive;
10471
+ this.updateActiveClasses();
10466
10472
  }
10467
10473
 
10468
10474
  /**
10469
- * Resets the menu to its initial state.
10470
- * This is the only way to return value to undefined.
10471
- * @public
10475
+ * Updates the CSS class for the menu option based on its active state.
10476
+ * This function adds or removes the 'active' class to visually indicate the option's active status.
10477
+ * @private
10472
10478
  */
10473
- reset() {
10474
- this.menuService.reset();
10475
-
10476
- // Dispatch reset event
10477
- dispatchMenuEvent(this, 'auroMenu-selectValueReset');
10479
+ updateActiveClasses() {
10480
+ // Update class based on active state
10481
+ if (this.active) this.classList.add('active');
10482
+ else this.classList.remove('active');
10478
10483
  }
10479
10484
 
10485
+
10480
10486
  /**
10481
- * Handles nested menu structure.
10487
+ * Updates the visual highlighting of text within the menu option based on the current match word.
10488
+ * This function highlights matching text segments and manages nested spacers for display formatting.
10482
10489
  * @private
10483
- * @param {HTMLElement} menu - Root menu element.
10484
10490
  */
10485
- handleNestedMenus(menu) {
10486
- menu.level = menu.parentElement.level >= 0 ? menu.parentElement.level + 1 : 0;
10491
+ updateTextHighlight() {
10487
10492
 
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
- }
10493
+ // Regex for matchWord if needed
10494
+ let regexWord = null;
10495
+
10496
+ if (this.matchWord && this.matchWord.length) {
10497
+ const escapedWord = this.matchWord.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
10498
+ regexWord = new RegExp(escapedWord, 'giu');
10494
10499
  }
10495
10500
 
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
- }
10501
+ // Update text highlighting if matchWord changed
10502
+ if (regexWord &&
10503
+ this.isActive && !this.hasAttribute('persistent')) {
10504
+ const nested = this.querySelectorAll('.nestingSpacer');
10502
10505
 
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
- }
10506
+ const displayValueEl = this.querySelector('[slot="displayValue"]');
10507
+ if (displayValueEl) {
10508
+ this.removeChild(displayValueEl);
10509
+ }
10515
10510
 
10516
- /**
10517
- * Handles slot change events.
10518
- * @private
10519
- */
10520
- handleSlotChange() {
10521
- if (this.rootMenu) {
10522
- this.initializeMenu();
10511
+ // Create nested spacers
10512
+ const nestingSpacerBundle = [...nested].map(() => this.nestingSpacer).join('');
10513
+
10514
+ // Update with spacers and matchWord
10515
+ this.innerHTML = nestingSpacerBundle +
10516
+ this.textContent.replace(
10517
+ regexWord,
10518
+ (match) => `<strong>${match}</strong>`
10519
+ );
10520
+ if (displayValueEl) {
10521
+ this.append(displayValueEl);
10522
+ }
10523
10523
  }
10524
10524
  }
10525
10525
 
10526
10526
  /**
10527
- * Handles custom events defined on options.
10527
+ * Handles click events on the menu option, toggling its selected state.
10528
+ * This function dispatches a click event and updates selection if the option is not disabled.
10528
10529
  * @private
10529
- * @param {HTMLElement} option - Option with custom event.
10530
10530
  */
10531
- handleCustomEvent(option) {
10532
- const eventName = option.getAttribute('event');
10533
- dispatchMenuEvent(this, eventName);
10534
- dispatchMenuEvent(this, 'auroMenu-customEventFired');
10531
+ handleClick() {
10532
+ if (!this.disabled) {
10533
+ this.dispatchClickEvent();
10534
+ this.selected = !this.selected;
10535
+ }
10535
10536
  }
10536
10537
 
10537
10538
  /**
10538
- * Notifies selection change to parent components.
10539
- * @param {any} source - The source that triggers this event.
10539
+ * Handles mouse enter events to highlight the menu option.
10540
+ * This function updates the menu service to set this option as the currently highlighted item if not disabled.
10540
10541
  * @private
10541
10542
  */
10542
- notifySelectionChange({value, stringValue, keys, options, reason} = {}) {
10543
- dispatchMenuEvent(this, 'auroMenu-selectedOption', {
10544
- value,
10545
- stringValue,
10546
- keys,
10547
- options,
10548
- reason
10549
- });
10543
+ handleMouseEnter() {
10544
+ if (!this.disabled) {
10545
+ this.menuService.setHighlightedOption(this);
10546
+ }
10550
10547
  }
10551
10548
 
10552
10549
  /**
10553
- * Checks if an option is currently selected.
10550
+ * Dispatches custom events defined for this menu option.
10551
+ * This function notifies listeners when a custom event is triggered by the option.
10554
10552
  * @private
10555
- * @param {HTMLElement} option - The option to check.
10556
- * @returns {boolean}
10557
10553
  */
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);
10554
+ handleCustomEvent() {
10555
+ if (this.event) {
10556
+ dispatchMenuEvent(this, this.event, { option: this });
10557
+ dispatchMenuEvent(this, 'auroMenu-customEventFired', { option: this });
10566
10558
  }
10567
-
10568
- return this.optionSelected === option;
10569
10559
  }
10570
10560
 
10571
10561
  /**
10572
- * Getter for loading placeholder state.
10573
- * @returns {boolean} - True if loading slots are present and non-empty.
10562
+ * Dispatches a click event for this menu option.
10563
+ * This function notifies listeners that the option has been clicked.
10564
+ * @private
10574
10565
  */
10575
- get hasLoadingPlaceholder() {
10576
- return this.loadingSlots && this.loadingSlots.length > 0;
10566
+ dispatchClickEvent() {
10567
+ this.dispatchEvent(new CustomEvent('auroMenuOption-click', {
10568
+ bubbles: true,
10569
+ cancelable: false,
10570
+ composed: true,
10571
+ detail: this
10572
+ }));
10577
10573
  }
10578
10574
 
10579
10575
  /**
10580
- * Getter for wrapper classes based on size.
10581
- * @returns {Object} - Class map for the wrapper element.
10576
+ * Generates an HTML element containing an SVG icon based on the provided `svgContent`.
10577
+ *
10582
10578
  * @private
10579
+ * @param {string} svgContent - The SVG content to be embedded.
10580
+ * @returns {Element} The HTML element containing the SVG icon.
10583
10581
  */
10584
- get wrapperClasses() {
10585
- return e$3({
10586
- 'menuWrapper': true,
10587
- [this.size]: true,
10588
- });
10582
+ generateIconHtml(svgContent) {
10583
+ const dom = new DOMParser().parseFromString(svgContent, 'text/html');
10584
+ const svg = dom.body.firstChild;
10585
+
10586
+ svg.setAttribute('slot', 'svg');
10587
+
10588
+ return u$4`<${this.iconTag} customColor customSvg>${svg}</${this.iconTag}>`;
10589
10589
  }
10590
10590
 
10591
10591
  /**
@@ -10594,26 +10594,26 @@ class AuroMenu extends AuroElement$1 {
10594
10594
  * @returns {void}
10595
10595
  */
10596
10596
  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
10597
 
10614
- return b$1`
10615
- <div class="${this.wrapperClasses}">
10616
- <slot @slotchange=${this.handleSlotChange}></slot>
10598
+ const fontClassMap = {
10599
+ xs: 'body-sm',
10600
+ sm: 'body-default',
10601
+ md: 'body-default',
10602
+ lg: 'body-lg',
10603
+ xl: 'body-lg'
10604
+ };
10605
+
10606
+ const classes = e$3({
10607
+ 'wrapper': true,
10608
+ [this.size ? fontClassMap[this.size] : 'body-sm']: true,
10609
+ });
10610
+
10611
+ return u$4`
10612
+ <div class="${classes}">
10613
+ ${this.selected && !this.noCheckmark
10614
+ ? this.generateIconHtml(checkmarkIcon.svg)
10615
+ : undefined}
10616
+ <slot></slot>
10617
10617
  </div>
10618
10618
  `;
10619
10619
  }