@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,108 @@
1
+ import { HelixElement } from '@fusion.dev/helix-core';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
+ declare const HelixHeadlessVideoPlaylist_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerActiveInterface) & typeof HelixElement;
4
+ /**
5
+ * @summary A set of clips and the one player they take turns in.
6
+ *
7
+ * @description
8
+ * **The player is slotted, never rendered here.** A consumer's player carries
9
+ * their appearance, their extra controls, their captions and their poster
10
+ * treatment, and a playlist that rendered its own would either lose all of that
11
+ * or grow a property for each of them. `Sandbox` takes its preview and `Menu`
12
+ * its trigger the same way.
13
+ *
14
+ * **The entries are markup rather than an array property.** A list of objects
15
+ * would be the shorter API and it does not survive the trip: React skips every
16
+ * property it would have to apply imperatively while hydrating, so an array
17
+ * handed to a custom element is missing on the first paint of every
18
+ * server-rendered page. `using-the-elements.mdx` carries the measurement. Markup
19
+ * is also what makes each entry a real button with a real name in it.
20
+ *
21
+ * **Nothing here plays anything.** It sets `src` on the player and lets the
22
+ * player be a player. What the playlist owns is which entry is current, and it
23
+ * moves that on three signals: an entry pressed, `helix-next` or
24
+ * `helix-previous` from the player, and the player reaching the end.
25
+ *
26
+ * `ended` advances without asking, because a set of clips that stopped between
27
+ * each one is a set the reader has to nurse. The clip that follows starts where
28
+ * the last one left off, which is `autoplay` in the only sense that matters
29
+ * here: the reader already pressed play once.
30
+ *
31
+ * @since 0.1.0
32
+ * @status experimental
33
+ * @category media
34
+ * @aliases Playlist, Queue, Up next
35
+ * @documentation https://helix.fusion.dev/components/video-playlist
36
+ *
37
+ * @slot - The entries.
38
+ * @slot player - The `helix-video` they play in.
39
+ *
40
+ * @event {HelixActivateEvent} helix-activate - Fired once the current one has moved, so the element already holds it.
41
+ * @event {HelixBeforeActivateEvent} helix-before-activate - Fired before the current entry changes, and cancelable.
42
+ *
43
+ * @csspart items - The list of entries.
44
+ * @csspart player - The region holding the player.
45
+ */
46
+ export declare class HelixHeadlessVideoPlaylist extends HelixHeadlessVideoPlaylist_base {
47
+ /**
48
+ * Accessible name for the list, which usually has no visible heading.
49
+ */
50
+ label: string;
51
+ /**
52
+ * The entries, in the order the consumer wrote them.
53
+ *
54
+ * **Found by tag and filtered on the property, never on `[value]`.** The
55
+ * prefilter used to be an attribute selector, which is redundant beside the
56
+ * tag match and is the half that broke: React assigns a matching property
57
+ * rather than an attribute, so a playlist written in JSX carried no `value`
58
+ * attribute anywhere and `querySelectorAll('[value]')` returned nothing. Every
59
+ * entry vanished from the list, the active one included, and the component
60
+ * threw no error because an empty playlist is a legal playlist.
61
+ *
62
+ * Reading `one.value` answers the same question and answers it the same way
63
+ * whether the consumer wrote markup or set a property, which is the only form
64
+ * that works for both. Found by rendering the React twin of this family's
65
+ * examples beside the markup ones.
66
+ */
67
+ private get items();
68
+ /**
69
+ * Whether the entry changed because somebody moved through the playlist.
70
+ *
71
+ * All three ways it moves are the reader going somewhere: pressing an entry,
72
+ * pressing next or previous, or a clip ending and the next one following it.
73
+ * Every one of those means play, and the one case that does not is the first
74
+ * render, where the playlist is simply pointing the player at its opening
75
+ * entry and nobody has asked for anything yet.
76
+ *
77
+ * A press is also what makes the play legal. Autoplay is refused when nothing
78
+ * the reader did asked for it, so starting here works because this is inside
79
+ * the gesture that chose the entry, and where it is refused anyway the player
80
+ * shows its start control and waits.
81
+ */
82
+ private chased;
83
+ private get player();
84
+ /** Moves by one, and does nothing at either end. */
85
+ private step;
86
+ private readonly handleSelect;
87
+ private readonly handleNext;
88
+ private readonly handlePrevious;
89
+ private readonly handleEnded;
90
+ connectedCallback(): void;
91
+ disconnectedCallback(): void;
92
+ /**
93
+ * Points the player at the current entry, and tells the entries which is on.
94
+ *
95
+ * In `updated` rather than in the handlers, so the three signals that move the
96
+ * current entry all arrive at one place that applies it. The server never runs
97
+ * this, which is correct: the entries are light DOM it cannot see, and what it
98
+ * renders is the player with whatever `src` the consumer wrote.
99
+ */
100
+ protected updated(changed: PropertyValues): void;
101
+ protected render(): TemplateResult;
102
+ }
103
+ declare global {
104
+ interface HTMLElementTagNameMap {
105
+ 'helix-headless-video-playlist': HelixHeadlessVideoPlaylist;
106
+ }
107
+ }
108
+ export {};
@@ -0,0 +1,218 @@
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, MixinControllerActive } from '@fusion.dev/helix-core';
8
+ import { html } from 'lit';
9
+ import { property } from 'lit/decorators.js';
10
+ /**
11
+ * @summary A set of clips and the one player they take turns in.
12
+ *
13
+ * @description
14
+ * **The player is slotted, never rendered here.** A consumer's player carries
15
+ * their appearance, their extra controls, their captions and their poster
16
+ * treatment, and a playlist that rendered its own would either lose all of that
17
+ * or grow a property for each of them. `Sandbox` takes its preview and `Menu`
18
+ * its trigger the same way.
19
+ *
20
+ * **The entries are markup rather than an array property.** A list of objects
21
+ * would be the shorter API and it does not survive the trip: React skips every
22
+ * property it would have to apply imperatively while hydrating, so an array
23
+ * handed to a custom element is missing on the first paint of every
24
+ * server-rendered page. `using-the-elements.mdx` carries the measurement. Markup
25
+ * is also what makes each entry a real button with a real name in it.
26
+ *
27
+ * **Nothing here plays anything.** It sets `src` on the player and lets the
28
+ * player be a player. What the playlist owns is which entry is current, and it
29
+ * moves that on three signals: an entry pressed, `helix-next` or
30
+ * `helix-previous` from the player, and the player reaching the end.
31
+ *
32
+ * `ended` advances without asking, because a set of clips that stopped between
33
+ * each one is a set the reader has to nurse. The clip that follows starts where
34
+ * the last one left off, which is `autoplay` in the only sense that matters
35
+ * here: the reader already pressed play once.
36
+ *
37
+ * @since 0.1.0
38
+ * @status experimental
39
+ * @category media
40
+ * @aliases Playlist, Queue, Up next
41
+ * @documentation https://helix.fusion.dev/components/video-playlist
42
+ *
43
+ * @slot - The entries.
44
+ * @slot player - The `helix-video` they play in.
45
+ *
46
+ * @event {HelixActivateEvent} helix-activate - Fired once the current one has moved, so the element already holds it.
47
+ * @event {HelixBeforeActivateEvent} helix-before-activate - Fired before the current entry changes, and cancelable.
48
+ *
49
+ * @csspart items - The list of entries.
50
+ * @csspart player - The region holding the player.
51
+ */
52
+ let HelixHeadlessVideoPlaylist = class HelixHeadlessVideoPlaylist extends MixinControllerActive(HelixElement) {
53
+ constructor() {
54
+ super(...arguments);
55
+ /**
56
+ * Accessible name for the list, which usually has no visible heading.
57
+ */
58
+ this.label = 'Playlist';
59
+ /*
60
+ * The player, whichever tag the consumer slotted.
61
+ *
62
+ * Asked of the slot rather than matched by tag name: the headless tier's
63
+ * player is `helix-headless-video` and the styled tier's is `helix-video`, and a
64
+ * consumer bringing a third under either name should still be driven. What is
65
+ * needed of it is `src`, which is the whole of the contract.
66
+ */
67
+ /**
68
+ * Whether the entry changed because somebody moved through the playlist.
69
+ *
70
+ * All three ways it moves are the reader going somewhere: pressing an entry,
71
+ * pressing next or previous, or a clip ending and the next one following it.
72
+ * Every one of those means play, and the one case that does not is the first
73
+ * render, where the playlist is simply pointing the player at its opening
74
+ * entry and nobody has asked for anything yet.
75
+ *
76
+ * A press is also what makes the play legal. Autoplay is refused when nothing
77
+ * the reader did asked for it, so starting here works because this is inside
78
+ * the gesture that chose the entry, and where it is refused anyway the player
79
+ * shows its start control and waits.
80
+ */
81
+ this.chased = false;
82
+ this.handleSelect = (event) => {
83
+ /* Stopped and not relayed. The entry says it was chosen, this element says
84
+ what is playing, and a consumer hearing both would hear one press twice
85
+ under two names.
86
+ *
87
+ * `stopImmediatePropagation`, not `stopPropagation`. The consumer's listener
88
+ * is on this same element, and stopping propagation only keeps an event off
89
+ * the *next* node: every listener already bound here still runs, so the
90
+ * entry's selection reached them anyway. Command carries the longer note,
91
+ * and the spec below is what caught this one. */
92
+ event.stopImmediatePropagation();
93
+ this.chased = true;
94
+ this.requestActive(event.detail.value);
95
+ };
96
+ this.handleNext = () => {
97
+ this.chased = true;
98
+ this.step(1);
99
+ };
100
+ this.handlePrevious = () => {
101
+ this.chased = true;
102
+ this.step(-1);
103
+ };
104
+ this.handleEnded = () => {
105
+ this.chased = true;
106
+ this.step(1);
107
+ };
108
+ }
109
+ /**
110
+ * The entries, in the order the consumer wrote them.
111
+ *
112
+ * **Found by tag and filtered on the property, never on `[value]`.** The
113
+ * prefilter used to be an attribute selector, which is redundant beside the
114
+ * tag match and is the half that broke: React assigns a matching property
115
+ * rather than an attribute, so a playlist written in JSX carried no `value`
116
+ * attribute anywhere and `querySelectorAll('[value]')` returned nothing. Every
117
+ * entry vanished from the list, the active one included, and the component
118
+ * threw no error because an empty playlist is a legal playlist.
119
+ *
120
+ * Reading `one.value` answers the same question and answers it the same way
121
+ * whether the consumer wrote markup or set a property, which is the only form
122
+ * that works for both. Found by rendering the React twin of this family's
123
+ * examples beside the markup ones.
124
+ */
125
+ get items() {
126
+ return [
127
+ ...this.querySelectorAll('helix-video-playlist-item, helix-headless-video-playlist-item'),
128
+ ].filter((one) => one.value !== '');
129
+ }
130
+ get player() {
131
+ const slot = this.renderRoot?.querySelector('slot[name="player"]');
132
+ const first = slot?.assignedElements()[0];
133
+ return (first ?? null);
134
+ }
135
+ /** Moves by one, and does nothing at either end. */
136
+ step(by) {
137
+ const items = this.items.filter((one) => !one.disabled);
138
+ const at = items.findIndex((one) => one.value === this.resolveActive(items)?.value);
139
+ const next = items[at + by];
140
+ if (next) {
141
+ this.requestActive(next.value);
142
+ }
143
+ }
144
+ connectedCallback() {
145
+ super.connectedCallback();
146
+ this.addEventListener('helix-select', this.handleSelect);
147
+ this.addEventListener('helix-next', this.handleNext);
148
+ this.addEventListener('helix-previous', this.handlePrevious);
149
+ /* `ended` is a media event and does not compose out of the player's shadow
150
+ root on its own. The player relays it, which is why listening here works
151
+ at all, and why this listens on the element rather than on a `<video>` it
152
+ has no reference to. */
153
+ this.addEventListener('ended', this.handleEnded);
154
+ }
155
+ disconnectedCallback() {
156
+ super.disconnectedCallback();
157
+ this.removeEventListener('helix-select', this.handleSelect);
158
+ this.removeEventListener('helix-next', this.handleNext);
159
+ this.removeEventListener('helix-previous', this.handlePrevious);
160
+ this.removeEventListener('ended', this.handleEnded);
161
+ }
162
+ /**
163
+ * Points the player at the current entry, and tells the entries which is on.
164
+ *
165
+ * In `updated` rather than in the handlers, so the three signals that move the
166
+ * current entry all arrive at one place that applies it. The server never runs
167
+ * this, which is correct: the entries are light DOM it cannot see, and what it
168
+ * renders is the player with whatever `src` the consumer wrote.
169
+ */
170
+ updated(changed) {
171
+ super.updated?.(changed);
172
+ const items = this.items;
173
+ const current = this.resolveActive(items);
174
+ for (const item of items) {
175
+ item.current = item === current;
176
+ }
177
+ const player = this.player;
178
+ if (!player || !current) {
179
+ return;
180
+ }
181
+ /* Only on a change. Writing `src` with the value it already holds reloads
182
+ the resource in every engine, so a playlist that assigned on each update
183
+ would restart the clip whenever anything else about it rendered. */
184
+ if (player.src !== current.src) {
185
+ player.src = current.src;
186
+ player.poster = current.poster;
187
+ player.label = current.text;
188
+ if (this.chased) {
189
+ /* After the player has rendered, not now. `src` here is the element's
190
+ property, and the `<video>` inside it only takes the new source on
191
+ its next render: playing at this point plays the outgoing clip for an
192
+ instant and the load that follows stops it again. Measured, and the
193
+ reading was a player left paused on the entry that had just been
194
+ chosen.
195
+
196
+ A microtask later is still inside the press that got us here, so the
197
+ platform still counts it as asked for. */
198
+ void player.updateComplete?.then(() => {
199
+ player.play();
200
+ });
201
+ }
202
+ }
203
+ this.chased = false;
204
+ }
205
+ render() {
206
+ return html `<div part="player"><slot name="player"></slot></div>
207
+ <div part="items" role="list" aria-label=${this.label}>
208
+ <slot></slot>
209
+ </div>`;
210
+ }
211
+ };
212
+ __decorate([
213
+ property()
214
+ ], HelixHeadlessVideoPlaylist.prototype, "label", void 0);
215
+ HelixHeadlessVideoPlaylist = __decorate([
216
+ customElement('helix-headless-video-playlist')
217
+ ], HelixHeadlessVideoPlaylist);
218
+ export { HelixHeadlessVideoPlaylist };
@@ -0,0 +1 @@
1
+ export * from './root/virtual-list-root.js';
@@ -0,0 +1 @@
1
+ export * from './root/virtual-list-root.js';
@@ -0,0 +1,121 @@
1
+ import { HelixElement } from '@fusion.dev/helix-core';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
+ /**
4
+ * @summary Renders the rows of a long set that are on screen, and no others.
5
+ *
6
+ * @description
7
+ * **The set arrives as data, which is what makes this a virtual list rather
8
+ * than a box that hides children.** `for` names a
9
+ * `<script type="application/json">` holding an array of objects, and a
10
+ * `<template>` child says what one row looks like: elements carrying
11
+ * `data-field="name"` are filled with that field of the item.
12
+ *
13
+ * Both halves are markup, and that is the whole reason for the shape.
14
+ * `VirtualizeController` says why the obvious alternatives are shut: an `items`
15
+ * property cannot survive React hydration, which skips every property it would
16
+ * have to apply imperatively, and light-DOM children exist by the time anything
17
+ * could decide not to create them. Text in the document is neither. A server
18
+ * emits it, React re-emits it as a child rather than applying it, and it is one
19
+ * node whatever the row count.
20
+ *
21
+ * **The same shape the charts already use**, `for="<id>"` pointing at markup the
22
+ * consumer wrote, and the difference is what is at the other end. A chart names
23
+ * a `<table>`, which is the accessible version of the picture and which a reader
24
+ * with no JavaScript still gets. Ten thousand rows cannot be that: the table
25
+ * would be the cost this exists to avoid. So the accessible version here is the
26
+ * rendered window plus `aria-setsize` and `aria-posinset`, which is what says
27
+ * "four thousand of ten thousand" rather than "four of twenty".
28
+ *
29
+ * **Rows are light DOM, deliberately.** They are cloned from the consumer's
30
+ * template and appended to the host, so a document rule reaches them, the base
31
+ * layer applies, and a class in the template means what it says. Cloned into
32
+ * the shadow root they would be markup the consumer wrote and could not style,
33
+ * which is the one thing a row template must not be.
34
+ *
35
+ * **Reading the source is client-only**, because a server has no document to
36
+ * query. The window renders empty from the server and fills on the first update,
37
+ * which is the same client-side enhancement rule every tree-reading component
38
+ * here follows.
39
+ *
40
+ * **On this tier the consumer gives the viewport its box**, and the component
41
+ * cannot do it for them: `helix/headless` ships no stylesheet, and a height is a
42
+ * decision rather than a fact this could publish. So a base list wants two rules
43
+ * before it is a list at all:
44
+ *
45
+ * ```css
46
+ * helix-headless-virtual-list::part(viewport) {
47
+ * block-size: 12rem;
48
+ * overflow-y: auto;
49
+ * }
50
+ * ```
51
+ *
52
+ * **Without them it is not a scroller**, and the failure is worse than it
53
+ * sounds. `scrollTop` is always zero, so nothing ever windows; and the box has
54
+ * no height of its own, so `clientHeight` is a function of the rows just drawn.
55
+ * Measuring then moves what is being measured, and the two need not converge:
56
+ * measured in Chromium at 500 rows, it settled into a two-cycle between 378 and
57
+ * 379 rows and stayed there, at two and a half thousand passes in eight seconds.
58
+ * `VirtualizeController` gives up after ten passes and says so, so this now
59
+ * draws a bad window rather than stopping the page, but a bad window is still
60
+ * the answer until the rules are written.
61
+ *
62
+ * The styled tier writes them for you, with `--virtual-list-block-size`.
63
+ *
64
+ * @category layout
65
+ * @since 0.1.0
66
+ * @status experimental
67
+ * @documentation https://helix.fusion.dev/components/virtual-list
68
+ *
69
+ * @csspart after - The space standing in for rows below the window.
70
+ * @csspart before - The space standing in for rows above the window.
71
+ * @csspart viewport - The scrolling box. Needs a block size and an overflow on this tier.
72
+ */
73
+ export declare class HelixHeadlessVirtualList extends HelixElement {
74
+ /**
75
+ * How tall one row is, in pixels, used to map scroll offset to an index.
76
+ */
77
+ estimate: number;
78
+ /**
79
+ * Id of the element holding the rows, as JSON in a script.
80
+ */
81
+ for: string;
82
+ /**
83
+ * What the list is called, since the rendered rows are only a window on it.
84
+ */
85
+ label: string;
86
+ /**
87
+ * The parsed source.
88
+ *
89
+ * Empty on a server, which has nothing to read.
90
+ */
91
+ private rows;
92
+ private readonly virtualize;
93
+ /**
94
+ * Reads the source named by `for`, once the document exists to read.
95
+ *
96
+ * `firstUpdated` rather than `connectedCallback`, per the server rules: the
97
+ * shim has attributes and no tree, so `getElementById` is undefined there.
98
+ * A source that is missing or not an array leaves the list empty rather than
99
+ * throwing, because a consumer whose data has not arrived yet is the ordinary
100
+ * case and an empty list says so by itself.
101
+ */
102
+ protected firstUpdated(changed: PropertyValues): void;
103
+ protected updated(changed: PropertyValues): void;
104
+ private read;
105
+ /**
106
+ * Puts the windowed rows into the light DOM, and takes the rest out.
107
+ *
108
+ * Cleared and re-cloned rather than reconciled, which is the simple thing and
109
+ * is measured rather than assumed to be enough: a window is twenty-odd rows
110
+ * and cloning that many is well under a frame. A reconciler here would be
111
+ * carrying keys and identity for a set nothing selects into, and is the kind
112
+ * of optimisation to add against a measurement rather than ahead of one.
113
+ */
114
+ private place;
115
+ protected render(): TemplateResult;
116
+ }
117
+ declare global {
118
+ interface HTMLElementTagNameMap {
119
+ 'helix-headless-virtual-list': HelixHeadlessVirtualList;
120
+ }
121
+ }
@@ -0,0 +1,221 @@
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, VirtualizeController } from '@fusion.dev/helix-core';
8
+ import { html } from 'lit';
9
+ import { property, state } from 'lit/decorators.js';
10
+ /**
11
+ * @summary Renders the rows of a long set that are on screen, and no others.
12
+ *
13
+ * @description
14
+ * **The set arrives as data, which is what makes this a virtual list rather
15
+ * than a box that hides children.** `for` names a
16
+ * `<script type="application/json">` holding an array of objects, and a
17
+ * `<template>` child says what one row looks like: elements carrying
18
+ * `data-field="name"` are filled with that field of the item.
19
+ *
20
+ * Both halves are markup, and that is the whole reason for the shape.
21
+ * `VirtualizeController` says why the obvious alternatives are shut: an `items`
22
+ * property cannot survive React hydration, which skips every property it would
23
+ * have to apply imperatively, and light-DOM children exist by the time anything
24
+ * could decide not to create them. Text in the document is neither. A server
25
+ * emits it, React re-emits it as a child rather than applying it, and it is one
26
+ * node whatever the row count.
27
+ *
28
+ * **The same shape the charts already use**, `for="<id>"` pointing at markup the
29
+ * consumer wrote, and the difference is what is at the other end. A chart names
30
+ * a `<table>`, which is the accessible version of the picture and which a reader
31
+ * with no JavaScript still gets. Ten thousand rows cannot be that: the table
32
+ * would be the cost this exists to avoid. So the accessible version here is the
33
+ * rendered window plus `aria-setsize` and `aria-posinset`, which is what says
34
+ * "four thousand of ten thousand" rather than "four of twenty".
35
+ *
36
+ * **Rows are light DOM, deliberately.** They are cloned from the consumer's
37
+ * template and appended to the host, so a document rule reaches them, the base
38
+ * layer applies, and a class in the template means what it says. Cloned into
39
+ * the shadow root they would be markup the consumer wrote and could not style,
40
+ * which is the one thing a row template must not be.
41
+ *
42
+ * **Reading the source is client-only**, because a server has no document to
43
+ * query. The window renders empty from the server and fills on the first update,
44
+ * which is the same client-side enhancement rule every tree-reading component
45
+ * here follows.
46
+ *
47
+ * **On this tier the consumer gives the viewport its box**, and the component
48
+ * cannot do it for them: `helix/headless` ships no stylesheet, and a height is a
49
+ * decision rather than a fact this could publish. So a base list wants two rules
50
+ * before it is a list at all:
51
+ *
52
+ * ```css
53
+ * helix-headless-virtual-list::part(viewport) {
54
+ * block-size: 12rem;
55
+ * overflow-y: auto;
56
+ * }
57
+ * ```
58
+ *
59
+ * **Without them it is not a scroller**, and the failure is worse than it
60
+ * sounds. `scrollTop` is always zero, so nothing ever windows; and the box has
61
+ * no height of its own, so `clientHeight` is a function of the rows just drawn.
62
+ * Measuring then moves what is being measured, and the two need not converge:
63
+ * measured in Chromium at 500 rows, it settled into a two-cycle between 378 and
64
+ * 379 rows and stayed there, at two and a half thousand passes in eight seconds.
65
+ * `VirtualizeController` gives up after ten passes and says so, so this now
66
+ * draws a bad window rather than stopping the page, but a bad window is still
67
+ * the answer until the rules are written.
68
+ *
69
+ * The styled tier writes them for you, with `--virtual-list-block-size`.
70
+ *
71
+ * @category layout
72
+ * @since 0.1.0
73
+ * @status experimental
74
+ * @documentation https://helix.fusion.dev/components/virtual-list
75
+ *
76
+ * @csspart after - The space standing in for rows below the window.
77
+ * @csspart before - The space standing in for rows above the window.
78
+ * @csspart viewport - The scrolling box. Needs a block size and an overflow on this tier.
79
+ */
80
+ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixElement {
81
+ constructor() {
82
+ super(...arguments);
83
+ /**
84
+ * How tall one row is, in pixels, used to map scroll offset to an index.
85
+ */
86
+ this.estimate = 32;
87
+ /**
88
+ * Id of the element holding the rows, as JSON in a script.
89
+ */
90
+ this.for = '';
91
+ /**
92
+ * What the list is called, since the rendered rows are only a window on it.
93
+ */
94
+ this.label = '';
95
+ /**
96
+ * The parsed source.
97
+ *
98
+ * Empty on a server, which has nothing to read.
99
+ */
100
+ this.rows = [];
101
+ /* No `overscan` property. The controller's four is a statement about a frame
102
+ of fast scrolling at a 32 pixel row, which is a fact about the platform
103
+ rather than a preference, and a knob here would be one more thing to get
104
+ wrong for no case anybody has. */
105
+ this.virtualize = new VirtualizeController(this, {
106
+ container: () => this.renderRoot.querySelector('[part="viewport"]'),
107
+ count: () => this.rows.length,
108
+ estimate: () => this.estimate,
109
+ });
110
+ }
111
+ /**
112
+ * Reads the source named by `for`, once the document exists to read.
113
+ *
114
+ * `firstUpdated` rather than `connectedCallback`, per the server rules: the
115
+ * shim has attributes and no tree, so `getElementById` is undefined there.
116
+ * A source that is missing or not an array leaves the list empty rather than
117
+ * throwing, because a consumer whose data has not arrived yet is the ordinary
118
+ * case and an empty list says so by itself.
119
+ */
120
+ firstUpdated(changed) {
121
+ super.firstUpdated?.(changed);
122
+ this.read();
123
+ }
124
+ updated(changed) {
125
+ super.updated?.(changed);
126
+ if (changed.has('for')) {
127
+ this.read();
128
+ }
129
+ this.virtualize.measure();
130
+ this.place();
131
+ }
132
+ read() {
133
+ const source = this.for === '' ? null : this.ownerDocument.getElementById(this.for);
134
+ const text = source?.textContent ?? '';
135
+ if (text.trim() === '') {
136
+ this.rows = [];
137
+ return;
138
+ }
139
+ try {
140
+ const parsed = JSON.parse(text);
141
+ this.rows = Array.isArray(parsed) ? parsed : [];
142
+ }
143
+ catch {
144
+ /* Left empty rather than thrown. The source is a consumer's markup, and a
145
+ component that throws on it takes the page down over a comma. */
146
+ this.rows = [];
147
+ }
148
+ }
149
+ /**
150
+ * Puts the windowed rows into the light DOM, and takes the rest out.
151
+ *
152
+ * Cleared and re-cloned rather than reconciled, which is the simple thing and
153
+ * is measured rather than assumed to be enough: a window is twenty-odd rows
154
+ * and cloning that many is well under a frame. A reconciler here would be
155
+ * carrying keys and identity for a set nothing selects into, and is the kind
156
+ * of optimisation to add against a measurement rather than ahead of one.
157
+ */
158
+ place() {
159
+ const template = this.querySelector('template');
160
+ if (!template) {
161
+ return;
162
+ }
163
+ for (const stale of [...this.children]) {
164
+ if (stale !== template) {
165
+ stale.remove();
166
+ }
167
+ }
168
+ const { first, last } = this.virtualize.window;
169
+ const total = this.rows.length;
170
+ const fragment = this.ownerDocument.createDocumentFragment();
171
+ for (let at = first; at < last; at += 1) {
172
+ const row = this.rows[at];
173
+ if (!row) {
174
+ continue;
175
+ }
176
+ const clone = template.content.cloneNode(true);
177
+ for (const hole of clone.querySelectorAll('[data-field]')) {
178
+ hole.textContent = row[hole.dataset.field ?? ''] ?? '';
179
+ }
180
+ /* The real index and the real total, not the position in the window. A
181
+ reader arrowing through this should hear where they are in the set. */
182
+ for (const element of clone.children) {
183
+ element.setAttribute('role', 'listitem');
184
+ element.setAttribute('aria-posinset', String(at + 1));
185
+ element.setAttribute('aria-setsize', String(total));
186
+ }
187
+ fragment.append(clone);
188
+ }
189
+ this.append(fragment);
190
+ }
191
+ render() {
192
+ const { after, before } = this.virtualize.window;
193
+ return html `<div
194
+ data-scroller
195
+ part="viewport"
196
+ role="list"
197
+ aria-label=${this.label}
198
+ @scroll=${() => this.virtualize.measure()}
199
+ >
200
+ <div part="before" style="block-size: ${before}px"></div>
201
+ <slot></slot>
202
+ <div part="after" style="block-size: ${after}px"></div>
203
+ </div>`;
204
+ }
205
+ };
206
+ __decorate([
207
+ property({ type: Number })
208
+ ], HelixHeadlessVirtualList.prototype, "estimate", void 0);
209
+ __decorate([
210
+ property()
211
+ ], HelixHeadlessVirtualList.prototype, "for", void 0);
212
+ __decorate([
213
+ property()
214
+ ], HelixHeadlessVirtualList.prototype, "label", void 0);
215
+ __decorate([
216
+ state()
217
+ ], HelixHeadlessVirtualList.prototype, "rows", void 0);
218
+ HelixHeadlessVirtualList = __decorate([
219
+ customElement('helix-headless-virtual-list')
220
+ ], HelixHeadlessVirtualList);
221
+ export { HelixHeadlessVirtualList };