@helixui/library 3.6.0 → 3.8.0-next.145

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 (413) hide show
  1. package/README.md +41 -0
  2. package/aaa-verdicts.json +2036 -0
  3. package/custom-elements.json +3045 -1254
  4. package/dist/components/hx-accordion/hx-accordion-item.d.ts.map +1 -1
  5. package/dist/components/hx-accordion/hx-accordion-item.styles.d.ts.map +1 -1
  6. package/dist/components/hx-accordion/index.js +1 -1
  7. package/dist/components/hx-action-bar/hx-action-bar.d.ts +18 -0
  8. package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
  9. package/dist/components/hx-action-bar/hx-action-bar.styles.d.ts.map +1 -1
  10. package/dist/components/hx-action-bar/index.js +1 -1
  11. package/dist/components/hx-alert/hx-alert.d.ts +18 -8
  12. package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
  13. package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
  14. package/dist/components/hx-alert/index.js +1 -1
  15. package/dist/components/hx-avatar/hx-avatar.d.ts +4 -1
  16. package/dist/components/hx-avatar/hx-avatar.d.ts.map +1 -1
  17. package/dist/components/hx-avatar/hx-avatar.styles.d.ts.map +1 -1
  18. package/dist/components/hx-avatar/index.js +1 -1
  19. package/dist/components/hx-badge/hx-badge.d.ts.map +1 -1
  20. package/dist/components/hx-badge/hx-badge.styles.d.ts.map +1 -1
  21. package/dist/components/hx-badge/index.js +1 -1
  22. package/dist/components/hx-banner/hx-banner.d.ts +19 -8
  23. package/dist/components/hx-banner/hx-banner.d.ts.map +1 -1
  24. package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -1
  25. package/dist/components/hx-banner/index.js +1 -1
  26. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts.map +1 -1
  27. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
  28. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +18 -0
  29. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
  30. package/dist/components/hx-breadcrumb/index.js +1 -1
  31. package/dist/components/hx-button/hx-button.d.ts +18 -0
  32. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  33. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  34. package/dist/components/hx-button/index.js +1 -1
  35. package/dist/components/hx-button-group/hx-button-group.d.ts +47 -0
  36. package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
  37. package/dist/components/hx-button-group/index.js +1 -1
  38. package/dist/components/hx-carousel/hx-carousel.d.ts.map +1 -1
  39. package/dist/components/hx-carousel/hx-carousel.styles.d.ts.map +1 -1
  40. package/dist/components/hx-carousel/index.js +1 -1
  41. package/dist/components/hx-checkbox/hx-checkbox.d.ts +18 -0
  42. package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
  43. package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
  44. package/dist/components/hx-checkbox/index.js +1 -1
  45. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +36 -0
  46. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
  47. package/dist/components/hx-checkbox-group/hx-checkbox-group.styles.d.ts.map +1 -1
  48. package/dist/components/hx-checkbox-group/index.js +1 -1
  49. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts +26 -9
  50. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts.map +1 -1
  51. package/dist/components/hx-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
  52. package/dist/components/hx-clinical-status/index.js +1 -1
  53. package/dist/components/hx-color-picker/hx-color-picker.d.ts +18 -0
  54. package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
  55. package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
  56. package/dist/components/hx-color-picker/index.js +1 -1
  57. package/dist/components/hx-combobox/hx-combobox.d.ts +18 -0
  58. package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
  59. package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
  60. package/dist/components/hx-combobox/index.js +1 -1
  61. package/dist/components/hx-copy-button/hx-copy-button.d.ts +18 -0
  62. package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
  63. package/dist/components/hx-copy-button/hx-copy-button.styles.d.ts.map +1 -1
  64. package/dist/components/hx-copy-button/index.js +1 -1
  65. package/dist/components/hx-date-picker/hx-date-picker.d.ts +18 -0
  66. package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
  67. package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
  68. package/dist/components/hx-date-picker/index.js +1 -1
  69. package/dist/components/hx-dialog/hx-dialog.d.ts +18 -0
  70. package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
  71. package/dist/components/hx-drawer/hx-drawer.d.ts +18 -0
  72. package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
  73. package/dist/components/hx-drawer/hx-drawer.styles.d.ts.map +1 -1
  74. package/dist/components/hx-drawer/index.js +1 -1
  75. package/dist/components/hx-dropdown/hx-dropdown.d.ts +18 -0
  76. package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
  77. package/dist/components/hx-dropdown/hx-dropdown.styles.d.ts.map +1 -1
  78. package/dist/components/hx-dropdown/index.js +1 -1
  79. package/dist/components/hx-field/hx-field.d.ts +17 -0
  80. package/dist/components/hx-field/hx-field.d.ts.map +1 -1
  81. package/dist/components/hx-field-label/hx-field-label.d.ts +17 -0
  82. package/dist/components/hx-field-label/hx-field-label.d.ts.map +1 -1
  83. package/dist/components/hx-file-upload/hx-file-upload.d.ts +46 -0
  84. package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
  85. package/dist/components/hx-file-upload/hx-file-upload.styles.d.ts.map +1 -1
  86. package/dist/components/hx-file-upload/index.js +1 -1
  87. package/dist/components/hx-form/hx-form.d.ts +19 -0
  88. package/dist/components/hx-form/hx-form.d.ts.map +1 -1
  89. package/dist/components/hx-help-text/hx-help-text.d.ts +17 -0
  90. package/dist/components/hx-help-text/hx-help-text.d.ts.map +1 -1
  91. package/dist/components/hx-help-text/hx-help-text.styles.d.ts.map +1 -1
  92. package/dist/components/hx-help-text/index.js +1 -1
  93. package/dist/components/hx-icon/hx-icon.d.ts +108 -12
  94. package/dist/components/hx-icon/hx-icon.d.ts.map +1 -1
  95. package/dist/components/hx-icon/hx-icon.styles.d.ts.map +1 -1
  96. package/dist/components/hx-icon/index.js +1 -1
  97. package/dist/components/hx-icon-button/hx-icon-button.d.ts +18 -0
  98. package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
  99. package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
  100. package/dist/components/hx-icon-button/index.js +1 -1
  101. package/dist/components/hx-link/hx-link.d.ts.map +1 -1
  102. package/dist/components/hx-link/hx-link.styles.d.ts.map +1 -1
  103. package/dist/components/hx-link/index.js +1 -1
  104. package/dist/components/hx-menu/hx-menu-item.d.ts.map +1 -1
  105. package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
  106. package/dist/components/hx-menu/hx-menu.d.ts +18 -0
  107. package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
  108. package/dist/components/hx-menu/index.js +1 -1
  109. package/dist/components/hx-nav/hx-nav.d.ts +18 -0
  110. package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
  111. package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
  112. package/dist/components/hx-nav/index.js +1 -1
  113. package/dist/components/hx-number-input/hx-number-input.d.ts +18 -0
  114. package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
  115. package/dist/components/hx-number-input/hx-number-input.styles.d.ts.map +1 -1
  116. package/dist/components/hx-number-input/index.js +1 -1
  117. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts +23 -1
  118. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
  119. package/dist/components/hx-overflow-menu/hx-overflow-menu.styles.d.ts.map +1 -1
  120. package/dist/components/hx-overflow-menu/index.js +1 -1
  121. package/dist/components/hx-pagination/hx-pagination.styles.d.ts.map +1 -1
  122. package/dist/components/hx-pagination/index.js +1 -1
  123. package/dist/components/hx-phi-field/hx-phi-field.d.ts.map +1 -1
  124. package/dist/components/hx-phi-field/hx-phi-field.styles.d.ts.map +1 -1
  125. package/dist/components/hx-phi-field/index.js +1 -1
  126. package/dist/components/hx-popover/hx-popover.d.ts +18 -0
  127. package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
  128. package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
  129. package/dist/components/hx-popover/index.js +1 -1
  130. package/dist/components/hx-popup/hx-popup.d.ts +18 -0
  131. package/dist/components/hx-popup/hx-popup.d.ts.map +1 -1
  132. package/dist/components/hx-popup/hx-popup.styles.d.ts.map +1 -1
  133. package/dist/components/hx-popup/index.js +1 -1
  134. package/dist/components/hx-radio-group/hx-radio-group.d.ts +18 -0
  135. package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
  136. package/dist/components/hx-radio-group/hx-radio-group.styles.d.ts.map +1 -1
  137. package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
  138. package/dist/components/hx-radio-group/index.js +1 -1
  139. package/dist/components/hx-rating/hx-rating.d.ts +19 -0
  140. package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
  141. package/dist/components/hx-rating/hx-rating.styles.d.ts.map +1 -1
  142. package/dist/components/hx-rating/index.js +1 -1
  143. package/dist/components/hx-select/hx-select.d.ts +18 -0
  144. package/dist/components/hx-select/hx-select.d.ts.map +1 -1
  145. package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
  146. package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
  147. package/dist/components/hx-side-nav/hx-side-nav.d.ts +18 -0
  148. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  149. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  150. package/dist/components/hx-side-nav/index.js +1 -1
  151. package/dist/components/hx-slider/hx-slider.d.ts +47 -0
  152. package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
  153. package/dist/components/hx-slider/index.js +1 -1
  154. package/dist/components/hx-split-button/hx-split-button.d.ts +18 -0
  155. package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
  156. package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
  157. package/dist/components/hx-split-button/index.js +1 -1
  158. package/dist/components/hx-stat/hx-stat.d.ts.map +1 -1
  159. package/dist/components/hx-stat/hx-stat.styles.d.ts.map +1 -1
  160. package/dist/components/hx-stat/index.js +1 -1
  161. package/dist/components/hx-steps/hx-step.d.ts.map +1 -1
  162. package/dist/components/hx-steps/hx-step.styles.d.ts.map +1 -1
  163. package/dist/components/hx-steps/index.js +1 -1
  164. package/dist/components/hx-switch/hx-switch.d.ts +18 -0
  165. package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
  166. package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
  167. package/dist/components/hx-switch/index.js +1 -1
  168. package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
  169. package/dist/components/hx-tabs/hx-tabs.d.ts +18 -0
  170. package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
  171. package/dist/components/hx-tabs/index.js +1 -1
  172. package/dist/components/hx-tag/hx-tag.d.ts.map +1 -1
  173. package/dist/components/hx-tag/hx-tag.styles.d.ts.map +1 -1
  174. package/dist/components/hx-tag/index.js +1 -1
  175. package/dist/components/hx-text-input/hx-text-input.d.ts +18 -0
  176. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  177. package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
  178. package/dist/components/hx-text-input/index.js +1 -1
  179. package/dist/components/hx-textarea/hx-textarea.d.ts +18 -0
  180. package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
  181. package/dist/components/hx-time-picker/hx-time-picker.d.ts +18 -0
  182. package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
  183. package/dist/components/hx-time-picker/hx-time-picker.styles.d.ts.map +1 -1
  184. package/dist/components/hx-time-picker/index.js +1 -1
  185. package/dist/components/hx-toast/hx-toast.d.ts +19 -8
  186. package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
  187. package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
  188. package/dist/components/hx-toast/index.js +1 -1
  189. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +18 -0
  190. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
  191. package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
  192. package/dist/components/hx-toggle-button/index.js +1 -1
  193. package/dist/components/hx-tooltip/hx-tooltip.d.ts +18 -0
  194. package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
  195. package/dist/components/hx-tooltip/hx-tooltip.styles.d.ts.map +1 -1
  196. package/dist/components/hx-tooltip/index.js +1 -1
  197. package/dist/components/hx-top-nav/hx-top-nav.d.ts +18 -0
  198. package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +1 -1
  199. package/dist/components/hx-top-nav/hx-top-nav.styles.d.ts.map +1 -1
  200. package/dist/components/hx-top-nav/index.js +1 -1
  201. package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
  202. package/dist/components/hx-tree-view/hx-tree-item.styles.d.ts.map +1 -1
  203. package/dist/components/hx-tree-view/index.js +1 -1
  204. package/dist/css/helix-all.css +414 -118
  205. package/dist/css/helix-core.css +43 -19
  206. package/dist/css/helix-feedback.css +15 -18
  207. package/dist/css/helix-forms.css +172 -44
  208. package/dist/css/helix-media.css +6 -3
  209. package/dist/css/helix-navigation.css +65 -12
  210. package/dist/css/helix-overlay.css +63 -0
  211. package/dist/css/helix-tokens.css +18 -15
  212. package/dist/css/helix-utility.css +44 -12
  213. package/dist/css/hx-action-bar.css +12 -0
  214. package/dist/css/hx-alert.css +4 -8
  215. package/dist/css/hx-avatar.css +1 -2
  216. package/dist/css/hx-badge.css +10 -5
  217. package/dist/css/hx-banner.css +4 -8
  218. package/dist/css/hx-button.css +15 -5
  219. package/dist/css/hx-carousel.css +6 -3
  220. package/dist/css/hx-checkbox-group.css +11 -0
  221. package/dist/css/hx-checkbox.css +24 -13
  222. package/dist/css/hx-clinical-status.css +4 -7
  223. package/dist/css/hx-color-picker.css +14 -1
  224. package/dist/css/hx-combobox.css +8 -0
  225. package/dist/css/hx-copy-button.css +5 -2
  226. package/dist/css/hx-date-picker.css +16 -3
  227. package/dist/css/hx-drawer.css +5 -0
  228. package/dist/css/hx-dropdown.css +18 -0
  229. package/dist/css/hx-file-upload.css +4 -0
  230. package/dist/css/hx-help-text.css +5 -0
  231. package/dist/css/hx-icon-button.css +4 -5
  232. package/dist/css/hx-icon.css +7 -0
  233. package/dist/css/hx-link.css +1 -2
  234. package/dist/css/hx-nav.css +31 -2
  235. package/dist/css/hx-number-input.css +10 -11
  236. package/dist/css/hx-overflow-menu.css +5 -0
  237. package/dist/css/hx-pagination.css +6 -3
  238. package/dist/css/hx-phi-field.css +2 -3
  239. package/dist/css/hx-popover.css +13 -0
  240. package/dist/css/hx-popup.css +14 -0
  241. package/dist/css/hx-radio-group.css +10 -0
  242. package/dist/css/hx-rating.css +6 -0
  243. package/dist/css/hx-side-nav.css +10 -5
  244. package/dist/css/hx-split-button.css +27 -10
  245. package/dist/css/hx-stat.css +1 -2
  246. package/dist/css/hx-switch.css +19 -1
  247. package/dist/css/hx-tag.css +5 -0
  248. package/dist/css/hx-text-input.css +4 -1
  249. package/dist/css/hx-time-picker.css +12 -2
  250. package/dist/css/hx-toast.css +6 -0
  251. package/dist/css/hx-toggle-button.css +29 -12
  252. package/dist/css/hx-tooltip.css +13 -0
  253. package/dist/css/hx-top-nav.css +13 -2
  254. package/dist/css/index.css +1 -1
  255. package/dist/css/manifest.json +60 -20
  256. package/dist/index.js +49 -49
  257. package/dist/shared/{hx-accordion-ZVzgDzTG.js → hx-accordion-DR--Ev4t.js} +48 -54
  258. package/dist/shared/hx-accordion-DR--Ev4t.js.map +1 -0
  259. package/dist/shared/{hx-action-bar-CitgcpGv.js → hx-action-bar-BlEG4aZv.js} +41 -29
  260. package/dist/shared/hx-action-bar-BlEG4aZv.js.map +1 -0
  261. package/dist/shared/{hx-alert-Bto8-TIi.js → hx-alert-C0axS32J.js} +40 -79
  262. package/dist/shared/hx-alert-C0axS32J.js.map +1 -0
  263. package/dist/shared/{hx-avatar-C9hOmlAb.js → hx-avatar-ChAYWnK8.js} +22 -24
  264. package/dist/shared/hx-avatar-ChAYWnK8.js.map +1 -0
  265. package/dist/shared/{hx-badge-JlFtAdxS.js → hx-badge-vX-1cuLA.js} +25 -20
  266. package/dist/shared/hx-badge-vX-1cuLA.js.map +1 -0
  267. package/dist/shared/{hx-banner-fpRnciIO.js → hx-banner-PbHwFNSb.js} +51 -90
  268. package/dist/shared/hx-banner-PbHwFNSb.js.map +1 -0
  269. package/dist/shared/{hx-breadcrumb-item-3tKppF9h.js → hx-breadcrumb-item-D8xYqe3s.js} +56 -43
  270. package/dist/shared/hx-breadcrumb-item-D8xYqe3s.js.map +1 -0
  271. package/dist/shared/{hx-button-BOwAEcF1.js → hx-button-DOZTZnz-.js} +29 -19
  272. package/dist/shared/hx-button-DOZTZnz-.js.map +1 -0
  273. package/dist/shared/hx-button-group-D3QUmSzl.js +248 -0
  274. package/dist/shared/hx-button-group-D3QUmSzl.js.map +1 -0
  275. package/dist/shared/{hx-carousel-item-z1Lc24op.js → hx-carousel-item-BVIKgQ4i.js} +72 -102
  276. package/dist/shared/hx-carousel-item-BVIKgQ4i.js.map +1 -0
  277. package/dist/shared/{hx-checkbox-CYd0YV_u.js → hx-checkbox-DDSXXhps.js} +56 -47
  278. package/dist/shared/hx-checkbox-DDSXXhps.js.map +1 -0
  279. package/dist/shared/{hx-checkbox-group-D5piJLY8.js → hx-checkbox-group-C0q6HDqn.js} +101 -58
  280. package/dist/shared/hx-checkbox-group-C0q6HDqn.js.map +1 -0
  281. package/dist/shared/{hx-clinical-status-D3XQIOqX.js → hx-clinical-status-ZSVEc3Qg.js} +68 -87
  282. package/dist/shared/hx-clinical-status-ZSVEc3Qg.js.map +1 -0
  283. package/dist/shared/{hx-color-picker-DBwJzT5f.js → hx-color-picker-CYjx8i8R.js} +97 -84
  284. package/dist/shared/hx-color-picker-CYjx8i8R.js.map +1 -0
  285. package/dist/shared/{hx-combobox-NgJaLbs2.js → hx-combobox-Be-mqOv4.js} +35 -45
  286. package/dist/shared/hx-combobox-Be-mqOv4.js.map +1 -0
  287. package/dist/shared/{hx-copy-button-sUVuikyH.js → hx-copy-button-DJirFCUL.js} +18 -15
  288. package/dist/shared/hx-copy-button-DJirFCUL.js.map +1 -0
  289. package/dist/shared/{hx-date-picker-B49yo4Vm.js → hx-date-picker-CziP3Hm1.js} +85 -84
  290. package/dist/shared/hx-date-picker-CziP3Hm1.js.map +1 -0
  291. package/dist/shared/hx-dialog-B4weoj_1.js.map +1 -1
  292. package/dist/shared/{hx-drawer-CM_upadk.js → hx-drawer-BlU2oX8-.js} +32 -36
  293. package/dist/shared/hx-drawer-BlU2oX8-.js.map +1 -0
  294. package/dist/shared/{hx-dropdown-D626S2ZG.js → hx-dropdown-DREqpIpm.js} +51 -33
  295. package/dist/shared/hx-dropdown-DREqpIpm.js.map +1 -0
  296. package/dist/shared/hx-field-label-BVRyyKeh.js.map +1 -1
  297. package/dist/shared/hx-field-zw0U1KVi.js.map +1 -1
  298. package/dist/shared/{hx-file-upload-D3rKROK5.js → hx-file-upload-CU5QGZSP.js} +137 -80
  299. package/dist/shared/hx-file-upload-CU5QGZSP.js.map +1 -0
  300. package/dist/shared/hx-form-CkChEATa.js.map +1 -1
  301. package/dist/shared/hx-help-text-CNaZ82LT.js +137 -0
  302. package/dist/shared/hx-help-text-CNaZ82LT.js.map +1 -0
  303. package/dist/shared/{hx-icon-button-a6OpeQz5.js → hx-icon-button-B2BdVdyK.js} +10 -11
  304. package/dist/shared/hx-icon-button-B2BdVdyK.js.map +1 -0
  305. package/dist/shared/hx-icon-bxz9eB9a.js +386 -0
  306. package/dist/shared/hx-icon-bxz9eB9a.js.map +1 -0
  307. package/dist/shared/{hx-link-CMnZRUtQ.js → hx-link-BURSdYLp.js} +19 -26
  308. package/dist/shared/hx-link-BURSdYLp.js.map +1 -0
  309. package/dist/shared/{hx-menu-divider-A6Guuzi_.js → hx-menu-divider-g0grbWV9.js} +19 -31
  310. package/dist/shared/hx-menu-divider-g0grbWV9.js.map +1 -0
  311. package/dist/shared/{hx-nav-ldFM3Fle.js → hx-nav-GTsAZGOx.js} +94 -85
  312. package/dist/shared/hx-nav-GTsAZGOx.js.map +1 -0
  313. package/dist/shared/{hx-nav-item-CODtUlew.js → hx-nav-item-CxE7Mp3M.js} +46 -41
  314. package/dist/shared/hx-nav-item-CxE7Mp3M.js.map +1 -0
  315. package/dist/shared/{hx-number-input-yUzFOSC1.js → hx-number-input-Bvyc9kOi.js} +59 -64
  316. package/dist/shared/hx-number-input-Bvyc9kOi.js.map +1 -0
  317. package/dist/shared/{hx-overflow-menu-DFjJAziP.js → hx-overflow-menu-LrTteeR1.js} +32 -39
  318. package/dist/shared/{hx-overflow-menu-DFjJAziP.js.map → hx-overflow-menu-LrTteeR1.js.map} +1 -1
  319. package/dist/shared/{hx-pagination-C7y8GVyU.js → hx-pagination-D726PyTM.js} +7 -4
  320. package/dist/shared/hx-pagination-D726PyTM.js.map +1 -0
  321. package/dist/shared/{hx-phi-field-C19oxlrr.js → hx-phi-field-sZt_rYIL.js} +46 -66
  322. package/dist/shared/hx-phi-field-sZt_rYIL.js.map +1 -0
  323. package/dist/shared/{hx-popover-BAlAFOH9.js → hx-popover-BjB0nkcq.js} +51 -38
  324. package/dist/shared/hx-popover-BjB0nkcq.js.map +1 -0
  325. package/dist/shared/{hx-popup-COUXXZ9X.js → hx-popup-BiV_2evC.js} +59 -45
  326. package/dist/shared/hx-popup-BiV_2evC.js.map +1 -0
  327. package/dist/shared/{hx-radio-C7eTj5YI.js → hx-radio-BD_c9NJy.js} +52 -39
  328. package/dist/shared/hx-radio-BD_c9NJy.js.map +1 -0
  329. package/dist/shared/{hx-rating-C3QP53k9.js → hx-rating-BGK4AxvI.js} +45 -71
  330. package/dist/shared/hx-rating-BGK4AxvI.js.map +1 -0
  331. package/dist/shared/hx-select-DahFehiZ.js.map +1 -1
  332. package/dist/shared/{hx-slider-Blmv_rwS.js → hx-slider-CkOk5BCY.js} +83 -23
  333. package/dist/shared/hx-slider-CkOk5BCY.js.map +1 -0
  334. package/dist/shared/{hx-split-button-Ddle8iVx.js → hx-split-button-Bg9FHrFK.js} +73 -65
  335. package/dist/shared/hx-split-button-Bg9FHrFK.js.map +1 -0
  336. package/dist/shared/{hx-stat-Gtw_SpK8.js → hx-stat-wKxbyep6.js} +22 -55
  337. package/dist/shared/hx-stat-wKxbyep6.js.map +1 -0
  338. package/dist/shared/{hx-step-R2rjp1fT.js → hx-step-CyGQAuiB.js} +7 -27
  339. package/dist/shared/hx-step-CyGQAuiB.js.map +1 -0
  340. package/dist/shared/{hx-switch-TvKGvZJz.js → hx-switch-BCXuNxEH.js} +42 -24
  341. package/dist/shared/hx-switch-BCXuNxEH.js.map +1 -0
  342. package/dist/shared/{hx-tab-panel-DzsX8BHV.js → hx-tab-panel-BfisavKo.js} +47 -32
  343. package/dist/shared/hx-tab-panel-BfisavKo.js.map +1 -0
  344. package/dist/shared/{hx-tag-C5aCUpVi.js → hx-tag-BqO6HY6V.js} +26 -21
  345. package/dist/shared/hx-tag-BqO6HY6V.js.map +1 -0
  346. package/dist/shared/{hx-text-input-D6FlOZM-.js → hx-text-input-V5sQOpDh.js} +5 -2
  347. package/dist/shared/hx-text-input-V5sQOpDh.js.map +1 -0
  348. package/dist/shared/hx-textarea-CNG590KY.js.map +1 -1
  349. package/dist/shared/{hx-time-picker-Bo7FWzmf.js → hx-time-picker-if5Cl0Ei.js} +42 -43
  350. package/dist/shared/hx-time-picker-if5Cl0Ei.js.map +1 -0
  351. package/dist/shared/{hx-toggle-button-DwBers3A.js → hx-toggle-button-xNVYeA3X.js} +64 -47
  352. package/dist/shared/hx-toggle-button-xNVYeA3X.js.map +1 -0
  353. package/dist/shared/{hx-tooltip-DVqtKPCD.js → hx-tooltip-CamO-9nd.js} +24 -11
  354. package/dist/shared/hx-tooltip-CamO-9nd.js.map +1 -0
  355. package/dist/shared/{hx-top-nav-DP6OFS8C.js → hx-top-nav-vP6oDWMV.js} +42 -44
  356. package/dist/shared/hx-top-nav-vP6oDWMV.js.map +1 -0
  357. package/dist/shared/{hx-tree-item-CXyspGxI.js → hx-tree-item-D8hwKd5m.js} +54 -57
  358. package/dist/shared/hx-tree-item-D8hwKd5m.js.map +1 -0
  359. package/dist/shared/{toast-factory-Dht3pVsw.js → toast-factory-DgnbFxVs.js} +127 -153
  360. package/dist/shared/toast-factory-DgnbFxVs.js.map +1 -0
  361. package/figma-inventory.json +1280 -429
  362. package/package.json +8 -4
  363. package/dist/shared/hx-accordion-ZVzgDzTG.js.map +0 -1
  364. package/dist/shared/hx-action-bar-CitgcpGv.js.map +0 -1
  365. package/dist/shared/hx-alert-Bto8-TIi.js.map +0 -1
  366. package/dist/shared/hx-avatar-C9hOmlAb.js.map +0 -1
  367. package/dist/shared/hx-badge-JlFtAdxS.js.map +0 -1
  368. package/dist/shared/hx-banner-fpRnciIO.js.map +0 -1
  369. package/dist/shared/hx-breadcrumb-item-3tKppF9h.js.map +0 -1
  370. package/dist/shared/hx-button-BOwAEcF1.js.map +0 -1
  371. package/dist/shared/hx-button-group-4NUBpkyC.js +0 -181
  372. package/dist/shared/hx-button-group-4NUBpkyC.js.map +0 -1
  373. package/dist/shared/hx-carousel-item-z1Lc24op.js.map +0 -1
  374. package/dist/shared/hx-checkbox-CYd0YV_u.js.map +0 -1
  375. package/dist/shared/hx-checkbox-group-D5piJLY8.js.map +0 -1
  376. package/dist/shared/hx-clinical-status-D3XQIOqX.js.map +0 -1
  377. package/dist/shared/hx-color-picker-DBwJzT5f.js.map +0 -1
  378. package/dist/shared/hx-combobox-NgJaLbs2.js.map +0 -1
  379. package/dist/shared/hx-copy-button-sUVuikyH.js.map +0 -1
  380. package/dist/shared/hx-date-picker-B49yo4Vm.js.map +0 -1
  381. package/dist/shared/hx-drawer-CM_upadk.js.map +0 -1
  382. package/dist/shared/hx-dropdown-D626S2ZG.js.map +0 -1
  383. package/dist/shared/hx-file-upload-D3rKROK5.js.map +0 -1
  384. package/dist/shared/hx-help-text-Xb2Yr8x2.js +0 -156
  385. package/dist/shared/hx-help-text-Xb2Yr8x2.js.map +0 -1
  386. package/dist/shared/hx-icon-button-a6OpeQz5.js.map +0 -1
  387. package/dist/shared/hx-icon-fuVm4-bk.js +0 -283
  388. package/dist/shared/hx-icon-fuVm4-bk.js.map +0 -1
  389. package/dist/shared/hx-link-CMnZRUtQ.js.map +0 -1
  390. package/dist/shared/hx-menu-divider-A6Guuzi_.js.map +0 -1
  391. package/dist/shared/hx-nav-item-CODtUlew.js.map +0 -1
  392. package/dist/shared/hx-nav-ldFM3Fle.js.map +0 -1
  393. package/dist/shared/hx-number-input-yUzFOSC1.js.map +0 -1
  394. package/dist/shared/hx-pagination-C7y8GVyU.js.map +0 -1
  395. package/dist/shared/hx-phi-field-C19oxlrr.js.map +0 -1
  396. package/dist/shared/hx-popover-BAlAFOH9.js.map +0 -1
  397. package/dist/shared/hx-popup-COUXXZ9X.js.map +0 -1
  398. package/dist/shared/hx-radio-C7eTj5YI.js.map +0 -1
  399. package/dist/shared/hx-rating-C3QP53k9.js.map +0 -1
  400. package/dist/shared/hx-slider-Blmv_rwS.js.map +0 -1
  401. package/dist/shared/hx-split-button-Ddle8iVx.js.map +0 -1
  402. package/dist/shared/hx-stat-Gtw_SpK8.js.map +0 -1
  403. package/dist/shared/hx-step-R2rjp1fT.js.map +0 -1
  404. package/dist/shared/hx-switch-TvKGvZJz.js.map +0 -1
  405. package/dist/shared/hx-tab-panel-DzsX8BHV.js.map +0 -1
  406. package/dist/shared/hx-tag-C5aCUpVi.js.map +0 -1
  407. package/dist/shared/hx-text-input-D6FlOZM-.js.map +0 -1
  408. package/dist/shared/hx-time-picker-Bo7FWzmf.js.map +0 -1
  409. package/dist/shared/hx-toggle-button-DwBers3A.js.map +0 -1
  410. package/dist/shared/hx-tooltip-DVqtKPCD.js.map +0 -1
  411. package/dist/shared/hx-top-nav-DP6OFS8C.js.map +0 -1
  412. package/dist/shared/hx-tree-item-CXyspGxI.js.map +0 -1
  413. package/dist/shared/toast-factory-Dht3pVsw.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-icon-fuVm4-bk.js","sources":["../../src/components/hx-icon/hx-icon.styles.ts","../../src/components/hx-icon/hx-icon.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixIconStyles = css`\n :host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* vertical-align: middle ensures the icon aligns to the visual centre of\n adjacent inline text rather than the text baseline. */\n vertical-align: middle;\n /* overflow: hidden prevents malformed or oversized icons from painting\n outside the component boundary. The inner SVG may still set\n overflow: visible for its own viewBox content. */\n overflow: hidden;\n width: var(--hx-icon-size, var(--hx-size-6, 1.5rem));\n height: var(--hx-icon-size, var(--hx-size-6, 1.5rem));\n color: var(--hx-icon-color, currentColor);\n flex-shrink: 0;\n }\n\n /* ─── Size Variants ───\n Fallback pixel values mirror the design token values at time of writing.\n If token values are updated the fallbacks should be updated to match. */\n\n :host([hx-size='xs']) {\n --hx-icon-size: var(--hx-size-4, 1rem);\n }\n\n :host([hx-size='sm']) {\n --hx-icon-size: var(--hx-size-5, 1.25rem);\n }\n\n :host([hx-size='md']) {\n --hx-icon-size: var(--hx-size-6, 1.5rem);\n }\n\n :host([hx-size='lg']) {\n --hx-icon-size: var(--hx-size-8, 2rem);\n }\n\n :host([hx-size='xl']) {\n --hx-icon-size: var(--hx-size-10, 2.5rem);\n }\n\n /* ─── SVG (sprite mode) ───\n In sprite mode [part=\"svg\"] is an actual <svg> element. The selector\n targets it specifically. In inline mode the part is applied to a <span>\n wrapper — see .icon__inline below. */\n\n svg[part='svg'] {\n width: 100%;\n height: 100%;\n fill: currentColor;\n display: block;\n overflow: visible;\n }\n\n /* ─── Inline SVG wrapper ───\n In inline mode [part=\"svg\"] is a <span> that wraps the fetched SVG.\n The inner <svg> is sized to fill the wrapper. */\n\n .icon__inline {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }\n\n .icon__inline svg {\n width: 100%;\n height: 100%;\n fill: currentColor;\n display: block;\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n :host {\n color: CanvasText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixIconStyles } from './hx-icon.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\n\n/**\n * An icon component that supports inline SVG fetching and SVG sprite sheet references.\n * Decorative icons are automatically hidden from assistive technology.\n * When a label is provided the icon is announced as an image with that label.\n *\n * **Render modes:**\n * - **Sprite mode** (recommended for Drupal/SSR): Set `name` and optionally `sprite-url`.\n * Renders an `<svg><use href=\"...#name\">` — works server-side without JavaScript.\n * - **Inline mode**: Set `src` to a URL of a standalone SVG file. The component fetches,\n * sanitizes, and embeds the SVG markup. Requires JavaScript; not server-side renderable.\n * For Drupal/Twig templates use sprite mode to avoid content shift before hydration.\n *\n * @summary SVG icon with sprite and inline fetch modes for healthcare applications.\n *\n * @tag hx-icon\n *\n * @csspart svg - The SVG element rendered in sprite mode, or the inline SVG container\n * in inline mode. In sprite mode this is an `<svg>` element; in inline mode it is a\n * `<span>` element wrapping the fetched SVG. Both expose the same `part` name for\n * consistent external styling via `::part(svg)`.\n *\n * @cssprop [--hx-icon-size=var(--hx-size-6,1.5rem)] - Width and height of the icon.\n * @cssprop [--hx-icon-color=currentColor] - Icon color.\n * @cssprop [--hx-size-4] - Size token.\n * @cssprop [--hx-size-5] - Size token.\n * @cssprop [--hx-size-6] - Size token.\n * @cssprop [--hx-size-8] - Size token.\n * @cssprop [--hx-size-10] - Size token.\n */\n@customElement('hx-icon')\nexport class HelixIcon extends HelixElement {\n static override styles = [helixIconStyles, forcedColorsSurface];\n\n /**\n * Icon name used as the fragment identifier when referencing a sprite sheet.\n * For sprite mode provide the bare symbol id (e.g. `check`). The component\n * will build the full href as `${spriteUrl}#${name}`. If `name` already\n * starts with `#` it is used as-is (inline sprite reference without a base\n * URL).\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * URL of a standalone SVG file to fetch and render inline. Takes precedence\n * over sprite mode when both `src` and `spriteUrl`/`name` are set.\n *\n * **Note:** Inline mode requires browser JavaScript (`fetch` + `DOMParser`).\n * It is not server-side renderable. For Drupal/Twig use sprite mode instead.\n * @attr src\n */\n @property({ type: String })\n src: string | undefined = undefined;\n\n /**\n * Base URL of the SVG sprite sheet. Used together with `name` to construct\n * the `<use>` href: `${spriteUrl}#${name}`.\n * @attr sprite-url\n */\n @property({ type: String, attribute: 'sprite-url' })\n spriteUrl: string | undefined = undefined;\n\n /**\n * Size variant of the icon.\n *\n * Set via the `hx-size` HTML attribute (e.g. `hx-size=\"lg\"`) or via the\n * `size` JavaScript property (e.g. `el.size = 'lg'`). Both are equivalent —\n * the `attribute: 'hx-size'` mapping is used to avoid colliding with the\n * native `<input>` `size` attribute in Drupal attribute-passthrough scenarios.\n * The CEM exposes both the JS property name (`size`) and the HTML attribute\n * name (`hx-size`).\n *\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md';\n\n /**\n * Accessible label for the icon. When non-empty, `role=\"img\"` and\n * `aria-label` are applied so assistive technology announces the icon.\n * When empty the icon is treated as decorative and `aria-hidden=\"true\"` is\n * applied.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Comma-separated list of allowed origins for cross-origin SVG fetches.\n * By default, only same-origin URLs are permitted. Set this to allow\n * specific CDN or asset server origins (e.g., \"https://cdn.example.com,https://assets.example.com\").\n * @attr allowed-origins\n */\n @property({ type: String, attribute: 'allowed-origins' })\n allowedOrigins = '';\n\n /**\n * Stores the sanitized inner markup of an externally fetched SVG.\n * @internal\n */\n @state()\n private _inlineSvg = '';\n\n /**\n * Tracks the `src` URL that was last successfully fetched so that we only\n * refetch when it genuinely changes.\n * @internal\n */\n @state()\n private _fetchedSrc: string | undefined = undefined;\n\n /**\n * Monotonically-increasing sequence number. Incremented before each fetch so\n * that stale out-of-order responses can be discarded.\n */\n /** @internal */\n private _fetchSeq = 0;\n\n // ─── Lifecycle ───\n\n override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n if (changed.has('src') && this.src !== this._fetchedSrc) {\n void this._fetchInlineSvg(this.src);\n }\n }\n\n // ─── Inline SVG Fetch ───\n\n /** @internal */\n private async _fetchInlineSvg(url: string | undefined): Promise<void> {\n const seq = ++this._fetchSeq;\n\n if (!url) {\n this._inlineSvg = '';\n this._fetchedSrc = undefined;\n return;\n }\n\n // Validate URL origin — only allow same-origin or data: URIs by default.\n // Cross-origin SVGs are blocked unless explicitly allowed via allowedOrigins.\n if (!this._isAllowedOrigin(url)) {\n console.warn(\n `[hx-icon] Blocked cross-origin SVG fetch: \"${url}\". ` +\n 'Only same-origin URLs are allowed by default. ' +\n 'Set the allowed-origins attribute to permit specific external origins.',\n );\n this._inlineSvg = '';\n this._fetchedSrc = undefined;\n return;\n }\n\n // Use module-level cache to avoid duplicate network requests for the same URL.\n // Multiple hx-icon instances sharing the same src will share one in-flight fetch.\n try {\n let pending = _svgCache.get(url);\n if (!pending) {\n pending = fetch(url).then(async (response) => {\n if (!response.ok) {\n _svgCache.delete(url);\n return '';\n }\n return response.text();\n });\n _svgCache.set(url, pending);\n }\n\n const text = await pending;\n if (seq !== this._fetchSeq) return;\n\n if (!text) {\n this._inlineSvg = '';\n this._fetchedSrc = undefined;\n return;\n }\n\n const sanitized = this._sanitizeSvg(text);\n this._inlineSvg = sanitized;\n this._fetchedSrc = url;\n } catch {\n if (seq !== this._fetchSeq) return;\n _svgCache.delete(url);\n this._inlineSvg = '';\n this._fetchedSrc = undefined;\n }\n }\n\n /**\n * Checks whether a URL is same-origin or matches the configured allowedOrigins.\n * Relative URLs and data: URIs are always allowed. Cross-origin URLs are blocked\n * unless their origin appears in the allowedOrigins list.\n * @internal\n */\n private _isAllowedOrigin(url: string): boolean {\n // Relative URLs are always same-origin\n if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {\n return true;\n }\n\n try {\n const parsed = new URL(url, window.location.href);\n\n // Same-origin is always allowed\n if (parsed.origin === window.location.origin) {\n return true;\n }\n\n // Check configured allowlist\n if (this.allowedOrigins) {\n const allowed = this.allowedOrigins\n .split(',')\n .map((o) => o.trim().toLowerCase())\n .filter(Boolean);\n return allowed.includes(parsed.origin.toLowerCase());\n }\n\n return false;\n } catch {\n // Unparseable URL — block it\n return false;\n }\n }\n\n /**\n * Parses the raw SVG text, strips dangerous content (script elements,\n * foreignObject, on* event-handler attributes, javascript:/data: URIs,\n * and style attributes that could carry CSS injection payloads), and\n * returns the outer SVG markup safe for rendering via `unsafeHTML`.\n *\n * Additionally injects `focusable=\"false\"` on the root SVG element to\n * prevent IE11/old-Edge from making the SVG keyboard-focusable, and strips\n * any ARIA attributes from the inner SVG to prevent conflicts with the\n * wrapper's own ARIA semantics.\n */\n /** @internal */\n private _sanitizeSvg(raw: string): string {\n const parser = new DOMParser();\n const doc = parser.parseFromString(raw, 'image/svg+xml');\n\n const parseError = doc.querySelector('parsererror');\n if (parseError) {\n return '';\n }\n\n const svgEl = doc.querySelector('svg');\n if (!svgEl) {\n return '';\n }\n\n // Remove dangerous embedded elements:\n // - script: arbitrary code execution\n // - foreignObject: can embed arbitrary HTML including scripts\n // - style: CSS injection (url() payloads, expression(), external references)\n // - animate, animateTransform, animateMotion, set: SMIL animation elements\n // can trigger event handlers and modify attributes to bypass sanitization\n const dangerousElements = [\n 'script',\n 'foreignObject',\n 'style',\n 'animate',\n 'animateTransform',\n 'animateMotion',\n 'set',\n ];\n svgEl.querySelectorAll(dangerousElements.join(', ')).forEach((s) => {\n s.remove();\n });\n\n // URL-bearing attributes that can carry javascript:/data: payloads.\n const urlAttrs = new Set(['href', 'xlink:href', 'src', 'action', 'formaction']);\n\n // ARIA attributes that may conflict with the wrapper element's own semantics.\n // The wrapper <span part=\"svg\"> owns role/aria-label/aria-hidden — the inner\n // SVG must not duplicate or contradict these.\n const ariaAttrs = new Set(['role', 'aria-label', 'aria-labelledby', 'aria-hidden']);\n\n // Sanitize every element including the root svg.\n const allElements: Element[] = [svgEl, ...Array.from(svgEl.querySelectorAll('*'))];\n allElements.forEach((el) => {\n const attrs = Array.from(el.attributes);\n attrs.forEach((attr) => {\n const attrName = attr.name.toLowerCase();\n // Strip event-handler attributes.\n if (attrName.startsWith('on')) {\n el.removeAttribute(attr.name);\n return;\n }\n // Strip style attributes — CSS can carry injection payloads via\n // url(javascript:...), expression(), or external filter/clip-path references.\n if (attrName === 'style') {\n el.removeAttribute(attr.name);\n return;\n }\n // Strip javascript: and data: URIs from URL-bearing attributes.\n if (urlAttrs.has(attrName)) {\n const val = attr.value.replace(/\\s/g, '').toLowerCase();\n if (val.startsWith('javascript:') || val.startsWith('data:')) {\n el.removeAttribute(attr.name);\n }\n }\n });\n });\n\n // Strip ARIA attributes from the root SVG only — they conflict with the\n // wrapper element's ARIA. Child elements' ARIA is left intact.\n ariaAttrs.forEach((a) => svgEl.removeAttribute(a));\n\n // Inject focusable=\"false\" so IE11/old-Edge do not tab into the SVG.\n svgEl.setAttribute('focusable', 'false');\n\n return svgEl.outerHTML;\n }\n\n // ─── Render Helpers ───\n\n /**\n * Returns the href used in the `<use>` element for sprite mode.\n * If `name` already begins with `#` it is treated as an inline reference.\n */\n /** @internal */\n private _spriteHref(): string {\n const n = this.name;\n if (n.startsWith('#')) {\n return n;\n }\n const base = this.spriteUrl ?? '';\n return base ? `${base}#${n}` : `#${n}`;\n }\n\n /** @internal */\n private _renderSprite() {\n const isDecorative = !this.label.trim();\n\n return html`\n <svg\n part=\"svg\"\n class=\"icon__svg\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n role=${isDecorative ? nothing : 'img'}\n aria-label=${isDecorative ? nothing : this.label}\n aria-hidden=${isDecorative ? 'true' : nothing}\n focusable=\"false\"\n >\n ${isDecorative ? nothing : html`<title>${this.label}</title>`}\n <use href=${this._spriteHref()}></use>\n </svg>\n `;\n }\n\n /** @internal */\n private _renderInline() {\n if (!this._inlineSvg) {\n return nothing;\n }\n\n const isDecorative = !this.label.trim();\n\n // The fetched SVG is rendered inside a wrapper span that carries the\n // csspart and ARIA semantics. The inner SVG from unsafeHTML fills the\n // container via the `.icon__inline svg` CSS rule. ARIA attributes and\n // focusable=\"false\" are injected into the inner SVG by _sanitizeSvg.\n return html`\n <span\n part=\"svg\"\n class=\"icon__inline\"\n role=${isDecorative ? nothing : 'img'}\n aria-label=${isDecorative ? nothing : this.label}\n aria-hidden=${isDecorative ? 'true' : nothing}\n >\n ${unsafeHTML(this._inlineSvg)}\n </span>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n // Inline fetch mode takes precedence when src is a non-empty string.\n if (typeof this.src === 'string' && this.src.trim().length > 0) {\n return this._renderInline();\n }\n\n // Sprite mode: requires at least a name.\n if (this.name) {\n return this._renderSprite();\n }\n\n return nothing;\n }\n}\n\n/**\n * Module-level SVG fetch cache. Shared across all `hx-icon` instances so that\n * multiple icons sharing the same `src` URL issue only one network request.\n * The cache stores in-flight `Promise<string>` values — resolved entries remain\n * cached for the lifetime of the page to prevent redundant re-fetches.\n */\nconst _svgCache = new Map<string, Promise<string>>();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-icon': HelixIcon;\n }\n}\n"],"names":["helixIconStyles","css","HelixIcon","HelixElement","changed","url","seq","pending","_svgCache","response","text","sanitized","parsed","o","raw","doc","svgEl","dangerousElements","s","urlAttrs","ariaAttrs","el","attr","attrName","val","a","n","base","isDecorative","html","nothing","unsafeHTML","forcedColorsSurface","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-link-CMnZRUtQ.js","sources":["../../src/components/hx-link/hx-link.styles.ts","../../src/components/hx-link/hx-link.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixLinkStyles = css`\n :host {\n display: inline;\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n /* --- Base Link --- */\n\n .link {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n color: var(--hx-link-color, var(--hx-color-primary-600, #0f7078));\n font-family: var(--hx-link-font-family, var(--hx-font-family-sans, inherit));\n font-size: inherit;\n line-height: inherit;\n text-decoration: var(--hx-link-text-decoration, underline);\n text-underline-offset: var(--hx-link-underline-offset, 2px);\n cursor: pointer;\n outline: 0;\n transition:\n color var(--hx-transition-fast, 150ms ease),\n text-decoration-color var(--hx-transition-fast, 150ms ease);\n }\n\n .link:hover {\n color: var(--hx-link-color-hover, var(--hx-color-primary-700, #0f6363));\n text-decoration: var(--hx-link-text-decoration-hover, underline);\n }\n\n .link:active {\n color: var(--hx-link-color-active, var(--hx-color-primary-800, #07494a));\n }\n\n .link:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-link-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n }\n\n /* --- Variant: subtle --- */\n\n .link--subtle {\n color: var(--hx-link-color-subtle, var(--hx-color-text-secondary, #313e4b));\n text-decoration: none;\n }\n\n .link--subtle:hover {\n color: var(--hx-link-color-hover, var(--hx-color-primary-700, #0f6363));\n text-decoration: underline;\n }\n\n /* --- Variant: danger --- */\n\n .link--danger {\n color: var(--hx-link-color-danger, var(--hx-color-error-text, #c92a2a));\n }\n\n .link--danger:hover {\n color: var(--hx-link-color-danger-hover, var(--hx-color-error-700, #a21312));\n }\n\n /* --- Disabled --- */\n\n .link--disabled {\n color: var(--hx-link-color-disabled, var(--hx-color-text-disabled, #8e9c98));\n text-decoration: none;\n cursor: not-allowed;\n }\n\n /* --- External link icon --- */\n\n .link__external-icon {\n display: inline-flex;\n width: 0.75em;\n height: 0.75em;\n flex-shrink: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .link {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .link {\n forced-color-adjust: none;\n color: LinkText;\n }\n\n .link:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .link--disabled {\n color: GrayText;\n }\n }\n\n /* --- Visually hidden (sr-only) --- */\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n`;\n","import { html, nothing, svg } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HelixElement } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { helixLinkStyles } from './hx-link.styles.js';\nimport { forcedColorsLink } from '../../styles/forced-colors.js';\n\n/**\n * Variant options for the link component.\n */\nexport type LinkVariant = 'default' | 'subtle' | 'danger';\n\n/**\n * A semantic hyperlink component with accessibility-first design.\n * Renders a native `<a>` element for enabled state and a `<span>` for\n * disabled state with full keyboard and screen reader support.\n *\n * @summary Accessible hyperlink with external-link detection, disabled state,\n * and download support.\n *\n * @tag hx-link\n *\n * @slot - Default slot for link label text or content.\n *\n * @fires {CustomEvent<{originalEvent: MouseEvent}>} hx-click - Dispatched when\n * the link is clicked and is not disabled.\n *\n * @csspart link - The inner anchor or span element.\n * @csspart external-icon - The external link icon SVG (when target=\"_blank\").\n *\n * @cssprop [--hx-link-color=var(--hx-color-primary-500)] - Default link color.\n * @cssprop [--hx-link-color-hover=var(--hx-color-primary-700)] - Hover color.\n * @cssprop [--hx-link-color-active=var(--hx-color-primary-800)] - Active color.\n * @cssprop [--hx-link-color-disabled=var(--hx-color-neutral-400)] - Disabled color.\n * @cssprop [--hx-link-color-subtle=var(--hx-color-neutral-600)] - Subtle variant color.\n * @cssprop [--hx-link-color-danger=var(--hx-color-error-text)] - Danger variant color.\n * @cssprop [--hx-link-color-danger-hover=var(--hx-color-error-700)] - Danger variant hover color.\n * @cssprop [--hx-link-font-family=var(--hx-font-family-sans)] - Link font family.\n * @cssprop [--hx-link-text-decoration=underline] - Link text decoration.\n * @cssprop [--hx-link-text-decoration-hover=underline] - Hover text decoration.\n * @cssprop [--hx-link-underline-offset=2px] - Text underline offset.\n * @cssprop [--hx-link-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n *\n * @note The `:visited` pseudo-class does not work inside Shadow DOM due to\n * browser privacy restrictions. This is a known platform limitation.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-color-primary-700] - Color.\n * @cssprop [--hx-color-primary-800] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-color-neutral-600] - Color.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-color-error-700] - Color.\n * @cssprop [--hx-color-neutral-400] - Color.\n */\n@customElement('hx-link')\nexport class HelixLink extends mixinDelegatesAria(HelixElement) {\n static override styles = [helixLinkStyles, forcedColorsLink];\n\n /**\n * The URL the link points to.\n * @attr href\n */\n @property({ type: String })\n href: string | undefined = undefined;\n\n /**\n * Where to display the linked URL (_self, _blank, etc.).\n * When set to \"_blank\", automatically adds rel=\"noopener noreferrer\"\n * and shows an external-link indicator.\n * @attr target\n */\n @property({ type: String })\n target: string | undefined = undefined;\n\n /**\n * Visual style variant of the link.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'subtle' | 'danger' = 'default';\n\n /**\n * Whether the link is disabled. Renders a span instead of an anchor.\n * The disabled span is keyboard-focusable (tabindex=\"0\") and announces\n * as a disabled link to screen readers.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Prompts the user to download the linked URL. When set to a string,\n * the value is used as the suggested filename.\n * @attr download\n */\n @property({ type: String })\n download: string | undefined = undefined;\n\n /**\n * Relationship between the current document and the linked URL.\n * Automatically set to \"noopener noreferrer\" when target=\"_blank\".\n * @attr rel\n */\n @property({ type: String })\n rel: string | undefined = undefined;\n\n /**\n * Localised announcement text appended (visually hidden) to the link's\n * accessible name when `target=\"_blank\"`. Defaults to English. Override\n * for i18n contexts so AT users hear the new-tab notice in their locale.\n * @attr external-label\n */\n @property({ type: String, attribute: 'external-label' })\n externalLabel: string = '(opens in new tab)';\n\n // --- Event Handling ---\n\n /** @internal Blocks Enter and Space activation on disabled span. */\n private _handleDisabledKeydown(e: KeyboardEvent): void {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n }\n }\n\n /** @internal */\n private _handleClick(e: MouseEvent): void {\n if (this.disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent<{ originalEvent: MouseEvent }>('hx-click', {\n bubbles: true,\n composed: true,\n detail: { originalEvent: e },\n }),\n );\n }\n\n // --- Render Helpers ---\n\n /** @internal */\n private _computeRel(): string | undefined {\n if (this.rel) return this.rel;\n if (this.target === '_blank') return 'noopener noreferrer';\n return undefined;\n }\n\n /** @internal */\n private _renderExternalIcon() {\n if (this.target !== '_blank') return nothing;\n\n return html`\n <svg\n class=\"link__external-icon\"\n part=\"external-icon\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n ${svg`<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" /><polyline points=\"15 3 21 3 21 9\" /><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />`}\n </svg>\n <span class=\"sr-only\">${this.externalLabel}</span>\n `;\n }\n\n // --- Render ---\n\n override render() {\n const classes = {\n link: true,\n [`link--${this.variant}`]: this.variant !== 'default',\n 'link--disabled': this.disabled,\n };\n\n // mixinDelegatesAria forwarding: consumer-set aria-* land in\n // data-aria-* on the host. Project them onto the inner role-bearing\n // element (the <a> or the <span role=\"link\">) so AT walks them\n // correctly without double-announcement on the host.\n const projectedLabel = this.getAttribute('data-aria-label');\n const projectedLabelledBy = this.getAttribute('data-aria-labelledby');\n const projectedDescribedBy = this.getAttribute('data-aria-describedby');\n const projectedCurrent = this.getAttribute('data-aria-current');\n\n if (this.disabled) {\n return html`\n <span\n part=\"link\"\n class=${classMap(classes)}\n role=\"link\"\n aria-disabled=\"true\"\n aria-label=${ifDefined(projectedLabel ?? undefined)}\n aria-labelledby=${ifDefined(projectedLabelledBy ?? undefined)}\n aria-describedby=${ifDefined(projectedDescribedBy ?? undefined)}\n aria-current=${ifDefined(projectedCurrent ?? undefined)}\n tabindex=\"0\"\n @click=${this._handleClick}\n @keydown=${this._handleDisabledKeydown}\n >\n <slot></slot>\n </span>\n `;\n }\n\n return html`\n <a\n part=\"link\"\n class=${classMap(classes)}\n href=${ifDefined(this.href)}\n target=${ifDefined(this.target)}\n rel=${ifDefined(this._computeRel())}\n download=${ifDefined(this.download)}\n aria-label=${ifDefined(projectedLabel ?? undefined)}\n aria-labelledby=${ifDefined(projectedLabelledBy ?? undefined)}\n aria-describedby=${ifDefined(projectedDescribedBy ?? undefined)}\n aria-current=${ifDefined(projectedCurrent ?? undefined)}\n @click=${this._handleClick}\n >\n <slot></slot>\n ${this._renderExternalIcon()}\n </a>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-link': HelixLink;\n }\n}\n"],"names":["helixLinkStyles","css","HelixLink","mixinDelegatesAria","HelixElement","nothing","html","svg","classes","projectedLabel","projectedLabelledBy","projectedDescribedBy","projectedCurrent","classMap","ifDefined","forcedColorsLink","__decorateClass","property","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-menu-divider-A6Guuzi_.js","sources":["../../src/components/hx-menu/hx-menu.styles.ts","../../src/components/hx-menu/hx-menu.ts","../../src/components/hx-menu/hx-menu-item.styles.ts","../../src/components/hx-menu/hx-menu-item.ts","../../src/components/hx-menu/hx-menu-divider.styles.ts","../../src/components/hx-menu/hx-menu-divider.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixMenuStyles = css`\n :host {\n display: block;\n }\n\n .menu {\n display: flex;\n flex-direction: column;\n padding: var(--hx-space-1, 0.25rem);\n background: var(--hx-menu-bg, var(--hx-color-surface-default, #ffffff));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-menu-border-color, var(--hx-color-border-default, #d6dbd5));\n border-radius: var(--hx-menu-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-menu-shadow,\n var(--hx-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))\n );\n min-width: var(--hx-menu-min-width, 10rem);\n max-height: var(--hx-menu-max-height, 20rem);\n overflow-y: auto;\n outline: none;\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu {\n background-color: Canvas;\n border: 2px solid CanvasText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuStyles } from './hx-menu.styles.js';\nimport type { HelixMenuItem } from './hx-menu-item.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport {\n installAriaIdrefMirror,\n resolveIdrefTokens,\n supportsIdrefElementReferences,\n type AriaIdrefMirrorHandle,\n} from '../../utils/aria-idref.js';\nimport { flattenAccName } from '../../utils/aria-flatten.js';\nimport { getMenuItemTypeaheadLabel } from '../../utils/menu-label.js';\nimport {\n findClosestMenuAncestor as findClosestMenuAncestorElement,\n findOwningMenuItem as findOwningMenuItemElement,\n} from '../../utils/menu-tree.js';\n\n/**\n * Typed wrapper around the shared `findClosestMenuAncestor` walker that\n * narrows the result to `HelixMenu` for in-file consumers. Codex push-gate\n * round-4 (logic) + round-9 (extraction).\n * @internal\n */\nfunction findClosestMenuAncestor(start: Element): HelixMenu | null {\n const found = findClosestMenuAncestorElement(start);\n return found instanceof Element && found.tagName.toLowerCase() === 'hx-menu'\n ? (found as HelixMenu)\n : null;\n}\n\n/**\n * Typed wrapper around the shared `findOwningMenuItem` walker. Codex\n * push-gate round-4 (logic) + round-9 (extraction).\n * @internal\n */\nfunction findOwningMenuItem(menu: HelixMenu): HelixMenuItem | null {\n const found = findOwningMenuItemElement(menu);\n return found instanceof Element && found.tagName.toLowerCase() === 'hx-menu-item'\n ? (found as HelixMenuItem)\n : null;\n}\n\n/**\n * A menu container that manages keyboard navigation over a list of menu items.\n * Use with `hx-menu-item` and `hx-menu-divider`.\n *\n * Group 5b host-canonical: `role=\"menu\"` lives on the **host** via\n * `_internals.role`. The host carries the announced surface so AT walks\n * `<hx-menu>` (role=menu) → slotted `<hx-menu-item>` (role=menuitem on host)\n * directly without two layers of indirection. Consumer-supplied\n * `aria-label` / `aria-labelledby` on the host are resolved via the shared\n * IDREF mirror; cross-shadow naming uses `ariaLabelledByElements` (modern)\n * with a flattened-string fallback (legacy).\n *\n * Submenu coordination: when an `hx-menu-item` emits `hx-item-submenu-open`\n * or `hx-item-submenu-close`, the parent menu auto-handles the toggle by\n * calling `setSubmenuOpen()` on the item — UNLESS the consumer has called\n * `event.preventDefault()` on the bubbled event, signaling that they own the\n * submenu lifecycle. This matches APG-mandated behaviour while leaving an\n * opt-out for advanced consumers.\n *\n * @summary Context/action menu with keyboard-navigable items.\n *\n * @tag hx-menu\n *\n * @slot - Default slot for hx-menu-item and hx-menu-divider elements.\n *\n * @fires {CustomEvent<{item: HelixMenuItem, value: string}>} hx-select - Dispatched when an item is selected.\n * @fires {CustomEvent<void>} hx-close - Dispatched when Escape is pressed.\n *\n * @csspart base - The root menu element.\n *\n * @cssprop [--hx-menu-bg=var(--hx-color-neutral-0)] - Menu background color.\n * @cssprop [--hx-menu-border-color=var(--hx-color-neutral-200)] - Menu border color.\n * @cssprop [--hx-menu-border-radius=var(--hx-border-radius-md)] - Menu border radius.\n * @cssprop [--hx-menu-shadow] - Menu box shadow.\n * @cssprop [--hx-menu-min-width=10rem] - Minimum menu width.\n * @cssprop [--hx-menu-max-height=20rem] - Maximum menu height before vertical scroll is activated.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-shadow-md] - Box shadow.\n */\n@customElement('hx-menu')\nexport class HelixMenu extends HelixElement {\n static override styles = [helixMenuStyles, forcedColorsInteractive];\n\n /**\n * Accessible label for the menu. Used as a fallback when no consumer-supplied\n * `aria-label` / `aria-labelledby` is present on the host. On the modern\n * host-canonical path this projects onto `internals.ariaLabel`; on the\n * legacy fallback path it appears as `aria-label` on the inner div.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Index of the currently focused menu item within the list of enabled items.\n * @internal\n */\n private _focusedIndex = -1;\n\n /**\n * Accumulated character buffer for typeahead search within menu items.\n * @internal\n */\n private _typeaheadBuffer = '';\n\n /**\n * Timer handle that clears the typeahead buffer after a period of inactivity.\n * @internal\n */\n private _typeaheadTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Host-canonical ARIA bookkeeping ───\n\n /**\n * Test seam (codex push-gate round-2 finding 1): when set to `true` or\n * `false`, overrides the platform `supportsIdrefElementReferences` probe\n * before `connectedCallback` seeds `_supportsIdrefRefs`. Mirrors the\n * hx-select / hx-menu-item seam — required so tests can deterministically\n * exercise the legacy fallback render branch (where the inner\n * `div[role=\"menu\"]` is the announced surface and must mirror the\n * resolved accessible name).\n *\n * Production code MUST NOT touch this field. It is `static` so the test\n * stub cleanup is global and obvious.\n * @internal\n */\n static __testSupportsIdrefRefsOverride: boolean | null = null;\n\n /** @internal */\n private _supportsIdrefRefs = true;\n\n /** @internal */\n private _ariaMirror: AriaIdrefMirrorHandle | null = null;\n\n /**\n * Resolved accessible name for the menu — the single source of truth that\n * both `_syncHostAriaSemantics()` (modern path: writes to\n * `internals.ariaLabel`) and the fallback `render()` branch (legacy path:\n * writes to inner `div[role=\"menu\"]` `aria-label`) read. Recomputed by\n * `_syncHostAriaSemantics()` whenever host aria-* or `label` changes via\n * the shared IDREF mirror. AccName 1.2 §4.3.1 precedence: consumer host\n * `aria-labelledby` (flattened) > consumer host `aria-label` > `label`\n * property > literal \"Menu\".\n * @internal\n */\n private _resolvedAccessibleName = '';\n\n /**\n * Return the menu's enabled, top-level `hx-menu-item` children.\n *\n * Codex push-gate round-6 finding 3: `querySelectorAll('hx-menu-item')`\n * walks the entire descendant tree, which on a parent menuitem\n * includes the slotted nested `<hx-menu>` and ITS items. Treating\n * those as top-level options corrupts roving tabindex, ArrowUp/Down\n * navigation, and typeahead matching (typing the first letter of a\n * grandchild item lands focus there instead of on the next sibling).\n * Restrict to direct children of `this` so each menu owns only its\n * own items.\n *\n * @internal\n */\n private _getItems(): HelixMenuItem[] {\n return Array.from(this.children).filter(\n (el): el is HelixMenuItem =>\n el.tagName.toLowerCase() === 'hx-menu-item' &&\n !(el as HelixMenuItem).disabled &&\n !(el as HelixMenuItem).loading,\n );\n }\n\n /**\n * Synchronize roving tabindex across all enabled items.\n * Only the active item (or first item if none active) gets tabindex=0.\n */\n /** @internal */\n private _syncRovingTabIndex(): void {\n const items = this._getItems();\n const activeIndex = this._focusedIndex >= 0 ? this._focusedIndex : 0;\n items.forEach((item, i) => {\n item.setRovingTabIndex(i === activeIndex ? 0 : -1);\n });\n }\n\n /** Focus the first menu item. */\n focusFirst(): void {\n const items = this._getItems();\n const first = items[0];\n if (first !== undefined) {\n this._focusedIndex = 0;\n this._syncRovingTabIndex();\n first.focus();\n }\n }\n\n /** Focus the last menu item. */\n focusLast(): void {\n const items = this._getItems();\n const last = items[items.length - 1];\n if (last !== undefined) {\n this._focusedIndex = items.length - 1;\n this._syncRovingTabIndex();\n last.focus();\n }\n }\n\n /** @internal */\n private _focusItem(index: number): void {\n const items = this._getItems();\n if (items.length === 0) return;\n this._focusedIndex = Math.max(0, Math.min(index, items.length - 1));\n this._syncRovingTabIndex();\n const target = items[this._focusedIndex];\n if (target !== undefined) target.focus();\n }\n\n /** @internal */\n private _updateFocusedIndex(): void {\n const items = this._getItems();\n const active = this.shadowRoot?.activeElement ?? document.activeElement;\n // Find the active item by checking if any item's shadow root contains the active element\n const idx = items.findIndex((item) => item.matches(':focus-within') || item === active);\n if (idx !== -1) this._focusedIndex = idx;\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n this._updateFocusedIndex();\n const items = this._getItems();\n if (items.length === 0) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._focusItem(this._focusedIndex + 1 < items.length ? this._focusedIndex + 1 : 0);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._focusItem(this._focusedIndex > 0 ? this._focusedIndex - 1 : items.length - 1);\n break;\n case 'Home':\n e.preventDefault();\n this._focusItem(0);\n break;\n case 'End':\n e.preventDefault();\n this._focusItem(items.length - 1);\n break;\n case 'Escape':\n e.preventDefault();\n this.dispatchEvent(new CustomEvent<void>('hx-close', { bubbles: true, composed: true }));\n break;\n default:\n if (e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {\n this._handleTypeahead(e.key, items);\n }\n break;\n }\n }\n\n /** @internal */\n private _handleTypeahead(char: string, items: HelixMenuItem[]): void {\n if (this._typeaheadTimer !== null) {\n clearTimeout(this._typeaheadTimer);\n }\n this._typeaheadBuffer += char.toLowerCase();\n this._typeaheadTimer = setTimeout(() => {\n this._typeaheadBuffer = '';\n this._typeaheadTimer = null;\n }, 500);\n\n const match = items.findIndex((item) => {\n if (item.disabled || item.hasAttribute('disabled')) return false;\n const text = this._getTypeaheadLabel(item).toLowerCase();\n return text.startsWith(this._typeaheadBuffer);\n });\n\n if (match !== -1) {\n this._focusItem(match);\n }\n }\n\n /**\n * Read the typeahead label for an item — delegates to the shared\n * `getMenuItemTypeaheadLabel` util so all four menu-bearing components\n * (`hx-menu`, `hx-dropdown`, `hx-overflow-menu`, `hx-split-button`)\n * share one submenu-aware extractor. Codex push-gate round-7 finding 3\n * extracted this helper from its original home here in `hx-menu.ts`.\n *\n * @internal\n */\n private _getTypeaheadLabel(item: HelixMenuItem): string {\n return getMenuItemTypeaheadLabel(item);\n }\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target;\n if (!(slot instanceof HTMLSlotElement)) return;\n const validTags = new Set(['hx-menu-item', 'hx-menu-divider']);\n const invalid = slot\n .assignedElements()\n .filter((el) => !validTags.has(el.tagName.toLowerCase()));\n if (invalid.length > 0) {\n devWarn(\n 'hx-menu',\n `Default slot expects <hx-menu-item> or <hx-menu-divider> elements. Found unexpected: ${invalid.map((el) => `<${el.tagName.toLowerCase()}>`).join(', ')}`,\n );\n }\n // Initialize roving tabindex when items are slotted\n this._syncRovingTabIndex();\n }\n\n /** @internal */\n private _handleItemSelect(e: Event): void {\n if (!(e instanceof CustomEvent)) return;\n const detail = (e as CustomEvent<{ item: HelixMenuItem; value: string }>).detail;\n const items = this._getItems();\n this._focusedIndex = items.indexOf(detail.item);\n\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem; value: string }>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { item: detail.item, value: detail.value },\n }),\n );\n }\n\n /**\n * Auto-handle submenu open/close events emitted by child `hx-menu-item`\n * children. APG-mandated behaviour: ArrowRight on a parent item opens the\n * nested submenu and focuses its first item; ArrowLeft closes the submenu\n * and returns focus to the parent item. Consumers that own submenu\n * lifecycle themselves can `event.preventDefault()` to opt out.\n * @internal\n */\n private _handleSubmenuOpen = (e: Event): void => {\n if (!(e instanceof CustomEvent)) return;\n const detail = (e as CustomEvent<{ item: HelixMenuItem }>).detail;\n const item = detail?.item;\n if (!item) return;\n // Defer to a microtask so consumer listeners (which may be registered\n // AFTER the menu's auto-handler in event order) get a chance to call\n // `event.preventDefault()` and opt out of default submenu lifecycle\n // handling. APG-mandated default: open the nested submenu and focus\n // its first item; consumers that own this themselves cancel the\n // default by calling preventDefault on the event.\n queueMicrotask(() => {\n if (e.defaultPrevented) return;\n item.setSubmenuOpen(true);\n void item.updateComplete\n .then(() => {\n const submenuSlot =\n item.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"submenu\"]');\n const nested = submenuSlot\n ?.assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'hx-menu') as HelixMenu | undefined;\n nested?.focusFirst();\n })\n .catch(() => undefined);\n });\n };\n\n /** @internal */\n private _handleSubmenuClose = (e: Event): void => {\n if (!(e instanceof CustomEvent)) return;\n const detail = (e as CustomEvent<{ item: HelixMenuItem }>).detail;\n const item = detail?.item;\n if (!item) return;\n // The bubbled event reaches every enclosing `hx-menu` — outer menus\n // would otherwise re-handle a Child's ArrowLeft and stomp on the inner\n // menu's close. Only act when THIS menu is the closest enclosing menu\n // of the dispatching item; outer menus defer to whichever inner menu\n // is responsible. Codex push-gate round-4 P1: previously the outer\n // menu handled the event and called `child.setSubmenuOpen(false)` —\n // a no-op since the child has no submenu — leaving the parent's\n // submenu open and focus stuck on the child.\n const closestMenu = findClosestMenuAncestor(item);\n if (closestMenu !== this) return;\n // Determine which menu-item owns the submenu we should close. When\n // THIS menu is itself slotted into a parent menu-item's `slot=\"submenu\"`\n // (i.e. THIS is a nested submenu), the parent item is the owner —\n // ArrowLeft from any descendant closes the parent's submenu and\n // returns focus to the parent. When THIS menu has no parent menu-item\n // (top-level menu), the dispatching item itself is the only sensible\n // target: a no-op for plain items, a self-close for items with their\n // own submenu open.\n const ownerItem = findOwningMenuItem(this) ?? item;\n queueMicrotask(() => {\n if (e.defaultPrevented) return;\n ownerItem.setSubmenuOpen(false);\n ownerItem.focus();\n });\n };\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Honour the static test override so synthetic environments choose the\n // path BEFORE connect runs — the fallback render branch needs to be\n // selected at first paint so the inner `[role=\"menu\"]` carries the\n // resolved accessible name without a mid-life flag flip.\n const ctor = this.constructor as typeof HelixMenu;\n this._supportsIdrefRefs =\n ctor.__testSupportsIdrefRefsOverride !== null\n ? ctor.__testSupportsIdrefRefsOverride\n : supportsIdrefElementReferences(this._internals);\n // Keydown is bound on the HOST so events from focused host-canonical\n // menu items (which keep keydown out of this menu's shadow DOM)\n // still reach the navigation handler. hx-item-select bubbles\n // through the composed path and is caught here as well.\n this.addEventListener('keydown', this._handleHostKeyDown);\n this.addEventListener('hx-item-select', this._handleItemSelectHost);\n this.addEventListener('hx-item-submenu-open', this._handleSubmenuOpen);\n this.addEventListener('hx-item-submenu-close', this._handleSubmenuClose);\n // Seed host-canonical semantics so role/label appear before first paint.\n this._syncHostAriaSemantics();\n this._ariaMirror = installAriaIdrefMirror(this, () => {\n this._syncHostAriaSemantics();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._typeaheadTimer !== null) {\n clearTimeout(this._typeaheadTimer);\n this._typeaheadTimer = null;\n }\n this.removeEventListener('keydown', this._handleHostKeyDown);\n this.removeEventListener('hx-item-select', this._handleItemSelectHost);\n this.removeEventListener('hx-item-submenu-open', this._handleSubmenuOpen);\n this.removeEventListener('hx-item-submenu-close', this._handleSubmenuClose);\n this._ariaMirror?.disconnect();\n this._ariaMirror = null;\n }\n\n /**\n * Codex push-gate round-7 finding 1: keydown bound on the HOST receives\n * events that bubble out of nested submenus. When a child submenu is\n * open and focus lives inside it, ArrowUp/Down/Home/End/Escape on the\n * inner item bubbles to EVERY enclosing `hx-menu`. Without this guard\n * the outer menu would run `_focusItem(...)` against its OWN top-level\n * items and steal focus back out of the child submenu, and Escape would\n * dispatch one `hx-close` per enclosing menu. Mirrors the\n * `findClosestMenuAncestor` pattern already used by the submenu\n * open/close handlers.\n * @internal\n */\n private _handleHostKeyDown = (e: KeyboardEvent): void => {\n const target = e.target;\n if (target instanceof Element && findClosestMenuAncestor(target) !== this) {\n return;\n }\n this._handleKeyDown(e);\n };\n\n /**\n * Codex push-gate round-7 finding 2: `hx-item-select` bubbles composed\n * through every enclosing `hx-menu`. The outer menu would otherwise\n * (a) corrupt `_focusedIndex` to `-1` because the bubbled item is not\n * a member of the outer menu's items, and (b) re-emit a duplicate\n * `hx-select`. Only act when THIS menu is the closest enclosing menu\n * of the dispatching item.\n * @internal\n */\n private _handleItemSelectHost = (e: Event): void => {\n if (!(e instanceof CustomEvent)) return;\n const detail = (e as CustomEvent<{ item: HelixMenuItem; value: string }>).detail;\n const item = detail?.item;\n if (item && findClosestMenuAncestor(item) !== this) {\n return;\n }\n this._handleItemSelect(e);\n };\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('label')) {\n this._syncHostAriaSemantics();\n }\n }\n\n override firstUpdated(): void {\n const hasEffectiveLabel =\n this.hasAttribute('aria-label') ||\n this.hasAttribute('aria-labelledby') ||\n Boolean(this.label);\n if (!hasEffectiveLabel) {\n devWarn(\n 'hx-menu',\n 'No accessible label provided. Set the `label` attribute, or supply `aria-label` / `aria-labelledby` on hx-menu so screen readers can identify this menu (WCAG 4.1.2).',\n );\n }\n }\n\n /**\n * Mirror menu semantics onto the host via ElementInternals so consumer-\n * supplied `aria-label`, `aria-labelledby`, and the `label` property all\n * reach the announced control. Falls back to a flattened-string label on\n * engines that do not implement `ariaLabelledByElements`.\n * @internal\n */\n private _syncHostAriaSemantics(): void {\n const internals = this._internals;\n\n // Codex push-gate round-8 finding 1 (mirrors round-6 finding 2 in\n // hx-menu-item): on the legacy fallback path the inner\n // `<div role=\"menu\" aria-label=\"…\">` is the announced surface. If we\n // ALSO write `internals.role = 'menu'` (and ariaLabel) onto the host,\n // AT sees TWO menus for one logical surface — the duplicate-surface\n // problem host-canonical migration is meant to eliminate. Suppress\n // host role + label writes on the fallback path; the inner element\n // is the canonical announced surface there. Modern path keeps the\n // host as the canonical surface and clears the inner role.\n if (!this._supportsIdrefRefs) {\n internals.role = null;\n internals.ariaLabel = null;\n } else {\n internals.role = 'menu';\n }\n\n const hostAriaLabel = this.getAttribute('aria-label')?.trim() || '';\n const consumerLabelledBy = this.getAttribute('aria-labelledby');\n const labelEls = resolveIdrefTokens(this, consumerLabelledBy);\n const hasEffectiveLabelledBy = labelEls.length > 0;\n\n type InternalsWithRefs = ElementInternals & {\n ariaLabelledByElements: Element[] | null;\n };\n\n if (this._supportsIdrefRefs) {\n const refsInternals = internals as InternalsWithRefs;\n refsInternals.ariaLabelledByElements = hasEffectiveLabelledBy ? labelEls : null;\n }\n\n // AccName 1.2 §4.3.1 precedence: consumer aria-labelledby (resolved) >\n // consumer aria-label > `label` property > literal \"Menu\" (last-resort).\n // The resolved string is cached on `_resolvedAccessibleName` so the\n // fallback render branch (legacy path: AT reads inner div) can mirror\n // the same name without duplicating the precedence ladder.\n let resolved = '';\n if (hasEffectiveLabelledBy) {\n const flattened =\n labelEls\n .map((el) => flattenAccName(el))\n .filter(Boolean)\n .join(' ') ||\n hostAriaLabel ||\n this.label ||\n 'Menu';\n resolved = flattened;\n if (this._supportsIdrefRefs) {\n // Modern path: element refs win; clear ariaLabel so they aren't\n // shadowed by a stale string. Fallback branch reads\n // `_resolvedAccessibleName` for its inner-div mirror — host\n // ariaLabel is already cleared above on the fallback path.\n internals.ariaLabel = null;\n }\n } else if (hostAriaLabel) {\n resolved = hostAriaLabel;\n if (this._supportsIdrefRefs) {\n internals.ariaLabel = hostAriaLabel;\n }\n } else {\n resolved = this.label || 'Menu';\n if (this._supportsIdrefRefs) {\n internals.ariaLabel = resolved;\n }\n }\n\n // Codex push-gate round-2 finding 1: keep the resolved name available\n // for the legacy render branch. Request a re-render so the fallback\n // `<div role=\"menu\" aria-label=...>` picks up the new value when host\n // aria-* changes after first paint.\n if (this._resolvedAccessibleName !== resolved) {\n this._resolvedAccessibleName = resolved;\n if (!this._supportsIdrefRefs) {\n this.requestUpdate();\n }\n }\n }\n\n override render() {\n // Host-canonical Path A: `role=\"menu\"` and the resolved label live on\n // the host via `_internals`. The inner div is roleless on the modern\n // path so AT does not see a duplicated container role nested inside\n // the host. Legacy fallback keeps the inner role + aria-label so AT\n // without IDL element references still announces the menu.\n // Keydown + hx-item-select listeners are bound on the host in\n // connectedCallback() — keydown does not propagate INTO this menu's\n // shadow DOM, so events from focused host-canonical menu items\n // would never fire on inner-div bindings. hx-item-select bubbles\n // composed through the host either way; we listen on the host for\n // symmetry.\n if (this._supportsIdrefRefs) {\n return html`\n <div part=\"base\" class=\"menu\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n\n // Codex push-gate round-2 finding 1: AT on the fallback path announces\n // the inner div, so it MUST mirror the same accessible name resolved\n // by `_syncHostAriaSemantics()` (consumer host aria-label / aria-\n // labelledby flatten / `label` property). Fall back to `this.label`\n // if the mirror has not run yet (pre-connect render).\n const fallbackLabel = this._resolvedAccessibleName || this.label || nothing;\n return html`\n <div part=\"base\" class=\"menu\" role=\"menu\" aria-label=${fallbackLabel}>\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu': HelixMenu;\n }\n}\n","import { css } from 'lit';\n\nexport const helixMenuItemStyles = css`\n :host {\n display: block;\n /* Host carries the roving tabindex on the modern host-canonical path,\n so it becomes the focusable surface. Strip the default focus outline\n from the host so the inner .menu-item:focus-visible (and the host\n :focus-visible rule below) own the visual treatment. */\n outline: none;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* Host is the Tab stop on the modern path; mirror the inner focus-ring\n onto the host so keyboard focus is visible on whichever surface the\n UA paints. The inner-element rule below still applies on the legacy\n fallback path (where the inner div carries the role + tabindex). */\n :host(:focus-visible) .menu-item {\n background-color: var(--hx-menu-item-hover-bg, var(--hx-color-surface-sunken, #ebeee9));\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-menu-item-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-menu-item-focus-ring-offset, 0px);\n }\n\n .menu-item {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n min-height: var(--hx-touch-target-min, 44px);\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n cursor: pointer;\n color: var(--hx-menu-item-color, var(--hx-color-text-primary, #0d1825));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-family: var(--hx-menu-item-font-family, var(--hx-font-family-sans, sans-serif));\n line-height: var(--hx-line-height-tight, 1.25);\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n background: none;\n width: 100%;\n box-sizing: border-box;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n .menu-item:hover,\n .menu-item:focus-visible {\n background-color: var(--hx-menu-item-hover-bg, var(--hx-color-surface-sunken, #ebeee9));\n }\n\n .menu-item:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-menu-item-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-menu-item-focus-ring-offset, 0px);\n }\n\n .menu-item__prefix,\n .menu-item__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .menu-item__label {\n flex: 1 1 auto;\n }\n\n .menu-item__checked-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n width: 1em;\n opacity: 0;\n transition: opacity var(--hx-transition-fast, 150ms ease);\n }\n\n .menu-item--checked .menu-item__checked-icon {\n opacity: 1;\n }\n\n .menu-item__submenu-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n margin-inline-start: auto;\n }\n\n .menu-item__spinner {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n animation: hx-menu-spin var(--hx-duration-spinner, 750ms) linear infinite;\n }\n\n @keyframes hx-menu-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-item {\n transition: none;\n }\n\n .menu-item__checked-icon {\n transition: none;\n }\n\n .menu-item__spinner {\n animation: none;\n opacity: var(--hx-opacity-muted, 0.6);\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu-item {\n forced-color-adjust: none;\n color: CanvasText;\n background-color: Canvas;\n }\n\n .menu-item:hover,\n .menu-item:focus-visible {\n background-color: Highlight;\n color: HighlightText;\n }\n\n .menu-item:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: -2px;\n }\n\n /* Host-canonical focus parity in forced-colors mode. */\n :host(:focus-visible) .menu-item {\n background-color: Highlight;\n color: HighlightText;\n outline: 2px solid Highlight;\n outline-offset: -2px;\n }\n\n :host([disabled]) .menu-item {\n color: GrayText;\n opacity: 1;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuItemStyles } from './hx-menu-item.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport {\n installAriaIdrefMirror,\n resolveIdrefTokens,\n supportsIdrefElementReferences,\n type AriaIdrefMirrorHandle,\n} from '../../utils/aria-idref.js';\nimport { flattenAccName } from '../../utils/aria-flatten.js';\n\n/**\n * A single interactive item for use inside `hx-menu`. Supports normal, checkbox,\n * and radio types, loading state, prefix/suffix slots, and submenu nesting.\n *\n * Group 5b host-canonical: `role=\"menuitem\"` (or `menuitemcheckbox` /\n * `menuitemradio` based on `type`) lives on the **host** via\n * `_internals.role`. The roving tabindex is written to the host, so the host\n * is the focusable surface and lands directly under the parent `<hx-menu>`\n * (which carries `role=\"menu\"`) in the AT walked tree. The inner element is\n * presentational on the modern path — no role, no aria-* attributes — and\n * carries only click/keyboard event handlers. Keyboard activation\n * (Enter/Space) is owned by the host's `keydown` handler.\n *\n * Cross-shadow naming: consumer-supplied `aria-label` / `aria-labelledby` on\n * the host project to `internals.ariaLabel` / `internals.ariaLabelledByElements`\n * via the shared IDREF mirror. The slotted text content is used as the default\n * accessible name when no override is set (AT walks slotted children\n * automatically through the host's role).\n *\n * @summary Interactive item within an hx-menu.\n *\n * @tag hx-menu-item\n *\n * @slot - Default slot for the item label.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Shortcut text or icon rendered after the label.\n * @slot submenu - A nested hx-menu for submenu content.\n *\n * @fires {CustomEvent<{item: HelixMenuItem, value: string}>} hx-item-select - Dispatched when the item is activated via click, Enter, or Space.\n * @fires {CustomEvent<{item: HelixMenuItem}>} hx-item-submenu-open - Dispatched when ArrowRight is pressed on an item with a submenu.\n * @fires {CustomEvent<{item: HelixMenuItem}>} hx-item-submenu-close - Dispatched when ArrowLeft is pressed on an item, signaling the parent to close the submenu and return focus.\n *\n * @csspart base - The root item element.\n * @csspart prefix - Prefix slot wrapper.\n * @csspart label - Label slot wrapper.\n * @csspart suffix - Suffix slot wrapper.\n * @csspart submenu-icon - The chevron icon indicating a submenu.\n * @csspart checked-icon - The checkmark icon for checkbox-type items.\n *\n * @cssprop [--hx-menu-item-color=var(--hx-color-neutral-900)] - Item text color.\n * @cssprop [--hx-menu-item-hover-bg=var(--hx-color-neutral-100)] - Item hover/focus background.\n */\n@customElement('hx-menu-item')\nexport class HelixMenuItem extends HelixElement {\n static override styles = [helixMenuItemStyles, forcedColorsInteractive];\n\n /**\n * Test seam (codex push-gate round-1 finding 3 mirror of hx-select\n * pattern): when set to `true` or `false`, overrides the platform\n * `supportsIdrefElementReferences` probe before `connectedCallback`\n * seeds `_supportsIdrefRefs`. Tests that need to exercise the fallback\n * path must select it BEFORE the host connects so tabindex / role\n * placement matches a legacy engine for the entire lifecycle.\n *\n * Production code MUST NOT touch this field. It is `static` so the test\n * stub cleanup is global and obvious.\n * @internal\n */\n static __testSupportsIdrefRefsOverride: boolean | null = null;\n\n /**\n * @internal Managed by parent hx-menu for roving tabindex.\n * Only the active item in the menu has tabindex=0; all others have -1.\n */\n @state()\n private _rovingTabIndex = -1;\n\n /** @internal Set the roving tabindex value. Called by parent hx-menu. */\n setRovingTabIndex(value: number): void {\n this._rovingTabIndex = value;\n this._applyHostTabIndex();\n }\n\n /** Set whether the nested submenu is open. Called by the component managing submenu visibility. */\n setSubmenuOpen(open: boolean): void {\n this._submenuOpen = open;\n }\n\n /**\n * The value associated with this item, emitted in the hx-select event.\n * @attr value\n */\n @property({ type: String })\n value = '';\n\n /**\n * Whether the item is disabled. Prevents interaction and event dispatch.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the item is checked. Only meaningful when type=\"checkbox\".\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * The type of menu item. \"checkbox\" renders a checkmark and toggles checked state.\n * \"radio\" renders a checkmark and emits selection for radio-group behavior.\n * @attr type\n */\n @property({ type: String, reflect: true })\n type: 'normal' | 'checkbox' | 'radio' = 'normal';\n\n /**\n * Whether the item is in a loading state. Shows a spinner and prevents interaction.\n * @attr loading\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** @internal */\n @state()\n private _hasSubmenu = false;\n\n /** @internal Tracks whether the nested submenu is currently open. */\n @state()\n private _submenuOpen = false;\n\n /** @internal */\n @query('.menu-item') private _menuItemEl!: HTMLElement | null;\n\n // ─── Host-canonical ARIA bookkeeping ───\n\n /** @internal */\n private _supportsIdrefRefs = true;\n\n /** @internal */\n private _ariaMirror: AriaIdrefMirrorHandle | null = null;\n\n /**\n * Resolved accessible name for the menu item — read by both\n * `_syncHostAriaSemantics()` (modern path: host `internals.ariaLabel`)\n * and the fallback `render()` branch (legacy path: inner\n * `div[role=\"menuitem*\"]` `aria-label`). Empty string means \"no\n * override\" — slotted text content provides the implicit name through\n * the announced surface (host on modern; inner div on fallback). AccName\n * 1.2 §4.3.1 precedence: consumer host `aria-labelledby` (flattened) >\n * consumer host `aria-label` > implicit slotted text.\n * @internal\n */\n private _resolvedAccessibleName = '';\n\n /**\n * Focus the menu item. On the modern host-canonical path, focus lands on\n * the host (which carries the roving tabindex and announced role). On the\n * legacy fallback path, focus delegates to the inner element which still\n * carries the role.\n */\n override focus(options?: FocusOptions): void {\n if (this._supportsIdrefRefs) {\n // Host is the canonical Tab stop on the modern path.\n HTMLElement.prototype.focus.call(this, options);\n } else {\n this._menuItemEl?.focus(options);\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Honour the static test override so synthetic environments choose the\n // path BEFORE connect runs (mirrors hx-select's seam — codex push-gate\n // round-1 finding 3 needs deterministic fallback-path entry to assert\n // host.tabIndex stays out of the tab order).\n const ctor = this.constructor as typeof HelixMenuItem;\n this._supportsIdrefRefs =\n ctor.__testSupportsIdrefRefsOverride !== null\n ? ctor.__testSupportsIdrefRefsOverride\n : supportsIdrefElementReferences(this._internals);\n // WCAG 4.1.2: menuitem role is only valid inside a role=\"menu\" or role=\"menubar\" container.\n // Check the closest ancestor with a menu role.\n const menuHost = this.closest('hx-menu, hx-split-button, [role=\"menu\"], [role=\"menubar\"]');\n if (!menuHost) {\n devWarn(\n 'hx-menu-item',\n 'hx-menu-item must be used inside an hx-menu or an element with role=\"menu\". ' +\n 'An orphaned menuitem violates WCAG 1.3.1 (Info and Relationships).',\n );\n }\n // Keyboard handling lives on the HOST so the active surface (the host\n // on the modern path; either the host or the inner div in delegating\n // engines) receives keydown events. Activation (Enter/Space) and\n // submenu navigation (ArrowLeft/ArrowRight) are routed here; the\n // parent hx-menu owns ArrowUp/ArrowDown/Home/End/typeahead.\n this.addEventListener('keydown', this._handleKeyDown);\n this.addEventListener('click', this._handleClick);\n this._syncHostAriaSemantics();\n this._applyHostTabIndex();\n this._ariaMirror = installAriaIdrefMirror(this, () => {\n this._syncHostAriaSemantics();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeyDown);\n this.removeEventListener('click', this._handleClick);\n this._ariaMirror?.disconnect();\n this._ariaMirror = null;\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (\n changedProperties.has('disabled') ||\n changedProperties.has('checked') ||\n changedProperties.has('type') ||\n changedProperties.has('loading') ||\n (changedProperties as Map<PropertyKey, unknown>).has('_hasSubmenu') ||\n (changedProperties as Map<PropertyKey, unknown>).has('_submenuOpen')\n ) {\n this._syncHostAriaSemantics();\n }\n if (\n (changedProperties as Map<PropertyKey, unknown>).has('_rovingTabIndex') ||\n changedProperties.has('disabled')\n ) {\n this._applyHostTabIndex();\n }\n }\n\n /**\n * Apply the roving tabindex to the host (modern path) so the host is the\n * Tab stop. Disabled items are non-tabbable.\n *\n * Codex push-gate round-1 finding 3: on the fallback path\n * (`_supportsIdrefRefs === false`), the inner `.menu-item` element\n * carries `role=\"menuitem\"` and the roving tabindex via the template\n * (see `render()`'s legacy branch). If we ALSO assign a non-negative\n * tabindex to the host, the user gets two focusable surfaces per item —\n * Tab can land on the host even though the AT-announced role/aria-* live\n * on the inner element. The host MUST be removed from the tab order on\n * the fallback path; the inner element is the canonical Tab stop.\n * @internal\n */\n private _applyHostTabIndex(): void {\n if (!this._supportsIdrefRefs) {\n // Fallback path: inner `.menu-item` is the focusable surface. Keep\n // the host out of the sequential focus order entirely.\n this.tabIndex = -1;\n return;\n }\n if (this.disabled) {\n this.tabIndex = -1;\n } else {\n this.tabIndex = this._rovingTabIndex;\n }\n }\n\n /**\n * Mirror menuitem semantics onto the host via ElementInternals. Role is\n * derived from `type` (normal → menuitem, checkbox → menuitemcheckbox,\n * radio → menuitemradio). aria-disabled, aria-checked, aria-haspopup,\n * aria-expanded, and aria-busy reactively follow component state.\n * Consumer-supplied `aria-label` / `aria-labelledby` on the host project\n * onto `internals.ariaLabel` / `internals.ariaLabelledByElements`.\n * @internal\n */\n private _syncHostAriaSemantics(): void {\n const internals = this._internals;\n const role = this._getRole();\n\n // Codex push-gate round-6 finding 2: on the legacy fallback path\n // (`_supportsIdrefRefs === false`) the inner `.menu-item` element\n // already exposes role=\"menuitem*\" + aria-disabled / aria-checked /\n // aria-haspopup / aria-expanded / aria-busy via the template. If we\n // ALSO write those onto the host's ElementInternals, AT sees TWO\n // menuitems for one logical option — the duplicate-surface problem\n // host-canonical migration is meant to eliminate. Suppress all of\n // these state writes on the host when the fallback path is in\n // effect; the inner element is the canonical announced surface.\n if (!this._supportsIdrefRefs) {\n internals.role = null;\n internals.ariaDisabled = null;\n internals.ariaChecked = null;\n internals.ariaHasPopup = null;\n internals.ariaExpanded = null;\n internals.ariaBusy = null;\n } else {\n internals.role = role;\n internals.ariaDisabled = this.disabled ? 'true' : null;\n\n const hasCheckableRole = this.type === 'checkbox' || this.type === 'radio';\n internals.ariaChecked = hasCheckableRole ? (this.checked ? 'true' : 'false') : null;\n\n internals.ariaHasPopup = this._hasSubmenu ? 'menu' : null;\n internals.ariaExpanded = this._hasSubmenu ? (this._submenuOpen ? 'true' : 'false') : null;\n internals.ariaBusy = this.loading ? 'true' : null;\n }\n\n const hostAriaLabel = this.getAttribute('aria-label')?.trim() || '';\n const consumerLabelledBy = this.getAttribute('aria-labelledby');\n const labelEls = resolveIdrefTokens(this, consumerLabelledBy);\n const hasEffectiveLabelledBy = labelEls.length > 0;\n\n type InternalsWithRefs = ElementInternals & {\n ariaLabelledByElements: Element[] | null;\n };\n\n if (this._supportsIdrefRefs) {\n const refsInternals = internals as InternalsWithRefs;\n refsInternals.ariaLabelledByElements = hasEffectiveLabelledBy ? labelEls : null;\n }\n\n // AccName 1.2 §4.3.1 precedence: consumer aria-labelledby (resolved) >\n // consumer aria-label > implicit slotted text (left to AccName\n // computation through the host's role). When neither override is\n // supplied, ariaLabel is cleared so AT walks slotted children for the\n // accessible name. The resolved string is cached on\n // `_resolvedAccessibleName` so the fallback render branch (legacy path:\n // AT reads inner div) can mirror the same override without duplicating\n // the precedence ladder.\n let resolved = '';\n if (hasEffectiveLabelledBy) {\n const flattened =\n labelEls\n .map((el) => flattenAccName(el))\n .filter(Boolean)\n .join(' ') ||\n hostAriaLabel ||\n '';\n resolved = flattened;\n if (this._supportsIdrefRefs) {\n // Modern path: element refs win; clear ariaLabel so they aren't\n // shadowed by a stale string. Fallback branch reads\n // `_resolvedAccessibleName` for its inner-div mirror.\n internals.ariaLabel = null;\n } else {\n internals.ariaLabel = flattened || null;\n }\n } else if (hostAriaLabel) {\n resolved = hostAriaLabel;\n if (this._supportsIdrefRefs) {\n // Modern path: host carries the accessible name directly.\n internals.ariaLabel = hostAriaLabel;\n } else {\n // Fallback path: the inner [role=\"menuitem*\"] div is the named\n // surface (it mirrors `_resolvedAccessibleName` via aria-label).\n // Suppress the host aria-label so AT does not announce a second\n // duplicate name (CodeRabbit MUST-FIX: leaked duplicate name).\n internals.ariaLabel = null;\n }\n } else {\n // No override — leave the announced surface to walk slotted text.\n internals.ariaLabel = null;\n }\n\n // Codex push-gate round-2 finding 2: keep the resolved override\n // available for the legacy render branch. Request a re-render so the\n // fallback `<div role=\"menuitem*\" aria-label=...>` picks up the new\n // value when host aria-* changes after first paint.\n if (this._resolvedAccessibleName !== resolved) {\n this._resolvedAccessibleName = resolved;\n if (!this._supportsIdrefRefs) {\n this.requestUpdate();\n }\n }\n }\n\n /** @internal */\n private _handleSubmenuSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasSubmenu = slot.assignedElements().length > 0;\n }\n\n /** @internal */\n private _activate(): void {\n if (this.disabled || this.loading) return;\n\n if (this.type === 'checkbox') {\n this.checked = !this.checked;\n } else if (this.type === 'radio') {\n const menu = this.closest('hx-menu');\n if (menu) {\n menu\n .querySelectorAll<HelixMenuItem>(':scope > hx-menu-item[type=\"radio\"]')\n .forEach((sibling) => {\n sibling.checked = sibling === this;\n });\n } else {\n this.checked = true;\n }\n }\n\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem; value: string }>('hx-item-select', {\n bubbles: true,\n composed: true,\n detail: { item: this, value: this.value },\n }),\n );\n }\n\n /**\n * Origin guard for host-bound click/keydown handlers. Returns `true` only\n * when the event originated on THIS host (its shadow tree) and not on a\n * nested `hx-menu-item` projected into the `submenu` slot.\n *\n * Codex push-gate round-5 P1: nested submenu items are slotted descendants\n * in the parent's light DOM. Click/keydown events from a Child item bubble\n * through the parent host's listeners — without this guard, selecting Child\n * also activates Parent (double `hx-item-select`) and Enter/Space/ArrowRight\n * on Child re-trigger Parent's handlers (wrong-level activation, second\n * submenu reopen).\n *\n * Walks `composedPath()` and returns the closest `hx-menu-item` ancestor of\n * the original target; the event is \"ours\" iff that ancestor is `this`.\n * Mirrors the inner-vs-host origin discipline used by `hx-checkbox`,\n * `hx-switch`, and `hx-toggle-button`'s host handlers (`path[0] !== this`)\n * but adapts for hx-menu-item's nested-host case where path[0] is the\n * deepest inner element of a slotted child's own shadow tree.\n * @internal\n */\n private _isOwnEvent(e: Event): boolean {\n const path = e.composedPath();\n for (const node of path) {\n if (!(node instanceof Element)) continue;\n if (node.tagName === 'HX-MENU-ITEM') {\n return node === this;\n }\n }\n return false;\n }\n\n /** @internal */\n private _handleClick = (e: MouseEvent): void => {\n // Codex push-gate round-5 finding 1 (P1): clicks on a nested submenu's\n // child item bubble through this host. Without an origin guard, both\n // Child and Parent activate — wrong value emitted, possibly closes menu.\n if (!this._isOwnEvent(e)) return;\n if (this.disabled || this.loading) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n this._activate();\n };\n\n /** @internal */\n private _handleKeyDown = (e: KeyboardEvent): void => {\n // Codex push-gate round-5 finding 2 (P1): Enter / Space / ArrowRight\n // dispatched at a focused Child item inside an open submenu bubble\n // through this host. Without an origin guard, Parent treats them as its\n // own — double activation and wrong-level submenu reopen. The original\n // JSDoc on this handler described this guard but never enforced it.\n if (!this._isOwnEvent(e)) return;\n\n // Only handle keys whose target is THIS host (or its shadow). The\n // parent hx-menu's keydown handler runs first via bubbling and may\n // already have moved focus; we ignore events that aren't aimed at us.\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._activate();\n return;\n }\n\n if (e.key === 'ArrowRight' && this._hasSubmenu) {\n e.preventDefault();\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem }>('hx-item-submenu-open', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: { item: this },\n }),\n );\n return;\n }\n\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem }>('hx-item-submenu-close', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: { item: this },\n }),\n );\n }\n };\n\n /** @internal */\n private _renderCheckedIcon() {\n return html`\n <span part=\"checked-icon\" class=\"menu-item__checked-icon\" aria-hidden=\"true\">\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n `;\n }\n\n /** @internal */\n private _renderSubmenuIcon() {\n return html`\n <span part=\"submenu-icon\" class=\"menu-item__submenu-icon\" aria-hidden=\"true\">\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </span>\n `;\n }\n\n /** @internal */\n private _renderSpinner() {\n return html`\n <svg class=\"menu-item__spinner\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\" opacity=\"0.3\" />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n }\n\n /** @internal */\n private _getRole(): 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' {\n switch (this.type) {\n case 'checkbox':\n return 'menuitemcheckbox';\n case 'radio':\n return 'menuitemradio';\n default:\n return 'menuitem';\n }\n }\n\n override render() {\n const role = this._getRole();\n const hasCheckableRole = this.type === 'checkbox' || this.type === 'radio';\n const classes = {\n 'menu-item': true,\n 'menu-item--checked': this.checked,\n };\n\n // Modern host-canonical path: role/aria-* and tabindex live on the\n // host via `_internals` and the `_applyHostTabIndex()` helper. The\n // inner element is a presentational div (ARIA 1.2 forbids\n // role=\"presentation\" on focusable elements; non-focusable plain div\n // is the cleanest strip). Click + keydown handlers stay on the host\n // via the wrapper div for delegation; this preserves keyboard\n // activation while leaving the host as the AT-announced surface.\n if (this._supportsIdrefRefs) {\n // Click + keydown handlers are bound on the host in\n // connectedCallback() — keydown does not propagate INTO shadow\n // DOM, so binding inside the template would miss host-focused\n // events on the modern path.\n return html`\n <div part=\"base\" class=${classMap(classes)}>\n ${this.loading ? this._renderSpinner() : nothing}\n ${hasCheckableRole ? this._renderCheckedIcon() : nothing}\n <span part=\"prefix\" class=\"menu-item__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"menu-item__label\">\n <slot></slot>\n </span>\n <span part=\"suffix\" class=\"menu-item__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n ${this._hasSubmenu ? this._renderSubmenuIcon() : nothing}\n <slot name=\"submenu\" @slotchange=${this._handleSubmenuSlotChange}></slot>\n </div>\n `;\n }\n\n // Legacy fallback: keep role/aria-* on inner div for AT without IDL\n // element references on ElementInternals. Click + keydown still\n // listen on the host (see connectedCallback) so behaviour is uniform.\n //\n // Codex push-gate round-2 finding 2: AT on the fallback path\n // announces the inner div, so it MUST mirror the same accessible name\n // resolved by `_syncHostAriaSemantics()` (consumer host aria-label /\n // aria-labelledby flatten). Empty string means \"no override\" — let AT\n // walk slotted text content for the implicit name.\n const fallbackAriaLabel = this._resolvedAccessibleName || nothing;\n return html`\n <div\n part=\"base\"\n class=${classMap(classes)}\n role=${role}\n tabindex=${this.disabled ? '-1' : String(this._rovingTabIndex)}\n aria-label=${fallbackAriaLabel}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-checked=${hasCheckableRole ? (this.checked ? 'true' : 'false') : nothing}\n aria-haspopup=${this._hasSubmenu ? 'menu' : nothing}\n aria-expanded=${this._hasSubmenu ? (this._submenuOpen ? 'true' : 'false') : nothing}\n aria-busy=${this.loading ? 'true' : nothing}\n >\n ${this.loading ? this._renderSpinner() : nothing}\n ${hasCheckableRole ? this._renderCheckedIcon() : nothing}\n <span part=\"prefix\" class=\"menu-item__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"menu-item__label\">\n <slot></slot>\n </span>\n <span part=\"suffix\" class=\"menu-item__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n ${this._hasSubmenu ? this._renderSubmenuIcon() : nothing}\n <slot name=\"submenu\" @slotchange=${this._handleSubmenuSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu-item': HelixMenuItem;\n }\n}\n","import { css } from 'lit';\n\nexport const helixMenuDividerStyles = css`\n :host {\n display: block;\n }\n\n .menu-divider {\n height: var(--hx-border-width-thin, 1px);\n background-color: var(--hx-menu-divider-color, var(--hx-color-border-default, #d6dbd5));\n margin: var(--hx-space-1, 0.25rem) calc(-1 * var(--hx-space-1, 0.25rem));\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu-divider {\n background-color: GrayText;\n }\n }\n`;\n","import { html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuDividerStyles } from './hx-menu-divider.styles.js';\nimport { supportsIdrefElementReferences } from '../../utils/aria-idref.js';\n\n/**\n * A visual separator for grouping items within an `hx-menu`.\n *\n * Group 5b host-canonical: `role=\"separator\"` lives on the **host** via\n * `_internals.role` so the parent `<hx-menu>` (`role=\"menu\"`) sees the\n * separator as a direct child. `aria-orientation` is mirrored onto the host\n * via `internals.ariaOrientation`. The inner div is presentational on the\n * modern path and stripped of its role; the legacy fallback keeps the\n * inner role for engines without ElementInternals IDL accessors.\n *\n * @summary Horizontal divider between menu sections.\n *\n * @tag hx-menu-divider\n *\n * @csspart base - The root separator element.\n *\n * @cssprop [--hx-menu-divider-color=var(--hx-color-neutral-200)] - Divider line color.\n */\n@customElement('hx-menu-divider')\nexport class HelixMenuDivider extends HelixElement {\n static override styles = [helixMenuDividerStyles, forcedColorsInteractive];\n\n /** @internal */\n private _supportsIdrefRefs = true;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._supportsIdrefRefs = supportsIdrefElementReferences(this._internals);\n const internals = this._internals;\n internals.role = 'separator';\n internals.ariaOrientation = 'horizontal';\n }\n\n override render() {\n if (this._supportsIdrefRefs) {\n // Modern path: role lives on host via internals; inner div is\n // presentational.\n return html`<div part=\"base\" class=\"menu-divider\"></div>`;\n }\n // Legacy fallback: keep role/aria-orientation on the inner div for AT\n // without IDL accessors on ElementInternals.\n return html`<div\n part=\"base\"\n class=\"menu-divider\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n ></div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu-divider': HelixMenuDivider;\n }\n}\n"],"names":["helixMenuStyles","css","findClosestMenuAncestor","start","found","findClosestMenuAncestorElement","findOwningMenuItem","menu","findOwningMenuItemElement","HelixMenu","HelixElement","detail","item","submenuSlot","_a","nested","el","ownerItem","target","items","activeIndex","i","first","last","index","active","idx","char","match","getMenuItemTypeaheadLabel","slot","validTags","invalid","devWarn","ctor","supportsIdrefElementReferences","installAriaIdrefMirror","changedProperties","internals","hostAriaLabel","consumerLabelledBy","labelEls","resolveIdrefTokens","hasEffectiveLabelledBy","refsInternals","resolved","flattenAccName","html","fallbackLabel","nothing","forcedColorsInteractive","__decorateClass","property","customElement","helixMenuItemStyles","HelixMenuItem","value","open","options","role","hasCheckableRole","flattened","sibling","path","node","classes","classMap","fallbackAriaLabel","state","query","helixMenuDividerStyles","HelixMenuDivider"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-nav-item-CODtUlew.js","sources":["../../src/components/hx-side-nav/hx-side-nav.styles.ts","../../src/components/hx-side-nav/hx-side-nav.ts","../../src/components/hx-side-nav/hx-nav-item.styles.ts","../../src/components/hx-side-nav/hx-nav-item.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSideNavStyles = css`\n :host {\n display: block;\n height: 100%;\n /* Mirror the nav background and text on the host so slotted light-DOM\n content (header, footer slots) inherits the correct dark surface color.\n Without this, axe-core cannot resolve the background for slotted nodes\n and evaluates their text against the page white background, producing\n false-positive color-contrast violations (WCAG 2.1 AA). */\n background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));\n color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Nav Container ─── */\n\n .side-nav {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: var(--hx-side-nav-width, 16rem);\n background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));\n color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));\n transition: width var(--hx-transition-normal, 300ms) ease;\n overflow: hidden;\n border-inline-end: var(--hx-border-width-thin, 1px) solid\n var(\n --hx-side-nav-border-color,\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))\n );\n }\n\n /* ─── Collapsed State ─── */\n\n :host([collapsed]) .side-nav {\n width: var(--hx-side-nav-collapsed-width, 3.5rem);\n }\n\n /* ─── Header ─── */\n\n .side-nav__header {\n display: flex;\n align-items: center;\n padding: var(--hx-side-nav-header-padding, var(--hx-space-4, 1rem));\n flex-shrink: 0;\n min-height: var(--hx-space-14, 3.5rem);\n border-bottom: var(--hx-border-width-thin, 1px) solid\n var(\n --hx-side-nav-border-color,\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))\n );\n overflow: hidden;\n }\n\n :host([collapsed]) .side-nav__header {\n justify-content: center;\n padding: var(--hx-space-3, 0.75rem);\n }\n\n /* ─── Body ─── */\n\n .side-nav__body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: var(--hx-space-2, 0.5rem) 0;\n }\n\n /* ─── Footer ─── */\n\n .side-nav__footer {\n display: flex;\n align-items: center;\n padding: var(--hx-side-nav-footer-padding, var(--hx-space-4, 1rem));\n flex-shrink: 0;\n min-height: var(--hx-space-14, 3.5rem);\n border-top: var(--hx-border-width-thin, 1px) solid\n var(\n --hx-side-nav-border-color,\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))\n );\n overflow: hidden;\n }\n\n :host([collapsed]) .side-nav__footer {\n justify-content: center;\n padding: var(--hx-space-3, 0.75rem);\n }\n\n /* ─── Toggle Button ─── */\n\n .side-nav__toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--hx-space-8, 2rem);\n height: var(--hx-space-8, 2rem);\n margin-inline-start: auto;\n flex-shrink: 0;\n padding: 0;\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background: transparent;\n color: var(--hx-side-nav-toggle-color, var(--hx-color-text-inverse, #ffffff));\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms) ease,\n color var(--hx-transition-fast, 150ms) ease;\n }\n\n .side-nav__toggle:hover {\n /* Read both deprecated --hx-color-border-on-dark-subtle (3.2.0/3.2.1 API)\n and canonical --hx-color-surface-on-dark-overlay-subtle so consumer\n overrides on either name reach paint. Deprecated removal: 4.0.0.\n Hex fallback for browsers without color-mix(). */\n background-color: var(\n --hx-color-border-on-dark-subtle,\n var(--hx-color-surface-on-dark-overlay-subtle, rgba(255, 255, 255, 0.1))\n );\n color: var(--hx-side-nav-toggle-hover-color, var(--hx-color-text-inverse, #ffffff));\n }\n\n @supports (color: color-mix(in srgb, red 50%, blue)) {\n /* Fold color-mix() into the same deprecated-first chain so consumer\n overrides on either token reach paint on the modern path too. */\n .side-nav__toggle:hover {\n background-color: var(\n --hx-color-border-on-dark-subtle,\n var(\n --hx-color-surface-on-dark-overlay-subtle,\n color-mix(in srgb, currentColor 15%, transparent)\n )\n );\n }\n }\n\n .side-nav__toggle:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-side-nav-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .side-nav__toggle svg {\n width: var(--hx-space-5, 1.25rem);\n height: var(--hx-space-5, 1.25rem);\n fill: currentColor;\n flex-shrink: 0;\n transition: transform var(--hx-transition-normal, 300ms) ease;\n }\n\n :host([collapsed]) .side-nav__toggle svg {\n transform: rotate(180deg);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .side-nav {\n transition: none;\n }\n\n .side-nav__toggle {\n transition: none;\n }\n\n .side-nav__toggle svg {\n transition: none;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .side-nav {\n border-inline-end-color: CanvasText;\n }\n\n .side-nav__header {\n border-bottom-color: CanvasText;\n }\n\n .side-nav__footer {\n border-top-color: CanvasText;\n }\n\n .side-nav__toggle {\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n border: 1px solid ButtonText;\n }\n\n .side-nav__toggle:hover {\n background-color: Highlight;\n color: HighlightText;\n border-color: Highlight;\n }\n\n .side-nav__toggle:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n }\n`;\n","import { html, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixSideNavStyles } from './hx-side-nav.styles.js';\n\n/**\n * A collapsible left-side navigation panel with nested menu item support.\n * Designed for clinical portals, admin dashboards, and department navigation.\n *\n * @summary Collapsible side navigation panel for enterprise healthcare applications.\n *\n * @tag hx-side-nav\n *\n * @slot - Default slot for hx-nav-item children.\n * @slot header - Logo or branding content.\n * @slot footer - User profile or settings content.\n *\n * @fires {CustomEvent<{ collapsed: boolean }>} hx-collapse - Dispatched when the nav collapses to icon-only mode.\n * @fires {CustomEvent<{ collapsed: boolean }>} hx-expand - Dispatched when the nav expands to full width.\n *\n * @csspart nav - The outer nav element.\n * @csspart header - The header section.\n * @csspart body - The scrollable body section.\n * @csspart footer - The footer section.\n * @csspart toggle - The collapse/expand toggle button.\n *\n * @cssprop [--hx-side-nav-width=16rem] - Full expanded width.\n * @cssprop [--hx-side-nav-collapsed-width=3.5rem] - Collapsed icon-only width.\n * @cssprop [--hx-side-nav-bg=var(--hx-color-surface-inverse)] - Background color.\n * @cssprop [--hx-side-nav-color=var(--hx-color-text-inverse)] - Text color.\n * @cssprop [--hx-side-nav-border-color=var(--hx-color-border-on-dark-strong)] - Border color (against the dark surface-inverse host bg).\n * @cssprop [--hx-side-nav-header-padding=var(--hx-space-4)] - Header padding.\n * @cssprop [--hx-side-nav-footer-padding=var(--hx-space-4)] - Footer padding.\n * @cssprop [--hx-side-nav-toggle-color=var(--hx-color-text-inverse)] - Toggle button icon color (resting).\n * @cssprop [--hx-side-nav-toggle-hover-color=var(--hx-color-text-inverse)] - Toggle button icon color on hover.\n * @cssprop [--hx-color-surface-inverse] - Side-nav surface fill (resolves to neutral-900 light, near-black dark).\n * @cssprop [--hx-color-text-inverse] - Side-nav text color (resolves to neutral-0).\n * @cssprop [--hx-color-border-on-dark-strong] - Container/header/footer divider border (overlay-white-70 light, overlay-black-50 dark — sized for visibility on the mode-flipped surface-inverse).\n * @cssprop [--hx-color-surface-on-dark-overlay-subtle] - Toggle button hover surface (overlay-white-10 primitive — translucent fill, not a border).\n * @cssprop [--hx-color-border-on-dark-subtle] - DEPRECATED 3.2.2; renamed to --hx-color-surface-on-dark-overlay-subtle (the value paints a translucent fill, not a border). Toggle-hover rule reads both names via deprecated-first fallback so existing overrides keep working until removal in 4.0.0.\n */\n@customElement('hx-side-nav')\nexport class HelixSideNav extends HelixElement {\n // 3.2.1: forced-colors deference is owned by the bespoke @media block in\n // hx-side-nav.styles.ts (toggle button, header/footer borders). Do NOT also\n // compose forcedColorsInteractive — XOR rule per the mixin docstring.\n static override styles = [helixSideNavStyles];\n\n // ─── Properties ───\n\n /**\n * When true, the nav collapses to show icons only.\n * @attr collapsed\n */\n @property({ type: Boolean, reflect: true })\n collapsed = false;\n\n /**\n * The accessible label for the nav landmark.\n * @attr label\n */\n @property({ type: String })\n label = 'Main Navigation';\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('collapsed')) {\n this._propagateCollapsedToChildren();\n }\n }\n\n // ─── Collapsed State Propagation ───\n\n /**\n * Propagates the collapsed state to all slotted hx-nav-item children by\n * setting or removing the `data-collapsed` attribute. This allows child\n * items to respond to collapsed mode via their CSS selectors.\n */\n /** @internal */\n private _propagateCollapsedToChildren(): void {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!slot) return;\n\n const navItems = slot\n .assignedElements({ flatten: true })\n .filter((el) => el.tagName.toLowerCase() === 'hx-nav-item');\n\n for (const item of navItems) {\n if (!(item instanceof HTMLElement)) continue;\n if (this.collapsed) {\n item.setAttribute('data-collapsed', '');\n } else {\n item.removeAttribute('data-collapsed');\n }\n }\n }\n\n /**\n * Handles the default slot's slotchange event so that if items are added\n * after initial render, they immediately receive the correct collapsed state.\n */\n /** @internal */\n private _onDefaultSlotChange(): void {\n this._propagateCollapsedToChildren();\n }\n\n // ─── Keyboard Navigation ───\n\n /**\n * Implements roving tabindex-style ArrowUp/ArrowDown keyboard navigation\n * among direct hx-nav-item children in the body slot. Disabled items are\n * skipped. Focus is applied to the interactive element inside the shadow DOM\n * of each item (anchor or button with part=\"link\").\n */\n /** @internal */\n private _handleKeydown(e: KeyboardEvent): void {\n const validKeys = ['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft', 'Home', 'End'];\n if (!validKeys.includes(e.key)) return;\n\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!slot) return;\n\n const topLevelItems = slot\n .assignedElements({ flatten: true })\n .filter(\n (el): el is HTMLElement =>\n el.tagName.toLowerCase() === 'hx-nav-item' && !el.hasAttribute('disabled'),\n );\n\n if (topLevelItems.length === 0) return;\n\n // Build a flattened list of navigable items: direct children plus visible\n // child items from expanded parent items (per ARIA APG tree pattern).\n const navItems: HTMLElement[] = [];\n for (const item of topLevelItems) {\n navItems.push(item);\n // If this item is expanded, include its non-disabled children\n if (item.hasAttribute('expanded')) {\n const childrenSlot =\n item.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"children\"]');\n if (childrenSlot) {\n const childItems = childrenSlot\n .assignedElements({ flatten: true })\n .filter(\n (el): el is HTMLElement =>\n el.tagName.toLowerCase() === 'hx-nav-item' && !el.hasAttribute('disabled'),\n );\n navItems.push(...childItems);\n }\n }\n }\n\n if (navItems.length === 0) return;\n\n // Find which item currently contains focus\n const activeEl = document.activeElement;\n let currentIndex = -1;\n for (let i = 0; i < navItems.length; i++) {\n const item = navItems[i];\n if (!item) continue;\n if (\n item === activeEl ||\n item.contains(activeEl) ||\n item.shadowRoot?.contains(activeEl) === true\n ) {\n currentIndex = i;\n break;\n }\n }\n\n // Handle ArrowRight/ArrowLeft for expand/collapse (ARIA APG tree pattern)\n if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {\n e.preventDefault();\n const currentItem = currentIndex >= 0 ? navItems[currentIndex] : null;\n if (!currentItem) return;\n\n if (e.key === 'ArrowRight') {\n // If the item has children and is collapsed, expand it\n if (\n currentItem.hasAttribute('expanded') === false &&\n currentItem.querySelector('[slot=\"children\"]')\n ) {\n currentItem.setAttribute('expanded', '');\n (currentItem as HTMLElement & { expanded?: boolean }).expanded = true;\n } else if (currentItem.hasAttribute('expanded')) {\n // Already expanded: move focus to first child item\n const childrenSlot =\n currentItem.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"children\"]');\n if (childrenSlot) {\n const firstChild = childrenSlot\n .assignedElements({ flatten: true })\n .find(\n (el): el is HTMLElement =>\n el.tagName.toLowerCase() === 'hx-nav-item' && !el.hasAttribute('disabled'),\n );\n if (firstChild) {\n firstChild.focus();\n return;\n }\n }\n }\n } else {\n // ArrowLeft: if expanded, collapse; if collapsed or non-expandable, find parent\n if (currentItem.hasAttribute('expanded')) {\n currentItem.removeAttribute('expanded');\n (currentItem as HTMLElement & { expanded?: boolean }).expanded = false;\n } else {\n // Move focus to parent item if this item is a child in another item's slot\n const parentNavItem =\n currentItem.closest<HTMLElement>('hx-nav-item:not(:scope)') ??\n currentItem.parentElement?.closest<HTMLElement>('hx-nav-item') ??\n null;\n if (parentNavItem && !parentNavItem.hasAttribute('disabled')) {\n parentNavItem.focus();\n }\n }\n }\n return;\n }\n\n e.preventDefault();\n\n let nextIndex: number;\n if (e.key === 'ArrowDown') {\n nextIndex = currentIndex < navItems.length - 1 ? currentIndex + 1 : 0;\n } else if (e.key === 'ArrowUp') {\n nextIndex = currentIndex > 0 ? currentIndex - 1 : navItems.length - 1;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else {\n nextIndex = navItems.length - 1;\n }\n\n const targetItem = navItems[nextIndex];\n if (!targetItem) return;\n // WCAG 2.1.1: call the public focus() method on the nav item rather than\n // piercing its Shadow DOM directly. hx-nav-item.focus() delegates to the\n // internal [part=\"link\"] element, preserving shadow encapsulation.\n targetItem.focus();\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleToggle(): void {\n this.collapsed = !this.collapsed;\n\n if (this.collapsed) {\n /**\n * Dispatched when the nav collapses to icon-only mode.\n * @event hx-collapse\n */\n this.dispatchEvent(\n new CustomEvent<{ collapsed: boolean }>('hx-collapse', {\n bubbles: true,\n composed: true,\n detail: { collapsed: true },\n }),\n );\n } else {\n /**\n * Dispatched when the nav expands to full width.\n * @event hx-expand\n */\n this.dispatchEvent(\n new CustomEvent<{ collapsed: boolean }>('hx-expand', {\n bubbles: true,\n composed: true,\n detail: { collapsed: false },\n }),\n );\n }\n }\n\n // ─── Render ───\n\n /** @internal */\n private _renderToggleIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n />\n </svg>`;\n }\n\n override render() {\n return html`\n <nav part=\"nav\" class=\"side-nav\" aria-label=${this.label}>\n <div part=\"header\" class=\"side-nav__header\">\n <slot name=\"header\"></slot>\n <button\n part=\"toggle\"\n class=\"side-nav__toggle\"\n aria-label=${this.collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-expanded=${!this.collapsed}\n @click=${this._handleToggle}\n >\n ${this._renderToggleIcon()}\n </button>\n </div>\n\n <div part=\"body\" class=\"side-nav__body\" id=\"side-nav-body\" @keydown=${this._handleKeydown}>\n <slot @slotchange=${this._onDefaultSlotChange}></slot>\n </div>\n\n <div part=\"footer\" class=\"side-nav__footer\">\n <slot name=\"footer\"></slot>\n </div>\n </nav>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-side-nav': HelixSideNav;\n }\n}\n\nexport type { HelixSideNav as HxSideNav };\n","import { css } from 'lit';\n\nexport const helixNavItemStyles = css`\n :host {\n display: block;\n /* The host background must be a concrete color so that axe-core can\n resolve text contrast ratios for shadow-DOM content correctly.\n surface-inverse + text-inverse flip per mode: dark-on-light in dark\n mode, light-on-dark in light mode. */\n background-color: var(--hx-nav-item-host-bg, var(--hx-color-surface-inverse, #0d1825));\n color: var(--hx-nav-item-color, var(--hx-color-text-inverse, #ffffff));\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Nav Item ─── */\n\n .nav-item {\n display: flex;\n flex-direction: column;\n }\n\n /* ─── Link / Button ─── */\n\n .nav-item__link {\n display: flex;\n align-items: center;\n gap: var(--hx-space-3, 0.75rem);\n padding: var(--hx-nav-item-padding, var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem));\n min-height: var(--hx-space-10, 2.5rem);\n text-decoration: none;\n color: var(--hx-nav-item-color, var(--hx-color-text-inverse, #ffffff));\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n margin: 0 var(--hx-space-2, 0.5rem);\n transition:\n background-color var(--hx-transition-fast, 150ms) ease,\n color var(--hx-transition-fast, 150ms) ease;\n white-space: nowrap;\n overflow: hidden;\n cursor: pointer;\n font-family: var(--hx-nav-item-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-normal, 1.5);\n position: relative;\n border: none;\n background: transparent;\n width: calc(100% - var(--hx-space-4, 1rem));\n text-align: start;\n }\n\n /* Link variant */\n a.nav-item__link {\n display: flex;\n }\n\n .nav-item__link:hover {\n background-color: var(\n --hx-nav-item-hover-bg,\n var(--hx-overlay-white-8, rgba(255, 255, 255, 0.08))\n ); /* fallback for browsers without color-mix() */\n color: var(--hx-nav-item-hover-color, var(--hx-color-text-inverse, #ffffff));\n }\n\n @supports (color: color-mix(in srgb, red 50%, blue)) {\n .nav-item__link:hover {\n background-color: var(\n --hx-nav-item-hover-bg,\n color-mix(in srgb, currentColor 10%, transparent)\n );\n }\n }\n\n .nav-item__link:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-nav-item-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Active State ─── */\n\n :host([active]) .nav-item__link {\n /* Active state sits on the darker primary-600 (#0F7078) fill. White text\n (#ffffff) on primary-600 = 5.82:1 WCAG AA pass. text-on-primary now\n resolves to neutral-900 (intended for the lighter primary-500 surface)\n which would fail here. text.on-primary-strong holds at neutral-0 across\n modes (no dark flip) so the active fg stays AA. 3.2.1: routed through\n the action.* / on-{role}-strong semantic tier per token-cascade\n remediation (no more bare primary-600 / neutral-0 consumption). */\n background-color: var(\n --hx-nav-item-active-bg,\n var(--hx-color-action-primary-bg-hover, #0f7078)\n );\n color: var(--hx-nav-item-active-color, var(--hx-color-text-on-primary-strong, #ffffff));\n }\n\n :host([active]) .nav-item__link:hover {\n /* text.on-primary-strong (#ffffff) on primary-700 (#0F6363) = WCAG AA ✓ */\n background-color: var(\n --hx-nav-item-active-hover-bg,\n var(--hx-color-action-primary-bg-active, #0f6363)\n );\n }\n\n /* ─── Disabled State ─── */\n\n :host([disabled]) .nav-item__link {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n cursor: not-allowed;\n }\n\n /* ─── Icon ─── */\n\n .nav-item__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-space-5, 1.25rem);\n height: var(--hx-space-5, 1.25rem);\n }\n\n /* ─── Label ─── */\n\n .nav-item__label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: opacity var(--hx-transition-fast, 150ms) ease;\n }\n\n /* ─── Badge ─── */\n\n .nav-item__badge {\n margin-inline-start: auto;\n flex-shrink: 0;\n }\n\n /* ─── Expand Arrow ─── */\n\n .nav-item__arrow {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-inline-start: auto;\n width: var(--hx-space-5, 1.25rem);\n height: var(--hx-space-5, 1.25rem);\n transition: transform var(--hx-transition-normal, 300ms) ease;\n }\n\n .nav-item__arrow svg {\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n fill: currentColor;\n }\n\n :host([expanded]) .nav-item__arrow {\n transform: rotate(90deg);\n }\n\n /* ─── Children (sub-nav) ─── */\n\n .nav-item__children {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--hx-transition-normal, 300ms ease);\n overflow: hidden;\n }\n\n :host([expanded]) .nav-item__children {\n grid-template-rows: 1fr;\n }\n\n .nav-item__children-inner {\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n padding-inline-start: var(--hx-space-6, 1.5rem);\n }\n\n /* ─── Tooltip (collapsed mode) ─── */\n\n .nav-item__tooltip {\n position: absolute;\n left: calc(100% + var(--hx-space-2, 0.5rem));\n top: 50%;\n transform: translateY(-50%);\n /* tooltip is an inverted surface — flips per mode via surface-inverse /\n text-inverse. 3.2.1: wrapped with component-tier slots so consumers can\n theme tooltip surface/text without overriding the global semantics. */\n background-color: var(--hx-nav-item-tooltip-bg, var(--hx-color-surface-inverse, #0d1825));\n color: var(--hx-nav-item-tooltip-color, var(--hx-color-text-inverse, #ffffff));\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n font-size: var(--hx-font-size-xs, 0.75rem);\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--hx-transition-fast, 150ms) ease;\n z-index: var(--hx-z-index-tooltip, 1600);\n box-shadow: var(--hx-shadow-md, 0 2px 8px rgb(0 0 0 / 0.2));\n }\n\n :host([data-collapsed]) .nav-item__link:hover .nav-item__tooltip,\n :host([data-collapsed]) .nav-item__link:focus-visible .nav-item__tooltip {\n opacity: 1;\n }\n\n /* ─── Collapsed host state (propagated from parent) ─── */\n\n :host([data-collapsed]) .nav-item__label {\n width: 0;\n overflow: hidden;\n opacity: 0;\n }\n\n :host([data-collapsed]) .nav-item__badge {\n display: none;\n }\n\n :host([data-collapsed]) .nav-item__arrow {\n display: none;\n }\n\n :host([data-collapsed]) .nav-item__children {\n display: none !important;\n }\n\n :host([data-collapsed]) .nav-item__link {\n justify-content: center;\n margin: 0 var(--hx-space-1, 0.25rem);\n width: calc(100% - var(--hx-space-2, 0.5rem));\n padding: var(--hx-space-2, 0.5rem);\n position: relative;\n overflow: visible;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .nav-item__link,\n .nav-item__label,\n .nav-item__arrow,\n .nav-item__children,\n .nav-item__tooltip {\n transition: none;\n }\n\n :host([expanded]) .nav-item__children {\n grid-template-rows: 1fr;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n /*\n * Bespoke block — sole owner of forced-colors deference for hx-nav-item\n * (the forcedColorsInteractive mixin is intentionally NOT composed; XOR\n * rule in styles/forced-colors.ts). Mirrors the mixin's interactive\n * contract (ButtonFace / ButtonText / Highlight on hover, GrayText on\n * disabled) for the .nav-item__link interactive surface, then layers the\n * component-specific active-state border and tooltip border on top.\n */\n .nav-item__link {\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n border: 1px solid ButtonText;\n }\n\n .nav-item__link:hover {\n background-color: Highlight;\n color: HighlightText;\n border-color: Highlight;\n }\n\n /*\n * Reset opacity on the SAME selector that sets it (.nav-item__link, line\n * 109) — the original :host([disabled]) reset was scoped to the host and\n * therefore had no effect on the link's 0.5 opacity. In forced-colors mode\n * GrayText must render at full opacity to preserve the system contrast\n * contract (WCAG 2.1 AA non-text contrast).\n */\n :host([disabled]) .nav-item__link {\n opacity: 1;\n color: GrayText;\n border-color: GrayText;\n }\n\n :host([active]:not([disabled])) .nav-item__link {\n border-color: Highlight;\n }\n\n .nav-item__link:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .nav-item__tooltip {\n border: 1px solid CanvasText;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { helixNavItemStyles } from './hx-nav-item.styles.js';\n\nconst _nextNavItemId = createIdCounter('hx-nav-item');\n\n/**\n * A navigation item for use inside hx-side-nav.\n * Supports icons, badges, sub-navigation, and active/disabled states.\n *\n * @summary Navigation item for hx-side-nav with support for icons, badges, and nested children.\n *\n * @tag hx-nav-item\n *\n * @slot - Default slot for item label text.\n * @slot icon - Icon to display before the label.\n * @slot badge - Badge content (e.g., notification count).\n * @slot children - Nested hx-nav-item children for sub-navigation.\n *\n * @csspart link - The anchor or button element.\n * @csspart icon - The icon container.\n * @csspart label - The label container.\n * @csspart badge - The badge container.\n * @csspart children - The children container.\n *\n * @cssprop [--hx-nav-item-color=var(--hx-color-text-inverse)] - Item text color.\n * @cssprop [--hx-nav-item-hover-bg] - Item hover background.\n * @cssprop [--hx-nav-item-hover-color=var(--hx-color-text-inverse)] - Item hover text color.\n * @cssprop [--hx-nav-item-active-bg=var(--hx-color-action-primary-bg-hover)] - Active item background.\n * @cssprop [--hx-nav-item-active-color=var(--hx-color-text-on-primary-strong)] - Active item text color.\n * @cssprop [--hx-nav-item-padding] - Item padding.\n * @cssprop [--hx-nav-item-host-bg=var(--hx-color-surface-inverse)] - Component host background color.\n * @cssprop [--hx-nav-item-tooltip-bg=var(--hx-color-surface-inverse)] - Tooltip background color (collapsed-rail tooltip).\n * @cssprop [--hx-nav-item-tooltip-color=var(--hx-color-text-inverse)] - Tooltip text color (collapsed-rail tooltip).\n */\n@customElement('hx-nav-item')\nexport class HelixNavItem extends HelixElement {\n // 3.2.1: forced-colors deference is owned by the bespoke @media block in\n // hx-nav-item.styles.ts (active border, focus outline, tooltip border).\n // Do NOT also compose forcedColorsInteractive — XOR rule per the mixin\n // docstring.\n static override styles = [helixNavItemStyles];\n\n /** @internal — per-instance tooltip ID */\n private _tooltipId = `${_nextNavItemId()}-tooltip`;\n\n // ─── Properties ───\n\n /**\n * The URL this nav item links to.\n * @attr href\n */\n @property({ type: String })\n href = '';\n\n /**\n * Whether this item is the current/active page.\n * @attr active\n */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n /**\n * Whether the sub-navigation is expanded.\n * @attr expanded\n */\n @property({ type: Boolean, reflect: true })\n expanded = false;\n\n /**\n * Whether this nav item is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── State ───\n\n /** Whether the children slot has assigned nodes. Updated via slotchange. */\n /** @internal */\n @state() private _hasChildren = false;\n\n /** Whether this item is in collapsed mode. Set externally by hx-side-nav via data-collapsed attribute. */\n /** @internal */\n @state() private _isCollapsed = false;\n\n // ─── Attribute Observer ───\n\n static override get observedAttributes(): string[] {\n return [...super.observedAttributes, 'data-collapsed'];\n }\n\n override attributeChangedCallback(name: string, old: string | null, value: string | null): void {\n super.attributeChangedCallback(name, old, value);\n if (name === 'data-collapsed') {\n this._isCollapsed = value !== null;\n }\n }\n\n // ─── Public API ───\n\n /**\n * Delegates focus to the internal link or button element (part=\"link\").\n * Allows parent components to focus nav items without piercing the Shadow DOM.\n * WCAG 2.1.1: keyboard navigation must not cross shadow boundaries via\n * direct shadowRoot queries.\n */\n override focus(options?: FocusOptions): void {\n const inner = this.shadowRoot?.querySelector<HTMLElement>('[part=\"link\"]');\n if (inner) {\n inner.focus(options);\n } else {\n super.focus(options);\n }\n }\n\n // ─── Slot Change Handler ───\n\n /** @internal */\n private _onChildrenSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasChildren = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Private Helpers ───\n\n /** @internal */\n private _getDirectText(): string {\n return Array.from(this.childNodes)\n .filter((n) => n.nodeType === Node.TEXT_NODE)\n .map((n) => n.textContent?.trim() ?? '')\n .filter(Boolean)\n .join(' ');\n }\n\n /** @internal */\n private _handleToggle(e: Event): void {\n if (this.disabled) return;\n e.preventDefault();\n this.expanded = !this.expanded;\n }\n\n /** @internal */\n private _renderExpandArrow() {\n return html`<span class=\"nav-item__arrow\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\">\n <path\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n />\n </svg>\n </span>`;\n }\n\n // ─── Render ───\n\n override render() {\n const label = this._getDirectText();\n\n const innerContent = html`\n <span part=\"icon\" class=\"nav-item__icon\">\n <slot name=\"icon\"></slot>\n </span>\n <span part=\"label\" class=\"nav-item__label\">\n <slot></slot>\n </span>\n <span part=\"badge\" class=\"nav-item__badge\">\n <slot name=\"badge\"></slot>\n </span>\n ${this._hasChildren ? this._renderExpandArrow() : nothing}\n ${this._isCollapsed\n ? html`<span id=${this._tooltipId} class=\"nav-item__tooltip\" role=\"tooltip\">${label}</span>`\n : nothing}\n `;\n\n // Render as anchor when href provided and no expandable children\n const linkEl =\n this.href && !this._hasChildren\n ? html`<a\n part=\"link\"\n class=\"nav-item__link\"\n href=${this.href}\n aria-current=${this.active ? 'page' : nothing}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-describedby=${this._isCollapsed ? this._tooltipId : nothing}\n tabindex=${this.disabled ? '-1' : '0'}\n >\n ${innerContent}\n </a>`\n : html`<button\n part=\"link\"\n class=\"nav-item__link\"\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-expanded=${this._hasChildren ? String(this.expanded) : nothing}\n aria-describedby=${this._isCollapsed ? this._tooltipId : nothing}\n tabindex=${this.disabled ? '-1' : '0'}\n @click=${this._handleToggle}\n >\n ${innerContent}\n </button>`;\n\n return html`\n <div class=\"nav-item\">\n ${linkEl}\n <div part=\"children\" class=\"nav-item__children\" role=\"group\">\n <div class=\"nav-item__children-inner\">\n <slot name=\"children\" @slotchange=${this._onChildrenSlotChange}></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-nav-item': HelixNavItem;\n }\n}\n\nexport type { HelixNavItem as HxNavItem };\n"],"names":["helixSideNavStyles","css","HelixSideNav","HelixElement","changedProperties","slot","_a","navItems","el","item","topLevelItems","childrenSlot","_b","childItems","activeEl","currentIndex","i","_c","currentItem","_d","firstChild","parentNavItem","_e","nextIndex","targetItem","html","__decorateClass","property","customElement","helixNavItemStyles","_nextNavItemId","createIdCounter","HelixNavItem","name","old","value","options","inner","n","label","innerContent","nothing","linkEl","state"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-nav-ldFM3Fle.js","sources":["../../src/components/hx-nav/hx-nav.styles.ts","../../src/components/hx-nav/hx-nav.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixNavStyles = css`\n :host {\n display: block;\n font-family: var(--hx-nav-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-nav-font-size, var(--hx-font-size-sm, 0.875rem));\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Nav Container ─── */\n\n [part='nav'] {\n position: relative;\n background-color: var(--hx-nav-bg, var(--hx-color-neutral-900, #0d1825));\n color: var(--hx-nav-color, var(--hx-color-neutral-100, #ebeee9));\n padding: var(--hx-nav-padding, var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem));\n }\n\n /* ─── Hamburger Toggle ─── */\n\n [part='toggle'] {\n display: none;\n align-items: center;\n justify-content: center;\n padding: var(--hx-space-2, 0.5rem);\n background: transparent;\n border: none;\n border-radius: var(--hx-nav-border-radius, var(--hx-border-radius-sm, 0.25rem));\n color: var(--hx-nav-color, var(--hx-color-neutral-100, #ebeee9));\n cursor: pointer;\n transition: background-color var(--hx-transition-fast, 150ms) ease;\n line-height: 0;\n }\n\n [part='toggle']:hover {\n background-color: var(--hx-nav-link-hover-bg, var(--hx-color-neutral-700, #313e4b));\n }\n\n [part='toggle']:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-nav-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Navigation List ─── */\n\n [part='list'] {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n list-style: none;\n margin: 0;\n padding: 0;\n gap: var(--hx-space-1, 0.25rem);\n align-items: center;\n }\n\n /* ─── Nav Item ─── */\n\n [part='item'] {\n position: relative;\n }\n\n /* ─── Nav Link / Button ─── */\n\n .nav__link {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n padding: var(--hx-nav-item-padding, var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem));\n color: var(--hx-nav-link-color, var(--hx-color-neutral-100, #ebeee9));\n text-decoration: none;\n border-radius: var(--hx-nav-border-radius, var(--hx-border-radius-sm, 0.25rem));\n border: none;\n background: transparent;\n cursor: pointer;\n font-family: inherit;\n font-size: inherit;\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-normal, 1.5);\n white-space: nowrap;\n transition:\n background-color var(--hx-transition-fast, 150ms) ease,\n color var(--hx-transition-fast, 150ms) ease;\n }\n\n .nav__link:hover {\n background-color: var(--hx-nav-link-hover-bg, var(--hx-color-neutral-700, #313e4b));\n color: var(--hx-nav-link-hover-color, var(--hx-color-neutral-0, #ffffff));\n }\n\n .nav__link:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-nav-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .nav__link--active {\n background-color: var(--hx-nav-link-active-bg, var(--hx-color-primary-600, #0f7078));\n color: var(--hx-nav-link-active-color, var(--hx-color-neutral-0, #ffffff));\n }\n\n /* ─── Chevron Icon ─── */\n\n .nav__chevron {\n transition: transform var(--hx-transition-normal, 200ms) ease;\n flex-shrink: 0;\n }\n\n .nav__link--expanded .nav__chevron {\n transform: rotate(180deg);\n }\n\n /* ─── Submenu ─── */\n\n .nav__submenu {\n position: absolute;\n top: calc(100% + var(--hx-space-1, 0.25rem));\n left: 0;\n min-width: var(--hx-nav-submenu-min-width, 12rem);\n list-style: none;\n margin: 0;\n padding: var(--hx-space-1, 0.25rem) 0;\n background-color: var(--hx-nav-submenu-bg, var(--hx-color-neutral-800, #202b39));\n border-radius: var(--hx-border-radius-md, 0.375rem);\n box-shadow: var(\n --hx-nav-shadow,\n var(--hx-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))\n );\n z-index: var(--hx-z-index-dropdown, 1000);\n }\n\n .nav__submenu[hidden] {\n display: none;\n }\n\n .nav__submenu .nav__link {\n display: block;\n width: 100%;\n text-align: start;\n border-radius: 0;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n }\n\n /* ─── Vertical / Sidebar Orientation ─── */\n\n :host([orientation='vertical']) [part='nav'] {\n padding: var(--hx-space-4, 1rem) var(--hx-space-2, 0.5rem);\n }\n\n :host([orientation='vertical']) [part='list'] {\n flex-direction: column;\n align-items: stretch;\n gap: var(--hx-space-1, 0.25rem);\n }\n\n :host([orientation='vertical']) .nav__link {\n width: 100%;\n justify-content: flex-start;\n }\n\n :host([orientation='vertical']) .nav__submenu {\n position: static;\n box-shadow: none;\n border-radius: 0;\n background-color: transparent;\n padding: 0;\n padding-inline-start: var(--hx-space-4, 1rem);\n }\n\n :host([orientation='vertical']) .nav__submenu[hidden] {\n display: none;\n }\n\n :host([orientation='vertical']) .nav__submenu .nav__link {\n padding: var(--hx-space-1-5, 0.375rem) var(--hx-space-3, 0.75rem);\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-nav-link-color, var(--hx-color-neutral-300, #b6bfb9));\n }\n\n /* ─── Mobile Responsive ─── */\n\n @media (max-width: 768px) {\n [part='nav'] {\n display: flex;\n flex-direction: column;\n padding: var(--hx-space-2, 0.5rem);\n }\n\n [part='toggle'] {\n display: inline-flex;\n align-self: flex-end;\n }\n\n [part='list'] {\n display: none;\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n margin-top: var(--hx-space-2, 0.5rem);\n gap: var(--hx-space-1, 0.25rem);\n }\n\n [part='list'].nav__list--open {\n display: flex;\n }\n\n [part='item'] {\n width: 100%;\n }\n\n .nav__link {\n width: 100%;\n justify-content: flex-start;\n }\n\n .nav__submenu {\n position: static;\n box-shadow: none;\n border-radius: 0;\n padding-inline-start: var(--hx-space-4, 1rem);\n background-color: transparent;\n }\n\n .nav__submenu .nav__link {\n padding: var(--hx-space-1-5, 0.375rem) var(--hx-space-3, 0.75rem);\n }\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .nav__link,\n .nav__chevron,\n [part='toggle'] {\n transition: none;\n animation: none;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n [part='nav'] {\n border: 1px solid CanvasText;\n }\n\n .nav__link--active {\n border: 1px solid Highlight;\n }\n\n .nav__submenu {\n border: 1px solid CanvasText;\n }\n }\n`;\n","import { html, nothing, svg } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixNavStyles } from './hx-nav.styles.js';\n\n/** A single navigation item, optionally with nested children. */\nexport interface NavItem {\n /** Display label for the item. */\n label: string;\n /** Href for the item link. Required unless children are provided. */\n href?: string;\n /** Whether this item represents the current page. */\n current?: boolean;\n /** Nested sub-menu items. */\n children?: NavItem[];\n}\n\n/** Layout orientation for the navigation. */\ntype NavOrientation = 'horizontal' | 'vertical';\n\n/**\n * Primary and secondary navigation component.\n * Supports horizontal menu bar and vertical sidebar patterns.\n * Mobile responsive with hamburger toggle.\n *\n * @summary Navigation bar supporting horizontal and vertical layouts with nested submenus.\n *\n * @tag hx-nav\n *\n * @fires {CustomEvent<{item: NavItem}>} hx-nav-select - Dispatched when a nav item is activated.\n *\n * @csspart nav - The nav landmark element.\n * @csspart list - The top-level list element.\n * @csspart item - Each list item wrapper.\n * @csspart link - The anchor or button element inside each item.\n * @csspart toggle - The mobile hamburger toggle button.\n *\n * @cssprop [--hx-nav-bg=var(--hx-color-neutral-900)] - Navigation background color.\n * @cssprop [--hx-nav-color=var(--hx-color-neutral-100)] - Navigation text color.\n * @cssprop [--hx-nav-font-family=var(--hx-font-family-sans)] - Navigation font family.\n * @cssprop [--hx-nav-link-color=var(--hx-color-neutral-100)] - Link text color.\n * @cssprop [--hx-nav-link-hover-bg=var(--hx-color-neutral-700)] - Link hover background.\n * @cssprop [--hx-nav-link-hover-color=var(--hx-color-white)] - Link hover text color.\n * @cssprop [--hx-nav-link-active-bg=var(--hx-color-primary-600)] - Active link background.\n * @cssprop [--hx-nav-link-active-color=var(--hx-color-white)] - Active link text color.\n * @cssprop [--hx-nav-submenu-bg=var(--hx-color-neutral-800)] - Submenu background color.\n * @cssprop [--hx-nav-submenu-min-width=12rem] - Submenu minimum width.\n * @cssprop [--hx-nav-font-size=var(--hx-font-size-sm)] - Navigation font size.\n * @cssprop [--hx-nav-padding=var(--hx-space-2) var(--hx-space-4)] - Navigation padding.\n * @cssprop [--hx-nav-item-padding=var(--hx-space-2) var(--hx-space-3)] - Item padding.\n * @cssprop [--hx-nav-border-radius=var(--hx-border-radius-sm)] - Item border radius.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-nav-focus-ring-color=var(--hx-focus-ring-color)] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-color-primary-600] - Color.\n * @cssprop [--hx-transition-normal] - Transition timing.\n * @cssprop [--hx-color-neutral-800] - Color.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-nav-shadow] - CSS custom property.\n * @cssprop [--hx-shadow-md] - Box shadow.\n * @cssprop [--hx-z-index-dropdown] - Z-index layer.\n * @cssprop [--hx-space-1-5] - Spacing token.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-300] - Color.\n */\n@customElement('hx-nav')\nexport class HelixNav extends HelixElement {\n static override styles = [helixNavStyles, forcedColorsInteractive];\n\n // ─── Properties ───\n\n /**\n * Navigation items array.\n * @attr items\n */\n @property({\n type: Array,\n converter: {\n fromAttribute(value: string | null): NavItem[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(value);\n return Array.isArray(parsed) ? (parsed as NavItem[]) : [];\n } catch {\n return [];\n }\n },\n },\n })\n items: NavItem[] = [];\n\n /**\n * Layout orientation: 'horizontal' (menu bar) or 'vertical' (sidebar).\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: NavOrientation = 'horizontal';\n\n /**\n * Accessible label for the nav landmark.\n * @attr label\n */\n @property({ type: String })\n label = 'Main navigation';\n\n /** Accessible label for the navigation toggle button when menu is closed. */\n @property({ type: String, attribute: 'label-open-menu' })\n labelOpenMenu = 'Open navigation menu';\n\n /** Accessible label for the navigation toggle button when menu is open. */\n @property({ type: String, attribute: 'label-close-menu' })\n labelCloseMenu = 'Close navigation menu';\n\n // ─── State ───\n\n /**\n * Tracks whether the mobile navigation menu is currently expanded.\n * @internal\n */\n @state() private _mobileOpen = false;\n /**\n * Index of the currently expanded top-level nav item with a submenu, or null if none is expanded.\n * @internal\n */\n @state() private _expandedIndex: number | null = null;\n\n // ─── Private: bound event handler reference ───\n\n /**\n * Stable bound reference to the outside-click handler, stored for addEventListener/removeEventListener symmetry.\n * @internal\n */\n private _boundOutsideClick: (e: MouseEvent) => void = this._handleOutsideClick.bind(this);\n\n /**\n * Stable bound reference to the focusout handler, stored for addEventListener/removeEventListener symmetry.\n * @internal\n */\n private _boundFocusout: (e: FocusEvent) => void = this._handleFocusout.bind(this);\n\n /**\n * Sanitizes a URL to prevent XSS via javascript: or data: URIs.\n * Only allows http:, https:, relative paths, and fragment-only links.\n */\n /** @internal */\n private _sanitizeHref(href: string | undefined): string {\n if (!href || href === '#') return '#';\n // Allow relative paths, fragments, and http(s)\n if (\n href.startsWith('/') ||\n href.startsWith('./') ||\n href.startsWith('../') ||\n href.startsWith('#')\n ) {\n return href;\n }\n if (typeof window === 'undefined') return href;\n try {\n const url = new URL(href, window.location.href);\n if (url.protocol === 'http:' || url.protocol === 'https:') {\n return href;\n }\n } catch {\n // Invalid URL — fall through to safe default\n }\n return '#';\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleToggle(): void {\n this._mobileOpen = !this._mobileOpen;\n if (!this._mobileOpen) {\n this._expandedIndex = null;\n }\n }\n\n /** @internal */\n private _handleItemClick(item: NavItem, index: number, e: Event): void {\n e.preventDefault();\n if (item.children?.length) {\n this._expandedIndex = this._expandedIndex === index ? null : index;\n } else {\n this._mobileOpen = false;\n this._expandedIndex = null;\n this.dispatchEvent(\n new CustomEvent<{ item: NavItem }>('hx-nav-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n }),\n );\n }\n }\n\n /** @internal */\n private _handleSubItemClick(item: NavItem, e: Event): void {\n e.preventDefault();\n this._mobileOpen = false;\n this._expandedIndex = null;\n this.dispatchEvent(\n new CustomEvent<{ item: NavItem }>('hx-nav-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n }),\n );\n }\n\n /** @internal */\n private _handleKeydown(e: KeyboardEvent, index: number, item: NavItem): void {\n const items = this.shadowRoot?.querySelectorAll<HTMLElement>(\n '[part=\"list\"] > [part=\"item\"] > [part=\"link\"]',\n );\n if (!items) return;\n const itemsArr = Array.from(items);\n const current = itemsArr[index];\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowDown': {\n e.preventDefault();\n if (item.children?.length && e.key === 'ArrowDown' && this.orientation === 'horizontal') {\n // open submenu and focus first item\n this._expandedIndex = index;\n void this.updateComplete.then(() => {\n const firstSub = this.shadowRoot?.querySelector<HTMLElement>(\n `.nav__submenu [part=\"link\"]`,\n );\n firstSub?.focus();\n });\n } else {\n const next = itemsArr[index + 1] ?? itemsArr[0];\n next?.focus();\n }\n break;\n }\n case 'ArrowLeft':\n case 'ArrowUp': {\n e.preventDefault();\n const prev = itemsArr[index - 1] ?? itemsArr[itemsArr.length - 1];\n prev?.focus();\n break;\n }\n case 'Home': {\n e.preventDefault();\n itemsArr[0]?.focus();\n break;\n }\n case 'End': {\n e.preventDefault();\n itemsArr[itemsArr.length - 1]?.focus();\n break;\n }\n case 'Escape': {\n this._expandedIndex = null;\n current?.focus();\n break;\n }\n case 'Enter':\n case ' ': {\n if (item.children?.length) {\n e.preventDefault();\n const wasExpanded = this._expandedIndex === index;\n this._expandedIndex = wasExpanded ? null : index;\n if (!wasExpanded) {\n void this.updateComplete.then(() => {\n const firstSub = this.shadowRoot?.querySelector<HTMLElement>(\n `.nav__submenu:not([hidden]) [part=\"link\"]`,\n );\n firstSub?.focus();\n });\n }\n }\n break;\n }\n }\n }\n\n /** @internal */\n private _handleSubKeydown(e: KeyboardEvent, parentIndex: number): void {\n const subItems = this.shadowRoot?.querySelectorAll<HTMLElement>(\n `.nav__submenu:not([hidden]) [part=\"link\"]`,\n );\n if (!subItems) return;\n const arr = Array.from(subItems);\n const focused = (e.currentTarget ?? e.target) as HTMLElement;\n const currentIdx = arr.indexOf(focused);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = arr[currentIdx + 1] ?? arr[0];\n next?.focus();\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = arr[currentIdx - 1] ?? arr[arr.length - 1];\n prev?.focus();\n break;\n }\n case 'Escape': {\n e.preventDefault();\n this._expandedIndex = null;\n const parentLinks = this.shadowRoot?.querySelectorAll<HTMLElement>(\n '[part=\"list\"] > [part=\"item\"] > [part=\"link\"]',\n );\n parentLinks?.[parentIndex]?.focus();\n break;\n }\n }\n }\n\n /** @internal */\n private _handleOutsideClick(e: MouseEvent): void {\n const path = e.composedPath();\n if (!path.includes(this)) {\n this._expandedIndex = null;\n }\n }\n\n /**\n * hx-nav-008: Close expanded submenu when focus moves outside the component.\n * @internal\n */\n private _handleFocusout(e: FocusEvent): void {\n const relatedTarget = e.relatedTarget as Node | null;\n if (relatedTarget && this.contains(relatedTarget)) return;\n if (relatedTarget && this.shadowRoot?.contains(relatedTarget)) return;\n this._expandedIndex = null;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (typeof document !== 'undefined') {\n document.addEventListener('click', this._boundOutsideClick);\n }\n this.addEventListener('focusout', this._boundFocusout);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._boundOutsideClick);\n this.removeEventListener('focusout', this._boundFocusout);\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderHamburgerIcon() {\n return html`<svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n ${this._mobileOpen\n ? svg`<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>`\n : svg`<line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>`}\n </svg>`;\n }\n\n /** @internal */\n private _renderChevronIcon() {\n return html`<svg\n class=\"nav__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4.5 6L8 9.5 11.5 6\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderSubMenu(children: NavItem[], parentIndex: number, parentLabel: string) {\n const isExpanded = this._expandedIndex === parentIndex;\n return html`\n <ul class=\"nav__submenu\" aria-label=\"${parentLabel} submenu\" ?hidden=${!isExpanded}>\n ${children.map(\n (child) => html`\n <li class=\"nav__submenu-item\">\n <a\n part=\"link\"\n href=${this._sanitizeHref(child.href)}\n class=${classMap({\n nav__link: true,\n 'nav__link--active': !!child.current,\n })}\n aria-current=${child.current ? 'page' : nothing}\n @click=${(e: Event) => this._handleSubItemClick(child, e)}\n @keydown=${(e: KeyboardEvent) => this._handleSubKeydown(e, parentIndex)}\n >\n ${child.label}\n </a>\n </li>\n `,\n )}\n </ul>\n `;\n }\n\n /** @internal */\n private _renderItem(item: NavItem, index: number) {\n const hasChildren = !!item.children?.length;\n const isExpanded = this._expandedIndex === index;\n const hasCurrentChild = hasChildren && !!item.children?.some((child) => child.current);\n\n const linkClasses = {\n nav__link: true,\n 'nav__link--active': !!item.current || hasCurrentChild,\n 'nav__link--has-submenu': hasChildren,\n 'nav__link--expanded': isExpanded,\n };\n\n const content = hasChildren\n ? html`\n <button\n part=\"link\"\n class=${classMap(linkClasses)}\n aria-expanded=${isExpanded ? 'true' : 'false'}\n aria-current=${hasCurrentChild ? 'true' : nothing}\n @click=${(e: Event) => this._handleItemClick(item, index, e)}\n @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, index, item)}\n >\n ${item.label} ${this._renderChevronIcon()}\n </button>\n ${this._renderSubMenu(item.children ?? [], index, item.label)}\n `\n : html`\n <a\n part=\"link\"\n href=${this._sanitizeHref(item.href)}\n class=${classMap(linkClasses)}\n aria-current=${item.current ? 'page' : nothing}\n @click=${(e: Event) => this._handleItemClick(item, index, e)}\n @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, index, item)}\n >\n ${item.label}\n </a>\n `;\n\n return html` <li part=\"item\" class=\"nav__item\">${content}</li> `;\n }\n\n // ─── Render ───\n\n override render() {\n const listClasses = {\n nav__list: true,\n 'nav__list--open': this._mobileOpen,\n };\n\n return html`\n <nav part=\"nav\" aria-label=${this.label}>\n <button\n part=\"toggle\"\n class=\"nav__toggle\"\n aria-expanded=${this._mobileOpen ? 'true' : 'false'}\n aria-controls=\"nav-list\"\n aria-label=${this._mobileOpen ? this.labelCloseMenu : this.labelOpenMenu}\n @click=${this._handleToggle}\n >\n ${this._renderHamburgerIcon()}\n </button>\n\n <ul part=\"list\" id=\"nav-list\" class=${classMap(listClasses)} role=\"list\">\n ${repeat(\n this.items,\n (_item, i) => i,\n (item, i) => this._renderItem(item, i),\n )}\n </ul>\n </nav>\n `;\n }\n}\n\n/** Canonical type alias for the hx-nav component. */\nexport type HxNav = HelixNav;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-nav': HelixNav;\n }\n}\n"],"names":["helixNavStyles","css","HelixNav","HelixElement","href","url","item","index","e","_a","items","itemsArr","current","_b","firstSub","next","prev","_c","_d","_e","wasExpanded","parentIndex","subItems","arr","focused","currentIdx","parentLinks","relatedTarget","html","svg","children","parentLabel","isExpanded","child","classMap","nothing","hasChildren","hasCurrentChild","linkClasses","content","listClasses","repeat","_item","i","forcedColorsInteractive","__decorateClass","property","value","parsed","state","customElement"],"mappings":";;;;;;AAEO,MAAMA,IAAiBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACoFvB,IAAMC,IAAN,cAAuBC,EAAa;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA,GAuBL,KAAA,QAAmB,CAAA,GAOnB,KAAA,cAA8B,cAO9B,KAAA,QAAQ,mBAIR,KAAA,gBAAgB,wBAIhB,KAAA,iBAAiB,yBAQR,KAAQ,cAAc,IAKtB,KAAQ,iBAAgC,MAQjD,KAAQ,qBAA8C,KAAK,oBAAoB,KAAK,IAAI,GAMxF,KAAQ,iBAA0C,KAAK,gBAAgB,KAAK,IAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOxE,cAAcC,GAAkC;AACtD,QAAI,CAACA,KAAQA,MAAS,IAAK,QAAO;AAUlC,QAPEA,EAAK,WAAW,GAAG,KACnBA,EAAK,WAAW,IAAI,KACpBA,EAAK,WAAW,KAAK,KACrBA,EAAK,WAAW,GAAG,KAIjB,OAAO,SAAW,IAAa,QAAOA;AAC1C,QAAI;AACF,YAAMC,IAAM,IAAI,IAAID,GAAM,OAAO,SAAS,IAAI;AAC9C,UAAIC,EAAI,aAAa,WAAWA,EAAI,aAAa;AAC/C,eAAOD;AAAA,IAEX,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAKQ,gBAAsB;AAC5B,SAAK,cAAc,CAAC,KAAK,aACpB,KAAK,gBACR,KAAK,iBAAiB;AAAA,EAE1B;AAAA;AAAA,EAGQ,iBAAiBE,GAAeC,GAAeC,GAAgB;;AACrE,IAAAA,EAAE,eAAA,IACEC,IAAAH,EAAK,aAAL,QAAAG,EAAe,SACjB,KAAK,iBAAiB,KAAK,mBAAmBF,IAAQ,OAAOA,KAE7D,KAAK,cAAc,IACnB,KAAK,iBAAiB,MACtB,KAAK;AAAA,MACH,IAAI,YAA+B,iBAAiB;AAAA,QAClD,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,MAAAD,EAAA;AAAA,MAAK,CAChB;AAAA,IAAA;AAAA,EAGP;AAAA;AAAA,EAGQ,oBAAoBA,GAAeE,GAAgB;AACzD,IAAAA,EAAE,eAAA,GACF,KAAK,cAAc,IACnB,KAAK,iBAAiB,MACtB,KAAK;AAAA,MACH,IAAI,YAA+B,iBAAiB;AAAA,QAClD,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,MAAAF,EAAA;AAAA,MAAK,CAChB;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA,EAGQ,eAAe,GAAkBC,GAAeD,GAAqB;;AAC3E,UAAMI,KAAQD,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,MAC7B;AAAA;AAEF,QAAI,CAACC,EAAO;AACZ,UAAMC,IAAW,MAAM,KAAKD,CAAK,GAC3BE,IAAUD,EAASJ,CAAK;AAE9B,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK,aAAa;AAEhB,YADA,EAAE,eAAA,IACEM,IAAAP,EAAK,aAAL,QAAAO,EAAe,UAAU,EAAE,QAAQ,eAAe,KAAK,gBAAgB;AAEzE,eAAK,iBAAiBN,GACjB,KAAK,eAAe,KAAK,MAAM;;AAClC,kBAAMO,KAAWL,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,cAChC;AAAA;AAEF,YAAAK,KAAA,QAAAA,EAAU;AAAA,UACZ,CAAC;AAAA,aACI;AACL,gBAAMC,IAAOJ,EAASJ,IAAQ,CAAC,KAAKI,EAAS,CAAC;AAC9C,UAAAI,KAAA,QAAAA,EAAM;AAAA,QACR;AACA;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK,WAAW;AACd,UAAE,eAAA;AACF,cAAMC,IAAOL,EAASJ,IAAQ,CAAC,KAAKI,EAASA,EAAS,SAAS,CAAC;AAChE,QAAAK,KAAA,QAAAA,EAAM;AACN;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AACX,UAAE,eAAA,IACFC,IAAAN,EAAS,CAAC,MAAV,QAAAM,EAAa;AACb;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,UAAE,eAAA,IACFC,IAAAP,EAASA,EAAS,SAAS,CAAC,MAA5B,QAAAO,EAA+B;AAC/B;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,aAAK,iBAAiB,MACtBN,KAAA,QAAAA,EAAS;AACT;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK,KAAK;AACR,aAAIO,IAAAb,EAAK,aAAL,QAAAa,EAAe,QAAQ;AACzB,YAAE,eAAA;AACF,gBAAMC,IAAc,KAAK,mBAAmBb;AAC5C,eAAK,iBAAiBa,IAAc,OAAOb,GACtCa,KACE,KAAK,eAAe,KAAK,MAAM;;AAClC,kBAAMN,KAAWL,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,cAChC;AAAA;AAEF,YAAAK,KAAA,QAAAA,EAAU;AAAA,UACZ,CAAC;AAAA,QAEL;AACA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGQ,kBAAkB,GAAkBO,GAA2B;;AACrE,UAAMC,KAAWb,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,MAChC;AAAA;AAEF,QAAI,CAACa,EAAU;AACf,UAAMC,IAAM,MAAM,KAAKD,CAAQ,GACzBE,IAAW,EAAE,iBAAiB,EAAE,QAChCC,IAAaF,EAAI,QAAQC,CAAO;AAEtC,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK,aAAa;AAChB,UAAE,eAAA;AACF,cAAMT,IAAOQ,EAAIE,IAAa,CAAC,KAAKF,EAAI,CAAC;AACzC,QAAAR,KAAA,QAAAA,EAAM;AACN;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,UAAE,eAAA;AACF,cAAMC,IAAOO,EAAIE,IAAa,CAAC,KAAKF,EAAIA,EAAI,SAAS,CAAC;AACtD,QAAAP,KAAA,QAAAA,EAAM;AACN;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,UAAE,eAAA,GACF,KAAK,iBAAiB;AACtB,cAAMU,KAAcb,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,UACnC;AAAA;AAEF,SAAAI,IAAAS,KAAA,gBAAAA,EAAcL,OAAd,QAAAJ,EAA4B;AAC5B;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGQ,oBAAoB,GAAqB;AAE/C,IADa,EAAE,aAAA,EACL,SAAS,IAAI,MACrB,KAAK,iBAAiB;AAAA,EAE1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgB,GAAqB;;AAC3C,UAAMU,IAAgB,EAAE;AACxB,IAAIA,KAAiB,KAAK,SAASA,CAAa,KAC5CA,OAAiBlB,IAAA,KAAK,eAAL,QAAAA,EAAiB,SAASkB,QAC/C,KAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA,EAIS,oBAA0B;AACjC,UAAM,kBAAA,GACF,OAAO,WAAa,OACtB,SAAS,iBAAiB,SAAS,KAAK,kBAAkB,GAE5D,KAAK,iBAAiB,YAAY,KAAK,cAAc;AAAA,EACvD;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA,GACN,SAAS,oBAAoB,SAAS,KAAK,kBAAkB,GAC7D,KAAK,oBAAoB,YAAY,KAAK,cAAc;AAAA,EAC1D;AAAA;AAAA;AAAA,EAKQ,uBAAuB;AAC7B,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAUH,KAAK,cACHC;AAAA,2DAEAA;AAAA;AAAA,yDAE+C;AAAA;AAAA,EAEvD;AAAA;AAAA,EAGQ,qBAAqB;AAC3B,WAAOD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBT;AAAA;AAAA,EAGQ,eAAeE,GAAqBT,GAAqBU,GAAqB;AACpF,UAAMC,IAAa,KAAK,mBAAmBX;AAC3C,WAAOO;AAAA,6CACkCG,CAAW,qBAAqB,CAACC,CAAU;AAAA,UAC9EF,EAAS;AAAA,MACT,CAACG,MAAUL;AAAA;AAAA;AAAA;AAAA,uBAIE,KAAK,cAAcK,EAAM,IAAI,CAAC;AAAA,wBAC7BC,EAAS;AAAA,QACf,WAAW;AAAA,QACX,qBAAqB,CAAC,CAACD,EAAM;AAAA,MAAA,CAC9B,CAAC;AAAA,+BACaA,EAAM,UAAU,SAASE,CAAO;AAAA,yBACtC,CAAC3B,MAAa,KAAK,oBAAoByB,GAAOzB,CAAC,CAAC;AAAA,2BAC9C,CAACA,MAAqB,KAAK,kBAAkBA,GAAGa,CAAW,CAAC;AAAA;AAAA,kBAErEY,EAAM,KAAK;AAAA;AAAA;AAAA;AAAA,IAAA,CAIpB;AAAA;AAAA;AAAA,EAGP;AAAA;AAAA,EAGQ,YAAY3B,GAAeC,GAAe;;AAChD,UAAM6B,IAAc,CAAC,GAAC3B,IAAAH,EAAK,aAAL,QAAAG,EAAe,SAC/BuB,IAAa,KAAK,mBAAmBzB,GACrC8B,IAAkBD,KAAe,CAAC,GAACvB,IAAAP,EAAK,aAAL,QAAAO,EAAe,KAAK,CAACoB,MAAUA,EAAM,WAExEK,IAAc;AAAA,MAClB,WAAW;AAAA,MACX,qBAAqB,CAAC,CAAChC,EAAK,WAAW+B;AAAA,MACvC,0BAA0BD;AAAA,MAC1B,uBAAuBJ;AAAA,IAAA,GAGnBO,IAAUH,IACZR;AAAA;AAAA;AAAA,oBAGYM,EAASI,CAAW,CAAC;AAAA,4BACbN,IAAa,SAAS,OAAO;AAAA,2BAC9BK,IAAkB,SAASF,CAAO;AAAA,qBACxC,CAAC3B,MAAa,KAAK,iBAAiBF,GAAMC,GAAOC,CAAC,CAAC;AAAA,uBACjD,CAACA,MAAqB,KAAK,eAAeA,GAAGD,GAAOD,CAAI,CAAC;AAAA;AAAA,cAElEA,EAAK,KAAK,IAAI,KAAK,oBAAoB;AAAA;AAAA,YAEzC,KAAK,eAAeA,EAAK,YAAY,CAAA,GAAIC,GAAOD,EAAK,KAAK,CAAC;AAAA,YAE/DsB;AAAA;AAAA;AAAA,mBAGW,KAAK,cAActB,EAAK,IAAI,CAAC;AAAA,oBAC5B4B,EAASI,CAAW,CAAC;AAAA,2BACdhC,EAAK,UAAU,SAAS6B,CAAO;AAAA,qBACrC,CAAC3B,MAAa,KAAK,iBAAiBF,GAAMC,GAAOC,CAAC,CAAC;AAAA,uBACjD,CAACA,MAAqB,KAAK,eAAeA,GAAGD,GAAOD,CAAI,CAAC;AAAA;AAAA,cAElEA,EAAK,KAAK;AAAA;AAAA;AAIpB,WAAOsB,uCAA0CW,CAAO;AAAA,EAC1D;AAAA;AAAA,EAIS,SAAS;AAChB,UAAMC,IAAc;AAAA,MAClB,WAAW;AAAA,MACX,mBAAmB,KAAK;AAAA,IAAA;AAG1B,WAAOZ;AAAA,mCACwB,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,0BAInB,KAAK,cAAc,SAAS,OAAO;AAAA;AAAA,uBAEtC,KAAK,cAAc,KAAK,iBAAiB,KAAK,aAAa;AAAA,mBAC/D,KAAK,aAAa;AAAA;AAAA,YAEzB,KAAK,sBAAsB;AAAA;AAAA;AAAA,8CAGOM,EAASM,CAAW,CAAC;AAAA,YACvDC;AAAA,MACA,KAAK;AAAA,MACL,CAACC,GAAOC,MAAMA;AAAA,MACd,CAACrC,GAAMqC,MAAM,KAAK,YAAYrC,GAAMqC,CAAC;AAAA,IAAA,CACtC;AAAA;AAAA;AAAA;AAAA,EAIT;AACF;AA9aazC,EACK,SAAS,CAACF,GAAgB4C,CAAuB;AAsBjEC,EAAA;AAAA,EAdCC,EAAS;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,MACT,cAAcC,GAAiC;AAC7C,YAAI,CAACA,EAAO,QAAO,CAAA;AACnB,YAAI;AACF,gBAAMC,IAAkB,KAAK,MAAMD,CAAK;AACxC,iBAAO,MAAM,QAAQC,CAAM,IAAKA,IAAuB,CAAA;AAAA,QACzD,QAAQ;AACN,iBAAO,CAAA;AAAA,QACT;AAAA,MACF;AAAA,IAAA;AAAA,EACF,CACD;AAAA,GAtBU9C,EAuBX,WAAA,SAAA,CAAA;AAOA2C,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA7B9B5C,EA8BX,WAAA,eAAA,CAAA;AAOA2C,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GApCf5C,EAqCX,WAAA,SAAA,CAAA;AAIA2C,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,mBAAmB;AAAA,GAxC7C5C,EAyCX,WAAA,iBAAA,CAAA;AAIA2C,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,oBAAoB;AAAA,GA5C9C5C,EA6CX,WAAA,kBAAA,CAAA;AAQiB2C,EAAA;AAAA,EAAhBI,EAAA;AAAM,GArDI/C,EAqDM,WAAA,eAAA,CAAA;AAKA2C,EAAA;AAAA,EAAhBI,EAAA;AAAM,GA1DI/C,EA0DM,WAAA,kBAAA,CAAA;AA1DNA,IAAN2C,EAAA;AAAA,EADNK,EAAc,QAAQ;AAAA,GACVhD,CAAA;"}