@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,144 @@
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, hostAria, MixinDismissible, slotFilled, } from '@fusion.dev/helix-core';
8
+ import { x } from '@fusion.dev/helix-icons';
9
+ import { html, nothing } from 'lit';
10
+ import { property } from 'lit/decorators.js';
11
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
+ /**
13
+ * @summary A page-level message above the masthead, which can be dismissed.
14
+ *
15
+ * @description
16
+ * Chrome rather than content. An announcement sits above the header and speaks
17
+ * for the whole page: a trial ending, a service degraded, a change of terms. A
18
+ * passage that interrupts a document to set itself apart is a `Callout`, which
19
+ * is read where it sits and cannot be dismissed. Neither is a variant of the
20
+ * other.
21
+ *
22
+ * **Always a polite live region.** `role="alert"` is assertive and interrupts
23
+ * whatever is being read, which is right for something that appears mid-session
24
+ * and wrong for something that was in the served HTML: an assertive
25
+ * announcement would cut across a screen-reader user on every page load, before
26
+ * they had read anything. Politeness costs a moment and is never wrong; the tone
27
+ * does not change that, because an error that was always there is still not an
28
+ * interruption.
29
+ *
30
+ * Dismissing is a request. The announcement does not remove itself, because the
31
+ * consumer owns the markup and taking the node out from under them would put
32
+ * their state and the document out of step. `preventDefault()` on the
33
+ * `helix-dismiss` is a refusal.
34
+ *
35
+ * @since 0.1.0
36
+ * @status stable
37
+ * @category feedback
38
+ * @aliases Banner, Notification bar, Alert bar
39
+ * @documentation https://helix.fusion.dev/components/announcement
40
+ *
41
+ * @slot - The message.
42
+ * @slot actions - What to do about it, usually a link or a button.
43
+ * @slot icon - Replaces the glyph inside the dismiss control.
44
+ *
45
+ * @event {HelixDismissEvent} helix-dismiss - Fired when the reader asks to close it. Cancelable: refusing it takes the decision and nothing moves.
46
+ *
47
+ * @csspart actions - The trailing action region.
48
+ * @csspart content - The message region.
49
+ * @csspart dismiss - The control that asks to close.
50
+ * @csspart dismiss-mark - The glyph on the dismiss control, where none is slotted.
51
+ */
52
+ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDismissible(HelixElement) {
53
+ willUpdate(changed) {
54
+ super.willUpdate(changed);
55
+ // On the host, and always polite. See the note above on `role="alert"`.
56
+ hostAria(this.internals, { role: 'status' });
57
+ this.internals.ariaLive = 'polite';
58
+ }
59
+ updated(changed) {
60
+ super.updated(changed);
61
+ this.markEmpty();
62
+ }
63
+ /**
64
+ * Says on the `actions` region whether anything is in it.
65
+ *
66
+ * An empty region is not free: it is still a flex item, so it still takes the
67
+ * container's gap. There is no selector that can ask, `slot:empty` being
68
+ * about a slot's fallback rather than its assigned nodes, so the component
69
+ * asks and says so, on the region inside this shadow root rather than on the
70
+ * host: an attribute written onto the host is a change to markup the consumer
71
+ * rendered, which React reports on hydration and does not patch up.
72
+ */
73
+ markEmpty() {
74
+ const region = this.renderRoot?.querySelector('[part="actions"]');
75
+ const empty = !slotFilled(this.renderRoot?.querySelector('slot[name="actions"]'));
76
+ region?.toggleAttribute('data-empty', empty);
77
+ /* `hidden` beside the mirror, because `data-empty` is a hook the styled
78
+ sheet reads and this tier has no sheet: an empty region left in the box
79
+ tree is a gap a consumer cannot close without knowing to look for it. The
80
+ styled rule stays, because that sheet sets `display` on this part and
81
+ therefore outranks the UA one. */
82
+ region?.toggleAttribute('hidden', empty);
83
+ }
84
+ /**
85
+ * The cross inside the dismiss button, behind a seam.
86
+ *
87
+ * Slot fallback, so a consumer replaces it by slotting; and a method, so the
88
+ * tier above replaces it by overriding. Those answer different people: the
89
+ * slot is for the page and the method is for whoever is building the styled
90
+ * layer, and a fallback with only the first is one a tier can restyle and
91
+ * cannot change.
92
+ *
93
+ * **Named for what it draws, which it was not.** It was `renderIcon`, with a
94
+ * description of "the mark for the announcement's tone", and it draws the `x`
95
+ * glyph inside the dismiss button and has never drawn a tone. The name is
96
+ * `renderIcon` on `Toast` and `Callout` too, and on both of those it takes a
97
+ * severity and draws exactly the tone mark this claimed to: the prose came
98
+ * from a sibling that meant it. An announcement has no tone mark at all.
99
+ */
100
+ renderDismissIcon() {
101
+ return html `<slot name="icon">
102
+ <svg part="dismiss-mark" viewBox=${x.viewBox} fill="currentColor" aria-hidden="true">
103
+ ${unsafeSVG(x.content)}
104
+ </svg>
105
+ </slot>`;
106
+ }
107
+ render() {
108
+ return html `<div part="content"><slot></slot></div>
109
+ <div part="actions"><slot name="actions"></slot></div>
110
+ ${
111
+ /* A plain `<button>`, the way `Menu` renders its way back and every
112
+ other in-shadow control in the library.
113
+
114
+ It was `helix-headless-icon-button`, which is the headless tier and
115
+ therefore ships no CSS at all, so the `<button>` inside it kept the
116
+ browser's own border and gray fill and the dismiss control read as a
117
+ form button dropped into a message bar. The styled tier could not
118
+ reach it: `[part="dismiss"]` selects the host and stops at its shadow
119
+ boundary, and its rules were already written for a plain button,
120
+ `all: unset` and all, which is the clue that this element was never
121
+ meant to be here.
122
+
123
+ Nesting a component inside a component's shadow root also makes the
124
+ parent depend on the child being registered, invisibly, and this was
125
+ the only place in the library doing it. */
126
+ this.dismissible
127
+ ? html `<button
128
+ part="dismiss"
129
+ type="button"
130
+ aria-label=${this.dismissLabel}
131
+ @click=${() => this.dismiss()}
132
+ >
133
+ ${this.renderDismissIcon()}
134
+ </button>`
135
+ : nothing}`;
136
+ }
137
+ };
138
+ __decorate([
139
+ property({ reflect: true })
140
+ ], HelixHeadlessAnnouncement.prototype, "tone", void 0);
141
+ HelixHeadlessAnnouncement = __decorate([
142
+ customElement('helix-headless-announcement')
143
+ ], HelixHeadlessAnnouncement);
144
+ export { HelixHeadlessAnnouncement };
@@ -0,0 +1 @@
1
+ export * from './root/app-header-root.js';
@@ -0,0 +1 @@
1
+ export * from './root/app-header-root.js';
@@ -0,0 +1,113 @@
1
+ import { HelixElement } from '@fusion.dev/helix-core';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
+ /**
4
+ * @summary Page-level banner holding brand, navigation, and actions.
5
+ *
6
+ * @description
7
+ * Tracks whether the page has scrolled and carries it as the custom state
8
+ * `scrolled`, so the styled tier can lift the bar off the page without a scroll
9
+ * handler of its own. Scroll position is the one piece of state the server
10
+ * genuinely cannot know, so it is read on connect rather than derived: a fresh
11
+ * load starts at the top, which is what the server rendered, and a reload
12
+ * part-way down corrects on hydration.
13
+ *
14
+ * **A custom state and not `data-scrolled`, which is what this used to be.**
15
+ * The attribute was written onto the host by the element itself, so a server
16
+ * sent the header without it and the element added it on upgrade. A framework
17
+ * hydrating the page then found an attribute it had not rendered and reported
18
+ * the tree as mismatched: intermittently, because it only happens when the
19
+ * reader reloads far enough down the page to pass the threshold. Every
20
+ * server-rendered consumer paid for that, and could only answer it by
21
+ * suppressing hydration warnings on an element they did not write.
22
+ *
23
+ * `ElementInternals.states` is deliberately not in the DOM, so there is nothing
24
+ * for a hydration pass to disagree with, and `:state(scrolled)` selects it. The
25
+ * base class made the same move for `data-settled` and its note explains the
26
+ * rest.
27
+ *
28
+ * The listener is passive and reads `scrollY` only, so it never blocks
29
+ * scrolling.
30
+ *
31
+ * Three regions, each in its own wrapper, because the row is a grid and a grid
32
+ * needs three items to put the middle one in the middle. A bare slot is
33
+ * `display: contents`, so its assigned elements become grid items themselves:
34
+ * two actions would take two tracks and push the navigation off center. These
35
+ * wrappers earn their boxes, which is the test; they carry no inset or fill of
36
+ * their own, so an empty one still paints nothing.
37
+ *
38
+ * The host is the banner and spans the viewport; the row inside it is what gets
39
+ * centered. A banner that is itself narrowed leaves its background stopping
40
+ * short of the window edges, which reads as a floating bar rather than as the
41
+ * top of the page. That needs one element and one row, not a wrapper as well:
42
+ * the host carries the material and `content` carries the measure.
43
+ *
44
+ * @since 0.1.0
45
+ * @status stable
46
+ * @category navigation
47
+ * @aliases Masthead, Navbar, TopBar
48
+ * @documentation https://helix.fusion.dev/components/app-header
49
+ *
50
+ * @slot - The middle region, usually a `Navigation`.
51
+ * @slot end - Trailing content.
52
+ * @slot start - Leading content, usually a wordmark.
53
+ *
54
+ * @event {HelixScrolledEvent} helix-scrolled - Fired when the page crosses the
55
+ * threshold, with the new state. A custom state cannot be observed the way an
56
+ * attribute could, so the header says when it changes rather than leaving
57
+ * consumers to run a second scroll listener and disagree about the hysteresis.
58
+ *
59
+ * @csspart content - The middle region.
60
+ * @csspart end - The trailing region.
61
+ * @csspart row - The centered row inside the banner.
62
+ * @csspart start - The leading region.
63
+ */
64
+ export declare class HelixHeadlessAppHeader extends HelixElement {
65
+ /**
66
+ * Where the middle region sits in the bar.
67
+ *
68
+ * Centered by default, which reads as the site's spine when the navigation is
69
+ * the primary thing in the header rather than an afterthought beside a logo.
70
+ * Centered against the banner rather than against whatever space the brand
71
+ * left over, so the middle of the nav is the middle of the window whatever
72
+ * the wordmark and the actions happen to measure.
73
+ *
74
+ * `start` is the opt-out, for a header whose middle region trails the brand.
75
+ *
76
+ * **Named for the region and not for what is usually in it.** It was
77
+ * `nav-align`, which reads as a property about `Navigation` and is not: the
78
+ * middle slot takes whatever a consumer puts there, a search field or a
79
+ * breadcrumb trail as readily as a nav, and a header that centered its search
80
+ * box would have been setting `nav-align` to do it. The part is called
81
+ * `content`, so the property is too.
82
+ */
83
+ contentAlign?: 'start';
84
+ private scrolled;
85
+ /**
86
+ * A band rather than a line, so the fill cannot flicker at the boundary.
87
+ *
88
+ * **`scrollY > 0` is a threshold with no width, and a threshold with no width
89
+ * is a switch sitting exactly where scroll positions cluster.** Zero is not a
90
+ * quiet place: rubber-banding overshoots past it and comes back, scroll
91
+ * anchoring nudges by a pixel when an image or a font lands, and a
92
+ * `scroll-behavior: smooth` jump settles by oscillating around its target.
93
+ * Every one of those crossings toggled the attribute, and the fill and the
94
+ * blur are both transitioned, so each toggle started a fresh animation in the
95
+ * opposite direction. What a reader sees is a bar that shimmers, and text
96
+ * legible through it for as long as the fill is part way in.
97
+ *
98
+ * Eight pixels to take the fill, two to give it back. Asymmetric on purpose:
99
+ * the bar should look attached to the top of the page for as long as it
100
+ * honestly is, so leaving is nearly the whole way back, and arriving needs
101
+ * enough travel to mean the reader moved rather than the layout did.
102
+ */
103
+ private readonly handleScroll;
104
+ protected willUpdate(changed: PropertyValues): void;
105
+ connectedCallback(): void;
106
+ disconnectedCallback(): void;
107
+ protected render(): TemplateResult;
108
+ }
109
+ declare global {
110
+ interface HTMLElementTagNameMap {
111
+ 'helix-headless-app-header': HelixHeadlessAppHeader;
112
+ }
113
+ }
@@ -0,0 +1,147 @@
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, HelixScrolledEvent, hostAria } from '@fusion.dev/helix-core';
8
+ import { html } from 'lit';
9
+ import { property } from 'lit/decorators.js';
10
+ /**
11
+ * @summary Page-level banner holding brand, navigation, and actions.
12
+ *
13
+ * @description
14
+ * Tracks whether the page has scrolled and carries it as the custom state
15
+ * `scrolled`, so the styled tier can lift the bar off the page without a scroll
16
+ * handler of its own. Scroll position is the one piece of state the server
17
+ * genuinely cannot know, so it is read on connect rather than derived: a fresh
18
+ * load starts at the top, which is what the server rendered, and a reload
19
+ * part-way down corrects on hydration.
20
+ *
21
+ * **A custom state and not `data-scrolled`, which is what this used to be.**
22
+ * The attribute was written onto the host by the element itself, so a server
23
+ * sent the header without it and the element added it on upgrade. A framework
24
+ * hydrating the page then found an attribute it had not rendered and reported
25
+ * the tree as mismatched: intermittently, because it only happens when the
26
+ * reader reloads far enough down the page to pass the threshold. Every
27
+ * server-rendered consumer paid for that, and could only answer it by
28
+ * suppressing hydration warnings on an element they did not write.
29
+ *
30
+ * `ElementInternals.states` is deliberately not in the DOM, so there is nothing
31
+ * for a hydration pass to disagree with, and `:state(scrolled)` selects it. The
32
+ * base class made the same move for `data-settled` and its note explains the
33
+ * rest.
34
+ *
35
+ * The listener is passive and reads `scrollY` only, so it never blocks
36
+ * scrolling.
37
+ *
38
+ * Three regions, each in its own wrapper, because the row is a grid and a grid
39
+ * needs three items to put the middle one in the middle. A bare slot is
40
+ * `display: contents`, so its assigned elements become grid items themselves:
41
+ * two actions would take two tracks and push the navigation off center. These
42
+ * wrappers earn their boxes, which is the test; they carry no inset or fill of
43
+ * their own, so an empty one still paints nothing.
44
+ *
45
+ * The host is the banner and spans the viewport; the row inside it is what gets
46
+ * centered. A banner that is itself narrowed leaves its background stopping
47
+ * short of the window edges, which reads as a floating bar rather than as the
48
+ * top of the page. That needs one element and one row, not a wrapper as well:
49
+ * the host carries the material and `content` carries the measure.
50
+ *
51
+ * @since 0.1.0
52
+ * @status stable
53
+ * @category navigation
54
+ * @aliases Masthead, Navbar, TopBar
55
+ * @documentation https://helix.fusion.dev/components/app-header
56
+ *
57
+ * @slot - The middle region, usually a `Navigation`.
58
+ * @slot end - Trailing content.
59
+ * @slot start - Leading content, usually a wordmark.
60
+ *
61
+ * @event {HelixScrolledEvent} helix-scrolled - Fired when the page crosses the
62
+ * threshold, with the new state. A custom state cannot be observed the way an
63
+ * attribute could, so the header says when it changes rather than leaving
64
+ * consumers to run a second scroll listener and disagree about the hysteresis.
65
+ *
66
+ * @csspart content - The middle region.
67
+ * @csspart end - The trailing region.
68
+ * @csspart row - The centered row inside the banner.
69
+ * @csspart start - The leading region.
70
+ */
71
+ let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
72
+ constructor() {
73
+ super(...arguments);
74
+ /* Whether the bar currently believes the page has moved, kept alongside the
75
+ attribute so a scroll that changes nothing writes nothing. */
76
+ this.scrolled = false;
77
+ /**
78
+ * A band rather than a line, so the fill cannot flicker at the boundary.
79
+ *
80
+ * **`scrollY > 0` is a threshold with no width, and a threshold with no width
81
+ * is a switch sitting exactly where scroll positions cluster.** Zero is not a
82
+ * quiet place: rubber-banding overshoots past it and comes back, scroll
83
+ * anchoring nudges by a pixel when an image or a font lands, and a
84
+ * `scroll-behavior: smooth` jump settles by oscillating around its target.
85
+ * Every one of those crossings toggled the attribute, and the fill and the
86
+ * blur are both transitioned, so each toggle started a fresh animation in the
87
+ * opposite direction. What a reader sees is a bar that shimmers, and text
88
+ * legible through it for as long as the fill is part way in.
89
+ *
90
+ * Eight pixels to take the fill, two to give it back. Asymmetric on purpose:
91
+ * the bar should look attached to the top of the page for as long as it
92
+ * honestly is, so leaving is nearly the whole way back, and arriving needs
93
+ * enough travel to mean the reader moved rather than the layout did.
94
+ */
95
+ this.handleScroll = () => {
96
+ const y = window.scrollY;
97
+ const next = this.scrolled ? y > 2 : y > 8;
98
+ if (next === this.scrolled) {
99
+ return;
100
+ }
101
+ this.scrolled = next;
102
+ /* The state is what CSS selects; the event is what anything outside this
103
+ element can hear. Both, because neither covers the other: a state cannot
104
+ be observed and an event cannot be styled. */
105
+ if (next) {
106
+ this.internals.states.add('scrolled');
107
+ }
108
+ else {
109
+ this.internals.states.delete('scrolled');
110
+ }
111
+ this.dispatchEvent(new HelixScrolledEvent({ scrolled: next }));
112
+ };
113
+ }
114
+ willUpdate(changed) {
115
+ super.willUpdate(changed);
116
+ // On the host, since the host is the banner.
117
+ hostAria(this.internals, { role: 'banner' });
118
+ }
119
+ connectedCallback() {
120
+ super.connectedCallback();
121
+ // Never reached on the server, which is correct: there is no scroll
122
+ // position to read there, and the un-scrolled markup it emits is what a
123
+ // fresh load actually shows.
124
+ window.addEventListener('scroll', this.handleScroll, { passive: true });
125
+ this.handleScroll();
126
+ }
127
+ disconnectedCallback() {
128
+ super.disconnectedCallback();
129
+ window.removeEventListener('scroll', this.handleScroll);
130
+ }
131
+ render() {
132
+ return html `
133
+ <div part="row">
134
+ <div part="start"><slot name="start"></slot></div>
135
+ <div part="content"><slot></slot></div>
136
+ <div part="end"><slot name="end"></slot></div>
137
+ </div>
138
+ `;
139
+ }
140
+ };
141
+ __decorate([
142
+ property({ attribute: 'content-align', reflect: true })
143
+ ], HelixHeadlessAppHeader.prototype, "contentAlign", void 0);
144
+ HelixHeadlessAppHeader = __decorate([
145
+ customElement('helix-headless-app-header')
146
+ ], HelixHeadlessAppHeader);
147
+ export { HelixHeadlessAppHeader };
@@ -0,0 +1,116 @@
1
+ import { HelixElement } from '@fusion.dev/helix-core';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
+ /**
4
+ * The largest `max` the styled tier can hide past.
5
+ *
6
+ * The fold is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
7
+ * per value, because `An+B` takes a literal and no custom property can be read
8
+ * into it. So the range is finite and this is where it is written down, in the
9
+ * tier that has to agree with it: a count that folds and a stylesheet that does
10
+ * not would put a "+5" beside five avatars that are still on screen.
11
+ */
12
+ export declare const FOLDS_UP_TO = 12;
13
+ /**
14
+ * @summary Overlapping avatars, with a count for the ones not shown.
15
+ *
16
+ * @description
17
+ * A part of `Avatar` rather than a family of its own: it arranges avatars and
18
+ * is about nothing else, and its member is a complete `Avatar` the group did
19
+ * not have to explain.
20
+ *
21
+ * **The overflow count is the group's, not a slot.** Which avatars are hidden
22
+ * is a fact the group works out from `max` and how many it was given, so a
23
+ * consumer writing the "+3" themselves would be writing a number that has to
24
+ * agree with a list they do not control.
25
+ *
26
+ * **Hidden, not removed.** Past `max`, the extra avatars stay in the DOM and
27
+ * stop being shown, so nothing re-renders when `max` changes and the accessible
28
+ * name can still be built from all of them. The count is what a sighted reader
29
+ * gets; the group's own name is what everyone else gets, and "Seven people" is
30
+ * more useful than seven names read in a row.
31
+ *
32
+ * **And hidden by the stylesheet, not by this class.** It wrote `data-overflow`
33
+ * onto each avatar from `updated`, which is one update too late and one element
34
+ * too far out: Lit renders on a microtask, so an avatar appended past the limit
35
+ * was laid out and painted before anything ran to hide it, and the group was
36
+ * writing attributes onto markup a consumer owns to do it. Measured in Chrome
37
+ * 148, appending two past `max="3"` and reading before yielding: five `flex`,
38
+ * folding to three on the next update. The styled tier now does it with
39
+ * `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, which is right at the
40
+ * first style resolution and writes nothing.
41
+ *
42
+ * **The fold is finite, and the count agrees with it.** `An+B` takes a literal,
43
+ * so there is one selector per value of `max` and the range stops at twelve.
44
+ * Past that the group shows everyone, counts nothing and says so, because
45
+ * showing everyone is a defensible answer and showing everyone beside a "+5" is
46
+ * not. `max` above twelve is a list the consumer should be slicing themselves.
47
+ *
48
+ * **It is a list.** A row of faces is a set of separate people, and a group
49
+ * with no role announces as one run of text. `role="list"` needs its children
50
+ * to be `listitem`, which they cannot be told to become without writing an
51
+ * attribute onto a consumer's element, so the group carries `role="group"` and
52
+ * its name instead: one announcement, correct, and nothing written to anyone
53
+ * else's markup.
54
+ *
55
+ * @since 0.1.0
56
+ * @status stable
57
+ * @aliases Avatar stack, Facepile
58
+ * @documentation https://helix.fusion.dev/components/avatar
59
+ *
60
+ * @slot - The avatars, in the order they should be read.
61
+ *
62
+ * @csspart overflow - The count of avatars past `max`.
63
+ */
64
+ export declare class HelixHeadlessAvatarGroup extends HelixElement {
65
+ /**
66
+ * Accessible name for the set, such as "Reviewers".
67
+ */
68
+ label: string;
69
+ /**
70
+ * How many avatars are shown before the rest become a count.
71
+ *
72
+ * Unset shows all of them, which is what no limit means and is more useful
73
+ * than refusing to render.
74
+ *
75
+ * **Reflected, because the fold is a stylesheet rule and nothing else.** The
76
+ * styled tier hides past the limit with `:host([max="N"]) ::slotted(:nth-child(n + N+1))`,
77
+ * so the attribute *is* the mechanism: a `max` that reaches this property and
78
+ * never reaches the host matches no rule, and every avatar is drawn beside a
79
+ * count that says two of them are hidden. That is the failure this repository
80
+ * already writes down as "reflect only what CSS selects on", and it went
81
+ * unnoticed because the examples set `max` in markup, where the author had
82
+ * written the attribute themselves.
83
+ *
84
+ * It is the path a script takes that was broken, and React takes it for
85
+ * everyone: React assigns a matching property rather than an attribute, so
86
+ * `<helix-avatar-group max={4}>` folded nothing at all. Measured against the
87
+ * markup twin, the fifth and sixth avatars rendered at full size where the
88
+ * markup version had them at 0x0.
89
+ *
90
+ * **Optional rather than defaulted, per the rule that a reflected property
91
+ * takes no default**: `max = 0` would stamp `max="0"` onto every host that
92
+ * never asked for a limit, including on the server.
93
+ */
94
+ max?: number;
95
+ /** The avatars, in light-DOM order. Empty on the server, which has no tree. */
96
+ get avatars(): HTMLElement[];
97
+ /**
98
+ * How many avatars are past the limit, and so not shown.
99
+ *
100
+ * Not `hidden`, which is `HTMLElement`'s own boolean: a getter of that name
101
+ * returning a number is a type error, and had it been assignable it would
102
+ * have been worse, because a group with three extra members would have set
103
+ * the attribute that hides the whole group.
104
+ */
105
+ get overflow(): number;
106
+ /** Said once per element, because a re-render is not a second mistake. */
107
+ private warned;
108
+ protected willUpdate(changed: PropertyValues): void;
109
+ protected updated(changed: PropertyValues): void;
110
+ protected render(): TemplateResult;
111
+ }
112
+ declare global {
113
+ interface HTMLElementTagNameMap {
114
+ 'helix-headless-avatar-group': HelixHeadlessAvatarGroup;
115
+ }
116
+ }
@@ -0,0 +1,136 @@
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, hostAria } from '@fusion.dev/helix-core';
8
+ import { html } from 'lit';
9
+ import { property } from 'lit/decorators.js';
10
+ /**
11
+ * The largest `max` the styled tier can hide past.
12
+ *
13
+ * The fold is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
14
+ * per value, because `An+B` takes a literal and no custom property can be read
15
+ * into it. So the range is finite and this is where it is written down, in the
16
+ * tier that has to agree with it: a count that folds and a stylesheet that does
17
+ * not would put a "+5" beside five avatars that are still on screen.
18
+ */
19
+ export const FOLDS_UP_TO = 12;
20
+ /**
21
+ * @summary Overlapping avatars, with a count for the ones not shown.
22
+ *
23
+ * @description
24
+ * A part of `Avatar` rather than a family of its own: it arranges avatars and
25
+ * is about nothing else, and its member is a complete `Avatar` the group did
26
+ * not have to explain.
27
+ *
28
+ * **The overflow count is the group's, not a slot.** Which avatars are hidden
29
+ * is a fact the group works out from `max` and how many it was given, so a
30
+ * consumer writing the "+3" themselves would be writing a number that has to
31
+ * agree with a list they do not control.
32
+ *
33
+ * **Hidden, not removed.** Past `max`, the extra avatars stay in the DOM and
34
+ * stop being shown, so nothing re-renders when `max` changes and the accessible
35
+ * name can still be built from all of them. The count is what a sighted reader
36
+ * gets; the group's own name is what everyone else gets, and "Seven people" is
37
+ * more useful than seven names read in a row.
38
+ *
39
+ * **And hidden by the stylesheet, not by this class.** It wrote `data-overflow`
40
+ * onto each avatar from `updated`, which is one update too late and one element
41
+ * too far out: Lit renders on a microtask, so an avatar appended past the limit
42
+ * was laid out and painted before anything ran to hide it, and the group was
43
+ * writing attributes onto markup a consumer owns to do it. Measured in Chrome
44
+ * 148, appending two past `max="3"` and reading before yielding: five `flex`,
45
+ * folding to three on the next update. The styled tier now does it with
46
+ * `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, which is right at the
47
+ * first style resolution and writes nothing.
48
+ *
49
+ * **The fold is finite, and the count agrees with it.** `An+B` takes a literal,
50
+ * so there is one selector per value of `max` and the range stops at twelve.
51
+ * Past that the group shows everyone, counts nothing and says so, because
52
+ * showing everyone is a defensible answer and showing everyone beside a "+5" is
53
+ * not. `max` above twelve is a list the consumer should be slicing themselves.
54
+ *
55
+ * **It is a list.** A row of faces is a set of separate people, and a group
56
+ * with no role announces as one run of text. `role="list"` needs its children
57
+ * to be `listitem`, which they cannot be told to become without writing an
58
+ * attribute onto a consumer's element, so the group carries `role="group"` and
59
+ * its name instead: one announcement, correct, and nothing written to anyone
60
+ * else's markup.
61
+ *
62
+ * @since 0.1.0
63
+ * @status stable
64
+ * @aliases Avatar stack, Facepile
65
+ * @documentation https://helix.fusion.dev/components/avatar
66
+ *
67
+ * @slot - The avatars, in the order they should be read.
68
+ *
69
+ * @csspart overflow - The count of avatars past `max`.
70
+ */
71
+ let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixElement {
72
+ constructor() {
73
+ super(...arguments);
74
+ /**
75
+ * Accessible name for the set, such as "Reviewers".
76
+ */
77
+ this.label = '';
78
+ /** Said once per element, because a re-render is not a second mistake. */
79
+ this.warned = false;
80
+ }
81
+ /** The avatars, in light-DOM order. Empty on the server, which has no tree. */
82
+ get avatars() {
83
+ /* `?? []` is the server: Lit's element shim carries attributes and not a
84
+ tree, so `children` is undefined there and spreading it throws. The same
85
+ fault the menu item, the table and the carousel each had in turn, which
86
+ is why it is written before it can happen again. */
87
+ return [...(this.children ?? [])].filter((child) => child instanceof HTMLElement);
88
+ }
89
+ /**
90
+ * How many avatars are past the limit, and so not shown.
91
+ *
92
+ * Not `hidden`, which is `HTMLElement`'s own boolean: a getter of that name
93
+ * returning a number is a type error, and had it been assignable it would
94
+ * have been worse, because a group with three extra members would have set
95
+ * the attribute that hides the whole group.
96
+ */
97
+ get overflow() {
98
+ const limit = this.max ?? 0;
99
+ const limited = limit > 0 && limit <= FOLDS_UP_TO;
100
+ return limited ? Math.max(this.avatars.length - limit, 0) : 0;
101
+ }
102
+ willUpdate(changed) {
103
+ super.willUpdate(changed);
104
+ hostAria(this.internals, { label: this.label, role: 'group' });
105
+ }
106
+ updated(changed) {
107
+ super.updated(changed);
108
+ /* Nothing hides anything here any more: the stylesheet does it, from `max`
109
+ on the host, so the arrangement is right at the first style resolution
110
+ rather than one update later. What is left is saying so when a `max` is
111
+ set that no rule can match, because showing everyone is a defensible
112
+ answer and showing everyone beside a "+5" is not. */
113
+ const limit = this.max ?? 0;
114
+ if (limit > FOLDS_UP_TO && this.avatars.length > limit && !this.warned) {
115
+ this.warned = true;
116
+ console.warn(`<${this.localName}> has max="${this.max}", past the ${FOLDS_UP_TO} the fold is written for, ` +
117
+ 'so every avatar is shown and none are counted. Lower `max`, or hand the group the ' +
118
+ 'avatars you want shown.');
119
+ }
120
+ }
121
+ render() {
122
+ const past = this.overflow;
123
+ return html `<slot @slotchange=${() => this.requestUpdate()}></slot>
124
+ ${past > 0 ? html `<span part="overflow" aria-hidden="true">+${past}</span>` : ''}`;
125
+ }
126
+ };
127
+ __decorate([
128
+ property()
129
+ ], HelixHeadlessAvatarGroup.prototype, "label", void 0);
130
+ __decorate([
131
+ property({ reflect: true, type: Number })
132
+ ], HelixHeadlessAvatarGroup.prototype, "max", void 0);
133
+ HelixHeadlessAvatarGroup = __decorate([
134
+ customElement('helix-headless-avatar-group')
135
+ ], HelixHeadlessAvatarGroup);
136
+ export { HelixHeadlessAvatarGroup };
@@ -0,0 +1,2 @@
1
+ export * from './group/avatar-group.js';
2
+ export * from './root/avatar-root.js';
@@ -0,0 +1,2 @@
1
+ export * from './group/avatar-group.js';
2
+ export * from './root/avatar-root.js';