@fusion.dev/helix-headless 0.142.1 → 0.144.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 (285) hide show
  1. package/custom-elements.json +25381 -1202
  2. package/dist/accordion/item/accordion-item.d.ts +38 -2
  3. package/dist/accordion/item/accordion-item.js +38 -6
  4. package/dist/accordion/root/accordion-root.d.ts +23 -1
  5. package/dist/accordion/root/accordion-root.js +39 -3
  6. package/dist/announcement/root/announcement-root.d.ts +11 -7
  7. package/dist/announcement/root/announcement-root.js +1 -1
  8. package/dist/app-header/root/app-header-root.d.ts +21 -0
  9. package/dist/app-header/root/app-header-root.js +31 -5
  10. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  11. package/dist/area-chart/root/area-chart-root.js +39 -11
  12. package/dist/avatar/group/avatar-group.d.ts +24 -3
  13. package/dist/avatar/group/avatar-group.js +34 -2
  14. package/dist/avatar/root/avatar-root.d.ts +17 -1
  15. package/dist/avatar/root/avatar-root.js +31 -10
  16. package/dist/badge/root/badge-root.d.ts +12 -0
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
  19. package/dist/bar-chart/root/bar-chart-root.js +58 -21
  20. package/dist/blockquote/root/blockquote-root.d.ts +12 -7
  21. package/dist/blockquote/root/blockquote-root.js +6 -4
  22. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
  24. package/dist/button/root/button-root.d.ts +84 -1
  25. package/dist/button/root/button-root.js +81 -3
  26. package/dist/callout/root/callout-root.d.ts +32 -6
  27. package/dist/callout/root/callout-root.js +26 -7
  28. package/dist/canvas/root/canvas-root.d.ts +1 -0
  29. package/dist/canvas/root/canvas-root.js +10 -1
  30. package/dist/card/root/card-root.d.ts +30 -1
  31. package/dist/card/root/card-root.js +38 -5
  32. package/dist/carousel/root/carousel-root.d.ts +47 -5
  33. package/dist/carousel/root/carousel-root.js +53 -21
  34. package/dist/chat/composer/chat-composer.d.ts +13 -11
  35. package/dist/chat/composer/chat-composer.js +6 -12
  36. package/dist/chat/message/chat-message.js +8 -1
  37. package/dist/chat/root/chat-root.d.ts +1 -0
  38. package/dist/chat/root/chat-root.js +2 -1
  39. package/dist/checkbox/root/checkbox-root.d.ts +7 -0
  40. package/dist/checkbox/root/checkbox-root.js +9 -3
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
  42. package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
  43. package/dist/code/root/code-root.d.ts +1 -1
  44. package/dist/code-block/lines.d.ts +13 -0
  45. package/dist/code-block/lines.js +2 -0
  46. package/dist/code-block/root/code-block-root.d.ts +49 -0
  47. package/dist/code-block/root/code-block-root.js +44 -3
  48. package/dist/color-input/root/color-input-root.d.ts +60 -2
  49. package/dist/color-input/root/color-input-root.js +55 -7
  50. package/dist/color-picker/channels.d.ts +26 -0
  51. package/dist/color-picker/channels.js +84 -0
  52. package/dist/color-picker/root/color-picker-root.d.ts +118 -12
  53. package/dist/color-picker/root/color-picker-root.js +183 -13
  54. package/dist/combobox/root/combobox-root.d.ts +126 -3
  55. package/dist/combobox/root/combobox-root.js +224 -21
  56. package/dist/command/root/command-root.d.ts +47 -10
  57. package/dist/command/root/command-root.js +45 -4
  58. package/dist/copy-button/from.d.ts +22 -0
  59. package/dist/copy-button/from.js +28 -0
  60. package/dist/copy-button/root/copy-button-root.d.ts +48 -7
  61. package/dist/copy-button/root/copy-button-root.js +54 -8
  62. package/dist/data-table/root/data-table-root.d.ts +164 -10
  63. package/dist/data-table/root/data-table-root.js +488 -57
  64. package/dist/date-input/root/date-input-root.d.ts +123 -9
  65. package/dist/date-input/root/date-input-root.js +147 -45
  66. package/dist/date-picker/root/date-picker-root.d.ts +229 -18
  67. package/dist/date-picker/root/date-picker-root.js +342 -46
  68. package/dist/dialog/description.d.ts +9 -0
  69. package/dist/dialog/description.js +14 -0
  70. package/dist/dialog/root/dialog-root.d.ts +101 -10
  71. package/dist/dialog/root/dialog-root.js +83 -4
  72. package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
  73. package/dist/donut-chart/root/donut-chart-root.js +48 -13
  74. package/dist/drawer/root/drawer-root.d.ts +93 -7
  75. package/dist/drawer/root/drawer-root.js +126 -5
  76. package/dist/drawer/swipe-start.d.ts +9 -0
  77. package/dist/drawer/swipe-start.js +12 -0
  78. package/dist/drilldown/item/drilldown-item.d.ts +16 -13
  79. package/dist/drilldown/item/drilldown-item.js +6 -2
  80. package/dist/drilldown/root/drilldown-root.d.ts +21 -5
  81. package/dist/drilldown/root/drilldown-root.js +26 -10
  82. package/dist/element-events.generated.js +42 -13
  83. package/dist/empty/root/empty-root.d.ts +1 -1
  84. package/dist/file-input/root/file-input-root.d.ts +65 -1
  85. package/dist/file-input/root/file-input-root.js +76 -12
  86. package/dist/file-input/screen.d.ts +35 -0
  87. package/dist/file-input/screen.js +49 -0
  88. package/dist/filter-input/menu/filter-menu.d.ts +9 -0
  89. package/dist/filter-input/menu/filter-menu.js +8 -0
  90. package/dist/filter-input/root/filter-input-root.d.ts +43 -6
  91. package/dist/filter-input/root/filter-input-root.js +89 -10
  92. package/dist/filter-input/suggest.d.ts +17 -0
  93. package/dist/filter-input/suggest.js +23 -0
  94. package/dist/format-date/options.d.ts +33 -0
  95. package/dist/format-date/options.js +42 -0
  96. package/dist/format-date/root/format-date-root.d.ts +62 -3
  97. package/dist/format-date/root/format-date-root.js +78 -37
  98. package/dist/graph/root/graph-root.d.ts +24 -3
  99. package/dist/graph/root/graph-root.js +66 -12
  100. package/dist/heatmap/root/buckets.d.ts +2 -1
  101. package/dist/heatmap/root/buckets.js +5 -1
  102. package/dist/heatmap/root/heatmap-root.d.ts +47 -9
  103. package/dist/heatmap/root/heatmap-root.js +46 -18
  104. package/dist/icon/index.d.ts +2 -0
  105. package/dist/icon/index.js +2 -0
  106. package/dist/icon/registry.d.ts +37 -0
  107. package/dist/icon/registry.js +83 -0
  108. package/dist/icon/root/icon-root.d.ts +53 -6
  109. package/dist/icon/root/icon-root.js +72 -4
  110. package/dist/icon/root/index.d.ts +2 -0
  111. package/dist/icon/root/index.js +2 -0
  112. package/dist/icon/set.d.ts +1 -0
  113. package/dist/icon/set.js +3 -0
  114. package/dist/icon-button/root/icon-button-root.d.ts +1 -1
  115. package/dist/image/root/image-root.d.ts +23 -2
  116. package/dist/image/root/image-root.js +23 -4
  117. package/dist/input/root/input-root.d.ts +62 -9
  118. package/dist/input/root/input-root.js +61 -5
  119. package/dist/kbd/root/kbd-root.d.ts +26 -11
  120. package/dist/kbd/root/kbd-root.js +35 -38
  121. package/dist/kbd/shortcut.d.ts +18 -0
  122. package/dist/kbd/shortcut.js +35 -0
  123. package/dist/legend/hidden-series.d.ts +8 -0
  124. package/dist/legend/hidden-series.js +13 -0
  125. package/dist/legend/root/legend-root.d.ts +63 -0
  126. package/dist/legend/root/legend-root.js +61 -7
  127. package/dist/lightbox/item/lightbox-item.d.ts +17 -1
  128. package/dist/lightbox/item/lightbox-item.js +10 -1
  129. package/dist/lightbox/root/lightbox-root.d.ts +77 -6
  130. package/dist/lightbox/root/lightbox-root.js +116 -5
  131. package/dist/line-chart/root/line-chart-root.d.ts +29 -4
  132. package/dist/line-chart/root/line-chart-root.js +58 -17
  133. package/dist/list/item/list-item.d.ts +11 -5
  134. package/dist/list/item/list-item.js +5 -6
  135. package/dist/listbox/range.d.ts +17 -0
  136. package/dist/listbox/range.js +5 -0
  137. package/dist/listbox/root/listbox-root.d.ts +184 -4
  138. package/dist/listbox/root/listbox-root.js +229 -23
  139. package/dist/loader/busy.d.ts +17 -0
  140. package/dist/loader/busy.js +24 -0
  141. package/dist/loader/root/loader-root.d.ts +37 -0
  142. package/dist/loader/root/loader-root.js +52 -3
  143. package/dist/map/root/map-root.d.ts +19 -4
  144. package/dist/map/root/map-root.js +36 -7
  145. package/dist/megamenu/root/megamenu-root.d.ts +10 -1
  146. package/dist/megamenu/root/megamenu-root.js +10 -1
  147. package/dist/menu/item/menu-item.d.ts +41 -12
  148. package/dist/menu/item/menu-item.js +46 -3
  149. package/dist/menu/root/menu-root.d.ts +32 -2
  150. package/dist/menu/root/menu-root.js +48 -8
  151. package/dist/meter/root/meter-root.d.ts +13 -0
  152. package/dist/meter/root/meter-root.js +24 -5
  153. package/dist/navigation/root/navigation-root.d.ts +10 -2
  154. package/dist/navigation/root/navigation-root.js +13 -2
  155. package/dist/notifications/feed-keys.d.ts +10 -0
  156. package/dist/notifications/feed-keys.js +14 -0
  157. package/dist/notifications/group/notification-group.d.ts +1 -0
  158. package/dist/notifications/notification/notification.d.ts +29 -0
  159. package/dist/notifications/notification/notification.js +51 -3
  160. package/dist/notifications/root/notifications-root.d.ts +49 -0
  161. package/dist/notifications/root/notifications-root.js +76 -2
  162. package/dist/number-input/root/number-input-root.d.ts +109 -7
  163. package/dist/number-input/root/number-input-root.js +109 -21
  164. package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
  165. package/dist/object-inspector/root/object-inspector-root.js +92 -12
  166. package/dist/option/root/option-root.d.ts +58 -6
  167. package/dist/option/root/option-root.js +35 -5
  168. package/dist/outline/root/outline-root.d.ts +13 -2
  169. package/dist/outline/root/outline-root.js +4 -2
  170. package/dist/pagination/root/pagination-root.d.ts +19 -1
  171. package/dist/pagination/root/pagination-root.js +49 -9
  172. package/dist/pagination/size/pagination-size.d.ts +13 -3
  173. package/dist/pagination/size/pagination-size.js +7 -0
  174. package/dist/pin-input/format.d.ts +7 -0
  175. package/dist/pin-input/format.js +16 -0
  176. package/dist/pin-input/root/pin-input-root.d.ts +37 -0
  177. package/dist/pin-input/root/pin-input-root.js +48 -7
  178. package/dist/popover/root/popover-root.d.ts +78 -3
  179. package/dist/popover/root/popover-root.js +74 -5
  180. package/dist/progress/root/progress-root.d.ts +23 -1
  181. package/dist/progress/root/progress-root.js +40 -10
  182. package/dist/qr-code/export.d.ts +31 -0
  183. package/dist/qr-code/export.js +10 -0
  184. package/dist/qr-code/root/qr-code-root.d.ts +45 -0
  185. package/dist/qr-code/root/qr-code-root.js +78 -3
  186. package/dist/radio/group/radio-group.d.ts +64 -0
  187. package/dist/radio/group/radio-group.js +66 -12
  188. package/dist/radio/root/radio-root.d.ts +8 -5
  189. package/dist/radio/root/radio-root.js +1 -2
  190. package/dist/rating/root/rating-root.d.ts +49 -1
  191. package/dist/rating/root/rating-root.js +69 -10
  192. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  193. package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
  194. package/dist/select/root/select-root.d.ts +93 -3
  195. package/dist/select/root/select-root.js +111 -13
  196. package/dist/skeleton/root/skeleton-root.d.ts +39 -3
  197. package/dist/skeleton/root/skeleton-root.js +33 -4
  198. package/dist/skip-link/root/skip-link-root.d.ts +10 -0
  199. package/dist/skip-link/root/skip-link-root.js +15 -1
  200. package/dist/slider/root/slider-root.d.ts +59 -2
  201. package/dist/slider/root/slider-root.js +82 -8
  202. package/dist/sparkline/root/sparkline-root.d.ts +9 -10
  203. package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
  204. package/dist/speed-dial/item/speed-dial-item.js +7 -2
  205. package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
  206. package/dist/speed-dial/root/speed-dial-root.js +19 -5
  207. package/dist/splitter/root/splitter-root.d.ts +28 -6
  208. package/dist/splitter/root/splitter-root.js +35 -1
  209. package/dist/stat/root/stat-root.d.ts +9 -1
  210. package/dist/stat/root/stat-root.js +15 -2
  211. package/dist/steps/root/steps-root.js +1 -1
  212. package/dist/steps/step/step.d.ts +1 -0
  213. package/dist/steps/step/step.js +1 -1
  214. package/dist/switch/root/switch-root.d.ts +14 -2
  215. package/dist/switch/root/switch-root.js +7 -1
  216. package/dist/table/cell/table-cell.d.ts +24 -4
  217. package/dist/table/cell/table-cell.js +21 -1
  218. package/dist/table/column/table-column.d.ts +32 -6
  219. package/dist/table/column/table-column.js +36 -6
  220. package/dist/table/root/table-root.d.ts +94 -3
  221. package/dist/table/root/table-root.js +128 -5
  222. package/dist/table/row/table-row.d.ts +7 -0
  223. package/dist/table/row/table-row.js +9 -1
  224. package/dist/tabs/root/tabs-root.d.ts +6 -1
  225. package/dist/tabs/root/tabs-root.js +6 -2
  226. package/dist/tag/group/tag-group.d.ts +107 -0
  227. package/dist/tag/group/tag-group.js +157 -0
  228. package/dist/tag/index.d.ts +1 -0
  229. package/dist/tag/index.js +1 -0
  230. package/dist/tag/root/tag-root.d.ts +83 -1
  231. package/dist/tag/root/tag-root.js +87 -17
  232. package/dist/tag/selection.d.ts +10 -0
  233. package/dist/tag/selection.js +12 -0
  234. package/dist/textarea/grow.d.ts +22 -0
  235. package/dist/textarea/grow.js +20 -0
  236. package/dist/textarea/root/textarea-root.d.ts +13 -0
  237. package/dist/textarea/root/textarea-root.js +10 -2
  238. package/dist/time-input/root/time-input-root.d.ts +71 -6
  239. package/dist/time-input/root/time-input-root.js +110 -44
  240. package/dist/time-picker/root/time-picker-root.d.ts +155 -26
  241. package/dist/time-picker/root/time-picker-root.js +192 -63
  242. package/dist/toast/hotkey.d.ts +22 -0
  243. package/dist/toast/hotkey.js +23 -0
  244. package/dist/toast/item/toast-item.d.ts +16 -1
  245. package/dist/toast/item/toast-item.js +41 -13
  246. package/dist/toast/root/toast-root.d.ts +105 -8
  247. package/dist/toast/root/toast-root.js +209 -4
  248. package/dist/toggle/group/toggle-group.d.ts +95 -16
  249. package/dist/toggle/group/toggle-group.js +99 -13
  250. package/dist/toggle/root/toggle-root.d.ts +26 -11
  251. package/dist/toggle/root/toggle-root.js +14 -6
  252. package/dist/toolbar/root/toolbar-root.d.ts +55 -15
  253. package/dist/toolbar/root/toolbar-root.js +99 -16
  254. package/dist/tooltip/focus-target.d.ts +6 -0
  255. package/dist/tooltip/focus-target.js +9 -0
  256. package/dist/tooltip/root/tooltip-root.d.ts +73 -15
  257. package/dist/tooltip/root/tooltip-root.js +96 -7
  258. package/dist/tour/naming.d.ts +30 -0
  259. package/dist/tour/naming.js +10 -0
  260. package/dist/tour/root/tour-root.d.ts +67 -3
  261. package/dist/tour/root/tour-root.js +105 -17
  262. package/dist/tour/stop/tour-stop.d.ts +65 -3
  263. package/dist/tour/stop/tour-stop.js +61 -11
  264. package/dist/tour/wait.d.ts +11 -0
  265. package/dist/tour/wait.js +19 -0
  266. package/dist/tree/item/tree-item.d.ts +21 -5
  267. package/dist/tree/item/tree-item.js +14 -4
  268. package/dist/tree/root/tree-root.d.ts +29 -5
  269. package/dist/tree/root/tree-root.js +64 -8
  270. package/dist/trend/root/trend-root.d.ts +36 -1
  271. package/dist/trend/root/trend-root.js +41 -15
  272. package/dist/video/root/keys.d.ts +5 -0
  273. package/dist/video/root/keys.js +13 -1
  274. package/dist/video/root/video-root.d.ts +19 -0
  275. package/dist/video/root/video-root.js +48 -4
  276. package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
  277. package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
  278. package/dist/video-playlist/root/video-playlist-root.js +6 -3
  279. package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
  280. package/dist/virtual-list/root/virtual-list-root.js +103 -21
  281. package/lint.json +1 -1
  282. package/package.json +5 -5
  283. package/types/jsx.d.ts +9140 -1149
  284. package/types/svelte.d.ts +1 -0
  285. package/types/vue.d.ts +2089 -267
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * @summary One measurement, with a label that names what it measures.
5
5
  *
@@ -21,6 +21,8 @@ import { type TemplateResult } from 'lit';
21
21
  * @slot - The value.
22
22
  * @slot label - What the value measures.
23
23
  * @slot unit - The unit, shown beside the value.
24
+ *
25
+ * @csspart value - The slot the value is written in. A slot draws no box, so it takes the inherited properties, such as color and font, and passes them to the value.
24
26
  */
25
27
  export declare class HelixHeadlessStat extends HelixElement {
26
28
  /**
@@ -38,6 +40,11 @@ export declare class HelixHeadlessStat extends HelixElement {
38
40
  * the value's baseline whichever way the pair goes, and only this element
39
41
  * knows which of its children the unit belongs to.
40
42
  *
43
+ * **`Trend` has a `direction` too, and there it means which way a number
44
+ * moved:** `up`, `down` or `neutral`. A Stat and a Trend are often written
45
+ * side by side, so watch for the mix-up. On a Stat those three words are not
46
+ * layouts, and the pair stays the column.
47
+ *
41
48
  * **Optional rather than defaulted to `column`, which is not a style
42
49
  * preference.** A reflecting property with a default writes its attribute onto
43
50
  * the host the moment the element upgrades, and the host is markup the
@@ -47,6 +54,7 @@ export declare class HelixHeadlessStat extends HelixElement {
47
54
  * carries nothing nobody wrote.
48
55
  */
49
56
  direction?: 'column-reverse' | 'row' | 'row-reverse';
57
+ protected updated(changed: PropertyValues): void;
50
58
  protected render(): TemplateResult;
51
59
  }
52
60
  declare global {
@@ -4,13 +4,26 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixElement } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, reportRuntime } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessStat = class HelixHeadlessStat extends HelixElement {
11
+ updated(changed) {
12
+ super.updated(changed);
13
+ const given = this.direction;
14
+ if (changed.has('direction') && (given === 'up' || given === 'down' || given === 'neutral')) {
15
+ reportRuntime({
16
+ kind: 'misread-direction',
17
+ message: `<${this.localName} direction="${given}"> lays out as the column: \`${given}\` is a ` +
18
+ "direction of Trend's, which says which way a number moved. Put it on the " +
19
+ '`helix-trend` beside the stat.',
20
+ tag: this.localName,
21
+ });
22
+ }
23
+ }
11
24
  render() {
12
25
  return html `<slot name="label"></slot>
13
- <slot></slot>
26
+ <slot part="value"></slot>
14
27
  <slot name="unit"></slot>`;
15
28
  }
16
29
  };
@@ -12,7 +12,7 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
12
12
  super(...arguments);
13
13
  this.label = 'Steps';
14
14
  this.handleSelection = (event) => {
15
- if (event.defaultPrevented) {
15
+ if (event.defaultPrevented || !this.steps.includes(event.target)) {
16
16
  return;
17
17
  }
18
18
  this.requestActive(event.detail.value);
@@ -38,6 +38,7 @@ import '../../button/index.js';
38
38
  * @csspart description - The line under the name.
39
39
  * @csspart label - The step's name, which is a control.
40
40
  * @csspart label-button - The button inside the label.
41
+ * @csspart label-live - The live region inside that button, rendered only from the first time the button is pending.
41
42
  * @csspart label-text - The words on that button, trimmed to their capitals and baseline.
42
43
  * @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
43
44
  * @csspart marker - The shape carrying the number or the check.
@@ -40,7 +40,7 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
40
40
  renderLabel() {
41
41
  return html `<${this.tag('button')}
42
42
  part="label"
43
- exportparts="button: label-button, text: label-text"
43
+ exportparts="button: label-button, live: label-live, text: label-text"
44
44
  emphasis="ghost"
45
45
  ?disabled=${this.disabled}
46
46
  @click=${this.select}
@@ -1,5 +1,5 @@
1
1
  import { AriaForwardController, HelixFormElement, HostClickController } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerCheckedInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
4
4
  /**
5
5
  * @summary A control that turns something on or off.
@@ -25,6 +25,8 @@ declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion
25
25
  * @documentation https://fusion.dev/helix/components/switch
26
26
  *
27
27
  * @slot - The label that names what the switch turns on.
28
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
29
+ * @slot hint - Help under the control, for content richer than the `hint` text.
28
30
  *
29
31
  * @event {Event} change - Sent from the input after the state changes.
30
32
  * @event {HelixBeforeToggleEvent} helix-before-toggle - Fired before the state changes, and cancelable.
@@ -38,7 +40,9 @@ declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion
38
40
  * @csspart track - The track. Draw the thumb on the track itself, with
39
41
  * `::part(track)::after` in your stylesheet. This tier ships no CSS, so it
40
42
  * renders no separate thumb element, which would be an empty child that costs
41
- * your layout as much as any other child. `ListItem` measured that cost.
43
+ * your layout as much as any other child. `ListItem` measured that cost. A
44
+ * subclass that draws one returns it from `renderThumb`, as the styled switch
45
+ * does.
42
46
  *
43
47
  * @cssstate checked - While it is on.
44
48
  * @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
@@ -68,6 +72,14 @@ export declare class HelixHeadlessSwitch extends HelixHeadlessSwitch_base {
68
72
  * rendered, which React reports on hydration and does not patch up.
69
73
  */
70
74
  private markEmpty;
75
+ /**
76
+ * The thumb, drawn inside the track after the input: nothing on this tier.
77
+ *
78
+ * A seam for a tier that draws the thumb as an element, so it can be a part
79
+ * and hold icons. An element here would be an empty child on every page that
80
+ * loads only this tier, which is the cost the `track` part notes.
81
+ */
82
+ protected renderThumb(): TemplateResult | typeof nothing;
71
83
  protected render(): TemplateResult;
72
84
  }
73
85
  declare global {
@@ -11,6 +11,7 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.aria = new AriaForwardController(this, {
14
+ label: true,
14
15
  target: () => this.partNamed('control'),
15
16
  });
16
17
  this.clicks = new HostClickController(this, () => this.partNamed('control'));
@@ -42,6 +43,9 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
42
43
  markEmpty() {
43
44
  markRegion(this.renderRoot, 'label', ['']);
44
45
  }
46
+ renderThumb() {
47
+ return nothing;
48
+ }
45
49
  render() {
46
50
  return html `<label part="field">
47
51
  <span part="track">
@@ -54,9 +58,11 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
54
58
  ?required=${this.required}
55
59
  aria-describedby=${this.describedBy ?? nothing}
56
60
  aria-invalid=${this.invalidity ?? nothing}
61
+ aria-readonly=${this.readOnly ? 'true' : nothing}
57
62
  @change=${this.handleChange}
63
+ @click=${this.holdReadOnly}
58
64
  @input=${this.stopInner}
59
- />
65
+ />${this.renderThumb()}
60
66
  </span>
61
67
  <span part="label"><slot>${this.label}</slot></span>
62
68
  </label>
@@ -5,9 +5,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
5
5
  *
6
6
  * @description
7
7
  * Sets its own role, because a grid of elements has no table structure for
8
- * assistive technology otherwise. `header` makes the cell a `columnheader`, so
9
- * a screen reader announces the heading with the value, for example "Attribute,
10
- * appearance".
8
+ * assistive technology otherwise. `header` makes the cell a header, so a screen
9
+ * reader announces it with the values it heads:
10
+ *
11
+ * - In a row that holds a cell without `header`, it is a `rowheader` and names
12
+ * its row, for example "web-app" in a row of a service's values.
13
+ * - In a row of `header` cells alone, it is a `columnheader`, which is what a
14
+ * table with no `TableColumn` heads its columns with.
11
15
  *
12
16
  * The role is on the host so the cell stays a child of its row in the flat
13
17
  * tree, which keeps the table structure intact.
@@ -25,10 +29,26 @@ import { type PropertyValues, type TemplateResult } from 'lit';
25
29
  */
26
30
  export declare class HelixHeadlessTableCell extends HelixElement {
27
31
  /**
28
- * Whether the cell is the header cell of its column.
32
+ * Whether the cell is a header: of its row in a row of values, and of its
33
+ * column in a row of headers alone.
29
34
  */
30
35
  header: boolean;
36
+ /**
37
+ * @internal Read by the row and by the cells beside it, to tell a header
38
+ * cell from a value. Not a consumer's to read or set.
39
+ */
40
+ readonly isTableCell = true;
41
+ /**
42
+ * Whether this cell, as a header, heads its row: true where the row also
43
+ * holds a cell that is not a header.
44
+ *
45
+ * The rule a browser applies to a `<th>` with no `scope`. Read from the
46
+ * siblings, which a server does not have, so a server render waits for the
47
+ * client to say which.
48
+ */
49
+ private get headsRow();
31
50
  protected willUpdate(changed: PropertyValues): void;
51
+ protected updated(changed: PropertyValues): void;
32
52
  /**
33
53
  * Sets the `text` state from the cell's own content.
34
54
  *
@@ -11,14 +11,34 @@ let HelixHeadlessTableCell = class HelixHeadlessTableCell extends HelixElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.header = false;
14
+ this.isTableCell = true;
14
15
  this.handleSlotChange = () => {
15
16
  const text = [...this.childNodes].some((node) => node.nodeType === Node.TEXT_NODE && (node.textContent ?? '').trim() !== '');
16
17
  this.toggleState('text', text);
17
18
  };
18
19
  }
20
+ get headsRow() {
21
+ const siblings = [...(this.parentElement?.children ?? [])];
22
+ return siblings.some((sibling) => sibling !== this &&
23
+ 'isTableCell' in sibling &&
24
+ !sibling.hasAttribute('header') &&
25
+ sibling.header !== true);
26
+ }
19
27
  willUpdate(changed) {
20
28
  super.willUpdate(changed);
21
- hostAria(this.internals, { role: this.header ? 'columnheader' : 'cell' });
29
+ const header = this.headsRow ? 'rowheader' : 'columnheader';
30
+ hostAria(this.internals, { role: this.header ? header : 'cell' });
31
+ }
32
+ updated(changed) {
33
+ super.updated(changed);
34
+ if (changed.has('header') && changed.get('header') !== undefined) {
35
+ for (const sibling of this.parentElement?.children ?? []) {
36
+ if (sibling !== this && 'isTableCell' in sibling) {
37
+ ;
38
+ sibling.requestUpdate();
39
+ }
40
+ }
41
+ }
22
42
  }
23
43
  render() {
24
44
  return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
@@ -68,12 +68,13 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
68
68
  * them with the column: a row with more cells than the table has tracks wraps
69
69
  * onto the next line.
70
70
  *
71
- * A heading that does something holds a control. A column header is not
72
- * focusable, so a sortable heading contains a `<button>`, which is the pattern
73
- * for a sortable table and the only way to reach the sort by keyboard. A
74
- * resizable column has a `separator` on its end edge, moved by dragging or with
75
- * the arrow keys. In a table with reorderable columns, each column has a grip
76
- * that the table moves.
71
+ * A heading that does something holds a control. In a `Table` a column
72
+ * header is not focusable, so a sortable heading contains a `<button>`, which
73
+ * is the pattern for a sortable table and the only way to reach the sort by
74
+ * keyboard. In a `DataTable` the heading is a cell of the grid, reached with
75
+ * the arrow keys, and its controls with Enter or F2. A resizable column has a
76
+ * `separator` on its end edge, moved by dragging or with the arrow keys. In a
77
+ * table with reorderable columns, each column has a grip that the table moves.
77
78
  *
78
79
  * @since 0.1.0
79
80
  * @status stable
@@ -254,6 +255,21 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
254
255
  * on a column the table will not move is a control that does nothing.
255
256
  */
256
257
  movable: boolean;
258
+ /**
259
+ * @internal Whether the column is a cell of a grid that moves focus between
260
+ * its cells, written by that table. Not a consumer's to set.
261
+ *
262
+ * **The heading's box takes the role and the focus.** The column element has
263
+ * no box, being `display: contents`, and an element with no box cannot be
264
+ * focused, so in a grid the `columnheader` role, `aria-sort` and the focus all
265
+ * go to `[part="column"]`, and the controls on it leave the tab order.
266
+ */
267
+ gridCell: boolean;
268
+ /**
269
+ * @internal Whether the heading is the grid's one tab stop, written by the
270
+ * table that sets `gridCell`. Not a consumer's to set.
271
+ */
272
+ tabStop: boolean;
257
273
  /** How wide the heading drew, for the separator to report. */
258
274
  private drawn;
259
275
  /** Where a drag of the separator started, while one is running. */
@@ -300,6 +316,16 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
300
316
  */
301
317
  order(row: Readonly<Record<string, unknown>>): unknown;
302
318
  protected willUpdate(changed: PropertyValues): void;
319
+ /**
320
+ * @internal The box a grid focuses for this heading, read by the table that
321
+ * sets `gridCell`. Not a consumer's to call.
322
+ */
323
+ get cellBox(): HTMLElement | null;
324
+ /**
325
+ * @internal The controls on the heading, in order, read by the table that
326
+ * sets `gridCell` to move focus into them. Not a consumer's to call.
327
+ */
328
+ get controls(): HTMLElement[];
303
329
  /** The words of the heading, for naming the controls on it. */
304
330
  private get name();
305
331
  connectedCallback(): void;
@@ -43,6 +43,8 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
43
43
  this.isTableColumn = true;
44
44
  this.sorted = undefined;
45
45
  this.movable = false;
46
+ this.gridCell = false;
47
+ this.tabStop = false;
46
48
  this.drawn = 0;
47
49
  this.handleResizeStart = (event) => {
48
50
  if (event.button !== 0) {
@@ -101,11 +103,25 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
101
103
  }
102
104
  willUpdate(changed) {
103
105
  super.willUpdate(changed);
104
- hostAria(this.internals, { role: 'columnheader' });
105
- this.internals.ariaSort = this.canSort ? (this.sorted ?? 'none') : null;
106
+ const named = this.movable || this.resizable;
107
+ const host = !this.gridCell;
108
+ hostAria(this.internals, {
109
+ label: host && named ? this.name : '',
110
+ role: host ? 'columnheader' : '',
111
+ });
112
+ this.internals.ariaSort = host && this.canSort ? (this.sorted ?? 'none') : null;
106
113
  this.toggleState('sorted-ascending', this.sorted === 'ascending');
107
114
  this.toggleState('sorted-descending', this.sorted === 'descending');
108
115
  }
116
+ get cellBox() {
117
+ return this.partNamed('column');
118
+ }
119
+ get controls() {
120
+ return ['grip', 'sort', 'resizer'].flatMap((name) => {
121
+ const control = this.partNamed(name);
122
+ return control ? [control] : [];
123
+ });
124
+ }
109
125
  get name() {
110
126
  return this.textContent?.trim() ?? '';
111
127
  }
@@ -167,19 +183,27 @@ let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixEleme
167
183
  }
168
184
  render() {
169
185
  const name = this.name;
170
- return html `<span part="column">${this.movable
171
- ? html `<button part="grip" type="button" aria-label=${fillTemplate(this.moveLabel, { name: name || 'column' })}>
186
+ const grid = this.gridCell;
187
+ const control = grid ? '-1' : nothing;
188
+ return html `<span
189
+ part="column"
190
+ role=${grid ? 'columnheader' : nothing}
191
+ tabindex=${grid ? (this.tabStop ? '0' : '-1') : nothing}
192
+ aria-sort=${grid && this.canSort ? (this.sorted ?? 'none') : nothing}
193
+ aria-label=${grid && (this.movable || this.resizable) && name ? name : nothing}
194
+ >${this.movable
195
+ ? html `<button part="grip" type="button" tabindex=${control} aria-label=${fillTemplate(this.moveLabel, { name: name || 'column' })}>
172
196
  <svg aria-hidden="true" fill="currentColor" part="grip-mark" viewBox=${dotsThreeVertical.viewBox}>
173
197
  ${unsafeSVG(dotsThreeVertical.content)}
174
198
  </svg>
175
199
  </button>`
176
200
  : nothing}${this.canSort
177
- ? html `<button part="sort" type="button"><slot></slot></button>`
201
+ ? html `<button part="sort" type="button" tabindex=${control}><slot></slot></button>`
178
202
  : html `<slot></slot>`}${this.resizable
179
203
  ? html `<span
180
204
  part="resizer"
181
205
  role="separator"
182
- tabindex="0"
206
+ tabindex=${grid ? '-1' : '0'}
183
207
  aria-label=${fillTemplate(this.resizeLabel, { name: name || 'column' })}
184
208
  aria-orientation="vertical"
185
209
  aria-valuemin=${HelixHeadlessTableColumn_1.NARROWEST}
@@ -231,6 +255,12 @@ __decorate([
231
255
  __decorate([
232
256
  state()
233
257
  ], HelixHeadlessTableColumn.prototype, "movable", void 0);
258
+ __decorate([
259
+ state()
260
+ ], HelixHeadlessTableColumn.prototype, "gridCell", void 0);
261
+ __decorate([
262
+ state()
263
+ ], HelixHeadlessTableColumn.prototype, "tabStop", void 0);
234
264
  __decorate([
235
265
  state()
236
266
  ], HelixHeadlessTableColumn.prototype, "drawn", void 0);
@@ -1,4 +1,4 @@
1
- import { HelixElement } from '@fusion.dev/helix-core';
1
+ import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import { type HelixHeadlessTableColumn } from '../column/table-column.js';
4
4
  declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & typeof HelixElement;
@@ -12,8 +12,14 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
12
12
  * else.
13
13
  *
14
14
  * A grid of elements has no table structure for assistive technology, so the
15
- * roles are set explicitly: `table`, `row`, `cell`, and `columnheader`. Rows
16
- * are `display: contents`, so their cells become items of the one grid.
15
+ * roles are set explicitly: `table`, `row`, `cell`, `columnheader`, and
16
+ * `rowheader` for a `header` cell in a row of values. Rows are
17
+ * `display: contents`, so their cells become items of the one grid.
18
+ *
19
+ * A column with `sortable` and a `field` sorts the rows by the text of its
20
+ * cells, numbers by their value. Your markup is not reordered: the table draws
21
+ * the rows in the sorted order. `helix-sort` asks first, so you can refuse it
22
+ * and reorder the rows yourself.
17
23
  *
18
24
  * The CSS custom properties listed for this component are written by it and
19
25
  * read by the stylesheet that draws it. Do not set them. Each holds a number
@@ -28,6 +34,8 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
28
34
  *
29
35
  * @slot - The table's rows.
30
36
  *
37
+ * @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.
38
+ *
31
39
  * @csspart empty - The text shown when there are no rows.
32
40
  * @csspart head - The row that holds the column headings. It has `display: contents`, so it takes no space of its own.
33
41
  * @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.
@@ -37,6 +45,8 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
37
45
  * @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.
38
46
  */
39
47
  export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
48
+ /** The word for an ascending sort, in `sorted-label`. */
49
+ ascendingLabel: string;
40
50
  /**
41
51
  * The column widths as one track list, written once on the table.
42
52
  *
@@ -68,10 +78,90 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
68
78
  * declared in it has nowhere else to be sized from.
69
79
  */
70
80
  columns: string;
81
+ /**
82
+ * The starting sort order, used until `sort` is set.
83
+ */
84
+ defaultSort: string;
85
+ /** The word for a descending sort, in `sorted-label`. */
86
+ descendingLabel: string;
71
87
  /**
72
88
  * Accessible name for the table.
89
+ *
90
+ * An `aria-label` or `aria-labelledby` on the host names the table too, and
91
+ * wins over this.
73
92
  */
74
93
  label: string;
94
+ /**
95
+ * The sort order, as `field:direction`, where `field` is a sortable column's
96
+ * `field`.
97
+ *
98
+ * The rows are compared by the text of their cells in that column, numbers by
99
+ * their value. A reader's click on a sortable heading fires `helix-sort`
100
+ * first, and refusing it leaves the order as it was. `default-sort` seeds an
101
+ * order this element then owns.
102
+ */
103
+ get sort(): string;
104
+ set sort(next: string);
105
+ /**
106
+ * What screen readers hear when the table is sorted. `{column}` is the
107
+ * column's heading and `{order}` is `ascending-label` or `descending-label`.
108
+ */
109
+ sortedLabel: string;
110
+ /** What screen readers hear when the table stops being sorted. */
111
+ unsortedLabel: string;
112
+ private sortState;
113
+ /**
114
+ * Carries a host `aria-label` and `aria-labelledby` to the grid, which is
115
+ * the element with the `table` role.
116
+ *
117
+ * A heading the table is named by is the consumer's markup, beside the
118
+ * host, and an IDREF on the host named a generic wrapper while the table
119
+ * itself kept its default name.
120
+ */
121
+ protected readonly aria: AriaForwardController;
122
+ /**
123
+ * Asks for a different order, and reports whether the request stood.
124
+ */
125
+ private requestSort;
126
+ /**
127
+ * Cycles the sort order of one column, as a click on its heading does.
128
+ *
129
+ * Ascending, descending, then the order the rows were written in.
130
+ */
131
+ toggleSort(field: string): boolean;
132
+ /**
133
+ * The rows in the order they are drawn: sorted by `sort`, and as written
134
+ * where there is no sort.
135
+ *
136
+ * **Drawn in order by assignment.** A manually assigned slot draws its nodes
137
+ * in the order they were assigned, so the rows move on screen and in the
138
+ * accessibility tree while the consumer's markup stays as it was written,
139
+ * which is what a framework holding those rows needs.
140
+ */
141
+ private get arrangedRows();
142
+ /** The sort last heard, so a render that changed nothing says nothing. */
143
+ private heardSort;
144
+ /**
145
+ * What the table says after a sort, once, in the collection's live region.
146
+ *
147
+ * A reader on a heading's button is not told that `aria-sort` moved, so the
148
+ * new order is said. Not on the first render, which is the table arriving.
149
+ */
150
+ private news;
151
+ /**
152
+ * Tells each column which way it is ordered, if it is the one.
153
+ *
154
+ * The table owns the sort and the column carries `aria-sort`, the same
155
+ * arrangement `DataTable` has.
156
+ */
157
+ private markSorted;
158
+ /**
159
+ * A click on a sortable heading's button.
160
+ *
161
+ * Enter and Space arrive here too, as the click the button makes of them.
162
+ * Only the button sorts: a click on a column's separator is a resize.
163
+ */
164
+ private readonly handleHeadClick;
75
165
  /** The columns declared as children, in the order they are written. */
76
166
  get tableColumns(): HelixHeadlessTableColumn[];
77
167
  /**
@@ -186,6 +276,7 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
186
276
  * take the outer column's edge for columns of its own that set none.
187
277
  */
188
278
  private alignCells;
279
+ protected willUpdate(changed: PropertyValues): void;
189
280
  protected updated(changed: PropertyValues): void;
190
281
  protected render(): TemplateResult;
191
282
  }