@helixui/library 2.1.2-next.51 → 2.1.2-next.53

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 (477) hide show
  1. package/custom-elements.json +522 -466
  2. package/dist/base/helix-element.d.ts.map +1 -1
  3. package/dist/components/hx-accordion/hx-accordion-item.d.ts +0 -2
  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/hx-accordion.styles.d.ts.map +1 -1
  7. package/dist/components/hx-accordion/index.js +1 -1
  8. package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
  9. package/dist/components/hx-alert/index.js +1 -1
  10. package/dist/components/hx-badge/hx-badge.styles.d.ts.map +1 -1
  11. package/dist/components/hx-badge/index.js +1 -1
  12. package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -1
  13. package/dist/components/hx-banner/index.js +1 -1
  14. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts.map +1 -1
  15. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
  16. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +0 -7
  17. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
  18. package/dist/components/hx-breadcrumb/index.js +1 -1
  19. package/dist/components/hx-button/hx-button.d.ts +9 -9
  20. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  21. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  22. package/dist/components/hx-button/index.js +1 -1
  23. package/dist/components/hx-button-group/hx-button-group.d.ts +1 -4
  24. package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
  25. package/dist/components/hx-button-group/index.js +1 -1
  26. package/dist/components/hx-card/hx-card.d.ts +16 -0
  27. package/dist/components/hx-card/hx-card.d.ts.map +1 -1
  28. package/dist/components/hx-card/hx-card.styles.d.ts.map +1 -1
  29. package/dist/components/hx-card/index.js +1 -1
  30. package/dist/components/hx-carousel/hx-carousel.d.ts.map +1 -1
  31. package/dist/components/hx-carousel/hx-carousel.styles.d.ts.map +1 -1
  32. package/dist/components/hx-carousel/index.js +1 -1
  33. package/dist/components/hx-checkbox/hx-checkbox.d.ts +8 -0
  34. package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
  35. package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
  36. package/dist/components/hx-checkbox/index.js +1 -1
  37. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +6 -8
  38. package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
  39. package/dist/components/hx-checkbox-group/hx-checkbox-group.styles.d.ts.map +1 -1
  40. package/dist/components/hx-checkbox-group/index.js +1 -1
  41. package/dist/components/hx-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
  42. package/dist/components/hx-clinical-status/index.js +1 -1
  43. package/dist/components/hx-code-snippet/hx-code-snippet.styles.d.ts.map +1 -1
  44. package/dist/components/hx-code-snippet/index.js +1 -1
  45. package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
  46. package/dist/components/hx-color-picker/index.js +1 -1
  47. package/dist/components/hx-combobox/hx-combobox.d.ts +20 -14
  48. package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
  49. package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
  50. package/dist/components/hx-combobox/index.js +1 -1
  51. package/dist/components/hx-copy-button/hx-copy-button.styles.d.ts.map +1 -1
  52. package/dist/components/hx-copy-button/index.js +1 -1
  53. package/dist/components/hx-counter/hx-counter.styles.d.ts.map +1 -1
  54. package/dist/components/hx-counter/index.js +1 -1
  55. package/dist/components/hx-data-table/hx-data-table.d.ts +20 -0
  56. package/dist/components/hx-data-table/hx-data-table.d.ts.map +1 -1
  57. package/dist/components/hx-data-table/hx-data-table.styles.d.ts.map +1 -1
  58. package/dist/components/hx-data-table/index.js +1 -1
  59. package/dist/components/hx-date-picker/hx-date-picker.d.ts +6 -17
  60. package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
  61. package/dist/components/hx-date-picker/index.js +1 -1
  62. package/dist/components/hx-dialog/hx-dialog.d.ts +7 -0
  63. package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
  64. package/dist/components/hx-dialog/hx-dialog.styles.d.ts.map +1 -1
  65. package/dist/components/hx-dialog/index.js +1 -1
  66. package/dist/components/hx-divider/hx-divider.styles.d.ts.map +1 -1
  67. package/dist/components/hx-divider/index.js +1 -1
  68. package/dist/components/hx-drawer/hx-drawer.d.ts +7 -0
  69. package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
  70. package/dist/components/hx-drawer/hx-drawer.styles.d.ts.map +1 -1
  71. package/dist/components/hx-drawer/index.js +1 -1
  72. package/dist/components/hx-dropdown/hx-dropdown.d.ts +8 -5
  73. package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
  74. package/dist/components/hx-dropdown/hx-dropdown.styles.d.ts.map +1 -1
  75. package/dist/components/hx-dropdown/index.js +1 -1
  76. package/dist/components/hx-field/hx-field.d.ts.map +1 -1
  77. package/dist/components/hx-field/hx-field.styles.d.ts.map +1 -1
  78. package/dist/components/hx-field/index.js +1 -1
  79. package/dist/components/hx-field-label/hx-field-label.styles.d.ts.map +1 -1
  80. package/dist/components/hx-field-label/index.js +1 -1
  81. package/dist/components/hx-file-upload/hx-file-upload.d.ts +6 -14
  82. package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
  83. package/dist/components/hx-file-upload/index.js +1 -1
  84. package/dist/components/hx-help-text/hx-help-text.styles.d.ts.map +1 -1
  85. package/dist/components/hx-help-text/index.js +1 -1
  86. package/dist/components/hx-icon/hx-icon.styles.d.ts.map +1 -1
  87. package/dist/components/hx-icon/index.js +1 -1
  88. package/dist/components/hx-icon-button/hx-icon-button.d.ts +10 -14
  89. package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
  90. package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
  91. package/dist/components/hx-icon-button/index.js +1 -1
  92. package/dist/components/hx-image/hx-image.styles.d.ts.map +1 -1
  93. package/dist/components/hx-image/index.js +1 -1
  94. package/dist/components/hx-link/hx-link.styles.d.ts.map +1 -1
  95. package/dist/components/hx-link/index.js +1 -1
  96. package/dist/components/hx-list/index.js +1 -1
  97. package/dist/components/hx-menu/hx-menu-divider.styles.d.ts.map +1 -1
  98. package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
  99. package/dist/components/hx-menu/hx-menu.styles.d.ts.map +1 -1
  100. package/dist/components/hx-menu/index.js +1 -1
  101. package/dist/components/hx-meter/hx-meter.d.ts +0 -2
  102. package/dist/components/hx-meter/hx-meter.d.ts.map +1 -1
  103. package/dist/components/hx-meter/hx-meter.styles.d.ts.map +1 -1
  104. package/dist/components/hx-meter/index.js +1 -1
  105. package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
  106. package/dist/components/hx-nav/index.js +1 -1
  107. package/dist/components/hx-number-input/hx-number-input.d.ts +6 -8
  108. package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
  109. package/dist/components/hx-number-input/hx-number-input.styles.d.ts.map +1 -1
  110. package/dist/components/hx-number-input/index.js +1 -1
  111. package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
  112. package/dist/components/hx-overflow-menu/hx-overflow-menu.styles.d.ts.map +1 -1
  113. package/dist/components/hx-overflow-menu/index.js +1 -1
  114. package/dist/components/hx-patient-banner/hx-patient-banner.styles.d.ts.map +1 -1
  115. package/dist/components/hx-patient-banner/index.js +1 -1
  116. package/dist/components/hx-phi-field/index.js +1 -1
  117. package/dist/components/hx-popover/hx-popover.d.ts +1 -0
  118. package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
  119. package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
  120. package/dist/components/hx-popover/index.js +1 -1
  121. package/dist/components/hx-popup/hx-popup.styles.d.ts.map +1 -1
  122. package/dist/components/hx-popup/index.js +1 -1
  123. package/dist/components/hx-progress-bar/hx-progress-bar.d.ts +0 -2
  124. package/dist/components/hx-progress-bar/hx-progress-bar.d.ts.map +1 -1
  125. package/dist/components/hx-progress-bar/index.js +1 -1
  126. package/dist/components/hx-radio-group/hx-radio-group.d.ts +6 -11
  127. package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
  128. package/dist/components/hx-radio-group/hx-radio-group.styles.d.ts.map +1 -1
  129. package/dist/components/hx-radio-group/hx-radio.d.ts.map +1 -1
  130. package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
  131. package/dist/components/hx-radio-group/index.js +1 -1
  132. package/dist/components/hx-rating/hx-rating.d.ts +6 -11
  133. package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
  134. package/dist/components/hx-rating/hx-rating.styles.d.ts.map +1 -1
  135. package/dist/components/hx-rating/index.js +1 -1
  136. package/dist/components/hx-select/hx-select.d.ts +8 -0
  137. package/dist/components/hx-select/hx-select.d.ts.map +1 -1
  138. package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
  139. package/dist/components/hx-select/index.js +1 -1
  140. package/dist/components/hx-side-nav/hx-nav-item.d.ts +0 -3
  141. package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
  142. package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
  143. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  144. package/dist/components/hx-side-nav/index.js +1 -1
  145. package/dist/components/hx-skeleton/hx-skeleton.styles.d.ts.map +1 -1
  146. package/dist/components/hx-skeleton/index.js +1 -1
  147. package/dist/components/hx-slider/hx-slider.d.ts +9 -9
  148. package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
  149. package/dist/components/hx-slider/index.js +1 -1
  150. package/dist/components/hx-spinner/hx-spinner.styles.d.ts.map +1 -1
  151. package/dist/components/hx-spinner/index.js +1 -1
  152. package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
  153. package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
  154. package/dist/components/hx-split-button/index.js +1 -1
  155. package/dist/components/hx-split-panel/hx-split-panel.styles.d.ts.map +1 -1
  156. package/dist/components/hx-split-panel/index.js +1 -1
  157. package/dist/components/hx-stat/hx-stat.d.ts +2 -2
  158. package/dist/components/hx-stat/hx-stat.d.ts.map +1 -1
  159. package/dist/components/hx-status-indicator/hx-status-indicator.styles.d.ts.map +1 -1
  160. package/dist/components/hx-status-indicator/index.js +1 -1
  161. package/dist/components/hx-steps/hx-step.styles.d.ts.map +1 -1
  162. package/dist/components/hx-steps/index.js +1 -1
  163. package/dist/components/hx-structured-list/hx-structured-list.styles.d.ts.map +1 -1
  164. package/dist/components/hx-structured-list/index.js +1 -1
  165. package/dist/components/hx-switch/hx-switch.d.ts +14 -17
  166. package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
  167. package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
  168. package/dist/components/hx-switch/index.js +1 -1
  169. package/dist/components/hx-table/hx-table.styles.d.ts.map +1 -1
  170. package/dist/components/hx-table/index.js +1 -1
  171. package/dist/components/hx-tabs/hx-tab-panel.styles.d.ts.map +1 -1
  172. package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
  173. package/dist/components/hx-tabs/hx-tabs.d.ts +6 -0
  174. package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
  175. package/dist/components/hx-tabs/hx-tabs.styles.d.ts.map +1 -1
  176. package/dist/components/hx-tabs/index.js +1 -1
  177. package/dist/components/hx-tag/hx-tag.styles.d.ts.map +1 -1
  178. package/dist/components/hx-tag/index.js +1 -1
  179. package/dist/components/hx-text-input/hx-text-input.d.ts +11 -0
  180. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  181. package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
  182. package/dist/components/hx-text-input/index.js +1 -1
  183. package/dist/components/hx-textarea/hx-textarea.d.ts +17 -9
  184. package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
  185. package/dist/components/hx-textarea/hx-textarea.styles.d.ts.map +1 -1
  186. package/dist/components/hx-textarea/index.js +1 -1
  187. package/dist/components/hx-time-picker/hx-time-picker.d.ts +6 -17
  188. package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
  189. package/dist/components/hx-time-picker/index.js +1 -1
  190. package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
  191. package/dist/components/hx-toast/index.js +1 -1
  192. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +6 -13
  193. package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
  194. package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
  195. package/dist/components/hx-toggle-button/index.js +1 -1
  196. package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
  197. package/dist/components/hx-tooltip/hx-tooltip.styles.d.ts.map +1 -1
  198. package/dist/components/hx-tooltip/index.js +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.styles.d.ts.map +1 -1
  202. package/dist/components/hx-tree-view/index.js +1 -1
  203. package/dist/css/helix-all.css +1269 -11
  204. package/dist/css/helix-core.css +137 -1
  205. package/dist/css/helix-data.css +69 -0
  206. package/dist/css/helix-feedback.css +77 -0
  207. package/dist/css/helix-forms.css +627 -3
  208. package/dist/css/helix-layout.css +22 -0
  209. package/dist/css/helix-media.css +24 -0
  210. package/dist/css/helix-navigation.css +110 -0
  211. package/dist/css/helix-overlay.css +87 -0
  212. package/dist/css/helix-utility.css +66 -0
  213. package/dist/css/hx-accordion.css +8 -0
  214. package/dist/css/hx-alert.css +21 -0
  215. package/dist/css/hx-badge.css +16 -0
  216. package/dist/css/hx-banner.css +17 -0
  217. package/dist/css/hx-button.css +4 -1
  218. package/dist/css/hx-card.css +12 -0
  219. package/dist/css/hx-carousel.css +24 -0
  220. package/dist/css/hx-checkbox-group.css +32 -0
  221. package/dist/css/hx-checkbox.css +66 -0
  222. package/dist/css/hx-clinical-status.css +23 -0
  223. package/dist/css/hx-code-snippet.css +22 -0
  224. package/dist/css/hx-color-picker.css +1 -1
  225. package/dist/css/hx-combobox.css +1 -1
  226. package/dist/css/hx-copy-button.css +28 -0
  227. package/dist/css/hx-counter.css +3 -0
  228. package/dist/css/hx-data-table.css +23 -0
  229. package/dist/css/hx-dialog.css +21 -0
  230. package/dist/css/hx-divider.css +8 -0
  231. package/dist/css/hx-drawer.css +21 -0
  232. package/dist/css/hx-dropdown.css +9 -0
  233. package/dist/css/hx-field-label.css +16 -0
  234. package/dist/css/hx-field.css +36 -0
  235. package/dist/css/hx-help-text.css +20 -0
  236. package/dist/css/hx-icon-button.css +27 -0
  237. package/dist/css/hx-icon.css +8 -0
  238. package/dist/css/hx-image.css +8 -0
  239. package/dist/css/hx-link.css +18 -0
  240. package/dist/css/hx-menu.css +9 -0
  241. package/dist/css/hx-meter.css +13 -0
  242. package/dist/css/hx-nav.css +16 -0
  243. package/dist/css/hx-number-input.css +78 -0
  244. package/dist/css/hx-overflow-menu.css +31 -0
  245. package/dist/css/hx-patient-banner.css +20 -0
  246. package/dist/css/hx-phi-field.css +1 -1
  247. package/dist/css/hx-popover.css +12 -0
  248. package/dist/css/hx-popup.css +12 -0
  249. package/dist/css/hx-radio-group.css +32 -0
  250. package/dist/css/hx-rating.css +39 -0
  251. package/dist/css/hx-select.css +82 -0
  252. package/dist/css/hx-side-nav.css +21 -0
  253. package/dist/css/hx-skeleton.css +12 -0
  254. package/dist/css/hx-spinner.css +12 -0
  255. package/dist/css/hx-split-button.css +35 -0
  256. package/dist/css/hx-split-panel.css +14 -0
  257. package/dist/css/hx-status-indicator.css +13 -0
  258. package/dist/css/hx-structured-list.css +16 -0
  259. package/dist/css/hx-switch.css +62 -0
  260. package/dist/css/hx-table.css +8 -0
  261. package/dist/css/hx-tabs.css +12 -0
  262. package/dist/css/hx-tag.css +12 -0
  263. package/dist/css/hx-text-input.css +62 -0
  264. package/dist/css/hx-textarea.css +62 -0
  265. package/dist/css/hx-toast.css +13 -0
  266. package/dist/css/hx-toggle-button.css +38 -1
  267. package/dist/css/hx-tooltip.css +12 -0
  268. package/dist/css/hx-top-nav.css +21 -0
  269. package/dist/css/index.css +1 -1
  270. package/dist/css/manifest.json +5 -3
  271. package/dist/index.js +67 -67
  272. package/dist/mixins/aria-delegation.d.ts +3 -1
  273. package/dist/mixins/aria-delegation.d.ts.map +1 -1
  274. package/dist/mixins/index.d.ts +1 -1
  275. package/dist/mixins/index.d.ts.map +1 -1
  276. package/dist/shared/{aria-delegation-CBP9eQ0M.js → aria-delegation-Doq6RRUy.js} +6 -6
  277. package/dist/shared/aria-delegation-Doq6RRUy.js.map +1 -0
  278. package/dist/shared/{helix-element-CZvaIEQP.js → helix-element-BJh1Ffvi.js} +18 -21
  279. package/dist/shared/{helix-element-CZvaIEQP.js.map → helix-element-BJh1Ffvi.js.map} +1 -1
  280. package/dist/shared/{hx-accordion-CpfO0YQo.js → hx-accordion-SlwR2C6S.js} +109 -62
  281. package/dist/shared/hx-accordion-SlwR2C6S.js.map +1 -0
  282. package/dist/shared/{hx-alert-CHOjTBds.js → hx-alert-DdlSyJGk.js} +22 -1
  283. package/dist/shared/hx-alert-DdlSyJGk.js.map +1 -0
  284. package/dist/shared/{hx-badge-RPzd-t5l.js → hx-badge-B_PzGlUo.js} +17 -1
  285. package/dist/shared/hx-badge-B_PzGlUo.js.map +1 -0
  286. package/dist/shared/{hx-banner-B-WEDiq7.js → hx-banner-D8AxkCfc.js} +30 -13
  287. package/dist/shared/hx-banner-D8AxkCfc.js.map +1 -0
  288. package/dist/shared/{hx-breadcrumb-item-jLAKK038.js → hx-breadcrumb-item-BCUIvpYX.js} +32 -15
  289. package/dist/shared/hx-breadcrumb-item-BCUIvpYX.js.map +1 -0
  290. package/dist/shared/{hx-button-DoN8jjQT.js → hx-button-BzqsDHmZ.js} +15 -16
  291. package/dist/shared/hx-button-BzqsDHmZ.js.map +1 -0
  292. package/dist/shared/{hx-button-group-BXlMQTt_.js → hx-button-group-a5Pb_9fU.js} +8 -9
  293. package/dist/shared/{hx-button-group-BXlMQTt_.js.map → hx-button-group-a5Pb_9fU.js.map} +1 -1
  294. package/dist/shared/{hx-card-BgXZXDuc.js → hx-card-DYlaxQy0.js} +59 -33
  295. package/dist/shared/hx-card-DYlaxQy0.js.map +1 -0
  296. package/dist/shared/{hx-carousel-item-Dwt9Pphz.js → hx-carousel-item-KQfCekKF.js} +45 -19
  297. package/dist/shared/hx-carousel-item-KQfCekKF.js.map +1 -0
  298. package/dist/shared/{hx-checkbox-C82GjRXe.js → hx-checkbox-DyDbR1B9.js} +97 -31
  299. package/dist/shared/hx-checkbox-DyDbR1B9.js.map +1 -0
  300. package/dist/shared/{hx-checkbox-group-DThZeN5d.js → hx-checkbox-group-C8TaFqy0.js} +75 -40
  301. package/dist/shared/hx-checkbox-group-C8TaFqy0.js.map +1 -0
  302. package/dist/shared/{hx-clinical-status-BjtT5c0M.js → hx-clinical-status-dDyk5oj1.js} +53 -30
  303. package/dist/shared/hx-clinical-status-dDyk5oj1.js.map +1 -0
  304. package/dist/shared/{hx-code-snippet-DcVENSuC.js → hx-code-snippet-DasrRF9k.js} +27 -5
  305. package/dist/shared/hx-code-snippet-DasrRF9k.js.map +1 -0
  306. package/dist/shared/{hx-color-picker-C6EIuS9t.js → hx-color-picker-zv6wtok4.js} +81 -81
  307. package/dist/shared/hx-color-picker-zv6wtok4.js.map +1 -0
  308. package/dist/shared/{hx-combobox-BJ4lQocO.js → hx-combobox-C-DVLFpu.js} +36 -45
  309. package/dist/shared/hx-combobox-C-DVLFpu.js.map +1 -0
  310. package/dist/shared/{hx-copy-button-BoM0WsMd.js → hx-copy-button-DikpbhWY.js} +54 -26
  311. package/dist/shared/hx-copy-button-DikpbhWY.js.map +1 -0
  312. package/dist/shared/{hx-counter-B5NgKlw4.js → hx-counter-_m4cq45V.js} +21 -18
  313. package/dist/shared/hx-counter-_m4cq45V.js.map +1 -0
  314. package/dist/shared/{hx-data-table-D5Ne-goy.js → hx-data-table-609C-e9w.js} +215 -150
  315. package/dist/shared/hx-data-table-609C-e9w.js.map +1 -0
  316. package/dist/shared/{hx-date-picker-Cd3I3WkX.js → hx-date-picker-Bh8410Sf.js} +26 -35
  317. package/dist/shared/hx-date-picker-Bh8410Sf.js.map +1 -0
  318. package/dist/shared/{hx-dialog-D4ubstxx.js → hx-dialog-D_DeqcNS.js} +46 -25
  319. package/dist/shared/hx-dialog-D_DeqcNS.js.map +1 -0
  320. package/dist/shared/{hx-divider-BBtOLHRP.js → hx-divider-lfOMElo2.js} +18 -10
  321. package/dist/shared/hx-divider-lfOMElo2.js.map +1 -0
  322. package/dist/shared/{hx-drawer--WDLuWtS.js → hx-drawer-NleCbKuN.js} +95 -60
  323. package/dist/shared/hx-drawer-NleCbKuN.js.map +1 -0
  324. package/dist/shared/{hx-dropdown-n5-XSmiV.js → hx-dropdown-CA9WYdhm.js} +37 -27
  325. package/dist/shared/hx-dropdown-CA9WYdhm.js.map +1 -0
  326. package/dist/shared/{hx-field-CwT9tki1.js → hx-field-Duiib9Bj.js} +48 -12
  327. package/dist/shared/hx-field-Duiib9Bj.js.map +1 -0
  328. package/dist/shared/{hx-field-label-CcOK9VU3.js → hx-field-label-Dud-psvE.js} +37 -21
  329. package/dist/shared/hx-field-label-Dud-psvE.js.map +1 -0
  330. package/dist/shared/{hx-file-upload-Di_vpQaG.js → hx-file-upload-CmCCAvej.js} +24 -33
  331. package/dist/shared/hx-file-upload-CmCCAvej.js.map +1 -0
  332. package/dist/shared/{hx-help-text-Bmb80bP4.js → hx-help-text-DARi-Pfp.js} +37 -17
  333. package/dist/shared/hx-help-text-DARi-Pfp.js.map +1 -0
  334. package/dist/shared/{hx-icon-button-CJuy9xbw.js → hx-icon-button-BcZtVVtH.js} +58 -41
  335. package/dist/shared/hx-icon-button-BcZtVVtH.js.map +1 -0
  336. package/dist/shared/{hx-icon-BKHs3OLu.js → hx-icon-jWcGmn66.js} +9 -1
  337. package/dist/shared/hx-icon-jWcGmn66.js.map +1 -0
  338. package/dist/shared/{hx-image-ztiXumZB.js → hx-image-DOjPp-K5.js} +28 -20
  339. package/dist/shared/hx-image-DOjPp-K5.js.map +1 -0
  340. package/dist/shared/{hx-link-CN7AvGOW.js → hx-link-DCBct0f4.js} +44 -26
  341. package/dist/shared/hx-link-DCBct0f4.js.map +1 -0
  342. package/dist/shared/{hx-list-CnDK30Yk.js → hx-list-Dnei26t4.js} +16 -16
  343. package/dist/shared/{hx-list-CnDK30Yk.js.map → hx-list-Dnei26t4.js.map} +1 -1
  344. package/dist/shared/{hx-menu-divider-DRT8yHRZ.js → hx-menu-divider-DVWER7iT.js} +93 -50
  345. package/dist/shared/hx-menu-divider-DVWER7iT.js.map +1 -0
  346. package/dist/shared/{hx-meter-BcVC9yrt.js → hx-meter-ChZdWNF2.js} +42 -28
  347. package/dist/shared/hx-meter-ChZdWNF2.js.map +1 -0
  348. package/dist/shared/{hx-nav-l0Rp7WPW.js → hx-nav-CHX1JOWB.js} +28 -12
  349. package/dist/shared/hx-nav-CHX1JOWB.js.map +1 -0
  350. package/dist/shared/{hx-nav-item-CJN4VDrf.js → hx-nav-item-CRAESq9s.js} +56 -22
  351. package/dist/shared/hx-nav-item-CRAESq9s.js.map +1 -0
  352. package/dist/shared/{hx-number-input-0Waw7Z7u.js → hx-number-input-Cm682AVP.js} +154 -72
  353. package/dist/shared/hx-number-input-Cm682AVP.js.map +1 -0
  354. package/dist/shared/{hx-overflow-menu-DElwFSCd.js → hx-overflow-menu-BDl6QfUD.js} +52 -19
  355. package/dist/shared/hx-overflow-menu-BDl6QfUD.js.map +1 -0
  356. package/dist/shared/{hx-patient-banner-BKiN7nIE.js → hx-patient-banner-B4IjHeTx.js} +54 -34
  357. package/dist/shared/hx-patient-banner-B4IjHeTx.js.map +1 -0
  358. package/dist/shared/{hx-phi-field-Df06K0J3.js → hx-phi-field-DD1qcBSO.js} +2 -2
  359. package/dist/shared/hx-phi-field-DD1qcBSO.js.map +1 -0
  360. package/dist/shared/{hx-popover-CydNuVkT.js → hx-popover-ZGRFgBbx.js} +29 -15
  361. package/dist/shared/hx-popover-ZGRFgBbx.js.map +1 -0
  362. package/dist/shared/{hx-popup-DbzezTOd.js → hx-popup-Cc4qz89i.js} +24 -12
  363. package/dist/shared/hx-popup-Cc4qz89i.js.map +1 -0
  364. package/dist/shared/{hx-progress-bar-Cm0VihTN.js → hx-progress-bar-BY1uE6bN.js} +17 -16
  365. package/dist/shared/hx-progress-bar-BY1uE6bN.js.map +1 -0
  366. package/dist/shared/{hx-radio-f8c5ggHG.js → hx-radio-YEEsbUPN.js} +139 -54
  367. package/dist/shared/hx-radio-YEEsbUPN.js.map +1 -0
  368. package/dist/shared/{hx-rating-qRJZXskm.js → hx-rating-DjUJTT0M.js} +54 -17
  369. package/dist/shared/hx-rating-DjUJTT0M.js.map +1 -0
  370. package/dist/shared/{hx-select-CgcgsHU5.js → hx-select-DZ7wfcJx.js} +119 -37
  371. package/dist/shared/hx-select-DZ7wfcJx.js.map +1 -0
  372. package/dist/shared/{hx-skeleton-tiYvKO-t.js → hx-skeleton-aqa-gr1S.js} +28 -16
  373. package/dist/shared/hx-skeleton-aqa-gr1S.js.map +1 -0
  374. package/dist/shared/{hx-slider-BvXtvxmN.js → hx-slider-DAilFrR_.js} +28 -25
  375. package/dist/shared/hx-slider-DAilFrR_.js.map +1 -0
  376. package/dist/shared/{hx-spinner-D6nzuGmj.js → hx-spinner-Dw3cRY-9.js} +26 -14
  377. package/dist/shared/hx-spinner-Dw3cRY-9.js.map +1 -0
  378. package/dist/shared/{hx-split-button-CPndTJlC.js → hx-split-button-Dk-zMDDo.js} +51 -14
  379. package/dist/shared/hx-split-button-Dk-zMDDo.js.map +1 -0
  380. package/dist/shared/{hx-split-panel-Dx72NaET.js → hx-split-panel-Kdp4BiLz.js} +15 -1
  381. package/dist/shared/hx-split-panel-Kdp4BiLz.js.map +1 -0
  382. package/dist/shared/hx-stat-DKlyBL_K.js.map +1 -1
  383. package/dist/shared/{hx-status-indicator-ClWpK6zz.js → hx-status-indicator-DWSM0Ctm.js} +30 -17
  384. package/dist/shared/hx-status-indicator-DWSM0Ctm.js.map +1 -0
  385. package/dist/shared/{hx-step-C2Jk4mHa.js → hx-step-CuoOvcI8.js} +52 -18
  386. package/dist/shared/{hx-step-C2Jk4mHa.js.map → hx-step-CuoOvcI8.js.map} +1 -1
  387. package/dist/shared/{hx-structured-list-DKlrv7kS.js → hx-structured-list-CQCD7bCT.js} +21 -5
  388. package/dist/shared/hx-structured-list-CQCD7bCT.js.map +1 -0
  389. package/dist/shared/{hx-switch-BzMN37PV.js → hx-switch-BdxKN9WM.js} +89 -32
  390. package/dist/shared/hx-switch-BdxKN9WM.js.map +1 -0
  391. package/dist/shared/{hx-tab-panel-J58zOSjq.js → hx-tab-panel-CwClQoWP.js} +141 -88
  392. package/dist/shared/hx-tab-panel-CwClQoWP.js.map +1 -0
  393. package/dist/shared/{hx-tag-F0ZcYj9b.js → hx-tag-BL5qJJCN.js} +20 -8
  394. package/dist/shared/hx-tag-BL5qJJCN.js.map +1 -0
  395. package/dist/shared/{hx-td-CNCvzBwY.js → hx-td-CzSvVKdp.js} +21 -13
  396. package/dist/shared/hx-td-CzSvVKdp.js.map +1 -0
  397. package/dist/shared/{hx-text-input-Zuodg9s_.js → hx-text-input-BfMrvN9N.js} +110 -48
  398. package/dist/shared/hx-text-input-BfMrvN9N.js.map +1 -0
  399. package/dist/shared/{hx-textarea-BfSJJtA1.js → hx-textarea-C-i_Vam6.js} +108 -47
  400. package/dist/shared/hx-textarea-C-i_Vam6.js.map +1 -0
  401. package/dist/shared/{hx-time-picker-CZvmihHD.js → hx-time-picker-MZyLQPW9.js} +50 -61
  402. package/dist/shared/hx-time-picker-MZyLQPW9.js.map +1 -0
  403. package/dist/shared/{hx-toggle-button-BZUQUULm.js → hx-toggle-button-ClyNYNVI.js} +68 -37
  404. package/dist/shared/hx-toggle-button-ClyNYNVI.js.map +1 -0
  405. package/dist/shared/{hx-tooltip-Ny4i1Idj.js → hx-tooltip-ByWT987R.js} +33 -19
  406. package/dist/shared/hx-tooltip-ByWT987R.js.map +1 -0
  407. package/dist/shared/{hx-top-nav-CC4FW2Hp.js → hx-top-nav-k7hY78kt.js} +35 -14
  408. package/dist/shared/hx-top-nav-k7hY78kt.js.map +1 -0
  409. package/dist/shared/{hx-tree-item-CPQ9dJiK.js → hx-tree-item-D0ZphA45.js} +9 -1
  410. package/dist/shared/hx-tree-item-D0ZphA45.js.map +1 -0
  411. package/dist/shared/{toast-factory-CEMNOt1T.js → toast-factory-Cwd0PihS.js} +49 -36
  412. package/dist/shared/toast-factory-Cwd0PihS.js.map +1 -0
  413. package/package.json +2 -2
  414. package/dist/shared/aria-delegation-CBP9eQ0M.js.map +0 -1
  415. package/dist/shared/hx-accordion-CpfO0YQo.js.map +0 -1
  416. package/dist/shared/hx-alert-CHOjTBds.js.map +0 -1
  417. package/dist/shared/hx-badge-RPzd-t5l.js.map +0 -1
  418. package/dist/shared/hx-banner-B-WEDiq7.js.map +0 -1
  419. package/dist/shared/hx-breadcrumb-item-jLAKK038.js.map +0 -1
  420. package/dist/shared/hx-button-DoN8jjQT.js.map +0 -1
  421. package/dist/shared/hx-card-BgXZXDuc.js.map +0 -1
  422. package/dist/shared/hx-carousel-item-Dwt9Pphz.js.map +0 -1
  423. package/dist/shared/hx-checkbox-C82GjRXe.js.map +0 -1
  424. package/dist/shared/hx-checkbox-group-DThZeN5d.js.map +0 -1
  425. package/dist/shared/hx-clinical-status-BjtT5c0M.js.map +0 -1
  426. package/dist/shared/hx-code-snippet-DcVENSuC.js.map +0 -1
  427. package/dist/shared/hx-color-picker-C6EIuS9t.js.map +0 -1
  428. package/dist/shared/hx-combobox-BJ4lQocO.js.map +0 -1
  429. package/dist/shared/hx-copy-button-BoM0WsMd.js.map +0 -1
  430. package/dist/shared/hx-counter-B5NgKlw4.js.map +0 -1
  431. package/dist/shared/hx-data-table-D5Ne-goy.js.map +0 -1
  432. package/dist/shared/hx-date-picker-Cd3I3WkX.js.map +0 -1
  433. package/dist/shared/hx-dialog-D4ubstxx.js.map +0 -1
  434. package/dist/shared/hx-divider-BBtOLHRP.js.map +0 -1
  435. package/dist/shared/hx-drawer--WDLuWtS.js.map +0 -1
  436. package/dist/shared/hx-dropdown-n5-XSmiV.js.map +0 -1
  437. package/dist/shared/hx-field-CwT9tki1.js.map +0 -1
  438. package/dist/shared/hx-field-label-CcOK9VU3.js.map +0 -1
  439. package/dist/shared/hx-file-upload-Di_vpQaG.js.map +0 -1
  440. package/dist/shared/hx-help-text-Bmb80bP4.js.map +0 -1
  441. package/dist/shared/hx-icon-BKHs3OLu.js.map +0 -1
  442. package/dist/shared/hx-icon-button-CJuy9xbw.js.map +0 -1
  443. package/dist/shared/hx-image-ztiXumZB.js.map +0 -1
  444. package/dist/shared/hx-link-CN7AvGOW.js.map +0 -1
  445. package/dist/shared/hx-menu-divider-DRT8yHRZ.js.map +0 -1
  446. package/dist/shared/hx-meter-BcVC9yrt.js.map +0 -1
  447. package/dist/shared/hx-nav-item-CJN4VDrf.js.map +0 -1
  448. package/dist/shared/hx-nav-l0Rp7WPW.js.map +0 -1
  449. package/dist/shared/hx-number-input-0Waw7Z7u.js.map +0 -1
  450. package/dist/shared/hx-overflow-menu-DElwFSCd.js.map +0 -1
  451. package/dist/shared/hx-patient-banner-BKiN7nIE.js.map +0 -1
  452. package/dist/shared/hx-phi-field-Df06K0J3.js.map +0 -1
  453. package/dist/shared/hx-popover-CydNuVkT.js.map +0 -1
  454. package/dist/shared/hx-popup-DbzezTOd.js.map +0 -1
  455. package/dist/shared/hx-progress-bar-Cm0VihTN.js.map +0 -1
  456. package/dist/shared/hx-radio-f8c5ggHG.js.map +0 -1
  457. package/dist/shared/hx-rating-qRJZXskm.js.map +0 -1
  458. package/dist/shared/hx-select-CgcgsHU5.js.map +0 -1
  459. package/dist/shared/hx-skeleton-tiYvKO-t.js.map +0 -1
  460. package/dist/shared/hx-slider-BvXtvxmN.js.map +0 -1
  461. package/dist/shared/hx-spinner-D6nzuGmj.js.map +0 -1
  462. package/dist/shared/hx-split-button-CPndTJlC.js.map +0 -1
  463. package/dist/shared/hx-split-panel-Dx72NaET.js.map +0 -1
  464. package/dist/shared/hx-status-indicator-ClWpK6zz.js.map +0 -1
  465. package/dist/shared/hx-structured-list-DKlrv7kS.js.map +0 -1
  466. package/dist/shared/hx-switch-BzMN37PV.js.map +0 -1
  467. package/dist/shared/hx-tab-panel-J58zOSjq.js.map +0 -1
  468. package/dist/shared/hx-tag-F0ZcYj9b.js.map +0 -1
  469. package/dist/shared/hx-td-CNCvzBwY.js.map +0 -1
  470. package/dist/shared/hx-text-input-Zuodg9s_.js.map +0 -1
  471. package/dist/shared/hx-textarea-BfSJJtA1.js.map +0 -1
  472. package/dist/shared/hx-time-picker-CZvmihHD.js.map +0 -1
  473. package/dist/shared/hx-toggle-button-BZUQUULm.js.map +0 -1
  474. package/dist/shared/hx-tooltip-Ny4i1Idj.js.map +0 -1
  475. package/dist/shared/hx-top-nav-CC4FW2Hp.js.map +0 -1
  476. package/dist/shared/hx-tree-item-CPQ9dJiK.js.map +0 -1
  477. package/dist/shared/toast-factory-CEMNOt1T.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-time-picker-CZvmihHD.js","sources":["../../src/components/hx-time-picker/hx-time-picker.styles.ts","../../src/components/hx-time-picker/hx-time-picker.ts"],"sourcesContent":["import { css } from 'lit';\n\n// prettier-ignore\nexport const helixTimePickerStyles = css`:host{display:block;position:relative}:host([disabled]){opacity:var(--hx-opacity-disabled, .5);pointer-events:none}*{box-sizing:border-box}.field{display:flex;flex-direction:column;gap:var(--hx-space-1, .25rem);font-family:var(--hx-time-picker-font-family, var(--hx-font-family-sans, sans-serif))}.field__label{display:flex;align-items:baseline;gap:var(--hx-space-1, .25rem);font-size:var(--hx-font-size-sm, .875rem);font-weight:var(--hx-font-weight-medium, 500);color:var(--hx-time-picker-label-color, var(--hx-color-neutral-700));line-height:var(--hx-line-height-normal, 1.5)}.field__required-marker{color:var(--hx-time-picker-error-color, var(--hx-color-error-text, #b91c1c));font-weight:var(--hx-font-weight-bold, 700)}.field__combobox{position:relative;display:flex;align-items:center;border:var(--hx-border-width-thin, 1px) solid var(--hx-time-picker-border-color, var(--hx-color-neutral-300));border-radius:var(--hx-time-picker-border-radius, var(--hx-border-radius-md, .375rem));background-color:var(--hx-time-picker-bg, var(--hx-color-neutral-0));transition:border-color var(--hx-transition-fast, .15s ease),box-shadow var(--hx-transition-fast, .15s ease);overflow:visible}.field__combobox:focus-within{border-color:var(--hx-time-picker-focus-ring-color, var(--hx-focus-ring-color));box-shadow:0 0 0 var(--hx-focus-ring-width, 2px) color-mix(in srgb,var(--hx-time-picker-focus-ring-color, var(--hx-focus-ring-color)) calc(var(--hx-focus-ring-opacity, .25) * 100%),transparent)}.field--error .field__combobox{border-color:var(--hx-time-picker-error-color, var(--hx-color-error-500))}.field--error .field__combobox:focus-within{border-color:var(--hx-time-picker-error-color, var(--hx-color-error-500));box-shadow:0 0 0 var(--hx-focus-ring-width, 2px) color-mix(in srgb,var(--hx-time-picker-error-color, var(--hx-color-error-500)) calc(var(--hx-focus-ring-opacity, .25) * 100%),transparent)}.field__input{flex:1;border:none;outline:none;background:transparent;padding:var(--hx-space-2, .5rem) var(--hx-space-3, .75rem);font-family:inherit;font-size:var(--hx-font-size-md, 1rem);color:var(--hx-time-picker-color, var(--hx-color-neutral-800));line-height:var(--hx-line-height-normal, 1.5);min-height:var(--hx-size-10, 2.5rem);width:100%;cursor:text}.field__input::placeholder{color:var(--hx-color-neutral-400)}.field__input:disabled{cursor:not-allowed}.field__toggle{display:flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0 var(--hx-space-3, .75rem);color:var(--hx-time-picker-chevron-color, var(--hx-color-neutral-500));cursor:pointer;height:100%;min-height:var(--hx-size-10, 2.5rem);flex-shrink:0;border-inline-start:var(--hx-border-width-thin, 1px) solid var(--hx-time-picker-border-color, var(--hx-color-neutral-300))}.field__toggle:focus-visible{outline:var(--hx-focus-ring-width, 2px) solid var(--hx-time-picker-focus-ring-color, var(--hx-focus-ring-color));outline-offset:-2px;border-radius:0 var(--hx-time-picker-border-radius, var(--hx-border-radius-md, .375rem))}.field__listbox{position:absolute;top:calc(100% + var(--hx-space-1, .25rem));inset-inline-start:0;inset-inline-end:0;z-index:var(--hx-z-index-dropdown, 1000);background-color:var(--hx-time-picker-listbox-bg, var(--hx-color-neutral-0));border:var(--hx-border-width-thin, 1px) solid var(--hx-time-picker-border-color, var(--hx-color-neutral-300));border-radius:var(--hx-time-picker-border-radius, var(--hx-border-radius-md, .375rem));box-shadow:var( --hx-time-picker-listbox-shadow, 0 4px 16px color-mix(in srgb, var(--hx-color-neutral-900) 12%, transparent) );max-height:var(--hx-time-picker-listbox-max-height, 16rem);overflow-y:auto;padding:var(--hx-space-1, .25rem) 0;list-style:none;margin:0}@media(prefers-reduced-motion:no-preference){.field__listbox{animation:hx-listbox-enter var(--hx-transition-fast, .15s ease) forwards}}@keyframes hx-listbox-enter{0%{opacity:0;transform:translateY(-.25rem)}to{opacity:1;transform:translateY(0)}}.field__option{display:flex;align-items:center;padding:var(--hx-space-2, .5rem) var(--hx-space-3, .75rem);font-size:var(--hx-font-size-md, 1rem);font-family:inherit;color:var(--hx-time-picker-option-color, var(--hx-color-neutral-800));cursor:pointer;transition:background-color var(--hx-transition-fast, .15s ease);line-height:var(--hx-line-height-normal, 1.5)}.field__option:hover,.field__option--active{background-color:var(--hx-time-picker-option-hover-bg, var(--hx-color-primary-50));color:var(--hx-time-picker-option-hover-color, var(--hx-color-primary-700))}.field__option--selected{background-color:var(--hx-time-picker-option-selected-bg, var(--hx-color-primary-100));color:var(--hx-time-picker-option-selected-color, var(--hx-color-primary-800));font-weight:var(--hx-font-weight-medium, 500)}.field__option--selected.field__option--active{background-color:var(--hx-time-picker-option-selected-bg, var(--hx-color-primary-100))}@media(prefers-reduced-motion:reduce){.field__combobox,.field__option{transition:none}}.field__help-text,.field__error{font-size:var(--hx-font-size-xs, .75rem);line-height:var(--hx-line-height-normal, 1.5)}.field__help-text{color:var(--hx-color-neutral-500)}.field__error{color:var(--hx-time-picker-error-color, var(--hx-color-error-text, #b91c1c))}`;\n","import { LitElement, 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 { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { helixTimePickerStyles } from './hx-time-picker.styles.js';\n\n// ─── Time Slot ───────────────────────────────────────────────────────────────\n\ninterface TimeSlot {\n /** HH:MM in 24-hour format — canonical internal value. */\n value: string;\n /** Display label respecting the component's `format` property. */\n label: string;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" into { hours, minutes }. Returns null when the string is not valid. */\nfunction parseHHMM(raw: string): { hours: number; minutes: number } | null {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(raw.trim());\n if (!match) return null;\n const hours = parseInt(match[1] ?? '0', 10);\n const minutes = parseInt(match[2] ?? '0', 10);\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;\n return { hours, minutes };\n}\n\n/** Format { hours, minutes } as zero-padded \"HH:MM\". */\nfunction toHHMM(hours: number, minutes: number): string {\n return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;\n}\n\n/** Convert a 24-hour HH:MM value to a 12-hour display string (e.g. \"02:30 PM\"). */\nfunction to12h(value: string): string {\n const parsed = parseHHMM(value);\n if (!parsed) return value;\n const { hours, minutes } = parsed;\n const period = hours < 12 ? 'AM' : 'PM';\n const h = hours % 12 === 0 ? 12 : hours % 12;\n return `${String(h).padStart(2, '0')}:${String(minutes).padStart(2, '0')} ${period}`;\n}\n\n/**\n * Generate ordered time slots between `minTime` and `maxTime` (inclusive) at\n * `stepMinutes` intervals. Both bounds are HH:MM strings; defaults fall back\n * to \"00:00\" / \"23:59\".\n */\nfunction generateSlots(\n minTime: string,\n maxTime: string,\n stepMinutes: number,\n format: '12h' | '24h',\n): TimeSlot[] {\n const minParsed = parseHHMM(minTime) ?? { hours: 0, minutes: 0 };\n const maxParsed = parseHHMM(maxTime) ?? { hours: 23, minutes: 59 };\n\n const minTotal = minParsed.hours * 60 + minParsed.minutes;\n const maxTotal = maxParsed.hours * 60 + maxParsed.minutes;\n\n // Guard against degenerate step values\n const step = Math.max(1, Math.round(stepMinutes));\n\n const slots: TimeSlot[] = [];\n for (let t = minTotal; t <= maxTotal; t += step) {\n const h = Math.floor(t / 60) % 24;\n const m = t % 60;\n const value = toHHMM(h, m);\n slots.push({\n value,\n label: format === '12h' ? to12h(value) : value,\n });\n }\n return slots;\n}\n\n/** Clamp a raw HH:MM value to the [min, max] range; return '' when value is empty. */\nfunction clampValue(value: string, minTime: string, maxTime: string): string {\n if (!value) return '';\n const parsed = parseHHMM(value);\n if (!parsed) return '';\n\n const total = parsed.hours * 60 + parsed.minutes;\n const minParsed = parseHHMM(minTime) ?? { hours: 0, minutes: 0 };\n const maxParsed = parseHHMM(maxTime) ?? { hours: 23, minutes: 59 };\n const minTotal = minParsed.hours * 60 + minParsed.minutes;\n const maxTotal = maxParsed.hours * 60 + maxParsed.minutes;\n\n if (total < minTotal) return toHHMM(minParsed.hours, minParsed.minutes);\n if (total > maxTotal) return toHHMM(maxParsed.hours, maxParsed.minutes);\n return toHHMM(parsed.hours, parsed.minutes);\n}\n\n/**\n * Attempt to parse a user-typed string (12 h or 24 h) into an HH:MM value.\n * Returns null when the string cannot be resolved.\n */\nfunction parseUserInput(raw: string): string | null {\n const trimmed = raw.trim().toUpperCase();\n\n // 24-hour \"HH:MM\" or \"H:MM\"\n const hhmm = parseHHMM(trimmed);\n if (hhmm) return toHHMM(hhmm.hours, hhmm.minutes);\n\n // 12-hour patterns: \"2:30 PM\", \"2:30PM\", \"02:30 AM\", \"230 pm\", \"2 PM\"\n const twelve =\n /^(\\d{1,2})(?::(\\d{2}))?\\s*(AM|PM)$/.exec(trimmed) ??\n /^(\\d{1,2})(\\d{2})\\s*(AM|PM)$/.exec(trimmed);\n\n if (twelve) {\n let hours = parseInt(twelve[1] ?? '0', 10);\n const minutes = twelve[2] !== undefined ? parseInt(twelve[2], 10) : 0;\n const period = twelve[3] ?? '';\n if (hours < 1 || hours > 12 || minutes < 0 || minutes > 59) return null;\n if (period === 'AM') {\n hours = hours === 12 ? 0 : hours;\n } else {\n hours = hours === 12 ? 12 : hours + 12;\n }\n return toHHMM(hours, minutes);\n }\n\n return null;\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\n/**\n * A time-picker component with a combobox pattern: a text input with format\n * masking and a dropdown listbox of pre-generated time slots.\n *\n * @summary Form-associated time picker with 12h/24h format support and dropdown listbox.\n *\n * @tag hx-time-picker\n *\n * @slot label - Custom label content; overrides the rendered label element when used.\n * @slot help-text - Help text displayed below the field.\n * @slot error - Custom error content; overrides the `error` property.\n *\n * @fires {CustomEvent<{value: string}>} hx-change - Dispatched when the selected time changes. Detail value is HH:MM (24h).\n *\n * @csspart label - The label element.\n * @csspart input - The text input element.\n * @csspart toggle - The clock icon toggle button.\n * @csspart listbox - The dropdown `<ul>` element.\n * @csspart option - Each `<li>` option in the listbox.\n * @csspart field - The outer field wrapper element.\n * @csspart error - The error message element.\n * @csspart help-text - The help text element.\n *\n * @cssprop [--hx-time-picker-bg=var(--hx-color-neutral-0)] - Input background color.\n * @cssprop [--hx-time-picker-color=var(--hx-color-neutral-800)] - Input text color.\n * @cssprop [--hx-time-picker-border-color=var(--hx-color-neutral-300)] - Border color.\n * @cssprop [--hx-time-picker-border-radius=var(--hx-border-radius-md)] - Border radius.\n * @cssprop [--hx-time-picker-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-time-picker-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-time-picker-error-color=var(--hx-color-error-500)] - Error state color.\n * @cssprop [--hx-time-picker-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-time-picker-chevron-color=var(--hx-color-neutral-500)] - Toggle chevron color.\n * @cssprop [--hx-time-picker-listbox-bg=var(--hx-color-neutral-0)] - Listbox background.\n * @cssprop [--hx-time-picker-listbox-max-height=16rem] - Maximum height of the dropdown.\n * @cssprop [--hx-time-picker-listbox-shadow=0 4px 16px color-mix(in srgb, var(--hx-color-neutral-900) 12%, transparent)] - Box shadow for the dropdown listbox.\n * @cssprop [--hx-time-picker-option-color=var(--hx-color-neutral-800)] - Option text color.\n * @cssprop [--hx-time-picker-option-hover-bg=var(--hx-color-primary-50)] - Option hover background.\n * @cssprop [--hx-time-picker-option-hover-color=var(--hx-color-primary-700)] - Option hover text color.\n * @cssprop [--hx-time-picker-option-selected-bg=var(--hx-color-primary-100)] - Selected option background.\n * @cssprop [--hx-time-picker-option-selected-color=var(--hx-color-primary-800)] - Selected option text color.\n */\n@customElement('hx-time-picker')\nexport class HelixTimePicker extends LitElement {\n static override styles = [helixTimePickerStyles];\n\n // ─── Form Association ───\n\n /**\n * Declares this element as form-associated so it participates in native form submission.\n * @internal\n */\n static formAssociated = true;\n\n /**\n * ElementInternals instance used for form participation and constraint validation.\n * @internal\n */\n private readonly _internals: ElementInternals;\n\n constructor() {\n super();\n /** @internal */\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The name submitted with the form. Value is always HH:MM (24-hour).\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The current value in HH:MM (24-hour) format.\n * @attr value\n */\n @property({ type: String, reflect: true })\n value = '';\n\n /**\n * The earliest selectable time in HH:MM format.\n * @attr min\n */\n @property({ type: String })\n min = '00:00';\n\n /**\n * The latest selectable time in HH:MM format.\n * @attr max\n */\n @property({ type: String })\n max = '23:59';\n\n /**\n * Step interval between dropdown options, in minutes. Defaults to 30.\n * @attr step\n */\n @property({ type: Number })\n step = 30;\n\n /**\n * The visible label text for the field.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether the field is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the field is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Error message to display. When set, the field enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Display format for the time input. '12h' shows AM/PM; '24h' is bare HH:MM.\n * @attr format\n */\n @property({ type: String, reflect: true })\n format: '12h' | '24h' = '12h';\n\n // ─── Internal State ───\n\n /**\n * Whether the dropdown listbox is currently open.\n * @internal\n */\n @state() private _open = false;\n /**\n * Index of the currently keyboard-active option in the listbox; -1 when none is active.\n * @internal\n */\n @state() private _activeIndex = -1;\n /**\n * The display string shown in the text input, formatted according to the current `format` property.\n * @internal\n */\n @state() private _inputDisplayValue = '';\n /**\n * Whether the label slot has slotted content assigned to it.\n * @internal\n */\n @state() private _hasLabelSlot = false;\n /**\n * Whether the error slot has slotted content assigned to it.\n * @internal\n */\n @state() private _hasErrorSlot = false;\n /**\n * Whether the help-text slot has slotted content assigned to it.\n * @internal\n */\n @state() private _hasHelpSlot = false;\n /**\n * The ID of the slotted label element, used for aria-labelledby cross-root linking.\n * @internal\n */\n @state() private _slottedLabelId = '';\n\n // ─── Stable IDs (monotonically incrementing counter for SSR safety) ───\n\n /**\n * Monotonically incrementing counter used to generate unique element IDs across instances.\n * @internal\n */\n private static _instanceCount = 0;\n\n /**\n * Unique ID for this component instance, used as the input element's `id` attribute.\n * @internal\n */\n private readonly _id = `hx-time-picker-${++HelixTimePicker._instanceCount}`;\n /**\n * Unique ID for the listbox element, referenced by `aria-controls` on the combobox input.\n * @internal\n */\n private readonly _listboxId = `${this._id}-listbox`;\n /**\n * Unique ID for the error message element, referenced by `aria-describedby` on the input.\n * @internal\n */\n private readonly _errorId = `${this._id}-error`;\n /**\n * Unique ID for the help text element, referenced by `aria-describedby` on the input.\n * @internal\n */\n private readonly _helpId = `${this._id}-help`;\n\n // ─── Query References ───\n\n /**\n * Reference to the text input element inside the shadow DOM.\n * @internal\n */\n @query('.field__input')\n private _inputEl: HTMLInputElement | undefined;\n\n /**\n * Reference to the listbox `<ul>` element inside the shadow DOM.\n * @internal\n */\n @query('.field__listbox')\n private _listboxEl: HTMLUListElement | undefined;\n\n // ─── Memoized slot generation (avoids regenerating on every render call) ───\n\n /**\n * Memoized array of generated time slots; null until first access.\n * @internal\n */\n private _cachedSlots: TimeSlot[] | null = null;\n /**\n * Cache key composed of min, max, step, and format; used to detect when slots must be regenerated.\n * @internal\n */\n private _slotsKey = '';\n\n /**\n * Lazily generates and caches the list of time slots based on current min, max, step, and format.\n * @internal\n */\n private get _slots(): TimeSlot[] {\n const key = `${this.min}|${this.max}|${this.step}|${this.format}`;\n if (this._cachedSlots === null || key !== this._slotsKey) {\n this._slotsKey = key;\n this._cachedSlots = generateSlots(this.min, this.max, this.step, this.format);\n }\n return this._cachedSlots;\n }\n\n // ─── Outside-click handler (bound reference for add/removeEventListener) ───\n\n /**\n * Closes the listbox when a click is detected outside the component; bound for stable add/removeEventListener calls.\n * @internal\n */\n private readonly _handleOutsideClick = (e: MouseEvent): void => {\n if (!this.isConnected) return;\n if (!this.contains(e.target as Node) && !this.shadowRoot?.contains(e.target as Node)) {\n this._closeListbox();\n }\n };\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n // Keep display value in sync whenever the canonical value or format changes\n if (changed.has('value') || changed.has('format')) {\n this._inputDisplayValue = this.value\n ? this.format === '12h'\n ? to12h(this.value)\n : this.value\n : '';\n }\n }\n\n override updated(changed: PropertyValues<this>): void {\n super.updated(changed);\n if (changed.has('value')) {\n this._internals.setFormValue(this.value || null);\n this._updateValidity();\n }\n // When the listbox opens, scroll the selected (or active) option into view\n if ((changed as Map<PropertyKey, unknown>).has('_open') && this._open) {\n this._scrollActiveOptionIntoView();\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the field satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** @internal */\n private _updateValidity(): void {\n if (this.required && !this.value) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'Please select a time.',\n this._inputEl ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** @internal */\n formResetCallback(): void {\n this.value = '';\n this._inputDisplayValue = '';\n this._internals.setFormValue(null);\n this._closeListbox();\n }\n\n /** @internal */\n formStateRestoreCallback(\n state: string | File | FormData,\n _mode: 'restore' | 'autocomplete' = 'restore',\n ): void {\n // Only string states are valid for this component; ignore File/FormData\n if (typeof state !== 'string') return;\n // Validate and clamp before assigning; ignore out-of-spec values\n const clamped = clampValue(state, this.min, this.max);\n this.value = clamped;\n }\n\n /** @internal */\n formDisabledCallback(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Listbox helpers ───\n\n /** @internal */\n private _openListbox(): void {\n if (this._open) return;\n // Pre-set active index to currently selected slot (or 0)\n const selectedIndex = this._slots.findIndex((s) => s.value === this.value);\n this._activeIndex = selectedIndex >= 0 ? selectedIndex : 0;\n this._open = true;\n }\n\n /** @internal */\n private _closeListbox(): void {\n if (!this._open) return;\n this._open = false;\n this._activeIndex = -1;\n }\n\n /** @internal */\n private _scrollActiveOptionIntoView(): void {\n if (!this._listboxEl) return;\n const active = this._listboxEl.querySelector<HTMLElement>('.field__option--active');\n active?.scrollIntoView({ block: 'nearest' });\n }\n\n /** @internal */\n private _selectSlot(slot: TimeSlot): void {\n const clamped = clampValue(slot.value, this.min, this.max);\n this.value = clamped;\n this._closeListbox();\n this._dispatchChange(clamped);\n }\n\n // ─── Slot tracking ───\n\n /** @internal */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const nodes = slot.assignedNodes({ flatten: true });\n this._hasLabelSlot = nodes.length > 0;\n if (this._hasLabelSlot) {\n // Forward aria-labelledby: ensure the slotted label element has an ID so\n // the shadow-DOM input can reference it via aria-labelledby (A-03).\n const labelEl = nodes.find((n) => n.nodeType === Node.ELEMENT_NODE) as\n | HTMLElement\n | undefined;\n if (labelEl) {\n if (!labelEl.id) {\n labelEl.id = `${this._id}-slotted-label`;\n }\n this._slottedLabelId = labelEl.id;\n }\n } else {\n this._slottedLabelId = '';\n }\n }\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleHelpSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Event Dispatch ───\n\n /** @internal */\n private _dispatchChange(value: string): void {\n this.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value },\n }),\n );\n }\n\n // ─── Input Handlers ───\n\n /** @internal */\n private _handleInputClick(): void {\n if (!this.disabled) this._openListbox();\n }\n\n /** @internal */\n private _handleToggleClick(e: MouseEvent): void {\n e.stopPropagation();\n if (this.disabled) return;\n if (this._open) {\n this._closeListbox();\n } else {\n this._openListbox();\n this._inputEl?.focus();\n }\n }\n\n /** @internal */\n private _handleInputInput(e: Event): void {\n const target = e.target as HTMLInputElement;\n this._inputDisplayValue = target.value;\n // Open the listbox as the user types\n if (!this._open) this._openListbox();\n }\n\n /** @internal */\n private _handleInputChange(e: Event): void {\n const target = e.target as HTMLInputElement;\n const raw = target.value.trim();\n\n if (!raw) {\n // User cleared the field\n this.value = '';\n this._internals.setFormValue(null);\n this._updateValidity();\n this._dispatchChange('');\n return;\n }\n\n const parsed = parseUserInput(raw);\n if (parsed) {\n const clamped = clampValue(parsed, this.min, this.max);\n this.value = clamped;\n this._dispatchChange(clamped);\n } else {\n // Revert display to last known good value\n this._inputDisplayValue = this.value\n ? this.format === '12h'\n ? to12h(this.value)\n : this.value\n : '';\n }\n }\n\n /** @internal */\n private _handleInputKeyDown(e: KeyboardEvent): void {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!this._open) {\n this._openListbox();\n } else {\n this._activeIndex = Math.min(this._activeIndex + 1, this._slots.length - 1);\n this._scrollActiveOptionIntoView();\n }\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n if (this._open) {\n this._activeIndex = Math.max(this._activeIndex - 1, 0);\n this._scrollActiveOptionIntoView();\n }\n break;\n\n case 'Enter':\n if (this._open && this._activeIndex >= 0) {\n e.preventDefault();\n const slot = this._slots[this._activeIndex];\n if (slot) this._selectSlot(slot);\n }\n break;\n\n case 'Escape':\n e.preventDefault();\n this._closeListbox();\n break;\n\n case 'Home':\n if (this._open) {\n e.preventDefault();\n this._activeIndex = 0;\n this._scrollActiveOptionIntoView();\n }\n break;\n\n case 'End':\n if (this._open) {\n e.preventDefault();\n this._activeIndex = this._slots.length - 1;\n this._scrollActiveOptionIntoView();\n }\n break;\n\n case 'Tab':\n this._closeListbox();\n break;\n }\n }\n\n /** @internal */\n private _handleOptionPointerDown(e: MouseEvent): void {\n // Prevent the input from losing focus when clicking an option\n e.preventDefault();\n }\n\n /** @internal */\n private _handleOptionClick(slot: TimeSlot): void {\n this._selectSlot(slot);\n this._inputEl?.focus();\n }\n\n /** @internal */\n private _handleOptionMouseEnter(index: number): void {\n this._activeIndex = index;\n }\n\n // ─── Public API ───\n\n /** Moves focus to the time input element. */\n override focus(options?: FocusOptions): void {\n this._inputEl?.focus(options);\n }\n\n // ─── Render ───\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n const slots = this._slots;\n\n const fieldClasses = {\n field: true,\n 'field--error': hasError,\n 'field--disabled': this.disabled,\n 'field--required': this.required,\n };\n\n const activeDescendant =\n this._open && this._activeIndex >= 0\n ? `${this._listboxId}-option-${this._activeIndex}`\n : undefined;\n\n const placeholder = this.format === '12h' ? 'hh:mm AM' : 'hh:mm';\n\n // WCAG 1.3.1: the help-text div with _helpId always renders in the DOM unconditionally.\n // Always include _helpId in describedBy — an empty target is harmless for AT and ensures\n // the link is established immediately without waiting for the slotchange event to fire.\n const describedBy =\n [hasError ? this._errorId : null, this._helpId].filter(Boolean).join(' ') || undefined;\n\n return html`\n <div part=\"field\" class=${classMap(fieldClasses)}>\n <!-- Label -->\n <slot name=\"label\" @slotchange=${this._handleLabelSlotChange}>\n ${this.label\n ? html`\n <label part=\"label\" class=\"field__label\" for=${this._id}>\n ${this.label}\n ${this.required\n ? html`<span class=\"field__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </label>\n `\n : nothing}\n </slot>\n\n <!-- Combobox wrapper; role=\"combobox\" lives on the input per ARIA 1.2 -->\n <div class=\"field__combobox\">\n <input\n part=\"input\"\n class=\"field__input\"\n id=${this._id}\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n role=\"combobox\"\n aria-expanded=${this._open ? 'true' : 'false'}\n aria-haspopup=\"listbox\"\n .value=${live(this._inputDisplayValue)}\n placeholder=${placeholder}\n ?required=${this.required}\n ?disabled=${this.disabled}\n name=${ifDefined(this.name || undefined)}\n aria-autocomplete=\"list\"\n aria-controls=${this._listboxId}\n aria-activedescendant=${ifDefined(activeDescendant)}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-describedby=${ifDefined(describedBy)}\n aria-required=${this.required ? 'true' : nothing}\n aria-labelledby=${ifDefined(\n this._hasLabelSlot && this._slottedLabelId ? this._slottedLabelId : undefined,\n )}\n @click=${this._handleInputClick}\n @input=${this._handleInputInput}\n @change=${this._handleInputChange}\n @keydown=${this._handleInputKeyDown}\n />\n\n <!-- Toggle button -->\n <button\n part=\"toggle\"\n type=\"button\"\n class=\"field__toggle\"\n tabindex=\"-1\"\n aria-label=${this._open ? 'Close time picker' : 'Open time picker'}\n ?disabled=${this.disabled}\n @click=${this._handleToggleClick}\n >\n <!-- Clock icon -->\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"currentColor\" stroke-width=\"1.25\" />\n <path\n d=\"M8 4.5V8L10.5 10\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n\n <!-- Dropdown listbox: always in DOM so aria-controls is never a dangling reference (WCAG 4.1.2). Hidden via the boolean hidden attribute when closed. -->\n <ul\n part=\"listbox\"\n class=\"field__listbox\"\n id=${this._listboxId}\n role=\"listbox\"\n aria-label=${this.label || 'Time options'}\n ?hidden=${!this._open}\n >\n ${this._open\n ? repeat(\n slots,\n (slot) => slot.value,\n (slot, index) => {\n const isSelected = slot.value === this.value;\n const isActive = index === this._activeIndex;\n return html`\n <li\n part=\"option\"\n class=${classMap({\n field__option: true,\n 'field__option--selected': isSelected,\n 'field__option--active': isActive,\n })}\n id=\"${this._listboxId}-option-${index}\"\n role=\"option\"\n aria-selected=${isSelected ? 'true' : 'false'}\n @pointerdown=${this._handleOptionPointerDown}\n @click=${() => this._handleOptionClick(slot)}\n @mouseenter=${() => this._handleOptionMouseEnter(index)}\n >\n ${slot.label}\n </li>\n `;\n },\n )\n : nothing}\n </ul>\n </div>\n\n <!-- Error slot / property -->\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${this.error\n ? html`\n <div part=\"error\" class=\"field__error\" id=${this._errorId} role=\"alert\">\n ${this.error}\n </div>\n `\n : nothing}\n </slot>\n\n <!-- Help slot -->\n <div part=\"help-text\" class=\"field__help-text\" id=${this._helpId}>\n <slot name=\"help-text\" @slotchange=${this._handleHelpSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-time-picker': HelixTimePicker;\n }\n}\n"],"names":["helixTimePickerStyles","css","parseHHMM","raw","match","hours","minutes","toHHMM","to12h","value","parsed","period","h","generateSlots","minTime","maxTime","stepMinutes","format","minParsed","maxParsed","minTotal","maxTotal","step","slots","t","m","clampValue","total","parseUserInput","trimmed","hhmm","twelve","HelixTimePicker","LitElement","_a","key","changed","state","_mode","clamped","disabled","selectedIndex","s","active","slot","nodes","labelEl","n","target","index","options","hasError","fieldClasses","activeDescendant","placeholder","describedBy","html","classMap","nothing","live","ifDefined","repeat","isSelected","isActive","__decorateClass","property","query","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-toggle-button-BZUQUULm.js","sources":["../../src/components/hx-toggle-button/hx-toggle-button.styles.ts","../../src/components/hx-toggle-button/hx-toggle-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixToggleButtonStyles = css`\n :host {\n display: inline-block;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* ─── Base Button ─── */\n\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-toggle-button-border-color, transparent);\n border-radius: var(--hx-toggle-button-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-toggle-button-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-toggle-button-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-toggle-button-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-toggle-button-font-weight, var(--hx-font-weight-semibold, 600));\n line-height: var(--hx-line-height-tight, 1.25);\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n text-decoration: none;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-toggle-button-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .button:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .button:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Size Variants ─── */\n\n .button--sm {\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-3, 0.75rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n min-height: var(--hx-size-8, 2rem);\n }\n\n .button--md {\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n font-size: var(--hx-font-size-md, 1rem);\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n .button--lg {\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-6, 1.5rem);\n font-size: var(--hx-font-size-lg, 1.125rem);\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Style Variants ─── */\n\n .button--primary {\n --hx-toggle-button-bg: var(--hx-color-primary-500, #2563eb);\n --hx-toggle-button-color: var(--hx-color-neutral-0, #ffffff);\n --hx-toggle-button-border-color: transparent;\n }\n\n .button--secondary {\n --hx-toggle-button-bg: transparent;\n --hx-toggle-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-toggle-button-border-color: var(--hx-color-primary-500, #2563eb);\n }\n\n .button--secondary:hover {\n --hx-toggle-button-bg: var(--hx-color-primary-50, #eff6ff);\n }\n\n .button--tertiary {\n --hx-toggle-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n --hx-toggle-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-toggle-button-border-color: transparent;\n }\n\n .button--tertiary:hover {\n --hx-toggle-button-bg: var(--hx-color-neutral-200, #e2e8f0);\n }\n\n .button--ghost {\n --hx-toggle-button-bg: transparent;\n --hx-toggle-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-toggle-button-border-color: transparent;\n }\n\n .button--ghost:hover {\n --hx-toggle-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n }\n\n .button--outline {\n --hx-toggle-button-bg: transparent;\n --hx-toggle-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-toggle-button-border-color: var(--hx-color-neutral-300, #cbd5e1);\n }\n\n .button--outline:hover {\n --hx-toggle-button-bg: var(--hx-color-neutral-50, #f8fafc);\n }\n\n /* ─── Pressed State ─── */\n\n /*\n * Primary: already uses solid primary bg; pressed deepens to primary-700\n * to give clear visual feedback without introducing a new color.\n */\n .button--primary.button--pressed {\n --hx-toggle-button-bg: var(--hx-toggle-button-pressed-bg, var(--hx-color-primary-700, #1d4ed8));\n --hx-toggle-button-color: var(\n --hx-toggle-button-pressed-color,\n var(--hx-color-neutral-0, #ffffff)\n );\n --hx-toggle-button-border-color: transparent;\n }\n\n /*\n * Secondary: unpressed is outlined/transparent; pressed fills with primary bg\n * so the state change is immediately legible.\n */\n .button--secondary.button--pressed {\n --hx-toggle-button-bg: var(--hx-toggle-button-pressed-bg, var(--hx-color-primary-500, #2563eb));\n --hx-toggle-button-color: var(\n --hx-toggle-button-pressed-color,\n var(--hx-color-neutral-0, #ffffff)\n );\n --hx-toggle-button-border-color: var(--hx-color-primary-500, #2563eb);\n }\n\n /* Tertiary pressed: use primary-100 bg + primary-700 text + border for WCAG 3:1 non-text contrast. */\n .button--tertiary.button--pressed {\n --hx-toggle-button-bg: var(--hx-toggle-button-pressed-bg, var(--hx-color-primary-100, #dbeafe));\n --hx-toggle-button-color: var(\n --hx-toggle-button-pressed-color,\n var(--hx-color-primary-700, #1d4ed8)\n );\n --hx-toggle-button-border-color: var(--hx-color-primary-400, #60a5fa);\n box-shadow: inset 0 0 0 1px var(--hx-color-primary-400, #60a5fa);\n }\n\n /* Ghost pressed: subtle neutral fill, matching hover behavior as a baseline. */\n .button--ghost.button--pressed {\n --hx-toggle-button-bg: var(--hx-toggle-button-pressed-bg, var(--hx-color-primary-100, #dbeafe));\n --hx-toggle-button-color: var(\n --hx-toggle-button-pressed-color,\n var(--hx-color-primary-700, #1d4ed8)\n );\n --hx-toggle-button-border-color: transparent;\n }\n\n /* Outline pressed: fills with a neutral tint, darkens the border, and adds an inset shadow for WCAG 3:1 non-text contrast. */\n .button--outline.button--pressed {\n --hx-toggle-button-bg: var(--hx-toggle-button-pressed-bg, var(--hx-color-neutral-100, #f1f5f9));\n --hx-toggle-button-color: var(\n --hx-toggle-button-pressed-color,\n var(--hx-color-neutral-900, #0f172a)\n );\n --hx-toggle-button-border-color: var(--hx-color-neutral-500, #64748b);\n box-shadow: inset 0 0 0 1px var(--hx-color-neutral-500, #64748b);\n }\n\n /* ─── Disabled ─── */\n\n .button[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Prefix / Suffix / Label ─── */\n\n .button__prefix,\n .button__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .button__label {\n flex: 1 1 auto;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .button {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { helixToggleButtonStyles } from './hx-toggle-button.styles.js';\n\n/**\n * A two-state toggle button that communicates a pressed/unpressed status to\n * assistive technology via `aria-pressed`. Supports multiple visual variants\n * and sizes, prefix/suffix slots, full ElementInternals form association, and\n * a distinct pressed visual state for every variant.\n *\n * @summary Two-state toggle button with pressed/unpressed ARIA semantics.\n *\n * @tag hx-toggle-button\n *\n * @slot - Default slot for the button label text or content.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Icon or content rendered after the label.\n *\n * @fires {CustomEvent<{pressed: boolean}>} hx-toggle - Dispatched when the\n * toggle state changes. Not dispatched when the button is disabled.\n *\n * @csspart button - The native `<button>` element.\n * @csspart label - The label text wrapper span.\n * @csspart prefix - The prefix slot container span.\n * @csspart suffix - The suffix slot container span.\n *\n * @cssprop [--hx-toggle-button-bg=var(--hx-color-primary-500)] - Button background color.\n * @cssprop [--hx-toggle-button-color=var(--hx-color-neutral-0)] - Button text color.\n * @cssprop [--hx-toggle-button-border-color=transparent] - Button border color.\n * @cssprop [--hx-toggle-button-border-radius=var(--hx-border-radius-md)] - Button border radius.\n * @cssprop [--hx-toggle-button-font-family=var(--hx-font-family-sans)] - Button font family.\n * @cssprop [--hx-toggle-button-font-weight=var(--hx-font-weight-semibold)] - Button font weight.\n * @cssprop [--hx-toggle-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-toggle-button-pressed-bg=var(--hx-color-primary-500)] - Background when pressed (variant-specific fallback applies).\n * @cssprop [--hx-toggle-button-pressed-color=var(--hx-color-neutral-0)] - Text color when pressed (variant-specific fallback applies).\n */\n@customElement('hx-toggle-button')\nexport class HelixToggleButton extends LitElement {\n static override styles = [helixToggleButtonStyles];\n\n // ─── Form Association ───\n\n /** @internal */\n static formAssociated = true;\n\n /** @internal */\n private _internals: ElementInternals;\n\n /** @internal */\n @query('slot:not([name])') private _defaultSlot!: HTMLSlotElement | null;\n\n constructor() {\n super();\n /** @internal */\n this._internals = this.attachInternals();\n }\n\n // ─── Public Properties ───\n\n /**\n * Whether the toggle button is in the pressed state.\n * Reflected as an attribute so CSS selectors like `:host([pressed])` work.\n * @attr pressed\n */\n @property({ type: Boolean, reflect: true })\n pressed = false;\n\n /**\n * Visual style variant of the button.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'outline' = 'secondary';\n\n /**\n * Size of the button.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Whether the button is disabled. Prevents all interaction and form actions.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Form field name submitted via ElementInternals when the button is pressed.\n * @attr name\n */\n @property({ type: String })\n name: string | undefined = undefined;\n\n /**\n * Form field value submitted via ElementInternals when the button is pressed.\n * @attr value\n */\n @property({ type: String })\n value: string | undefined = undefined;\n\n /**\n * Accessible label forwarded to the inner `<button>` as `aria-label`.\n * Required for icon-only toggle buttons where no visible text is present.\n * @attr label\n */\n @property({ type: String })\n label: string | undefined = undefined;\n\n /**\n * When true, the button must be in the pressed state for the form to be submitted.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n // ─── Form API ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Returns the current validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Checks whether the button satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n // ─── Lifecycle ───\n\n override firstUpdated(changedProperties: PropertyValues<this>): void {\n super.firstUpdated(changedProperties);\n\n if (!this.label) {\n const slot = this._defaultSlot;\n const hasSlotText = slot\n ? slot.assignedNodes({ flatten: true }).some((n) => n.textContent?.trim())\n : false;\n if (!hasSlotText) {\n console.warn(\n '[hx-toggle-button] No accessible label found. Set the `label` attribute or provide slot text content for WCAG 4.1.2 compliance.',\n );\n }\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n\n if (\n changedProperties.has('pressed') ||\n changedProperties.has('value') ||\n changedProperties.has('required')\n ) {\n this._syncFormValue();\n }\n }\n\n /** @internal */\n formResetCallback(): void {\n this.pressed = false;\n }\n\n /** @internal */\n formStateRestoreCallback(\n state: string | File | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n this.pressed = typeof state === 'string' && state === 'pressed';\n }\n\n /** @internal */\n formDisabledCallback(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Private Helpers ───\n\n /** @internal */\n private _syncFormValue(): void {\n if (this.pressed && this.value !== undefined) {\n // Pass explicit state 'pressed' so formStateRestoreCallback can reliably detect it.\n this._internals.setFormValue(this.value, 'pressed');\n } else {\n this._internals.setFormValue(null);\n }\n this._updateValidity();\n }\n\n /** @internal */\n private _updateValidity(): void {\n if (this.required && !this.pressed) {\n this._internals.setValidity(\n { valueMissing: true },\n 'Please activate this toggle button.',\n this.shadowRoot?.querySelector<HTMLElement>('[part=\"button\"]') ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n // ─── Event Handling ───\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.pressed = !this.pressed;\n this._syncFormValue();\n\n /**\n * Dispatched when the toggle state changes.\n * @event hx-toggle\n */\n this.dispatchEvent(\n new CustomEvent<{ pressed: boolean }>('hx-toggle', {\n bubbles: true,\n composed: true,\n detail: { pressed: this.pressed },\n }),\n );\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderInner() {\n return html`\n <span part=\"prefix\" class=\"button__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"button__label\">\n <slot></slot>\n </span>\n <span part=\"suffix\" class=\"button__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n button: true,\n [`button--${this.variant}`]: true,\n [`button--${this.size}`]: true,\n 'button--pressed': this.pressed,\n };\n\n return html`\n <button\n part=\"button\"\n class=${classMap(classes)}\n ?disabled=${this.disabled}\n type=\"button\"\n aria-pressed=${this.pressed ? 'true' : 'false'}\n aria-label=${this.label ?? nothing}\n @click=${this._handleClick}\n >\n ${this._renderInner()}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-toggle-button': HelixToggleButton;\n }\n}\n"],"names":["helixToggleButtonStyles","css","HelixToggleButton","LitElement","changedProperties","slot","_a","state","_mode","disabled","e","html","classes","classMap","nothing","__decorateClass","query","property","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-tooltip-Ny4i1Idj.js","sources":["../../src/components/hx-tooltip/hx-tooltip.styles.ts","../../src/components/hx-tooltip/hx-tooltip.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTooltipStyles = css`\n :host {\n display: inline-block;\n }\n\n .trigger-wrapper {\n display: inline-block;\n }\n\n [part='tooltip'] {\n position: fixed;\n z-index: var(--hx-tooltip-z-index, var(--hx-z-index-tooltip, 1600));\n max-width: var(--hx-tooltip-max-width, 280px);\n padding: var(--hx-tooltip-padding, var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem));\n background: var(--hx-tooltip-bg, var(--hx-color-neutral-900, #111827));\n color: var(--hx-tooltip-color, var(--hx-color-neutral-50, #f9fafb));\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-tooltip-font-size, var(--hx-font-size-xs, 0.75rem));\n line-height: var(--hx-line-height-normal, 1.5);\n border-radius: var(--hx-tooltip-border-radius, var(--hx-border-radius-sm, 0.25rem));\n box-shadow: var(\n --hx-tooltip-shadow,\n var(--hx-shadow-sm, 0 2px 8px var(--hx-overlay-black-20, rgba(0, 0, 0, 0.2)))\n );\n visibility: hidden;\n opacity: 0;\n transition:\n opacity var(--hx-tooltip-transition-duration, var(--hx-transition-fast, 150ms ease)),\n visibility var(--hx-tooltip-transition-duration, var(--hx-transition-fast, 150ms ease));\n overflow-wrap: break-word;\n }\n\n [part='tooltip'].visible {\n visibility: visible;\n opacity: 1;\n }\n\n [part='arrow'] {\n position: absolute;\n width: var(--hx-tooltip-arrow-size, 8px);\n height: var(--hx-tooltip-arrow-size, 8px);\n background: var(--hx-tooltip-bg, var(--hx-color-neutral-900, #111827));\n transform: rotate(45deg);\n pointer-events: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n [part='tooltip'] {\n transition: none;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { computePosition, flip, shift, offset, arrow } from '@floating-ui/dom';\nimport { helixTooltipStyles } from './hx-tooltip.styles.js';\n\nlet _tooltipCounter = 0;\n\n/**\n * A tooltip that displays contextual help text on hover or focus.\n *\n * @summary Contextual help text and abbreviations with smart positioning.\n *\n * @tag hx-tooltip\n *\n * @slot - Default slot for the trigger element.\n * @slot content - Tooltip content to display.\n *\n * @csspart tooltip - The tooltip container element.\n * @csspart arrow - The arrow indicator element.\n *\n * @cssprop [--hx-tooltip-bg=var(--hx-color-neutral-900)] - Tooltip background color.\n * @cssprop [--hx-tooltip-color=var(--hx-color-neutral-50)] - Tooltip text color.\n * @cssprop [--hx-tooltip-font-size=var(--hx-font-size-xs)] - Tooltip font size.\n * @cssprop [--hx-tooltip-max-width=280px] - Maximum tooltip width.\n * @cssprop [--hx-tooltip-padding] - Tooltip padding.\n * @cssprop [--hx-tooltip-border-radius=var(--hx-border-radius-sm)] - Tooltip border radius.\n * @cssprop [--hx-tooltip-shadow] - Tooltip box shadow.\n * @cssprop [--hx-tooltip-z-index=9999] - Tooltip z-index.\n * @cssprop [--hx-tooltip-transition-duration=0.15s] - Show/hide transition duration.\n * @cssprop [--hx-tooltip-arrow-size=8px] - Size of the arrow indicator.\n *\n * @example\n * ```html\n * <hx-tooltip>\n * <button>Hover me</button>\n * <span slot=\"content\">Helpful context here</span>\n * </hx-tooltip>\n * ```\n *\n * @example Drupal/Twig usage\n * ```twig\n * <hx-tooltip>\n * <button type=\"button\">{{ trigger_label }}</button>\n * <span slot=\"content\">{{ tooltip_text }}</span>\n * </hx-tooltip>\n * ```\n */\n\n@customElement('hx-tooltip')\nexport class HelixTooltip extends LitElement {\n static override styles = [helixTooltipStyles];\n\n /**\n * Preferred placement of the tooltip relative to the trigger.\n * Supports all Floating UI placement values including alignment variants\n * (e.g. 'top-start', 'bottom-end') and 'auto'.\n * @attr placement\n */\n @property({ type: String, reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'top';\n\n /**\n * Delay in milliseconds before the tooltip is shown.\n * @attr show-delay\n */\n @property({ type: Number, attribute: 'show-delay' })\n showDelay = 300;\n\n /**\n * Delay in milliseconds before the tooltip is hidden.\n * @attr hide-delay\n */\n @property({ type: Number, attribute: 'hide-delay' })\n hideDelay = 100;\n\n /** @internal */\n @state() private _visible = false;\n\n /** @internal */\n private _showTimer: ReturnType<typeof setTimeout> | null = null;\n /** @internal */\n private _hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** @internal */\n private readonly _tooltipId = `hx-tooltip-${++_tooltipCounter}`;\n\n /** @internal */\n @query('slot:not([name])') private _defaultSlot!: HTMLSlotElement | null;\n /** @internal */\n @query('slot[name=\"content\"]') private _contentSlot!: HTMLSlotElement | null;\n /** @internal */\n @query('.trigger-wrapper') private _triggerWrapper!: HTMLElement | null;\n /** @internal */\n @query('[part=\"tooltip\"]') private _tooltipEl!: HTMLElement | null;\n /** @internal */\n @query('[part=\"arrow\"]') private _arrowEl!: HTMLElement | null;\n\n /**\n * Visually-hidden description element in light DOM.\n * Necessary because aria-describedby cannot cross Shadow DOM boundaries —\n * ARIA ID references are scoped to the element's root node. This element\n * lives in the document scope so the trigger's aria-describedby resolves correctly.\n * @internal\n */\n private _lightDomDescription: HTMLSpanElement | null = null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('keydown', this._handleKeydown);\n // Re-run ARIA setup on reconnection (firstUpdated does not re-run).\n // hasUpdated is true after the first update cycle completes.\n if (this.hasUpdated) {\n this._setupTriggerAria();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n this._clearTimers();\n this._lightDomDescription?.remove();\n this._lightDomDescription = null;\n }\n\n override firstUpdated(): void {\n this._setupTriggerAria();\n }\n\n // ─── ARIA setup ───\n\n /** @internal */\n private _setupTriggerAria(): void {\n const slot = this._defaultSlot;\n if (!slot) return;\n const trigger = slot.assignedElements()[0] as HTMLElement | undefined;\n\n // Sync content from the content slot into a visually-hidden light DOM element.\n // aria-describedby cannot cross Shadow DOM boundaries, so the referenced element\n // must live in the document scope (light DOM), not inside the shadow root.\n const contentSlot = this._contentSlot;\n const contentText =\n contentSlot\n ?.assignedElements()\n .map((el) => el.textContent)\n .join(' ')\n .trim() ?? '';\n\n // Guard for SSR — document is unavailable server-side\n if (!this._lightDomDescription && typeof document !== 'undefined') {\n this._lightDomDescription = document.createElement('span');\n this._lightDomDescription.id = this._tooltipId;\n // Visually hidden but accessible to screen readers via aria-describedby\n this._lightDomDescription.style.cssText =\n 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0';\n this.appendChild(this._lightDomDescription);\n }\n if (this._lightDomDescription) {\n this._lightDomDescription.textContent = contentText;\n }\n\n if (trigger) {\n trigger.setAttribute('aria-describedby', this._tooltipId);\n }\n }\n\n // ─── Show/Hide ───\n\n /** @internal */\n private _scheduleShow(): void {\n this._clearTimers();\n this._showTimer = setTimeout(() => {\n void this._show();\n }, this.showDelay);\n }\n\n /** @internal */\n private _scheduleHide(): void {\n this._clearTimers();\n this._hideTimer = setTimeout(() => {\n this._hide();\n }, this.hideDelay);\n }\n\n /** @internal */\n private async _show(): Promise<void> {\n this._visible = true;\n await this.updateComplete;\n await this._updatePosition();\n }\n\n /** @internal */\n private _hide(): void {\n this._visible = false;\n }\n\n /** @internal */\n private _clearTimers(): void {\n if (this._showTimer !== null) {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n }\n if (this._hideTimer !== null) {\n clearTimeout(this._hideTimer);\n this._hideTimer = null;\n }\n }\n\n // ─── Positioning ───\n\n /** @internal */\n private async _updatePosition(): Promise<void> {\n const reference = this._triggerWrapper;\n const tooltipEl = this._tooltipEl;\n const arrowEl = this._arrowEl;\n\n if (!reference || !tooltipEl || !arrowEl) return;\n\n const { x, y, placement, middlewareData } = await computePosition(reference, tooltipEl, {\n placement: this.placement,\n strategy: 'fixed',\n middleware: [offset(8), flip(), shift({ padding: 8 }), arrow({ element: arrowEl })],\n });\n\n Object.assign(tooltipEl.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n\n const arrowData = middlewareData.arrow;\n const basePlacement = placement.split('-')[0] ?? 'top';\n const oppositeSide: Record<string, string> = {\n top: 'bottom',\n right: 'left',\n bottom: 'top',\n left: 'right',\n };\n const staticSide = oppositeSide[basePlacement] ?? 'bottom';\n\n // Offset is derived from the arrow element's actual size so that custom\n // --hx-tooltip-arrow-size values position the arrow correctly.\n Object.assign(arrowEl.style, {\n left: arrowData?.x != null ? `${arrowData.x}px` : '',\n top: arrowData?.y != null ? `${arrowData.y}px` : '',\n right: '',\n bottom: '',\n [staticSide]: `${-(arrowEl.offsetWidth / 2)}px`,\n });\n }\n\n // ─── Events ───\n\n /** @internal */\n private _handleKeydown = (e: Event): void => {\n if (!(e instanceof KeyboardEvent)) return;\n if (e.key === 'Escape' && this._visible) {\n this._clearTimers();\n this._hide();\n }\n };\n\n /**\n * Handle mouseleave on the trigger wrapper.\n * Does not schedule hide if keyboard focus is still on the trigger element,\n * preventing mixed keyboard+mouse interactions from dismissing the tooltip\n * while the user is still navigating by keyboard.\n * @internal\n */\n private _handleTriggerMouseleave(): void {\n const slot = this._defaultSlot;\n const trigger = slot?.assignedElements()[0] as HTMLElement | undefined;\n // Guard for SSR — document is unavailable server-side\n const active = typeof document !== 'undefined' ? document.activeElement : null;\n if (trigger && (trigger === active || trigger.contains(active))) {\n return;\n }\n this._scheduleHide();\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div\n class=\"trigger-wrapper\"\n @mouseenter=${this._scheduleShow}\n @mouseleave=${this._handleTriggerMouseleave}\n @focusin=${this._scheduleShow}\n @focusout=${this._scheduleHide}\n >\n <slot @slotchange=${this._setupTriggerAria}></slot>\n </div>\n <div\n part=\"tooltip\"\n id=${this._tooltipId}\n role=\"tooltip\"\n aria-hidden=${String(!this._visible)}\n class=${this._visible ? 'visible' : ''}\n @mouseenter=${this._clearTimers}\n @mouseleave=${this._scheduleHide}\n >\n <slot name=\"content\" @slotchange=${this._setupTriggerAria}></slot>\n <div part=\"arrow\"></div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tooltip': HelixTooltip;\n }\n}\n"],"names":["helixTooltipStyles","css","_tooltipCounter","HelixTooltip","LitElement","e","_a","slot","trigger","contentSlot","contentText","el","reference","tooltipEl","arrowEl","x","y","placement","middlewareData","computePosition","offset","flip","shift","arrow","arrowData","basePlacement","staticSide","active","html","__decorateClass","property","state","query","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-top-nav-CC4FW2Hp.js","sources":["../../src/components/hx-top-nav/hx-top-nav.styles.ts","../../src/components/hx-top-nav/hx-top-nav.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTopNavStyles = css`\n /* ─── Host ─── */\n\n :host {\n display: block;\n }\n\n /* ─── Header wrapper (landmark) ─── */\n\n header {\n display: block;\n margin: 0;\n padding: 0;\n }\n\n /* ─── Sticky mode ─── */\n\n :host([sticky]) .nav {\n position: sticky;\n top: 0;\n /* Fallback 1000 is appropriate for sticky navbars (below modals ~1300, above content) */\n z-index: var(--hx-top-nav-z-index, var(--hx-z-index-sticky, 1000));\n }\n\n /* ─── Nav container ─── */\n\n .nav {\n background-color: var(--hx-top-nav-bg, var(--hx-color-neutral-0, #ffffff));\n color: var(--hx-top-nav-color, var(--hx-color-neutral-800, #212529));\n border-bottom: var(--hx-border-width-thin, 1px) solid\n var(--hx-top-nav-border-color, var(--hx-color-neutral-200, #dee2e6));\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n /* ─── Bar row (always visible) ─── */\n\n .nav__bar {\n display: flex;\n align-items: center;\n min-height: var(--hx-top-nav-height, var(--hx-space-16, 4rem));\n padding-inline: var(--hx-top-nav-padding-x, var(--hx-space-6, 1.5rem));\n gap: var(--hx-space-4, 1rem);\n }\n\n /* ─── Logo ─── */\n\n .nav__logo {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n /* ─── Mobile toggle (hamburger) ─── */\n\n .mobile-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-inline-start: auto;\n /* var(--hx-space-3, 0.75rem) padding + 24px icon = 48×48px touch target (exceeds WCAG 2.5.5 44×44px) */\n padding: var(--hx-space-3, 0.75rem);\n background: transparent;\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n color: var(--hx-top-nav-toggle-color, var(--hx-color-neutral-700, #343a40));\n cursor: pointer;\n line-height: 0;\n }\n\n .mobile-toggle:hover {\n background: var(--hx-color-neutral-100, #f1f3f5);\n }\n\n .mobile-toggle:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-focus-ring-color, var(--hx-color-primary-500, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .mobile-toggle__icon {\n width: var(--hx-space-6, 1.5rem);\n height: var(--hx-space-6, 1.5rem);\n }\n\n /* ─── Collapsible panel (mobile) ─── */\n\n .nav__collapsible {\n display: none;\n flex-direction: column;\n width: 100%;\n padding-block: var(--hx-space-3, 0.75rem);\n border-top: var(--hx-border-width-thin, 1px) solid\n var(--hx-top-nav-border-color, var(--hx-color-neutral-200, #dee2e6));\n }\n\n .nav__collapsible--open {\n display: flex;\n animation: hx-mobile-nav-open var(--hx-duration-fast, 150ms) ease-out;\n }\n\n /* ─── Menu and actions in collapsible (mobile) ─── */\n\n .nav__menu,\n .nav__actions {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n padding-inline: var(--hx-top-nav-padding-x, var(--hx-space-6, 1.5rem));\n }\n\n .nav__actions {\n margin-top: var(--hx-space-3, 0.75rem);\n padding-top: var(--hx-space-3, 0.75rem);\n border-top: var(--hx-border-width-thin, 1px) solid\n var(--hx-top-nav-border-color, var(--hx-color-neutral-200, #dee2e6));\n }\n\n /* ─── Desktop breakpoint ─── */\n\n /* NOTE: CSS @media queries do not support custom properties.\n This value corresponds to --hx-breakpoint-md (768px). */\n @media (min-width: 768px) {\n /* Make nav a flex row so bar and collapsible sit side-by-side */\n .nav {\n display: flex;\n align-items: center;\n padding-inline: var(--hx-top-nav-padding-x, var(--hx-space-6, 1.5rem));\n }\n\n .nav__bar {\n flex-shrink: 0;\n padding-inline: 0;\n min-height: var(--hx-top-nav-height, var(--hx-space-16, 4rem));\n }\n\n /* Hide hamburger on desktop */\n .mobile-toggle {\n display: none;\n }\n\n /* Collapsible becomes a standard inline flex row */\n .nav__collapsible {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex: 1;\n padding-block: 0;\n border-top: none;\n margin-inline-start: auto;\n gap: var(--hx-space-4, 1rem);\n animation: none;\n }\n\n /* Override open modifier — always visible on desktop regardless of state */\n .nav__collapsible--open {\n display: flex;\n animation: none;\n }\n\n /* Menu grows to fill available space */\n .nav__menu {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n flex: 1;\n padding-inline: 0;\n }\n\n /* Actions sit at the far right */\n .nav__actions {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n margin-top: 0;\n padding-top: 0;\n padding-inline: 0;\n border-top: none;\n flex-shrink: 0;\n }\n }\n\n /* ─── Mobile menu open animation ─── */\n\n @keyframes hx-mobile-nav-open {\n from {\n opacity: 0;\n transform: translateY(-0.25rem);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* ─── Reduced motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .nav__collapsible--open {\n animation: none;\n }\n }\n`;\n","import { LitElement, html, 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 { helixTopNavStyles } from './hx-top-nav.styles.js';\n\n/**\n * Top-of-page site navigation bar with logo, menu items, and utility area.\n * Supports sticky positioning, responsive hamburger menu, and full slot-driven\n * content composition for Drupal and other CMS consumers.\n *\n * @summary Site-level navigation bar with logo, nav items, and action slots.\n *\n * @tag hx-top-nav\n *\n * @slot logo - Brand area rendered on the left side.\n * @slot - Default slot for primary navigation items rendered in the center.\n * IMPORTANT: Do NOT place a `<nav>` element in this slot — the component\n * already renders a `<nav>` landmark internally. Use a `<div>` or bare links.\n * @slot actions - Utility area rendered on the right side (search, user menu, etc.).\n *\n * @fires {CustomEvent<{open: boolean}>} hx-mobile-toggle - Dispatched when the\n * hamburger button is toggled. Detail contains the new open state.\n *\n * @csspart header - The outer `<header>` landmark element.\n * @csspart nav - The `<nav>` element inside the header.\n * @csspart logo - The logo slot container.\n * @csspart menu - The primary navigation slot container.\n * @csspart actions - The actions slot container.\n * @csspart mobile-toggle - The hamburger toggle button.\n *\n * @cssprop [--hx-top-nav-bg=var(--hx-color-neutral-0)] - Navigation bar background color.\n * @cssprop [--hx-top-nav-color=var(--hx-color-neutral-800)] - Navigation bar text color.\n * @cssprop [--hx-top-nav-border-color=var(--hx-color-neutral-200)] - Bottom border color.\n * @cssprop [--hx-top-nav-height=var(--hx-space-16)] - Navigation bar height.\n * @cssprop [--hx-top-nav-padding-x=var(--hx-space-6)] - Horizontal padding.\n * @cssprop [--hx-top-nav-z-index=var(--hx-z-index-sticky)] - Z-index for sticky mode.\n * @cssprop [--hx-top-nav-toggle-color=var(--hx-color-neutral-700)] - Hamburger icon color.\n */\n@customElement('hx-top-nav')\nexport class HelixTopNav extends LitElement {\n static override styles = [helixTopNavStyles];\n\n // ─── Public Properties ───\n\n /**\n * When true, the navigation bar sticks to the top of the viewport during scroll.\n * @attr sticky\n */\n @property({ type: Boolean, reflect: true })\n sticky = false;\n\n /**\n * Accessible label applied to the `<nav>` element via `aria-label`.\n * @attr label\n */\n @property({ type: String })\n label = 'Site Navigation';\n\n // ─── Private State ───\n\n /** Whether the mobile collapsible menu is currently open. */\n /** @internal */\n @state() private _mobileOpen = false;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleMobileToggle(): void {\n this._mobileOpen = !this._mobileOpen;\n\n /**\n * Dispatched when the hamburger button is toggled.\n * @event hx-mobile-toggle\n */\n this.dispatchEvent(\n new CustomEvent<{ open: boolean }>('hx-mobile-toggle', {\n bubbles: true,\n composed: true,\n detail: { open: this._mobileOpen },\n }),\n );\n\n if (this._mobileOpen) {\n // Move focus to first truly interactive element in the default slot (WCAG 2.4.3).\n // A plain HTMLElement (e.g. <div>) is not keyboard-reachable; we must find a\n // focusable descendant to avoid trapping focus on a non-interactive node.\n void this.updateComplete.then(() => {\n const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), [tabindex=\"0\"]';\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n const assigned = slot?.assignedElements({ flatten: true }) ?? [];\n let firstFocusable: HTMLElement | null = null;\n for (const el of assigned) {\n if (!(el instanceof HTMLElement)) continue;\n if (el.matches(FOCUSABLE_SELECTOR)) {\n firstFocusable = el;\n break;\n }\n const found = el.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n if (found) {\n firstFocusable = found;\n break;\n }\n }\n firstFocusable?.focus();\n });\n }\n }\n\n /** @internal */\n private _handleKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this._mobileOpen) {\n this._mobileOpen = false;\n this.dispatchEvent(\n new CustomEvent<{ open: boolean }>('hx-mobile-toggle', {\n bubbles: true,\n composed: true,\n detail: { open: false },\n }),\n );\n // Return focus to the toggle button\n this.shadowRoot?.querySelector<HTMLButtonElement>('[part=\"mobile-toggle\"]')?.focus();\n }\n };\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderHamburgerIcon() {\n return html`\n <svg\n class=\"mobile-toggle__icon\"\n aria-hidden=\"true\"\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 ${this._mobileOpen\n ? svg`\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n `\n : svg`\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n `}\n </svg>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const menuClasses = {\n nav__collapsible: true,\n 'nav__collapsible--open': this._mobileOpen,\n };\n\n return html`\n <header part=\"header\">\n <nav part=\"nav\" class=\"nav\" aria-label=${this.label}>\n <div class=\"nav__bar\">\n <div part=\"logo\" class=\"nav__logo\">\n <slot name=\"logo\"></slot>\n </div>\n\n <button\n part=\"mobile-toggle\"\n class=\"mobile-toggle\"\n type=\"button\"\n aria-expanded=${String(this._mobileOpen)}\n aria-controls=\"nav-menu\"\n aria-label=${this._mobileOpen ? 'Close navigation' : 'Open navigation'}\n @click=${this._handleMobileToggle}\n >\n ${this._renderHamburgerIcon()}\n </button>\n </div>\n\n <div id=\"nav-menu\" class=${classMap(menuClasses)}>\n <div part=\"menu\" class=\"nav__menu\">\n <slot></slot>\n </div>\n\n <div part=\"actions\" class=\"nav__actions\">\n <slot name=\"actions\"></slot>\n </div>\n </div>\n </nav>\n </header>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-top-nav': HelixTopNav;\n }\n}\n"],"names":["helixTopNavStyles","css","HelixTopNav","LitElement","e","_b","_a","FOCUSABLE_SELECTOR","slot","assigned","firstFocusable","el","found","html","svg","menuClasses","classMap","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-tree-item-CPQ9dJiK.js","sources":["../../src/components/hx-tree-view/hx-tree-view.styles.ts","../../src/components/hx-tree-view/hx-tree-view.ts","../../src/components/hx-tree-view/hx-tree-item.styles.ts","../../src/components/hx-tree-view/hx-tree-item.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTreeViewStyles = css`\n :host {\n display: block;\n contain: layout style;\n font-family: var(--hx-tree-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n * {\n box-sizing: border-box;\n }\n\n .tree {\n display: block;\n outline: none;\n }\n\n .tree:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { helixTreeViewStyles } from './hx-tree-view.styles.js';\nimport type { HelixTreeItem, HxTreeItemSelectDetail } from './hx-tree-item.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/** Selection mode for the tree. */\nexport type TreeSelection = 'none' | 'single' | 'multiple';\n\n/** Detail type for the `hx-select` event. */\nexport interface HxSelectDetail {\n /** The tree item that was selected or deselected. */\n item: HelixTreeItem;\n /** Whether the item is now selected. */\n selected: boolean;\n}\n\n/**\n * A hierarchical tree component for navigating nested data structures.\n * Used in healthcare applications for org charts, ICD-10 code hierarchies, and department navigation.\n *\n * Implements WAI-ARIA tree view pattern with `role=\"tree\"` on the container\n * and `role=\"treeitem\"` on each item. Supports `aria-label` via the `label` property\n * for screen reader identification. Full keyboard navigation: Arrow keys for movement,\n * Enter/Space for selection, Home/End for first/last item.\n *\n * ## Scale Limits\n *\n * This component renders all tree items simultaneously in the DOM. It is suitable for\n * trees with up to ~500 visible items. For large taxonomies (e.g., ICD-10 with 70,000+\n * codes), use async/lazy loading: only render top-level nodes initially and populate\n * child nodes on `hx-select` or expand events. The component exposes the `expanded`\n * property on `hx-tree-item` for programmatic control of subtrees, enabling consumer-level\n * virtualization strategies without requiring changes to this component.\n *\n * @summary Hierarchical tree view with expand/collapse and keyboard navigation.\n *\n * @tag hx-tree-view\n *\n * @slot - Default slot for hx-tree-item elements.\n *\n * @fires {CustomEvent<HxSelectDetail>} hx-select - Dispatched when a tree item is selected or deselected.\n *\n * @csspart tree - The tree container element with role=\"tree\".\n *\n * @cssprop [--hx-tree-font-family=var(--hx-font-family-sans)] - Tree font family.\n */\n@customElement('hx-tree-view')\nexport class HelixTreeView extends LitElement {\n static override styles = [helixTreeViewStyles];\n\n // ─── Properties ───\n\n /**\n * Accessible label for the tree. Applied as `aria-label` on the tree container.\n * Provides context to screen readers about the tree's purpose.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Selection mode for the tree.\n * - `none` — items cannot be selected\n * - `single` — only one item can be selected at a time\n * - `multiple` — multiple items can be selected\n * @attr selection\n */\n @property({ type: String, reflect: true })\n selection: 'none' | 'single' | 'multiple' = 'none';\n\n // ─── Internal State ───\n\n /** @internal */\n @state() private _currentIndex = 0;\n\n /** Tracks whether the tree has any visible items, to decide the container tabindex. */\n /** @internal */\n @state() private _hasVisibleItems = false;\n\n // ─── Visible items cache ───\n\n /**\n * Cached flat list of visible items (depth-first, respects collapsed nodes).\n * Set to null to invalidate; rebuilt on next access.\n * @internal\n */\n private _cachedVisibleItems: HelixTreeItem[] | null = null;\n\n /**\n * Invalidate the visible-items cache. Call after any expand/collapse or structural change.\n * @internal\n */\n private _invalidateVisibleItemsCache(): void {\n this._cachedVisibleItems = null;\n }\n\n // ─── Internal Helpers ───\n\n /**\n * Returns a flat ordered list of all visible (not inside a collapsed item) hx-tree-items\n * in depth-first order. Result is cached; invalidated on expand/collapse/slotchange.\n */\n /** @internal */\n private _getVisibleItems(): HelixTreeItem[] {\n if (!this._cachedVisibleItems) {\n this._cachedVisibleItems = this._collectVisibleItems(this);\n }\n return this._cachedVisibleItems;\n }\n\n /** @internal */\n private _collectVisibleItems(container: Element): HelixTreeItem[] {\n const items: HelixTreeItem[] = [];\n for (const child of Array.from(container.children)) {\n if (child.tagName.toLowerCase() === 'hx-tree-item') {\n const item = child as HelixTreeItem;\n items.push(item);\n if (item.expanded) {\n items.push(...this._collectVisibleItems(item));\n }\n } else {\n items.push(...this._collectVisibleItems(child));\n }\n }\n return items;\n }\n\n /** @internal */\n private _getSelectedItems(): HelixTreeItem[] {\n return Array.from(this.querySelectorAll<HelixTreeItem>('hx-tree-item[selected]'));\n }\n\n /**\n * Updates the roving tabindex across all visible items so that only the\n * item at `activeIndex` has `tabindex=\"0\"`. All others receive `tabindex=\"-1\"`.\n * This is called whenever the active item changes (navigation, initial render).\n */\n /** @internal */\n private _updateRovingTabindex(items: HelixTreeItem[], activeIndex: number): void {\n items.forEach((item, i) => {\n item.setRovingActive(i === activeIndex);\n });\n }\n\n /** @internal */\n private _focusItem(index: number): void {\n const items = this._getVisibleItems();\n if (items.length === 0) return;\n const clamped = Math.max(0, Math.min(index, items.length - 1));\n this._currentIndex = clamped;\n this._updateRovingTabindex(items, clamped);\n items[clamped]?.focus();\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleTreeItemSelect(e: Event): void {\n if (!(e instanceof CustomEvent)) return;\n const event = e as CustomEvent<HxTreeItemSelectDetail>;\n const item = event.detail.item;\n\n if (this.selection === 'none') return;\n\n if (this.selection === 'single') {\n const wasSelected = item.selected;\n this._getSelectedItems().forEach((i) => {\n i.selected = false;\n });\n item.selected = !wasSelected;\n } else if (this.selection === 'multiple') {\n item.selected = !item.selected;\n }\n\n this.dispatchEvent(\n new CustomEvent<HxSelectDetail>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { item, selected: item.selected },\n }),\n );\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n const items = this._getVisibleItems();\n if (items.length === 0) return;\n\n let currentIndex = this._currentIndex;\n const focused = document.activeElement;\n\n for (let i = 0; i < items.length; i++) {\n if (items[i] === focused || items[i]?.shadowRoot?.activeElement) {\n currentIndex = i;\n break;\n }\n }\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n // Intentional design: wrap-around from last to first item provides\n // a continuous navigation loop, consistent with the component's\n // circular keyboard navigation model.\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n this._focusItem(next);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n // Intentional design: wrap-around from first to last item (see ArrowDown note).\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n this._focusItem(prev);\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n const currentItem = items[currentIndex];\n if (!currentItem) break;\n if (currentItem.expanded && currentItem.hasChildItems) {\n currentItem.expanded = false;\n this._invalidateVisibleItemsCache();\n } else {\n const parentItem = currentItem.parentElement?.closest('hx-tree-item') as\n | HelixTreeItem\n | undefined;\n if (parentItem) {\n const parentIndex = items.indexOf(parentItem);\n if (parentIndex >= 0) {\n this._focusItem(parentIndex);\n }\n }\n }\n break;\n }\n case 'ArrowRight': {\n e.preventDefault();\n const currentItem = items[currentIndex];\n if (!currentItem) break;\n if (currentItem.hasChildItems) {\n if (!currentItem.expanded) {\n currentItem.expanded = true;\n this._invalidateVisibleItemsCache();\n } else {\n this._focusItem(currentIndex + 1);\n }\n }\n break;\n }\n case 'Home': {\n e.preventDefault();\n this._focusItem(0);\n break;\n }\n case 'End': {\n e.preventDefault();\n this._focusItem(items.length - 1);\n break;\n }\n default: {\n // WAI-ARIA APG typeahead: a printable character moves focus to the next visible\n // item whose label starts with that character (case-insensitive).\n if (e.key.length === 1) {\n e.preventDefault();\n const matchIndex = this._findTypeaheadMatch(e.key.toLowerCase(), currentIndex);\n if (matchIndex !== -1) {\n this._focusItem(matchIndex);\n }\n }\n break;\n }\n }\n }\n\n /**\n * Finds the next visible item (starting after `currentIndex`, wrapping around) whose\n * label text begins with the given lowercase character. Returns -1 if no match.\n * @internal\n */\n private _findTypeaheadMatch(char: string, currentIndex: number): number {\n const items = this._getVisibleItems();\n if (items.length === 0) return -1;\n for (let i = 1; i <= items.length; i++) {\n const index = (currentIndex + i) % items.length;\n const item = items[index];\n if (item && item.labelText.toLowerCase().startsWith(char)) {\n return index;\n }\n }\n return -1;\n }\n\n /** @internal */\n private _handleFocusIn(e: FocusEvent): void {\n // With roving tabindex, the tree container (tabindex=\"-1\") should only receive\n // focus when the tree is empty. If focus does land on the container (e.g. the\n // tree is empty or programmatic focus), redirect to the active item if present.\n if (e.target === e.currentTarget) {\n const items = this._getVisibleItems();\n if (items.length > 0) {\n this._focusItem(this._currentIndex);\n }\n }\n }\n\n /**\n * Compute and push ARIA position metadata (level, posInSet, setSize, selectable) to all\n * direct hx-tree-item children of a container in a single O(n) pass.\n * Each item also recurses for its own children, building the full tree in O(total-items) total.\n * @internal\n */\n private _updateAriaMetadataForContainer(container: Element, level: number): void {\n const selectable = this.selection === 'single' || this.selection === 'multiple';\n const children = Array.from(container.children).filter(\n (c) => c.tagName.toLowerCase() === 'hx-tree-item',\n ) as HelixTreeItem[];\n const setSize = children.length;\n children.forEach((item, index) => {\n item.setAriaMetadata(level, index + 1, setSize, selectable);\n // Recurse into child items so the full tree is updated in one traversal\n this._updateAriaMetadataForContainer(item, level + 1);\n });\n }\n\n /**\n * Initializes the roving tabindex after items are first slotted in.\n * Ensures the active item (index 0 by default) has tabindex=\"0\" from the start,\n * so a Tab into the tree lands directly on the first item without a redirect.\n * Also updates `_hasVisibleItems` so the container tabindex re-renders correctly.\n * Pushes O(n) ARIA metadata to all items to replace the O(n^2) per-item ancestor walk.\n */\n /** @internal */\n private _handleSlotChange(): void {\n this._invalidateVisibleItemsCache();\n // Push ARIA metadata from parent in a single O(n) traversal\n this._updateAriaMetadataForContainer(this, 1);\n const items = this._getVisibleItems();\n this._hasVisibleItems = items.length > 0;\n if (items.length === 0) return;\n // Clamp _currentIndex in case items were removed.\n const clamped = Math.min(this._currentIndex, items.length - 1);\n this._currentIndex = clamped;\n this._updateRovingTabindex(items, clamped);\n }\n\n // ─── Lifecycle ───\n\n override firstUpdated(): void {\n if (!this.label) {\n devWarn(\n 'hx-tree-view',\n 'No accessible label provided. Set the `label` attribute on hx-tree-view so screen readers can identify this tree (WCAG 4.1.2).',\n );\n }\n }\n\n // ─── Render ───\n\n override render() {\n // Roving tabindex pattern (WCAG 2.4.3 Fix):\n // The tree container is NOT a Tab stop (tabindex=\"-1\"). Tab focus goes\n // directly to the active item, which carries tabindex=\"0\". The container\n // is only a landing target (tabindex=\"0\") when the tree is empty.\n const containerTabindex = this._hasVisibleItems ? '-1' : '0';\n\n return html`\n <div\n part=\"tree\"\n class=\"tree\"\n role=\"tree\"\n tabindex=${containerTabindex}\n aria-label=${this.label || 'Tree'}\n aria-multiselectable=${this.selection === 'none'\n ? nothing\n : this.selection === 'multiple'\n ? 'true'\n : 'false'}\n @hx-tree-item-select=${this._handleTreeItemSelect}\n @keydown=${this._handleKeyDown}\n @focusin=${this._handleFocusIn}\n >\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tree-view': HelixTreeView;\n }\n}\n\n/** Canonical type alias for HelixTreeView. Use this when typing hx-tree-view element references. */\nexport type HxTreeView = HelixTreeView;\n\n/** @deprecated Use {@link HxTreeView} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcTreeView = HelixTreeView;\n","import { css } from 'lit';\n\nexport const helixTreeItemStyles = css`\n :host {\n display: block;\n contain: layout style;\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Item Container ─── */\n\n .item {\n display: block;\n }\n\n /* ─── Item Row ─── */\n\n .item-row {\n display: flex;\n align-items: center;\n gap: var(--hx-tree-item-gap, var(--hx-space-2, 0.5rem));\n padding: var(--hx-tree-item-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-tree-item-padding-x, var(--hx-space-2, 0.5rem));\n padding-inline-start: calc(\n var(--hx-tree-item-padding-x, var(--hx-space-2, 0.5rem)) + var(--_indent-level, 0) *\n var(--hx-tree-indent-size, 1.5rem)\n );\n border-radius: var(--hx-tree-item-border-radius, var(--hx-border-radius-sm, 0.25rem));\n cursor: pointer;\n outline: none;\n color: var(--hx-tree-item-color, var(--hx-color-neutral-900, #111827));\n font-family: var(--hx-tree-item-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-tree-item-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-normal, 1.5);\n transition: background-color var(--hx-transition-fast, 150ms ease);\n user-select: none;\n }\n\n .item-row:hover {\n background-color: var(--hx-tree-item-hover-bg, var(--hx-color-neutral-100, #f3f4f6));\n }\n\n .item-row:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-tree-item-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, -2px);\n }\n\n /* ─── Selected State ─── */\n\n :host([selected]) .item-row {\n background-color: var(--hx-tree-item-selected-bg, var(--hx-color-primary-100, #dbeafe));\n color: var(--hx-tree-item-selected-color, var(--hx-color-primary-800, #1e40af));\n }\n\n :host([selected]) .item-row:hover {\n background-color: var(--hx-tree-item-selected-hover-bg, var(--hx-color-primary-200, #bfdbfe));\n }\n\n /* ─── Disabled State ─── */\n\n :host([disabled]) .item-row {\n opacity: var(--hx-opacity-disabled, 0.5);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n /* ─── Expand Icon ─── */\n\n .expand-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n }\n\n .expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n padding: 0;\n border: none;\n background: transparent;\n color: var(--hx-tree-item-expand-icon-color, var(--hx-color-neutral-500, #6b7280));\n cursor: pointer;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n transition: transform var(--hx-transition-fast, 150ms ease);\n pointer-events: auto;\n }\n\n .expand-btn:hover {\n background-color: var(\n --hx-tree-item-expand-hover-bg,\n var(--hx-overlay-black-6, rgba(0, 0, 0, 0.06))\n );\n }\n\n .expand-btn:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-tree-item-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .expand-btn svg {\n width: var(--hx-space-3, 0.75rem);\n height: var(--hx-space-3, 0.75rem);\n stroke: currentColor;\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n :host([expanded]) .expand-btn svg {\n transform: rotate(90deg);\n }\n\n .expand-placeholder {\n display: block;\n width: var(--hx-space-4, 1rem);\n flex-shrink: 0;\n }\n\n /* ─── Icon Slot ─── */\n\n .item-icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--hx-tree-item-icon-color, var(--hx-color-neutral-500, #6b7280));\n }\n\n .item-icon:empty {\n display: none;\n }\n\n /* ─── Label ─── */\n\n .item-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ─── Children (animated) ─── */\n\n .children {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--hx-transition-base, 200ms ease);\n --_indent-level: calc(var(--_indent-level, 0) + 1);\n }\n\n .children--expanded {\n grid-template-rows: 1fr;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item-row,\n .expand-btn,\n .expand-btn svg,\n .children {\n transition: none;\n }\n }\n\n .children-inner {\n overflow: hidden;\n }\n`;\n","import { LitElement, html, nothing } 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 { helixTreeItemStyles } from './hx-tree-item.styles.js';\n\n/** Detail type for the `hx-tree-item-select` event. */\nexport interface HxTreeItemSelectDetail {\n /** The tree item that was selected or activated. */\n item: HelixTreeItem;\n}\n\n/**\n * A tree item used within an hx-tree-view component.\n * Supports expand/collapse, selection, keyboard navigation, and icon/children slots.\n *\n * @summary Individual item within an hx-tree-view hierarchical tree.\n *\n * @tag hx-tree-item\n *\n * @slot - Default slot for the item label content. This text is also used to label the children group.\n * @slot icon - Custom icon shown before the label.\n * @slot children - Nested hx-tree-item elements for sub-tree.\n *\n * @csspart item - The outer item container.\n * @csspart row - The interactive item row (contains expand icon, icon slot, and label).\n * @csspart expand-icon - The expand/collapse toggle button.\n * @csspart label - The label text content area.\n * @csspart children - The children container.\n *\n * @cssprop [--hx-tree-item-color=var(--hx-color-neutral-900)] - Item text color.\n * @cssprop [--hx-tree-item-hover-bg=var(--hx-color-neutral-100)] - Hover background color.\n * @cssprop [--hx-tree-item-selected-bg=var(--hx-color-primary-100)] - Selected background color.\n * @cssprop [--hx-tree-item-selected-color=var(--hx-color-primary-800)] - Selected text color.\n * @cssprop [--hx-tree-item-padding-x=var(--hx-space-2)] - Horizontal padding.\n * @cssprop [--hx-tree-item-padding-y=var(--hx-space-1)] - Vertical padding.\n * @cssprop [--hx-tree-indent-size=1.5rem] - Indentation size per level.\n *\n * @fires {CustomEvent<HxTreeItemSelectDetail>} hx-tree-item-select - Dispatched when this item is clicked or activated via keyboard.\n */\n@customElement('hx-tree-item')\nexport class HelixTreeItem extends LitElement {\n static override styles = [helixTreeItemStyles];\n\n // ─── Properties ───\n\n /**\n * Whether the item is expanded (showing children).\n * @attr expanded\n */\n @property({ type: Boolean, reflect: true })\n expanded = false;\n\n /**\n * Whether the item is selected.\n * @attr selected\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /**\n * Whether the item is disabled (non-interactive).\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── Internal State ───\n\n /**\n * Tracks whether any elements are assigned to the children slot, controlling expand icon visibility.\n * @internal\n */\n @state() private _hasChildren = false;\n\n /**\n * Whether this item is the roving-tabindex active item in the tree.\n * @internal\n */\n @state() private _rovingActive = false;\n\n /**\n * Text content from the default slot, used to label the children group for screen readers.\n * @internal\n */\n @state() private _labelText = '';\n\n /**\n * Cached ARIA position metadata. Computed once on connect and on slotchange\n * of the parent container, avoiding repeated DOM traversal on every render.\n * @internal\n */\n @state() private _level = 1;\n /**\n * One-based position of this item within its sibling set, set as aria-posinset.\n * @internal\n */\n @state() private _posInSet = 1;\n /**\n * Total count of sibling hx-tree-item elements at the same level, set as aria-setsize.\n * @internal\n */\n @state() private _setSize = 1;\n /**\n * Whether the owning hx-tree-view supports item selection (single or multiple mode).\n * @internal\n */\n @state() private _selectable = false;\n\n /** @internal */\n @query('.item-row') private _itemRowEl!: HTMLElement | null;\n\n // ─── Computed ARIA ───\n\n /**\n * Whether this item has slotted children.\n * @returns True if one or more elements are assigned to the children slot.\n */\n get hasChildItems(): boolean {\n return this._hasChildren;\n }\n\n /**\n * The text content of the item's label slot, used for typeahead keyboard navigation.\n * Returns an empty string until the label slot has been assigned.\n */\n get labelText(): string {\n return this._labelText;\n }\n\n /**\n * Recompute all cached ARIA metadata in a single DOM pass.\n * Called on connect, slotchange, and whenever structural context may change.\n * @internal\n */\n private _updateAriaMetadata(): void {\n // Compute nesting level by counting ancestor hx-tree-item elements.\n let level = 1;\n let el: Element | null = this.parentElement;\n while (el) {\n if (el.tagName.toLowerCase() === 'hx-tree-item') level++;\n el = el.parentElement;\n }\n this._level = level;\n\n // Compute position-in-set and set-size from sibling hx-tree-item elements.\n const parent = this.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (c) => c.tagName.toLowerCase() === 'hx-tree-item',\n );\n this._posInSet = siblings.indexOf(this) + 1;\n this._setSize = siblings.length;\n } else {\n this._posInSet = 1;\n this._setSize = 1;\n }\n\n // Determine if the owning tree supports selection.\n const tree = this.closest('hx-tree-view');\n if (tree) {\n const selection = tree.getAttribute('selection');\n this._selectable = selection === 'single' || selection === 'multiple';\n } else {\n this._selectable = false;\n }\n }\n\n /**\n * Set ARIA position metadata from the parent hx-tree-view in a single O(n) pass.\n * Calling this avoids the O(n^2) ancestor-walk + sibling-iteration in _updateAriaMetadata\n * when the parent already knows the layout.\n * @internal\n */\n setAriaMetadata(level: number, posInSet: number, setSize: number, selectable: boolean): void {\n this._level = level;\n this._posInSet = posInSet;\n this._setSize = setSize;\n this._selectable = selectable;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._updateAriaMetadata();\n }\n\n // ─── Children Detection ───\n\n /**\n * Updates _hasChildren and recomputes ARIA metadata when the children slot assignment changes.\n * @internal\n */\n private _handleChildrenSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasChildren = slot.assignedElements().length > 0;\n this._updateAriaMetadata();\n }\n\n /**\n * Captures the text content from the default (label) slot for use on the children group label.\n * @internal\n */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const nodes = slot.assignedNodes({ flatten: true });\n this._labelText = nodes\n .map((n) => n.textContent ?? '')\n .join('')\n .trim();\n }\n\n // ─── Event Handlers ───\n\n /**\n * Toggles the expanded state when the expand/collapse button is clicked, stopping event propagation.\n * @internal\n */\n private _handleExpandClick(e: Event): void {\n e.stopPropagation();\n if (this.disabled) return;\n this.expanded = !this.expanded;\n }\n\n /**\n * Dispatches the hx-tree-item-select event when the item is activated via click or keyboard.\n * @internal\n */\n private _handleRowClick(): void {\n if (this.disabled) return;\n this.dispatchEvent(\n new CustomEvent<HxTreeItemSelectDetail>('hx-tree-item-select', {\n bubbles: true,\n composed: true,\n detail: { item: this },\n }),\n );\n }\n\n /**\n * Handles keyboard interaction for the tree item, including expand/collapse, activation, and delegation of list-navigation keys to the parent tree.\n * @internal\n */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (this.disabled) return;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (this._hasChildren && !this.expanded) {\n this.expanded = true;\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (this._hasChildren && this.expanded) {\n this.expanded = false;\n }\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n this._handleRowClick();\n break;\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Home':\n case 'End':\n // Bubble up to hx-tree-view for navigation\n break;\n }\n }\n\n // ─── Public API ───\n\n /**\n * Sets the roving tabindex state for this item.\n * When `active` is true, the item row gets `tabindex=\"0\"` making it the\n * Tab-reachable item in the tree. All other items should be set to false.\n * Called by the parent hx-tree-view to manage the roving tabindex pattern.\n */\n setRovingActive(active: boolean): void {\n this._rovingActive = active;\n }\n\n /** Focus this item's interactive row element. */\n override focus(): void {\n this._itemRowEl?.focus();\n }\n\n // ─── Render ───\n\n /**\n * Renders the expand/collapse chevron button, or a placeholder span when the item has no children.\n * @internal\n */\n private _renderExpandIcon() {\n if (!this._hasChildren) {\n return html`<span class=\"expand-placeholder\" aria-hidden=\"true\"></span>`;\n }\n return html`\n <button\n part=\"expand-icon\"\n class=\"expand-btn\"\n tabindex=\"-1\"\n aria-label=\"${this.expanded ? 'Collapse' : 'Expand'}\"\n @click=${this._handleExpandClick}\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <polyline points=\"6 4 10 8 6 12\" />\n </svg>\n </button>\n `;\n }\n\n override render() {\n const ariaExpanded = this._hasChildren ? String(this.expanded) : nothing;\n const ariaSelected = this._selectable ? String(this.selected) : nothing;\n\n return html`\n <div part=\"item\" class=\"item\">\n <div\n part=\"row\"\n class=\"item-row\"\n role=\"treeitem\"\n tabindex=${this._rovingActive ? '0' : '-1'}\n aria-expanded=${ariaExpanded}\n aria-selected=${ariaSelected}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-level=${this._level}\n aria-posinset=${this._posInSet}\n aria-setsize=${this._setSize}\n @click=${this._handleRowClick}\n @keydown=${this._handleKeyDown}\n >\n ${this._renderExpandIcon()}\n <span class=\"item-icon\">\n <slot name=\"icon\"></slot>\n </span>\n <span part=\"label\" class=\"item-label\">\n <slot @slotchange=${this._handleLabelSlotChange}></slot>\n </span>\n </div>\n <div\n part=\"children\"\n class=${classMap({ children: true, 'children--expanded': this.expanded })}\n role=\"group\"\n aria-label=${this._labelText ? `${this._labelText} children` : 'children'}\n aria-hidden=${!this.expanded || nothing}\n >\n <div class=\"children-inner\">\n <slot name=\"children\" @slotchange=${this._handleChildrenSlotChange}></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tree-item': HelixTreeItem;\n }\n}\n\n/** Canonical type alias for HelixTreeItem. Use this when typing hx-tree-item element references. */\nexport type HxTreeItem = HelixTreeItem;\n\n/** @deprecated Use {@link HxTreeItem} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcTreeItem = HelixTreeItem;\n"],"names":["helixTreeViewStyles","css","HelixTreeView","LitElement","container","items","child","item","activeIndex","i","index","clamped","_a","wasSelected","currentIndex","focused","_b","next","prev","currentItem","parentItem","_c","parentIndex","matchIndex","char","level","selectable","children","c","setSize","containerTabindex","html","nothing","__decorateClass","property","state","customElement","helixTreeItemStyles","HelixTreeItem","el","parent","siblings","tree","selection","posInSet","slot","nodes","n","active","ariaExpanded","ariaSelected","classMap","query"],"mappings":";;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AC+C5B,IAAMC,IAAN,cAA4BC,EAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA,GAWL,KAAA,QAAQ,IAUR,KAAA,YAA4C,QAKnC,KAAQ,gBAAgB,GAIxB,KAAQ,mBAAmB,IASpC,KAAQ,sBAA8C;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9C,+BAAqC;AAC3C,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,mBAAoC;AAC1C,WAAK,KAAK,wBACR,KAAK,sBAAsB,KAAK,qBAAqB,IAAI,IAEpD,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ,qBAAqBC,GAAqC;AAChE,UAAMC,IAAyB,CAAA;AAC/B,eAAWC,KAAS,MAAM,KAAKF,EAAU,QAAQ;AAC/C,UAAIE,EAAM,QAAQ,YAAA,MAAkB,gBAAgB;AAClD,cAAMC,IAAOD;AACb,QAAAD,EAAM,KAAKE,CAAI,GACXA,EAAK,YACPF,EAAM,KAAK,GAAG,KAAK,qBAAqBE,CAAI,CAAC;AAAA,MAEjD;AACE,QAAAF,EAAM,KAAK,GAAG,KAAK,qBAAqBC,CAAK,CAAC;AAGlD,WAAOD;AAAA,EACT;AAAA;AAAA,EAGQ,oBAAqC;AAC3C,WAAO,MAAM,KAAK,KAAK,iBAAgC,wBAAwB,CAAC;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,sBAAsBA,GAAwBG,GAA2B;AAC/E,IAAAH,EAAM,QAAQ,CAACE,GAAME,MAAM;AACzB,MAAAF,EAAK,gBAAgBE,MAAMD,CAAW;AAAA,IACxC,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,WAAWE,GAAqB;;AACtC,UAAML,IAAQ,KAAK,iBAAA;AACnB,QAAIA,EAAM,WAAW,EAAG;AACxB,UAAMM,IAAU,KAAK,IAAI,GAAG,KAAK,IAAID,GAAOL,EAAM,SAAS,CAAC,CAAC;AAC7D,SAAK,gBAAgBM,GACrB,KAAK,sBAAsBN,GAAOM,CAAO,IACzCC,IAAAP,EAAMM,CAAO,MAAb,QAAAC,EAAgB;AAAA,EAClB;AAAA;AAAA;AAAA,EAKQ,sBAAsB,GAAgB;AAC5C,QAAI,EAAE,aAAa,aAAc;AAEjC,UAAML,IADQ,EACK,OAAO;AAE1B,QAAI,KAAK,cAAc,QAEvB;AAAA,UAAI,KAAK,cAAc,UAAU;AAC/B,cAAMM,IAAcN,EAAK;AACzB,aAAK,kBAAA,EAAoB,QAAQ,CAACE,MAAM;AACtC,UAAAA,EAAE,WAAW;AAAA,QACf,CAAC,GACDF,EAAK,WAAW,CAACM;AAAA,MACnB,MAAA,CAAW,KAAK,cAAc,eAC5BN,EAAK,WAAW,CAACA,EAAK;AAGxB,WAAK;AAAA,QACH,IAAI,YAA4B,aAAa;AAAA,UAC3C,SAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAQ,EAAE,MAAAA,GAAM,UAAUA,EAAK,SAAA;AAAA,QAAS,CACzC;AAAA,MAAA;AAAA;AAAA,EAEL;AAAA;AAAA,EAGQ,eAAe,GAAwB;;AAC7C,UAAMF,IAAQ,KAAK,iBAAA;AACnB,QAAIA,EAAM,WAAW,EAAG;AAExB,QAAIS,IAAe,KAAK;AACxB,UAAMC,IAAU,SAAS;AAEzB,aAASN,IAAI,GAAGA,IAAIJ,EAAM,QAAQI;AAChC,UAAIJ,EAAMI,CAAC,MAAMM,MAAWC,KAAAJ,IAAAP,EAAMI,CAAC,MAAP,gBAAAG,EAAU,eAAV,QAAAI,EAAsB,eAAe;AAC/D,QAAAF,IAAeL;AACf;AAAA,MACF;AAGF,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK,aAAa;AAChB,UAAE,eAAA;AAIF,cAAMQ,IAAOH,IAAeT,EAAM,SAAS,IAAIS,IAAe,IAAI;AAClE,aAAK,WAAWG,CAAI;AACpB;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,UAAE,eAAA;AAEF,cAAMC,IAAOJ,IAAe,IAAIA,IAAe,IAAIT,EAAM,SAAS;AAClE,aAAK,WAAWa,CAAI;AACpB;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,UAAE,eAAA;AACF,cAAMC,IAAcd,EAAMS,CAAY;AACtC,YAAI,CAACK,EAAa;AAClB,YAAIA,EAAY,YAAYA,EAAY;AACtC,UAAAA,EAAY,WAAW,IACvB,KAAK,6BAAA;AAAA,aACA;AACL,gBAAMC,KAAaC,IAAAF,EAAY,kBAAZ,gBAAAE,EAA2B,QAAQ;AAGtD,cAAID,GAAY;AACd,kBAAME,IAAcjB,EAAM,QAAQe,CAAU;AAC5C,YAAIE,KAAe,KACjB,KAAK,WAAWA,CAAW;AAAA,UAE/B;AAAA,QACF;AACA;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,UAAE,eAAA;AACF,cAAMH,IAAcd,EAAMS,CAAY;AACtC,YAAI,CAACK,EAAa;AAClB,QAAIA,EAAY,kBACTA,EAAY,WAIf,KAAK,WAAWL,IAAe,CAAC,KAHhCK,EAAY,WAAW,IACvB,KAAK,6BAAA;AAKT;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AACX,UAAE,eAAA,GACF,KAAK,WAAW,CAAC;AACjB;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,UAAE,eAAA,GACF,KAAK,WAAWd,EAAM,SAAS,CAAC;AAChC;AAAA,MACF;AAAA,MACA,SAAS;AAGP,YAAI,EAAE,IAAI,WAAW,GAAG;AACtB,YAAE,eAAA;AACF,gBAAMkB,IAAa,KAAK,oBAAoB,EAAE,IAAI,YAAA,GAAeT,CAAY;AAC7E,UAAIS,MAAe,MACjB,KAAK,WAAWA,CAAU;AAAA,QAE9B;AACA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAoBC,GAAcV,GAA8B;AACtE,UAAMT,IAAQ,KAAK,iBAAA;AACnB,QAAIA,EAAM,WAAW,EAAG,QAAO;AAC/B,aAASI,IAAI,GAAGA,KAAKJ,EAAM,QAAQI,KAAK;AACtC,YAAMC,KAASI,IAAeL,KAAKJ,EAAM,QACnCE,IAAOF,EAAMK,CAAK;AACxB,UAAIH,KAAQA,EAAK,UAAU,cAAc,WAAWiB,CAAI;AACtD,eAAOd;AAAA,IAEX;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,eAAe,GAAqB;AAI1C,IAAI,EAAE,WAAW,EAAE,iBACH,KAAK,iBAAA,EACT,SAAS,KACjB,KAAK,WAAW,KAAK,aAAa;AAAA,EAGxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,gCAAgCN,GAAoBqB,GAAqB;AAC/E,UAAMC,IAAa,KAAK,cAAc,YAAY,KAAK,cAAc,YAC/DC,IAAW,MAAM,KAAKvB,EAAU,QAAQ,EAAE;AAAA,MAC9C,CAACwB,MAAMA,EAAE,QAAQ,kBAAkB;AAAA,IAAA,GAE/BC,IAAUF,EAAS;AACzB,IAAAA,EAAS,QAAQ,CAACpB,GAAMG,MAAU;AAChC,MAAAH,EAAK,gBAAgBkB,GAAOf,IAAQ,GAAGmB,GAASH,CAAU,GAE1D,KAAK,gCAAgCnB,GAAMkB,IAAQ,CAAC;AAAA,IACtD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,oBAA0B;AAChC,SAAK,6BAAA,GAEL,KAAK,gCAAgC,MAAM,CAAC;AAC5C,UAAMpB,IAAQ,KAAK,iBAAA;AAEnB,QADA,KAAK,mBAAmBA,EAAM,SAAS,GACnCA,EAAM,WAAW,EAAG;AAExB,UAAMM,IAAU,KAAK,IAAI,KAAK,eAAeN,EAAM,SAAS,CAAC;AAC7D,SAAK,gBAAgBM,GACrB,KAAK,sBAAsBN,GAAOM,CAAO;AAAA,EAC3C;AAAA;AAAA,EAIS,eAAqB;AAC5B,IAAK,KAAK;AAAA,EAMZ;AAAA;AAAA,EAIS,SAAS;AAKhB,UAAMmB,IAAoB,KAAK,mBAAmB,OAAO;AAEzD,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKQD,CAAiB;AAAA,qBACf,KAAK,SAAS,MAAM;AAAA,+BACV,KAAK,cAAc,SACtCE,IACA,KAAK,cAAc,aACjB,SACA,OAAO;AAAA,+BACU,KAAK,qBAAqB;AAAA,mBACtC,KAAK,cAAc;AAAA,mBACnB,KAAK,cAAc;AAAA;AAAA,4BAEV,KAAK,iBAAiB;AAAA;AAAA;AAAA,EAGhD;AACF;AAlVa9B,EACK,SAAS,CAACF,CAAmB;AAU7CiC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAV9BhC,EAWX,WAAA,SAAA,CAAA;AAUA+B,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GApB9BhC,EAqBX,WAAA,aAAA,CAAA;AAKiB+B,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA1BIjC,EA0BM,WAAA,iBAAA,CAAA;AAIA+B,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA9BIjC,EA8BM,WAAA,oBAAA,CAAA;AA9BNA,IAAN+B,EAAA;AAAA,EADNG,EAAc,cAAc;AAAA,GAChBlC,CAAA;AC/CN,MAAMmC,IAAsBpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACuC5B,IAAMqC,IAAN,cAA4BnC,EAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA,GAUL,KAAA,WAAW,IAOX,KAAA,WAAW,IAOX,KAAA,WAAW,IAQF,KAAQ,eAAe,IAMvB,KAAQ,gBAAgB,IAMxB,KAAQ,aAAa,IAOrB,KAAQ,SAAS,GAKjB,KAAQ,YAAY,GAKpB,KAAQ,WAAW,GAKnB,KAAQ,cAAc;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW/B,IAAI,gBAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,sBAA4B;AAElC,QAAIsB,IAAQ,GACRc,IAAqB,KAAK;AAC9B,WAAOA;AACL,MAAIA,EAAG,QAAQ,YAAA,MAAkB,kBAAgBd,KACjDc,IAAKA,EAAG;AAEV,SAAK,SAASd;AAGd,UAAMe,IAAS,KAAK;AACpB,QAAIA,GAAQ;AACV,YAAMC,IAAW,MAAM,KAAKD,EAAO,QAAQ,EAAE;AAAA,QAC3C,CAACZ,MAAMA,EAAE,QAAQ,kBAAkB;AAAA,MAAA;AAErC,WAAK,YAAYa,EAAS,QAAQ,IAAI,IAAI,GAC1C,KAAK,WAAWA,EAAS;AAAA,IAC3B;AACE,WAAK,YAAY,GACjB,KAAK,WAAW;AAIlB,UAAMC,IAAO,KAAK,QAAQ,cAAc;AACxC,QAAIA,GAAM;AACR,YAAMC,IAAYD,EAAK,aAAa,WAAW;AAC/C,WAAK,cAAcC,MAAc,YAAYA,MAAc;AAAA,IAC7D;AACE,WAAK,cAAc;AAAA,EAEvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgBlB,GAAemB,GAAkBf,GAAiBH,GAA2B;AAC3F,SAAK,SAASD,GACd,KAAK,YAAYmB,GACjB,KAAK,WAAWf,GAChB,KAAK,cAAcH;AAAA,EACrB;AAAA;AAAA,EAIS,oBAA0B;AACjC,UAAM,kBAAA,GACN,KAAK,oBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,0BAA0B,GAAgB;AAChD,UAAMmB,IAAO,EAAE;AACf,SAAK,eAAeA,EAAK,iBAAA,EAAmB,SAAS,GACrD,KAAK,oBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,GAAgB;AAE7C,UAAMC,IADO,EAAE,OACI,cAAc,EAAE,SAAS,IAAM;AAClD,SAAK,aAAaA,EACf,IAAI,CAACC,MAAMA,EAAE,eAAe,EAAE,EAC9B,KAAK,EAAE,EACP,KAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,mBAAmB,GAAgB;AAEzC,IADA,EAAE,gBAAA,GACE,MAAK,aACT,KAAK,WAAW,CAAC,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAwB;AAC9B,IAAI,KAAK,YACT,KAAK;AAAA,MACH,IAAI,YAAoC,uBAAuB;AAAA,QAC7D,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,MAAM,KAAA;AAAA,MAAK,CACtB;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,GAAwB;AAC7C,QAAI,MAAK;AAET,cAAQ,EAAE,KAAA;AAAA,QACR,KAAK;AACH,YAAE,eAAA,GACE,KAAK,gBAAgB,CAAC,KAAK,aAC7B,KAAK,WAAW;AAElB;AAAA,QACF,KAAK;AACH,YAAE,eAAA,GACE,KAAK,gBAAgB,KAAK,aAC5B,KAAK,WAAW;AAElB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,YAAE,eAAA,GACF,KAAK,gBAAA;AACL;AAAA,MAMA;AAAA,EAEN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,gBAAgBC,GAAuB;AACrC,SAAK,gBAAgBA;AAAA,EACvB;AAAA;AAAA,EAGS,QAAc;;AACrB,KAAApC,IAAA,KAAK,eAAL,QAAAA,EAAiB;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,oBAAoB;AAC1B,WAAK,KAAK,eAGHmB;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKW,KAAK,WAAW,aAAa,QAAQ;AAAA,iBAC1C,KAAK,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAR3BA;AAAA,EAeX;AAAA,EAES,SAAS;AAChB,UAAMkB,IAAe,KAAK,eAAe,OAAO,KAAK,QAAQ,IAAIjB,GAC3DkB,IAAe,KAAK,cAAc,OAAO,KAAK,QAAQ,IAAIlB;AAEhE,WAAOD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMU,KAAK,gBAAgB,MAAM,IAAI;AAAA,0BAC1BkB,CAAY;AAAA,0BACZC,CAAY;AAAA,0BACZ,KAAK,WAAW,SAASlB,CAAO;AAAA,uBACnC,KAAK,MAAM;AAAA,0BACR,KAAK,SAAS;AAAA,yBACf,KAAK,QAAQ;AAAA,mBACnB,KAAK,eAAe;AAAA,qBAClB,KAAK,cAAc;AAAA;AAAA,YAE5B,KAAK,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,gCAKJ,KAAK,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKzCmB,EAAS,EAAE,UAAU,IAAM,sBAAsB,KAAK,UAAU,CAAC;AAAA;AAAA,uBAE5D,KAAK,aAAa,GAAG,KAAK,UAAU,cAAc,UAAU;AAAA,wBAC3D,CAAC,KAAK,YAAYnB,CAAO;AAAA;AAAA;AAAA,gDAGD,KAAK,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK5E;AACF;AA7TaM,EACK,SAAS,CAACD,CAAmB;AAS7CJ,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAT/BI,EAUX,WAAA,YAAA,CAAA;AAOAL,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAhB/BI,EAiBX,WAAA,YAAA,CAAA;AAOAL,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAvB/BI,EAwBX,WAAA,YAAA,CAAA;AAQiBL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAhCIG,EAgCM,WAAA,gBAAA,CAAA;AAMAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAtCIG,EAsCM,WAAA,iBAAA,CAAA;AAMAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA5CIG,EA4CM,WAAA,cAAA,CAAA;AAOAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAnDIG,EAmDM,WAAA,UAAA,CAAA;AAKAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAxDIG,EAwDM,WAAA,aAAA,CAAA;AAKAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA7DIG,EA6DM,WAAA,YAAA,CAAA;AAKAL,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAlEIG,EAkEM,WAAA,eAAA,CAAA;AAGWL,EAAA;AAAA,EAA3BmB,EAAM,WAAW;AAAA,GArEPd,EAqEiB,WAAA,cAAA,CAAA;AArEjBA,IAANL,EAAA;AAAA,EADNG,EAAc,cAAc;AAAA,GAChBE,CAAA;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"toast-factory-CEMNOt1T.js","sources":["../../src/components/hx-toast/hx-toast.styles.ts","../../src/components/hx-toast/hx-toast.ts","../../src/components/hx-toast/hx-toast-stack.ts","../../src/components/hx-toast/toast-factory.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixToastStyles = css`\n /* ─── hx-toast host ─── */\n\n :host {\n display: block;\n pointer-events: none;\n }\n\n :host([open]) {\n pointer-events: auto;\n }\n\n /* ─── Toast base ─── */\n\n .toast {\n display: flex;\n align-items: flex-start;\n gap: var(--hx-space-3, 0.75rem);\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\n border-radius: var(--hx-toast-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-toast-bg, var(--hx-color-neutral-900, #0f172a));\n color: var(--hx-toast-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-sm, 0.875rem);\n line-height: var(--hx-line-height-normal, 1.5);\n box-shadow: var(\n --hx-toast-shadow,\n 0 4px 6px -1px rgb(0 0 0 / 0.1),\n 0 2px 4px -2px rgb(0 0 0 / 0.1)\n );\n opacity: 0;\n transform: translateY(var(--hx-toast-enter-translate, var(--hx-space-2, 0.5rem)));\n transition:\n opacity var(--hx-transition-normal, 250ms ease),\n transform var(--hx-transition-normal, 250ms ease);\n width: var(--hx-toast-width, 20rem);\n max-width: 100%;\n pointer-events: auto;\n }\n\n :host([open]) .toast {\n opacity: 1;\n transform: translateY(0);\n }\n\n /* ─── Variant overrides ─── */\n\n .toast--success {\n --hx-toast-bg: var(--hx-color-success-600, #16a34a);\n --hx-toast-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .toast--warning {\n --hx-toast-bg: var(--hx-color-warning-500, #f59e0b);\n --hx-toast-color: var(--hx-color-neutral-900, #0f172a);\n }\n\n .toast--danger {\n --hx-toast-bg: var(--hx-color-error-600, #dc2626);\n --hx-toast-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .toast--info {\n --hx-toast-bg: var(--hx-color-primary-600, #2563eb);\n --hx-toast-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n /* ─── Severity Label (WCAG 1.4.1) ─── */\n /* Visually hidden — non-color cue for severity variants (success/warning/danger/info). */\n /* Ensures variant is not conveyed by color alone for color-blind users. */\n\n .toast__severity-label {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Icon ─── */\n\n .toast__icon {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n line-height: 1;\n }\n\n .toast__icon:empty {\n display: none;\n }\n\n /* ─── Message ─── */\n\n .toast__message {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n /* ─── Action slot ─── */\n\n .toast__action {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n }\n\n .toast__action:empty {\n display: none;\n }\n\n /* ─── Close button ─── */\n\n .toast__close {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* WCAG 2.5.5: minimum 44×44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n padding: var(--hx-space-1, 0.25rem);\n background: transparent;\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n color: inherit;\n cursor: pointer;\n opacity: var(--hx-opacity-75, 0.75);\n transition: opacity var(--hx-transition-fast, 150ms ease);\n }\n\n .toast__close:hover {\n opacity: 1;\n }\n\n .toast__close:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid currentColor;\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Reduced motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .toast {\n transition: none;\n }\n\n .toast__close {\n transition: none;\n }\n }\n`;\n\nexport const helixToastStackStyles = css`\n :host {\n display: block;\n position: fixed;\n z-index: var(--hx-z-index-toast, 1700);\n pointer-events: none;\n }\n\n .toast-stack {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-3, 0.75rem);\n padding: var(--hx-space-4, 1rem);\n pointer-events: none;\n }\n\n /* ─── Placements ─── */\n\n :host([placement='top-start']) {\n top: 0;\n inset-inline-start: 0;\n inset-inline-end: auto;\n bottom: auto;\n }\n\n :host([placement='top-center']) {\n top: 0;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n inset-inline-end: auto;\n bottom: auto;\n }\n\n :host([placement='top-end']) {\n top: 0;\n inset-inline-end: 0;\n inset-inline-start: auto;\n bottom: auto;\n }\n\n :host([placement='bottom-start']) {\n bottom: 0;\n inset-inline-start: 0;\n inset-inline-end: auto;\n top: auto;\n }\n\n :host([placement='bottom-center']) {\n bottom: 0;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n inset-inline-end: auto;\n top: auto;\n }\n\n :host([placement='bottom-end']) {\n bottom: 0;\n inset-inline-end: 0;\n inset-inline-start: auto;\n top: auto;\n }\n\n /* ─── Bottom placements: reverse order so newest is on top ─── */\n\n :host([placement^='bottom']) .toast-stack {\n flex-direction: column-reverse;\n }\n\n /* ─── Slide direction by placement ─── */\n\n :host([placement^='top']) ::slotted(hx-toast) {\n --hx-toast-enter-translate: calc(var(--hx-space-2, 0.5rem) * -1);\n }\n`;\n","import { LitElement, 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 { helixToastStyles } from './hx-toast.styles.js';\n\nexport type ToastVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\n/**\n * A transient notification message that auto-dismisses after a configurable duration.\n * Supports multiple visual variants, a closable button, icon/action slots, and full\n * ARIA live region semantics for screen readers.\n *\n * @summary Transient notification toast component.\n *\n * @tag hx-toast\n *\n * @slot - Default slot for the notification message.\n * @slot icon - Optional icon rendered before the message.\n * @slot action - Optional action button rendered after the message.\n *\n * @fires {CustomEvent} hx-show - Dispatched when the toast becomes visible.\n * @fires {CustomEvent} hx-hide - Dispatched when the toast begins hiding.\n * @fires {CustomEvent} hx-after-hide - Dispatched after the hide animation completes.\n *\n * @csspart base - The inner toast container div.\n * @csspart icon - The icon slot wrapper.\n * @csspart message - The message slot wrapper.\n * @csspart close-button - The dismiss button (only when closable).\n * @csspart action - The action slot wrapper.\n *\n * @cssprop [--hx-toast-bg=var(--hx-color-neutral-900)] - Toast background color.\n * @cssprop [--hx-toast-color=var(--hx-color-neutral-0)] - Toast text color.\n * @cssprop [--hx-toast-border-radius=var(--hx-border-radius-md)] - Toast border radius.\n * @cssprop [--hx-toast-shadow] - Toast box shadow.\n * @cssprop [--hx-toast-width=20rem] - Toast width.\n */\n@customElement('hx-toast')\nexport class HelixToast extends LitElement {\n static override styles = [helixToastStyles];\n\n // ─── Public Properties ───\n\n /**\n * Visual style variant.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'success' | 'warning' | 'danger' | 'info' = 'default';\n\n /**\n * Auto-dismiss duration in milliseconds. Set to 0 for persistent toasts.\n * @attr duration\n */\n @property({ type: Number })\n duration = 5000;\n\n /**\n * Whether to show a close button.\n * @attr closable\n */\n @property({ type: Boolean, reflect: true })\n closable = false;\n\n /**\n * Whether the toast is currently visible.\n * @attr open\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Accessible label for the close button. Override for localization.\n * @attr label-close\n */\n @property({ attribute: 'label-close' })\n labelClose = 'Dismiss notification';\n\n // ─── Private State ───\n\n /** @internal */\n @query('.toast') private _toastEl!: HTMLElement | null;\n\n /** @internal Tracks whether the action slot has slotted content. */\n @state() private _hasActionContent = false;\n\n /** @internal */\n private _timer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Reduced Motion ───\n\n /** @internal Returns true when the user has opted into reduced motion. */\n private get _reducedMotion(): boolean {\n // Guard for SSR — window.matchMedia is unavailable server-side\n if (typeof window === 'undefined') return false;\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n\n /** @internal */\n private _timerStartedAt: number | null = null;\n\n /** @internal */\n private _timerRemaining: number | null = null;\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('open')) {\n if (this.open) {\n this.removeAttribute('aria-hidden');\n this._emitShow();\n if (this.duration > 0 && !this._reducedMotion && !this._hasActionContent) {\n this._startTimer();\n }\n } else {\n this.setAttribute('aria-hidden', 'true');\n this._clearTimer();\n this._emitHide();\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._clearTimer();\n }\n\n // ─── Public API ───\n\n /** Show the toast. */\n show(): void {\n if (!this.open) {\n this.open = true;\n }\n }\n\n /** Hide the toast. */\n hide(): void {\n if (this.open) {\n this.open = false;\n }\n }\n\n // ─── Private Helpers ───\n\n /** @internal */\n private _startTimer(remaining?: number): void {\n this._clearTimerHandle();\n const delay = remaining ?? this.duration;\n this._timerStartedAt = Date.now();\n this._timerRemaining = delay;\n this._timer = setTimeout(() => {\n this.open = false;\n }, delay);\n }\n\n /** @internal */\n private _pauseTimer(): void {\n if (this._timer === null || this._timerStartedAt === null || this._timerRemaining === null) {\n return;\n }\n const elapsed = Date.now() - this._timerStartedAt;\n this._timerRemaining = Math.max(0, this._timerRemaining - elapsed);\n this._clearTimerHandle();\n }\n\n /** @internal */\n private _clearTimerHandle(): void {\n if (this._timer !== null) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n }\n\n /** @internal */\n private _clearTimer(): void {\n this._clearTimerHandle();\n this._timerStartedAt = null;\n this._timerRemaining = null;\n }\n\n /** @internal */\n private _emitShow(): void {\n this.dispatchEvent(new CustomEvent<void>('hx-show', { bubbles: true, composed: true }));\n }\n\n /** @internal */\n private _emitHide(): void {\n this.dispatchEvent(new CustomEvent<void>('hx-hide', { bubbles: true, composed: true }));\n\n let fired = false;\n const fireAfterHide = () => {\n if (fired) return;\n fired = true;\n this.dispatchEvent(new CustomEvent<void>('hx-after-hide', { bubbles: true, composed: true }));\n };\n\n // Fire on transitionend if available; fallback ensures it fires in test environments\n // and when transitions are disabled (prefers-reduced-motion, no CSS transitions).\n const base = this._toastEl;\n if (base) {\n base.addEventListener('transitionend', fireAfterHide, { once: true });\n }\n // Fallback fires after the CSS transition duration (250ms) plus a small buffer.\n setTimeout(fireAfterHide, 300);\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _handleMouseEnter(): void {\n this._pauseTimer();\n }\n\n /** @internal */\n private _handleMouseLeave(): void {\n if (this.open && this.duration > 0) {\n this._startTimer(this._timerRemaining ?? undefined);\n }\n }\n\n /** @internal */\n private _handleFocusIn(): void {\n this._pauseTimer();\n }\n\n /** @internal */\n private _handleFocusOut(): void {\n if (this.open && this.duration > 0) {\n this._startTimer(this._timerRemaining ?? undefined);\n }\n }\n\n /** @internal */\n private _handleClose(): void {\n this.hide();\n }\n\n /** @internal */\n private _handleActionSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasActionContent = slot.assignedNodes({ flatten: true }).length > 0;\n if (this._hasActionContent && this.open) {\n this._pauseTimer();\n }\n }\n\n // ─── ARIA Helpers ───\n\n /** @internal */\n private get _role(): 'alert' | 'status' {\n return this.variant === 'danger' ? 'alert' : 'status';\n }\n\n /** @internal */\n private get _ariaLive(): 'assertive' | 'polite' {\n return this.variant === 'danger' ? 'assertive' : 'polite';\n }\n\n // ─── WCAG 1.4.1: Default Icons ───\n // Each semantic variant renders a default icon when no icon is slotted,\n // ensuring the severity is not conveyed by color alone.\n\n /** @internal */\n private _renderSuccessIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\" width=\"16\" height=\"16\">\n <path\n fill=\"currentColor\"\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm3.03 6.28a.75.75 0 00-1.06-1.06L9 10.19 7.78 8.97a.75.75 0 00-1.06 1.06l1.75 1.75a.75.75 0 001.06 0l3.5-3.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderWarningIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\" width=\"16\" height=\"16\">\n <path\n fill=\"currentColor\"\n d=\"M8.49 2.92a1.75 1.75 0 013.02 0l6.25 10.83A1.75 1.75 0 0116.25 16H3.75a1.75 1.75 0 01-1.51-2.25L8.49 2.92zM10 7a.75.75 0 01.75.75v3a.75.75 0 01-1.5 0v-3A.75.75 0 0110 7zm0 7.5a.75.75 0 100-1.5.75.75 0 000 1.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderDangerIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\" width=\"16\" height=\"16\">\n <path\n fill=\"currentColor\"\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm-1.72 5.22a.75.75 0 011.06 0L10 7.94l.66-.72a.75.75 0 111.06 1.06L11.06 9l.66.72a.75.75 0 11-1.06 1.06L10 10.06l-.66.72a.75.75 0 01-1.06-1.06L8.94 9l-.66-.72a.75.75 0 010-1.06z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderInfoIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\" width=\"16\" height=\"16\">\n <path\n fill=\"currentColor\"\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm.75 4.75a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM9.25 9a.75.75 0 011.5 0v4a.75.75 0 01-1.5 0V9z\"\n />\n </svg>`;\n }\n\n /** @internal Returns the default icon for the current variant, or nothing for 'default'. */\n private get _defaultIcon() {\n switch (this.variant) {\n case 'success':\n return this._renderSuccessIcon();\n case 'warning':\n return this._renderWarningIcon();\n case 'danger':\n return this._renderDangerIcon();\n case 'info':\n return this._renderInfoIcon();\n default:\n return nothing;\n }\n }\n\n // ─── WCAG 1.4.1: Severity label map ───\n\n /** @internal */\n private static readonly _SEVERITY_LABELS: Partial<Record<ToastVariant, string>> = {\n success: 'Success',\n warning: 'Warning',\n danger: 'Error',\n info: 'Info',\n };\n\n /** @internal */\n private get _severityLabel(): string {\n return HelixToast._SEVERITY_LABELS[this.variant] ?? '';\n }\n\n // ─── Render ───\n\n override render() {\n const severityLabel = this._severityLabel;\n\n return html`\n <div\n part=\"base\"\n class=${classMap({\n toast: true,\n [`toast--${this.variant}`]: true,\n })}\n role=${this._role}\n aria-live=${this._ariaLive}\n aria-atomic=\"true\"\n @mouseenter=${this._handleMouseEnter}\n @mouseleave=${this._handleMouseLeave}\n @focusin=${this._handleFocusIn}\n @focusout=${this._handleFocusOut}\n >\n ${this.open\n ? html`\n ${severityLabel\n ? html`<span class=\"toast__severity-label\">${severityLabel}: </span>`\n : nothing}\n <span part=\"icon\" class=\"toast__icon\">\n <slot name=\"icon\">${this._defaultIcon}</slot>\n </span>\n <span part=\"message\" class=\"toast__message\">\n <slot></slot>\n </span>\n <span part=\"action\" class=\"toast__action\">\n <slot name=\"action\" @slotchange=${this._handleActionSlotChange}></slot>\n </span>\n ${this.closable\n ? html`\n <button\n part=\"close-button\"\n class=\"toast__close\"\n aria-label=${this.labelClose}\n @click=${this._handleClose}\n >\n <svg\n aria-hidden=\"true\"\n width=\"16\"\n height=\"16\"\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 <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n </button>\n `\n : nothing}\n `\n : nothing}\n </div>\n `;\n }\n}\n\n// ─── Declarative Global Types ───\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-toast': HelixToast;\n }\n}\n","import { LitElement, html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { helixToastStackStyles } from './hx-toast.styles.js';\n\nexport type ToastStackPlacement =\n | 'top-start'\n | 'top-center'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-center'\n | 'bottom-end';\n\n/**\n * A fixed-position container that stacks `hx-toast` elements at the specified\n * corner of the viewport. Enforces a maximum visible toast count via `stack-limit`.\n *\n * @summary Toast stack container managing position and count limits.\n *\n * @tag hx-toast-stack\n *\n * @slot - Accepts `hx-toast` elements.\n *\n * @csspart base - The inner stack container div.\n *\n * @cssprop [--hx-z-index-toast=9000] - Z-index for the fixed stack.\n */\n@customElement('hx-toast-stack')\nexport class HelixToastStack extends LitElement {\n static override styles = [helixToastStackStyles];\n\n /**\n * Corner of the viewport where toasts appear.\n * @attr placement\n */\n @property({ type: String, reflect: true })\n placement:\n | 'top-start'\n | 'top-center'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-center'\n | 'bottom-end' = 'bottom-end';\n\n /**\n * Maximum number of simultaneously visible toasts. 0 = unlimited.\n * @attr stack-limit\n */\n @property({ type: Number, attribute: 'stack-limit' })\n stackLimit = 3;\n\n override render() {\n return html`\n <div\n part=\"base\"\n class=${classMap({\n 'toast-stack': true,\n [`toast-stack--${this.placement}`]: true,\n })}\n >\n <slot></slot>\n </div>\n `;\n }\n}\n\n// ─── Declarative Global Types ───\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-toast-stack': HelixToastStack;\n }\n}\n","import { HelixToast } from './hx-toast.js';\nimport { HelixToastStack } from './hx-toast-stack.js';\nimport type { ToastVariant } from './hx-toast.js';\nimport type { ToastStackPlacement } from './hx-toast-stack.js';\n\nexport interface ToastOptions {\n /** The notification message text. */\n message: string;\n /** Visual variant. Defaults to 'default'. */\n variant?: ToastVariant;\n /** Auto-dismiss duration in ms. 0 = persistent. Defaults to 3000. */\n duration?: number;\n /** Placement of the shared stack. Defaults to 'bottom-end'. */\n placement?: ToastStackPlacement;\n}\n\n/**\n * Imperatively create and display a toast notification.\n *\n * Creates a shared `hx-toast-stack` on `document.body` if one does not exist,\n * then appends a new `hx-toast` with the given options. Respects the stack's\n * `stackLimit` by hiding the oldest visible toast when the limit is exceeded.\n *\n * @example\n * import { toast } from '@helixui/library/components/hx-toast/index.js';\n * toast({ message: 'Patient record saved.', variant: 'success' });\n */\nexport function toast(options: ToastOptions): HelixToast {\n if (typeof document === 'undefined') throw new Error('toast() requires a browser environment');\n const placement = options.placement ?? 'bottom-end';\n\n // Find or create a dedicated stack for this placement\n const stackSelector = `hx-toast-stack[placement=\"${placement}\"]`;\n let stack = document.querySelector<HelixToastStack>(stackSelector);\n if (!stack) {\n stack = document.createElement('hx-toast-stack');\n stack.placement = placement;\n // Intentional design decision: the toast stack is appended to document.body rather\n // than inserted near the caller. This is required so that the fixed-position overlay\n // is not clipped by an ancestor with `overflow: hidden`, `transform`, or `filter`\n // (all of which create a new stacking context and break fixed positioning).\n // Drupal compatibility note: Drupal's BigPipe / AJAX behaviors can re-attach the\n // document body without removing these stacks. The selector check above\n // (`document.querySelector`) ensures only one stack per placement is ever created,\n // preventing duplicates on re-attach cycles.\n document.body.appendChild(stack);\n }\n\n // Enforce stack limit: hide oldest open toast if at capacity\n if (stack.stackLimit > 0) {\n const openToasts = [...stack.querySelectorAll<HelixToast>('hx-toast')].filter((t) => t.open);\n if (openToasts.length >= stack.stackLimit) {\n openToasts[0]?.hide();\n }\n }\n\n // Create toast element\n const toastEl = document.createElement('hx-toast');\n toastEl.variant = options.variant ?? 'default';\n toastEl.duration = options.duration ?? 3000;\n toastEl.closable = true;\n toastEl.textContent = options.message;\n\n // Remove from DOM after hiding\n toastEl.addEventListener('hx-after-hide', () => {\n toastEl.remove();\n });\n\n stack.appendChild(toastEl);\n toastEl.show();\n\n return toastEl;\n}\n"],"names":["helixToastStyles","css","helixToastStackStyles","HelixToast","LitElement","changedProperties","remaining","delay","elapsed","fired","fireAfterHide","base","e","slot","html","nothing","severityLabel","classMap","__decorateClass","property","query","state","customElement","HelixToastStack","toast","options","placement","stackSelector","stack","openToasts","t","_a","toastEl"],"mappings":";;;;AAEO,MAAMA,IAAmBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GA6JnBC,IAAwBD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACzH9B,IAAME,IAAN,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"}