@fusion.dev/helix-headless 0.146.0 → 0.148.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 (288) hide show
  1. package/custom-elements.json +9287 -1084
  2. package/dist/accordion/item/accordion-item.d.ts +43 -21
  3. package/dist/accordion/item/accordion-item.js +37 -11
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +6 -8
  6. package/dist/announcement/root/announcement-root.d.ts +66 -6
  7. package/dist/announcement/root/announcement-root.js +144 -13
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +14 -7
  10. package/dist/avatar/root/avatar-root.d.ts +31 -1
  11. package/dist/avatar/root/avatar-root.js +11 -1
  12. package/dist/badge/count.d.ts +14 -0
  13. package/dist/badge/count.js +20 -0
  14. package/dist/badge/root/badge-root.d.ts +57 -6
  15. package/dist/badge/root/badge-root.js +77 -8
  16. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  17. package/dist/bar-chart/stack.d.ts +10 -0
  18. package/dist/bar-chart/stack.js +8 -0
  19. package/dist/blockquote/root/blockquote-root.d.ts +66 -8
  20. package/dist/blockquote/root/blockquote-root.js +85 -8
  21. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  22. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  24. package/dist/button/root/button-root.d.ts +24 -38
  25. package/dist/button/root/button-root.js +6 -37
  26. package/dist/button/submitter.d.ts +27 -0
  27. package/dist/button/submitter.js +25 -0
  28. package/dist/button-group/arrows.d.ts +14 -0
  29. package/dist/button-group/arrows.js +10 -0
  30. package/dist/button-group/root/button-group-root.d.ts +141 -3
  31. package/dist/button-group/root/button-group-root.js +142 -2
  32. package/dist/canvas/edge-pan.d.ts +61 -0
  33. package/dist/canvas/edge-pan.js +63 -0
  34. package/dist/canvas/node/canvas-node.d.ts +12 -2
  35. package/dist/canvas/node/canvas-node.js +6 -2
  36. package/dist/canvas/root/canvas-document.d.ts +10 -0
  37. package/dist/canvas/root/canvas-document.js +1 -0
  38. package/dist/canvas/root/canvas-root.d.ts +107 -5
  39. package/dist/canvas/root/canvas-root.js +140 -36
  40. package/dist/canvas/snap.d.ts +42 -0
  41. package/dist/canvas/snap.js +32 -0
  42. package/dist/card/root/card-root.d.ts +12 -1
  43. package/dist/card/root/card-root.js +11 -4
  44. package/dist/carousel/root/carousel-root.d.ts +4 -3
  45. package/dist/carousel/root/carousel-root.js +2 -6
  46. package/dist/chat/root/chat-root.d.ts +28 -4
  47. package/dist/chat/root/chat-root.js +12 -7
  48. package/dist/checkbox/root/checkbox-root.js +5 -7
  49. package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
  50. package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
  51. package/dist/checkbox-group/select-all.d.ts +9 -4
  52. package/dist/checkbox-group/select-all.js +1 -1
  53. package/dist/code-block/root/code-block-root.d.ts +41 -18
  54. package/dist/code-block/root/code-block-root.js +21 -6
  55. package/dist/color-input/root/color-input-root.d.ts +11 -0
  56. package/dist/color-input/root/color-input-root.js +12 -5
  57. package/dist/color-picker/channels.js +1 -2
  58. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  59. package/dist/color-picker/root/color-picker-root.js +99 -55
  60. package/dist/color-picker/wheel.d.ts +28 -0
  61. package/dist/color-picker/wheel.js +15 -0
  62. package/dist/combobox/root/combobox-root.d.ts +83 -11
  63. package/dist/combobox/root/combobox-root.js +81 -18
  64. package/dist/command/root/command-root.d.ts +7 -4
  65. package/dist/command/root/command-root.js +2 -19
  66. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  67. package/dist/copy-button/root/copy-button-root.js +7 -2
  68. package/dist/data-table/keys.d.ts +0 -18
  69. package/dist/data-table/keys.js +1 -11
  70. package/dist/data-table/root/data-table-root.js +29 -50
  71. package/dist/date-input/root/date-input-root.d.ts +8 -1
  72. package/dist/date-input/root/date-input-root.js +8 -5
  73. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  74. package/dist/date-picker/root/date-picker-root.js +21 -16
  75. package/dist/description-list/item/description-list-item.d.ts +22 -4
  76. package/dist/description-list/item/description-list-item.js +14 -4
  77. package/dist/divider/root/divider-root.d.ts +45 -16
  78. package/dist/divider/root/divider-root.js +28 -4
  79. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  80. package/dist/donut-chart/slice-label.d.ts +35 -0
  81. package/dist/donut-chart/slice-label.js +11 -0
  82. package/dist/drawer/root/drawer-root.d.ts +4 -2
  83. package/dist/drawer/root/drawer-root.js +15 -3
  84. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  85. package/dist/drilldown/item/drilldown-item.js +38 -4
  86. package/dist/drilldown/root/drilldown-root.js +3 -2
  87. package/dist/element-events.generated.js +5 -1
  88. package/dist/empty/root/empty-root.d.ts +46 -2
  89. package/dist/empty/root/empty-root.js +50 -5
  90. package/dist/file-input/root/file-input-root.d.ts +34 -6
  91. package/dist/file-input/root/file-input-root.js +55 -21
  92. package/dist/file-input/status.d.ts +24 -0
  93. package/dist/file-input/status.js +11 -0
  94. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  95. package/dist/filter-input/chip/filter-chip.js +10 -2
  96. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  97. package/dist/filter-input/root/filter-input-root.js +17 -27
  98. package/dist/format-date/fields.d.ts +20 -0
  99. package/dist/format-date/fields.js +14 -0
  100. package/dist/format-date/options.d.ts +5 -5
  101. package/dist/format-date/options.js +10 -39
  102. package/dist/format-date/root/format-date-root.d.ts +53 -4
  103. package/dist/format-date/root/format-date-root.js +38 -50
  104. package/dist/graph/root/graph-root.d.ts +23 -5
  105. package/dist/graph/root/graph-root.js +17 -20
  106. package/dist/heatmap/root/buckets.d.ts +21 -0
  107. package/dist/heatmap/root/buckets.js +34 -0
  108. package/dist/heatmap/root/heatmap-root.d.ts +76 -3
  109. package/dist/heatmap/root/heatmap-root.js +105 -20
  110. package/dist/icon/index.d.ts +1 -1
  111. package/dist/icon/index.js +1 -1
  112. package/dist/icon/registry.d.ts +26 -1
  113. package/dist/icon/registry.js +12 -1
  114. package/dist/icon/root/icon-root.d.ts +13 -0
  115. package/dist/icon/root/icon-root.js +23 -2
  116. package/dist/icon/root/index.d.ts +1 -1
  117. package/dist/icon/root/index.js +1 -1
  118. package/dist/image/root/image-root.d.ts +20 -0
  119. package/dist/image/root/image-root.js +6 -1
  120. package/dist/input/root/input-root.d.ts +23 -2
  121. package/dist/input/root/input-root.js +12 -8
  122. package/dist/kbd/root/kbd-root.d.ts +20 -3
  123. package/dist/kbd/root/kbd-root.js +23 -50
  124. package/dist/legend/hidden-series.d.ts +10 -2
  125. package/dist/legend/hidden-series.js +5 -2
  126. package/dist/legend/root/legend-root.d.ts +25 -7
  127. package/dist/legend/root/legend-root.js +25 -26
  128. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  129. package/dist/lightbox/root/lightbox-root.js +76 -8
  130. package/dist/lightbox/zoom.d.ts +2 -0
  131. package/dist/lightbox/zoom.js +5 -3
  132. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  133. package/dist/line-chart/root/line-chart-root.js +10 -2
  134. package/dist/list/root/list-root.d.ts +10 -2
  135. package/dist/list/root/list-root.js +31 -24
  136. package/dist/list/selection.d.ts +17 -0
  137. package/dist/list/selection.js +16 -0
  138. package/dist/listbox/root/listbox-root.d.ts +125 -26
  139. package/dist/listbox/root/listbox-root.js +156 -166
  140. package/dist/map/marker/map-marker.d.ts +2 -1
  141. package/dist/map/root/map-root.d.ts +40 -2
  142. package/dist/map/root/map-root.js +64 -23
  143. package/dist/megamenu/hand-over.d.ts +75 -0
  144. package/dist/megamenu/hand-over.js +67 -0
  145. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  146. package/dist/megamenu/root/megamenu-root.js +29 -50
  147. package/dist/menu/item/menu-item.js +4 -4
  148. package/dist/menu/root/menu-root.d.ts +5 -2
  149. package/dist/meter/root/meter-root.d.ts +42 -0
  150. package/dist/meter/root/meter-root.js +33 -7
  151. package/dist/navigation/root/navigation-root.js +5 -8
  152. package/dist/notifications/group/notification-group.d.ts +8 -1
  153. package/dist/notifications/group/notification-group.js +12 -6
  154. package/dist/notifications/notification/notification.d.ts +12 -1
  155. package/dist/notifications/notification/notification.js +3 -1
  156. package/dist/notifications/root/notifications-root.d.ts +48 -3
  157. package/dist/notifications/root/notifications-root.js +36 -6
  158. package/dist/number-input/grain.d.ts +28 -0
  159. package/dist/number-input/grain.js +14 -0
  160. package/dist/number-input/root/number-input-root.d.ts +17 -1
  161. package/dist/number-input/root/number-input-root.js +29 -18
  162. package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
  163. package/dist/object-inspector/root/object-inspector-root.js +31 -20
  164. package/dist/option/index.d.ts +1 -0
  165. package/dist/option/index.js +1 -0
  166. package/dist/option/separator/option-separator.d.ts +30 -0
  167. package/dist/option/separator/option-separator.js +21 -0
  168. package/dist/outline/root/outline-root.d.ts +12 -0
  169. package/dist/outline/root/outline-root.js +5 -19
  170. package/dist/pagination/size/pagination-size.d.ts +6 -0
  171. package/dist/pagination/size/pagination-size.js +5 -3
  172. package/dist/pin-input/code.d.ts +51 -1
  173. package/dist/pin-input/code.js +37 -0
  174. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  175. package/dist/pin-input/root/pin-input-root.js +151 -156
  176. package/dist/popover/hide-outside.js +2 -9
  177. package/dist/popover/root/popover-root.d.ts +7 -1
  178. package/dist/popover/root/popover-root.js +9 -1
  179. package/dist/progress/root/progress-root.d.ts +27 -0
  180. package/dist/progress/root/progress-root.js +25 -7
  181. package/dist/qr-code/export.d.ts +19 -0
  182. package/dist/qr-code/export.js +14 -0
  183. package/dist/qr-code/name.d.ts +11 -0
  184. package/dist/qr-code/name.js +7 -0
  185. package/dist/qr-code/root/qr-code-root.d.ts +31 -9
  186. package/dist/qr-code/root/qr-code-root.js +29 -17
  187. package/dist/radio/group/radio-group.d.ts +15 -0
  188. package/dist/radio/root/radio-root.js +2 -2
  189. package/dist/rating/root/rating-root.d.ts +22 -9
  190. package/dist/rating/root/rating-root.js +15 -39
  191. package/dist/scatter-chart/measures.d.ts +22 -0
  192. package/dist/scatter-chart/measures.js +11 -0
  193. package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
  194. package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
  195. package/dist/scroll-area/scrollbar.d.ts +0 -8
  196. package/dist/scroll-area/scrollbar.js +1 -1
  197. package/dist/select/align.d.ts +47 -0
  198. package/dist/select/align.js +7 -0
  199. package/dist/select/root/select-root.d.ts +115 -11
  200. package/dist/select/root/select-root.js +104 -20
  201. package/dist/slider/root/slider-root.d.ts +18 -1
  202. package/dist/slider/root/slider-root.js +22 -0
  203. package/dist/sparkline/readings.d.ts +30 -12
  204. package/dist/sparkline/readings.js +32 -15
  205. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  206. package/dist/sparkline/root/sparkline-root.js +60 -21
  207. package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
  208. package/dist/speed-dial/group/speed-dial-group.js +43 -0
  209. package/dist/speed-dial/index.d.ts +1 -0
  210. package/dist/speed-dial/index.js +1 -0
  211. package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
  212. package/dist/speed-dial/item/speed-dial-item.js +43 -5
  213. package/dist/speed-dial/long-press.d.ts +50 -0
  214. package/dist/speed-dial/long-press.js +48 -0
  215. package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
  216. package/dist/speed-dial/root/speed-dial-root.js +123 -6
  217. package/dist/splitter/root/splitter-root.d.ts +9 -2
  218. package/dist/splitter/root/splitter-root.js +18 -3
  219. package/dist/steps/root/steps-root.d.ts +8 -1
  220. package/dist/steps/root/steps-root.js +6 -1
  221. package/dist/steps/step/step.d.ts +1 -0
  222. package/dist/steps/step/step.js +1 -1
  223. package/dist/table/cell/table-cell.d.ts +8 -1
  224. package/dist/table/cell/table-cell.js +6 -2
  225. package/dist/table/column/table-column.d.ts +6 -0
  226. package/dist/table/column/table-column.js +5 -1
  227. package/dist/table/grid-controller.d.ts +117 -0
  228. package/dist/table/grid-controller.js +293 -0
  229. package/dist/table/root/table-root.d.ts +47 -3
  230. package/dist/table/root/table-root.js +93 -29
  231. package/dist/table/row/table-row.d.ts +36 -0
  232. package/dist/table/row/table-row.js +52 -2
  233. package/dist/tabs/root/tabs-root.d.ts +5 -3
  234. package/dist/tag/group/tag-group.d.ts +16 -4
  235. package/dist/tag/group/tag-group.js +23 -20
  236. package/dist/textarea/root/textarea-root.d.ts +14 -2
  237. package/dist/textarea/root/textarea-root.js +6 -7
  238. package/dist/time-input/root/time-input-root.d.ts +5 -1
  239. package/dist/time-input/root/time-input-root.js +10 -7
  240. package/dist/time-picker/root/time-picker-root.d.ts +12 -14
  241. package/dist/time-picker/root/time-picker-root.js +18 -23
  242. package/dist/toast/item/toast-item.d.ts +9 -6
  243. package/dist/toast/item/toast-item.js +1 -1
  244. package/dist/toast/root/toast-root.d.ts +40 -4
  245. package/dist/toast/root/toast-root.js +68 -16
  246. package/dist/toast/words.d.ts +12 -0
  247. package/dist/toast/words.js +25 -0
  248. package/dist/toggle/group/toggle-group.d.ts +29 -5
  249. package/dist/toggle/group/toggle-group.js +26 -43
  250. package/dist/toggle/root/toggle-root.js +2 -4
  251. package/dist/toolbar/root/toolbar-root.d.ts +52 -5
  252. package/dist/toolbar/root/toolbar-root.js +88 -13
  253. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  254. package/dist/tooltip/root/tooltip-root.js +10 -2
  255. package/dist/tour/root/tour-root.d.ts +15 -0
  256. package/dist/tour/root/tour-root.js +20 -1
  257. package/dist/tour/stop/tour-stop.d.ts +3 -0
  258. package/dist/tour/stop/tour-stop.js +3 -3
  259. package/dist/tree/root/tree-root.js +2 -2
  260. package/dist/trend/figure.d.ts +16 -0
  261. package/dist/trend/figure.js +8 -0
  262. package/dist/trend/root/trend-root.d.ts +41 -2
  263. package/dist/trend/root/trend-root.js +29 -3
  264. package/dist/video/root/extra-controls.d.ts +12 -0
  265. package/dist/video/root/extra-controls.js +6 -2
  266. package/dist/video/root/video-root.d.ts +16 -1
  267. package/dist/video/root/video-root.js +15 -1
  268. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  269. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  270. package/dist/virtual-list/fill.d.ts +11 -0
  271. package/dist/virtual-list/fill.js +9 -0
  272. package/dist/virtual-list/keys.d.ts +16 -7
  273. package/dist/virtual-list/keys.js +17 -6
  274. package/dist/virtual-list/plan.d.ts +17 -1
  275. package/dist/virtual-list/plan.js +13 -2
  276. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  277. package/dist/virtual-list/root/virtual-list-root.js +53 -41
  278. package/lint.json +1 -1
  279. package/package.json +5 -5
  280. package/types/jsx.d.ts +4934 -954
  281. package/types/svelte.d.ts +2 -0
  282. package/types/vue.d.ts +946 -253
  283. package/dist/color-picker/swatches.d.ts +0 -12
  284. package/dist/color-picker/swatches.js +0 -26
  285. package/dist/rating/steps.d.ts +0 -7
  286. package/dist/rating/steps.js +0 -9
  287. package/dist/tooltip/focus-target.d.ts +0 -6
  288. package/dist/tooltip/focus-target.js +0 -9
@@ -31,7 +31,9 @@ declare const HelixHeadlessSteps_base: (new (...args: any[]) => import("@fusion.
31
31
  * its stages that are `complete`. The `progress` part carries it as a
32
32
  * `progressbar` and as `--steps-progress`, and is hidden until a stylesheet
33
33
  * gives it a `display`, so a bar of your own costs nothing until you draw it.
34
- * The sequence is `:state(complete)` once every stage is.
34
+ * A screen reader hears it as `progress-label` says, "33% complete" unless
35
+ * set, as Ark UI's steps write it. The sequence is `:state(complete)` once
36
+ * every stage is.
35
37
  *
36
38
  * The sequence is a list named by `label`, and each step a list item. The
37
39
  * current stage's button says `aria-current="step"`, and a finished stage's
@@ -82,6 +84,11 @@ export declare class HelixHeadlessSteps extends HelixHeadlessSteps_base {
82
84
  * catches people out.
83
85
  */
84
86
  orientation?: 'vertical';
87
+ /**
88
+ * What the `progress` part says to a screen reader, with `{percent}` filled
89
+ * in with `progress`.
90
+ */
91
+ progressLabel: string;
85
92
  /**
86
93
  * A function that answers whether a stage is valid, asked about the stage a
87
94
  * reader is on before they move forward from it. Return `false` to keep them
@@ -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 { customElement, HelixElement, hostAria, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { customElement, fillTemplate, HelixElement, hostAria, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { canReach, progressOf } from '../reach.js';
@@ -13,6 +13,7 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
13
13
  super(...arguments);
14
14
  this.label = 'Steps';
15
15
  this.linear = false;
16
+ this.progressLabel = '{percent}% complete';
16
17
  this.handleSelection = (event) => {
17
18
  if (event.defaultPrevented || !this.steps.includes(event.target)) {
18
19
  return;
@@ -140,6 +141,7 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
140
141
  aria-valuemin="0"
141
142
  aria-valuemax="100"
142
143
  aria-valuenow=${progress}
144
+ aria-valuetext=${fillTemplate(this.progressLabel, { percent: String(progress) })}
143
145
  style="--steps-progress: ${progress}%"
144
146
  hidden
145
147
  ></div>`;
@@ -154,6 +156,9 @@ __decorate([
154
156
  __decorate([
155
157
  property({ reflect: true })
156
158
  ], HelixHeadlessSteps.prototype, "orientation", void 0);
159
+ __decorate([
160
+ property({ attribute: 'progress-label' })
161
+ ], HelixHeadlessSteps.prototype, "progressLabel", void 0);
157
162
  __decorate([
158
163
  property({ attribute: false })
159
164
  ], HelixHeadlessSteps.prototype, "validate", void 0);
@@ -45,6 +45,7 @@ import '../../button/index.js';
45
45
  * @csspart label - The step's name, which is a control.
46
46
  * @csspart label-button - The button inside the label.
47
47
  * @csspart label-live - The live region inside that button, rendered only from the first time the button is pending.
48
+ * @csspart label-spinner - The ring that button turns while it is pending.
48
49
  * @csspart label-text - The words on that button, trimmed to their capitals and baseline.
49
50
  * @csspart live - The live region that says a stage was completed, rendered from the first time one is.
50
51
  * @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
@@ -53,7 +53,7 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
53
53
  renderLabel() {
54
54
  return html `<${this.tag('button')}
55
55
  part="label"
56
- exportparts="button: label-button, live: label-live, text: label-text"
56
+ exportparts="button: label-button, live: label-live, spinner: label-spinner, text: label-text"
57
57
  emphasis="ghost"
58
58
  aria-current=${this.current ? 'step' : nothing}
59
59
  aria-describedby=${this.complete ? 'state' : nothing}
@@ -14,7 +14,9 @@ import { type PropertyValues, type TemplateResult } from 'lit';
14
14
  * table with no `TableColumn` heads its columns with.
15
15
  *
16
16
  * The role is on the host so the cell stays a child of its row in the flat
17
- * tree, which keeps the table structure intact.
17
+ * tree, which keeps the table structure intact. In a `grid` table a value is
18
+ * a `gridcell`, and the table gives the cell a `tabindex` so focus can rest on
19
+ * it.
18
20
  *
19
21
  * @since 0.1.0
20
22
  * @status stable
@@ -33,6 +35,11 @@ export declare class HelixHeadlessTableCell extends HelixElement {
33
35
  * column in a row of headers alone.
34
36
  */
35
37
  header: boolean;
38
+ /**
39
+ * @internal Whether the cell is a cell of a `grid` table, which moves focus
40
+ * between its cells, written by that table. Not a consumer's to set.
41
+ */
42
+ gridCell: boolean;
36
43
  /**
37
44
  * @internal Read by the row and by the cells beside it, to tell a header
38
45
  * cell from a value. Not a consumer's to read or set.
@@ -6,11 +6,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
- import { property } from 'lit/decorators.js';
9
+ import { property, state } from 'lit/decorators.js';
10
10
  let HelixHeadlessTableCell = class HelixHeadlessTableCell extends HelixElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.header = false;
14
+ this.gridCell = false;
14
15
  this.isTableCell = true;
15
16
  this.handleSlotChange = () => {
16
17
  const text = [...this.childNodes].some((node) => node.nodeType === Node.TEXT_NODE && (node.textContent ?? '').trim() !== '');
@@ -27,7 +28,7 @@ let HelixHeadlessTableCell = class HelixHeadlessTableCell extends HelixElement {
27
28
  willUpdate(changed) {
28
29
  super.willUpdate(changed);
29
30
  const header = this.headsRow ? 'rowheader' : 'columnheader';
30
- hostAria(this.internals, { role: this.header ? header : 'cell' });
31
+ hostAria(this.internals, { role: this.header ? header : this.gridCell ? 'gridcell' : 'cell' });
31
32
  }
32
33
  updated(changed) {
33
34
  super.updated(changed);
@@ -47,6 +48,9 @@ let HelixHeadlessTableCell = class HelixHeadlessTableCell extends HelixElement {
47
48
  __decorate([
48
49
  property({ reflect: true, type: Boolean })
49
50
  ], HelixHeadlessTableCell.prototype, "header", void 0);
51
+ __decorate([
52
+ state()
53
+ ], HelixHeadlessTableCell.prototype, "gridCell", void 0);
50
54
  HelixHeadlessTableCell = __decorate([
51
55
  customElement('helix-headless-table-cell')
52
56
  ], HelixHeadlessTableCell);
@@ -271,6 +271,12 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
271
271
  * table that sets `gridCell`. Not a consumer's to set.
272
272
  */
273
273
  tabStop: boolean;
274
+ /**
275
+ * @internal The sort said in words on the sort button, written by the table
276
+ * on Android, where TalkBack reads no `aria-sort`. Empty elsewhere. Not a
277
+ * consumer's to set: the table's `sorted-label` holds the words.
278
+ */
279
+ sortWords: string;
274
280
  /** How wide the heading drew, for the separator to report. */
275
281
  private drawn;
276
282
  /** Where a drag of the separator started, while one is running. */
@@ -30,6 +30,7 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
30
30
  this.movable = false;
31
31
  this.gridCell = false;
32
32
  this.tabStop = false;
33
+ this.sortWords = '';
33
34
  this.drawn = 0;
34
35
  this.handleResizeStart = (event) => {
35
36
  if (event.button !== 0) {
@@ -184,7 +185,7 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
184
185
  </svg>
185
186
  </button>`
186
187
  : nothing}${this.canSort
187
- ? html `<button part="sort" type="button" tabindex=${control}><slot></slot></button>`
188
+ ? html `<button part="sort" type="button" tabindex=${control} aria-description=${this.sortWords || nothing}><slot></slot></button>`
188
189
  : html `<slot></slot>`}${this.resizable
189
190
  ? html `<span
190
191
  part="resizer"
@@ -250,6 +251,9 @@ __decorate([
250
251
  __decorate([
251
252
  state()
252
253
  ], HelixHeadlessTableColumn.prototype, "tabStop", void 0);
254
+ __decorate([
255
+ state()
256
+ ], HelixHeadlessTableColumn.prototype, "sortWords", void 0);
253
257
  __decorate([
254
258
  state()
255
259
  ], HelixHeadlessTableColumn.prototype, "drawn", void 0);
@@ -0,0 +1,117 @@
1
+ import { type GridPlace } from '@fusion.dev/helix-core';
2
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
3
+ import type { HelixHeadlessTableColumn } from './column/table-column.js';
4
+ /** A place in the grid with the element that holds focus there. */
5
+ export interface GridCell extends GridPlace {
6
+ cell: HTMLElement;
7
+ }
8
+ export interface TableGridOptions {
9
+ /**
10
+ * Acts on a cell for Enter, Space or F2, and says whether it did. A key it
11
+ * leaves alone moves into the cell's controls, Enter and F2 only.
12
+ */
13
+ activate: (place: GridCell, event: KeyboardEvent) => boolean;
14
+ /** The headings that are drawn, in order. */
15
+ columns: () => HelixHeadlessTableColumn[];
16
+ /** The element in the table's own shadow root holding a part of that name. */
17
+ part: (name: string) => HTMLElement | null;
18
+ /** The rows in the order they are drawn. */
19
+ rows: () => Element[];
20
+ /** Selects every row for Control or Command with A, and says whether it did. */
21
+ selectAll: () => boolean;
22
+ /** Whether a checkbox column leads. */
23
+ selectable: () => boolean;
24
+ /** Whether the table is a grid now. */
25
+ on: () => boolean;
26
+ }
27
+ /**
28
+ * The keyboard of a `grid` table: one tab stop among its cells, the arrow
29
+ * keys, Home, End and the Page keys between them, and Enter or F2 into a
30
+ * cell's controls.
31
+ *
32
+ * **Tab leaves the grid.** The controls in a cell are the consumer's, so their
33
+ * tab order is left as written: Tab on a cell, or past the last control of a
34
+ * cell, focuses an empty box at the grid's end (Shift: its start) and lets the
35
+ * key go on from there, as React Aria's collections do. A control in a cell
36
+ * that focus reaches from outside by the keyboard hands it to the stop, so the
37
+ * grid is one stop from either side. A press, or a script focusing a cell, is
38
+ * left where it lands, and the stop follows it.
39
+ */
40
+ export declare class TableGridController implements ReactiveController {
41
+ private readonly host;
42
+ private readonly options;
43
+ /** The row holding the stop, `head` for the headings, or nothing for the first row. */
44
+ private stopRow;
45
+ /** The column holding the stop. */
46
+ private stopColumn;
47
+ /** Where the stop's row was drawn when last marked, for the row that takes over when it goes. */
48
+ private stopIndex;
49
+ /** The row focus is in, while it is in the grid's rows. */
50
+ private focusRow;
51
+ /** Whether the next update focuses the stop, after a key moved it. */
52
+ private focusWanted;
53
+ /** Whether focus is arriving from a press, which keeps its place. */
54
+ private pointing;
55
+ /** The cells given a `tabindex`, so a table that stops being a grid takes it back. */
56
+ private readonly given;
57
+ constructor(host: ReactiveControllerHost & HTMLElement, options: TableGridOptions);
58
+ hostConnected(): void;
59
+ hostDisconnected(): void;
60
+ /**
61
+ * A row taken away while it held the stop hands it to the row drawn in its
62
+ * place, or to the row before where it was the last, at the same column.
63
+ * Where focus was in that row and went with it, focus follows the stop, as
64
+ * React Aria's collections move it to a neighbor; focus that had already
65
+ * left the grid is left where it is. Before the render, so the cells the
66
+ * table draws itself are drawn with the stop where it now is.
67
+ */
68
+ hostUpdate(): void;
69
+ /** How many columns lead the consumer's cells: the checkbox column, where there is one. */
70
+ private get offset();
71
+ /** The first row: the headings where there are any, and the first row of cells otherwise. */
72
+ private get top();
73
+ /** A row's cells that are drawn, in order. */
74
+ private cellsOf;
75
+ /** How many columns a row has. */
76
+ private widthOf;
77
+ /** The element that takes focus at a place, or nothing where there is none. */
78
+ cellAt({ column, row }: GridPlace): HTMLElement | null;
79
+ /** The place holding the stop now, held to the grid as it is. */
80
+ current(): GridPlace;
81
+ /** Whether the stop is at a place, for a cell the table draws itself. */
82
+ isStop(place: GridPlace): boolean;
83
+ /** The place an event came from or through, with the element that holds focus there. */
84
+ private placeOf;
85
+ /** Moves the stop to a place, and focus with it on the next update. */
86
+ private moveTo;
87
+ /**
88
+ * Writes the stops: a `tabindex` on every cell, `0` on the one holding the
89
+ * stop, and the grid's state on the rows and headings. Takes it all back
90
+ * once the table stops being a grid. Called by the table after each update.
91
+ */
92
+ mark(): void;
93
+ /** Focuses the stop where a key asked for it. Called by the table after `mark`. */
94
+ place(): void;
95
+ /** The controls in a cell, in order: what Enter and F2 move into, and Tab moves between. */
96
+ private controlsIn;
97
+ /**
98
+ * Hands focus to the empty box at the grid's end, or its start, so the Tab
99
+ * under way goes on from there and out of the grid.
100
+ */
101
+ private leave;
102
+ /** How many rows a Page key moves from a cell. */
103
+ private pageFrom;
104
+ private readonly handleKeydown;
105
+ /** The keys the grid takes while focus is on a control inside a cell. */
106
+ private handleControlKey;
107
+ /**
108
+ * Focus arriving on a cell, or inside one. From outside the grid by the
109
+ * keyboard, anywhere but the stop is handed to the stop; otherwise the stop
110
+ * moves to where focus went.
111
+ */
112
+ private readonly handleFocusIn;
113
+ /** Focus leaving for somewhere outside the grid's host is no longer in a row. */
114
+ private readonly handleFocusOut;
115
+ /** A press is under way, so the focus it brings stays where it lands. */
116
+ private readonly handlePointerDown;
117
+ }
@@ -0,0 +1,293 @@
1
+ import { deepActiveElement, deepContains, focusableElements, gridMove, inlineStep, pageRows, scrollingAncestor, scrollRoom, selectsAll, whenHydrated, } from '@fusion.dev/helix-core';
2
+ const shown = (element) => {
3
+ const hidden = element.getAttribute('hidden');
4
+ return hidden === null || hidden === 'until-found';
5
+ };
6
+ export class TableGridController {
7
+ constructor(host, options) {
8
+ this.stopRow = undefined;
9
+ this.stopColumn = 0;
10
+ this.stopIndex = 0;
11
+ this.focusRow = undefined;
12
+ this.focusWanted = false;
13
+ this.pointing = false;
14
+ this.given = new Set();
15
+ this.handleKeydown = (event) => {
16
+ if (!this.options.on() || event.defaultPrevented || event.altKey) {
17
+ return;
18
+ }
19
+ const place = this.placeOf(event);
20
+ if (!place) {
21
+ return;
22
+ }
23
+ if (event.composedPath()[0] !== place.cell) {
24
+ this.handleControlKey(event, place);
25
+ return;
26
+ }
27
+ if (event.key === 'Tab') {
28
+ this.leave(event.shiftKey);
29
+ return;
30
+ }
31
+ if (selectsAll(event) && !event.shiftKey) {
32
+ if (this.options.selectAll()) {
33
+ event.preventDefault();
34
+ }
35
+ return;
36
+ }
37
+ if (event.key === 'Enter' || event.key === ' ' || event.key === 'F2') {
38
+ if (event.key !== 'F2' && this.options.activate(place, event)) {
39
+ event.preventDefault();
40
+ return;
41
+ }
42
+ const first = event.key === ' ' ? undefined : this.controlsIn(place)[0];
43
+ if (first) {
44
+ event.preventDefault();
45
+ first.focus();
46
+ }
47
+ return;
48
+ }
49
+ const to = gridMove(event.key, place, { last: this.options.rows().length - 1, top: this.top, width: this.widthOf(place.row) }, {
50
+ control: event.ctrlKey || event.metaKey,
51
+ page: event.key.startsWith('Page') ? this.pageFrom(place.cell) : 1,
52
+ step: inlineStep(this.host, event.key),
53
+ });
54
+ if (!to) {
55
+ return;
56
+ }
57
+ event.preventDefault();
58
+ to.column = Math.max(0, Math.min(to.column, this.widthOf(to.row) - 1));
59
+ if (to.row !== place.row || to.column !== place.column) {
60
+ this.moveTo(to);
61
+ }
62
+ };
63
+ this.handleFocusIn = (event) => {
64
+ if (!this.options.on()) {
65
+ return;
66
+ }
67
+ const place = this.placeOf(event);
68
+ if (!place) {
69
+ return;
70
+ }
71
+ const from = event.relatedTarget;
72
+ const entering = !(from instanceof Node && deepContains(this.host, from));
73
+ if (entering && !this.pointing && event.composedPath()[0] !== place.cell) {
74
+ const stop = this.cellAt(this.current());
75
+ if (stop) {
76
+ stop.focus();
77
+ return;
78
+ }
79
+ }
80
+ this.focusRow = place.row === -1 ? undefined : this.options.rows()[place.row];
81
+ const at = this.current();
82
+ if (at.row !== place.row || at.column !== place.column) {
83
+ this.moveTo(place, false);
84
+ }
85
+ };
86
+ this.handleFocusOut = (event) => {
87
+ const to = event.relatedTarget;
88
+ if (to instanceof Node && !deepContains(this.host, to)) {
89
+ this.focusRow = undefined;
90
+ }
91
+ };
92
+ this.handlePointerDown = () => {
93
+ this.pointing = true;
94
+ setTimeout(() => {
95
+ this.pointing = false;
96
+ });
97
+ };
98
+ this.host = host;
99
+ this.options = options;
100
+ host.addController(this);
101
+ }
102
+ hostConnected() {
103
+ this.host.addEventListener('keydown', this.handleKeydown);
104
+ this.host.addEventListener('focusin', this.handleFocusIn);
105
+ this.host.addEventListener('focusout', this.handleFocusOut);
106
+ this.host.addEventListener('pointerdown', this.handlePointerDown);
107
+ }
108
+ hostDisconnected() {
109
+ this.host.removeEventListener('keydown', this.handleKeydown);
110
+ this.host.removeEventListener('focusin', this.handleFocusIn);
111
+ this.host.removeEventListener('focusout', this.handleFocusOut);
112
+ this.host.removeEventListener('pointerdown', this.handlePointerDown);
113
+ }
114
+ hostUpdate() {
115
+ const gone = this.stopRow;
116
+ const rows = this.options.rows();
117
+ if (!(gone instanceof Element) || rows.includes(gone)) {
118
+ return;
119
+ }
120
+ this.stopRow = rows[Math.min(this.stopIndex, rows.length - 1)];
121
+ const active = deepActiveElement();
122
+ if (this.focusRow === gone && (!active || active === document.body)) {
123
+ this.focusWanted = true;
124
+ }
125
+ this.focusRow = undefined;
126
+ }
127
+ get offset() {
128
+ return this.options.selectable() ? 1 : 0;
129
+ }
130
+ get top() {
131
+ return this.options.columns().length > 0 || this.options.selectable() ? -1 : 0;
132
+ }
133
+ cellsOf(row) {
134
+ return [...(row?.children ?? [])].filter(shown);
135
+ }
136
+ widthOf(row) {
137
+ const own = row === -1 ? this.options.columns().length : this.cellsOf(this.options.rows()[row]).length;
138
+ return this.offset + own;
139
+ }
140
+ cellAt({ column, row }) {
141
+ const lead = column < this.offset;
142
+ if (row === -1) {
143
+ return lead
144
+ ? this.options.part('select-all')
145
+ : (this.options.columns()[column - this.offset]?.cellBox ?? null);
146
+ }
147
+ const line = this.options.rows()[row];
148
+ if (lead) {
149
+ return line?.shadowRoot?.querySelector('[part~="select"]') ?? null;
150
+ }
151
+ return this.cellsOf(line)[column - this.offset] ?? null;
152
+ }
153
+ current() {
154
+ const found = this.stopRow === undefined || this.stopRow === 'head'
155
+ ? -1
156
+ : this.options.rows().indexOf(this.stopRow);
157
+ const row = this.stopRow === 'head' || found < 0 ? this.top : found;
158
+ const width = this.widthOf(row);
159
+ return { column: Math.max(0, Math.min(this.stopColumn, width - 1)), row };
160
+ }
161
+ isStop(place) {
162
+ const at = this.current();
163
+ return this.options.on() && at.row === place.row && at.column === place.column;
164
+ }
165
+ placeOf(event) {
166
+ const columns = this.options.columns();
167
+ const rows = this.options.rows();
168
+ for (const node of event.composedPath()) {
169
+ if (node === this.host) {
170
+ return undefined;
171
+ }
172
+ if (!(node instanceof HTMLElement)) {
173
+ continue;
174
+ }
175
+ const heading = columns.indexOf(node);
176
+ if (heading >= 0) {
177
+ const cell = node.cellBox;
178
+ return cell ? { cell, column: heading + this.offset, row: -1 } : undefined;
179
+ }
180
+ const part = node.getAttribute('part') ?? '';
181
+ if (part === 'select-all' && node.getRootNode() === this.host.shadowRoot) {
182
+ return { cell: node, column: 0, row: -1 };
183
+ }
184
+ const root = node.getRootNode();
185
+ if (part.split(' ').includes('select') && rows.includes(root.host)) {
186
+ return { cell: node, column: 0, row: rows.indexOf(root.host) };
187
+ }
188
+ const parent = node.parentElement;
189
+ if (parent && rows.includes(parent) && shown(node)) {
190
+ const column = this.cellsOf(parent).indexOf(node);
191
+ return { cell: node, column: column + this.offset, row: rows.indexOf(parent) };
192
+ }
193
+ }
194
+ return undefined;
195
+ }
196
+ moveTo(place, focus = true) {
197
+ this.stopRow = place.row === -1 ? 'head' : this.options.rows()[place.row];
198
+ this.stopColumn = place.column;
199
+ this.focusWanted = focus;
200
+ this.host.requestUpdate();
201
+ }
202
+ mark() {
203
+ const on = this.options.on();
204
+ const at = this.current();
205
+ this.stopIndex = Math.max(0, at.row);
206
+ const columns = this.options.columns();
207
+ for (const [index, column] of columns.entries()) {
208
+ column.gridCell = on;
209
+ column.tabStop = on && at.row === -1 && at.column === index + this.offset;
210
+ }
211
+ for (const [index, line] of this.options.rows().entries()) {
212
+ const row = line;
213
+ if (row.isTableRow) {
214
+ whenHydrated(row, () => {
215
+ row.gridCell = on;
216
+ row.selectStop = on && at.row === index && at.column === 0 && this.offset === 1;
217
+ });
218
+ }
219
+ for (const [place, cell] of this.cellsOf(line).entries()) {
220
+ if ('isTableCell' in cell) {
221
+ ;
222
+ cell.gridCell = on;
223
+ }
224
+ if (!on) {
225
+ continue;
226
+ }
227
+ const stop = at.row === index && at.column === place + this.offset ? 0 : -1;
228
+ if (cell.tabIndex !== stop || !cell.hasAttribute('tabindex')) {
229
+ cell.tabIndex = stop;
230
+ }
231
+ this.given.add(cell);
232
+ }
233
+ }
234
+ for (const cell of this.given) {
235
+ if (!on || !cell.isConnected) {
236
+ if (!on) {
237
+ cell.removeAttribute('tabindex');
238
+ }
239
+ this.given.delete(cell);
240
+ }
241
+ }
242
+ }
243
+ place() {
244
+ if (!this.focusWanted || !this.options.on()) {
245
+ return;
246
+ }
247
+ this.focusWanted = false;
248
+ this.cellAt(this.current())?.focus();
249
+ }
250
+ controlsIn(place) {
251
+ if (place.row === -1) {
252
+ return place.column < this.offset
253
+ ? []
254
+ : (this.options.columns()[place.column - this.offset]?.controls ?? []);
255
+ }
256
+ return place.column < this.offset ? [] : focusableElements(place.cell);
257
+ }
258
+ leave(back) {
259
+ const edge = this.options.part(back ? 'grid-start' : 'grid-end');
260
+ if (!edge) {
261
+ return;
262
+ }
263
+ edge.tabIndex = 0;
264
+ edge.addEventListener('focusout', () => {
265
+ edge.tabIndex = -1;
266
+ }, { once: true });
267
+ edge.focus({ preventScroll: true });
268
+ }
269
+ pageFrom(cell) {
270
+ const room = scrollRoom(scrollingAncestor(cell, { axis: 'y', overflowing: true }));
271
+ return pageRows(room, cell.getBoundingClientRect().height);
272
+ }
273
+ handleControlKey(event, place) {
274
+ if (event.key === 'Escape' || event.key === 'F2') {
275
+ event.preventDefault();
276
+ place.cell.focus();
277
+ return;
278
+ }
279
+ if (event.key !== 'Tab') {
280
+ return;
281
+ }
282
+ const origin = event.composedPath()[0];
283
+ const controls = this.controlsIn(place);
284
+ const at = controls.findIndex((one) => deepContains(one, origin));
285
+ const next = at >= 0 ? controls[at + (event.shiftKey ? -1 : 1)] : undefined;
286
+ if (next) {
287
+ event.preventDefault();
288
+ next.focus();
289
+ return;
290
+ }
291
+ this.leave(event.shiftKey);
292
+ }
293
+ }
@@ -50,9 +50,28 @@ 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
+ * **A grid.** `grid` makes the table one tab stop that the arrow keys move
57
+ * through cell by cell, the headings included, as React Aria's table is. The
58
+ * table is then a `grid` and each value a `gridcell`, and the table gives
59
+ * every cell a `tabindex` so focus can rest on it: set `grid` only where the
60
+ * cells may carry one. For typeahead and range selection, use `DataTable`.
61
+ *
62
+ * | Key | What it does |
63
+ * |---|---|
64
+ * | Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. |
65
+ * | Down, Up | Moves one row, the headings included. |
66
+ * | Home, End | Moves to the first or the last cell of the row. |
67
+ * | Control with Home or End | Moves to the first or the last cell of the table. |
68
+ * | Page Down, Page Up | Moves by the rows that fit in view. |
69
+ * | 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. |
70
+ * | Enter on a cell of a row with `href` | Follows the row's link. |
71
+ * | Enter, Space on a sortable heading | Sorts by the column. |
72
+ * | Space on a row, Enter or Space on its checkbox cell | Selects the row, in a `selectable` table. |
73
+ * | Control or Command with A | Selects every row, in a `selectable` table. |
74
+ * | Tab | Leaves the table. |
56
75
  *
57
76
  * The CSS custom properties listed for this component are written by it and
58
77
  * read by the stylesheet that draws it. Do not set them. Each holds a number
@@ -85,6 +104,8 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
85
104
  * @csspart checkbox-mark-dash - Added to `checkbox-mark` while it draws the dash, which it keeps until its box is checked.
86
105
  * @csspart checkbox-mark-indeterminate - Added to `checkbox-mark` while only some rows are selected.
87
106
  * @csspart empty - The text shown when there are no rows.
107
+ * @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.
108
+ * @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.
88
109
  * @csspart head - The row that holds the column headings. It has `display: contents`, so it takes no space of its own.
89
110
  * @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.
90
111
  * @csspart loading - The text shown while the rows are loading.
@@ -138,6 +159,16 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
138
159
  defaultSort: string;
139
160
  /** The word for a descending sort, in `sorted-label`. */
140
161
  descendingLabel: string;
162
+ /**
163
+ * Makes the table a grid: one tab stop, and the arrow keys, Home, End and the
164
+ * Page keys move focus between its cells, the headings included. Enter moves
165
+ * into a cell's controls, and Tab leaves the table.
166
+ *
167
+ * Off by default, where the table is a static `table` and Tab reaches each
168
+ * link and control in it. On, the table writes a `tabindex` onto each of its
169
+ * cells, which is the one way a cell of your markup can take focus.
170
+ */
171
+ grid: boolean;
141
172
  /**
142
173
  * Accessible name for the table.
143
174
  *
@@ -202,6 +233,8 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
202
233
  * itself kept its default name.
203
234
  */
204
235
  protected readonly aria: AriaForwardController;
236
+ /** The keyboard of a `grid` table, in `grid-controller.ts`. */
237
+ private readonly gridKeys;
205
238
  /**
206
239
  * Asks for a different order, and reports whether the request stood.
207
240
  */
@@ -248,6 +281,17 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
248
281
  * left alone.
249
282
  */
250
283
  private readonly handleToggle;
284
+ /** Every row's key, in the order the rows are written. */
285
+ private get everyKey();
286
+ /** The checkbox in the heading: every row, or none where every row is chosen. */
287
+ private chooseAll;
288
+ /** One row's checkbox, ticked or not. */
289
+ private chooseRow;
290
+ /**
291
+ * Enter, Space or F2 on a cell of a `grid` table, and whether it did
292
+ * anything. Left alone, Enter and F2 move into the cell's controls.
293
+ */
294
+ private activate;
251
295
  /**
252
296
  * Tells each row whether it is selected and what its checkbox is called.
253
297
  *