@fusion.dev/helix-headless 0.143.0 → 0.145.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 (314) hide show
  1. package/custom-elements.json +16990 -1383
  2. package/dist/accordion/item/accordion-item.d.ts +48 -12
  3. package/dist/accordion/item/accordion-item.js +26 -5
  4. package/dist/accordion/root/accordion-root.d.ts +6 -0
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +21 -1
  7. package/dist/announcement/root/announcement-root.js +36 -1
  8. package/dist/app-header/root/app-header-root.d.ts +7 -0
  9. package/dist/app-header/root/app-header-root.js +5 -1
  10. package/dist/app-header/sectioning.d.ts +7 -0
  11. package/dist/app-header/sectioning.js +26 -0
  12. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  13. package/dist/area-chart/root/area-chart-root.js +24 -7
  14. package/dist/avatar/root/avatar-root.d.ts +14 -0
  15. package/dist/avatar/root/avatar-root.js +23 -9
  16. package/dist/badge/root/badge-root.d.ts +11 -7
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
  19. package/dist/bar-chart/root/bar-chart-root.js +17 -10
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
  22. package/dist/button/root/button-root.d.ts +47 -1
  23. package/dist/button/root/button-root.js +38 -4
  24. package/dist/callout/root/callout-root.d.ts +18 -1
  25. package/dist/callout/root/callout-root.js +15 -4
  26. package/dist/canvas/root/canvas-root.d.ts +38 -3
  27. package/dist/canvas/root/canvas-root.js +121 -40
  28. package/dist/card/root/card-root.d.ts +30 -1
  29. package/dist/card/root/card-root.js +38 -5
  30. package/dist/carousel/root/carousel-root.d.ts +90 -0
  31. package/dist/carousel/root/carousel-root.js +134 -12
  32. package/dist/chat/composer/chat-composer.d.ts +38 -6
  33. package/dist/chat/composer/chat-composer.js +42 -9
  34. package/dist/chat/message/chat-message.d.ts +32 -1
  35. package/dist/chat/message/chat-message.js +25 -9
  36. package/dist/chat/naming.d.ts +22 -0
  37. package/dist/chat/naming.js +12 -0
  38. package/dist/chat/relative-clock.d.ts +39 -0
  39. package/dist/chat/relative-clock.js +31 -0
  40. package/dist/chat/root/chat-root.d.ts +36 -0
  41. package/dist/chat/root/chat-root.js +24 -1
  42. package/dist/checkbox/root/checkbox-root.js +2 -0
  43. package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
  44. package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
  45. package/dist/code-block/lines.d.ts +13 -0
  46. package/dist/code-block/lines.js +2 -0
  47. package/dist/code-block/root/code-block-root.d.ts +38 -1
  48. package/dist/code-block/root/code-block-root.js +28 -7
  49. package/dist/color-input/root/color-input-root.d.ts +34 -1
  50. package/dist/color-input/root/color-input-root.js +23 -4
  51. package/dist/color-picker/channels.d.ts +26 -0
  52. package/dist/color-picker/channels.js +84 -0
  53. package/dist/color-picker/root/color-picker-root.d.ts +81 -5
  54. package/dist/color-picker/root/color-picker-root.js +103 -10
  55. package/dist/combobox/root/combobox-root.d.ts +38 -3
  56. package/dist/combobox/root/combobox-root.js +64 -2
  57. package/dist/command/root/command-root.d.ts +30 -4
  58. package/dist/command/root/command-root.js +33 -3
  59. package/dist/copy-button/from.d.ts +22 -0
  60. package/dist/copy-button/from.js +28 -0
  61. package/dist/copy-button/root/copy-button-root.d.ts +47 -1
  62. package/dist/copy-button/root/copy-button-root.js +44 -8
  63. package/dist/data-table/root/data-table-root.d.ts +150 -2
  64. package/dist/data-table/root/data-table-root.js +303 -29
  65. package/dist/data-table/tree.d.ts +40 -0
  66. package/dist/data-table/tree.js +55 -0
  67. package/dist/date-input/root/date-input-root.d.ts +73 -4
  68. package/dist/date-input/root/date-input-root.js +93 -43
  69. package/dist/date-picker/root/date-picker-root.d.ts +145 -1
  70. package/dist/date-picker/root/date-picker-root.js +239 -48
  71. package/dist/description-list/item/description-list-item.d.ts +17 -2
  72. package/dist/description-list/item/description-list-item.js +15 -2
  73. package/dist/description-list/root/description-list-root.d.ts +27 -1
  74. package/dist/description-list/root/description-list-root.js +26 -1
  75. package/dist/dialog/description.d.ts +9 -0
  76. package/dist/dialog/description.js +14 -0
  77. package/dist/dialog/root/dialog-root.d.ts +64 -1
  78. package/dist/dialog/root/dialog-root.js +49 -23
  79. package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
  80. package/dist/donut-chart/root/donut-chart-root.js +21 -6
  81. package/dist/drawer/root/drawer-root.d.ts +63 -2
  82. package/dist/drawer/root/drawer-root.js +95 -19
  83. package/dist/drawer/swipe-start.d.ts +9 -0
  84. package/dist/drawer/swipe-start.js +12 -0
  85. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  86. package/dist/drilldown/item/drilldown-item.js +8 -5
  87. package/dist/drilldown/root/drilldown-root.d.ts +11 -0
  88. package/dist/drilldown/root/drilldown-root.js +8 -3
  89. package/dist/element-events.generated.js +61 -13
  90. package/dist/empty/root/empty-root.d.ts +1 -1
  91. package/dist/file-input/root/file-input-root.d.ts +47 -0
  92. package/dist/file-input/root/file-input-root.js +60 -22
  93. package/dist/file-input/screen.d.ts +35 -0
  94. package/dist/file-input/screen.js +49 -0
  95. package/dist/filter-input/menu/filter-menu.d.ts +3 -0
  96. package/dist/filter-input/menu/filter-menu.js +8 -4
  97. package/dist/filter-input/root/filter-input-root.d.ts +38 -4
  98. package/dist/filter-input/root/filter-input-root.js +67 -3
  99. package/dist/filter-input/suggest.d.ts +17 -0
  100. package/dist/filter-input/suggest.js +23 -0
  101. package/dist/format-date/options.d.ts +33 -0
  102. package/dist/format-date/options.js +42 -0
  103. package/dist/format-date/root/format-date-root.d.ts +51 -0
  104. package/dist/format-date/root/format-date-root.js +58 -38
  105. package/dist/heatmap/root/heatmap-root.d.ts +23 -6
  106. package/dist/heatmap/root/heatmap-root.js +24 -13
  107. package/dist/icon/index.d.ts +2 -0
  108. package/dist/icon/index.js +2 -0
  109. package/dist/icon/registry.d.ts +37 -0
  110. package/dist/icon/registry.js +83 -0
  111. package/dist/icon/root/icon-root.d.ts +30 -4
  112. package/dist/icon/root/icon-root.js +41 -6
  113. package/dist/icon/root/index.d.ts +2 -0
  114. package/dist/icon/root/index.js +2 -0
  115. package/dist/icon/set.d.ts +1 -0
  116. package/dist/icon/set.js +3 -0
  117. package/dist/image/root/image-root.d.ts +14 -0
  118. package/dist/image/root/image-root.js +23 -2
  119. package/dist/input/root/input-root.d.ts +11 -0
  120. package/dist/input/root/input-root.js +16 -1
  121. package/dist/kbd/root/kbd-root.d.ts +20 -13
  122. package/dist/kbd/root/kbd-root.js +35 -37
  123. package/dist/kbd/shortcut.d.ts +18 -0
  124. package/dist/kbd/shortcut.js +35 -0
  125. package/dist/legend/hidden-series.d.ts +8 -0
  126. package/dist/legend/hidden-series.js +13 -0
  127. package/dist/legend/root/legend-root.d.ts +56 -0
  128. package/dist/legend/root/legend-root.js +54 -5
  129. package/dist/lightbox/item/lightbox-item.d.ts +15 -0
  130. package/dist/lightbox/item/lightbox-item.js +10 -1
  131. package/dist/lightbox/root/lightbox-root.d.ts +61 -1
  132. package/dist/lightbox/root/lightbox-root.js +94 -4
  133. package/dist/line-chart/root/line-chart-root.d.ts +11 -3
  134. package/dist/line-chart/root/line-chart-root.js +19 -5
  135. package/dist/list/item/list-item.d.ts +68 -1
  136. package/dist/list/item/list-item.js +66 -4
  137. package/dist/list/numbering.d.ts +14 -0
  138. package/dist/list/numbering.js +8 -0
  139. package/dist/list/root/list-root.d.ts +106 -9
  140. package/dist/list/root/list-root.js +189 -4
  141. package/dist/list/selection.d.ts +19 -0
  142. package/dist/list/selection.js +21 -0
  143. package/dist/listbox/root/listbox-root.d.ts +74 -3
  144. package/dist/listbox/root/listbox-root.js +86 -9
  145. package/dist/loader/busy.d.ts +17 -0
  146. package/dist/loader/busy.js +24 -0
  147. package/dist/loader/root/loader-root.d.ts +37 -0
  148. package/dist/loader/root/loader-root.js +52 -3
  149. package/dist/map/root/map-root.d.ts +6 -2
  150. package/dist/map/root/map-root.js +5 -2
  151. package/dist/megamenu/root/megamenu-root.d.ts +21 -0
  152. package/dist/megamenu/root/megamenu-root.js +16 -2
  153. package/dist/menu/index.d.ts +1 -0
  154. package/dist/menu/index.js +1 -0
  155. package/dist/menu/item/menu-item.d.ts +38 -11
  156. package/dist/menu/item/menu-item.js +33 -1
  157. package/dist/menu/root/menu-root.d.ts +25 -1
  158. package/dist/menu/root/menu-root.js +63 -6
  159. package/dist/menu/section/menu-section.d.ts +55 -0
  160. package/dist/menu/section/menu-section.js +60 -0
  161. package/dist/meter/root/meter-root.d.ts +7 -0
  162. package/dist/meter/root/meter-root.js +6 -3
  163. package/dist/navigation/root/navigation-root.d.ts +16 -1
  164. package/dist/navigation/root/navigation-root.js +27 -1
  165. package/dist/notifications/feed-keys.d.ts +10 -0
  166. package/dist/notifications/feed-keys.js +14 -0
  167. package/dist/notifications/notification/notification.d.ts +17 -0
  168. package/dist/notifications/notification/notification.js +21 -2
  169. package/dist/notifications/root/notifications-root.d.ts +60 -0
  170. package/dist/notifications/root/notifications-root.js +76 -1
  171. package/dist/number-input/root/number-input-root.d.ts +47 -0
  172. package/dist/number-input/root/number-input-root.js +58 -22
  173. package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
  174. package/dist/object-inspector/root/object-inspector-root.js +180 -80
  175. package/dist/object-inspector/rows.d.ts +57 -0
  176. package/dist/object-inspector/rows.js +86 -0
  177. package/dist/option/root/option-root.d.ts +54 -5
  178. package/dist/option/root/option-root.js +34 -5
  179. package/dist/outline/levels.d.ts +31 -0
  180. package/dist/outline/levels.js +23 -0
  181. package/dist/outline/root/outline-root.d.ts +68 -3
  182. package/dist/outline/root/outline-root.js +73 -8
  183. package/dist/pagination/size/pagination-size.d.ts +11 -2
  184. package/dist/pagination/size/pagination-size.js +19 -4
  185. package/dist/pin-input/format.d.ts +7 -0
  186. package/dist/pin-input/format.js +16 -0
  187. package/dist/pin-input/root/pin-input-root.d.ts +21 -0
  188. package/dist/pin-input/root/pin-input-root.js +29 -2
  189. package/dist/popover/root/popover-root.d.ts +62 -4
  190. package/dist/popover/root/popover-root.js +53 -5
  191. package/dist/progress/root/progress-root.d.ts +7 -0
  192. package/dist/progress/root/progress-root.js +9 -3
  193. package/dist/qr-code/export.d.ts +31 -0
  194. package/dist/qr-code/export.js +10 -0
  195. package/dist/qr-code/root/qr-code-root.d.ts +26 -0
  196. package/dist/qr-code/root/qr-code-root.js +49 -2
  197. package/dist/radio/group/radio-group.d.ts +17 -0
  198. package/dist/radio/group/radio-group.js +14 -1
  199. package/dist/rating/root/rating-root.d.ts +25 -0
  200. package/dist/rating/root/rating-root.js +46 -4
  201. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  202. package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
  203. package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
  204. package/dist/scroll-area/root/scroll-area-root.js +218 -3
  205. package/dist/scroll-area/scrollbar.d.ts +65 -0
  206. package/dist/scroll-area/scrollbar.js +24 -0
  207. package/dist/select/root/select-root.d.ts +24 -0
  208. package/dist/select/root/select-root.js +21 -7
  209. package/dist/skeleton/root/skeleton-root.d.ts +25 -0
  210. package/dist/skeleton/root/skeleton-root.js +17 -2
  211. package/dist/slider/root/slider-root.d.ts +39 -0
  212. package/dist/slider/root/slider-root.js +45 -9
  213. package/dist/splitter/root/splitter-root.d.ts +13 -0
  214. package/dist/splitter/root/splitter-root.js +20 -2
  215. package/dist/splitter/snap.d.ts +9 -0
  216. package/dist/splitter/snap.js +12 -0
  217. package/dist/stat/root/stat-root.d.ts +2 -0
  218. package/dist/stat/root/stat-root.js +1 -1
  219. package/dist/steps/reach.d.ts +15 -0
  220. package/dist/steps/reach.js +12 -0
  221. package/dist/steps/root/steps-root.d.ts +30 -0
  222. package/dist/steps/root/steps-root.js +53 -0
  223. package/dist/steps/step/step.d.ts +39 -2
  224. package/dist/steps/step/step.js +29 -7
  225. package/dist/switch/root/switch-root.d.ts +12 -2
  226. package/dist/switch/root/switch-root.js +6 -1
  227. package/dist/table/column/table-column.d.ts +11 -0
  228. package/dist/table/column/table-column.js +6 -1
  229. package/dist/table/root/table-root.d.ts +101 -0
  230. package/dist/table/root/table-root.js +166 -5
  231. package/dist/table/row/table-row.d.ts +47 -1
  232. package/dist/table/row/table-row.js +39 -2
  233. package/dist/tabs/panel/tab-panel.d.ts +9 -5
  234. package/dist/tabs/panel/tab-panel.js +3 -4
  235. package/dist/tabs/root/tabs-root.d.ts +25 -1
  236. package/dist/tabs/root/tabs-root.js +21 -3
  237. package/dist/tabs/tab/tab.d.ts +36 -4
  238. package/dist/tabs/tab/tab.js +46 -3
  239. package/dist/tag/group/tag-group.d.ts +107 -0
  240. package/dist/tag/group/tag-group.js +157 -0
  241. package/dist/tag/index.d.ts +1 -0
  242. package/dist/tag/index.js +1 -0
  243. package/dist/tag/root/tag-root.d.ts +60 -0
  244. package/dist/tag/root/tag-root.js +74 -18
  245. package/dist/tag/selection.d.ts +10 -0
  246. package/dist/tag/selection.js +12 -0
  247. package/dist/textarea/grow.d.ts +22 -0
  248. package/dist/textarea/grow.js +20 -0
  249. package/dist/textarea/root/textarea-root.d.ts +9 -0
  250. package/dist/textarea/root/textarea-root.js +9 -1
  251. package/dist/time-input/root/time-input-root.d.ts +44 -5
  252. package/dist/time-input/root/time-input-root.js +69 -39
  253. package/dist/time-picker/root/time-picker-root.d.ts +54 -8
  254. package/dist/time-picker/root/time-picker-root.js +121 -91
  255. package/dist/timeline/group/timeline-group.d.ts +46 -0
  256. package/dist/timeline/group/timeline-group.js +37 -0
  257. package/dist/timeline/index.d.ts +1 -0
  258. package/dist/timeline/index.js +1 -0
  259. package/dist/timeline/root/timeline-root.d.ts +10 -3
  260. package/dist/toast/hotkey.d.ts +22 -0
  261. package/dist/toast/hotkey.js +23 -0
  262. package/dist/toast/item/toast-item.d.ts +26 -18
  263. package/dist/toast/item/toast-item.js +55 -48
  264. package/dist/toast/root/toast-root.d.ts +42 -8
  265. package/dist/toast/root/toast-root.js +64 -4
  266. package/dist/toggle/group/toggle-group.d.ts +57 -15
  267. package/dist/toggle/group/toggle-group.js +69 -9
  268. package/dist/toggle/root/toggle-root.d.ts +12 -1
  269. package/dist/toggle/root/toggle-root.js +11 -3
  270. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  271. package/dist/toolbar/root/toolbar-root.js +15 -5
  272. package/dist/tooltip/focus-target.d.ts +6 -0
  273. package/dist/tooltip/focus-target.js +9 -0
  274. package/dist/tooltip/root/tooltip-root.d.ts +42 -17
  275. package/dist/tooltip/root/tooltip-root.js +50 -9
  276. package/dist/tour/naming.d.ts +30 -0
  277. package/dist/tour/naming.js +10 -0
  278. package/dist/tour/root/tour-root.d.ts +35 -0
  279. package/dist/tour/root/tour-root.js +56 -5
  280. package/dist/tour/stop/tour-stop.d.ts +53 -8
  281. package/dist/tour/stop/tour-stop.js +45 -15
  282. package/dist/tour/wait.d.ts +11 -0
  283. package/dist/tour/wait.js +19 -0
  284. package/dist/tree/item/tree-item.d.ts +54 -1
  285. package/dist/tree/item/tree-item.js +89 -20
  286. package/dist/tree/root/tree-root.d.ts +37 -0
  287. package/dist/tree/root/tree-root.js +51 -6
  288. package/dist/tree/selection.d.ts +24 -0
  289. package/dist/tree/selection.js +26 -0
  290. package/dist/trend/root/trend-root.d.ts +13 -0
  291. package/dist/trend/root/trend-root.js +14 -9
  292. package/dist/video/media-events.d.ts +49 -0
  293. package/dist/video/media-events.js +39 -0
  294. package/dist/video/root/video-root.d.ts +99 -13
  295. package/dist/video/root/video-root.js +84 -47
  296. package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
  297. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  298. package/dist/video-playlist/order.d.ts +41 -0
  299. package/dist/video-playlist/order.js +34 -0
  300. package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
  301. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  302. package/dist/virtual-list/controls.d.ts +4 -0
  303. package/dist/virtual-list/controls.js +30 -0
  304. package/dist/virtual-list/fill.d.ts +30 -0
  305. package/dist/virtual-list/fill.js +39 -0
  306. package/dist/virtual-list/keys.d.ts +15 -0
  307. package/dist/virtual-list/keys.js +24 -0
  308. package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
  309. package/dist/virtual-list/root/virtual-list-root.js +175 -34
  310. package/lint.json +1 -1
  311. package/package.json +5 -5
  312. package/types/jsx.d.ts +8871 -1286
  313. package/types/svelte.d.ts +3 -0
  314. package/types/vue.d.ts +1918 -269
@@ -84,6 +84,7 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
84
84
  * @slot - The heading.
85
85
  *
86
86
  * @event {HelixBeforeResizeEvent} helix-before-resize - The column is about to be resized, with the requested width. Cancelable: cancel it to keep the current width.
87
+ * @event {HelixResizedEvent} helix-resized - Fired after the column is resized, with the new width.
87
88
  *
88
89
  * @csspart column - The heading cell.
89
90
  * @csspart grip - The handle for moving the column, when the table allows it.
@@ -154,6 +155,16 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
154
155
  * replaced with the heading text.
155
156
  */
156
157
  resizeLabel: string;
158
+ /**
159
+ * Makes this column's cells the headers of their rows, in `DataTable`.
160
+ *
161
+ * A screen reader moving along a row or down a column names the row by its
162
+ * row header, so the cell that identifies a row, a file's name say, is the
163
+ * one to mark. Where no column sets it, `DataTable` makes the first column
164
+ * with a `field` the row header. A `Table`'s cells are your markup, so there
165
+ * a cell is a row header through its own `header` attribute.
166
+ */
167
+ rowHeader: boolean;
157
168
  /**
158
169
  * Whether the table can be sorted by this column.
159
170
  *
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessTableColumn_1;
8
- import { customElement, fillTemplate, HelixBeforeResizeEvent, HelixElement, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
8
+ import { customElement, fillTemplate, HelixBeforeResizeEvent, HelixElement, HelixResizedEvent, hostAria, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
9
9
  import { dotsThreeVertical } from '@fusion.dev/helix-icons';
10
10
  import { html, nothing } from 'lit';
11
11
  import { property, state } from 'lit/decorators.js';
@@ -37,6 +37,7 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
37
37
  this.moveLabel = 'Move {name}';
38
38
  this.resizable = false;
39
39
  this.resizeLabel = 'Resize {name}';
40
+ this.rowHeader = false;
40
41
  this.sortable = false;
41
42
  this.width = '';
42
43
  this.widthLabel = '{width} pixels';
@@ -172,6 +173,7 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
172
173
  requestChange({
173
174
  apply: (value) => {
174
175
  this.width = value;
176
+ this.dispatchEvent(new HelixResizedEvent({ value }));
175
177
  },
176
178
  event: (value) => new HelixBeforeResizeEvent({ value }),
177
179
  host: this,
@@ -237,6 +239,9 @@ __decorate([
237
239
  __decorate([
238
240
  property({ attribute: 'resize-label' })
239
241
  ], HelixHeadlessTableColumn.prototype, "resizeLabel", void 0);
242
+ __decorate([
243
+ property({ attribute: 'row-header', type: Boolean })
244
+ ], HelixHeadlessTableColumn.prototype, "rowHeader", void 0);
240
245
  __decorate([
241
246
  property({ reflect: true, type: Boolean })
242
247
  ], HelixHeadlessTableColumn.prototype, "sortable", void 0);
@@ -1,5 +1,6 @@
1
1
  import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
+ import '../../checkbox/index.js';
3
4
  import { type HelixHeadlessTableColumn } from '../column/table-column.js';
4
5
  declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & typeof HelixElement;
5
6
  /**
@@ -21,6 +22,17 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
21
22
  * the rows in the sorted order. `helix-sort` asks first, so you can refuse it
22
23
  * and reorder the rows yourself.
23
24
  *
25
+ * The `heading` slot names the table: slot a heading or a line of text into
26
+ * it, and the table is named by its words. An `aria-label` or `aria-labelledby` on the
27
+ * host wins over it.
28
+ *
29
+ * `selectable` adds a column of checkboxes. Each row is known by its `value`,
30
+ * and `selected` holds the chosen keys, comma separated, the same shape
31
+ * `DataTable` uses. The checkbox in the heading selects every row. For a grid
32
+ * a reader moves through with the arrow keys, with typeahead and range
33
+ * selection, use `DataTable`. To act on one row, put a link or a button in a
34
+ * cell.
35
+ *
24
36
  * The CSS custom properties listed for this component are written by it and
25
37
  * read by the stylesheet that draws it. Do not set them. Each holds a number
26
38
  * the component computes and CSS cannot, so the stylesheet can draw the table
@@ -33,13 +45,29 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
33
45
  * @documentation https://fusion.dev/helix/components/table
34
46
  *
35
47
  * @slot - The table's rows.
48
+ * @slot heading - Words that name the table, shown above it, such as a heading.
36
49
  *
50
+ * @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.
51
+ * @event {HelixSelectedEvent} helix-selected - Fired after the selection changes, with every selected key, separated by commas.
37
52
  * @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.
53
+ * @event {HelixSortedEvent} helix-sorted - Fired after the sort order changes, with the new order.
38
54
  *
55
+ * @csspart checkbox - The checkbox in the heading that selects every row, in a `selectable` table.
56
+ * @csspart checkbox-box - The box drawn for the checkbox's input.
57
+ * @csspart checkbox-control - The checkbox's input.
58
+ * @csspart checkbox-feedback - Forwarded from the checkbox. Not shown in the table.
59
+ * @csspart checkbox-field - The row that holds the checkbox's box.
60
+ * @csspart checkbox-hint - Forwarded from the checkbox. Not shown in the table.
61
+ * @csspart checkbox-label - Forwarded from the checkbox. The label is read by screen readers only.
62
+ * @csspart checkbox-mark - The check mark, or the dash while some rows are selected.
63
+ * @csspart checkbox-mark-checked - Added to `checkbox-mark` while its box is checked.
64
+ * @csspart checkbox-mark-dash - Added to `checkbox-mark` while it draws the dash, which it keeps until its box is checked.
65
+ * @csspart checkbox-mark-indeterminate - Added to `checkbox-mark` while only some rows are selected.
39
66
  * @csspart empty - The text shown when there are no rows.
40
67
  * @csspart head - The row that holds the column headings. It has `display: contents`, so it takes no space of its own.
41
68
  * @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.
42
69
  * @csspart loading - The text shown while the rows are loading.
70
+ * @csspart select-all - The heading that holds the checkbox that selects every row.
43
71
  * @csspart table - The grid.
44
72
  *
45
73
  * @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.
@@ -78,6 +106,11 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
78
106
  * declared in it has nowhere else to be sized from.
79
107
  */
80
108
  columns: string;
109
+ /**
110
+ * The keys selected at the start, separated by commas. Used until `selected`
111
+ * is set.
112
+ */
113
+ defaultSelected: string;
81
114
  /**
82
115
  * The starting sort order, used until `sort` is set.
83
116
  */
@@ -91,6 +124,32 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
91
124
  * wins over this.
92
125
  */
93
126
  label: string;
127
+ /**
128
+ * Adds a column of checkboxes for selecting rows. Each row is known by its
129
+ * `value`, and by its place among the rows as written where it has none.
130
+ */
131
+ selectable: boolean;
132
+ /** The name of the checkbox in the heading that selects every row. */
133
+ selectAllLabel: string;
134
+ /**
135
+ * The keys of the selected rows, separated by commas.
136
+ *
137
+ * A reader's press fires `helix-select` first, and refusing it leaves the
138
+ * selection as it was. `default-selected` seeds a selection this element
139
+ * then owns.
140
+ */
141
+ get selected(): string;
142
+ set selected(next: string);
143
+ /**
144
+ * What screen readers hear when the chosen rows change. `{count}` is how many
145
+ * rows are chosen.
146
+ */
147
+ selectedLabel: string;
148
+ /**
149
+ * The name of a row's checkbox. `{row}` is replaced with the words of the
150
+ * row's first cell.
151
+ */
152
+ selectRowLabel: string;
94
153
  /**
95
154
  * The sort order, as `field:direction`, where `field` is a sortable column's
96
155
  * `field`.
@@ -110,6 +169,9 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
110
169
  /** What screen readers hear when the table stops being sorted. */
111
170
  unsortedLabel: string;
112
171
  private sortState;
172
+ private selectedState;
173
+ /** Whether the heading names the table, so taking it away clears only this element's own name. */
174
+ private headed;
113
175
  /**
114
176
  * Carries a host `aria-label` and `aria-labelledby` to the grid, which is
115
177
  * the element with the `table` role.
@@ -148,6 +210,39 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
148
210
  * new order is said. Not on the first render, which is the table arriving.
149
211
  */
150
212
  private news;
213
+ /** The sort as the last render had it, so a selection said beside a sort waits. */
214
+ private heardSortBefore;
215
+ /** The selection last heard, so a render that changed nothing says nothing. */
216
+ private heardSelected;
217
+ /** The rows as written, each with the key `selected` lists it by. */
218
+ private get keyed();
219
+ /** The keys selected now. */
220
+ private get chosen();
221
+ /** Asks for a different set of selected rows, and reports whether the request stood. */
222
+ private requestSelected;
223
+ /**
224
+ * A checkbox this table drew asked to change: a row's, or the one in the
225
+ * heading. Refused, and asked of the selection instead, so a box shows only
226
+ * what `selected` says. A checkbox a consumer put in a cell is theirs and is
227
+ * left alone.
228
+ */
229
+ private readonly handleToggle;
230
+ /**
231
+ * Tells each row whether it is selected and what its checkbox is called.
232
+ *
233
+ * Pushed down for the reason the sort is: the selection is the table's, and
234
+ * the checkbox is drawn by the row.
235
+ */
236
+ private markSelected;
237
+ /**
238
+ * Names the table by its heading, where the host names it no other way.
239
+ *
240
+ * Through element reflection, because the heading is the consumer's markup
241
+ * and the table is in this shadow root, which an id cannot reach across.
242
+ */
243
+ private nameByHeading;
244
+ /** What the heading slot is given. */
245
+ private get headings();
151
246
  /**
152
247
  * Tells each column which way it is ordered, if it is the one.
153
248
  *
@@ -175,6 +270,8 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
175
270
  * track for one that declares neither.
176
271
  */
177
272
  private get template();
273
+ /** The tracks of the columns, before any checkbox column. */
274
+ private get tracks();
178
275
  /**
179
276
  * Tracks for the columns that set nothing, from how much text each holds.
180
277
  *
@@ -195,6 +292,8 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
195
292
  * after. Sampled, so a table of thousands of rows reads `SAMPLE` of them.
196
293
  */
197
294
  private fitted;
295
+ /** Asks for the render a hydration put off, which reads the rows. */
296
+ protected firstUpdated(changed: PropertyValues): void;
198
297
  private readonly handleSlotChange;
199
298
  /**
200
299
  * Watches the light DOM for rows and columns arriving, leaving and moving.
@@ -278,6 +377,8 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
278
377
  private alignCells;
279
378
  protected willUpdate(changed: PropertyValues): void;
280
379
  protected updated(changed: PropertyValues): void;
380
+ /** The heading of the checkbox column, which selects every row. */
381
+ private renderSelectAll;
281
382
  protected render(): TemplateResult;
282
383
  }
283
384
  declare global {
@@ -4,9 +4,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, customElement, fillTemplate, HelixElement, HelixSortEvent, MixinCollection, requestChange, splitValues, } from '@fusion.dev/helix-core';
8
- import { html, nothing } from 'lit';
7
+ import { AriaForwardController, commaList, customElement, fillTemplate, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, MixinCollection, reflectElements, requestChange, splitValues, whenHydrated, } from '@fusion.dev/helix-core';
8
+ import { nothing } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
+ import { html } from 'lit/static-html.js';
11
+ import '../../checkbox/index.js';
10
12
  import { cycle, format, parse, sort } from '../../data-table/root/order.js';
11
13
  import { edgeOf } from '../column/table-column.js';
12
14
  const tracksOf = (list, wanted) => {
@@ -47,17 +49,61 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
47
49
  super(...arguments);
48
50
  this.ascendingLabel = 'ascending';
49
51
  this.columns = '';
52
+ this.defaultSelected = '';
50
53
  this.defaultSort = '';
51
54
  this.descendingLabel = 'descending';
52
55
  this.label = '';
56
+ this.selectable = false;
57
+ this.selectAllLabel = 'Select every row';
58
+ this.selectedLabel = '{count} selected';
59
+ this.selectRowLabel = 'Select {row}';
53
60
  this.sortedLabel = 'Sorted by {column}, {order}';
54
61
  this.unsortedLabel = 'Not sorted';
55
62
  this.sortState = undefined;
63
+ this.selectedState = undefined;
64
+ this.headed = false;
56
65
  this.aria = new AriaForwardController(this, {
57
66
  label: true,
58
67
  target: () => this.partNamed('table'),
59
68
  });
60
69
  this.heardSort = undefined;
70
+ this.heardSortBefore = undefined;
71
+ this.heardSelected = undefined;
72
+ this.handleToggle = (event) => {
73
+ const origin = event.composedPath()[0];
74
+ if (!(origin instanceof Element) || origin.getAttribute('part') !== 'checkbox') {
75
+ return;
76
+ }
77
+ const root = origin.getRootNode();
78
+ const keys = this.chosen;
79
+ if (root === this.renderRoot) {
80
+ event.preventDefault();
81
+ const every = this.keyed.map(({ key }) => key);
82
+ const all = every.length > 0 && every.every((key) => keys.has(key));
83
+ for (const key of every) {
84
+ if (all) {
85
+ keys.delete(key);
86
+ }
87
+ else {
88
+ keys.add(key);
89
+ }
90
+ }
91
+ this.requestSelected(keys);
92
+ return;
93
+ }
94
+ const found = this.keyed.find(({ row }) => row.shadowRoot === root);
95
+ if (!found) {
96
+ return;
97
+ }
98
+ event.preventDefault();
99
+ if (event.detail.checked) {
100
+ keys.add(found.key);
101
+ }
102
+ else {
103
+ keys.delete(found.key);
104
+ }
105
+ this.requestSelected(keys);
106
+ };
61
107
  this.handleHeadClick = (event) => {
62
108
  const path = event.composedPath();
63
109
  if (!path.some((node) => node instanceof Element && node.getAttribute('part') === 'sort')) {
@@ -76,6 +122,14 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
76
122
  this.alignment = undefined;
77
123
  this.aligned = '';
78
124
  }
125
+ get selected() {
126
+ return this.selectedState ?? this.defaultSelected;
127
+ }
128
+ set selected(next) {
129
+ const previous = this.selected;
130
+ this.selectedState = next;
131
+ this.requestUpdate('selected', previous);
132
+ }
79
133
  get sort() {
80
134
  return this.sortState ?? this.defaultSort;
81
135
  }
@@ -90,6 +144,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
90
144
  const previous = this.sort;
91
145
  this.sortState = value;
92
146
  this.requestUpdate('sort', previous);
147
+ this.dispatchEvent(new HelixSortedEvent({ value }));
93
148
  },
94
149
  event: (value) => new HelixSortEvent({ value }),
95
150
  host: this,
@@ -133,8 +188,57 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
133
188
  : this.unsortedLabel;
134
189
  }
135
190
  this.heardSort = current;
191
+ const selected = this.selectable ? this.selected : '';
192
+ if (this.hasUpdated && current === this.heardSortBefore && selected !== this.heardSelected) {
193
+ said = fillTemplate(this.selectedLabel, { count: this.chosen.size });
194
+ }
195
+ this.heardSortBefore = current;
196
+ this.heardSelected = selected;
136
197
  return said;
137
198
  }
199
+ get keyed() {
200
+ return this.slotted.map((row, index) => ({
201
+ key: row.value || String(index),
202
+ row: row,
203
+ }));
204
+ }
205
+ get chosen() {
206
+ return new Set(commaList(this.selected));
207
+ }
208
+ requestSelected(keys) {
209
+ return requestChange({
210
+ apply: (value) => {
211
+ const previous = this.selected;
212
+ this.selectedState = value;
213
+ this.requestUpdate('selected', previous);
214
+ this.dispatchEvent(new HelixSelectedEvent({ value }));
215
+ },
216
+ event: (value) => new HelixSelectEvent({ value }),
217
+ host: this,
218
+ next: [...keys].join(','),
219
+ });
220
+ }
221
+ markSelected() {
222
+ const keys = this.chosen;
223
+ for (const { key, row } of this.keyed) {
224
+ if (!row.isTableRow) {
225
+ continue;
226
+ }
227
+ const label = fillTemplate(this.selectRowLabel, { row: textOf(row.children[0]) || key });
228
+ whenHydrated(row, () => {
229
+ row.selectable = this.selectable;
230
+ row.selected = keys.has(key);
231
+ row.selectLabel = label;
232
+ });
233
+ }
234
+ }
235
+ nameByHeading() {
236
+ const named = this.hasAttribute('aria-label') || this.hasAttribute('aria-labelledby');
237
+ this.headed = reflectElements(this.partNamed('table'), 'ariaLabelledByElements', named ? [] : this.headings, this.headed);
238
+ }
239
+ get headings() {
240
+ return [...(this.children ?? [])].filter((child) => child.getAttribute('slot') === 'heading');
241
+ }
138
242
  markSorted() {
139
243
  const current = parse(this.sort);
140
244
  for (const column of this.tableColumns) {
@@ -150,6 +254,10 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
150
254
  return this.knownChildren.filter((child) => 'isTableColumn' in child && child.isTableColumn === true);
151
255
  }
152
256
  get template() {
257
+ const tracks = this.tracks;
258
+ return this.selectable && tracks ? `max-content ${tracks}` : tracks;
259
+ }
260
+ get tracks() {
153
261
  const declared = this.tableColumns;
154
262
  if (declared.length === 0) {
155
263
  return this.columns;
@@ -187,17 +295,23 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
187
295
  : 'max-content';
188
296
  });
189
297
  }
298
+ firstUpdated(changed) {
299
+ super.firstUpdated(changed);
300
+ this.finishHydration();
301
+ }
190
302
  connectedCallback() {
191
303
  super.connectedCallback();
192
304
  this.watcher = new MutationObserver(() => this.requestUpdate());
193
305
  this.watcher.observe(this, { characterData: true, childList: true, subtree: true });
194
306
  this.addEventListener('click', this.handleHeadClick);
307
+ this.addEventListener('helix-before-toggle', this.handleToggle);
195
308
  }
196
309
  disconnectedCallback() {
197
310
  super.disconnectedCallback();
198
311
  this.watcher?.disconnect();
199
312
  this.watcher = undefined;
200
313
  this.removeEventListener('click', this.handleHeadClick);
314
+ this.removeEventListener('helix-before-toggle', this.handleToggle);
201
315
  }
202
316
  static { this.shadowRootOptions = {
203
317
  ...HelixElement.shadowRootOptions,
@@ -205,7 +319,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
205
319
  }; }
206
320
  get slotted() {
207
321
  const columns = new Set(this.tableColumns);
208
- return [...(this.children ?? [])].filter((child) => !columns.has(child));
322
+ return [...(this.children ?? [])].filter((child) => !columns.has(child) && child.getAttribute('slot') !== 'heading');
209
323
  }
210
324
  assign() {
211
325
  if (this.assignsByName) {
@@ -221,6 +335,9 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
221
335
  }
222
336
  head.assign(...this.tableColumns);
223
337
  body.assign(...this.arrangedRows);
338
+ this.renderRoot
339
+ ?.querySelector('slot[name="heading"]')
340
+ ?.assign(...this.headings);
224
341
  }
225
342
  alignCells() {
226
343
  if (typeof CSSStyleSheet === 'undefined' || !('replaceSync' in CSSStyleSheet.prototype)) {
@@ -252,17 +369,40 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
252
369
  this.assign();
253
370
  this.alignCells();
254
371
  this.markSorted();
372
+ this.markSelected();
373
+ this.nameByHeading();
374
+ }
375
+ renderSelectAll() {
376
+ if (!this.selectable) {
377
+ return nothing;
378
+ }
379
+ const every = this.childrenKnown ? this.keyed.map(({ key }) => key) : [];
380
+ const keys = this.chosen;
381
+ const count = every.filter((key) => keys.has(key)).length;
382
+ const checkbox = this.tag('checkbox');
383
+ return html `<span part="select-all" role="columnheader"
384
+ ><${checkbox}
385
+ part="checkbox"
386
+ exportparts="box: checkbox-box, control: checkbox-control, feedback: checkbox-feedback,
387
+ field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark,
388
+ mark-checked: checkbox-mark-checked, mark-dash: checkbox-mark-dash,
389
+ mark-indeterminate: checkbox-mark-indeterminate"
390
+ aria-label=${this.selectAllLabel}
391
+ .checked=${every.length > 0 && count === every.length}
392
+ .indeterminate=${count > 0 && count < every.length}
393
+ ></${checkbox}
394
+ ></span>`;
255
395
  }
256
396
  render() {
257
397
  const template = this.template;
258
- return html `<div
398
+ return html `<slot name="heading"></slot><div
259
399
  part="table"
260
400
  role="table"
261
401
  aria-busy=${this.loading ? 'true' : nothing}
262
402
  aria-label=${this.label || 'Table'}
263
403
  style=${template ? `--table-template: ${template}` : ''}
264
404
  >
265
- <div part="head" role="row"><slot name="columns"></slot></div>
405
+ <div part="head" role="row">${this.renderSelectAll()}<slot name="columns"></slot></div>
266
406
  <slot
267
407
  @slotchange=${(event) => {
268
408
  this.countRows(event);
@@ -279,6 +419,9 @@ __decorate([
279
419
  __decorate([
280
420
  property()
281
421
  ], HelixHeadlessTable.prototype, "columns", void 0);
422
+ __decorate([
423
+ property({ attribute: 'default-selected' })
424
+ ], HelixHeadlessTable.prototype, "defaultSelected", void 0);
282
425
  __decorate([
283
426
  property({ attribute: 'default-sort' })
284
427
  ], HelixHeadlessTable.prototype, "defaultSort", void 0);
@@ -288,6 +431,21 @@ __decorate([
288
431
  __decorate([
289
432
  property()
290
433
  ], HelixHeadlessTable.prototype, "label", void 0);
434
+ __decorate([
435
+ property({ type: Boolean })
436
+ ], HelixHeadlessTable.prototype, "selectable", void 0);
437
+ __decorate([
438
+ property({ attribute: 'select-all-label' })
439
+ ], HelixHeadlessTable.prototype, "selectAllLabel", void 0);
440
+ __decorate([
441
+ property()
442
+ ], HelixHeadlessTable.prototype, "selected", null);
443
+ __decorate([
444
+ property({ attribute: 'selected-label' })
445
+ ], HelixHeadlessTable.prototype, "selectedLabel", void 0);
446
+ __decorate([
447
+ property({ attribute: 'select-row-label' })
448
+ ], HelixHeadlessTable.prototype, "selectRowLabel", void 0);
291
449
  __decorate([
292
450
  property()
293
451
  ], HelixHeadlessTable.prototype, "sort", null);
@@ -300,6 +458,9 @@ __decorate([
300
458
  __decorate([
301
459
  state()
302
460
  ], HelixHeadlessTable.prototype, "sortState", void 0);
461
+ __decorate([
462
+ state()
463
+ ], HelixHeadlessTable.prototype, "selectedState", void 0);
303
464
  HelixHeadlessTable = __decorate([
304
465
  customElement('helix-headless-table')
305
466
  ], HelixHeadlessTable);
@@ -1,5 +1,6 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
+ import '../../checkbox/index.js';
3
4
  /**
4
5
  * @summary One row of a table.
5
6
  *
@@ -9,12 +10,31 @@ import { type PropertyValues, type TemplateResult } from 'lit';
9
10
  * across rows. The row still exists as an element, so you can style it, hide
10
11
  * it, or make it interactive.
11
12
  *
13
+ * In a `selectable` table the row draws a checkbox cell before its own cells,
14
+ * and `value` is the key the table's `selected` lists it by.
15
+ *
12
16
  * @since 0.1.0
13
17
  * @status stable
14
18
  * @aliases Row, TableRow
15
19
  * @documentation https://fusion.dev/helix/components/table
16
20
  *
17
21
  * @slot - The row's cells.
22
+ *
23
+ * @csspart checkbox - The row's checkbox, in a `selectable` table.
24
+ * @csspart checkbox-box - The box drawn for the checkbox's input.
25
+ * @csspart checkbox-control - The checkbox's input.
26
+ * @csspart checkbox-feedback - Forwarded from the checkbox. Not shown in the table.
27
+ * @csspart checkbox-field - The row that holds the checkbox's box.
28
+ * @csspart checkbox-hint - Forwarded from the checkbox. Not shown in the table.
29
+ * @csspart checkbox-label - Forwarded from the checkbox. The label is read by screen readers only.
30
+ * @csspart checkbox-mark - The check mark.
31
+ * @csspart checkbox-mark-checked - Added to `checkbox-mark` while its box is checked.
32
+ * @csspart checkbox-mark-dash - Added to `checkbox-mark` while it draws the dash, which it keeps until its box is checked.
33
+ * @csspart checkbox-mark-indeterminate - Added to `checkbox-mark` while only some rows are selected.
34
+ * @csspart select - The cell that holds the row's checkbox, in a `selectable` table.
35
+ * @csspart select-selected - Added to `select` while the row is selected.
36
+ *
37
+ * @cssstate selected - While the row is selected, in a `selectable` table.
18
38
  */
19
39
  export declare class HelixHeadlessTableRow extends HelixElement {
20
40
  /**
@@ -22,6 +42,23 @@ export declare class HelixHeadlessTableRow extends HelixElement {
22
42
  * finds its columns. Not a consumer's to read or set.
23
43
  */
24
44
  readonly isTableRow = true;
45
+ /**
46
+ * The key the table's `selected` lists this row by. Left empty, the row is
47
+ * known by its place among the rows as written.
48
+ */
49
+ value: string;
50
+ /**
51
+ * @internal Whether the table this row sits in is `selectable`, written by
52
+ * that table. Not a consumer's to set: the selection is the table's.
53
+ */
54
+ selectable: boolean;
55
+ /**
56
+ * @internal Whether the row is selected, written by the table that owns the
57
+ * selection. Not a consumer's to set: write the table's `selected`.
58
+ */
59
+ selected: boolean;
60
+ /** @internal The name of the row's checkbox, written by the table. Not a consumer's to set. */
61
+ selectLabel: string;
25
62
  /** The table's rules this row holds, so the next ones replace them rather than pile up. */
26
63
  private columnRules;
27
64
  /**
@@ -39,6 +76,15 @@ export declare class HelixHeadlessTableRow extends HelixElement {
39
76
  * upgrades while its row is still being parsed has no value beside it yet.
40
77
  */
41
78
  private readonly handleSlotChange;
79
+ /**
80
+ * The checkbox cell, in a `selectable` table.
81
+ *
82
+ * A cell of the row's own, before the consumer's cells, so the table's grid
83
+ * gives it the first track. The table hears its `helix-before-toggle`,
84
+ * refuses it and asks for the new selection, so the box shows only what the
85
+ * table's `selected` says.
86
+ */
87
+ protected renderSelect(): TemplateResult | typeof nothing;
42
88
  protected render(): TemplateResult;
43
89
  }
44
90
  declare global {
@@ -5,11 +5,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
8
- import { html } from 'lit';
8
+ import { nothing } from 'lit';
9
+ import { property, state } from 'lit/decorators.js';
10
+ import { html } from 'lit/static-html.js';
11
+ import '../../checkbox/index.js';
9
12
  let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
10
13
  constructor() {
11
14
  super(...arguments);
12
15
  this.isTableRow = true;
16
+ this.value = '';
17
+ this.selectable = false;
18
+ this.selected = false;
19
+ this.selectLabel = '';
13
20
  this.columnRules = undefined;
14
21
  this.handleSlotChange = () => {
15
22
  for (const cell of this.children) {
@@ -34,11 +41,41 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
34
41
  willUpdate(changed) {
35
42
  super.willUpdate(changed);
36
43
  hostAria(this.internals, { role: 'row' });
44
+ this.toggleState('selected', this.selectable && this.selected);
45
+ }
46
+ renderSelect() {
47
+ if (!this.selectable) {
48
+ return nothing;
49
+ }
50
+ const checkbox = this.tag('checkbox');
51
+ return html `<span part="select${this.selected ? ' select-selected' : ''}" role="cell"
52
+ ><${checkbox}
53
+ part="checkbox"
54
+ exportparts="box: checkbox-box, control: checkbox-control, feedback: checkbox-feedback,
55
+ field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark,
56
+ mark-checked: checkbox-mark-checked, mark-dash: checkbox-mark-dash,
57
+ mark-indeterminate: checkbox-mark-indeterminate"
58
+ aria-label=${this.selectLabel}
59
+ .checked=${this.selected}
60
+ ></${checkbox}
61
+ ></span>`;
37
62
  }
38
63
  render() {
39
- return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
64
+ return html `${this.renderSelect()}<slot @slotchange=${this.handleSlotChange}></slot>`;
40
65
  }
41
66
  };
67
+ __decorate([
68
+ property()
69
+ ], HelixHeadlessTableRow.prototype, "value", void 0);
70
+ __decorate([
71
+ state()
72
+ ], HelixHeadlessTableRow.prototype, "selectable", void 0);
73
+ __decorate([
74
+ state()
75
+ ], HelixHeadlessTableRow.prototype, "selected", void 0);
76
+ __decorate([
77
+ state()
78
+ ], HelixHeadlessTableRow.prototype, "selectLabel", void 0);
42
79
  HelixHeadlessTableRow = __decorate([
43
80
  customElement('helix-headless-table-row')
44
81
  ], HelixHeadlessTableRow);