@fusion.dev/helix-headless 0.145.0 → 0.147.0

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 (343) hide show
  1. package/custom-elements.json +12286 -4281
  2. package/dist/accordion/item/accordion-item.d.ts +51 -18
  3. package/dist/accordion/item/accordion-item.js +45 -13
  4. package/dist/accordion/root/accordion-root.d.ts +16 -7
  5. package/dist/accordion/root/accordion-root.js +3 -3
  6. package/dist/announcement/root/announcement-root.d.ts +16 -6
  7. package/dist/announcement/root/announcement-root.js +37 -7
  8. package/dist/app-header/root/app-header-root.d.ts +7 -2
  9. package/dist/app-header/root/app-header-root.js +9 -1
  10. package/dist/app-header/sectioning.d.ts +3 -1
  11. package/dist/app-header/sectioning.js +3 -2
  12. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  13. package/dist/area-chart/root/area-chart-root.js +11 -3
  14. package/dist/avatar/group/avatar-group.d.ts +20 -14
  15. package/dist/avatar/group/avatar-group.js +17 -19
  16. package/dist/avatar/root/avatar-root.d.ts +31 -1
  17. package/dist/avatar/root/avatar-root.js +11 -1
  18. package/dist/badge/root/badge-root.d.ts +60 -7
  19. package/dist/badge/root/badge-root.js +89 -6
  20. package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
  21. package/dist/bar-chart/root/bar-chart-root.js +48 -20
  22. package/dist/bar-chart/stack.d.ts +25 -0
  23. package/dist/bar-chart/stack.js +27 -0
  24. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  25. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  26. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
  27. package/dist/breadcrumbs/root/breadcrumbs-root.js +51 -4
  28. package/dist/button/root/button-root.d.ts +50 -38
  29. package/dist/button/root/button-root.js +42 -53
  30. package/dist/button/submitter.d.ts +27 -0
  31. package/dist/button/submitter.js +25 -0
  32. package/dist/button-group/root/button-group-root.d.ts +2 -1
  33. package/dist/button-group/root/button-group-root.js +5 -1
  34. package/dist/canvas/node/canvas-node.d.ts +4 -3
  35. package/dist/canvas/node/canvas-node.js +3 -2
  36. package/dist/canvas/root/canvas-root.js +2 -2
  37. package/dist/card/root/card-root.d.ts +36 -4
  38. package/dist/card/root/card-root.js +29 -10
  39. package/dist/carousel/root/carousel-root.d.ts +43 -4
  40. package/dist/carousel/root/carousel-root.js +40 -12
  41. package/dist/carousel/stops.d.ts +20 -0
  42. package/dist/carousel/stops.js +30 -0
  43. package/dist/chat/message/chat-message.js +5 -4
  44. package/dist/chat/naming.d.ts +5 -1
  45. package/dist/chat/naming.js +4 -2
  46. package/dist/chat/root/chat-root.d.ts +40 -4
  47. package/dist/chat/root/chat-root.js +32 -6
  48. package/dist/checkbox/root/checkbox-root.d.ts +20 -0
  49. package/dist/checkbox/root/checkbox-root.js +18 -7
  50. package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
  51. package/dist/checkbox-group/root/checkbox-group-root.js +14 -11
  52. package/dist/checkbox-group/select-all.d.ts +21 -0
  53. package/dist/checkbox-group/select-all.js +7 -0
  54. package/dist/code-block/highlight.d.ts +15 -0
  55. package/dist/code-block/highlight.js +4 -0
  56. package/dist/code-block/root/code-block-root.d.ts +79 -10
  57. package/dist/code-block/root/code-block-root.js +74 -5
  58. package/dist/color-input/root/color-input-root.d.ts +14 -0
  59. package/dist/color-input/root/color-input-root.js +17 -7
  60. package/dist/color-picker/channels.js +1 -2
  61. package/dist/color-picker/root/color-picker-root.d.ts +53 -16
  62. package/dist/color-picker/root/color-picker-root.js +155 -46
  63. package/dist/color-picker/wheel.d.ts +17 -0
  64. package/dist/color-picker/wheel.js +6 -0
  65. package/dist/combobox/root/combobox-root.d.ts +56 -0
  66. package/dist/combobox/root/combobox-root.js +92 -15
  67. package/dist/command/root/command-root.d.ts +19 -2
  68. package/dist/command/root/command-root.js +24 -23
  69. package/dist/copy-button/root/copy-button-root.d.ts +21 -1
  70. package/dist/copy-button/root/copy-button-root.js +16 -4
  71. package/dist/data-table/index.d.ts +1 -1
  72. package/dist/data-table/index.js +1 -1
  73. package/dist/data-table/keys.d.ts +6 -0
  74. package/dist/data-table/keys.js +14 -0
  75. package/dist/data-table/root/data-table-root.d.ts +27 -18
  76. package/dist/data-table/root/data-table-root.js +31 -57
  77. package/dist/data-table/tree.d.ts +16 -1
  78. package/dist/data-table/tree.js +2 -3
  79. package/dist/date-input/root/date-input-root.d.ts +11 -2
  80. package/dist/date-input/root/date-input-root.js +26 -12
  81. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  82. package/dist/date-picker/root/date-picker-root.js +33 -22
  83. package/dist/description-list/item/description-list-item.d.ts +18 -4
  84. package/dist/description-list/item/description-list-item.js +8 -4
  85. package/dist/dialog/description.js +15 -1
  86. package/dist/dialog/root/dialog-root.d.ts +8 -2
  87. package/dist/dialog/root/dialog-root.js +16 -1
  88. package/dist/divider/root/divider-root.d.ts +3 -0
  89. package/dist/divider/root/divider-root.js +2 -1
  90. package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
  91. package/dist/donut-chart/root/donut-chart-root.js +55 -1
  92. package/dist/donut-chart/slice-label.d.ts +35 -0
  93. package/dist/donut-chart/slice-label.js +11 -0
  94. package/dist/drawer/reveal.d.ts +8 -0
  95. package/dist/drawer/reveal.js +1 -0
  96. package/dist/drawer/root/drawer-root.d.ts +63 -2
  97. package/dist/drawer/root/drawer-root.js +75 -4
  98. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  99. package/dist/drilldown/item/drilldown-item.js +40 -5
  100. package/dist/drilldown/root/drilldown-root.d.ts +21 -3
  101. package/dist/drilldown/root/drilldown-root.js +22 -3
  102. package/dist/element-events.generated.js +35 -6
  103. package/dist/empty/root/empty-root.d.ts +34 -2
  104. package/dist/empty/root/empty-root.js +26 -4
  105. package/dist/file-input/root/file-input-root.d.ts +99 -8
  106. package/dist/file-input/root/file-input-root.js +120 -22
  107. package/dist/file-input/screen.d.ts +2 -1
  108. package/dist/file-input/status.d.ts +24 -0
  109. package/dist/file-input/status.js +10 -0
  110. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  111. package/dist/filter-input/chip/filter-chip.js +11 -2
  112. package/dist/filter-input/menu/filter-menu.d.ts +2 -0
  113. package/dist/filter-input/menu/filter-menu.js +12 -4
  114. package/dist/filter-input/root/filter-input-root.d.ts +38 -6
  115. package/dist/filter-input/root/filter-input-root.js +18 -28
  116. package/dist/filter-input/suggest.d.ts +28 -3
  117. package/dist/filter-input/suggest.js +18 -8
  118. package/dist/format-date/options.d.ts +3 -4
  119. package/dist/format-date/options.js +2 -2
  120. package/dist/format-date/root/format-date-root.d.ts +27 -17
  121. package/dist/format-date/root/format-date-root.js +27 -48
  122. package/dist/heatmap/root/buckets.d.ts +21 -0
  123. package/dist/heatmap/root/buckets.js +34 -0
  124. package/dist/heatmap/root/heatmap-root.d.ts +83 -11
  125. package/dist/heatmap/root/heatmap-root.js +104 -12
  126. package/dist/icon/index.d.ts +1 -1
  127. package/dist/icon/index.js +1 -1
  128. package/dist/icon/registry.d.ts +26 -1
  129. package/dist/icon/registry.js +12 -1
  130. package/dist/icon/root/icon-root.d.ts +25 -1
  131. package/dist/icon/root/icon-root.js +44 -12
  132. package/dist/icon/root/index.d.ts +1 -1
  133. package/dist/icon/root/index.js +1 -1
  134. package/dist/icon/settle.d.ts +7 -0
  135. package/dist/icon/settle.js +10 -0
  136. package/dist/icon-button/root/icon-button-root.d.ts +2 -0
  137. package/dist/image/root/image-root.d.ts +14 -1
  138. package/dist/image/root/image-root.js +7 -2
  139. package/dist/input/root/input-root.d.ts +34 -3
  140. package/dist/input/root/input-root.js +17 -4
  141. package/dist/kbd/keys.d.ts +29 -0
  142. package/dist/kbd/keys.js +52 -0
  143. package/dist/kbd/root/kbd-root.d.ts +52 -1
  144. package/dist/kbd/root/kbd-root.js +40 -47
  145. package/dist/legend/hidden-series.d.ts +10 -2
  146. package/dist/legend/hidden-series.js +5 -2
  147. package/dist/legend/root/legend-root.d.ts +77 -12
  148. package/dist/legend/root/legend-root.js +71 -17
  149. package/dist/lightbox/root/lightbox-root.d.ts +98 -10
  150. package/dist/lightbox/root/lightbox-root.js +153 -18
  151. package/dist/lightbox/zoom-controller.d.ts +59 -0
  152. package/dist/lightbox/zoom-controller.js +128 -0
  153. package/dist/lightbox/zoom.d.ts +24 -0
  154. package/dist/lightbox/zoom.js +18 -0
  155. package/dist/line-chart/root/line-chart-root.d.ts +38 -1
  156. package/dist/line-chart/root/line-chart-root.js +31 -3
  157. package/dist/list/item/list-item.d.ts +2 -0
  158. package/dist/list/item/list-item.js +11 -2
  159. package/dist/list/root/list-root.d.ts +70 -13
  160. package/dist/list/root/list-root.js +91 -13
  161. package/dist/list/selection.d.ts +54 -7
  162. package/dist/list/selection.js +32 -7
  163. package/dist/listbox/root/listbox-root.d.ts +44 -4
  164. package/dist/listbox/root/listbox-root.js +72 -34
  165. package/dist/loader/busy.d.ts +10 -0
  166. package/dist/loader/busy.js +11 -0
  167. package/dist/loader/root/loader-root.d.ts +9 -2
  168. package/dist/loader/root/loader-root.js +23 -3
  169. package/dist/megamenu/hand-over.d.ts +75 -0
  170. package/dist/megamenu/hand-over.js +67 -0
  171. package/dist/megamenu/root/megamenu-root.d.ts +80 -15
  172. package/dist/megamenu/root/megamenu-root.js +76 -19
  173. package/dist/menu/item/menu-item.d.ts +51 -2
  174. package/dist/menu/item/menu-item.js +50 -26
  175. package/dist/menu/root/menu-root.d.ts +17 -0
  176. package/dist/menu/root/menu-root.js +2 -2
  177. package/dist/meter/root/meter-root.d.ts +62 -1
  178. package/dist/meter/root/meter-root.js +38 -16
  179. package/dist/navigation/root/navigation-root.d.ts +2 -1
  180. package/dist/navigation/root/navigation-root.js +2 -2
  181. package/dist/notifications/root/notifications-root.d.ts +20 -4
  182. package/dist/notifications/root/notifications-root.js +30 -8
  183. package/dist/number-input/grain.d.ts +28 -0
  184. package/dist/number-input/grain.js +14 -0
  185. package/dist/number-input/root/number-input-root.d.ts +34 -9
  186. package/dist/number-input/root/number-input-root.js +31 -25
  187. package/dist/object-inspector/root/object-inspector-root.d.ts +88 -33
  188. package/dist/object-inspector/root/object-inspector-root.js +134 -92
  189. package/dist/object-inspector/rows.d.ts +18 -0
  190. package/dist/object-inspector/rows.js +33 -0
  191. package/dist/option/index.d.ts +1 -0
  192. package/dist/option/index.js +1 -0
  193. package/dist/option/root/option-root.d.ts +5 -3
  194. package/dist/option/separator/option-separator.d.ts +30 -0
  195. package/dist/option/separator/option-separator.js +21 -0
  196. package/dist/outline/root/outline-root.d.ts +30 -0
  197. package/dist/outline/root/outline-root.js +17 -13
  198. package/dist/pagination/size/pagination-size.d.ts +6 -0
  199. package/dist/pagination/size/pagination-size.js +5 -3
  200. package/dist/pin-input/code.d.ts +37 -0
  201. package/dist/pin-input/code.js +25 -0
  202. package/dist/pin-input/root/pin-input-root.d.ts +116 -115
  203. package/dist/pin-input/root/pin-input-root.js +163 -155
  204. package/dist/popover/hide-outside.d.ts +14 -0
  205. package/dist/popover/hide-outside.js +34 -0
  206. package/dist/popover/root/popover-root.d.ts +64 -8
  207. package/dist/popover/root/popover-root.js +67 -4
  208. package/dist/progress/root/progress-root.d.ts +47 -0
  209. package/dist/progress/root/progress-root.js +34 -16
  210. package/dist/qr-code/export.d.ts +45 -1
  211. package/dist/qr-code/export.js +28 -0
  212. package/dist/qr-code/name.d.ts +11 -0
  213. package/dist/qr-code/name.js +7 -0
  214. package/dist/qr-code/root/qr-code-root.d.ts +36 -11
  215. package/dist/qr-code/root/qr-code-root.js +58 -11
  216. package/dist/quote/marks.d.ts +8 -0
  217. package/dist/quote/marks.js +5 -0
  218. package/dist/quote/root/quote-root.d.ts +14 -2
  219. package/dist/quote/root/quote-root.js +23 -1
  220. package/dist/radio/group/radio-group.d.ts +15 -0
  221. package/dist/radio/root/radio-root.d.ts +6 -2
  222. package/dist/radio/root/radio-root.js +7 -2
  223. package/dist/rating/root/rating-root.d.ts +30 -12
  224. package/dist/rating/root/rating-root.js +27 -27
  225. package/dist/scatter-chart/fit.d.ts +15 -0
  226. package/dist/scatter-chart/fit.js +35 -0
  227. package/dist/scatter-chart/root/scatter-chart-root.d.ts +51 -1
  228. package/dist/scatter-chart/root/scatter-chart-root.js +64 -24
  229. package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
  230. package/dist/scroll-area/root/scroll-area-root.js +57 -173
  231. package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
  232. package/dist/scroll-area/scrollbar-controller.js +172 -0
  233. package/dist/scroll-area/scrollbar.d.ts +27 -8
  234. package/dist/scroll-area/scrollbar.js +10 -1
  235. package/dist/select/align.d.ts +47 -0
  236. package/dist/select/align.js +7 -0
  237. package/dist/select/root/select-root.d.ts +71 -0
  238. package/dist/select/root/select-root.js +78 -6
  239. package/dist/skeleton/root/skeleton-root.d.ts +3 -0
  240. package/dist/skeleton/root/skeleton-root.js +4 -2
  241. package/dist/skip-link/root/skip-link-root.js +2 -2
  242. package/dist/slider/root/slider-root.d.ts +59 -5
  243. package/dist/slider/root/slider-root.js +45 -3
  244. package/dist/sparkline/readings.d.ts +36 -0
  245. package/dist/sparkline/readings.js +36 -0
  246. package/dist/sparkline/root/sparkline-root.d.ts +121 -7
  247. package/dist/sparkline/root/sparkline-root.js +160 -26
  248. package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
  249. package/dist/speed-dial/item/speed-dial-item.js +2 -2
  250. package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
  251. package/dist/speed-dial/root/speed-dial-root.js +11 -3
  252. package/dist/splitter/root/splitter-root.d.ts +10 -12
  253. package/dist/splitter/root/splitter-root.js +211 -204
  254. package/dist/stat/root/stat-root.d.ts +14 -5
  255. package/dist/stat/root/stat-root.js +21 -5
  256. package/dist/steps/reach.d.ts +5 -0
  257. package/dist/steps/reach.js +3 -0
  258. package/dist/steps/root/steps-root.d.ts +56 -3
  259. package/dist/steps/root/steps-root.js +50 -6
  260. package/dist/steps/step/step.d.ts +8 -0
  261. package/dist/steps/step/step.js +8 -3
  262. package/dist/switch/root/switch-root.d.ts +10 -0
  263. package/dist/table/column/table-column.d.ts +6 -10
  264. package/dist/table/column/table-column.js +8 -20
  265. package/dist/table/root/table-root.d.ts +31 -10
  266. package/dist/table/root/table-root.js +14 -18
  267. package/dist/table/row/table-row.d.ts +24 -0
  268. package/dist/table/row/table-row.js +37 -1
  269. package/dist/tabs/panel/tab-panel.d.ts +16 -3
  270. package/dist/tabs/panel/tab-panel.js +34 -5
  271. package/dist/tabs/root/tabs-root.d.ts +17 -3
  272. package/dist/tabs/root/tabs-root.js +1 -1
  273. package/dist/tabs/tab/tab.d.ts +5 -0
  274. package/dist/tabs/tab/tab.js +5 -2
  275. package/dist/tag/group/tag-group.d.ts +44 -5
  276. package/dist/tag/group/tag-group.js +60 -9
  277. package/dist/tag/root/tag-root.js +9 -2
  278. package/dist/textarea/root/textarea-root.d.ts +41 -2
  279. package/dist/textarea/root/textarea-root.js +39 -1
  280. package/dist/time-input/root/time-input-root.d.ts +10 -2
  281. package/dist/time-input/root/time-input-root.js +24 -13
  282. package/dist/time-picker/root/time-picker-root.d.ts +28 -17
  283. package/dist/time-picker/root/time-picker-root.js +18 -29
  284. package/dist/time-picker/wheel-name.d.ts +9 -0
  285. package/dist/time-picker/wheel-name.js +15 -0
  286. package/dist/timeline/group/timeline-group.js +2 -2
  287. package/dist/toast/item/toast-item.d.ts +16 -3
  288. package/dist/toast/item/toast-item.js +22 -6
  289. package/dist/toast/root/toast-root.d.ts +34 -4
  290. package/dist/toast/root/toast-root.js +74 -13
  291. package/dist/toast/words.d.ts +12 -0
  292. package/dist/toast/words.js +25 -0
  293. package/dist/toggle/group/toggle-group.d.ts +52 -7
  294. package/dist/toggle/group/toggle-group.js +58 -44
  295. package/dist/toggle/root/toggle-root.js +2 -4
  296. package/dist/toolbar/root/toolbar-root.d.ts +21 -5
  297. package/dist/toolbar/root/toolbar-root.js +52 -8
  298. package/dist/tooltip/root/tooltip-root.d.ts +20 -3
  299. package/dist/tooltip/root/tooltip-root.js +18 -1
  300. package/dist/tour/back.d.ts +10 -0
  301. package/dist/tour/back.js +8 -0
  302. package/dist/tour/root/tour-root.d.ts +45 -2
  303. package/dist/tour/root/tour-root.js +53 -8
  304. package/dist/tour/stop/tour-stop.d.ts +3 -0
  305. package/dist/tour/stop/tour-stop.js +3 -3
  306. package/dist/tree/item/tree-item.d.ts +7 -3
  307. package/dist/tree/item/tree-item.js +3 -0
  308. package/dist/tree/root/tree-root.d.ts +24 -3
  309. package/dist/tree/root/tree-root.js +32 -13
  310. package/dist/tree/selection.js +2 -15
  311. package/dist/trend/figure.d.ts +16 -0
  312. package/dist/trend/figure.js +8 -0
  313. package/dist/trend/root/trend-root.d.ts +83 -19
  314. package/dist/trend/root/trend-root.js +59 -8
  315. package/dist/video/media-events.d.ts +13 -18
  316. package/dist/video/media-events.js +1 -5
  317. package/dist/video/root/extra-controls.d.ts +12 -0
  318. package/dist/video/root/extra-controls.js +6 -2
  319. package/dist/video/root/video-root.d.ts +23 -6
  320. package/dist/video/root/video-root.js +19 -10
  321. package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
  322. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  323. package/dist/video-playlist/root/video-playlist-root.d.ts +17 -1
  324. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  325. package/dist/virtual-list/fill.d.ts +11 -8
  326. package/dist/virtual-list/fill.js +10 -17
  327. package/dist/virtual-list/keys.d.ts +16 -7
  328. package/dist/virtual-list/keys.js +17 -6
  329. package/dist/virtual-list/plan.d.ts +65 -0
  330. package/dist/virtual-list/plan.js +27 -0
  331. package/dist/virtual-list/root/virtual-list-root.d.ts +136 -13
  332. package/dist/virtual-list/root/virtual-list-root.js +218 -51
  333. package/lint.json +1 -1
  334. package/package.json +8 -8
  335. package/types/jsx.d.ts +7441 -1458
  336. package/types/svelte.d.ts +1 -0
  337. package/types/vue.d.ts +1501 -326
  338. package/dist/chat/relative-clock.d.ts +0 -39
  339. package/dist/chat/relative-clock.js +0 -31
  340. package/dist/data-table/root/order.d.ts +0 -141
  341. package/dist/data-table/root/order.js +0 -76
  342. package/dist/tag/selection.d.ts +0 -10
  343. package/dist/tag/selection.js +0 -12
@@ -4,54 +4,106 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, customElement, elementById, HelixElement, HelixLoadMoreEvent, HelixRangeChangeEvent, searchableById, VirtualizeController, } from '@fusion.dev/helix-core';
8
- import { html, render } from 'lit';
7
+ import { AriaForwardController, commaList, customElement, elementById, HelixBeforeChangeEvent, HelixElement, HelixLoadMoreEvent, HelixRangeChangeEvent, isRtl, rangeAdd, requestChange, searchableById, selectsAll, Typeahead, toggleValue, typesCharacter, VirtualizeController, } from '@fusion.dev/helix-core';
8
+ import { html, nothing, render } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
10
  import { holdControls, releaseControls } from '../controls.js';
11
- import { fillHoles } from '../fill.js';
11
+ import { fillHoles, keyOf, textsOf } from '../fill.js';
12
12
  import { stepIndex } from '../keys.js';
13
+ import { drawPlan, itemsOf, stopAfter } from '../plan.js';
13
14
  let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixElement {
14
15
  constructor() {
15
16
  super(...arguments);
17
+ this.columns = 1;
16
18
  this.estimate = 32;
17
19
  this.for = '';
20
+ this.keyField = '';
18
21
  this.label = '';
22
+ this.loading = false;
23
+ this.loadingLabel = 'Loading more';
19
24
  this.measured = false;
25
+ this.textField = '';
26
+ this.value = '';
20
27
  this.rows = [];
21
28
  this.source = null;
22
29
  this.active = 0;
23
30
  this.said = { first: 0, last: 0 };
24
- this.askedAt = -1;
31
+ this.typeahead = new Typeahead();
25
32
  this.aria = new AriaForwardController(this, {
26
33
  label: true,
27
34
  target: () => this.partNamed('viewport'),
28
35
  });
29
36
  this.virtualize = new VirtualizeController(this, {
30
37
  container: () => this.partNamed('viewport'),
31
- count: () => this.data.length,
38
+ count: () => Math.ceil(this.data.length / this.across),
32
39
  estimate: () => this.estimate,
33
40
  measured: () => this.measured,
34
- rows: () => this.drawn(),
41
+ rows: () => this.lines(),
35
42
  });
36
43
  this.handleKeydown = (event) => {
37
- if (event.defaultPrevented ||
38
- event.altKey ||
39
- event.ctrlKey ||
40
- event.metaKey ||
41
- event.shiftKey) {
44
+ if (event.defaultPrevented) {
42
45
  return;
43
46
  }
44
47
  const at = this.indexOf(event.target);
45
48
  if (at === undefined) {
46
49
  return;
47
50
  }
51
+ if (typesCharacter(event) && (event.key !== ' ' || this.typeahead.typing())) {
52
+ const found = this.typeahead.match(event.key, this.texts(), at);
53
+ event.preventDefault();
54
+ if (found >= 0 && found !== at) {
55
+ void this.focusIndex(found);
56
+ }
57
+ return;
58
+ }
59
+ const toggle = event.ctrlKey || event.metaKey;
60
+ if (this.selectionMode && !event.altKey) {
61
+ if (selectsAll(event) && this.selectionMode === 'multiple') {
62
+ event.preventDefault();
63
+ this.choose(this.keys().join(','));
64
+ return;
65
+ }
66
+ if (event.key === ' ' && !toggle) {
67
+ event.preventDefault();
68
+ this.press(at, event.shiftKey);
69
+ return;
70
+ }
71
+ }
72
+ const extend = event.shiftKey && this.selectionMode === 'multiple';
73
+ if (event.altKey || toggle || (event.shiftKey && !extend)) {
74
+ return;
75
+ }
48
76
  const { first, last } = this.virtualize.visible();
49
- const next = stepIndex(event.key, at, this.data.length, last - first - 1);
77
+ const next = stepIndex(event.key, at, this.data.length, last - first - 1, {
78
+ across: this.across,
79
+ forward: isRtl(this) ? 'ArrowLeft' : 'ArrowRight',
80
+ });
50
81
  if (next === undefined) {
51
82
  return;
52
83
  }
53
84
  event.preventDefault();
54
85
  void this.focusIndex(next);
86
+ if (extend) {
87
+ this.anchor ??= this.keyAt(at);
88
+ this.press(next, true);
89
+ }
90
+ };
91
+ this.handleClick = (event) => {
92
+ if (!this.selectionMode) {
93
+ return;
94
+ }
95
+ const path = event.composedPath();
96
+ const row = path.find((node) => node instanceof HTMLElement && node.parentElement === this);
97
+ const at = this.indexOf(row ?? null);
98
+ if (at === undefined) {
99
+ return;
100
+ }
101
+ const inner = path.slice(0, path.indexOf(row));
102
+ if (inner.some((node) => node instanceof HTMLElement &&
103
+ node.matches('a[href], button, input, select, textarea, label'))) {
104
+ return;
105
+ }
106
+ this.press(at, event.shiftKey && this.selectionMode === 'multiple');
55
107
  };
56
108
  this.handleFocusOut = () => {
57
109
  this.requestUpdate();
@@ -69,14 +121,21 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
69
121
  };
70
122
  }
71
123
  get range() {
72
- return this.virtualize.visible();
124
+ return this.itemsOn(this.virtualize.visible());
125
+ }
126
+ get across() {
127
+ return Math.max(1, Math.trunc(this.columns) || 1);
128
+ }
129
+ itemsOn(lines) {
130
+ return itemsOf(lines, this.across, this.data.length);
73
131
  }
74
132
  scrollToIndex(index, options = {}) {
75
133
  const count = this.data.length;
76
134
  if (count === 0 || !Number.isFinite(index)) {
77
135
  return;
78
136
  }
79
- this.virtualize.reveal(Math.max(0, Math.min(Math.trunc(index), count - 1)), 0, options);
137
+ const at = Math.max(0, Math.min(Math.trunc(index), count - 1));
138
+ this.virtualize.reveal(Math.floor(at / this.across), 0, options);
80
139
  this.virtualize.measure();
81
140
  }
82
141
  get data() {
@@ -88,6 +147,15 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
88
147
  index: Number(element.dataset.index),
89
148
  }));
90
149
  }
150
+ lines() {
151
+ const across = this.across;
152
+ const drawn = this.drawn();
153
+ return across === 1
154
+ ? drawn
155
+ : drawn
156
+ .filter(({ index }) => index % across === 0)
157
+ .map(({ element, index }) => ({ element, index: index / across }));
158
+ }
91
159
  willUpdate(changed) {
92
160
  super.willUpdate(changed);
93
161
  if (this.readFor !== this.for && searchableById(this) && !this.hydrating) {
@@ -98,6 +166,7 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
98
166
  connectedCallback() {
99
167
  super.connectedCallback();
100
168
  this.addEventListener('keydown', this.handleKeydown);
169
+ this.addEventListener('click', this.handleClick);
101
170
  this.addEventListener('focusin', this.handleFocusIn);
102
171
  this.addEventListener('focusout', this.handleFocusOut);
103
172
  if (typeof MutationObserver === 'undefined') {
@@ -113,6 +182,7 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
113
182
  disconnectedCallback() {
114
183
  super.disconnectedCallback();
115
184
  this.removeEventListener('keydown', this.handleKeydown);
185
+ this.removeEventListener('click', this.handleClick);
116
186
  this.removeEventListener('focusin', this.handleFocusIn);
117
187
  this.removeEventListener('focusout', this.handleFocusOut);
118
188
  this.watcher?.disconnect();
@@ -155,22 +225,23 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
155
225
  }
156
226
  }
157
227
  report() {
158
- const { first, last } = this.virtualize.visible();
228
+ const { first, last } = this.range;
159
229
  if (first !== this.said.first || last !== this.said.last) {
160
230
  this.said = { first, last };
161
231
  this.dispatchEvent(new HelixRangeChangeEvent({ first, last }));
162
232
  }
163
- const box = this.partNamed('viewport');
164
- const count = this.data.length;
165
- const screen = box?.clientHeight ?? 0;
166
- if (count > 0 &&
167
- screen > 0 &&
168
- this.askedAt !== count &&
169
- this.virtualize.remaining() <= screen) {
170
- this.askedAt = count;
233
+ if (!this.loading && this.virtualize.endInSight()) {
171
234
  this.dispatchEvent(new HelixLoadMoreEvent());
172
235
  }
173
236
  }
237
+ texts() {
238
+ const field = this.textField ||
239
+ this.querySelector(':scope > template')
240
+ ?.content.querySelector('[data-field]')
241
+ ?.getAttribute('data-field') ||
242
+ '';
243
+ return textsOf(this.data, field);
244
+ }
174
245
  indexOf(node) {
175
246
  if (!(node instanceof HTMLElement) || node.parentElement !== this) {
176
247
  return undefined;
@@ -181,10 +252,62 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
181
252
  rowFor(index) {
182
253
  return this.querySelector(`:scope > [data-index="${index}"]`);
183
254
  }
255
+ keyAt(at) {
256
+ return keyOf(this.data[at], at, this.keyField);
257
+ }
258
+ keys() {
259
+ return this.data.map((_, at) => this.keyAt(at));
260
+ }
261
+ get chosen() {
262
+ return new Set(commaList(this.value));
263
+ }
264
+ press(at, extend = false) {
265
+ const mode = this.selectionMode;
266
+ const key = this.keyAt(at);
267
+ if (!mode || at < 0 || at >= this.data.length) {
268
+ return;
269
+ }
270
+ const now = commaList(this.value);
271
+ if (extend && mode === 'multiple') {
272
+ const keys = this.keys();
273
+ const from = this.anchor === undefined ? -1 : keys.indexOf(this.anchor);
274
+ const range = rangeAdd(now, keys, from, at);
275
+ if (range) {
276
+ this.choose(this.inOrder(range));
277
+ }
278
+ return;
279
+ }
280
+ this.anchor = key;
281
+ if (mode === 'single') {
282
+ this.choose(now.length === 1 && now[0] === key ? '' : key);
283
+ return;
284
+ }
285
+ this.choose(this.inOrder(toggleValue(now, key)));
286
+ }
287
+ inOrder(keys) {
288
+ const wanted = new Set(keys);
289
+ const ordered = this.keys().filter((key) => wanted.has(key));
290
+ const placed = new Set(ordered);
291
+ return [...ordered, ...keys.filter((key) => !placed.has(key))].join(',');
292
+ }
293
+ choose(next) {
294
+ if (next === this.value) {
295
+ return;
296
+ }
297
+ requestChange({
298
+ apply: (value) => {
299
+ this.value = value;
300
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
301
+ },
302
+ event: (value) => new HelixBeforeChangeEvent({ value }),
303
+ host: this,
304
+ next,
305
+ });
306
+ }
184
307
  async focusIndex(index) {
185
308
  this.active = index;
186
309
  this.focusing = index;
187
- this.virtualize.reveal(index);
310
+ this.virtualize.reveal(Math.floor(index / this.across));
188
311
  this.virtualize.measure();
189
312
  this.requestUpdate();
190
313
  try {
@@ -206,13 +329,21 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
206
329
  }
207
330
  keptIndex() {
208
331
  const index = this.focusing ?? this.focusedIndex();
209
- const { first, last } = this.virtualize.window;
332
+ const { first, last } = this.itemsOn(this.virtualize.window);
210
333
  return index !== undefined && index < this.data.length && (index < first || index >= last)
211
334
  ? index
212
335
  : undefined;
213
336
  }
337
+ mark(element, at, chosen) {
338
+ element.setAttribute('role', this.selectionMode ? 'option' : 'listitem');
339
+ if (this.selectionMode) {
340
+ element.setAttribute('aria-selected', String(chosen.has(this.keyAt(at))));
341
+ }
342
+ else {
343
+ element.removeAttribute('aria-selected');
344
+ }
345
+ }
214
346
  stamp(element, at) {
215
- element.setAttribute('role', 'listitem');
216
347
  element.setAttribute('aria-posinset', String(at + 1));
217
348
  element.setAttribute('aria-setsize', String(this.data.length));
218
349
  element.setAttribute('data-index', String(at));
@@ -246,25 +377,21 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
246
377
  return;
247
378
  }
248
379
  const count = this.data.length;
249
- const { first, last } = this.virtualize.window;
250
- const kept = this.keptIndex();
251
- const wanted = [];
252
- for (let at = first; at < Math.min(last, count); at += 1) {
253
- wanted.push(at);
254
- }
255
- if (kept !== undefined) {
256
- wanted.push(kept);
257
- wanted.sort((a, b) => a - b);
258
- }
259
- const keep = new Set(wanted);
260
- const redraw = (this.filledBy === undefined) !== (this.renderItem === undefined);
380
+ const { first, last } = this.itemsOn(this.virtualize.window);
381
+ const children = [...this.children].filter((child) => child !== template && child instanceof HTMLElement && !child.hasAttribute('slot'));
382
+ const plan = drawPlan({
383
+ across: this.across,
384
+ count,
385
+ drawn: children.map((child) => Number(child.dataset.index)),
386
+ first,
387
+ kept: this.keptIndex(),
388
+ last,
389
+ redraw: (this.filledBy === undefined) !== (this.renderItem === undefined),
390
+ });
261
391
  const drawn = new Map();
262
- for (const child of [...this.children]) {
263
- if (child === template) {
264
- continue;
265
- }
392
+ for (const child of children) {
266
393
  const index = Number(child.dataset.index);
267
- if (redraw || !Number.isInteger(index) || !keep.has(index)) {
394
+ if (plan.remove.has(index)) {
268
395
  child.remove();
269
396
  continue;
270
397
  }
@@ -275,7 +402,7 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
275
402
  this.filledBy = this.renderItem;
276
403
  const fresh = new Set();
277
404
  let anchor = drawn.values().next().value?.[0] ?? null;
278
- for (const at of wanted) {
405
+ for (const at of plan.wanted) {
279
406
  const group = drawn.get(at);
280
407
  if (group) {
281
408
  if (refill) {
@@ -290,11 +417,17 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
290
417
  fresh.add(at);
291
418
  this.insertBefore(fragment, anchor);
292
419
  }
293
- if (!keep.has(this.active)) {
294
- const onScreen = this.virtualize.visible().first;
295
- this.active = Math.max(Math.min(onScreen, Math.min(last, count) - 1), first, 0);
296
- }
420
+ this.active = stopAfter(this.active, plan.wanted, {
421
+ count,
422
+ first,
423
+ last,
424
+ onScreen: this.range.first,
425
+ });
426
+ const chosen = this.chosen;
297
427
  for (const [at, group] of drawn) {
428
+ for (const element of group) {
429
+ this.mark(element, at, chosen);
430
+ }
298
431
  const stop = at === this.active;
299
432
  group[0]?.setAttribute('tabindex', stop ? '0' : '-1');
300
433
  if (stop && (fresh.has(at) || this.released !== at)) {
@@ -307,11 +440,15 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
307
440
  this.released = this.active;
308
441
  }
309
442
  render() {
310
- const { after, before } = this.virtualize.spacers(this.hasUpdated ? this.keptIndex() : undefined);
443
+ const kept = this.hasUpdated ? this.keptIndex() : undefined;
444
+ const { after, before } = this.virtualize.spacers(kept === undefined ? undefined : Math.floor(kept / this.across));
445
+ const across = this.across;
311
446
  return html `<div
312
447
  data-scroller
313
448
  part="viewport"
314
- role="list"
449
+ role=${this.selectionMode ? 'listbox' : 'list'}
450
+ aria-multiselectable=${this.selectionMode === 'multiple' ? 'true' : nothing}
451
+ aria-busy=${this.loading ? 'true' : nothing}
315
452
  aria-label=${this.label}
316
453
  @scroll=${() => {
317
454
  this.virtualize.measure();
@@ -319,11 +456,23 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
319
456
  }}
320
457
  >
321
458
  <div part="before" style="block-size: ${before}px"></div>
322
- <slot></slot>
459
+ <slot
460
+ style=${across === 1
461
+ ? nothing
462
+ : `display: grid; grid-template-columns: repeat(${across}, minmax(0, 1fr))`}
463
+ ></slot>
323
464
  <div part="after" style="block-size: ${after}px"></div>
465
+ ${this.loading
466
+ ? html `<div part="loading" role=${this.selectionMode ? 'option' : 'listitem'}>
467
+ <slot name="loading">${this.loadingLabel}</slot>
468
+ </div>`
469
+ : nothing}
324
470
  </div>`;
325
471
  }
326
472
  };
473
+ __decorate([
474
+ property({ type: Number })
475
+ ], HelixHeadlessVirtualList.prototype, "columns", void 0);
327
476
  __decorate([
328
477
  property({ type: Number })
329
478
  ], HelixHeadlessVirtualList.prototype, "estimate", void 0);
@@ -333,15 +482,33 @@ __decorate([
333
482
  __decorate([
334
483
  property({ attribute: false })
335
484
  ], HelixHeadlessVirtualList.prototype, "items", void 0);
485
+ __decorate([
486
+ property({ attribute: 'key-field' })
487
+ ], HelixHeadlessVirtualList.prototype, "keyField", void 0);
336
488
  __decorate([
337
489
  property()
338
490
  ], HelixHeadlessVirtualList.prototype, "label", void 0);
491
+ __decorate([
492
+ property({ type: Boolean })
493
+ ], HelixHeadlessVirtualList.prototype, "loading", void 0);
494
+ __decorate([
495
+ property({ attribute: 'loading-label' })
496
+ ], HelixHeadlessVirtualList.prototype, "loadingLabel", void 0);
339
497
  __decorate([
340
498
  property({ type: Boolean })
341
499
  ], HelixHeadlessVirtualList.prototype, "measured", void 0);
342
500
  __decorate([
343
501
  property({ attribute: false })
344
502
  ], HelixHeadlessVirtualList.prototype, "renderItem", void 0);
503
+ __decorate([
504
+ property({ attribute: 'selection-mode' })
505
+ ], HelixHeadlessVirtualList.prototype, "selectionMode", void 0);
506
+ __decorate([
507
+ property({ attribute: 'text-field' })
508
+ ], HelixHeadlessVirtualList.prototype, "textField", void 0);
509
+ __decorate([
510
+ property()
511
+ ], HelixHeadlessVirtualList.prototype, "value", void 0);
345
512
  __decorate([
346
513
  state()
347
514
  ], HelixHeadlessVirtualList.prototype, "rows", void 0);