@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
@@ -24,6 +24,18 @@ declare const HelixHeadlessTree_base: (new (...args: any[]) => import("@fusion.d
24
24
  * checked values, comma separated, which `values` also gives as a list, and
25
25
  * the tree says `aria-multiselectable`.
26
26
  *
27
+ * `selection-mode="leaf"` chooses one item at a time and only the items at the
28
+ * ends: a press, Enter or Space on a branch opens or closes it and chooses
29
+ * nothing, as Web Awesome's `leaf` mode does.
30
+ *
31
+ * Keys: Up and Down Arrow move between the items a reader can see; Right
32
+ * Arrow opens a shut branch and then moves into it, and Left Arrow shuts an
33
+ * open one and then moves to its parent, the two swapping on a right-to-left
34
+ * page. Home and End go to the first and the last item, Enter and Space choose
35
+ * or open, and the tree's one tab stop stays on the item last reached. In a
36
+ * tree of check marks, Control+A (Command+A on an Apple keyboard) checks every
37
+ * item or clears them all, and Shift with Up or Down Arrow moves and checks.
38
+ *
27
39
  * @since 0.1.0
28
40
  * @status stable
29
41
  * @category navigation
@@ -91,12 +103,12 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
91
103
  */
92
104
  nesting?: 'heading' | 'peer' | 'subordinate';
93
105
  /**
94
- * Whether a reader can check many items. Unset, one item is chosen at a
95
- * time.
106
+ * Whether a reader can check many items, or choose only the items at the
107
+ * ends. Unset, one item is chosen at a time, branches included.
96
108
  *
97
109
  * Optional, so a tree of one choice writes no attribute onto the host.
98
110
  */
99
- selectionMode?: 'multiple';
111
+ selectionMode?: 'leaf' | 'multiple';
100
112
  /**
101
113
  * The checked values, as a list, under `selection-mode="multiple"`, and the
102
114
  * chosen value alone otherwise. Writing it sets `active`.
@@ -154,6 +166,15 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
154
166
  * Returns whether the press was one of those.
155
167
  */
156
168
  private handleTyping;
169
+ /**
170
+ * The keys of a tree of check marks, as the tree pattern gives them:
171
+ * Control+A (Command+A on an Apple keyboard) checks every item, or clears
172
+ * them all where every one is checked, and Shift with Up or Down Arrow moves
173
+ * to the item before or after and checks or unchecks it.
174
+ *
175
+ * Returns whether the press was one of those.
176
+ */
177
+ private handleMultiple;
157
178
  private move;
158
179
  private focusOn;
159
180
  private readonly handleKeydown;
@@ -4,7 +4,7 @@ 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, closestInstance, commaList, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, slottedWords, Typeahead, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, closestInstance, commaList, customElement, HelixElement, inlineStep, keyClaimed, MixinCollection, MixinControllerActive, scrollItemIntoView, selectsAll, slottedWords, Typeahead, treeArrow, typesCharacter, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessTreeItem } from '../item/tree-item.js';
@@ -45,6 +45,10 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
45
45
  if (!current || !this.items.includes(current)) {
46
46
  return;
47
47
  }
48
+ if (this.multiple && this.handleMultiple(current, event)) {
49
+ event.preventDefault();
50
+ return;
51
+ }
48
52
  if (this.handleTyping(current, event)) {
49
53
  event.preventDefault();
50
54
  return;
@@ -71,21 +75,16 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
71
75
  else if (event.key === 'End') {
72
76
  this.focusOn(this.visibleItems.at(-1));
73
77
  }
74
- else if (along === 1) {
75
- if (current.isBranch && !current.open && !current.disabled) {
76
- current.requestOpen(true);
78
+ else if (along !== 0) {
79
+ const arrow = treeArrow({ branch: current.isBranch, disabled: current.disabled, open: current.open }, along);
80
+ if (arrow === 'open' || arrow === 'close') {
81
+ current.requestOpen(arrow === 'open');
77
82
  this.syncItems();
78
83
  }
79
- else if (current.isBranch) {
84
+ else if (arrow === 'child') {
80
85
  this.move(current, 1);
81
86
  }
82
- }
83
- else if (along === -1) {
84
- if (current.isBranch && current.open && !current.disabled) {
85
- current.requestOpen(false);
86
- this.syncItems();
87
- }
88
- else {
87
+ else if (arrow === 'parent') {
89
88
  const parent = closestInstance(current.parentElement, HelixHeadlessTreeItem);
90
89
  this.focusOn(parent instanceof HelixHeadlessTreeItem ? parent : undefined);
91
90
  }
@@ -157,7 +156,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
157
156
  const held = visible.find((item) => item.focusable) ??
158
157
  this.visibleAncestor(this.items.find((item) => item.focusable));
159
158
  const stop = held ?? chosen;
160
- const heads = this.nesting === 'heading';
159
+ const heads = this.nesting === 'heading' || this.selectionMode === 'leaf';
161
160
  const multiple = this.multiple;
162
161
  const checked = new Set(this.values);
163
162
  for (const item of this.items) {
@@ -217,6 +216,26 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
217
216
  }
218
217
  return true;
219
218
  }
219
+ handleMultiple(current, event) {
220
+ if (selectsAll(event)) {
221
+ const leaves = this.items
222
+ .filter((item) => !this.holds(item) && !item.disabled && item.value !== '')
223
+ .map((item) => item.value);
224
+ this.requestActive(pressRow({ branch: true, disabled: false, leaves, value: '' }, this.values, this.order).join(','));
225
+ this.syncItems();
226
+ return true;
227
+ }
228
+ if (event.shiftKey && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
229
+ const visible = this.visibleItems;
230
+ const next = visible[visible.indexOf(current) + (event.key === 'ArrowDown' ? 1 : -1)];
231
+ if (next) {
232
+ this.focusOn(next);
233
+ next.select();
234
+ }
235
+ return true;
236
+ }
237
+ return false;
238
+ }
220
239
  move(from, delta) {
221
240
  const visible = this.visibleItems;
222
241
  const index = visible.indexOf(from);
@@ -1,3 +1,4 @@
1
+ import { toggleEvery } from '@fusion.dev/helix-core';
1
2
  const valuesOf = (row) => row.branch && row.leaves.length > 0 ? [...row.leaves] : row.value === '' ? [] : [row.value];
2
3
  export const checkedState = (row, chosen) => {
3
4
  const values = valuesOf(row);
@@ -8,19 +9,5 @@ export const checkedState = (row, chosen) => {
8
9
  return count === values.length ? true : 'mixed';
9
10
  };
10
11
  export const pressRow = (row, chosen, order) => {
11
- if (row.disabled) {
12
- return [...chosen];
13
- }
14
- const values = valuesOf(row);
15
- const all = values.every((value) => chosen.includes(value));
16
- const next = new Set(chosen);
17
- for (const value of values) {
18
- if (all) {
19
- next.delete(value);
20
- }
21
- else {
22
- next.add(value);
23
- }
24
- }
25
- return order.filter((value) => next.has(value));
12
+ return row.disabled ? [...chosen] : toggleEvery(chosen, valuesOf(row), order);
26
13
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The movement a signed change makes: `up` above zero, `down` below it and
3
+ * `neutral` at zero. Nothing for a value that is no number, so a trend with
4
+ * none falls back to what its attributes say.
5
+ */
6
+ export declare const movementOf: (value: number | undefined) => 'down' | 'neutral' | 'up' | undefined;
7
+ /**
8
+ * A change written in a locale with `Intl.NumberFormat` options, such as
9
+ * `12%` for 0.12 with `{ style: 'percent' }`.
10
+ *
11
+ * **The size of the change, with no sign**, because the movement is already
12
+ * said by the arrow and the word: "Down, worse 8%" rather than "Down, worse
13
+ * -8%". Options that set `signDisplay` ask for the sign, and get the value as
14
+ * it is.
15
+ */
16
+ export declare const figureOf: (value: number, locale?: string, options?: Intl.NumberFormatOptions) => string;
@@ -0,0 +1,8 @@
1
+ import { formatNumber } from '@fusion.dev/helix-core';
2
+ export const movementOf = (value) => {
3
+ if (value === undefined || !Number.isFinite(value)) {
4
+ return undefined;
5
+ }
6
+ return value > 0 ? 'up' : value < 0 ? 'down' : 'neutral';
7
+ };
8
+ export const figureOf = (value, locale = '', options) => formatNumber(options?.signDisplay === undefined ? Math.abs(value) : value, locale, options);
@@ -1,23 +1,36 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * @summary An indicator that shows which way a measurement moved, and whether the change is good.
5
5
  *
6
6
  * @description
7
- * A trend has three parts: a direction of up, down, or neutral, the metric that
8
- * moved, and a label for the period it moved over. The arrow shows the
9
- * direction and its color shows whether the change is good. Direction and
7
+ * A trend has three parts: a `movement` of up, down, or neutral, the metric
8
+ * that moved, and a label for the period it moved over. The arrow shows the
9
+ * movement and its color shows whether the change is good. Movement and
10
10
  * judgment are separate properties because they are separate facts.
11
11
  *
12
12
  * `good` is unset by default, so a trend with no judgment is gray. For churn,
13
13
  * latency, error rate, cost, and bounce rate, up is bad. Set the metric's
14
14
  * polarity once with `good`, and the component picks the color from the
15
- * direction.
15
+ * movement. The judgment is also a custom state, `better` or `worse`, for a
16
+ * sheet of your own.
16
17
  *
17
- * The direction is also written as a word, so a screen reader reads it. The
18
+ * The movement is also written as a word, so a screen reader reads it. The
18
19
  * styled tier hides `part="direction"` visually and keeps it in the
19
20
  * accessibility tree. The words are properties, `up-label` through
20
- * `worse-label`, so a page in another language can set its own.
21
+ * `worse-label`, so a page in another language can set its own. The arrow and
22
+ * any glyph slotted in its place are hidden from screen readers.
23
+ *
24
+ * **Or give the change as a number.** `value` is the signed change, such as
25
+ * `0.12` or `-8`: its sign is the movement, and its size is written as the
26
+ * metric with `Intl.NumberFormat`, in `locale` and with `format-options`,
27
+ * such as `{"style":"percent"}` for `12%`. `movement` still wins when it is
28
+ * written. Without `value` the metric is what the page slots.
29
+ *
30
+ * Slot one glyph per movement into `up-icon`, `down-icon` and `neutral-icon`,
31
+ * and the trend shows the one that matches; a glyph in `icon` stands in for
32
+ * all three. Inside a `Stat`, put the trend in the stat's `trend` slot so it is
33
+ * read with the figure it qualifies.
21
34
  *
22
35
  * The metric and the label are bare slots. An element that assigned its own
23
36
  * slot on connect would add an attribute to its host after upgrade, which the
@@ -29,12 +42,19 @@ import { type TemplateResult } from 'lit';
29
42
  * @aliases Delta, Change, Movement
30
43
  * @documentation https://fusion.dev/helix/components/trend
31
44
  *
32
- * @slot - The metric that moved.
33
- * @slot icon - Replaces the arrow, such as with a glyph of your own set. Slot the one for the current direction.
45
+ * @slot - The metric that moved. Not needed with `value`, which writes it.
46
+ * @slot down-icon - Replaces the arrow while `movement` is `down`. Hidden from screen readers.
47
+ * @slot icon - Replaces the arrow for every movement, such as with a glyph of your own set. Hidden from screen readers, since the movement is also a word.
34
48
  * @slot label - The period the metric moved over.
49
+ * @slot neutral-icon - Replaces the bar while the trend has not moved. Hidden from screen readers.
50
+ * @slot up-icon - Replaces the arrow while `movement` is `up`. Hidden from screen readers.
35
51
  *
36
- * @csspart direction - The direction as a word, for people who cannot see the arrow.
52
+ * @csspart direction - The movement as a word, for people who cannot see the arrow.
37
53
  * @csspart icon - The arrow.
54
+ * @csspart value - The change written from `value`, hidden while `value` is no number.
55
+ *
56
+ * @cssstate better - The trend moved the way `good` names.
57
+ * @cssstate worse - The trend moved against the way `good` names.
38
58
  */
39
59
  export declare class HelixHeadlessTrend extends HelixElement {
40
60
  /**
@@ -42,14 +62,11 @@ export declare class HelixHeadlessTrend extends HelixElement {
42
62
  */
43
63
  betterLabel: string;
44
64
  /**
45
- * Which way the measurement moved.
65
+ * Which way the measurement moved, as `movement` says it.
46
66
  *
47
- * Absent is neutral, so a trend with nothing to report draws a bar rather
48
- * than picking a direction. Optional rather than defaulted for the reason
49
- * `Stat.direction` is: a reflecting property with a default writes its
50
- * attribute onto the host the moment the element upgrades, and the host is
51
- * markup the consumer rendered, which React compares against what it rendered
52
- * and reports as a hydration mismatch.
67
+ * @deprecated Use `movement`. `direction` is a layout on `Stat` and `Flex`,
68
+ * which are written beside a trend, so one word meant two things. Still read
69
+ * when `movement` is absent.
53
70
  */
54
71
  direction?: 'down' | 'neutral' | 'up';
55
72
  /**
@@ -57,14 +74,45 @@ export declare class HelixHeadlessTrend extends HelixElement {
57
74
  */
58
75
  downLabel: string;
59
76
  /**
60
- * Which direction counts as an improvement for this metric.
77
+ * `Intl.NumberFormat` options `value` is written with, as React Aria's
78
+ * NumberField takes them: a percent, a currency, a unit or a number of
79
+ * decimals. Written as JSON in the attribute.
80
+ *
81
+ * ```html
82
+ * <helix-trend value="-0.084" format-options='{"style":"percent","maximumFractionDigits":1}'></helix-trend>
83
+ * ```
84
+ *
85
+ * The example says "Down 8.4%". The size is written without a sign, since
86
+ * the arrow and the word say which way; set `signDisplay` for one. Absent
87
+ * writes the number as the locale writes any number.
88
+ */
89
+ formatOptions?: Intl.NumberFormatOptions;
90
+ /**
91
+ * Which movement counts as an improvement for this metric.
61
92
  *
62
93
  * Absent states the movement without judging it, which is the honest default:
63
94
  * revenue up is good news and latency up is bad news, and only the consumer
64
95
  * knows which one this is. Set it once per metric and it holds while the
65
- * direction changes underneath.
96
+ * movement changes underneath.
66
97
  */
67
98
  good?: 'down' | 'up';
99
+ /**
100
+ * The locale `value` is written in, such as `de` for `1.234,5`.
101
+ *
102
+ * Absent uses the runtime's own. Set it on a page rendered on a server, so
103
+ * the server and the browser write the figure alike.
104
+ */
105
+ locale: string;
106
+ /**
107
+ * Which way the measurement moved.
108
+ *
109
+ * Absent is neutral, so a trend with nothing to report draws a bar rather
110
+ * than picking a direction. Optional rather than defaulted: a reflecting
111
+ * property with a default writes its attribute onto the host the moment the
112
+ * element upgrades, and the host is markup the consumer rendered, which React
113
+ * compares against what it rendered and reports as a hydration mismatch.
114
+ */
115
+ movement?: 'down' | 'neutral' | 'up';
68
116
  /**
69
117
  * The word read out for no move, or for a direction that is not one of the
70
118
  * three.
@@ -74,6 +122,16 @@ export declare class HelixHeadlessTrend extends HelixElement {
74
122
  * The word read out for a move up.
75
123
  */
76
124
  upLabel: string;
125
+ /**
126
+ * The change as a signed number, such as `0.12` or `-8`, which sets the
127
+ * movement by its sign and is written as the metric.
128
+ *
129
+ * Above zero is up, below is down, and zero is neutral; `movement` wins when
130
+ * both are written. The size is written in the `value` part with
131
+ * `format-options` and `locale`, in place of a slotted metric. Absent leaves
132
+ * the movement to `movement` and the metric to the slot.
133
+ */
134
+ value?: number;
77
135
  /**
78
136
  * The word read out after the direction when the move is a setback.
79
137
  */
@@ -90,6 +148,12 @@ export declare class HelixHeadlessTrend extends HelixElement {
90
148
  content: string;
91
149
  viewBox: string;
92
150
  }): TemplateResult;
151
+ /** The movement, read from `movement`, then from the old `direction`, then from the sign of `value`. */
152
+ private get moved();
153
+ /** Better or worse, or neither when `good` is unset or nothing moved. */
154
+ private get judged();
155
+ protected updated(changed: PropertyValues): void;
156
+ protected willUpdate(changed: PropertyValues): void;
93
157
  protected render(): TemplateResult;
94
158
  }
95
159
  declare global {
@@ -4,11 +4,12 @@ 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 { customElement, HelixElement } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, reportRuntime } from '@fusion.dev/helix-core';
8
8
  import { arrowDown, arrowUp, minus } from '@fusion.dev/helix-icons';
9
9
  import { html } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
+ import { figureOf, movementOf } from '../figure.js';
12
13
  const DIRECTIONS = {
13
14
  down: { icon: arrowDown, word: 'downLabel' },
14
15
  neutral: { icon: minus, word: 'unchangedLabel' },
@@ -20,12 +21,13 @@ let HelixHeadlessTrend = class HelixHeadlessTrend extends HelixElement {
20
21
  super(...arguments);
21
22
  this.betterLabel = 'better';
22
23
  this.downLabel = 'Down';
24
+ this.locale = '';
23
25
  this.unchangedLabel = 'Unchanged';
24
26
  this.upLabel = 'Up';
25
27
  this.worseLabel = 'worse';
26
28
  }
27
29
  renderIcon(icon) {
28
- return html `<slot name="icon"
30
+ return html `<slot aria-hidden="true" name="icon"
29
31
  ><svg
30
32
  aria-hidden="true"
31
33
  data-glyph
@@ -37,14 +39,51 @@ let HelixHeadlessTrend = class HelixHeadlessTrend extends HelixElement {
37
39
  </svg></slot
38
40
  >`;
39
41
  }
42
+ get moved() {
43
+ return this.movement ?? this.direction ?? movementOf(this.value);
44
+ }
45
+ get judged() {
46
+ const moved = this.moved;
47
+ if (!this.good || !moved || !(moved in DIRECTIONS) || moved === 'neutral') {
48
+ return undefined;
49
+ }
50
+ return this.good === moved ? 'better' : 'worse';
51
+ }
52
+ updated(changed) {
53
+ super.updated(changed);
54
+ if (changed.has('direction') && this.direction && changed.get('direction') === undefined) {
55
+ reportRuntime({
56
+ kind: 'deprecated',
57
+ message: `<${this.localName} direction="${this.direction}"> is deprecated: write ` +
58
+ `movement="${this.direction}", which says the same. \`direction\` is a layout on Stat and Flex.`,
59
+ tag: this.localName,
60
+ });
61
+ }
62
+ }
63
+ willUpdate(changed) {
64
+ super.willUpdate(changed);
65
+ const judged = this.judged;
66
+ this.toggleState('better', judged === 'better');
67
+ this.toggleState('worse', judged === 'worse');
68
+ }
40
69
  render() {
41
- const direction = readDirection(this.direction);
42
- const judgment = this.good && this.direction && this.direction !== 'neutral'
43
- ? `, ${this.good === this.direction ? this.betterLabel : this.worseLabel}`
44
- : '';
45
- return html `${this.renderIcon(direction.icon)}
70
+ const moved = this.moved;
71
+ const direction = readDirection(moved);
72
+ const judged = this.judged;
73
+ const judgment = judged ? `, ${judged === 'better' ? this.betterLabel : this.worseLabel}` : '';
74
+ const icon = this.renderIcon(direction.icon);
75
+ const glyph = moved === 'up'
76
+ ? html `<slot aria-hidden="true" name="up-icon">${icon}</slot>`
77
+ : moved === 'down'
78
+ ? html `<slot aria-hidden="true" name="down-icon">${icon}</slot>`
79
+ : html `<slot aria-hidden="true" name="neutral-icon">${icon}</slot>`;
80
+ const value = this.value;
81
+ const figure = value === undefined || !Number.isFinite(value)
82
+ ? ''
83
+ : figureOf(value, this.locale, this.formatOptions);
84
+ return html `${glyph}
46
85
  <span part="direction">${`${this[direction.word]}${judgment}`}</span>
47
- <slot></slot>
86
+ <span part="value" ?hidden=${figure === ''}>${figure}</span><slot></slot>
48
87
  <slot name="label"></slot>`;
49
88
  }
50
89
  };
@@ -57,15 +96,27 @@ __decorate([
57
96
  __decorate([
58
97
  property({ attribute: 'down-label' })
59
98
  ], HelixHeadlessTrend.prototype, "downLabel", void 0);
99
+ __decorate([
100
+ property({ attribute: 'format-options', type: Object })
101
+ ], HelixHeadlessTrend.prototype, "formatOptions", void 0);
60
102
  __decorate([
61
103
  property({ reflect: true })
62
104
  ], HelixHeadlessTrend.prototype, "good", void 0);
105
+ __decorate([
106
+ property()
107
+ ], HelixHeadlessTrend.prototype, "locale", void 0);
108
+ __decorate([
109
+ property({ reflect: true })
110
+ ], HelixHeadlessTrend.prototype, "movement", void 0);
63
111
  __decorate([
64
112
  property({ attribute: 'unchanged-label' })
65
113
  ], HelixHeadlessTrend.prototype, "unchangedLabel", void 0);
66
114
  __decorate([
67
115
  property({ attribute: 'up-label' })
68
116
  ], HelixHeadlessTrend.prototype, "upLabel", void 0);
117
+ __decorate([
118
+ property({ type: Number })
119
+ ], HelixHeadlessTrend.prototype, "value", void 0);
69
120
  __decorate([
70
121
  property({ attribute: 'worse-label' })
71
122
  ], HelixHeadlessTrend.prototype, "worseLabel", void 0);
@@ -22,28 +22,23 @@ export declare const MEDIA_EVENTS: readonly ['abort', 'canplay', 'canplaythrough
22
22
  /** One of the media events the player relays. */
23
23
  export type MediaEventName = (typeof MEDIA_EVENTS)[number];
24
24
  /**
25
- * The copy the host sends: the same name, neither bubbling nor composed.
25
+ * Hands each media event the video fires to `relay`, and returns what stops
26
+ * it. The player relays through `relayNativeEvent`, which sends the same name
27
+ * with the same `bubbles`, `cancelable` and `composed`.
26
28
  *
27
- * **As the platform sends it, which is what makes it reach a React consumer at
28
- * all.** These names are in react-dom's `nonDelegatedEvents`, which React wires
29
- * on a `<video>` and never on a custom element, so its root listener hears none
30
- * of them. `bindReactHandler` closes that for an event that does not bubble,
31
- * and skips one that does, on the grounds that a bubbling relay already reaches
32
- * React's delegated listener and binding it again would double every call. A
33
- * copy sent with `bubbles: true` lands in the branch that refuses to bind, and
34
- * `onPlay` on the player is silent.
35
- *
36
- * Not cancelable, as the platform's are not: the media has already moved by the
37
- * time the event is sent, and a refusal would have nothing to stop.
38
- */
39
- export declare const relayedCopy: (event: Event) => Event;
40
- /**
41
- * Sends each media event the video fires on from the host, and returns what
42
- * stops it.
29
+ * **As the platform sends it, neither bubbling nor composed, which is what
30
+ * makes it reach a React consumer at all.** These names are in react-dom's
31
+ * `nonDelegatedEvents`, which React wires on a `<video>` and never on a custom
32
+ * element, so its root listener hears none of them. `bindReactHandler` closes
33
+ * that for an event that does not bubble, and skips one that does, on the
34
+ * grounds that a bubbling relay already reaches React's delegated listener and
35
+ * binding it again would double every call. A copy sent with `bubbles: true`
36
+ * would land in the branch that refuses to bind, and `onPlay` on the player
37
+ * would be silent.
43
38
  *
44
39
  * Bound once, after the first render, so the player's own listeners in its
45
40
  * template are ahead of it on the same video: what a consumer reads off the
46
41
  * player in a handler (`paused`, `volume`, `currentTime`) is already the
47
42
  * player's state by the time the copy reaches them.
48
43
  */
49
- export declare const relayMedia: (video: EventTarget, host: EventTarget) => (() => void);
44
+ export declare const relayMedia: (video: EventTarget, relay: (event: Event) => void) => (() => void);
@@ -23,11 +23,7 @@ export const MEDIA_EVENTS = [
23
23
  'volumechange',
24
24
  'waiting',
25
25
  ];
26
- export const relayedCopy = (event) => new Event(event.type, { bubbles: false, cancelable: false, composed: false });
27
- export const relayMedia = (video, host) => {
28
- const relay = (event) => {
29
- host.dispatchEvent(relayedCopy(event));
30
- };
26
+ export const relayMedia = (video, relay) => {
31
27
  for (const name of MEDIA_EVENTS) {
32
28
  video.addEventListener(name, relay);
33
29
  }
@@ -20,6 +20,18 @@ export interface Conditions {
20
20
  }
21
21
  /** Whether this platform can do a named control at all. */
22
22
  export declare const offers: (one: string, player: Conditions) => boolean;
23
+ /**
24
+ * What `full` stands for in a list of controls: every control that does
25
+ * something to the video by itself, as Web Awesome's `full` preset adds speed
26
+ * and picture in picture to its standard bar.
27
+ *
28
+ * `download`, `previous` and `next` are left out. Offering the file is a
29
+ * decision about the content, and the other two move a set the player cannot
30
+ * see, so each is named where it is wanted.
31
+ */
32
+ export declare const FULL_CONTROLS: readonly ['rewind', 'forward', 'speed', 'pip', 'remote'];
33
+ /** The names in a written list, with `full` read as the controls it stands for, each once. */
34
+ export declare const controlNames: (written: string) => string[];
23
35
  /** The extras asked for, in order, and only the ones this platform can do. */
24
36
  export declare const barControls: (written: string, player: Conditions) => string[];
25
37
  /**
@@ -20,10 +20,14 @@ export const offers = (one, player) => {
20
20
  }
21
21
  return one === 'speed';
22
22
  };
23
- export const barControls = (written, player) => writtenList(written).filter((one) => offers(one, player));
23
+ export const FULL_CONTROLS = ['rewind', 'forward', 'speed', 'pip', 'remote'];
24
+ export const controlNames = (written) => [
25
+ ...new Set(writtenList(written).flatMap((one) => one === 'full' ? FULL_CONTROLS : [one])),
26
+ ];
27
+ export const barControls = (written, player) => controlNames(written).filter((one) => offers(one, player));
24
28
  export const menuControls = (written, onBar, player) => {
25
29
  const bar = new Set(onBar);
26
- return writtenList(written).filter((one) => !bar.has(one) && offers(one, player));
30
+ return controlNames(written).filter((one) => !bar.has(one) && offers(one, player));
27
31
  };
28
32
  export const ownFile = (src) => {
29
33
  if (src === '') {
@@ -17,11 +17,22 @@ import '../../menu/index.js';
17
17
  * not drawn, and the keys below are not bound, so a key press does not seek
18
18
  * twice.
19
19
  *
20
- * The keys match other players, and they are bound on the element only:
21
- * - Space and `k` play or pause.
22
- * - The arrow keys seek and change the volume.
23
- * - `m` mutes.
24
- * - `f` toggles fullscreen.
20
+ * **Keyboard.** The keys match other players, and they are bound on the
21
+ * element only, so they work while focus is on the player.
22
+ *
23
+ * | Key | What it does |
24
+ * |---|---|
25
+ * | Space, `k` | Plays or pauses. Space on a button presses the button. |
26
+ * | Right, Left | Moves 5 seconds forward or back. |
27
+ * | Shift with Right or Left | Moves 10 seconds forward or back. |
28
+ * | `l`, `j` | Moves 10 seconds forward or back, as the skip buttons do. |
29
+ * | Up, Down | Raises or lowers the volume by a tenth. |
30
+ * | `m` | Mutes or unmutes. |
31
+ * | `f` | Enters or leaves fullscreen. |
32
+ * | Tab | Moves through the controls on the bar. |
33
+ *
34
+ * On the scrubber and the volume slider, the arrow keys, Page Up, Page Down,
35
+ * Home, and End move the slider, as on any range input.
25
36
  *
26
37
  * `<source>` and `<track>` children are copied into the video. A media element
27
38
  * selects resources from its own child nodes, and a slot is one node, so
@@ -107,6 +118,8 @@ import '../../menu/index.js';
107
118
  * @csspart entry-mark - The trailing mark: a check mark when the row is checked, or a caret when it opens a submenu.
108
119
  * @csspart entry-shortcut - The key drawn for a row's shortcut. The player's rows set none.
109
120
  * @csspart entry-shortcut-kbd - The key inside `entry-shortcut`.
121
+ * @csspart entry-shortcut-key - One key of a row's shortcut chord, inside `entry-shortcut`. The player's rows set none.
122
+ * @csspart entry-shortcut-separator - The `+` between two keys of a row's shortcut, where the platform writes one.
110
123
  * @csspart entry-start - The leading column that holds the `start` slot. It is always rendered.
111
124
  * @csspart failure - The message shown when the source cannot be played.
112
125
  * @csspart forward - The button that skips forward ten seconds.
@@ -229,7 +242,11 @@ export declare class HelixHeadlessVideo extends HelixElement {
229
242
  * that cannot work is worse than one that is not there.
230
243
  *
231
244
  * The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
232
- * `previous` and `next`.
245
+ * `previous` and `next`. `full` stands for `rewind`, `forward`, `speed`,
246
+ * `pip` and `remote` in that order, the controls that act on the video by
247
+ * themselves, as Web Awesome's `full` preset does, and a name it already
248
+ * holds is drawn once. `extra-controls="full"` is the whole bar, and
249
+ * `overflow-controls="full"` puts all of it behind one button.
233
250
  *
234
251
  * **`previous` and `next` do nothing to the video, and are offered anyway.**
235
252
  * They announce `helix-previous` and `helix-next` and stop there, so what