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