@aurodesignsystem-dev/auro-formkit 0.0.0-pr1379.0 → 0.0.0-pr1379.10

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