@fusion.dev/helix-headless 0.147.0 → 0.149.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 (296) hide show
  1. package/custom-elements.json +11222 -2332
  2. package/dist/accordion/item/accordion-item.d.ts +5 -2
  3. package/dist/accordion/item/accordion-item.js +11 -7
  4. package/dist/accordion/root/accordion-root.js +4 -6
  5. package/dist/announcement/root/announcement-root.d.ts +61 -5
  6. package/dist/announcement/root/announcement-root.js +126 -20
  7. package/dist/area-chart/root/area-chart-root.d.ts +11 -0
  8. package/dist/area-chart/root/area-chart-root.js +21 -9
  9. package/dist/avatar/group/avatar-group.d.ts +10 -2
  10. package/dist/avatar/group/avatar-group.js +10 -5
  11. package/dist/badge/count.d.ts +19 -0
  12. package/dist/badge/count.js +20 -0
  13. package/dist/badge/root/badge-root.d.ts +6 -2
  14. package/dist/badge/root/badge-root.js +8 -22
  15. package/dist/bar-chart/root/bar-chart-root.d.ts +13 -1
  16. package/dist/bar-chart/root/bar-chart-root.js +17 -4
  17. package/dist/blockquote/root/blockquote-root.d.ts +66 -8
  18. package/dist/blockquote/root/blockquote-root.js +85 -8
  19. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +2 -2
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +8 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +5 -2
  22. package/dist/button/root/button-root.d.ts +10 -1
  23. package/dist/button/root/button-root.js +3 -2
  24. package/dist/button-group/arrows.d.ts +14 -0
  25. package/dist/button-group/arrows.js +10 -0
  26. package/dist/button-group/root/button-group-root.d.ts +144 -3
  27. package/dist/button-group/root/button-group-root.js +142 -2
  28. package/dist/callout/root/callout-root.d.ts +16 -2
  29. package/dist/callout/root/callout-root.js +16 -4
  30. package/dist/canvas/describe.d.ts +10 -0
  31. package/dist/canvas/describe.js +9 -0
  32. package/dist/canvas/edge-pan.d.ts +61 -0
  33. package/dist/canvas/edge-pan.js +63 -0
  34. package/dist/canvas/neighbor.d.ts +17 -0
  35. package/dist/canvas/neighbor.js +1 -0
  36. package/dist/canvas/node/canvas-node.d.ts +12 -2
  37. package/dist/canvas/node/canvas-node.js +8 -3
  38. package/dist/canvas/root/canvas-document.d.ts +10 -0
  39. package/dist/canvas/root/canvas-document.js +1 -0
  40. package/dist/canvas/root/canvas-root.d.ts +168 -9
  41. package/dist/canvas/root/canvas-root.js +239 -69
  42. package/dist/canvas/snap.d.ts +42 -0
  43. package/dist/canvas/snap.js +32 -0
  44. package/dist/carousel/root/carousel-root.d.ts +9 -3
  45. package/dist/carousel/root/carousel-root.js +17 -10
  46. package/dist/chat/composer/chat-composer.d.ts +5 -0
  47. package/dist/chat/composer/chat-composer.js +4 -1
  48. package/dist/chat/message/chat-message.d.ts +9 -5
  49. package/dist/chat/message/chat-message.js +8 -4
  50. package/dist/chat/naming.js +2 -2
  51. package/dist/chat/root/chat-root.d.ts +40 -4
  52. package/dist/chat/root/chat-root.js +38 -14
  53. package/dist/checkbox/root/checkbox-root.d.ts +11 -0
  54. package/dist/checkbox/root/checkbox-root.js +8 -2
  55. package/dist/checkbox-group/root/checkbox-group-root.d.ts +24 -0
  56. package/dist/checkbox-group/root/checkbox-group-root.js +28 -12
  57. package/dist/checkbox-group/select-all.d.ts +11 -0
  58. package/dist/checkbox-group/select-all.js +5 -0
  59. package/dist/code-block/root/code-block-root.d.ts +20 -8
  60. package/dist/code-block/root/code-block-root.js +16 -5
  61. package/dist/color-input/root/color-input-root.d.ts +13 -0
  62. package/dist/color-input/root/color-input-root.js +18 -5
  63. package/dist/color-picker/root/color-picker-root.d.ts +19 -3
  64. package/dist/color-picker/root/color-picker-root.js +52 -24
  65. package/dist/color-picker/wheel.d.ts +11 -0
  66. package/dist/color-picker/wheel.js +9 -0
  67. package/dist/combobox/root/combobox-root.d.ts +106 -18
  68. package/dist/combobox/root/combobox-root.js +101 -26
  69. package/dist/command/root/command-root.d.ts +19 -9
  70. package/dist/command/root/command-root.js +9 -4
  71. package/dist/copy-button/root/copy-button-root.d.ts +5 -0
  72. package/dist/copy-button/root/copy-button-root.js +7 -2
  73. package/dist/data-table/root/data-table-root.d.ts +171 -29
  74. package/dist/data-table/root/data-table-root.js +284 -161
  75. package/dist/date-input/root/date-input-root.d.ts +32 -9
  76. package/dist/date-input/root/date-input-root.js +66 -44
  77. package/dist/date-picker/root/date-picker-root.d.ts +38 -15
  78. package/dist/date-picker/root/date-picker-root.js +52 -33
  79. package/dist/description-list/item/description-list-item.d.ts +4 -0
  80. package/dist/description-list/item/description-list-item.js +7 -1
  81. package/dist/dialog/root/dialog-root.d.ts +12 -1
  82. package/dist/dialog/root/dialog-root.js +11 -4
  83. package/dist/divider/root/divider-root.d.ts +45 -16
  84. package/dist/divider/root/divider-root.js +28 -4
  85. package/dist/donut-chart/root/donut-chart-root.d.ts +5 -0
  86. package/dist/donut-chart/root/donut-chart-root.js +8 -5
  87. package/dist/drawer/root/drawer-root.d.ts +12 -1
  88. package/dist/drawer/root/drawer-root.js +9 -2
  89. package/dist/drilldown/item/drilldown-item.js +3 -4
  90. package/dist/drilldown/root/drilldown-root.d.ts +5 -0
  91. package/dist/drilldown/root/drilldown-root.js +4 -1
  92. package/dist/element-events.generated.js +26 -3
  93. package/dist/empty/root/empty-root.d.ts +17 -3
  94. package/dist/empty/root/empty-root.js +29 -5
  95. package/dist/file-input/root/file-input-root.d.ts +18 -3
  96. package/dist/file-input/root/file-input-root.js +34 -18
  97. package/dist/file-input/status.js +2 -1
  98. package/dist/filter-input/chip/filter-chip.d.ts +13 -0
  99. package/dist/filter-input/chip/filter-chip.js +7 -3
  100. package/dist/filter-input/menu/filter-menu.d.ts +5 -0
  101. package/dist/filter-input/menu/filter-menu.js +3 -1
  102. package/dist/filter-input/root/filter-input-root.d.ts +20 -3
  103. package/dist/filter-input/root/filter-input-root.js +8 -4
  104. package/dist/format-date/fields.d.ts +20 -0
  105. package/dist/format-date/fields.js +14 -0
  106. package/dist/format-date/options.d.ts +2 -1
  107. package/dist/format-date/options.js +9 -38
  108. package/dist/format-date/root/format-date-root.d.ts +55 -5
  109. package/dist/format-date/root/format-date-root.js +29 -34
  110. package/dist/graph/root/graph-model.d.ts +11 -0
  111. package/dist/graph/root/graph-model.js +4 -0
  112. package/dist/graph/root/graph-root.d.ts +101 -14
  113. package/dist/graph/root/graph-root.js +140 -46
  114. package/dist/heatmap/root/heatmap-root.d.ts +37 -4
  115. package/dist/heatmap/root/heatmap-root.js +51 -16
  116. package/dist/icon-button/root/icon-button-root.d.ts +5 -0
  117. package/dist/icon-button/root/icon-button-root.js +1 -0
  118. package/dist/image/root/image-root.d.ts +11 -0
  119. package/dist/input/root/input-root.d.ts +5 -0
  120. package/dist/input/root/input-root.js +4 -1
  121. package/dist/kbd/root/kbd-root.js +1 -2
  122. package/dist/legend/root/legend-root.js +4 -17
  123. package/dist/lightbox/root/lightbox-root.d.ts +14 -4
  124. package/dist/lightbox/root/lightbox-root.js +25 -7
  125. package/dist/line-chart/root/line-chart-root.d.ts +5 -0
  126. package/dist/line-chart/root/line-chart-root.js +4 -2
  127. package/dist/list/item/list-item.d.ts +32 -0
  128. package/dist/list/item/list-item.js +34 -7
  129. package/dist/list/root/list-root.d.ts +87 -0
  130. package/dist/list/root/list-root.js +119 -23
  131. package/dist/listbox/reorder/index.d.ts +1 -0
  132. package/dist/listbox/reorder/index.js +4 -0
  133. package/dist/listbox/reorder/listbox-reorder.d.ts +83 -0
  134. package/dist/listbox/reorder/listbox-reorder.js +151 -0
  135. package/dist/listbox/root/listbox-root.d.ts +185 -33
  136. package/dist/listbox/root/listbox-root.js +166 -136
  137. package/dist/loader/root/loader-root.d.ts +5 -0
  138. package/dist/loader/root/loader-root.js +3 -1
  139. package/dist/map/area/map-area.d.ts +5 -0
  140. package/dist/map/area/map-area.js +3 -1
  141. package/dist/map/buildings/map-buildings.d.ts +5 -0
  142. package/dist/map/buildings/map-buildings.js +3 -1
  143. package/dist/map/contours/map-contours.d.ts +5 -0
  144. package/dist/map/contours/map-contours.js +3 -1
  145. package/dist/map/landcover/map-landcover.d.ts +5 -0
  146. package/dist/map/landcover/map-landcover.js +3 -1
  147. package/dist/map/marker/map-marker.d.ts +18 -2
  148. package/dist/map/marker/map-marker.js +13 -5
  149. package/dist/map/points/map-points.d.ts +5 -0
  150. package/dist/map/points/map-points.js +6 -4
  151. package/dist/map/position/map-position.d.ts +5 -0
  152. package/dist/map/position/map-position.js +3 -1
  153. package/dist/map/raster/map-raster.d.ts +5 -0
  154. package/dist/map/raster/map-raster.js +3 -1
  155. package/dist/map/root/map-root.d.ts +73 -16
  156. package/dist/map/root/map-root.js +122 -44
  157. package/dist/map/route/map-route.d.ts +5 -0
  158. package/dist/map/route/map-route.js +3 -1
  159. package/dist/map/terrain/map-terrain.d.ts +5 -0
  160. package/dist/map/terrain/map-terrain.js +3 -1
  161. package/dist/megamenu/root/megamenu-root.js +4 -11
  162. package/dist/menu/root/menu-root.d.ts +7 -2
  163. package/dist/menu/root/menu-root.js +3 -1
  164. package/dist/meter/root/meter-root.d.ts +16 -3
  165. package/dist/meter/root/meter-root.js +12 -5
  166. package/dist/navigation/root/navigation-root.d.ts +5 -0
  167. package/dist/navigation/root/navigation-root.js +7 -8
  168. package/dist/notifications/group/notification-group.d.ts +8 -1
  169. package/dist/notifications/group/notification-group.js +12 -6
  170. package/dist/notifications/notification/notification.d.ts +17 -1
  171. package/dist/notifications/notification/notification.js +6 -2
  172. package/dist/notifications/root/notifications-root.d.ts +49 -5
  173. package/dist/notifications/root/notifications-root.js +36 -8
  174. package/dist/number-input/root/number-input-root.d.ts +21 -8
  175. package/dist/number-input/root/number-input-root.js +26 -11
  176. package/dist/object-inspector/root/object-inspector-root.d.ts +56 -13
  177. package/dist/object-inspector/root/object-inspector-root.js +41 -30
  178. package/dist/outline/root/outline-root.d.ts +5 -0
  179. package/dist/outline/root/outline-root.js +3 -1
  180. package/dist/pagination/root/pagination-root.d.ts +7 -1
  181. package/dist/pagination/root/pagination-root.js +16 -7
  182. package/dist/pagination/size/pagination-size.d.ts +8 -3
  183. package/dist/pagination/size/pagination-size.js +5 -3
  184. package/dist/pagination/summary/pagination-summary.d.ts +8 -6
  185. package/dist/pagination/summary/pagination-summary.js +4 -9
  186. package/dist/pin-input/code.d.ts +23 -0
  187. package/dist/pin-input/code.js +21 -0
  188. package/dist/pin-input/root/pin-input-root.d.ts +9 -3
  189. package/dist/pin-input/root/pin-input-root.js +13 -23
  190. package/dist/popover/root/popover-root.d.ts +12 -2
  191. package/dist/popover/root/popover-root.js +10 -4
  192. package/dist/progress/root/progress-root.d.ts +7 -2
  193. package/dist/progress/root/progress-root.js +5 -2
  194. package/dist/qr-code/name.d.ts +3 -2
  195. package/dist/qr-code/name.js +2 -2
  196. package/dist/qr-code/root/qr-code-root.d.ts +26 -5
  197. package/dist/qr-code/root/qr-code-root.js +27 -6
  198. package/dist/radio/group/radio-group.d.ts +11 -0
  199. package/dist/radio/group/radio-group.js +8 -2
  200. package/dist/rating/root/rating-root.d.ts +12 -1
  201. package/dist/rating/root/rating-root.js +10 -3
  202. package/dist/scatter-chart/measures.d.ts +22 -0
  203. package/dist/scatter-chart/measures.js +11 -0
  204. package/dist/scatter-chart/root/scatter-chart-root.d.ts +22 -8
  205. package/dist/scatter-chart/root/scatter-chart-root.js +25 -23
  206. package/dist/select/root/select-root.d.ts +67 -8
  207. package/dist/select/root/select-root.js +45 -11
  208. package/dist/skip-link/root/skip-link-root.d.ts +5 -0
  209. package/dist/skip-link/root/skip-link-root.js +3 -1
  210. package/dist/slider/root/slider-root.d.ts +7 -2
  211. package/dist/slider/root/slider-root.js +11 -5
  212. package/dist/sparkline/readings.d.ts +15 -5
  213. package/dist/sparkline/readings.js +3 -3
  214. package/dist/sparkline/root/sparkline-root.d.ts +9 -4
  215. package/dist/sparkline/root/sparkline-root.js +9 -3
  216. package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
  217. package/dist/speed-dial/group/speed-dial-group.js +43 -0
  218. package/dist/speed-dial/index.d.ts +1 -0
  219. package/dist/speed-dial/index.js +1 -0
  220. package/dist/speed-dial/item/speed-dial-item.d.ts +26 -1
  221. package/dist/speed-dial/item/speed-dial-item.js +41 -3
  222. package/dist/speed-dial/long-press.d.ts +50 -0
  223. package/dist/speed-dial/long-press.js +48 -0
  224. package/dist/speed-dial/root/speed-dial-root.d.ts +85 -1
  225. package/dist/speed-dial/root/speed-dial-root.js +117 -5
  226. package/dist/splitter/root/splitter-root.d.ts +12 -3
  227. package/dist/splitter/root/splitter-root.js +22 -4
  228. package/dist/steps/root/steps-root.d.ts +9 -2
  229. package/dist/steps/root/steps-root.js +6 -3
  230. package/dist/steps/step/step.d.ts +12 -0
  231. package/dist/steps/step/step.js +11 -2
  232. package/dist/switch/root/switch-root.d.ts +11 -0
  233. package/dist/switch/root/switch-root.js +8 -2
  234. package/dist/table/cell/table-cell.d.ts +8 -1
  235. package/dist/table/cell/table-cell.js +6 -2
  236. package/dist/table/column/table-column.d.ts +11 -4
  237. package/dist/table/column/table-column.js +15 -10
  238. package/dist/table/grid-controller.d.ts +122 -0
  239. package/dist/table/grid-controller.js +299 -0
  240. package/dist/table/root/table-root.d.ts +154 -8
  241. package/dist/table/root/table-root.js +197 -38
  242. package/dist/table/row/table-row.d.ts +55 -1
  243. package/dist/table/row/table-row.js +60 -7
  244. package/dist/tabs/root/tabs-root.d.ts +5 -0
  245. package/dist/tabs/root/tabs-root.js +3 -1
  246. package/dist/tag/group/tag-group.d.ts +5 -0
  247. package/dist/tag/group/tag-group.js +8 -15
  248. package/dist/tag/root/tag-root.d.ts +14 -1
  249. package/dist/tag/root/tag-root.js +11 -8
  250. package/dist/textarea/root/textarea-root.d.ts +5 -0
  251. package/dist/textarea/root/textarea-root.js +3 -1
  252. package/dist/time-input/root/time-input-root.d.ts +14 -7
  253. package/dist/time-input/root/time-input-root.js +43 -32
  254. package/dist/time-picker/root/time-picker-root.d.ts +16 -7
  255. package/dist/time-picker/root/time-picker-root.js +28 -12
  256. package/dist/toast/item/toast-item.d.ts +13 -3
  257. package/dist/toast/item/toast-item.js +2 -0
  258. package/dist/toast/root/toast-root.d.ts +22 -2
  259. package/dist/toast/root/toast-root.js +24 -17
  260. package/dist/toggle/group/toggle-group.js +3 -5
  261. package/dist/toolbar/root/toolbar-root.d.ts +36 -0
  262. package/dist/toolbar/root/toolbar-root.js +43 -9
  263. package/dist/tooltip/root/tooltip-root.d.ts +27 -17
  264. package/dist/tooltip/root/tooltip-root.js +1 -2
  265. package/dist/tour/root/tour-root.d.ts +8 -2
  266. package/dist/tour/root/tour-root.js +4 -2
  267. package/dist/tour/stop/tour-stop.d.ts +5 -0
  268. package/dist/tour/stop/tour-stop.js +6 -1
  269. package/dist/tree/grip.d.ts +5 -0
  270. package/dist/tree/grip.js +1 -0
  271. package/dist/tree/item/tree-item.d.ts +24 -0
  272. package/dist/tree/item/tree-item.js +27 -5
  273. package/dist/tree/root/tree-root.d.ts +66 -1
  274. package/dist/tree/root/tree-root.js +77 -5
  275. package/dist/trend/root/trend-root.d.ts +20 -4
  276. package/dist/trend/root/trend-root.js +20 -5
  277. package/dist/video/root/video-root.d.ts +23 -3
  278. package/dist/video/root/video-root.js +56 -15
  279. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
  280. package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
  281. package/dist/video-playlist/root/video-playlist-root.d.ts +5 -0
  282. package/dist/video-playlist/root/video-playlist-root.js +3 -1
  283. package/dist/virtual-list/root/virtual-list-root.d.ts +19 -3
  284. package/dist/virtual-list/root/virtual-list-root.js +10 -19
  285. package/lint.json +1 -1
  286. package/package.json +7 -6
  287. package/types/jsx.d.ts +6005 -2114
  288. package/types/svelte.d.ts +1 -0
  289. package/types/vue.d.ts +1594 -676
  290. package/types/words.d.ts +3280 -0
  291. package/dist/kbd/keys.d.ts +0 -29
  292. package/dist/kbd/keys.js +0 -52
  293. package/dist/toast/hotkey.d.ts +0 -22
  294. package/dist/toast/hotkey.js +0 -23
  295. package/dist/tooltip/focus-target.d.ts +0 -6
  296. package/dist/tooltip/focus-target.js +0 -9
@@ -0,0 +1,299 @@
1
+ import { deepActiveElement, deepContains, focusableElements, gridMove, inlineStep, pageRows, scrollingAncestor, scrollRoom, selectsAll, whenHydrated, } from '@fusion.dev/helix-core';
2
+ const HEADS = { grip: 'grip-head', select: 'select-all' };
3
+ const shown = (element) => {
4
+ const hidden = element.getAttribute('hidden');
5
+ return hidden === null || hidden === 'until-found';
6
+ };
7
+ export class TableGridController {
8
+ constructor(host, options) {
9
+ this.stopRow = undefined;
10
+ this.stopColumn = 0;
11
+ this.stopIndex = 0;
12
+ this.focusRow = undefined;
13
+ this.focusWanted = false;
14
+ this.pointing = false;
15
+ this.given = new Set();
16
+ this.handleKeydown = (event) => {
17
+ if (!this.options.on() || event.defaultPrevented || event.altKey) {
18
+ return;
19
+ }
20
+ const place = this.placeOf(event);
21
+ if (!place) {
22
+ return;
23
+ }
24
+ if (event.composedPath()[0] !== place.cell) {
25
+ this.handleControlKey(event, place);
26
+ return;
27
+ }
28
+ if (event.key === 'Tab') {
29
+ this.leave(event.shiftKey);
30
+ return;
31
+ }
32
+ if (selectsAll(event) && !event.shiftKey) {
33
+ if (this.options.selectAll()) {
34
+ event.preventDefault();
35
+ }
36
+ return;
37
+ }
38
+ if (event.key === 'Enter' || event.key === ' ' || event.key === 'F2') {
39
+ if (event.key !== 'F2' && this.options.activate(place, event)) {
40
+ event.preventDefault();
41
+ return;
42
+ }
43
+ const first = event.key === ' ' ? undefined : this.controlsIn(place)[0];
44
+ if (first) {
45
+ event.preventDefault();
46
+ first.focus();
47
+ }
48
+ return;
49
+ }
50
+ const to = gridMove(event.key, place, { last: this.options.rows().length - 1, top: this.top, width: this.widthOf(place.row) }, {
51
+ control: event.ctrlKey || event.metaKey,
52
+ page: event.key.startsWith('Page') ? this.pageFrom(place.cell) : 1,
53
+ step: inlineStep(this.host, event.key),
54
+ });
55
+ if (!to) {
56
+ return;
57
+ }
58
+ event.preventDefault();
59
+ to.column = Math.max(0, Math.min(to.column, this.widthOf(to.row) - 1));
60
+ if (to.row !== place.row || to.column !== place.column) {
61
+ this.moveTo(to);
62
+ }
63
+ };
64
+ this.handleFocusIn = (event) => {
65
+ if (!this.options.on()) {
66
+ return;
67
+ }
68
+ const place = this.placeOf(event);
69
+ if (!place) {
70
+ return;
71
+ }
72
+ const from = event.relatedTarget;
73
+ const entering = !(from instanceof Node && deepContains(this.host, from));
74
+ if (entering && !this.pointing && event.composedPath()[0] !== place.cell) {
75
+ const stop = this.cellAt(this.current());
76
+ if (stop) {
77
+ stop.focus();
78
+ return;
79
+ }
80
+ }
81
+ this.focusRow = place.row === -1 ? undefined : this.options.rows()[place.row];
82
+ const at = this.current();
83
+ if (at.row !== place.row || at.column !== place.column) {
84
+ this.moveTo(place, false);
85
+ }
86
+ };
87
+ this.handleFocusOut = (event) => {
88
+ const to = event.relatedTarget;
89
+ if (to instanceof Node && !deepContains(this.host, to)) {
90
+ this.focusRow = undefined;
91
+ }
92
+ };
93
+ this.handlePointerDown = () => {
94
+ this.pointing = true;
95
+ setTimeout(() => {
96
+ this.pointing = false;
97
+ });
98
+ };
99
+ this.host = host;
100
+ this.options = options;
101
+ host.addController(this);
102
+ }
103
+ hostConnected() {
104
+ this.host.addEventListener('keydown', this.handleKeydown);
105
+ this.host.addEventListener('focusin', this.handleFocusIn);
106
+ this.host.addEventListener('focusout', this.handleFocusOut);
107
+ this.host.addEventListener('pointerdown', this.handlePointerDown);
108
+ }
109
+ hostDisconnected() {
110
+ this.host.removeEventListener('keydown', this.handleKeydown);
111
+ this.host.removeEventListener('focusin', this.handleFocusIn);
112
+ this.host.removeEventListener('focusout', this.handleFocusOut);
113
+ this.host.removeEventListener('pointerdown', this.handlePointerDown);
114
+ }
115
+ hostUpdate() {
116
+ const gone = this.stopRow;
117
+ const rows = this.options.rows();
118
+ if (!(gone instanceof Element) || rows.includes(gone)) {
119
+ return;
120
+ }
121
+ this.stopRow = rows[Math.min(this.stopIndex, rows.length - 1)];
122
+ const active = deepActiveElement();
123
+ if (this.focusRow === gone && (!active || active === document.body)) {
124
+ this.focusWanted = true;
125
+ }
126
+ this.focusRow = undefined;
127
+ }
128
+ get offset() {
129
+ return this.options.lead().length;
130
+ }
131
+ get top() {
132
+ return this.options.columns().length > 0 || this.offset > 0 ? -1 : 0;
133
+ }
134
+ cellsOf(row) {
135
+ return [...(row?.children ?? [])].filter(shown);
136
+ }
137
+ widthOf(row) {
138
+ const own = row === -1 ? this.options.columns().length : this.cellsOf(this.options.rows()[row]).length;
139
+ return this.offset + own;
140
+ }
141
+ cellAt({ column, row }) {
142
+ const lead = this.options.lead()[column];
143
+ if (row === -1) {
144
+ return lead
145
+ ? this.options.part(HEADS[lead])
146
+ : (this.options.columns()[column - this.offset]?.cellBox ?? null);
147
+ }
148
+ const line = this.options.rows()[row];
149
+ if (lead) {
150
+ return line?.shadowRoot?.querySelector(`[part~="${lead}"]`) ?? null;
151
+ }
152
+ return this.cellsOf(line)[column - this.offset] ?? null;
153
+ }
154
+ current() {
155
+ const found = this.stopRow === undefined || this.stopRow === 'head'
156
+ ? -1
157
+ : this.options.rows().indexOf(this.stopRow);
158
+ const row = this.stopRow === 'head' || found < 0 ? this.top : found;
159
+ const width = this.widthOf(row);
160
+ return { column: Math.max(0, Math.min(this.stopColumn, width - 1)), row };
161
+ }
162
+ isStop(place) {
163
+ const at = this.current();
164
+ return this.options.on() && at.row === place.row && at.column === place.column;
165
+ }
166
+ placeOf(event) {
167
+ const columns = this.options.columns();
168
+ const rows = this.options.rows();
169
+ for (const node of event.composedPath()) {
170
+ if (node === this.host) {
171
+ return undefined;
172
+ }
173
+ if (!(node instanceof HTMLElement)) {
174
+ continue;
175
+ }
176
+ const heading = columns.indexOf(node);
177
+ if (heading >= 0) {
178
+ const cell = node.cellBox;
179
+ return cell ? { cell, column: heading + this.offset, row: -1 } : undefined;
180
+ }
181
+ const part = node.getAttribute('part') ?? '';
182
+ const root = node.getRootNode();
183
+ for (const [column, lead] of this.options.lead().entries()) {
184
+ if (part === HEADS[lead] && root === this.host.shadowRoot) {
185
+ return { cell: node, column, row: -1 };
186
+ }
187
+ if (part.split(' ').includes(lead) && rows.includes(root.host)) {
188
+ return { cell: node, column, row: rows.indexOf(root.host) };
189
+ }
190
+ }
191
+ const parent = node.parentElement;
192
+ if (parent && rows.includes(parent) && shown(node)) {
193
+ const column = this.cellsOf(parent).indexOf(node);
194
+ return { cell: node, column: column + this.offset, row: rows.indexOf(parent) };
195
+ }
196
+ }
197
+ return undefined;
198
+ }
199
+ moveTo(place, focus = true) {
200
+ this.stopRow = place.row === -1 ? 'head' : this.options.rows()[place.row];
201
+ this.stopColumn = place.column;
202
+ this.focusWanted = focus;
203
+ this.host.requestUpdate();
204
+ }
205
+ mark() {
206
+ const on = this.options.on();
207
+ const at = this.current();
208
+ const lead = this.options.lead();
209
+ this.stopIndex = Math.max(0, at.row);
210
+ const columns = this.options.columns();
211
+ for (const [index, column] of columns.entries()) {
212
+ column.gridCell = on;
213
+ column.tabStop = on && at.row === -1 && at.column === index + this.offset;
214
+ }
215
+ for (const [index, line] of this.options.rows().entries()) {
216
+ const row = line;
217
+ if (row.isTableRow) {
218
+ const here = on && at.row === index;
219
+ whenHydrated(row, () => {
220
+ row.gridCell = on;
221
+ row.gripStop = here && lead[at.column] === 'grip';
222
+ row.selectStop = here && lead[at.column] === 'select';
223
+ });
224
+ }
225
+ for (const [place, cell] of this.cellsOf(line).entries()) {
226
+ if ('isTableCell' in cell) {
227
+ ;
228
+ cell.gridCell = on;
229
+ }
230
+ if (!on) {
231
+ continue;
232
+ }
233
+ const stop = at.row === index && at.column === place + this.offset ? 0 : -1;
234
+ if (cell.tabIndex !== stop || !cell.hasAttribute('tabindex')) {
235
+ cell.tabIndex = stop;
236
+ }
237
+ this.given.add(cell);
238
+ }
239
+ }
240
+ for (const cell of this.given) {
241
+ if (!on || !cell.isConnected) {
242
+ if (!on) {
243
+ cell.removeAttribute('tabindex');
244
+ }
245
+ this.given.delete(cell);
246
+ }
247
+ }
248
+ }
249
+ place() {
250
+ if (!this.focusWanted || !this.options.on()) {
251
+ return;
252
+ }
253
+ this.focusWanted = false;
254
+ this.cellAt(this.current())?.focus();
255
+ }
256
+ controlsIn(place) {
257
+ if (place.row === -1) {
258
+ return place.column < this.offset
259
+ ? []
260
+ : (this.options.columns()[place.column - this.offset]?.controls ?? []);
261
+ }
262
+ return place.column < this.offset ? [] : focusableElements(place.cell);
263
+ }
264
+ leave(back) {
265
+ const edge = this.options.part(back ? 'grid-start' : 'grid-end');
266
+ if (!edge) {
267
+ return;
268
+ }
269
+ edge.tabIndex = 0;
270
+ edge.addEventListener('focusout', () => {
271
+ edge.tabIndex = -1;
272
+ }, { once: true });
273
+ edge.focus({ preventScroll: true });
274
+ }
275
+ pageFrom(cell) {
276
+ const room = scrollRoom(scrollingAncestor(cell, { axis: 'y', overflowing: true }));
277
+ return pageRows(room, cell.getBoundingClientRect().height);
278
+ }
279
+ handleControlKey(event, place) {
280
+ if (event.key === 'Escape' || event.key === 'F2') {
281
+ event.preventDefault();
282
+ place.cell.focus();
283
+ return;
284
+ }
285
+ if (event.key !== 'Tab') {
286
+ return;
287
+ }
288
+ const origin = event.composedPath()[0];
289
+ const controls = this.controlsIn(place);
290
+ const at = controls.findIndex((one) => deepContains(one, origin));
291
+ const next = at >= 0 ? controls[at + (event.shiftKey ? -1 : 1)] : undefined;
292
+ if (next) {
293
+ event.preventDefault();
294
+ next.focus();
295
+ return;
296
+ }
297
+ this.leave(event.shiftKey);
298
+ }
299
+ }
@@ -50,9 +50,48 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
50
50
  * 4. A chosen row takes `:state(selected)`, and a screen reader hears
51
51
  * `selected-label` ("2 selected") from a polite region.
52
52
  *
53
- * Tab reaches each checkbox, and Space ticks it. For a grid a reader moves
54
- * through with the arrow keys, with typeahead and range selection, use
55
- * `DataTable`. To act on one row, put a link or a button in a cell.
53
+ * Tab reaches each checkbox, and Space ticks it. To act on one row, put a
54
+ * link or a button in a cell, or give the row an `href`.
55
+ *
56
+ * **Moving rows.** `reorderable` adds a column of grips before the checkboxes,
57
+ * under a heading named by `row-grips-label`.
58
+ *
59
+ * 1. Each row is known by its `value`, or by its place among the rows where it
60
+ * has none, as for selecting. Give rows a `value` when they move, so a key
61
+ * stays with its row.
62
+ * 2. A grip is a button named by `move-row-label` ("Move {row}") with the
63
+ * words of the row's first cell. Drag it to move its row, and the page
64
+ * scrolls near an edge. Or press it with Space, Enter, or a click to pick
65
+ * the row up, move it with Up, Down, Home, and End, and press it again to
66
+ * drop it. A click on another row drops it there, and Escape puts it back.
67
+ * 3. `helix-before-reorder` asks first, and `helix-reorder` follows with
68
+ * `keys`, every row's key in the new order. **You move the rows**: the
69
+ * table moves no element of yours, and focus goes back to the moved row's
70
+ * grip once you have.
71
+ * 4. Each step is said in the table's live region, in words you can change:
72
+ * `picked-up-label`, `moved-label`, `dropped-label`, and `canceled-label`.
73
+ * The grips do nothing while a sort is set.
74
+ *
75
+ * **A grid.** `grid` makes the table one tab stop that the arrow keys move
76
+ * through cell by cell, the headings included, as React Aria's table is. The
77
+ * table is then a `grid` and each value a `gridcell`, and the table gives
78
+ * every cell a `tabindex` so focus can rest on it: set `grid` only where the
79
+ * cells may carry one. For typeahead and range selection, use `DataTable`.
80
+ *
81
+ * | Key | What it does |
82
+ * |---|---|
83
+ * | Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. |
84
+ * | Down, Up | Moves one row, the headings included. |
85
+ * | Home, End | Moves to the first or the last cell of the row. |
86
+ * | Control with Home or End | Moves to the first or the last cell of the table. |
87
+ * | Page Down, Page Up | Moves by the rows that fit in view. |
88
+ * | Enter, F2 | Moves into the cell's links and controls. Escape or F2 moves back to the cell, and Tab moves between the controls of one cell. |
89
+ * | Enter on a cell of a row with `href` | Follows the row's link. |
90
+ * | Enter, Space on a sortable heading | Sorts by the column. |
91
+ * | Space on a row, Enter or Space on its checkbox cell | Selects the row, in a `selectable` table. |
92
+ * | Enter or Space on a grip cell | Picks the row up, or drops it, in a `reorderable` table. Up, Down, Home, and End move a row picked up, and Escape puts it back. |
93
+ * | Control or Command with A | Selects every row, in a `selectable` table. |
94
+ * | Tab | Leaves the table. |
56
95
  *
57
96
  * The CSS custom properties listed for this component are written by it and
58
97
  * read by the stylesheet that draws it. Do not set them. Each holds a number
@@ -68,6 +107,8 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
68
107
  * @slot - The table's rows.
69
108
  * @slot heading - Words that name the table, shown above it, such as a heading.
70
109
  *
110
+ * @event {HelixBeforeReorderEvent} helix-before-reorder - Fired when a row is dropped at a new place, in a `reorderable` table, with every row's key in the new order. Cancelable: cancel it to keep the row where it is.
111
+ * @event {HelixReorderEvent} helix-reorder - Fired after `helix-before-reorder` when nobody canceled it. Move your rows to the order in `keys`. Cancelable: cancel it to say the move did not happen.
71
112
  * @event {HelixSelectEvent} helix-select - The selection is about to change. The event carries every selected key, separated by commas. Cancelable: cancel it to keep the current selection.
72
113
  * @event {HelixSelectedEvent} helix-selected - Fired after the selection changes, with every selected key, separated by commas.
73
114
  * @event {HelixSortEvent} helix-sort - A different sort order was requested, as `field:direction`, or empty for the order the rows were written in. Cancelable: cancel it to keep the current order.
@@ -84,9 +125,13 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
84
125
  * @csspart checkbox-mark-checked - Added to `checkbox-mark` while its box is checked.
85
126
  * @csspart checkbox-mark-dash - Added to `checkbox-mark` while it draws the dash, which it keeps until its box is checked.
86
127
  * @csspart checkbox-mark-indeterminate - Added to `checkbox-mark` while only some rows are selected.
128
+ * @csspart drag-preview - A copy of the row a pointer drags by its grip, which follows the pointer in the top layer until the row is let go, in a `reorderable` table. Hidden from assistive technology.
87
129
  * @csspart empty - The text shown when there are no rows.
130
+ * @csspart grid-end - An empty box after the rows, in a `grid` table. Tab focuses it on its way out of the table, so the key leaves from the end.
131
+ * @csspart grid-start - An empty box before the rows, in a `grid` table. Shift with Tab focuses it on its way out of the table.
132
+ * @csspart grip-head - The heading over the row grips, in a `reorderable` table.
88
133
  * @csspart head - The row that holds the column headings. It has `display: contents`, so it takes no space of its own.
89
- * @csspart live - A live region that repeats the empty and loading text, so screen readers announce it when it changes. Visually hidden in the styled tier.
134
+ * @csspart live - A live region that repeats the empty and loading text, and says each step of a move, so screen readers announce it when it changes. Visually hidden in the styled tier.
90
135
  * @csspart loading - The text shown while the rows are loading.
91
136
  * @csspart select-all - The heading that holds the checkbox that selects every row.
92
137
  * @csspart table - The grid.
@@ -94,8 +139,24 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
94
139
  * @cssproperty --table-template - The column track list the table works out from its columns. The component writes it inline on the element that reads it, so setting it has no effect. Set `columns` to change the tracks.
95
140
  */
96
141
  export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
97
- /** The word for an ascending sort, in `sorted-label`. */
142
+ /**
143
+ * The key this family's words are registered under, its styled tag:
144
+ * `registerWords('de', { 'helix-table': { selectAllLabel: 'Alle Zeilen auswählen' } })`.
145
+ */
146
+ static words: string;
147
+ /**
148
+ * The word for an ascending sort, in a `sorted-label` that writes `{order}`.
149
+ *
150
+ * @deprecated Write the whole sentence for each order in `sorted-label`, with
151
+ * `{direction, select, ascending {...} descending {...} other {...}}`.
152
+ * Removed in the next major version.
153
+ */
98
154
  ascendingLabel: string;
155
+ /**
156
+ * What screen readers hear when a held row is put back, or a move is
157
+ * refused, in a `reorderable` table.
158
+ */
159
+ canceledLabel: string;
99
160
  /**
100
161
  * The column widths as one track list, written once on the table.
101
162
  *
@@ -136,8 +197,31 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
136
197
  * The starting sort order, used until `sort` is set.
137
198
  */
138
199
  defaultSort: string;
139
- /** The word for a descending sort, in `sorted-label`. */
200
+ /**
201
+ * The word for a descending sort, in a `sorted-label` that writes `{order}`.
202
+ *
203
+ * @deprecated Write the whole sentence for each order in `sorted-label`, with
204
+ * `{direction, select, ascending {...} descending {...} other {...}}`.
205
+ * Removed in the next major version.
206
+ */
140
207
  descendingLabel: string;
208
+ /** What screen readers hear when a held row is dropped, in a `reorderable` table. */
209
+ droppedLabel: string;
210
+ /**
211
+ * The table's name where neither `label` nor an `aria-label` or
212
+ * `aria-labelledby` on the host gives it one.
213
+ */
214
+ fallbackLabel: string;
215
+ /**
216
+ * Makes the table a grid: one tab stop, and the arrow keys, Home, End and the
217
+ * Page keys move focus between its cells, the headings included. Enter moves
218
+ * into a cell's controls, and Tab leaves the table.
219
+ *
220
+ * Off by default, where the table is a static `table` and Tab reaches each
221
+ * link and control in it. On, the table writes a `tabindex` onto each of its
222
+ * cells, which is the one way a cell of your markup can take focus.
223
+ */
224
+ grid: boolean;
141
225
  /**
142
226
  * Accessible name for the table.
143
227
  *
@@ -145,6 +229,29 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
145
229
  * wins over this.
146
230
  */
147
231
  label: string;
232
+ /**
233
+ * What screen readers hear each time a key moves a held row, in a
234
+ * `reorderable` table. `{name}` is the row's words, `{position}` the place it
235
+ * would go, counting from 1, and `{count}` the number of rows.
236
+ */
237
+ movedLabel: string;
238
+ /**
239
+ * The name of a row's grip, in a `reorderable` table. `{row}` is replaced
240
+ * with the words of the row's first cell.
241
+ */
242
+ moveRowLabel: string;
243
+ /**
244
+ * What screen readers hear when a key or a click picks up a row, in a
245
+ * `reorderable` table. `{name}` is the row's words.
246
+ */
247
+ pickedUpLabel: string;
248
+ /**
249
+ * Adds a column of grips that move rows, by dragging or with the keys. The
250
+ * table moves no row itself: you move your rows on `helix-reorder`.
251
+ */
252
+ reorderable: boolean;
253
+ /** The name of the heading over the row grips, in a `reorderable` table. */
254
+ rowGripsLabel: string;
148
255
  /**
149
256
  * Adds a column of checkboxes for selecting rows. Each row is known by its
150
257
  * `value`, and by its place among the rows as written where it has none.
@@ -163,7 +270,9 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
163
270
  set selected(next: string);
164
271
  /**
165
272
  * What screen readers hear when the chosen rows change. `{count}` is how many
166
- * rows are chosen.
273
+ * rows are chosen, written in the locale, and a language that needs plural
274
+ * forms writes them: `{count, plural, one {# wybrany} few {# wybrane} many
275
+ * {# wybranych} other {# wybranego}}`.
167
276
  */
168
277
  selectedLabel: string;
169
278
  /**
@@ -184,7 +293,9 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
184
293
  set sort(next: string);
185
294
  /**
186
295
  * What screen readers hear when the table is sorted. `{column}` is the
187
- * column's heading and `{order}` is `ascending-label` or `descending-label`.
296
+ * column's heading and `{direction}` is `ascending` or `descending`, so each
297
+ * order has its whole sentence. `{order}` is the deprecated
298
+ * `ascending-label` or `descending-label`.
188
299
  */
189
300
  sortedLabel: string;
190
301
  /** What screen readers hear when the table stops being sorted. */
@@ -202,6 +313,23 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
202
313
  * itself kept its default name.
203
314
  */
204
315
  protected readonly aria: AriaForwardController;
316
+ /** The keyboard of a `grid` table, in `grid-controller.ts`. */
317
+ private readonly gridKeys;
318
+ /**
319
+ * Moving rows by their grips, in a `reorderable` table. The rows are the
320
+ * page's, so a drop asks the page to move them, and the grips do nothing
321
+ * while a sort decides the order.
322
+ */
323
+ private readonly reorder;
324
+ /** The columns drawn before the consumer's cells: the grips, then the checkboxes. */
325
+ private get lead();
326
+ /** The row that stands for a key. */
327
+ private rowFor;
328
+ /**
329
+ * What takes focus for a row's grip, in a `reorderable` table: the cell in a
330
+ * grid, where every cell takes focus, and the button otherwise.
331
+ */
332
+ private gripOf;
205
333
  /**
206
334
  * Asks for a different order, and reports whether the request stood.
207
335
  */
@@ -231,6 +359,11 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
231
359
  * new order is said. Not on the first render, which is the table arriving.
232
360
  */
233
361
  private news;
362
+ /**
363
+ * The sentence a sort is said in: `sorted-label` with the column, and the
364
+ * order both as `{direction}` and as the deprecated `{order}` word.
365
+ */
366
+ private sortSaid;
234
367
  /** The sort as the last render had it, so a selection said beside a sort waits. */
235
368
  private heardSortBefore;
236
369
  /** The selection last heard, so a render that changed nothing says nothing. */
@@ -248,6 +381,17 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
248
381
  * left alone.
249
382
  */
250
383
  private readonly handleToggle;
384
+ /** Every row's key, in the order the rows are written. */
385
+ private get everyKey();
386
+ /** The checkbox in the heading: every row, or none where every row is chosen. */
387
+ private chooseAll;
388
+ /** One row's checkbox, ticked or not. */
389
+ private chooseRow;
390
+ /**
391
+ * Enter, Space or F2 on a cell of a `grid` table, and whether it did
392
+ * anything. Left alone, Enter and F2 move into the cell's controls.
393
+ */
394
+ private activate;
251
395
  /**
252
396
  * Tells each row whether it is selected and what its checkbox is called.
253
397
  *
@@ -398,6 +542,8 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
398
542
  private alignCells;
399
543
  protected willUpdate(changed: PropertyValues): void;
400
544
  protected updated(changed: PropertyValues): void;
545
+ /** The heading over the row grips, named by `row-grips-label`. */
546
+ private renderGripHead;
401
547
  /** The heading of the checkbox column, which selects every row. */
402
548
  private renderSelectAll;
403
549
  protected render(): TemplateResult;