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