@fusion.dev/helix-headless 0.0.0-dev

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 (424) hide show
  1. package/LICENSE +21 -0
  2. package/custom-elements.json +75202 -0
  3. package/dist/accordion/index.d.ts +2 -0
  4. package/dist/accordion/index.js +2 -0
  5. package/dist/accordion/item/accordion-item.d.ts +141 -0
  6. package/dist/accordion/item/accordion-item.js +214 -0
  7. package/dist/accordion/root/accordion-root.d.ts +57 -0
  8. package/dist/accordion/root/accordion-root.js +96 -0
  9. package/dist/announcement/index.d.ts +1 -0
  10. package/dist/announcement/index.js +1 -0
  11. package/dist/announcement/root/announcement-root.d.ts +106 -0
  12. package/dist/announcement/root/announcement-root.js +144 -0
  13. package/dist/app-header/index.d.ts +1 -0
  14. package/dist/app-header/index.js +1 -0
  15. package/dist/app-header/root/app-header-root.d.ts +113 -0
  16. package/dist/app-header/root/app-header-root.js +147 -0
  17. package/dist/avatar/group/avatar-group.d.ts +116 -0
  18. package/dist/avatar/group/avatar-group.js +136 -0
  19. package/dist/avatar/index.d.ts +2 -0
  20. package/dist/avatar/index.js +2 -0
  21. package/dist/avatar/root/avatar-root.d.ts +71 -0
  22. package/dist/avatar/root/avatar-root.js +147 -0
  23. package/dist/badge/index.d.ts +1 -0
  24. package/dist/badge/index.js +1 -0
  25. package/dist/badge/root/badge-root.d.ts +61 -0
  26. package/dist/badge/root/badge-root.js +121 -0
  27. package/dist/bar-chart/index.d.ts +1 -0
  28. package/dist/bar-chart/index.js +1 -0
  29. package/dist/bar-chart/root/bar-chart-root.d.ts +266 -0
  30. package/dist/bar-chart/root/bar-chart-root.js +515 -0
  31. package/dist/blockquote/index.d.ts +1 -0
  32. package/dist/blockquote/index.js +1 -0
  33. package/dist/blockquote/root/blockquote-root.d.ts +51 -0
  34. package/dist/blockquote/root/blockquote-root.js +84 -0
  35. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +104 -0
  36. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +137 -0
  37. package/dist/breadcrumbs/index.d.ts +2 -0
  38. package/dist/breadcrumbs/index.js +2 -0
  39. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +77 -0
  40. package/dist/breadcrumbs/root/breadcrumbs-root.js +94 -0
  41. package/dist/button/index.d.ts +1 -0
  42. package/dist/button/index.js +1 -0
  43. package/dist/button/root/button-root.d.ts +251 -0
  44. package/dist/button/root/button-root.js +401 -0
  45. package/dist/button-group/index.d.ts +1 -0
  46. package/dist/button-group/index.js +1 -0
  47. package/dist/button-group/root/button-group-root.d.ts +62 -0
  48. package/dist/button-group/root/button-group-root.js +62 -0
  49. package/dist/callout/index.d.ts +1 -0
  50. package/dist/callout/index.js +1 -0
  51. package/dist/callout/root/callout-root.d.ts +72 -0
  52. package/dist/callout/root/callout-root.js +90 -0
  53. package/dist/card/index.d.ts +1 -0
  54. package/dist/card/index.js +1 -0
  55. package/dist/card/root/card-root.d.ts +54 -0
  56. package/dist/card/root/card-root.js +71 -0
  57. package/dist/carousel/index.d.ts +1 -0
  58. package/dist/carousel/index.js +1 -0
  59. package/dist/carousel/root/carousel-root.d.ts +399 -0
  60. package/dist/carousel/root/carousel-root.js +723 -0
  61. package/dist/chat/composer/chat-composer.d.ts +160 -0
  62. package/dist/chat/composer/chat-composer.js +273 -0
  63. package/dist/chat/index.d.ts +3 -0
  64. package/dist/chat/index.js +3 -0
  65. package/dist/chat/message/chat-message.d.ts +170 -0
  66. package/dist/chat/message/chat-message.js +271 -0
  67. package/dist/chat/root/chat-root.d.ts +216 -0
  68. package/dist/chat/root/chat-root.js +389 -0
  69. package/dist/checkbox/index.d.ts +1 -0
  70. package/dist/checkbox/index.js +1 -0
  71. package/dist/checkbox/root/checkbox-root.d.ts +108 -0
  72. package/dist/checkbox/root/checkbox-root.js +207 -0
  73. package/dist/checkbox-group/index.d.ts +1 -0
  74. package/dist/checkbox-group/index.js +1 -0
  75. package/dist/checkbox-group/root/checkbox-group-root.d.ts +155 -0
  76. package/dist/checkbox-group/root/checkbox-group-root.js +293 -0
  77. package/dist/code/index.d.ts +1 -0
  78. package/dist/code/index.js +1 -0
  79. package/dist/code/root/code-root.d.ts +36 -0
  80. package/dist/code/root/code-root.js +43 -0
  81. package/dist/code-block/index.d.ts +1 -0
  82. package/dist/code-block/index.js +1 -0
  83. package/dist/code-block/root/code-block-root.d.ts +112 -0
  84. package/dist/code-block/root/code-block-root.js +155 -0
  85. package/dist/color-input/index.d.ts +1 -0
  86. package/dist/color-input/index.js +1 -0
  87. package/dist/color-input/root/color-input-root.d.ts +227 -0
  88. package/dist/color-input/root/color-input-root.js +456 -0
  89. package/dist/color-picker/color.d.ts +74 -0
  90. package/dist/color-picker/color.js +238 -0
  91. package/dist/color-picker/index.d.ts +2 -0
  92. package/dist/color-picker/index.js +2 -0
  93. package/dist/color-picker/root/color-picker-root.d.ts +303 -0
  94. package/dist/color-picker/root/color-picker-root.js +576 -0
  95. package/dist/combobox/index.d.ts +1 -0
  96. package/dist/combobox/index.js +1 -0
  97. package/dist/combobox/root/combobox-root.d.ts +396 -0
  98. package/dist/combobox/root/combobox-root.js +808 -0
  99. package/dist/command/index.d.ts +1 -0
  100. package/dist/command/index.js +1 -0
  101. package/dist/command/root/command-root.d.ts +166 -0
  102. package/dist/command/root/command-root.js +353 -0
  103. package/dist/copy-button/index.d.ts +1 -0
  104. package/dist/copy-button/index.js +1 -0
  105. package/dist/copy-button/root/copy-button-root.d.ts +154 -0
  106. package/dist/copy-button/root/copy-button-root.js +225 -0
  107. package/dist/data-table/index.d.ts +2 -0
  108. package/dist/data-table/index.js +2 -0
  109. package/dist/data-table/root/data-table-root.d.ts +392 -0
  110. package/dist/data-table/root/data-table-root.js +729 -0
  111. package/dist/data-table/root/order.d.ts +116 -0
  112. package/dist/data-table/root/order.js +175 -0
  113. package/dist/date-input/index.d.ts +1 -0
  114. package/dist/date-input/index.js +1 -0
  115. package/dist/date-input/root/date-input-root.d.ts +361 -0
  116. package/dist/date-input/root/date-input-root.js +791 -0
  117. package/dist/date-picker/index.d.ts +1 -0
  118. package/dist/date-picker/index.js +1 -0
  119. package/dist/date-picker/root/date-picker-root.d.ts +361 -0
  120. package/dist/date-picker/root/date-picker-root.js +837 -0
  121. package/dist/dialog/index.d.ts +1 -0
  122. package/dist/dialog/index.js +1 -0
  123. package/dist/dialog/root/dialog-root.d.ts +185 -0
  124. package/dist/dialog/root/dialog-root.js +319 -0
  125. package/dist/divider/index.d.ts +1 -0
  126. package/dist/divider/index.js +1 -0
  127. package/dist/divider/root/divider-root.d.ts +68 -0
  128. package/dist/divider/root/divider-root.js +116 -0
  129. package/dist/donut-chart/index.d.ts +1 -0
  130. package/dist/donut-chart/index.js +1 -0
  131. package/dist/donut-chart/root/donut-chart-root.d.ts +209 -0
  132. package/dist/donut-chart/root/donut-chart-root.js +395 -0
  133. package/dist/drawer/index.d.ts +1 -0
  134. package/dist/drawer/index.js +1 -0
  135. package/dist/drawer/root/drawer-root.d.ts +144 -0
  136. package/dist/drawer/root/drawer-root.js +222 -0
  137. package/dist/drilldown/index.d.ts +2 -0
  138. package/dist/drilldown/index.js +2 -0
  139. package/dist/drilldown/item/drilldown-item.d.ts +87 -0
  140. package/dist/drilldown/item/drilldown-item.js +152 -0
  141. package/dist/drilldown/root/drilldown-root.d.ts +115 -0
  142. package/dist/drilldown/root/drilldown-root.js +263 -0
  143. package/dist/element-events.generated.d.ts +1 -0
  144. package/dist/element-events.generated.js +125 -0
  145. package/dist/empty/index.d.ts +1 -0
  146. package/dist/empty/index.js +1 -0
  147. package/dist/empty/root/empty-root.d.ts +47 -0
  148. package/dist/empty/root/empty-root.js +68 -0
  149. package/dist/file-input/index.d.ts +1 -0
  150. package/dist/file-input/index.js +1 -0
  151. package/dist/file-input/root/file-input-root.d.ts +196 -0
  152. package/dist/file-input/root/file-input-root.js +488 -0
  153. package/dist/format-date/index.d.ts +1 -0
  154. package/dist/format-date/index.js +1 -0
  155. package/dist/format-date/root/format-date-root.d.ts +151 -0
  156. package/dist/format-date/root/format-date-root.js +266 -0
  157. package/dist/heatmap/index.d.ts +2 -0
  158. package/dist/heatmap/index.js +2 -0
  159. package/dist/heatmap/root/buckets.d.ts +62 -0
  160. package/dist/heatmap/root/buckets.js +85 -0
  161. package/dist/heatmap/root/heatmap-root.d.ts +330 -0
  162. package/dist/heatmap/root/heatmap-root.js +526 -0
  163. package/dist/icon/index.d.ts +1 -0
  164. package/dist/icon/index.js +1 -0
  165. package/dist/icon/root/icon-root.d.ts +53 -0
  166. package/dist/icon/root/icon-root.js +93 -0
  167. package/dist/icon-button/index.d.ts +1 -0
  168. package/dist/icon-button/index.js +1 -0
  169. package/dist/icon-button/root/icon-button-root.d.ts +40 -0
  170. package/dist/icon-button/root/icon-button-root.js +46 -0
  171. package/dist/image/index.d.ts +1 -0
  172. package/dist/image/index.js +1 -0
  173. package/dist/image/root/image-root.d.ts +213 -0
  174. package/dist/image/root/image-root.js +335 -0
  175. package/dist/index.d.ts +99 -0
  176. package/dist/index.js +99 -0
  177. package/dist/input/index.d.ts +1 -0
  178. package/dist/input/index.js +1 -0
  179. package/dist/input/root/input-root.d.ts +281 -0
  180. package/dist/input/root/input-root.js +472 -0
  181. package/dist/kbd/index.d.ts +1 -0
  182. package/dist/kbd/index.js +1 -0
  183. package/dist/kbd/root/kbd-root.d.ts +98 -0
  184. package/dist/kbd/root/kbd-root.js +230 -0
  185. package/dist/legend/index.d.ts +1 -0
  186. package/dist/legend/index.js +1 -0
  187. package/dist/legend/root/legend-root.d.ts +83 -0
  188. package/dist/legend/root/legend-root.js +125 -0
  189. package/dist/line-chart/index.d.ts +1 -0
  190. package/dist/line-chart/index.js +1 -0
  191. package/dist/line-chart/root/line-chart-root.d.ts +238 -0
  192. package/dist/line-chart/root/line-chart-root.js +365 -0
  193. package/dist/list/index.d.ts +2 -0
  194. package/dist/list/index.js +2 -0
  195. package/dist/list/item/list-item.d.ts +95 -0
  196. package/dist/list/item/list-item.js +148 -0
  197. package/dist/list/root/list-root.d.ts +72 -0
  198. package/dist/list/root/list-root.js +61 -0
  199. package/dist/listbox/index.d.ts +1 -0
  200. package/dist/listbox/index.js +1 -0
  201. package/dist/listbox/root/listbox-root.d.ts +357 -0
  202. package/dist/listbox/root/listbox-root.js +890 -0
  203. package/dist/loader/index.d.ts +1 -0
  204. package/dist/loader/index.js +1 -0
  205. package/dist/loader/root/loader-root.d.ts +52 -0
  206. package/dist/loader/root/loader-root.js +74 -0
  207. package/dist/megamenu/index.d.ts +1 -0
  208. package/dist/megamenu/index.js +1 -0
  209. package/dist/megamenu/root/megamenu-root.d.ts +254 -0
  210. package/dist/megamenu/root/megamenu-root.js +526 -0
  211. package/dist/menu/index.d.ts +2 -0
  212. package/dist/menu/index.js +2 -0
  213. package/dist/menu/item/menu-item.d.ts +231 -0
  214. package/dist/menu/item/menu-item.js +405 -0
  215. package/dist/menu/root/menu-root.d.ts +158 -0
  216. package/dist/menu/root/menu-root.js +422 -0
  217. package/dist/meter/index.d.ts +1 -0
  218. package/dist/meter/index.js +1 -0
  219. package/dist/meter/root/meter-root.d.ts +234 -0
  220. package/dist/meter/root/meter-root.js +316 -0
  221. package/dist/navigation/index.d.ts +1 -0
  222. package/dist/navigation/index.js +1 -0
  223. package/dist/navigation/root/navigation-root.d.ts +55 -0
  224. package/dist/navigation/root/navigation-root.js +130 -0
  225. package/dist/notifications/index.d.ts +2 -0
  226. package/dist/notifications/index.js +2 -0
  227. package/dist/notifications/notification/notification.d.ts +181 -0
  228. package/dist/notifications/notification/notification.js +305 -0
  229. package/dist/notifications/root/notifications-root.d.ts +168 -0
  230. package/dist/notifications/root/notifications-root.js +291 -0
  231. package/dist/number-input/index.d.ts +1 -0
  232. package/dist/number-input/index.js +1 -0
  233. package/dist/number-input/root/number-input-root.d.ts +282 -0
  234. package/dist/number-input/root/number-input-root.js +592 -0
  235. package/dist/option/group/option-group.d.ts +38 -0
  236. package/dist/option/group/option-group.js +58 -0
  237. package/dist/option/index.d.ts +2 -0
  238. package/dist/option/index.js +2 -0
  239. package/dist/option/root/option-root.d.ts +194 -0
  240. package/dist/option/root/option-root.js +247 -0
  241. package/dist/outline/index.d.ts +1 -0
  242. package/dist/outline/index.js +1 -0
  243. package/dist/outline/root/outline-root.d.ts +237 -0
  244. package/dist/outline/root/outline-root.js +519 -0
  245. package/dist/pagination/index.d.ts +3 -0
  246. package/dist/pagination/index.js +3 -0
  247. package/dist/pagination/root/pagination-root.d.ts +390 -0
  248. package/dist/pagination/root/pagination-root.js +695 -0
  249. package/dist/pagination/size/pagination-size.d.ts +127 -0
  250. package/dist/pagination/size/pagination-size.js +232 -0
  251. package/dist/pagination/summary/pagination-summary.d.ts +90 -0
  252. package/dist/pagination/summary/pagination-summary.js +145 -0
  253. package/dist/pin-input/index.d.ts +1 -0
  254. package/dist/pin-input/index.js +1 -0
  255. package/dist/pin-input/root/pin-input-root.d.ts +292 -0
  256. package/dist/pin-input/root/pin-input-root.js +553 -0
  257. package/dist/popover/index.d.ts +1 -0
  258. package/dist/popover/index.js +1 -0
  259. package/dist/popover/root/popover-root.d.ts +108 -0
  260. package/dist/popover/root/popover-root.js +231 -0
  261. package/dist/progress/index.d.ts +1 -0
  262. package/dist/progress/index.js +1 -0
  263. package/dist/progress/root/progress-root.d.ts +125 -0
  264. package/dist/progress/root/progress-root.js +212 -0
  265. package/dist/qr-code/index.d.ts +1 -0
  266. package/dist/qr-code/index.js +1 -0
  267. package/dist/qr-code/root/qr-code-root.d.ts +93 -0
  268. package/dist/qr-code/root/qr-code-root.js +233 -0
  269. package/dist/quote/index.d.ts +1 -0
  270. package/dist/quote/index.js +1 -0
  271. package/dist/quote/root/quote-root.d.ts +36 -0
  272. package/dist/quote/root/quote-root.js +50 -0
  273. package/dist/radio/group/radio-group.d.ts +84 -0
  274. package/dist/radio/group/radio-group.js +170 -0
  275. package/dist/radio/index.d.ts +2 -0
  276. package/dist/radio/index.js +2 -0
  277. package/dist/radio/root/radio-root.d.ts +102 -0
  278. package/dist/radio/root/radio-root.js +151 -0
  279. package/dist/rating/index.d.ts +1 -0
  280. package/dist/rating/index.js +1 -0
  281. package/dist/rating/root/rating-root.d.ts +242 -0
  282. package/dist/rating/root/rating-root.js +484 -0
  283. package/dist/scroll-area/index.d.ts +1 -0
  284. package/dist/scroll-area/index.js +1 -0
  285. package/dist/scroll-area/root/scroll-area-root.d.ts +96 -0
  286. package/dist/scroll-area/root/scroll-area-root.js +215 -0
  287. package/dist/select/index.d.ts +1 -0
  288. package/dist/select/index.js +1 -0
  289. package/dist/select/root/select-root.d.ts +170 -0
  290. package/dist/select/root/select-root.js +419 -0
  291. package/dist/skeleton/index.d.ts +1 -0
  292. package/dist/skeleton/index.js +1 -0
  293. package/dist/skeleton/root/skeleton-root.d.ts +31 -0
  294. package/dist/skeleton/root/skeleton-root.js +42 -0
  295. package/dist/slider/index.d.ts +1 -0
  296. package/dist/slider/index.js +1 -0
  297. package/dist/slider/root/slider-root.d.ts +235 -0
  298. package/dist/slider/root/slider-root.js +488 -0
  299. package/dist/sparkline/index.d.ts +1 -0
  300. package/dist/sparkline/index.js +1 -0
  301. package/dist/sparkline/root/sparkline-root.d.ts +147 -0
  302. package/dist/sparkline/root/sparkline-root.js +278 -0
  303. package/dist/speed-dial/index.d.ts +2 -0
  304. package/dist/speed-dial/index.js +2 -0
  305. package/dist/speed-dial/item/speed-dial-item.d.ts +71 -0
  306. package/dist/speed-dial/item/speed-dial-item.js +113 -0
  307. package/dist/speed-dial/root/speed-dial-root.d.ts +122 -0
  308. package/dist/speed-dial/root/speed-dial-root.js +251 -0
  309. package/dist/splitter/index.d.ts +1 -0
  310. package/dist/splitter/index.js +1 -0
  311. package/dist/splitter/root/splitter-root.d.ts +491 -0
  312. package/dist/splitter/root/splitter-root.js +1030 -0
  313. package/dist/stat/group/stat-group.d.ts +30 -0
  314. package/dist/stat/group/stat-group.js +47 -0
  315. package/dist/stat/index.d.ts +2 -0
  316. package/dist/stat/index.js +2 -0
  317. package/dist/stat/root/stat-root.d.ts +62 -0
  318. package/dist/stat/root/stat-root.js +51 -0
  319. package/dist/steps/index.d.ts +2 -0
  320. package/dist/steps/index.js +2 -0
  321. package/dist/steps/root/steps-root.d.ts +110 -0
  322. package/dist/steps/root/steps-root.js +130 -0
  323. package/dist/steps/step/step.d.ts +139 -0
  324. package/dist/steps/step/step.js +215 -0
  325. package/dist/switch/index.d.ts +1 -0
  326. package/dist/switch/index.js +1 -0
  327. package/dist/switch/root/switch-root.d.ts +74 -0
  328. package/dist/switch/root/switch-root.js +153 -0
  329. package/dist/table/cell/table-cell.d.ts +34 -0
  330. package/dist/table/cell/table-cell.js +52 -0
  331. package/dist/table/column/table-column.d.ts +165 -0
  332. package/dist/table/column/table-column.js +222 -0
  333. package/dist/table/index.d.ts +4 -0
  334. package/dist/table/index.js +4 -0
  335. package/dist/table/root/table-root.d.ts +98 -0
  336. package/dist/table/root/table-root.js +161 -0
  337. package/dist/table/row/table-row.d.ts +27 -0
  338. package/dist/table/row/table-row.js +42 -0
  339. package/dist/tabs/index.d.ts +3 -0
  340. package/dist/tabs/index.js +3 -0
  341. package/dist/tabs/panel/tab-panel.d.ts +67 -0
  342. package/dist/tabs/panel/tab-panel.js +98 -0
  343. package/dist/tabs/root/tabs-root.d.ts +123 -0
  344. package/dist/tabs/root/tabs-root.js +217 -0
  345. package/dist/tabs/tab/tab.d.ts +64 -0
  346. package/dist/tabs/tab/tab.js +116 -0
  347. package/dist/tag/index.d.ts +1 -0
  348. package/dist/tag/index.js +1 -0
  349. package/dist/tag/root/tag-root.d.ts +41 -0
  350. package/dist/tag/root/tag-root.js +67 -0
  351. package/dist/textarea/index.d.ts +1 -0
  352. package/dist/textarea/index.js +1 -0
  353. package/dist/textarea/root/textarea-root.d.ts +215 -0
  354. package/dist/textarea/root/textarea-root.js +380 -0
  355. package/dist/time-input/index.d.ts +1 -0
  356. package/dist/time-input/index.js +1 -0
  357. package/dist/time-input/root/time-input-root.d.ts +322 -0
  358. package/dist/time-input/root/time-input-root.js +661 -0
  359. package/dist/time-picker/index.d.ts +1 -0
  360. package/dist/time-picker/index.js +1 -0
  361. package/dist/time-picker/root/time-picker-root.d.ts +380 -0
  362. package/dist/time-picker/root/time-picker-root.js +669 -0
  363. package/dist/timeline/index.d.ts +2 -0
  364. package/dist/timeline/index.js +2 -0
  365. package/dist/timeline/item/timeline-item.d.ts +81 -0
  366. package/dist/timeline/item/timeline-item.js +128 -0
  367. package/dist/timeline/root/timeline-root.d.ts +52 -0
  368. package/dist/timeline/root/timeline-root.js +72 -0
  369. package/dist/toast/index.d.ts +2 -0
  370. package/dist/toast/index.js +2 -0
  371. package/dist/toast/item/toast-item.d.ts +183 -0
  372. package/dist/toast/item/toast-item.js +345 -0
  373. package/dist/toast/root/toast-root.d.ts +72 -0
  374. package/dist/toast/root/toast-root.js +87 -0
  375. package/dist/toggle/group/toggle-group.d.ts +140 -0
  376. package/dist/toggle/group/toggle-group.js +278 -0
  377. package/dist/toggle/index.d.ts +2 -0
  378. package/dist/toggle/index.js +2 -0
  379. package/dist/toggle/root/toggle-root.d.ts +99 -0
  380. package/dist/toggle/root/toggle-root.js +146 -0
  381. package/dist/toolbar/index.d.ts +1 -0
  382. package/dist/toolbar/index.js +1 -0
  383. package/dist/toolbar/root/toolbar-root.d.ts +105 -0
  384. package/dist/toolbar/root/toolbar-root.js +260 -0
  385. package/dist/tooltip/index.d.ts +1 -0
  386. package/dist/tooltip/index.js +1 -0
  387. package/dist/tooltip/root/tooltip-root.d.ts +388 -0
  388. package/dist/tooltip/root/tooltip-root.js +707 -0
  389. package/dist/tour/index.d.ts +2 -0
  390. package/dist/tour/index.js +2 -0
  391. package/dist/tour/root/tour-root.d.ts +161 -0
  392. package/dist/tour/root/tour-root.js +351 -0
  393. package/dist/tour/stop/tour-stop.d.ts +131 -0
  394. package/dist/tour/stop/tour-stop.js +249 -0
  395. package/dist/tree/index.d.ts +2 -0
  396. package/dist/tree/index.js +2 -0
  397. package/dist/tree/item/tree-item.d.ts +208 -0
  398. package/dist/tree/item/tree-item.js +381 -0
  399. package/dist/tree/root/tree-root.d.ts +88 -0
  400. package/dist/tree/root/tree-root.js +287 -0
  401. package/dist/trend/index.d.ts +1 -0
  402. package/dist/trend/index.js +1 -0
  403. package/dist/trend/root/trend-root.d.ts +67 -0
  404. package/dist/trend/root/trend-root.js +106 -0
  405. package/dist/video/index.d.ts +1 -0
  406. package/dist/video/index.js +1 -0
  407. package/dist/video/root/video-root.d.ts +711 -0
  408. package/dist/video/root/video-root.js +1821 -0
  409. package/dist/video-playlist/index.d.ts +3 -0
  410. package/dist/video-playlist/index.js +3 -0
  411. package/dist/video-playlist/item/video-playlist-item.d.ts +101 -0
  412. package/dist/video-playlist/item/video-playlist-item.js +162 -0
  413. package/dist/video-playlist/menu/video-playlist-menu.d.ts +121 -0
  414. package/dist/video-playlist/menu/video-playlist-menu.js +237 -0
  415. package/dist/video-playlist/root/video-playlist-root.d.ts +108 -0
  416. package/dist/video-playlist/root/video-playlist-root.js +218 -0
  417. package/dist/virtual-list/index.d.ts +1 -0
  418. package/dist/virtual-list/index.js +1 -0
  419. package/dist/virtual-list/root/virtual-list-root.d.ts +121 -0
  420. package/dist/virtual-list/root/virtual-list-root.js +221 -0
  421. package/jsx.d.ts +49767 -0
  422. package/package.json +77 -0
  423. package/svelte.d.ts +129 -0
  424. package/vue.d.ts +9242 -0
@@ -0,0 +1,723 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { customElement, HelixElement, HelixSelectEvent, hostAria, requestChange, } from '@fusion.dev/helix-core';
8
+ import { caretLeft, caretRight, play, stop } from '@fusion.dev/helix-icons';
9
+ import { html, nothing } from 'lit';
10
+ import { property, state } from 'lit/decorators.js';
11
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
+ /**
13
+ * @summary Shows one slide of several, with controls to move between them.
14
+ *
15
+ * @description
16
+ * The track is a scroller with scroll snapping, so a drag, a trackpad swipe,
17
+ * and the browser's own momentum all work without being reimplemented. The
18
+ * controls scroll it; they do not drive a transform.
19
+ *
20
+ * Slides are the consumer's own elements, and nothing is written onto them. The
21
+ * component renders a pane per slide carrying `role="group"`,
22
+ * `aria-roledescription="slide"` and a name reading its position in the set,
23
+ * and assigns the slide into it: a screen-reader user hears where they are, and
24
+ * a slide that is itself a link is still a link, which it was not while the role
25
+ * was being written on top of it. See `assign`.
26
+ *
27
+ * **Rotation stops on focus and on hover, and once stopped it stays stopped.**
28
+ * The APG is explicit: rotation must not resume unless the reader asks for it,
29
+ * so hovering away does not start it again. The control names the action it
30
+ * performs, and it is first in the tab order.
31
+ *
32
+ * @since 0.1.0
33
+ * @status experimental
34
+ * @category layout
35
+ * @aliases Slider, Gallery, Slideshow
36
+ * @documentation https://helix.fusion.dev/components/carousel
37
+ *
38
+ * @slot - The slides.
39
+ *
40
+ * @event {HelixSelectEvent} helix-select - Fired when the slide in view changes, with its index. Cancelable: refusing it takes the decision and nothing moves.
41
+ *
42
+ * @csspart controls - The row of controls.
43
+ * @csspart indicator - One of them, and a way to reach that slide.
44
+ * @csspart indicators - The row of controls saying where the reader is.
45
+ * @csspart next - The control that moves to the next slide.
46
+ * @csspart next-mark - The glyph on the next control.
47
+ * @csspart previous - The control that moves to the previous slide.
48
+ * @csspart previous-mark - The glyph on the previous control.
49
+ * @csspart rotation - The control that stops and starts rotation.
50
+ * @csspart rotation-mark - The glyph on the play and pause control.
51
+ * @csspart slide - The pane one slide is shown in, and the box the track snaps to.
52
+ * @csspart track - The scroller the slides sit in.
53
+ */
54
+ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
55
+ constructor() {
56
+ super(...arguments);
57
+ /**
58
+ * Accessible name for the carousel.
59
+ */
60
+ this.label = 'Carousel';
61
+ /**
62
+ * Slide to start on, where nothing declared one.
63
+ */
64
+ this.defaultIndex = 0;
65
+ /** The slide in view, whoever set it, and `undefined` until somebody has. */
66
+ this.indexState = undefined;
67
+ /**
68
+ * Whether moving past either end wraps to the other.
69
+ */
70
+ this.loop = false;
71
+ /**
72
+ * Whether the carousel advances on its own.
73
+ */
74
+ this.autoplay = false;
75
+ /**
76
+ * How long each slide is held, in milliseconds.
77
+ */
78
+ this.interval = 5000;
79
+ /**
80
+ * Whether rotation is running.
81
+ *
82
+ * Absent until autoplay starts it.
83
+ */
84
+ this.rotating = false;
85
+ /**
86
+ * The arrows move between indicators, which is the tablist pattern.
87
+ *
88
+ * One tab stop for the set and the arrows within it, so a reader does not
89
+ * have to press Tab once per slide to get past a carousel of twelve. Moving
90
+ * changes the slide, because an indicator that could be focused without
91
+ * selecting would leave the highlight and the slide disagreeing with nothing
92
+ * on screen saying which is which.
93
+ */
94
+ this.handleIndicatorKeydown = (event) => {
95
+ const step = event.key === 'ArrowRight' ? 1 : event.key === 'ArrowLeft' ? -1 : 0;
96
+ if (step === 0) {
97
+ return;
98
+ }
99
+ event.preventDefault();
100
+ this.goTo(this.index + step);
101
+ this.updateComplete.then(() => {
102
+ this.renderRoot.querySelector('[part="indicator"][data-current]')?.focus();
103
+ });
104
+ };
105
+ /**
106
+ * Whether the scroll now settling is one this component asked for.
107
+ *
108
+ * Cleared by the first `scrollend` after it is set, and by a reader taking
109
+ * hold of the track. The second half is not belt and braces: a `scrollTo`
110
+ * whose target is already the scroll position fires no `scrollend` at all,
111
+ * and the clamped end of a `per-view` track is exactly that case. Measured:
112
+ * clicking past the last reachable slide moves `index` and produces no
113
+ * `scrollend`, so a flag that only a `scrollend` could clear would stay set
114
+ * and swallow the reader's next drag.
115
+ */
116
+ this.settling = false;
117
+ /* A reader's own input on the track ends our claim on the next `scrollend`,
118
+ whatever became of the scroll we issued. */
119
+ this.handleTake = () => {
120
+ this.settling = false;
121
+ };
122
+ /**
123
+ * Follows the track while a reader is still dragging it.
124
+ *
125
+ * **`scrollend` is the only honest place to commit an index and much too late
126
+ * to show one.** It fires once momentum has fully settled, which on iOS is
127
+ * most of a second after the finger has left the glass, so the dots sat on
128
+ * the old slide for the whole of the coast and then jumped. Reported exactly
129
+ * that way, as the delay on the indicator being too great.
130
+ *
131
+ * So showing and committing are separated. This moves the marker and nothing
132
+ * else: no state is written and no event is dispatched, because neither is
133
+ * true yet. A drag in flight is not a reader having chosen, `handleScroll`
134
+ * still decides that, and a consumer holding `index` still hears once.
135
+ *
136
+ * **The marker only, and not `aria-current` or the roving `tabindex`.** Those
137
+ * describe where the reader *is*, which is a question with one answer per
138
+ * settled position; moving them every frame of a drag would churn the
139
+ * accessibility tree to report a place nobody has arrived at.
140
+ *
141
+ * Coalesced to a frame, a scroll firing far more often than a screen
142
+ * refreshes, and skipped while we are settling a scroll of our own: a click
143
+ * has already moved the index and the track is following it, which is the
144
+ * precedence `handleScroll` documents at length.
145
+ */
146
+ this.handleTrackScroll = () => {
147
+ if (this.settling || this.scrollFrame) {
148
+ return;
149
+ }
150
+ this.scrollFrame = requestAnimationFrame(() => {
151
+ this.scrollFrame = 0;
152
+ const nearest = this.nearest();
153
+ if (nearest !== undefined && nearest !== this.showing) {
154
+ this.showing = nearest;
155
+ }
156
+ });
157
+ };
158
+ /**
159
+ * Reads where a reader's drag settled, and only a reader's.
160
+ *
161
+ * **The scroll we issued ourselves ends with a `scrollend` too, and taking it
162
+ * as a reading is what makes the dots jump back.** This ran on every one, so
163
+ * the index a reader had just chosen was overwritten by whichever slide
164
+ * happened to be nearest the leading edge at the moment the animation
165
+ * finished. Any disagreement there is enough: a snap settling a pixel short of
166
+ * a midpoint, a target clamped by the scroller's own maximum, a fractional
167
+ * layout, or a smooth scroll cut off by the next click. The component asked
168
+ * for slide four, the pixels said three, and the pixels won.
169
+ *
170
+ * Which is the wrong precedence in one direction only. A drag is the reader
171
+ * moving the track and the index has to follow it; a click is the reader
172
+ * moving the index and the track has to follow *that*. One `scrollend` cannot
173
+ * tell those apart, so the flag does.
174
+ */
175
+ this.handleScroll = () => {
176
+ if (this.settling) {
177
+ this.settling = false;
178
+ return;
179
+ }
180
+ /* The marker goes back to following the committed index, whatever this
181
+ reading turns out to be: the drag is over, so there is no longer a
182
+ position of its own to show. */
183
+ this.showing = undefined;
184
+ const nearest = this.nearest();
185
+ if (nearest === undefined) {
186
+ return;
187
+ }
188
+ /* Announced after the fact, and deliberately, where `goTo` announces
189
+ before. The reader has already dragged the track here: there is nothing
190
+ to refuse, and `preventDefault()` could not un-drag it. This is the case
191
+ the controlled-change helper's own documentation distinguishes, a native
192
+ control that has already moved, and putting it on that path would offer a
193
+ refusal that cannot be honoured. */
194
+ if (nearest === this.index) {
195
+ return;
196
+ }
197
+ this.indexState = nearest;
198
+ this.requestUpdate('index');
199
+ this.dispatchEvent(new HelixSelectEvent({ value: String(nearest) }));
200
+ };
201
+ /** The pending frame for the above, so a burst of scrolls costs one reading. */
202
+ this.scrollFrame = 0;
203
+ /**
204
+ * Whether the reader has stopped it, as opposed to something pausing it.
205
+ *
206
+ * The two were one flag and the difference matters: `focusin` bubbles, so
207
+ * every focus move inside the carousel re-ran `stop()`, and a reader who
208
+ * pressed Start had it undone by their very next Tab. Pausing on hover and on
209
+ * focus is right; forgetting that the reader asked it to stop is not, and the
210
+ * APG is explicit that rotation resumes only when the reader asks.
211
+ */
212
+ this.stopped = false;
213
+ /**
214
+ * Watches the light DOM for slides arriving and leaving.
215
+ *
216
+ * **A manually assigned slot does not announce them.** `slotchange` fires when
217
+ * an assignment changes, and under `slotAssignment: 'manual'` the only thing
218
+ * that changes an assignment is this component calling `assign`, so a slide
219
+ * appended by a consumer would reach no slot, render nowhere and be counted by
220
+ * nothing. The default slot used to carry that duty and could, because it took
221
+ * whatever was there. `Chat` watches for the same reason.
222
+ */
223
+ this.watcher = undefined;
224
+ /** Pauses without forgetting that the reader wanted it running. */
225
+ this.pause = () => {
226
+ if (!this.stopped) {
227
+ this.rotating = false;
228
+ }
229
+ };
230
+ }
231
+ /**
232
+ * Manual, so each slide can be wrapped without its markup being touched.
233
+ *
234
+ * A slide has to be a `group` carrying `aria-roledescription="slide"` and a
235
+ * position in the run, and those are the component's facts rather than the
236
+ * consumer's element's. Writing them on is what a React consumer's hydration
237
+ * reports and does not patch up, and on a slide that is itself a link it also
238
+ * takes the link's role away. Assigning into a pane the component rendered
239
+ * says the same thing to a screen reader and leaves the consumer's element
240
+ * exactly as it was served. `Chat` and `DataTable` wrap their children the
241
+ * same way and for the first of those two reasons.
242
+ */
243
+ static { this.shadowRootOptions = {
244
+ ...HelixElement.shadowRootOptions,
245
+ slotAssignment: 'manual',
246
+ }; }
247
+ /**
248
+ * The slide in view, counted from zero.
249
+ *
250
+ * Reading gives the real slide, in either mode. Writing sets it, the way a
251
+ * script assigning to a native control does. Which mode the carousel is in is
252
+ * read once, at the first update, from whether anything had declared an
253
+ * `index` by then: declared, and the consumer owns it and the carousel only
254
+ * announces where it would have gone; not declared, and the carousel owns it
255
+ * and `default-index` says where it starts.
256
+ *
257
+ * The same contract the four mixins carry, written out here rather than
258
+ * extracted, because a slide is addressed by position and every one of those
259
+ * mixins is keyed by a name. One consumer is not a mixin: if a second numeric
260
+ * state turns up, this is what it is extracted from.
261
+ *
262
+ *
263
+ */
264
+ get index() {
265
+ return this.indexState ?? this.defaultIndex;
266
+ }
267
+ set index(next) {
268
+ const previous = this.index;
269
+ this.indexState = next;
270
+ this.requestUpdate('index', previous);
271
+ }
272
+ /**
273
+ * How many distinct views the track holds, which is what the indicators count.
274
+ *
275
+ * A window of `perView` slides sliding one at a time over `n` of them stops
276
+ * `n - perView + 1` times, so six slides four across is three: 0 to 3, 1 to 4,
277
+ * 2 to 5. One at minimum, since a carousel showing everything it has still
278
+ * has the one place to be.
279
+ */
280
+ get positions() {
281
+ const across = Math.max(1, Math.floor(this.perView ?? 1));
282
+ return Math.max(1, this.slides.length - across + 1);
283
+ }
284
+ /**
285
+ * The panes rendered for the slides, in order. Empty until the first render.
286
+ *
287
+ * One per slide, and the box the track actually lays out: the slide itself is
288
+ * assigned into it and takes its size from it, so every offset the scroller
289
+ * is asked about is a pane's. Read fresh rather than cached, because a slide
290
+ * arriving or leaving re-renders the run.
291
+ */
292
+ get panes() {
293
+ return [...(this.renderRoot?.querySelectorAll?.('[part="slide"]') ?? [])];
294
+ }
295
+ /** The slides, in light-DOM order. Empty on the server, which has no tree. */
296
+ get slides() {
297
+ /* `?? []` is the server, and the comment above it was already right and
298
+ still did not save it: this said "client only" while `render` read it to
299
+ count the indicators, so every carousel SSR spec died on an unhandled
300
+ spread of `undefined`. Third time in this library, after the menu item
301
+ and the table, and the only one of the three the note was written on.
302
+ Knowing where a getter must not be reached is not the same as it not
303
+ being reached, which is what the guard is for.
304
+
305
+ Empty is also the honest answer rather than damage control. The
306
+ indicators are one per position and a position is counted from the
307
+ children, which the server cannot see, so they
308
+ arrive with the upgrade. Nothing moves when they do: the tags are hidden
309
+ until they are defined. */
310
+ return [...(this.children ?? [])].filter((child) => child instanceof HTMLElement);
311
+ }
312
+ /** Moves to a slide, wrapping only where `loop` says to. */
313
+ goTo(index) {
314
+ if (this.slides.length === 0) {
315
+ return;
316
+ }
317
+ /* Positions, not slides. The last place a four-across track of six can stop
318
+ is the third, and clamping to the sixth gave three indices that all
319
+ scrolled to the same clamped offset. */
320
+ const count = this.positions;
321
+ const next = this.loop ? (index + count) % count : Math.min(Math.max(index, 0), count - 1);
322
+ if (next === this.index) {
323
+ return;
324
+ }
325
+ requestChange({
326
+ apply: (value) => {
327
+ const previous = this.index;
328
+ this.indexState = value;
329
+ this.requestUpdate('index', previous);
330
+ },
331
+ event: (value) => new HelixSelectEvent({ value: String(value) }),
332
+ host: this,
333
+ next,
334
+ });
335
+ }
336
+ /**
337
+ * The leading padding the track keeps for a slide to draw its own edge in.
338
+ *
339
+ * A styled track carries one so a slide's shadow and focus ring have
340
+ * somewhere to go: a scroll container clips at its padding box, and a slide
341
+ * flush against that edge loses whatever it paints outside itself. The
342
+ * headless tier has no stylesheet and so no padding, and this reads zero
343
+ * there, which is why both tiers can share the arithmetic below.
344
+ *
345
+ * Physical sides rather than logical, to match the physical `offsetLeft` and
346
+ * `offsetTop` it is subtracted from. The bleed is one length on all four
347
+ * sides, so the two agree whatever the writing mode; if that stops being
348
+ * true, this is the method that has to know.
349
+ */
350
+ bleed(track) {
351
+ const style = getComputedStyle(track);
352
+ const read = Number.parseFloat(this.orientation === 'vertical' ? style.paddingTop : style.paddingLeft);
353
+ /* Zero where there is no number to read, which is a harness rather than a
354
+ browser. happy-dom resolves nothing out of an adopted stylesheet and
355
+ returns `''` for every side of this, so `parseFloat` gives `NaN`, and a
356
+ `NaN` distance loses every comparison it is in: the nearest-slide search
357
+ below picked nothing and a reader's drag stopped moving the index at all.
358
+ Three specs caught it. A browser always answers with a used length, so
359
+ this arm is only ever the harness, and zero is the right answer there,
360
+ nothing being laid out or clipped in the first place. */
361
+ return Number.isNaN(read) ? 0 : read;
362
+ }
363
+ /**
364
+ * Where a slide's leading edge sits, in the scroller's own coordinates.
365
+ *
366
+ * **Both directions go through here, because they have to agree.** The
367
+ * offsets are measured to the track's *border* box and `scrollTop` and
368
+ * `scrollLeft` are measured from its content box, so the two differ by the
369
+ * bleed: sending the carousel to a slide and reading back which slide it is
370
+ * on used the same expression, and correcting one of them alone put a drag
371
+ * one position off what the arrows did.
372
+ *
373
+ * Unsubtracted, the leading slide's own offset *is* the bleed, so scrolling
374
+ * to index 0 put its edge back on the clip edge. Measured on the insights
375
+ * carousel: `scrollLeft` resting at 4 against a 4px bleed, the first card
376
+ * shaved, and no scrolling done to cause it.
377
+ */
378
+ edgeOf(slide, track, bleed) {
379
+ return this.orientation === 'vertical'
380
+ ? slide.offsetTop - track.offsetTop - bleed
381
+ : slide.offsetLeft - track.offsetLeft - bleed;
382
+ }
383
+ scrollToIndex() {
384
+ /* The pane, not the slide inside it. The pane is the flex item the track
385
+ lays out and the box carrying `scroll-snap-align`, so it is what the
386
+ scroller's offsets are about; the slide is its content and, before the
387
+ assignment lands, is not in the track's layout at all. */
388
+ const slide = this.panes[this.index];
389
+ const track = this.renderRoot.querySelector('[part="track"]');
390
+ if (!slide || !track) {
391
+ return;
392
+ }
393
+ /* The preference is read here, because this is where the motion is.
394
+ *
395
+ * `scroll-behavior: auto` in a reduce block does nothing: it restates the
396
+ * initial value, and the scroll that actually animates is this call, which
397
+ * names `smooth` outright and overrides the property either way. A reader
398
+ * who asked not to be moved was moved. */
399
+ const vertical = this.orientation === 'vertical';
400
+ const target = this.edgeOf(slide, track, this.bleed(track));
401
+ /* Already there, and saying so rather than asking anyway.
402
+ *
403
+ * This is every index change that came *from* the track: a drag settles,
404
+ * the index follows it, and this would then send the scroller where it
405
+ * already is. No scroll runs, so no `scrollend` arrives, and a claim staked
406
+ * here would be cleared by the reader's *next* drag rather than by its own
407
+ * scroll, swallowing it. A pixel of slack, because a snapped offset is
408
+ * fractional and an exact comparison never holds. */
409
+ if (Math.abs(target - (vertical ? track.scrollTop : track.scrollLeft)) < 1) {
410
+ return;
411
+ }
412
+ /* The preference is read here, because this is where the motion is.
413
+ *
414
+ * `scroll-behavior: auto` in a reduce block does nothing: it restates the
415
+ * initial value, and the scroll that actually animates is this call, which
416
+ * names `smooth` outright and overrides the property either way. A reader
417
+ * who asked not to be moved was moved. */
418
+ const still = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;
419
+ /* The scroll about to run is ours, so the `scrollend` it produces is not a
420
+ reader saying where they went. See `handleScroll`. */
421
+ this.settling = true;
422
+ track.scrollTo({
423
+ behavior: still ? 'instant' : 'smooth',
424
+ ...(vertical ? { top: target } : { left: target }),
425
+ });
426
+ }
427
+ /**
428
+ * Stops rotation for good.
429
+ *
430
+ * Hovering away or moving focus out does not start it again. The APG is
431
+ * explicit that rotation resumes only when the reader asks for it, because a
432
+ * carousel that starts moving again on its own is the thing the control
433
+ * exists to escape.
434
+ */
435
+ stop() {
436
+ this.stopped = true;
437
+ this.rotating = false;
438
+ }
439
+ start() {
440
+ this.stopped = false;
441
+ this.rotating = true;
442
+ }
443
+ /**
444
+ * Owns the timer, from the state rather than from the call site.
445
+ *
446
+ * `start()` and `stop()` each held the interval and `connectedCallback`
447
+ * started one, which the rules forbid: a DOM move re-ran connect and restarted
448
+ * rotation the reader had stopped, and the server, which never runs connect at
449
+ * all, rendered the control saying the opposite of what it would do. The
450
+ * state is what is declared and the timer follows it, which also means one
451
+ * place clears it.
452
+ */
453
+ runTimer() {
454
+ clearInterval(this.timer);
455
+ this.timer = undefined;
456
+ if (!this.rotating || this.slides.length < 2) {
457
+ return;
458
+ }
459
+ this.timer = setInterval(() => this.goTo(this.index + 1), this.interval);
460
+ }
461
+ /**
462
+ * The slide the track is nearest to, or undefined when there is no track.
463
+ *
464
+ * Shared by the two readers of the scroll position, which want the same
465
+ * arithmetic and disagree about what to do with it: one commits where a drag
466
+ * settled, the other follows it while it is still moving.
467
+ *
468
+ * Only the leading edges a window can actually rest on. Past the last
469
+ * position every remaining slide is on screen already, and taking the nearest
470
+ * of *those* to the scroller's edge reported a place the reader could not get
471
+ * back to: dragged fully right, a four-across six reported the sixth slide
472
+ * and the dots jumped to an indicator that no longer existed.
473
+ */
474
+ nearest() {
475
+ const track = this.renderRoot.querySelector('[part="track"]');
476
+ if (!track) {
477
+ return undefined;
478
+ }
479
+ const bleed = this.bleed(track);
480
+ const at = this.orientation === 'vertical' ? track.scrollTop : track.scrollLeft;
481
+ return this.panes.slice(0, this.positions).reduce((best, slide, index) => {
482
+ const distance = Math.abs(this.edgeOf(slide, track, bleed) - at);
483
+ return distance < best.distance ? { distance, index } : best;
484
+ }, { distance: Number.POSITIVE_INFINITY, index: this.index }).index;
485
+ }
486
+ connectedCallback() {
487
+ super.connectedCallback();
488
+ this.addEventListener('focusin', this.pause);
489
+ this.addEventListener('pointerenter', this.pause);
490
+ this.watcher = new MutationObserver(() => this.requestUpdate());
491
+ this.watcher.observe(this, { childList: true });
492
+ }
493
+ disconnectedCallback() {
494
+ super.disconnectedCallback();
495
+ if (this.scrollFrame) {
496
+ cancelAnimationFrame(this.scrollFrame);
497
+ this.scrollFrame = 0;
498
+ }
499
+ this.removeEventListener('focusin', this.pause);
500
+ this.removeEventListener('pointerenter', this.pause);
501
+ this.watcher?.disconnect();
502
+ this.watcher = undefined;
503
+ clearInterval(this.timer);
504
+ this.timer = undefined;
505
+ }
506
+ willUpdate(changed) {
507
+ super.willUpdate(changed);
508
+ /* Seeded from the markup rather than started on connect, so the server and
509
+ the client agree about whether it is running. A reader's stop survives a
510
+ reconnection because `stopped` outlives it. */
511
+ if (!this.hasUpdated) {
512
+ this.rotating = this.autoplay;
513
+ }
514
+ hostAria(this.internals, { label: this.label, role: 'group' });
515
+ // Announced as a carousel rather than as a bare group, so a reader knows
516
+ // what the controls beside it are for.
517
+ this.internals.ariaRoleDescription = 'carousel';
518
+ }
519
+ updated(changed) {
520
+ super.updated(changed);
521
+ /* The track follows `index`, whoever moved it.
522
+ *
523
+ * This was called from inside `goTo`'s apply callback, which returns early
524
+ * in controlled mode, so a controlled carousel announced where it would go,
525
+ * the consumer assigned `index`, and the track never moved: the dots
526
+ * updated and the slides sat still. Every other path in was equally
527
+ * stranded, a plain `carousel.index = 2` included, apply being the only
528
+ * caller. Here it is one place and it covers all of them. */
529
+ if (changed.has('index')) {
530
+ this.scrollToIndex();
531
+ }
532
+ this.runTimer();
533
+ /* Back inside the set when the set shrinks.
534
+ *
535
+ * Nothing re-clamped `index`, and the indicators carry a roving tab stop
536
+ * keyed on it, so a carousel whose slides were removed under it was left
537
+ * with no tab stop, no current dot and a focus restore pointing at nothing.
538
+ * In `updated` rather than `willUpdate` because `slides` is empty on the
539
+ * server, and through `goTo` so a controlled consumer is told rather than
540
+ * overwritten. */
541
+ const count = this.slides.length;
542
+ if (count > 0 && this.index > count - 1) {
543
+ this.goTo(count - 1);
544
+ }
545
+ this.assign();
546
+ }
547
+ /**
548
+ * Puts each slide into the pane rendered for it.
549
+ *
550
+ * **The panes carry the ARIA and the consumer's element carries none**, which
551
+ * is the whole reason this is a manual assignment rather than a plain slot.
552
+ * The APG wants each slide to be a `group` with `aria-roledescription="slide"`
553
+ * and a name saying where it sits in the run, and this used to be four
554
+ * `setAttribute` calls onto the elements a consumer wrote. Two things were
555
+ * wrong with that, and only one of them was about frameworks.
556
+ *
557
+ * **A React consumer's slides are nodes React is in the middle of hydrating.**
558
+ * The attributes landed before React reached them, so React found a DOM it had
559
+ * not rendered and reported a mismatch it says it will not patch up. It means
560
+ * it: the ARIA survived and the announcement was correct, so nothing looked
561
+ * wrong and the console was the only tell. Deferring the write was tried
562
+ * first, and a frame is a race rather than an ordering: measured in Chromium
563
+ * on the landing page, a tab opened in the foreground still reported the
564
+ * mismatch, and a tab opened hidden did not, only because `requestAnimationFrame`
565
+ * had not run there yet. `Chat` reached this same conclusion for the same
566
+ * reason and its comment on `shadowRootOptions` says so.
567
+ *
568
+ * **And `role="group"` on a consumer's `<a href>` is not additive.** It
569
+ * replaces the implicit link role, so six insight cards on the landing page
570
+ * announced as groups and left the links list entirely. Every slide that is
571
+ * itself a control had this, and no amount of deferring the write would have
572
+ * helped, because the write was the bug. A pane around the slide is what the
573
+ * pattern actually asks for: a group holding a link, rather than a link
574
+ * relabeled as a group.
575
+ *
576
+ * So nothing is written onto a consumer's element at all now, and the
577
+ * mismatch is gone by construction rather than by timing.
578
+ */
579
+ assign() {
580
+ const panes = this.renderRoot?.querySelectorAll?.('[part="slide"] slot');
581
+ if (!panes) {
582
+ return;
583
+ }
584
+ /* Paired by position, and short-circuited by whichever ran out: a render
585
+ and a child list can disagree for one update when children arrive after
586
+ the template was built, and the mutation observer schedules the update
587
+ that reconciles them. */
588
+ this.slides.forEach((slide, index) => {
589
+ panes[index]?.assign?.(slide);
590
+ });
591
+ }
592
+ render() {
593
+ const rotating = this.rotating;
594
+ return html `<div part="controls">
595
+ ${this.autoplay
596
+ ? html `<button
597
+ part="rotation"
598
+ type="button"
599
+ aria-label=${rotating ? 'Stop slide rotation' : 'Start slide rotation'}
600
+ @click=${() => (rotating ? this.stop() : this.start())}
601
+ >
602
+ <svg part="rotation-mark"
603
+ fill="currentColor"
604
+ viewBox=${rotating ? stop.viewBox : play.viewBox}
605
+ aria-hidden="true"
606
+ >
607
+ ${unsafeSVG(rotating ? stop.content : play.content)}
608
+ </svg>
609
+ </button>`
610
+ : nothing}
611
+ ${
612
+ /* `none` takes them out of the tree rather than hiding them, so they
613
+ leave the tab order with them. `auto` renders them and lets the
614
+ stylesheet answer for the pointer, a question CSS can ask directly
615
+ and this cannot without watching a media query from script. */
616
+ this.controls === 'none'
617
+ ? nothing
618
+ : html `<button
619
+ part="previous"
620
+ type="button"
621
+ aria-label="Previous slide"
622
+ @click=${() => this.goTo(this.index - 1)}
623
+ >
624
+ <svg part="previous-mark" fill="currentColor" viewBox=${caretLeft.viewBox} aria-hidden="true">
625
+ ${unsafeSVG(caretLeft.content)}
626
+ </svg>
627
+ </button>
628
+ <button
629
+ part="next"
630
+ type="button"
631
+ aria-label="Next slide"
632
+ @click=${() => this.goTo(this.index + 1)}
633
+ >
634
+ <svg part="next-mark" fill="currentColor" viewBox=${caretRight.viewBox} aria-hidden="true">
635
+ ${unsafeSVG(caretRight.content)}
636
+ </svg>
637
+ </button>`}
638
+ </div>
639
+ <div
640
+ data-scroller
641
+ part="track"
642
+ @scroll=${this.handleTrackScroll}
643
+ @scrollend=${this.handleScroll}
644
+ @pointerdown=${this.handleTake}
645
+ @touchstart=${this.handleTake}
646
+ @wheel=${this.handleTake}
647
+ >
648
+ ${this.slides.map((_, index) => html `<div
649
+ part="slide"
650
+ role="group"
651
+ aria-roledescription="slide"
652
+ aria-label=${`${index + 1} of ${this.slides.length}`}
653
+ >
654
+ <slot @slotchange=${() => this.requestUpdate()}></slot>
655
+ </div>`)}
656
+ </div>
657
+ ${this.slides.length > 1
658
+ ? html `<div part="indicators" role="group" aria-label=${`${this.label} slides`}>
659
+ ${
660
+ /* Plain buttons, not a half-built tablist.
661
+ *
662
+ * They were `role="tab"` inside `role="tablist"` with no
663
+ * `aria-controls`, while the slides were `role="group"` rather
664
+ * than tabpanels: the APG has two carousel patterns and this
665
+ * was the announcement of one over the structure of the other,
666
+ * so a reader was told to expect panels that do not exist.
667
+ *
668
+ * The basic pattern is what this is: buttons that move the
669
+ * carousel, with the current one marked. `aria-current` is the
670
+ * right word for "the one you are on" where nothing is being
671
+ * selected. */
672
+ ''}
673
+ ${Array.from({ length: this.positions }).map((_place, at) => html `<button
674
+ part="indicator"
675
+ type="button"
676
+ aria-label=${`Slide ${at + 1}`}
677
+ aria-current=${at === this.index ? 'true' : nothing}
678
+ tabindex=${at === this.index ? '0' : '-1'}
679
+ ?data-current=${at === (this.showing ?? this.index)}
680
+ @keydown=${this.handleIndicatorKeydown}
681
+ @click=${() => this.goTo(at)}
682
+ ></button>`)}
683
+ </div>`
684
+ : nothing}`;
685
+ }
686
+ };
687
+ __decorate([
688
+ property()
689
+ ], HelixHeadlessCarousel.prototype, "label", void 0);
690
+ __decorate([
691
+ property({ type: Number })
692
+ ], HelixHeadlessCarousel.prototype, "index", null);
693
+ __decorate([
694
+ property({ reflect: true })
695
+ ], HelixHeadlessCarousel.prototype, "orientation", void 0);
696
+ __decorate([
697
+ property({ reflect: true })
698
+ ], HelixHeadlessCarousel.prototype, "controls", void 0);
699
+ __decorate([
700
+ property({ attribute: 'default-index', type: Number })
701
+ ], HelixHeadlessCarousel.prototype, "defaultIndex", void 0);
702
+ __decorate([
703
+ property({ type: Boolean })
704
+ ], HelixHeadlessCarousel.prototype, "loop", void 0);
705
+ __decorate([
706
+ property({ type: Boolean })
707
+ ], HelixHeadlessCarousel.prototype, "autoplay", void 0);
708
+ __decorate([
709
+ property({ type: Number })
710
+ ], HelixHeadlessCarousel.prototype, "interval", void 0);
711
+ __decorate([
712
+ state()
713
+ ], HelixHeadlessCarousel.prototype, "rotating", void 0);
714
+ __decorate([
715
+ property({ attribute: 'per-view', reflect: true, type: Number })
716
+ ], HelixHeadlessCarousel.prototype, "perView", void 0);
717
+ __decorate([
718
+ state()
719
+ ], HelixHeadlessCarousel.prototype, "showing", void 0);
720
+ HelixHeadlessCarousel = __decorate([
721
+ customElement('helix-headless-carousel')
722
+ ], HelixHeadlessCarousel);
723
+ export { HelixHeadlessCarousel };