@fusion.dev/helix-headless 0.146.0 → 0.147.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/custom-elements.json +5266 -785
  2. package/dist/accordion/item/accordion-item.d.ts +38 -19
  3. package/dist/accordion/item/accordion-item.js +31 -9
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +3 -3
  6. package/dist/announcement/root/announcement-root.d.ts +13 -4
  7. package/dist/announcement/root/announcement-root.js +34 -6
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +11 -3
  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/root/badge-root.d.ts +57 -6
  13. package/dist/badge/root/badge-root.js +88 -5
  14. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  15. package/dist/bar-chart/stack.d.ts +10 -0
  16. package/dist/bar-chart/stack.js +8 -0
  17. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  18. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  19. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  20. package/dist/button/root/button-root.d.ts +24 -38
  21. package/dist/button/root/button-root.js +6 -37
  22. package/dist/button/submitter.d.ts +27 -0
  23. package/dist/button/submitter.js +25 -0
  24. package/dist/card/root/card-root.d.ts +12 -1
  25. package/dist/card/root/card-root.js +11 -4
  26. package/dist/chat/root/chat-root.d.ts +15 -1
  27. package/dist/chat/root/chat-root.js +11 -2
  28. package/dist/checkbox/root/checkbox-root.js +5 -7
  29. package/dist/checkbox-group/root/checkbox-group-root.js +4 -3
  30. package/dist/checkbox-group/select-all.d.ts +0 -6
  31. package/dist/checkbox-group/select-all.js +0 -5
  32. package/dist/code-block/root/code-block-root.d.ts +35 -14
  33. package/dist/code-block/root/code-block-root.js +17 -3
  34. package/dist/color-input/root/color-input-root.d.ts +11 -0
  35. package/dist/color-input/root/color-input-root.js +12 -5
  36. package/dist/color-picker/channels.js +1 -2
  37. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  38. package/dist/color-picker/root/color-picker-root.js +101 -51
  39. package/dist/color-picker/wheel.d.ts +17 -0
  40. package/dist/color-picker/wheel.js +6 -0
  41. package/dist/combobox/root/combobox-root.d.ts +13 -0
  42. package/dist/combobox/root/combobox-root.js +14 -1
  43. package/dist/command/root/command-root.d.ts +3 -1
  44. package/dist/command/root/command-root.js +2 -19
  45. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  46. package/dist/copy-button/root/copy-button-root.js +7 -2
  47. package/dist/data-table/keys.d.ts +0 -18
  48. package/dist/data-table/keys.js +1 -11
  49. package/dist/data-table/root/data-table-root.js +13 -7
  50. package/dist/date-input/root/date-input-root.d.ts +8 -1
  51. package/dist/date-input/root/date-input-root.js +8 -5
  52. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  53. package/dist/date-picker/root/date-picker-root.js +21 -16
  54. package/dist/description-list/item/description-list-item.d.ts +18 -4
  55. package/dist/description-list/item/description-list-item.js +8 -4
  56. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  57. package/dist/donut-chart/slice-label.d.ts +35 -0
  58. package/dist/donut-chart/slice-label.js +11 -0
  59. package/dist/drawer/root/drawer-root.d.ts +4 -2
  60. package/dist/drawer/root/drawer-root.js +15 -3
  61. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  62. package/dist/drilldown/item/drilldown-item.js +39 -4
  63. package/dist/drilldown/root/drilldown-root.js +3 -2
  64. package/dist/element-events.generated.js +4 -1
  65. package/dist/empty/root/empty-root.d.ts +31 -1
  66. package/dist/empty/root/empty-root.js +26 -5
  67. package/dist/file-input/root/file-input-root.d.ts +34 -6
  68. package/dist/file-input/root/file-input-root.js +54 -19
  69. package/dist/file-input/status.d.ts +24 -0
  70. package/dist/file-input/status.js +10 -0
  71. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  72. package/dist/filter-input/chip/filter-chip.js +11 -2
  73. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  74. package/dist/filter-input/root/filter-input-root.js +17 -27
  75. package/dist/format-date/options.d.ts +3 -4
  76. package/dist/format-date/options.js +2 -2
  77. package/dist/format-date/root/format-date-root.d.ts +18 -1
  78. package/dist/format-date/root/format-date-root.js +19 -23
  79. package/dist/heatmap/root/buckets.d.ts +21 -0
  80. package/dist/heatmap/root/buckets.js +34 -0
  81. package/dist/heatmap/root/heatmap-root.d.ts +64 -3
  82. package/dist/heatmap/root/heatmap-root.js +89 -19
  83. package/dist/icon/index.d.ts +1 -1
  84. package/dist/icon/index.js +1 -1
  85. package/dist/icon/registry.d.ts +26 -1
  86. package/dist/icon/registry.js +12 -1
  87. package/dist/icon/root/icon-root.d.ts +13 -0
  88. package/dist/icon/root/icon-root.js +23 -2
  89. package/dist/icon/root/index.d.ts +1 -1
  90. package/dist/icon/root/index.js +1 -1
  91. package/dist/image/root/image-root.d.ts +9 -0
  92. package/dist/image/root/image-root.js +6 -1
  93. package/dist/input/root/input-root.d.ts +23 -2
  94. package/dist/input/root/input-root.js +12 -8
  95. package/dist/kbd/keys.d.ts +29 -0
  96. package/dist/kbd/keys.js +52 -0
  97. package/dist/kbd/root/kbd-root.d.ts +20 -3
  98. package/dist/kbd/root/kbd-root.js +24 -50
  99. package/dist/legend/hidden-series.d.ts +10 -2
  100. package/dist/legend/hidden-series.js +5 -2
  101. package/dist/legend/root/legend-root.d.ts +25 -7
  102. package/dist/legend/root/legend-root.js +22 -10
  103. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  104. package/dist/lightbox/root/lightbox-root.js +76 -8
  105. package/dist/lightbox/zoom.d.ts +2 -0
  106. package/dist/lightbox/zoom.js +5 -3
  107. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  108. package/dist/line-chart/root/line-chart-root.js +10 -2
  109. package/dist/list/root/list-root.d.ts +10 -2
  110. package/dist/list/root/list-root.js +26 -5
  111. package/dist/list/selection.d.ts +17 -0
  112. package/dist/list/selection.js +16 -0
  113. package/dist/listbox/root/listbox-root.d.ts +9 -5
  114. package/dist/listbox/root/listbox-root.js +29 -37
  115. package/dist/megamenu/hand-over.d.ts +75 -0
  116. package/dist/megamenu/hand-over.js +67 -0
  117. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  118. package/dist/megamenu/root/megamenu-root.js +36 -50
  119. package/dist/menu/item/menu-item.js +4 -4
  120. package/dist/menu/root/menu-root.d.ts +3 -0
  121. package/dist/meter/root/meter-root.d.ts +42 -0
  122. package/dist/meter/root/meter-root.js +33 -7
  123. package/dist/notifications/root/notifications-root.d.ts +10 -1
  124. package/dist/notifications/root/notifications-root.js +11 -1
  125. package/dist/number-input/grain.d.ts +28 -0
  126. package/dist/number-input/grain.js +14 -0
  127. package/dist/number-input/root/number-input-root.d.ts +17 -1
  128. package/dist/number-input/root/number-input-root.js +29 -18
  129. package/dist/object-inspector/root/object-inspector-root.d.ts +13 -6
  130. package/dist/object-inspector/root/object-inspector-root.js +18 -17
  131. package/dist/option/index.d.ts +1 -0
  132. package/dist/option/index.js +1 -0
  133. package/dist/option/separator/option-separator.d.ts +30 -0
  134. package/dist/option/separator/option-separator.js +21 -0
  135. package/dist/outline/root/outline-root.d.ts +12 -0
  136. package/dist/outline/root/outline-root.js +5 -19
  137. package/dist/pagination/size/pagination-size.d.ts +5 -0
  138. package/dist/pagination/size/pagination-size.js +4 -2
  139. package/dist/pin-input/code.d.ts +28 -1
  140. package/dist/pin-input/code.js +12 -0
  141. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  142. package/dist/pin-input/root/pin-input-root.js +157 -148
  143. package/dist/popover/hide-outside.js +2 -9
  144. package/dist/popover/root/popover-root.d.ts +7 -1
  145. package/dist/popover/root/popover-root.js +9 -1
  146. package/dist/progress/root/progress-root.d.ts +27 -0
  147. package/dist/progress/root/progress-root.js +25 -7
  148. package/dist/qr-code/export.d.ts +19 -0
  149. package/dist/qr-code/export.js +14 -0
  150. package/dist/qr-code/name.d.ts +11 -0
  151. package/dist/qr-code/name.js +7 -0
  152. package/dist/qr-code/root/qr-code-root.d.ts +17 -6
  153. package/dist/qr-code/root/qr-code-root.js +10 -12
  154. package/dist/radio/group/radio-group.d.ts +15 -0
  155. package/dist/radio/root/radio-root.js +2 -2
  156. package/dist/rating/root/rating-root.d.ts +22 -9
  157. package/dist/rating/root/rating-root.js +15 -39
  158. package/dist/scatter-chart/root/scatter-chart-root.d.ts +30 -0
  159. package/dist/scatter-chart/root/scatter-chart-root.js +34 -7
  160. package/dist/scroll-area/scrollbar.d.ts +0 -8
  161. package/dist/scroll-area/scrollbar.js +1 -1
  162. package/dist/select/align.d.ts +47 -0
  163. package/dist/select/align.js +7 -0
  164. package/dist/select/root/select-root.d.ts +59 -3
  165. package/dist/select/root/select-root.js +72 -12
  166. package/dist/slider/root/slider-root.d.ts +18 -1
  167. package/dist/slider/root/slider-root.js +22 -0
  168. package/dist/sparkline/readings.d.ts +30 -12
  169. package/dist/sparkline/readings.js +32 -15
  170. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  171. package/dist/sparkline/root/sparkline-root.js +60 -21
  172. package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
  173. package/dist/speed-dial/item/speed-dial-item.js +2 -2
  174. package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
  175. package/dist/speed-dial/root/speed-dial-root.js +9 -1
  176. package/dist/splitter/root/splitter-root.d.ts +3 -0
  177. package/dist/splitter/root/splitter-root.js +2 -0
  178. package/dist/steps/root/steps-root.d.ts +8 -1
  179. package/dist/steps/root/steps-root.js +6 -1
  180. package/dist/steps/step/step.d.ts +1 -0
  181. package/dist/steps/step/step.js +1 -1
  182. package/dist/table/column/table-column.d.ts +6 -0
  183. package/dist/table/column/table-column.js +5 -1
  184. package/dist/table/root/table-root.js +13 -6
  185. package/dist/table/row/table-row.d.ts +24 -0
  186. package/dist/table/row/table-row.js +37 -1
  187. package/dist/tabs/root/tabs-root.d.ts +5 -3
  188. package/dist/tag/group/tag-group.d.ts +16 -4
  189. package/dist/tag/group/tag-group.js +19 -7
  190. package/dist/textarea/root/textarea-root.d.ts +14 -2
  191. package/dist/textarea/root/textarea-root.js +6 -7
  192. package/dist/time-input/root/time-input-root.d.ts +5 -1
  193. package/dist/time-input/root/time-input-root.js +10 -7
  194. package/dist/time-picker/root/time-picker-root.d.ts +11 -14
  195. package/dist/time-picker/root/time-picker-root.js +15 -23
  196. package/dist/toast/item/toast-item.d.ts +3 -3
  197. package/dist/toast/item/toast-item.js +0 -1
  198. package/dist/toast/root/toast-root.d.ts +28 -4
  199. package/dist/toast/root/toast-root.js +58 -12
  200. package/dist/toast/words.d.ts +12 -0
  201. package/dist/toast/words.js +25 -0
  202. package/dist/toggle/group/toggle-group.d.ts +29 -5
  203. package/dist/toggle/group/toggle-group.js +26 -41
  204. package/dist/toggle/root/toggle-root.js +2 -4
  205. package/dist/toolbar/root/toolbar-root.d.ts +21 -5
  206. package/dist/toolbar/root/toolbar-root.js +52 -8
  207. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  208. package/dist/tooltip/root/tooltip-root.js +10 -1
  209. package/dist/tour/root/tour-root.d.ts +15 -0
  210. package/dist/tour/root/tour-root.js +20 -1
  211. package/dist/tour/stop/tour-stop.d.ts +3 -0
  212. package/dist/tour/stop/tour-stop.js +3 -3
  213. package/dist/tree/root/tree-root.js +2 -2
  214. package/dist/trend/figure.d.ts +16 -0
  215. package/dist/trend/figure.js +8 -0
  216. package/dist/trend/root/trend-root.d.ts +41 -2
  217. package/dist/trend/root/trend-root.js +29 -3
  218. package/dist/video/root/extra-controls.d.ts +12 -0
  219. package/dist/video/root/extra-controls.js +6 -2
  220. package/dist/video/root/video-root.d.ts +5 -1
  221. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  222. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  223. package/dist/virtual-list/fill.d.ts +11 -0
  224. package/dist/virtual-list/fill.js +9 -0
  225. package/dist/virtual-list/keys.d.ts +16 -7
  226. package/dist/virtual-list/keys.js +17 -6
  227. package/dist/virtual-list/plan.d.ts +17 -1
  228. package/dist/virtual-list/plan.js +13 -2
  229. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  230. package/dist/virtual-list/root/virtual-list-root.js +48 -24
  231. package/lint.json +1 -1
  232. package/package.json +5 -5
  233. package/types/jsx.d.ts +2979 -738
  234. package/types/svelte.d.ts +1 -0
  235. package/types/vue.d.ts +619 -202
  236. package/dist/color-picker/swatches.d.ts +0 -12
  237. package/dist/color-picker/swatches.js +0 -26
  238. package/dist/rating/steps.d.ts +0 -7
  239. package/dist/rating/steps.js +0 -9
package/types/vue.d.ts CHANGED
@@ -56,6 +56,7 @@ import type {
56
56
  HelixHeadlessDrilldownItem,
57
57
  HelixHeadlessDrilldown,
58
58
  HelixHeadlessEmpty,
59
+ FileStatus,
59
60
  HelixHeadlessFileInput,
60
61
  HelixHeadlessFilterChip,
61
62
  HelixHeadlessFilterField,
@@ -105,10 +106,13 @@ import type {
105
106
  HelixHeadlessOptionGroup,
106
107
  optionsAmong,
107
108
  HelixHeadlessOption,
109
+ HelixHeadlessOptionSeparator,
108
110
  HelixHeadlessOutline,
109
111
  HelixHeadlessPagination,
110
112
  HelixHeadlessPaginationSize,
111
113
  HelixHeadlessPaginationSummary,
114
+ PinCase,
115
+ PinType,
112
116
  HelixHeadlessPinInput,
113
117
  HelixHeadlessPopover,
114
118
  HelixHeadlessProgress,
@@ -229,6 +233,7 @@ import type {
229
233
  HelixMapTiltEvent,
230
234
  HelixMapZoomEvent,
231
235
  HelixToggleEvent,
236
+ HelixBandEvent,
232
237
  HelixReadEvent,
233
238
  HelixCompleteEvent,
234
239
  HelixPreviewEvent,
@@ -333,18 +338,16 @@ too. */
333
338
  /** Whether find in page searches the section while it is closed, and opens it
334
339
  on a match.
335
340
 
336
- Off by default. A closed section is then `hidden="until-found"`, which
337
- hides through `content-visibility`, so a stylesheet that animates the
338
- section closed shows an empty box for the length of that animation. The
339
- accordion's own `hidden-until-found` turns it on for every section. */
341
+ Unset takes the accordion's `hidden-until-found`, which is on. Write
342
+ `hidden-until-found="false"` to keep find in page out of this section: a
343
+ closed section is then `hidden` and `inert`. */
340
344
  "hidden-until-found"?: (HelixHeadlessAccordionItem["hiddenUntilFound"]) | undefined;
341
345
  /** Whether find in page searches the section while it is closed, and opens it
342
346
  on a match.
343
347
 
344
- Off by default. A closed section is then `hidden="until-found"`, which
345
- hides through `content-visibility`, so a stylesheet that animates the
346
- section closed shows an empty box for the length of that animation. The
347
- accordion's own `hidden-until-found` turns it on for every section. */
348
+ Unset takes the accordion's `hidden-until-found`, which is on. Write
349
+ `hidden-until-found="false"` to keep find in page out of this section: a
350
+ closed section is then `hidden` and `inert`. */
348
351
  hiddenUntilFound?: (HelixHeadlessAccordionItem["hiddenUntilFound"]) | undefined;
349
352
  /** A group name. Opening an item closes the other items with the same name,
350
353
  as `<details name>` does.
@@ -403,12 +406,18 @@ Unset is 3. An item's own `heading-level` wins over this. */
403
406
  Unset is 3. An item's own `heading-level` wins over this. */
404
407
  headingLevel?: (HelixHeadlessAccordion["headingLevel"]) | undefined;
405
408
  /** Whether find in page searches every closed section, and opens the one it
406
- matches in. Each item's own `hidden-until-found` turns it on for that item
407
- alone. */
409
+ matches in.
410
+
411
+ On by default, as in React Aria's disclosure. Write
412
+ `hidden-until-found="false"` to turn it off for every section; an item's
413
+ own `hidden-until-found` wins for that item. */
408
414
  "hidden-until-found"?: (HelixHeadlessAccordion["hiddenUntilFound"]) | undefined;
409
415
  /** Whether find in page searches every closed section, and opens the one it
410
- matches in. Each item's own `hidden-until-found` turns it on for that item
411
- alone. */
416
+ matches in.
417
+
418
+ On by default, as in React Aria's disclosure. Write
419
+ `hidden-until-found="false"` to turn it off for every section; an item's
420
+ own `hidden-until-found` wins for that item. */
412
421
  hiddenUntilFound?: (HelixHeadlessAccordion["hiddenUntilFound"]) | undefined;
413
422
  /** How many sections may be open at once.
414
423
 
@@ -561,6 +570,13 @@ The same three values `LineChart` takes, with the same fallback: a bare
561
570
  rather than under them, because the bands are opaque and a rule under one is
562
571
  a rule nobody sees. */
563
572
  gridlines?: (HelixHeadlessAreaChart["gridlines"]) | undefined;
573
+ /** Draws every band from zero, in front of the next, so a band's height is
574
+ its own part's amount and not its place in a stack.
575
+
576
+ Absent stacks the parts, so the top edge is the total. Set, the first
577
+ column is in front and the scale fits the largest part. Reflected, because
578
+ the styled tier lets the bands behind show through the ones in front. */
579
+ overlap?: (HelixHeadlessAreaChart["overlap"]) | undefined;
564
580
  /** Draws each reading as a hundred percent, so each band shows its share of
565
581
  the total.
566
582
 
@@ -672,6 +688,19 @@ replaces them when it arrives, so a slow connection shows who it is
672
688
  without a cached picture flashing initials first. Radix's `delayMs` is the
673
689
  same idea. */
674
690
  fallbackDelay?: (HelixHeadlessAvatar["fallbackDelay"]) | undefined;
691
+ /** The letters shown where no picture loaded, such as `GH`, in place of the
692
+ ones taken from `name`.
693
+
694
+ For a name whose initials are not its first and last letters, or an
695
+ entity with a short mark of its own. Absent, the first letters of the
696
+ first and last words of `name` are shown. */
697
+ initials?: (HelixHeadlessAvatar["initials"]) | undefined;
698
+ /** When the browser fetches the picture: `lazy` waits until it is near the
699
+ screen, as an `<img loading="lazy">` does, and `eager` fetches it at once.
700
+
701
+ Absent is the browser's own default, which is `eager`. `lazy` suits a long
702
+ list of people, most of them off screen. */
703
+ loading?: (HelixHeadlessAvatar["loading"]) | undefined;
675
704
  /** Name of the person or entity.
676
705
 
677
706
  Used for the label and the initials. */
@@ -701,12 +730,28 @@ export type HelixHeadlessAvatarVueEvents = {
701
730
  };
702
731
 
703
732
  export type HelixHeadlessBadgeVueProps = {
733
+ /** `Intl.NumberFormat` options a count is written with, such as
734
+ `{"notation":"compact"}` for `1.2K`, written as JSON in the attribute.
735
+
736
+ Absent, a count is shown as it was given. Text that is not a number is
737
+ shown as it is either way. */
738
+ "format-options"?: (HelixHeadlessBadge["formatOptions"]) | undefined;
739
+ /** `Intl.NumberFormat` options a count is written with, such as
740
+ `{"notation":"compact"}` for `1.2K`, written as JSON in the attribute.
741
+
742
+ Absent, a count is shown as it was given. Text that is not a number is
743
+ shown as it is either way. */
744
+ formatOptions?: (HelixHeadlessBadge["formatOptions"]) | undefined;
704
745
  /** The badge's name, read by screen readers.
705
746
 
706
747
  Required for a dot, which has no text to read. `{count}` is replaced with
707
748
  what the badge shows, so `label="{count} unread"` reads "8 unread" and
708
749
  stays current as `value` changes, with no label of yours to keep in step. */
709
750
  label?: (HelixHeadlessBadge["label"]) | undefined;
751
+ /** The locale a count is written in under `format-options`, such as `de`.
752
+
753
+ Absent uses the runtime's own. */
754
+ locale?: (HelixHeadlessBadge["locale"]) | undefined;
710
755
  /** The largest number the badge shows.
711
756
 
712
757
  Past it the indicator reads `{max}+`. */
@@ -995,33 +1040,23 @@ is the platform's `commandfor`. */
995
1040
  commandFor?: (HelixHeadlessButton["commandFor"]) | undefined;
996
1041
  /** Where this button's submission goes, overriding the form's own.
997
1042
 
998
- **The five `form*` overrides work by writing the form and putting it back**,
999
- which is the only mechanism available and is closer to the platform than it
1000
- sounds. `requestSubmit(submitter)` is how a native submitter carries these,
1001
- and it refuses ours twice over: the inner `<button>` is `type="button"` so
1002
- it is not a submit button, and it sits in this shadow root so its form owner
1003
- is not the consumer's form. Both throw. So the submission is started with no
1004
- submitter and the overrides are applied to the form for the duration of it.
1005
-
1006
- The whole submit algorithm runs synchronously inside `requestSubmit()`, so
1007
- the window is one call and a `finally` closes it whether or not a listener
1008
- refused. What a `submit` handler observes during that window is the form a
1009
- native submitter would have given it, which is the point. */
1043
+ **The five `form*` overrides ride on a native submit button that stands in
1044
+ for this one**, because `requestSubmit(submitter)` refuses the inner
1045
+ `<button>` twice over: it is `type="button"`, and it sits in this shadow
1046
+ root, so its form owner is not the consumer's form. The stand-in is a
1047
+ hidden `<button type="submit">` in the form for the one synchronous call,
1048
+ so the platform applies the overrides to that submission alone and leaves
1049
+ the form as it was. See `submitAs`. */
1010
1050
  formaction?: (HelixHeadlessButton["formAction"]) | undefined;
1011
1051
  /** Where this button's submission goes, overriding the form's own.
1012
1052
 
1013
- **The five `form*` overrides work by writing the form and putting it back**,
1014
- which is the only mechanism available and is closer to the platform than it
1015
- sounds. `requestSubmit(submitter)` is how a native submitter carries these,
1016
- and it refuses ours twice over: the inner `<button>` is `type="button"` so
1017
- it is not a submit button, and it sits in this shadow root so its form owner
1018
- is not the consumer's form. Both throw. So the submission is started with no
1019
- submitter and the overrides are applied to the form for the duration of it.
1020
-
1021
- The whole submit algorithm runs synchronously inside `requestSubmit()`, so
1022
- the window is one call and a `finally` closes it whether or not a listener
1023
- refused. What a `submit` handler observes during that window is the form a
1024
- native submitter would have given it, which is the point. */
1053
+ **The five `form*` overrides ride on a native submit button that stands in
1054
+ for this one**, because `requestSubmit(submitter)` refuses the inner
1055
+ `<button>` twice over: it is `type="button"`, and it sits in this shadow
1056
+ root, so its form owner is not the consumer's form. The stand-in is a
1057
+ hidden `<button type="submit">` in the form for the one synchronous call,
1058
+ so the platform applies the overrides to that submission alone and leaves
1059
+ the form as it was. See `submitAs`. */
1025
1060
  formAction?: (HelixHeadlessButton["formAction"]) | undefined;
1026
1061
  /** How the submission is encoded, overriding the form's own. */
1027
1062
  formenctype?: (HelixHeadlessButton["formEnctype"]) | undefined;
@@ -1067,13 +1102,10 @@ a press, so focus stays where the reader left it. */
1067
1102
  /** The value this button submits under its own `name`, as a native submit
1068
1103
  button does.
1069
1104
 
1070
- **Reported for exactly the submission this button starts and not otherwise.**
1105
+ **Sent with exactly the submission this button starts and not otherwise.**
1071
1106
  A native submit button contributes `name=value` only when it is the one
1072
- that submitted, and every other button on the form contributes nothing. A
1073
- form-associated element reporting a value continuously would contribute on
1074
- every submission whoever started it, which is a different feature wearing
1075
- the same name, so `submit` below sets it, submits, and clears it inside one
1076
- synchronous call.
1107
+ that submitted, and every other button on the form contributes nothing,
1108
+ which is what the native button standing in for this one at submit does.
1077
1109
 
1078
1110
  `CopyButton` has a `value` of its own meaning the text to put on the
1079
1111
  clipboard, which is not this and is why it is declared there rather than
@@ -2239,6 +2271,22 @@ export type HelixHeadlessChatHelixSendElementEvent =
2239
2271
  HelixHeadlessChatElementEvent<HelixSendEvent>;
2240
2272
 
2241
2273
  export type HelixHeadlessChatVueProps = {
2274
+ /** Declarations for the turns from `turns` by each author, keyed by `author`,
2275
+ as JSON in the attribute: `{"ada": "--chat-message-background-color: …"}`.
2276
+
2277
+ The message drawn for each turn by that author takes them as its `style`,
2278
+ so the custom properties a message reads, its fill, text color, radius and
2279
+ padding, change for that author alone. A turn by an author with no entry
2280
+ takes none, and looks as it did. JSON that does not parse is no entries. */
2281
+ "author-styles"?: (HelixHeadlessChat["authorStyles"]) | undefined;
2282
+ /** Declarations for the turns from `turns` by each author, keyed by `author`,
2283
+ as JSON in the attribute: `{"ada": "--chat-message-background-color: …"}`.
2284
+
2285
+ The message drawn for each turn by that author takes them as its `style`,
2286
+ so the custom properties a message reads, its fill, text color, radius and
2287
+ padding, change for that author alone. A turn by an author with no entry
2288
+ takes none, and looks as it did. JSON that does not parse is no entries. */
2289
+ authorStyles?: (HelixHeadlessChat["authorStyles"]) | undefined;
2242
2290
  /** Whether the transcript opens pinned to the bottom, when `pinned` is not
2243
2291
  set.
2244
2292
 
@@ -2620,6 +2668,12 @@ block lays out. Not for a diff, whose files each scroll on their own. */
2620
2668
  In a diff, each file is named from the patch, and this names a patch that
2621
2669
  carries no name of its own. */
2622
2670
  label?: (HelixHeadlessCodeBlock["label"]) | undefined;
2671
+ /** The language the code is written in, such as `ts` or `css`, handed to
2672
+ `highlight` as its second argument.
2673
+
2674
+ Absent hands it an empty string. It draws nothing of its own: the block's
2675
+ name is `label`. */
2676
+ language?: (HelixHeadlessCodeBlock["language"]) | undefined;
2623
2677
  /** Whether the lines are numbered in a gutter beside the code.
2624
2678
 
2625
2679
  The numbers are hidden from the accessibility tree and are not part of a
@@ -2683,15 +2737,24 @@ than defaulted, so the host carries no attribute the consumer did not write. */
2683
2737
  /** Turns the code into highlighted markup, which the block draws in place of
2684
2738
  the plain text.
2685
2739
 
2686
- Called with the code as written and returning HTML, such as the output of
2687
- Shiki's `codeToHtml` or Prism's `highlight`. **The markup is drawn as
2688
- given**, so it has to escape the code it was handed, which those
2689
- highlighters do. A `<pre>` and `<code>` around the whole of it, which
2690
- Shiki writes, are taken off, so the lines sit level with the gutter's
2691
- numbers and the block keeps one tab stop. Bind the language in the function you pass. The code
2692
- stays in the slot, so the copy button copies it as written and a reader
2693
- without the script still has it. Not called on a server, which has no code
2694
- to read, nor for a diff. */
2740
+ Called with the code as written and the block's `language`, and returning
2741
+ HTML, such as the output of Shiki's `codeToHtml` or Prism's `highlight`.
2742
+ One function serves every block on a page, each block saying its own
2743
+ language:
2744
+
2745
+ ```js
2746
+ for (const block of document.querySelectorAll('helix-code-block')) {
2747
+ block.highlight = (code, lang) => codeToHtml(code, { lang, theme: 'github-light' })
2748
+ }
2749
+ ```
2750
+
2751
+ **The markup is drawn as given**, so it has to escape the code it was
2752
+ handed, which those highlighters do. A `<pre>` and `<code>` around the
2753
+ whole of it, which Shiki writes, are taken off, so the lines sit level
2754
+ with the gutter's numbers and the block keeps one tab stop. The code stays
2755
+ in the slot, so the copy button copies it as written and a reader without
2756
+ the script still has it. Not called on a server, which has no code to
2757
+ read, nor for a diff. */
2695
2758
  highlight?: (HelixHeadlessCodeBlock["highlight"]) | undefined;
2696
2759
  };
2697
2760
 
@@ -2797,6 +2860,9 @@ The trade is real and is the reason this is not the default: a swatch cannot
2797
2860
  be read or pasted into without opening the panel, which is worse for a form
2798
2861
  where the color is the answer rather than a setting. */
2799
2862
  variant?: (HelixHeadlessColorInput["variant"]) | undefined;
2863
+ /** Draws the panel's hue as a wheel around the square, in place of the hue
2864
+ ramp. See Color Picker's `wheel`. */
2865
+ wheel?: (HelixHeadlessColorInput["wheel"]) | undefined;
2800
2866
  /** The message shown when the field holds text the picker cannot read as a
2801
2867
  date, a time, or a color.
2802
2868
 
@@ -3025,13 +3091,6 @@ the color. */
3025
3091
  "eyedropper-label"?: (HelixHeadlessColorPicker["eyedropperLabel"]) | undefined;
3026
3092
  /** What the eyedropper is called. */
3027
3093
  eyedropperLabel?: (HelixHeadlessColorPicker["eyedropperLabel"]) | undefined;
3028
- /** A message under the picker, such as what is wrong with the color.
3029
-
3030
- While set, the picker is invalid and does not submit, as a field's
3031
- `feedback` is, and the square and the value text are described by it.
3032
- Color Input shows its own message here, so a reader in the open panel
3033
- still sees it. */
3034
- feedback?: (HelixHeadlessColorPicker["feedback"]) | undefined;
3035
3094
  /** The syntax the value is written in: `hex`, `rgb`, or `hsl`.
3036
3095
 
3037
3096
  Only what is written. Everything is read whatever this says, so a picker on
@@ -3049,14 +3108,6 @@ Only what is written. Everything is read whatever this says, so a picker on
3049
3108
  "hue-label"?: (HelixHeadlessColorPicker["hueLabel"]) | undefined;
3050
3109
  /** What the hue channel is called. */
3051
3110
  hueLabel?: (HelixHeadlessColorPicker["hueLabel"]) | undefined;
3052
- /** Whether the current selection fails validation.
3053
-
3054
- A flag rather than a message, the split Date Picker also draws. A flat
3055
- picker has no room of its own for a sentence: the field that wraps one owns
3056
- the label, the hint and the feedback, and a second message inside the panel
3057
- would be the same error said twice. What is left for the picker is the one
3058
- thing the field cannot draw from outside, the mark on the answer itself. */
3059
- invalid?: (HelixHeadlessColorPicker["invalid"]) | undefined;
3060
3111
  /** What the lightness channel's field is called, in `channel-fields` with
3061
3112
  hsl. */
3062
3113
  "lightness-label"?: (HelixHeadlessColorPicker["lightnessLabel"]) | undefined;
@@ -3210,6 +3261,27 @@ speaks it. Absent is the control's own sentence, in English. */
3210
3261
  named for the validity flag it reports, so a form in another language
3211
3262
  speaks it. Absent is the control's own sentence, in English. */
3212
3263
  valueMissingMessage?: (HelixHeadlessColorPicker["valueMissingMessage"]) | undefined;
3264
+ /** Draws the hue as a wheel around the square, in place of the hue ramp, as
3265
+ React Aria's ColorWheel sits round its ColorArea.
3266
+
3267
+ The ring is one stop, a slider a reader turns with the arrow keys, Home
3268
+ and End, the same way round in either writing direction, and a press or a
3269
+ drag on it takes the hue in that direction. Off, the picker keeps its
3270
+ ramp. */
3271
+ wheel?: (HelixHeadlessColorPicker["wheel"]) | undefined;
3272
+ /** A message under the picker, such as what is wrong with the answer.
3273
+
3274
+ While set, the picker is invalid and does not submit, as a field's
3275
+ `feedback` is, it is marked invalid to a reader and to CSS, and the
3276
+ controls a reader answers with are described by it. */
3277
+ feedback?: (HelixHeadlessColorPicker["feedback"]) | undefined;
3278
+ /** Whether the answer fails validation, marked on the controls a reader
3279
+ answers with and as `:state(invalid)`.
3280
+
3281
+ A flag a field that wraps the picker sets, since that field owns the
3282
+ label, the hint and the message; on its own, `feedback` both marks the
3283
+ picker and says why. */
3284
+ invalid?: (HelixHeadlessColorPicker["invalid"]) | undefined;
3213
3285
  /** The value the control starts with. A form reset returns it to this value,
3214
3286
  and to the `value` attribute where this one is not written, as a native
3215
3287
  control resets to the `value` it declares. */
@@ -3624,7 +3696,9 @@ so a palette filtered on a server sends one `helix-filter` for a word.
3624
3696
  so a palette filtered on a server sends one `helix-filter` for a word.
3625
3697
  `0` filters on every keystroke. See Listbox's `filter-delay`. */
3626
3698
  filterDelay?: (HelixHeadlessCommand["filterDelay"]) | undefined;
3627
- /** The key that opens the palette, written as `mod+k`, `shift+p`, or `k`.
3699
+ /** The key that opens the palette, written as `mod+k`, `shift+p`, or `k`,
3700
+ in Kbd's chord spelling: `mod` is Command or Control, `ctrl`, `cmd`,
3701
+ `alt` and `shift` the keys they name.
3628
3702
 
3629
3703
  Empty turns it off, for a consumer who opens the palette from a button or
3630
3704
  from their own shortcut handler. There is no list of defaults to fight
@@ -4299,7 +4373,11 @@ Saturday.
4299
4373
  Absent follows `locale`, where the engine knows the week of that language,
4300
4374
  and is Sunday otherwise. */
4301
4375
  firstDayOfWeek?: (HelixHeadlessDateInput["firstDayOfWeek"]) | undefined;
4302
- /** The language tag for the names of months and days in the calendar. */
4376
+ /** The language tag for the field's order and words, and for the names of
4377
+ months and days in the calendar.
4378
+
4379
+ Absent is the page's: the `lang` of the nearest element with one, as
4380
+ Shoelace and Web Awesome read it, then the runtime's own. */
4303
4381
  locale?: (HelixHeadlessDateInput["locale"]) | undefined;
4304
4382
  /** The latest date that can be chosen, as `YYYY-MM-DD`. */
4305
4383
  max?: (HelixHeadlessDateInput["max"]) | undefined;
@@ -4665,13 +4743,12 @@ Absent follows `locale`, where the engine knows the week of that language
4665
4743
  Absent follows `locale`, where the engine knows the week of that language
4666
4744
  (Firefox does not), and is Sunday otherwise. */
4667
4745
  firstDayOfWeek?: (HelixHeadlessDatePicker["firstDayOfWeek"]) | undefined;
4668
- /** Whether the current selection fails validation. */
4669
- invalid?: (HelixHeadlessDatePicker["invalid"]) | undefined;
4670
4746
  /** Accessible name for the grid. */
4671
4747
  label?: (HelixHeadlessDatePicker["label"]) | undefined;
4672
- /** Locale for month and day names.
4748
+ /** Locale for month and day names, and the day a week starts on.
4673
4749
 
4674
- Absent uses the runtime's own. */
4750
+ Absent is the page's: the `lang` of the nearest element with one, as
4751
+ Shoelace and Web Awesome read it, then the runtime's own. */
4675
4752
  locale?: (HelixHeadlessDatePicker["locale"]) | undefined;
4676
4753
  /** Latest selectable date, as `YYYY-MM-DD`. */
4677
4754
  max?: (HelixHeadlessDatePicker["max"]) | undefined;
@@ -4821,6 +4898,19 @@ filled in as the year on show. */
4821
4898
  /** The name of the heading where it shows a page of years, with `{heading}`
4822
4899
  filled in as the year on show. */
4823
4900
  yearViewLabel?: (HelixHeadlessDatePicker["yearViewLabel"]) | undefined;
4901
+ /** A message under the picker, such as what is wrong with the answer.
4902
+
4903
+ While set, the picker is invalid and does not submit, as a field's
4904
+ `feedback` is, it is marked invalid to a reader and to CSS, and the
4905
+ controls a reader answers with are described by it. */
4906
+ feedback?: (HelixHeadlessDatePicker["feedback"]) | undefined;
4907
+ /** Whether the answer fails validation, marked on the controls a reader
4908
+ answers with and as `:state(invalid)`.
4909
+
4910
+ A flag a field that wraps the picker sets, since that field owns the
4911
+ label, the hint and the message; on its own, `feedback` both marks the
4912
+ picker and says why. */
4913
+ invalid?: (HelixHeadlessDatePicker["invalid"]) | undefined;
4824
4914
  /** The value the control starts with. A form reset returns it to this value,
4825
4915
  and to the `value` attribute where this one is not written, as a native
4826
4916
  control resets to the `value` it declares. */
@@ -4914,6 +5004,10 @@ The fallback of the `label` slot, so slotted content replaces it rather than
4914
5004
  appearing beside it. The value itself is the default slot: it is the half
4915
5005
  that varies and is often more than text. */
4916
5006
  label?: (HelixHeadlessDescriptionListItem["label"]) | undefined;
5007
+ /** Says the values are several `<dd>` elements of your own, so the item
5008
+ draws no `<dd>` of its own around them, on the server too. Without it the
5009
+ item finds them once it runs, and the served markup wraps them until then. */
5010
+ several?: (HelixHeadlessDescriptionListItem["several"]) | undefined;
4917
5011
  };
4918
5012
 
4919
5013
  export type HelixHeadlessDescriptionListItemVueEvents = {};
@@ -5387,6 +5481,21 @@ export type HelixHeadlessDrilldownVueEvents = {
5387
5481
  };
5388
5482
 
5389
5483
  export type HelixHeadlessEmptyVueProps = {
5484
+ /** The heading as words, such as "No results", drawn as a heading when
5485
+ nothing is slotted into `heading`.
5486
+
5487
+ Absent draws none, and the `heading` slot is the only heading. */
5488
+ heading?: (HelixHeadlessEmpty["heading"]) | undefined;
5489
+ /** The level of the heading `heading` draws, from 1 to 6.
5490
+
5491
+ Absent is 3, the level of a heading inside a page's section. Set it to fit
5492
+ the outline the empty view sits in. A slotted heading keeps its own. */
5493
+ "heading-level"?: (HelixHeadlessEmpty["headingLevel"] | `${number}`) | undefined;
5494
+ /** The level of the heading `heading` draws, from 1 to 6.
5495
+
5496
+ Absent is 3, the level of a heading inside a page's section. Set it to fit
5497
+ the outline the empty view sits in. A slotted heading keeps its own. */
5498
+ headingLevel?: (HelixHeadlessEmpty["headingLevel"]) | undefined;
5390
5499
  /** Whether the state is announced when it appears.
5391
5500
 
5392
5501
  On by default: an empty view almost always replaces something that was
@@ -5448,6 +5557,12 @@ refused. */
5448
5557
  maxFileSize?: (HelixHeadlessFileInput["maxFileSize"]) | undefined;
5449
5558
  /** Whether more than one file can be chosen. */
5450
5559
  multiple?: (HelixHeadlessFileInput["multiple"]) | undefined;
5560
+ /** The name of a file's progress bar, read by screen readers, with `{name}`
5561
+ filled in. A label with no `{name}` has it added after it. */
5562
+ "progress-label"?: (HelixHeadlessFileInput["progressLabel"]) | undefined;
5563
+ /** The name of a file's progress bar, read by screen readers, with `{name}`
5564
+ filled in. A label with no `{name}` has it added after it. */
5565
+ progressLabel?: (HelixHeadlessFileInput["progressLabel"]) | undefined;
5451
5566
  /** What a reader hears when files are refused, with `{count}` and `{names}`
5452
5567
  filled in. */
5453
5568
  "rejected-text"?: (HelixHeadlessFileInput["rejectedText"]) | undefined;
@@ -5947,6 +6062,17 @@ few characters and a date is not. */
5947
6062
  elapsed?: (HelixHeadlessFormatDate["elapsed"]) | undefined;
5948
6063
  /** How the era is written, such as AD, where a date is shown. */
5949
6064
  era?: (HelixHeadlessFormatDate["era"]) | undefined;
6065
+ /** Draws an `elapsed` or `relative` reading once and leaves it, where it
6066
+ would otherwise move on as it goes stale.
6067
+
6068
+ For a reading that describes a moment the page itself is about, such as
6069
+ "3 hours ago" in a report generated then, or a list a reader compares
6070
+ line by line while it should not change under them. The reading is taken
6071
+ when the element draws, and again whenever `date` or another option
6072
+ changes. Turned off, the reading catches up and moves on again.
6073
+ `sl-relative-time` and `wa-relative-time` keep still unless `sync` is
6074
+ set; this keeps moving unless `frozen` is. */
6075
+ frozen?: (HelixHeadlessFormatDate["frozen"]) | undefined;
5950
6076
  /** How the hour is written, where a time of day is shown. */
5951
6077
  hour?: (HelixHeadlessFormatDate["hour"]) | undefined;
5952
6078
  /** The clock a time of day is written on: `h12` or `h11` for twelve hours,
@@ -5963,7 +6089,8 @@ reader the same clock whatever their language. */
5963
6089
  hourCycle?: (HelixHeadlessFormatDate["hourCycle"]) | undefined;
5964
6090
  /** The locale to format the timestamp in.
5965
6091
 
5966
- Empty is the runtime's own. */
6092
+ Absent is the page's: the `lang` of the nearest element with one, as
6093
+ Shoelace and Web Awesome read it, then the runtime's own. */
5967
6094
  locale?: (HelixHeadlessFormatDate["locale"]) | undefined;
5968
6095
  /** How the minute is written, where a time of day is shown. */
5969
6096
  minute?: (HelixHeadlessFormatDate["minute"]) | undefined;
@@ -6315,6 +6442,9 @@ export type HelixHeadlessHeatmapElementEvent<E = Event> = TypedEvent<
6315
6442
  HelixHeadlessHeatmap,
6316
6443
  E
6317
6444
  >;
6445
+ /** `helix-before-change` event type */
6446
+ export type HelixHeadlessHeatmapHelixBeforeChangeElementEvent =
6447
+ HelixHeadlessHeatmapElementEvent<HelixBeforeChangeEvent>;
6318
6448
  /** `helix-resize` event type */
6319
6449
  export type HelixHeadlessHeatmapHelixResizeElementEvent =
6320
6450
  HelixHeadlessHeatmapElementEvent<HelixResizeEvent>;
@@ -6381,6 +6511,20 @@ calendar heatmap does: a week is a column, so the strip reads along the
6381
6511
  line in weeks, from the right on a right-to-left page, and top to bottom in
6382
6512
  days. */
6383
6513
  rows?: (HelixHeadlessHeatmap["rows"]) | undefined;
6514
+ /** What the `selection` part says after the selection changes, with `{count}` for
6515
+ how many cells are selected. */
6516
+ "selection-label"?: (HelixHeadlessHeatmap["selectionLabel"]) | undefined;
6517
+ /** What the `selection` part says after the selection changes, with `{count}` for
6518
+ how many cells are selected. */
6519
+ selectionLabel?: (HelixHeadlessHeatmap["selectionLabel"]) | undefined;
6520
+ /** How many cells a reader can select: `single` or `multiple`.
6521
+
6522
+ Absent selects nothing, and a press or Space does what it did. */
6523
+ "selection-mode"?: (HelixHeadlessHeatmap["selectionMode"]) | undefined;
6524
+ /** How many cells a reader can select: `single` or `multiple`.
6525
+
6526
+ Absent selects nothing, and a press or Space does what it did. */
6527
+ selectionMode?: (HelixHeadlessHeatmap["selectionMode"]) | undefined;
6384
6528
  /** Lower bounds for the tone buckets, in the order the tones are given.
6385
6529
 
6386
6530
  `thresholds="1 3 6 9"` with `tones="1 2 3 4"` puts 1 and 2 in the ramp's
@@ -6403,6 +6547,12 @@ no order in it. */
6403
6547
  "total-label"?: (HelixHeadlessHeatmap["totalLabel"]) | undefined;
6404
6548
  /** The word the `overview` puts before the total of the readings drawn. */
6405
6549
  totalLabel?: (HelixHeadlessHeatmap["totalLabel"]) | undefined;
6550
+ /** The selected cells, by the names their rows have in the table, such as
6551
+ `2026-06-11`, separated by commas.
6552
+
6553
+ Set it to start with cells selected. Written by a press or a key under
6554
+ `selection-mode`. */
6555
+ value?: (HelixHeadlessHeatmap["value"]) | undefined;
6406
6556
  /** The id of the table to read.
6407
6557
 
6408
6558
  Names a table in the same tree, so a chart inside another component's
@@ -6442,6 +6592,10 @@ legend hid is not counted. */
6442
6592
  };
6443
6593
 
6444
6594
  export type HelixHeadlessHeatmapVueEvents = {
6595
+ /** Fired once a press or a key has changed which cells are selected. */
6596
+ change: HelixHeadlessHeatmapElementEvent;
6597
+ /** Fired before a press or a key changes which cells are selected, with the `value` it would leave. Cancelable. */
6598
+ "helix-before-change": HelixHeadlessHeatmapHelixBeforeChangeElementEvent;
6445
6599
  /** Fired when the number of cells drawn changes, with the new number. */
6446
6600
  "helix-resize": HelixHeadlessHeatmapHelixResizeElementEvent;
6447
6601
  };
@@ -6478,33 +6632,23 @@ is the platform's `commandfor`. */
6478
6632
  commandFor?: (HelixHeadlessIconButton["commandFor"]) | undefined;
6479
6633
  /** Where this button's submission goes, overriding the form's own.
6480
6634
 
6481
- **The five `form*` overrides work by writing the form and putting it back**,
6482
- which is the only mechanism available and is closer to the platform than it
6483
- sounds. `requestSubmit(submitter)` is how a native submitter carries these,
6484
- and it refuses ours twice over: the inner `<button>` is `type="button"` so
6485
- it is not a submit button, and it sits in this shadow root so its form owner
6486
- is not the consumer's form. Both throw. So the submission is started with no
6487
- submitter and the overrides are applied to the form for the duration of it.
6488
-
6489
- The whole submit algorithm runs synchronously inside `requestSubmit()`, so
6490
- the window is one call and a `finally` closes it whether or not a listener
6491
- refused. What a `submit` handler observes during that window is the form a
6492
- native submitter would have given it, which is the point. */
6635
+ **The five `form*` overrides ride on a native submit button that stands in
6636
+ for this one**, because `requestSubmit(submitter)` refuses the inner
6637
+ `<button>` twice over: it is `type="button"`, and it sits in this shadow
6638
+ root, so its form owner is not the consumer's form. The stand-in is a
6639
+ hidden `<button type="submit">` in the form for the one synchronous call,
6640
+ so the platform applies the overrides to that submission alone and leaves
6641
+ the form as it was. See `submitAs`. */
6493
6642
  formaction?: (HelixHeadlessIconButton["formAction"]) | undefined;
6494
6643
  /** Where this button's submission goes, overriding the form's own.
6495
6644
 
6496
- **The five `form*` overrides work by writing the form and putting it back**,
6497
- which is the only mechanism available and is closer to the platform than it
6498
- sounds. `requestSubmit(submitter)` is how a native submitter carries these,
6499
- and it refuses ours twice over: the inner `<button>` is `type="button"` so
6500
- it is not a submit button, and it sits in this shadow root so its form owner
6501
- is not the consumer's form. Both throw. So the submission is started with no
6502
- submitter and the overrides are applied to the form for the duration of it.
6503
-
6504
- The whole submit algorithm runs synchronously inside `requestSubmit()`, so
6505
- the window is one call and a `finally` closes it whether or not a listener
6506
- refused. What a `submit` handler observes during that window is the form a
6507
- native submitter would have given it, which is the point. */
6645
+ **The five `form*` overrides ride on a native submit button that stands in
6646
+ for this one**, because `requestSubmit(submitter)` refuses the inner
6647
+ `<button>` twice over: it is `type="button"`, and it sits in this shadow
6648
+ root, so its form owner is not the consumer's form. The stand-in is a
6649
+ hidden `<button type="submit">` in the form for the one synchronous call,
6650
+ so the platform applies the overrides to that submission alone and leaves
6651
+ the form as it was. See `submitAs`. */
6508
6652
  formAction?: (HelixHeadlessIconButton["formAction"]) | undefined;
6509
6653
  /** How the submission is encoded, overriding the form's own. */
6510
6654
  formenctype?: (HelixHeadlessIconButton["formEnctype"]) | undefined;
@@ -6550,13 +6694,10 @@ a press, so focus stays where the reader left it. */
6550
6694
  /** The value this button submits under its own `name`, as a native submit
6551
6695
  button does.
6552
6696
 
6553
- **Reported for exactly the submission this button starts and not otherwise.**
6697
+ **Sent with exactly the submission this button starts and not otherwise.**
6554
6698
  A native submit button contributes `name=value` only when it is the one
6555
- that submitted, and every other button on the form contributes nothing. A
6556
- form-associated element reporting a value continuously would contribute on
6557
- every submission whoever started it, which is a different feature wearing
6558
- the same name, so `submit` below sets it, submits, and clears it inside one
6559
- synchronous call.
6699
+ that submitted, and every other button on the form contributes nothing,
6700
+ which is what the native button standing in for this one at submit does.
6560
6701
 
6561
6702
  `CopyButton` has a `value` of its own meaning the text to put on the
6562
6703
  clipboard, which is not this and is why it is declared there rather than
@@ -6789,7 +6930,12 @@ the *first* update mirrors to a custom state instead, which is what
6789
6930
  `:state(open)` and `:state(checked)` are.
6790
6931
 
6791
6932
  `loading` writes nothing, because it is where every image starts and the
6792
- resting state of a mirror is the attribute's absence. */
6933
+ resting state of a mirror is the attribute's absence.
6934
+
6935
+ **Kept beside the custom states, and what the styled tier draws from.** An
6936
+ engine without `CustomStateSet`, Safari before 17.4 and Firefox before
6937
+ 126, records no state, and a picture faded in by `:state(loaded)` alone
6938
+ would stay transparent there for good. A sheet of your own can read either. */
6793
6939
  status?: (HelixHeadlessImage["status"]) | undefined;
6794
6940
  };
6795
6941
 
@@ -7037,6 +7183,13 @@ export type HelixHeadlessKbdHelixShortcutElementEvent =
7037
7183
  HelixHeadlessKbdElementEvent<HelixShortcutEvent>;
7038
7184
 
7039
7185
  export type HelixHeadlessKbdVueProps = {
7186
+ /** What the chord does to the control `for` names once it is pressed:
7187
+ `focus` moves focus to the control and `click` presses it.
7188
+
7189
+ Unset, the chord sends `helix-shortcut` and does nothing else, for a page
7190
+ that acts on the event itself. It acts only where `within` listens, after
7191
+ `helix-shortcut`, and not when a listener cancels that event. */
7192
+ activate?: (HelixHeadlessKbd["activate"]) | undefined;
7040
7193
  /** Draws a chord under `keys` as one key per key, each a `key` part with a
7041
7194
  `separator` part between two where the platform writes a `+`, as GitHub
7042
7195
  and most docs draw `Ctrl` `K`.
@@ -7141,14 +7294,18 @@ shadow root reads a table in that root rather than one in the document.
7141
7294
 
7142
7295
  Set it to start with series hidden. Every chart reading the same table
7143
7296
  draws without them. Commas only, because a column's heading may hold a
7144
- space. For a ring the names are the rows. */
7297
+ space. For a ring the names are the rows. An array of names set on the
7298
+ property works too, as React sets `hiddenSeries={['Direct']}`; a toggle
7299
+ writes the list back as a string. */
7145
7300
  "hidden-series"?: (HelixHeadlessLegend["hiddenSeries"]) | undefined;
7146
7301
  /** The series hidden on the table, by name, separated by commas: what
7147
7302
  `toggles` hides and shows.
7148
7303
 
7149
7304
  Set it to start with series hidden. Every chart reading the same table
7150
7305
  draws without them. Commas only, because a column's heading may hold a
7151
- space. For a ring the names are the rows. */
7306
+ space. For a ring the names are the rows. An array of names set on the
7307
+ property works too, as React sets `hiddenSeries={['Direct']}`; a toggle
7308
+ writes the list back as a string. */
7152
7309
  hiddenSeries?: (HelixHeadlessLegend["hiddenSeries"]) | undefined;
7153
7310
  /** The name of the list, which a screen reader announces before its entries.
7154
7311
 
@@ -7207,12 +7364,14 @@ export type HelixHeadlessLightboxToggleElementEvent =
7207
7364
  HelixHeadlessLightboxElementEvent<ToggleEvent>;
7208
7365
 
7209
7366
  export type HelixHeadlessLightboxVueProps = {
7210
- /** Draws the viewer's own previous, next and close controls over the picture.
7367
+ /** Draws the viewer's own previous, next and close controls over the picture,
7368
+ and zoom-out and zoom-in controls where `max-zoom` allows zooming.
7211
7369
 
7212
7370
  Off by default, for a viewer whose chrome you compose in the `header` and
7213
7371
  `footer` slots. The controls hide with the rest of the chrome while the
7214
- reader is idle, and the previous and next ones say they are unavailable at
7215
- either end of a set that does not `loop`. */
7372
+ reader is idle, the previous and next ones say they are unavailable at
7373
+ either end of a set that does not `loop`, and the zoom ones at either end
7374
+ of the scale. */
7216
7375
  controls?: (HelixHeadlessLightbox["controls"]) | undefined;
7217
7376
  /** Draws the place of the shown item in the set over the picture, in the
7218
7377
  words of `status-label`, such as "2 of 5". It hides with the controls while
@@ -7285,6 +7444,20 @@ Announced rather than only drawn, because the picture changing under a
7285
7444
  reader who cannot see it is otherwise silent. A consumer who has their own
7286
7445
  counter in the chrome can empty this and say it themselves. */
7287
7446
  statusLabel?: (HelixHeadlessLightbox["statusLabel"]) | undefined;
7447
+ /** The zoom-in control's accessible name. */
7448
+ "zoom-in-label"?: (HelixHeadlessLightbox["zoomInLabel"]) | undefined;
7449
+ /** The zoom-in control's accessible name. */
7450
+ zoomInLabel?: (HelixHeadlessLightbox["zoomInLabel"]) | undefined;
7451
+ /** The zoom-out control's accessible name. */
7452
+ "zoom-out-label"?: (HelixHeadlessLightbox["zoomOutLabel"]) | undefined;
7453
+ /** The zoom-out control's accessible name. */
7454
+ zoomOutLabel?: (HelixHeadlessLightbox["zoomOutLabel"]) | undefined;
7455
+ /** What the live region says once a reader has stopped zooming, with the
7456
+ scale as a whole `{percent}` filled in. Empty it to say nothing. */
7457
+ "zoom-status-label"?: (HelixHeadlessLightbox["zoomStatusLabel"]) | undefined;
7458
+ /** What the live region says once a reader has stopped zooming, with the
7459
+ scale as a whole `{percent}` filled in. Empty it to say nothing. */
7460
+ zoomStatusLabel?: (HelixHeadlessLightbox["zoomStatusLabel"]) | undefined;
7288
7461
  /** The `value` of the current item.
7289
7462
 
7290
7463
  Not `option.active`, which is the option the keyboard is on: that is a
@@ -7369,6 +7542,13 @@ sum can pass under the curve fitted through the sum beneath it, so a
7369
7542
  smoothed stack can draw a part as less than nothing. There is no such edge
7370
7543
  here, which is what lets a line take the reading aid. */
7371
7544
  curve?: (HelixHeadlessLineChart["curve"]) | undefined;
7545
+ /** The series drawn as a dashed line, by their headings, separated by
7546
+ commas: `dashed="Forecast, Target"`.
7547
+
7548
+ For a series that is not a reading, such as a forecast or a goal, drawn
7549
+ beside the ones that are. Each takes a `line-dashed` part beside `line`,
7550
+ which a stylesheet draws dashed. Absent, every line is solid. */
7551
+ dashed?: (HelixHeadlessLineChart["dashed"]) | undefined;
7372
7552
  /** Which rules are drawn across the plot, if any.
7373
7553
 
7374
7554
  Absent draws none, which is the honest default rather than a timid one: a
@@ -8903,6 +9083,15 @@ slot replaces it. */
8903
9083
 
8904
9084
  export type HelixHeadlessMenuSectionVueEvents = {};
8905
9085
 
9086
+ /** `HelixHeadlessMeter` component event */
9087
+ export type HelixHeadlessMeterElementEvent<E = Event> = TypedEvent<
9088
+ HelixHeadlessMeter,
9089
+ E
9090
+ >;
9091
+ /** `helix-band` event type */
9092
+ export type HelixHeadlessMeterHelixBandElementEvent =
9093
+ HelixHeadlessMeterElementEvent<HelixBandEvent>;
9094
+
8906
9095
  export type HelixHeadlessMeterVueProps = {
8907
9096
  /** Sets the band directly, for a rule that `low`, `high`, and `optimum` cannot
8908
9097
  express.
@@ -8932,6 +9121,16 @@ stylesheet outside as `indicator-good`, `-fair` or `-poor` among the fill's
8932
9121
  part names, so reflecting here would write an attribute onto the host for
8933
9122
  no reader. */
8934
9123
  band?: (HelixHeadlessMeter["band"]) | undefined;
9124
+ /** The words each band is said with under `live`, by its name, written as
9125
+ JSON in the attribute: `band-labels='{"poor":"Almost full"}'`.
9126
+
9127
+ A band left out keeps its default: "Good", "Fair" or "Poor". */
9128
+ "band-labels"?: (HelixHeadlessMeter["bandLabels"]) | undefined;
9129
+ /** The words each band is said with under `live`, by its name, written as
9130
+ JSON in the attribute: `band-labels='{"poor":"Almost full"}'`.
9131
+
9132
+ A band left out keeps its default: "Good", "Fair" or "Poor". */
9133
+ bandLabels?: (HelixHeadlessMeter["bandLabels"]) | undefined;
8935
9134
  /** `Intl.NumberFormat` options the reading is written with, as React Aria's
8936
9135
  Meter and ProgressBar take them: a unit, a currency, or a number of
8937
9136
  decimals. Written as JSON in the attribute.
@@ -8967,6 +9166,13 @@ Absent leaves the range unbanded. */
8967
9166
  A visible label in the `label` slot names it instead, with the words it
8968
9167
  shows, so the name and the label cannot disagree. */
8969
9168
  label?: (HelixHeadlessMeter["label"]) | undefined;
9169
+ /** Says the reading in a polite `live` region each time it moves into
9170
+ another band, with the band's word, such as "92%, Poor".
9171
+
9172
+ For a meter whose value changes while it is on screen. Off by default,
9173
+ because a meter that reads a fixed level has nothing new to say. A meter
9174
+ with no bands says nothing. */
9175
+ live?: (HelixHeadlessMeter["live"]) | undefined;
8970
9176
  /** The locale the percentage is written in, such as `fr` for `72 %`.
8971
9177
 
8972
9178
  Absent uses the runtime's own. */
@@ -9032,7 +9238,10 @@ fair summary of a task and a poor one of a quantity. */
9032
9238
  valueText?: (HelixHeadlessMeter["valueText"]) | undefined;
9033
9239
  };
9034
9240
 
9035
- export type HelixHeadlessMeterVueEvents = {};
9241
+ export type HelixHeadlessMeterVueEvents = {
9242
+ /** Fired when the reading moves into another band, with the band it is in now, or `''` where it is in none. Not sent on the first render, since a meter that arrives in a band has not moved. */
9243
+ "helix-band": HelixHeadlessMeterHelixBandElementEvent;
9244
+ };
9036
9245
 
9037
9246
  export type HelixHeadlessNavigationVueProps = {
9038
9247
  /** Whether the arrow keys move focus between the destinations.
@@ -9374,7 +9583,13 @@ than states: a duration, a weight, a count they are looking for rather than
9374
9583
  one they already know. */
9375
9584
  scrub?: (HelixHeadlessNumberInput["scrub"]) | undefined;
9376
9585
  /** How far one step moves. A value off the step grid, counted from `min`, is
9377
- invalid, as it is in a native number field. */
9586
+ invalid, as it is in a native number field.
9587
+
9588
+ Unset, a step moves by one, or by one percent under a percent format, and
9589
+ a typed number is rounded to the smallest amount `format-options` shows
9590
+ rather than to whole steps, as React Aria's NumberField does: a field
9591
+ showing dollars keeps the cents typed into it. Without `format-options`
9592
+ the grid is whole numbers, as in a native number field. */
9378
9593
  step?: (HelixHeadlessNumberInput["step"]) | undefined;
9379
9594
  /** The message the browser shows when the number is off the step grid, with
9380
9595
  `{below}` and `{above}` filled in with the nearest valid values. */
@@ -9841,6 +10056,10 @@ export type HelixHeadlessOptionVueEvents = {
9841
10056
  "helix-select": HelixHeadlessOptionHelixSelectElementEvent;
9842
10057
  };
9843
10058
 
10059
+ export type HelixHeadlessOptionSeparatorVueProps = {};
10060
+
10061
+ export type HelixHeadlessOptionSeparatorVueEvents = {};
10062
+
9844
10063
  /** `HelixHeadlessOutline` component event */
9845
10064
  export type HelixHeadlessOutlineElementEvent<E = Event> = TypedEvent<
9846
10065
  HelixHeadlessOutline,
@@ -10169,12 +10388,9 @@ export type HelixHeadlessPinInputHelixCompleteElementEvent =
10169
10388
  HelixHeadlessPinInputElementEvent<HelixCompleteEvent>;
10170
10389
 
10171
10390
  export type HelixHeadlessPinInputVueProps = {
10172
- /** The autofill hint for the browser, set on the first box only.
10173
-
10174
- `one-time-code` is why this defaults to anything at all: it is the token
10175
- that lets a phone offer the code out of a message. Later cells stay `off`
10176
- for the reason in the class comment above, that six cells each offering
10177
- the same code is one offer made six times. */
10391
+ /** The autofill hint for the browser. `one-time-code` is why this defaults to
10392
+ anything at all: it is the token that lets a phone offer the code out of a
10393
+ message. */
10178
10394
  autocomplete?: (HelixHeadlessPinInput["autocomplete"]) | undefined;
10179
10395
  /** Whether the form is submitted once the last box is filled, as Web
10180
10396
  Awesome's `autosubmit` and Radix's `autoSubmit`. Only for a code the field
@@ -10184,9 +10400,9 @@ took: a refused last character submits nothing. */
10184
10400
  to keep them as typed. Web Awesome's OTP input takes the same `case`, for
10185
10401
  a code a service reads in one case. */
10186
10402
  case?: (HelixHeadlessPinInput["case"]) | undefined;
10187
- /** Accessible name for one box, with `{index}` and `{length}` filled in. */
10403
+ /** The name each box once had, with `{index}` and `{length}` filled in. */
10188
10404
  "cell-label"?: (HelixHeadlessPinInput["cellLabel"]) | undefined;
10189
- /** Accessible name for one box, with `{index}` and `{length}` filled in. */
10405
+ /** The name each box once had, with `{index}` and `{length}` filled in. */
10190
10406
  cellLabel?: (HelixHeadlessPinInput["cellLabel"]) | undefined;
10191
10407
  /** Separators drawn between the boxes: `#` or `*` for a box and anything
10192
10408
  else as it is written, so `###-###` draws a dash after the third. The
@@ -10194,21 +10410,22 @@ separators are hidden from screen readers and are not part of the value. */
10194
10410
  format?: (HelixHeadlessPinInput["format"]) | undefined;
10195
10411
  /** How many characters the code has. */
10196
10412
  length?: (HelixHeadlessPinInput["length"]) | undefined;
10197
- /** Whether the characters are hidden, the way a password is. */
10413
+ /** Whether the characters are hidden, the way a password is. The field is a
10414
+ password field, and each filled box draws `mask-character`. */
10198
10415
  mask?: (HelixHeadlessPinInput["mask"]) | undefined;
10199
- /** What an empty box shows, usually a single dot.
10200
-
10201
- The platform's own placeholder, on each cell, rather than a character
10202
- drawn behind the field: it clears the moment anything is typed, it is
10203
- already excluded from the accessible value, and it works the same under
10204
- `mask`, where the cell is a password input and a hand-drawn glyph would
10205
- have to know that.
10206
-
10207
- Empty by default, because a row of boxes already reads as a row of boxes. */
10416
+ /** What a filled box draws under `mask`, in place of its character, as Web
10417
+ Awesome's `--mask-char`. */
10418
+ "mask-character"?: (HelixHeadlessPinInput["maskCharacter"]) | undefined;
10419
+ /** What a filled box draws under `mask`, in place of its character, as Web
10420
+ Awesome's `--mask-char`. */
10421
+ maskCharacter?: (HelixHeadlessPinInput["maskCharacter"]) | undefined;
10422
+ /** What an empty box shows, usually a single dot. It is not shown in the box
10423
+ the caret is in. Empty by default, because a row of boxes already reads as
10424
+ a row of boxes. */
10208
10425
  placeholder?: (HelixHeadlessPinInput["placeholder"]) | undefined;
10209
- /** Whether the boxes block input. A read-only code still submits its value. */
10426
+ /** Whether the field blocks input. A read-only code still submits its value. */
10210
10427
  readonly?: (HelixHeadlessPinInput["readOnly"]) | undefined;
10211
- /** Whether the boxes block input. A read-only code still submits its value. */
10428
+ /** Whether the field blocks input. A read-only code still submits its value. */
10212
10429
  readOnly?: (HelixHeadlessPinInput["readOnly"]) | undefined;
10213
10430
  /** The message shown when the code is started and not finished, with
10214
10431
  `{length}` filled in. When it is unset, an English default is shown. */
@@ -10233,8 +10450,7 @@ marked letters wants `text`, which judges nothing.
10233
10450
 
10234
10451
  **Not reflected**: nothing selects on it, so reflecting only writes
10235
10452
  `type="numeric"` onto every `<helix-headless-pin-input>` ever rendered, an
10236
- attribute no consumer's markup had. The area rules carry the sentence
10237
- "reflect only what CSS selects on". The real inputs take it as a binding,
10453
+ attribute no consumer's markup had. The field takes it as `inputmode`,
10238
10454
  which is what makes the keyboard follow. */
10239
10455
  type?: (HelixHeadlessPinInput["type"]) | undefined;
10240
10456
  /** The value the control starts with. A form reset returns it to this value,
@@ -10383,7 +10599,28 @@ export type HelixHeadlessPopoverVueEvents = {
10383
10599
  toggle: HelixHeadlessPopoverToggleElementEvent;
10384
10600
  };
10385
10601
 
10602
+ /** `HelixHeadlessProgress` component event */
10603
+ export type HelixHeadlessProgressElementEvent<E = Event> = TypedEvent<
10604
+ HelixHeadlessProgress,
10605
+ E
10606
+ >;
10607
+ /** `helix-complete` event type */
10608
+ export type HelixHeadlessProgressHelixCompleteElementEvent =
10609
+ HelixHeadlessProgressElementEvent<HelixCompleteEvent>;
10610
+
10386
10611
  export type HelixHeadlessProgressVueProps = {
10612
+ /** The words a screen reader hears when the value reaches `max`, such as
10613
+ "Upload complete".
10614
+
10615
+ Said once, politely, as the work finishes. Empty says nothing, for a bar
10616
+ whose page announces the result itself. */
10617
+ "complete-label"?: (HelixHeadlessProgress["completeLabel"]) | undefined;
10618
+ /** The words a screen reader hears when the value reaches `max`, such as
10619
+ "Upload complete".
10620
+
10621
+ Said once, politely, as the work finishes. Empty says nothing, for a bar
10622
+ whose page announces the result itself. */
10623
+ completeLabel?: (HelixHeadlessProgress["completeLabel"]) | undefined;
10387
10624
  /** `Intl.NumberFormat` options the reading is written with, as React Aria's
10388
10625
  Meter and ProgressBar take them: a unit, a currency, or a number of
10389
10626
  decimals. Written as JSON in the attribute.
@@ -10494,7 +10731,10 @@ report progress. */
10494
10731
  valueText?: (HelixHeadlessProgress["valueText"]) | undefined;
10495
10732
  };
10496
10733
 
10497
- export type HelixHeadlessProgressVueEvents = {};
10734
+ export type HelixHeadlessProgressVueEvents = {
10735
+ /** The value reached `max` from below. Its `value` is `max`. Not sent for a bar that starts full. */
10736
+ "helix-complete": HelixHeadlessProgressHelixCompleteElementEvent;
10737
+ };
10498
10738
 
10499
10739
  /** `HelixHeadlessQrCode` component event */
10500
10740
  export type HelixHeadlessQrCodeElementEvent<E = Event> = TypedEvent<
@@ -10503,6 +10743,12 @@ export type HelixHeadlessQrCodeElementEvent<E = Event> = TypedEvent<
10503
10743
  >;
10504
10744
 
10505
10745
  export type HelixHeadlessQrCodeVueProps = {
10746
+ /** The words a code with no `label` is named by, followed by its value where
10747
+ the value is a web address. */
10748
+ "code-label"?: (HelixHeadlessQrCode["codeLabel"]) | undefined;
10749
+ /** The words a code with no `label` is named by, followed by its value where
10750
+ the value is a web address. */
10751
+ codeLabel?: (HelixHeadlessQrCode["codeLabel"]) | undefined;
10506
10752
  /** The error correction level, which sets how much of the code can be lost
10507
10753
  and still scan.
10508
10754
 
@@ -10512,10 +10758,13 @@ chosen automatically when the slot is filled: it is the level that makes
10512
10758
  covering safe, and a consumer who fills the slot has said what they want
10513
10759
  without having to know that. */
10514
10760
  correction?: (HelixHeadlessQrCode["correction"]) | undefined;
10515
- /** The image's accessible name.
10761
+ /** The image's accessible name: what the code is for, such as "Open the
10762
+ menu".
10516
10763
 
10517
- Falling back to the value is deliberate: a code almost always holds a URL,
10518
- and a URL is a better name than "QR code" for a reader who cannot see it. */
10764
+ Absent names it by `code-label` and, for a web address, the address,
10765
+ which is what a reader who cannot scan it needs. Any other value is left
10766
+ out of the name, since it may hold a secret, such as an authenticator's
10767
+ key or a network's password. */
10519
10768
  label?: (HelixHeadlessQrCode["label"]) | undefined;
10520
10769
  /** How the modules are drawn.
10521
10770
 
@@ -10985,6 +11234,20 @@ is read along. */
10985
11234
  "points-label"?: (HelixHeadlessScatterChart["pointsLabel"]) | undefined;
10986
11235
  /** The word the summary uses for a row when it counts them. */
10987
11236
  pointsLabel?: (HelixHeadlessScatterChart["pointsLabel"]) | undefined;
11237
+ /** The heading of a column whose numbers size the points, such as
11238
+ `Population`, which makes the chart a bubble chart.
11239
+
11240
+ That column is then a measure and no series: it draws no points of its
11241
+ own, and each point's area follows its row's number in it. Absent, every
11242
+ point is one size. */
11243
+ "size-by"?: (HelixHeadlessScatterChart["sizeBy"]) | undefined;
11244
+ /** The heading of a column whose numbers size the points, such as
11245
+ `Population`, which makes the chart a bubble chart.
11246
+
11247
+ That column is then a measure and no series: it draws no points of its
11248
+ own, and each point's area follows its row's number in it. Absent, every
11249
+ point is one size. */
11250
+ sizeBy?: (HelixHeadlessScatterChart["sizeBy"]) | undefined;
10988
11251
  /** Draws each series' line of best fit across the plot, by least squares, in
10989
11252
  the series' color: the regression line a reader would otherwise draw by
10990
11253
  eye.
@@ -11109,6 +11372,24 @@ export type HelixHeadlessSelectVueProps = {
11109
11372
  Passed to the listbox rather than acted on here, because the listbox owns
11110
11373
  the filtering, the empty state and the keyboard. */
11111
11374
  filterable?: (HelixHeadlessSelect["filterable"]) | undefined;
11375
+ /** The open list's name where nothing names the Select, read by screen
11376
+ readers. The list has no visible name.
11377
+
11378
+ A Select named by `label`, `aria-label`, `aria-labelledby` or a `<label>`
11379
+ gives its list that name, and this is not used. Unnamed, the Select is
11380
+ reported once by the missing-name warning, and its list is not reported a
11381
+ second time for a name the page never wrote: the list is this element's,
11382
+ and so is the fallback. Combobox calls its list the same. */
11383
+ "list-label"?: (HelixHeadlessSelect["listLabel"]) | undefined;
11384
+ /** The open list's name where nothing names the Select, read by screen
11385
+ readers. The list has no visible name.
11386
+
11387
+ A Select named by `label`, `aria-label`, `aria-labelledby` or a `<label>`
11388
+ gives its list that name, and this is not used. Unnamed, the Select is
11389
+ reported once by the missing-name warning, and its list is not reported a
11390
+ second time for a name the page never wrote: the list is this element's,
11391
+ and so is the fallback. Combobox calls its list the same. */
11392
+ listLabel?: (HelixHeadlessSelect["listLabel"]) | undefined;
11112
11393
  /** Whether the options are still loading.
11113
11394
 
11114
11395
  Passed straight to the list, which is where the rows are and so where the
@@ -11123,6 +11404,16 @@ consumer wiring the same flag twice. */
11123
11404
  multiple?: (HelixHeadlessSelect["multiple"]) | undefined;
11124
11405
  /** Shown on the trigger while nothing is chosen. */
11125
11406
  placeholder?: (HelixHeadlessSelect["placeholder"]) | undefined;
11407
+ /** Where the list opens: `floating`, under the trigger and above it where
11408
+ there is no room, or `item-aligned`, over the trigger with the chosen
11409
+ option where the trigger is, as a native select does on macOS and Radix
11410
+ Select does by default.
11411
+
11412
+ Over the trigger, a reader's eye stays on the answer as the list opens
11413
+ round it, and a short move reaches the options either side. Near an edge
11414
+ of the screen the list moves to stay on it, so the option may sit beside
11415
+ the trigger rather than on it. It follows the page as it scrolls. */
11416
+ position?: (HelixHeadlessSelect["position"]) | undefined;
11126
11417
  /** Whether the element starts open. Ignored once `open` is written. */
11127
11418
  "default-open"?: (HelixHeadlessSelect["defaultOpen"]) | undefined;
11128
11419
  /** Whether the element starts open. Ignored once `open` is written. */
@@ -11211,6 +11502,16 @@ imperatively later, and nothing is hydrating by then.
11211
11502
 
11212
11503
  Here rather than on each control. */
11213
11504
  name?: (HelixHeadlessSelect["name"]) | undefined;
11505
+ /** Whether the trigger holds its group's tab stop.
11506
+
11507
+ A toolbar keeps one tab stop across its controls, and writing `tabindex`
11508
+ onto this element would change markup the consumer rendered, which a React
11509
+ consumer's hydration reports. A toolbar sets this property instead, and
11510
+ the stop moves on the trigger inside the shadow root, as Button's does.
11511
+
11512
+ No attribute, because it is coordination between elements rather than
11513
+ anything a consumer sets. */
11514
+ focusable?: (HelixHeadlessSelect["focusable"]) | undefined;
11214
11515
  /** What the trigger shows for the chosen options: a function given them, in
11215
11516
  the order they appear, that returns text, an element or a Lit template.
11216
11517
 
@@ -11391,6 +11692,11 @@ filled in. Write it in the page's language, such as `{start} bis {end}`. */
11391
11692
  showValue?: (HelixHeadlessSlider["showValue"]) | undefined;
11392
11693
  /** How far one press of an arrow key moves the thumb. */
11393
11694
  step?: (HelixHeadlessSlider["step"]) | undefined;
11695
+ /** Whether each thumb shows its value in a bubble beside it, as Web
11696
+ Awesome's `with-tooltip`. The styled slider shows the bubbles while the
11697
+ slider is under the pointer or holds focus. They repeat what each thumb
11698
+ already reports, so a screen reader skips them. */
11699
+ tooltip?: (HelixHeadlessSlider["tooltip"]) | undefined;
11394
11700
  /** What a screen reader says for a thumb's value, with `{value}` filled in,
11395
11701
  such as `{value} degrees`. Empty announces the number alone. */
11396
11702
  "value-text"?: (HelixHeadlessSlider["valueText"]) | undefined;
@@ -11539,6 +11845,20 @@ separated by spaces.
11539
11845
  Absent marks none, and the drawing is what it was. Each mark is a part,
11540
11846
  placed at its reading, for a stylesheet to draw. */
11541
11847
  marks?: (HelixHeadlessSparkline["marks"]) | undefined;
11848
+ /** What the readings come to, said after the name: `{first}` and `{last}`
11849
+ for the first and the last reading, `{high}` and `{low}` for the highest
11850
+ and the lowest, each written as the readout writes it.
11851
+
11852
+ Set it to the words of the page's language, or to nothing to say no
11853
+ more than the name. Said only where the sparkline is named. */
11854
+ "overview-label"?: (HelixHeadlessSparkline["overviewLabel"]) | undefined;
11855
+ /** What the readings come to, said after the name: `{first}` and `{last}`
11856
+ for the first and the last reading, `{high}` and `{low}` for the highest
11857
+ and the lowest, each written as the readout writes it.
11858
+
11859
+ Set it to the words of the page's language, or to nothing to say no
11860
+ more than the name. Said only where the sparkline is named. */
11861
+ overviewLabel?: (HelixHeadlessSparkline["overviewLabel"]) | undefined;
11542
11862
  /** What the readings are drawn as.
11543
11863
 
11544
11864
  Absent is `area`, a line with the region beneath it washed. `line` is the
@@ -11581,6 +11901,12 @@ it. `{position}` and `{count}` are replaced with the numbers, written in
11581
11901
  Set it to the words of the page's language, such as `{position} von
11582
11902
  {count}`, or to nothing to say no position. */
11583
11903
  positionLabel?: (HelixHeadlessSparkline["positionLabel"]) | undefined;
11904
+ /** Two values a band is drawn between, behind the line, separated by a
11905
+ space: `range="60 100"` marks a normal range.
11906
+
11907
+ The scale stretches to hold the band where the readings do not reach it.
11908
+ Absent draws none. */
11909
+ range?: (HelixHeadlessSparkline["range"]) | undefined;
11584
11910
  /** The numbers, separated by whitespace or by commas.
11585
11911
 
11586
11912
  An array assigned to the property works too, which is what React 19 does
@@ -11821,6 +12147,8 @@ export type HelixHeadlessSplitterVueEvents = {
11821
12147
  "helix-collapse": HelixHeadlessSplitterHelixCollapseElementEvent;
11822
12148
  /** Fired after the divider settles somewhere new, with the new position. */
11823
12149
  "helix-resized": HelixHeadlessSplitterHelixResizedElementEvent;
12150
+ /** Fired each time a drag moves the divider, before it settles, as a range input does while it is dragged. Read `position` for where it is now. */
12151
+ input: HelixHeadlessSplitterElementEvent;
11824
12152
  };
11825
12153
 
11826
12154
  export type HelixHeadlessStatGroupVueProps = {
@@ -11897,6 +12225,12 @@ in both. Of those four combinations three are ones nobody should pick, and
11897
12225
  a property whose job is mostly to be left alone is a property that mostly
11898
12226
  catches people out. */
11899
12227
  orientation?: (HelixHeadlessSteps["orientation"]) | undefined;
12228
+ /** What the `progress` part says to a screen reader, with `{percent}` filled
12229
+ in with `progress`. */
12230
+ "progress-label"?: (HelixHeadlessSteps["progressLabel"]) | undefined;
12231
+ /** What the `progress` part says to a screen reader, with `{percent}` filled
12232
+ in with `progress`. */
12233
+ progressLabel?: (HelixHeadlessSteps["progressLabel"]) | undefined;
11900
12234
  /** What each step is marked with.
11901
12235
 
11902
12236
  Absent is the state itself: a check where a stage is done, a target where
@@ -12441,6 +12775,13 @@ export type HelixHeadlessTableVueEvents = {
12441
12775
  };
12442
12776
 
12443
12777
  export type HelixHeadlessTableRowVueProps = {
12778
+ /** The URL a press on the row follows, which makes the whole row a link.
12779
+ Empty, the default, leaves presses to the row's cells. */
12780
+ href?: (HelixHeadlessTableRow["href"]) | undefined;
12781
+ /** The `rel` of the row's link. You set it yourself, as on an anchor. */
12782
+ rel?: (HelixHeadlessTableRow["rel"]) | undefined;
12783
+ /** Where the row's link opens, such as `_blank`. */
12784
+ target?: (HelixHeadlessTableRow["target"]) | undefined;
12444
12785
  /** The key the table's `selected` lists this row by. Left empty, the row is
12445
12786
  known by its place among the rows as written. */
12446
12787
  value?: (HelixHeadlessTableRow["value"]) | undefined;
@@ -12600,6 +12941,12 @@ export type HelixHeadlessTagGroupHelixDismissElementEvent =
12600
12941
  HelixHeadlessTagGroupElementEvent<HelixDismissEvent>;
12601
12942
 
12602
12943
  export type HelixHeadlessTagGroupVueProps = {
12944
+ /** The words the group shows and says once its last tag is removed, where
12945
+ nothing is in the `empty` slot. */
12946
+ "empty-label"?: (HelixHeadlessTagGroup["emptyLabel"]) | undefined;
12947
+ /** The words the group shows and says once its last tag is removed, where
12948
+ nothing is in the `empty` slot. */
12949
+ emptyLabel?: (HelixHeadlessTagGroup["emptyLabel"]) | undefined;
12603
12950
  /** The name of the set, such as "Filters", which a screen reader announces
12604
12951
  before its tags. */
12605
12952
  label?: (HelixHeadlessTagGroup["label"]) | undefined;
@@ -12926,7 +13273,8 @@ Handed to the list. The value is `HH:mm` on twenty-four hours either way. */
12926
13273
  hourCycle?: (HelixHeadlessTimeInput["hourCycle"]) | undefined;
12927
13274
  /** Language tag the times are written in.
12928
13275
 
12929
- Absent uses the runtime's own. */
13276
+ Absent is the page's: the `lang` of the nearest element with one, as
13277
+ Shoelace and Web Awesome read it, then the runtime's own. */
12930
13278
  locale?: (HelixHeadlessTimeInput["locale"]) | undefined;
12931
13279
  /** Latest time that can be chosen, as `HH:mm`. */
12932
13280
  max?: (HelixHeadlessTimeInput["max"]) | undefined;
@@ -13275,21 +13623,14 @@ English, "Stunde" in German. */
13275
13623
  Absent is the locale's own word, from `Intl.DisplayNames`: "Hour" in
13276
13624
  English, "Stunde" in German. */
13277
13625
  hourLabel?: (HelixHeadlessTimePicker["hourLabel"]) | undefined;
13278
- /** Whether the current selection fails validation.
13279
-
13280
- A flag rather than a message, the same split Date Picker draws. A flat
13281
- picker has no room of its own for a sentence: the field that wraps one owns
13282
- the label, the hint and the feedback, and a second message inside the panel
13283
- would be the same error said twice. What is left for the picker is the one
13284
- thing the field cannot draw from outside, the mark on the answer itself. */
13285
- invalid?: (HelixHeadlessTimePicker["invalid"]) | undefined;
13286
13626
  /** Accessible name for the list, which has no visible one of its own.
13287
13627
 
13288
13628
  An `aria-label` or `aria-labelledby` on the host names the list instead. */
13289
13629
  label?: (HelixHeadlessTimePicker["label"]) | undefined;
13290
- /** Language tag the times are written in.
13630
+ /** Language tag the times and the wheels' names are written in.
13291
13631
 
13292
- Absent uses the runtime's own. */
13632
+ Absent is the page's: the `lang` of the nearest element with one, as
13633
+ Shoelace and Web Awesome read it, then the runtime's own. */
13293
13634
  locale?: (HelixHeadlessTimePicker["locale"]) | undefined;
13294
13635
  /** Stops the arrow keys in the list from choosing each time they move to.
13295
13636
  Enter, Space or a click chooses.
@@ -13442,6 +13783,19 @@ not touch, and React reads that as a hydration mismatch. The absent
13442
13783
  attribute *is* the list, which the stylesheet reads as the base rule, so
13443
13784
  only the departure has to be named. */
13444
13785
  variant?: (HelixHeadlessTimePicker["variant"]) | undefined;
13786
+ /** A message under the picker, such as what is wrong with the answer.
13787
+
13788
+ While set, the picker is invalid and does not submit, as a field's
13789
+ `feedback` is, it is marked invalid to a reader and to CSS, and the
13790
+ controls a reader answers with are described by it. */
13791
+ feedback?: (HelixHeadlessTimePicker["feedback"]) | undefined;
13792
+ /** Whether the answer fails validation, marked on the controls a reader
13793
+ answers with and as `:state(invalid)`.
13794
+
13795
+ A flag a field that wraps the picker sets, since that field owns the
13796
+ label, the hint and the message; on its own, `feedback` both marks the
13797
+ picker and says why. */
13798
+ invalid?: (HelixHeadlessTimePicker["invalid"]) | undefined;
13445
13799
  /** The value the control starts with. A form reset returns it to this value,
13446
13800
  and to the `value` attribute where this one is not written, as a native
13447
13801
  control resets to the `value` it declares. */
@@ -14440,6 +14794,30 @@ export type HelixHeadlessTrendVueProps = {
14440
14794
  "down-label"?: (HelixHeadlessTrend["downLabel"]) | undefined;
14441
14795
  /** The word read out for a move down. */
14442
14796
  downLabel?: (HelixHeadlessTrend["downLabel"]) | undefined;
14797
+ /** `Intl.NumberFormat` options `value` is written with, as React Aria's
14798
+ NumberField takes them: a percent, a currency, a unit or a number of
14799
+ decimals. Written as JSON in the attribute.
14800
+
14801
+ ```html
14802
+ <helix-trend value="-0.084" format-options='{"style":"percent","maximumFractionDigits":1}'></helix-trend>
14803
+ ```
14804
+
14805
+ The example says "Down 8.4%". The size is written without a sign, since
14806
+ the arrow and the word say which way; set `signDisplay` for one. Absent
14807
+ writes the number as the locale writes any number. */
14808
+ "format-options"?: (HelixHeadlessTrend["formatOptions"]) | undefined;
14809
+ /** `Intl.NumberFormat` options `value` is written with, as React Aria's
14810
+ NumberField takes them: a percent, a currency, a unit or a number of
14811
+ decimals. Written as JSON in the attribute.
14812
+
14813
+ ```html
14814
+ <helix-trend value="-0.084" format-options='{"style":"percent","maximumFractionDigits":1}'></helix-trend>
14815
+ ```
14816
+
14817
+ The example says "Down 8.4%". The size is written without a sign, since
14818
+ the arrow and the word say which way; set `signDisplay` for one. Absent
14819
+ writes the number as the locale writes any number. */
14820
+ formatOptions?: (HelixHeadlessTrend["formatOptions"]) | undefined;
14443
14821
  /** Which movement counts as an improvement for this metric.
14444
14822
 
14445
14823
  Absent states the movement without judging it, which is the honest default:
@@ -14447,6 +14825,11 @@ revenue up is good news and latency up is bad news, and only the consumer
14447
14825
  knows which one this is. Set it once per metric and it holds while the
14448
14826
  movement changes underneath. */
14449
14827
  good?: (HelixHeadlessTrend["good"]) | undefined;
14828
+ /** The locale `value` is written in, such as `de` for `1.234,5`.
14829
+
14830
+ Absent uses the runtime's own. Set it on a page rendered on a server, so
14831
+ the server and the browser write the figure alike. */
14832
+ locale?: (HelixHeadlessTrend["locale"]) | undefined;
14450
14833
  /** Which way the measurement moved.
14451
14834
 
14452
14835
  Absent is neutral, so a trend with nothing to report draws a bar rather
@@ -14465,6 +14848,14 @@ three. */
14465
14848
  "up-label"?: (HelixHeadlessTrend["upLabel"]) | undefined;
14466
14849
  /** The word read out for a move up. */
14467
14850
  upLabel?: (HelixHeadlessTrend["upLabel"]) | undefined;
14851
+ /** The change as a signed number, such as `0.12` or `-8`, which sets the
14852
+ movement by its sign and is written as the metric.
14853
+
14854
+ Above zero is up, below is down, and zero is neutral; `movement` wins when
14855
+ both are written. The size is written in the `value` part with
14856
+ `format-options` and `locale`, in place of a slotted metric. Absent leaves
14857
+ the movement to `movement` and the metric to the slot. */
14858
+ value?: (HelixHeadlessTrend["value"]) | undefined;
14468
14859
  /** The word read out after the direction when the move is a setback. */
14469
14860
  "worse-label"?: (HelixHeadlessTrend["worseLabel"]) | undefined;
14470
14861
  /** The word read out after the direction when the move is a setback. */
@@ -14587,7 +14978,7 @@ Ignored once `active` is written. */
14587
14978
  };
14588
14979
 
14589
14980
  export type HelixHeadlessVideoPlaylistVueEvents = {
14590
- /** The current entry changed. The playlist already holds the new entry when this is sent, and `detail.previous` is the entry it left. */
14981
+ /** The current entry changed. The playlist already holds the new entry when this is sent, and `detail.previous` is the entry it left. `currentEntry` is the entry itself, with its `src`, `poster` and name. */
14591
14982
  "helix-activate": HelixHeadlessVideoPlaylistHelixActivateElementEvent;
14592
14983
  /** The current entry is about to change. Cancelable: cancel it to keep the current entry. */
14593
14984
  "helix-before-activate": HelixHeadlessVideoPlaylistHelixBeforeActivateElementEvent;
@@ -14697,7 +15088,11 @@ assumed: it is absent on iPhone and behind a flag in Firefox, and a button
14697
15088
  that cannot work is worse than one that is not there.
14698
15089
 
14699
15090
  The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
14700
- `previous` and `next`.
15091
+ `previous` and `next`. `full` stands for `rewind`, `forward`, `speed`,
15092
+ `pip` and `remote` in that order, the controls that act on the video by
15093
+ themselves, as Web Awesome's `full` preset does, and a name it already
15094
+ holds is drawn once. `extra-controls="full"` is the whole bar, and
15095
+ `overflow-controls="full"` puts all of it behind one button.
14701
15096
 
14702
15097
  **`previous` and `next` do nothing to the video, and are offered anyway.**
14703
15098
  They announce `helix-previous` and `helix-next` and stop there, so what
@@ -14727,7 +15122,11 @@ assumed: it is absent on iPhone and behind a flag in Firefox, and a button
14727
15122
  that cannot work is worse than one that is not there.
14728
15123
 
14729
15124
  The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
14730
- `previous` and `next`.
15125
+ `previous` and `next`. `full` stands for `rewind`, `forward`, `speed`,
15126
+ `pip` and `remote` in that order, the controls that act on the video by
15127
+ themselves, as Web Awesome's `full` preset does, and a name it already
15128
+ holds is drawn once. `extra-controls="full"` is the whole bar, and
15129
+ `overflow-controls="full"` puts all of it behind one button.
14731
15130
 
14732
15131
  **`previous` and `next` do nothing to the video, and are offered anyway.**
14733
15132
  They announce `helix-previous` and `helix-next` and stop there, so what
@@ -15038,6 +15437,10 @@ export type HelixHeadlessVirtualListHelixRangeChangeElementEvent =
15038
15437
  HelixHeadlessVirtualListElementEvent<HelixRangeChangeEvent>;
15039
15438
 
15040
15439
  export type HelixHeadlessVirtualListVueProps = {
15440
+ /** How many items a line holds. One, the default, is a list; more lays the
15441
+ items out as a grid of that many equal columns, windowed a line at a
15442
+ time, with Left and Right moving along a line. */
15443
+ columns?: (HelixHeadlessVirtualList["columns"]) | undefined;
15041
15444
  /** The height of one row, in pixels, used to find the row at a scroll offset.
15042
15445
 
15043
15446
  An estimate rather than a measurement while `measured` is off, which is
@@ -15224,6 +15627,10 @@ export type CustomCssProperties = {
15224
15627
  "--megamenu-surface-inline-size"?: (string) | undefined;
15225
15628
  /** Where the panel starts, measured from the bar above it. */
15226
15629
  "--megamenu-top"?: (string) | undefined;
15630
+ /** The trigger's width, written on the panel while it is open, as in `min-inline-size: var(--floating-anchor-inline-size)`. Read it; a value set here is written over. */
15631
+ "--floating-anchor-inline-size"?: (string) | undefined;
15632
+ /** The room between the panel and the edge of the screen it opens toward, written on the panel while it is open. Read it; a value set here is written over. */
15633
+ "--floating-available-block-size"?: (string) | undefined;
15227
15634
  /** Where a bound sits on the arc, as a length along it. */
15228
15635
  "--meter-along"?: (string) | undefined;
15229
15636
  /** Where a bound sits on a linear track, as a percentage. */
@@ -15244,6 +15651,8 @@ export type CustomCssProperties = {
15244
15651
  "--rating-step"?: (string) | undefined;
15245
15652
  /** The number of steps in the whole row: `max` divided by `step`. */
15246
15653
  "--rating-steps"?: (string) | undefined;
15654
+ /** How large a point is drawn under `size-by`, from 0 to 1, by area. The component writes it, and the stylesheet that sizes the point reads it. */
15655
+ "--chart-point-weight"?: (string) | undefined;
15247
15656
  /** A point's horizontal position, as a percentage. The component writes it. */
15248
15657
  "--chart-point-x"?: (string) | undefined;
15249
15658
  /** A point's vertical position, as a percentage from the top. The component writes it. */
@@ -15254,6 +15663,8 @@ export type CustomCssProperties = {
15254
15663
  "--scroll-area-scroll-fraction"?: (string) | undefined;
15255
15664
  /** The share of the track the thumb covers, from 0 to 1, which is how much of the content is in view. Written on each `scrollbar` part. */
15256
15665
  "--scroll-area-thumb-fraction"?: (string) | undefined;
15666
+ /** Where a bubble's thumb is, as a fraction of the track, 0 to 1. Set on each `tooltip` part. */
15667
+ "--slider-at"?: (string) | undefined;
15257
15668
  /** The value as a fraction of the range, 0 to 1. */
15258
15669
  "--slider-fraction"?: (string) | undefined;
15259
15670
  /** Where the filled span starts, as a fraction of the track, 0 to 1: a range's lower thumb, or a single thumb's `origin`. */
@@ -15298,19 +15709,19 @@ export type CustomCssProperties = {
15298
15709
  // Note: Some tooling expects this augmentation under "@vue/runtime-core", while
15299
15710
  // other docs/examples use "vue". We emit both for compatibility.
15300
15711
  export interface WcToolkitVueGlobalComponents {
15301
- /** Holds its own open state. Used alone, outside an accordion, it works as a disclosure. The trigger sits inside a heading, so a screen reader lists the section with the page's headings. The level is the item's 'heading-level', then the accordion's, then 3. Content stays mounted when the item is closed, so it can animate and its text is present in server-rendered HTML. Closed content has both 'hidden' and 'inert'. 'hidden' collapses it when no stylesheet is loaded. 'inert' keeps it out of the tab order and the accessibility tree after the styled tier's 'display' overrides 'hidden'. While it is open, the content part carries the content's height as '--accordion-content-height', as Radix's accordion does, for a stylesheet that animates the section open with keyframes of its own. Set 'hidden-until-found' and the browser's find in page searches a closed section too: a match opens it, with 'helix-before-open' first, as React Aria's disclosure does. The content is then 'hidden="until-found"' while closed, and not 'inert', since an inert region is never searched. */
15712
+ /** Holds its own open state. Used alone, outside an accordion, it works as a disclosure. The trigger sits inside a heading, so a screen reader lists the section with the page's headings. The level is the item's 'heading-level', then the accordion's, then 3. Content stays mounted when the item is closed, so it can animate and its text is present in server-rendered HTML. The browser's find in page searches a closed section, and a match opens it, with 'helix-before-open' first, as React Aria's disclosure does. Closed content is 'hidden="until-found"', which hides it with no stylesheet loaded and keeps it out of the tab order and the accessibility tree. A section that closes keeps its content drawn until the content part's animations and transitions end, so a sheet that animates the section closed shows the content shrinking rather than an empty box. Set 'hidden-until-found="false"' and a closed section is 'hidden' and 'inert' instead, and find in page skips it. While it is open, the content part carries the content's height as '--accordion-content-height', as Radix's accordion does, for a stylesheet that animates the section open with keyframes of its own. */
15302
15713
  "helix-headless-accordion-item": DefineCustomElement<
15303
15714
  HelixHeadlessAccordionItem,
15304
15715
  HelixHeadlessAccordionItemVueProps,
15305
15716
  HelixHeadlessAccordionItemVueEvents
15306
15717
  >;
15307
- /** Holds the mode. Each item coordinates itself: when you click an item, it finds the nearest accordion, reads the mode, and closes the other items. The accordion does not listen for items opening. 'helix-before-open' does not bubble and is not composed, because overlays nest and an inner overlay's events must stay separate from the outer one's. Items are found when they are clicked, so there is no registry to keep up to date. An item added after render coordinates on its first click. Items are matched with 'instanceof HelixHeadlessAccordionItem', so the headless tier does not depend on the styled tier's tag names. Keys, on a trigger: Up and Down Arrow move to the previous and the next trigger, and so do Left and Right, wrapping at the ends; Home and End go to the first and the last. Enter and Space open and close the section. Disabled sections are passed over. Each trigger is a button with 'aria-expanded' and 'aria-controls', inside a heading, level 3 unless 'heading-level' says otherwise, so the sections are in a screen reader's list of headings. An open section is a region named by its trigger. Set the level that fits the page's outline. */
15718
+ /** Holds the mode. Each item coordinates itself: when you click an item, it finds the nearest accordion, reads the mode, and closes the other items. The accordion does not listen for items opening. 'helix-before-open' does not bubble and is not composed, because overlays nest and an inner overlay's events must stay separate from the outer one's. Items are found when they are clicked, so there is no registry to keep up to date. An item added after render coordinates on its first click. Items are matched with 'instanceof HelixHeadlessAccordionItem', so the headless tier does not depend on the styled tier's tag names. Keys, on a trigger: Up and Down Arrow move to the previous and the next trigger, and so do Left and Right, wrapping at the ends; Home and End go to the first and the last. Enter and Space open and close the section. Disabled sections are passed over. Each trigger is a button with 'aria-expanded' and 'aria-controls', inside a heading, level 3 unless 'heading-level' says otherwise, so the sections are in a screen reader's list of headings. An open section is a region named by its trigger. Set the level that fits the page's outline. Find in page searches the closed sections too, and opens the one it matches in. 'hidden-until-found="false"' turns that off. */
15308
15719
  "helix-headless-accordion": DefineCustomElement<
15309
15720
  HelixHeadlessAccordion,
15310
15721
  HelixHeadlessAccordionVueProps,
15311
15722
  HelixHeadlessAccordionVueEvents
15312
15723
  >;
15313
- /** An announcement is a banner above the page header with news about the whole site or session, such as a trial ending, a degraded service, or a change of terms. For a passage inside a document, use 'Callout', which stays where it is placed and cannot be dismissed. The announcement is always a polite live region, whatever its 'tone'. 'role="alert"' is assertive and interrupts a screen reader, so an announcement served with the page would interrupt on every page load. The live region is its own part. When the announcement appears after the page has loaded, the message is written into the region one frame later, so screen readers read it reliably, and the region is emptied seven seconds later. While the region holds the copy, the message itself is hidden from screen readers, so it is in the page once. When the announcement is in the served HTML, the region stays empty and nothing is read out. The dismiss button fires 'helix-dismiss', and the announcement stays in the document, so remove it in your listener. The event is cancelable, and 'dismiss()' returns 'false' when a listener calls 'preventDefault()'. When your listener removes an announcement whose dismiss button has focus, focus moves to the dismiss button of the announcement beside it. With no other announcement beside it, move focus yourself, for example to the page's main heading. Set 'duration' to dismiss it after a time. The clock stops while the pointer or focus is on the announcement, and continues from what was left, so a reader partway through is not cut off. When the time runs out it sends 'helix-dismiss', as the button does. */
15724
+ /** An announcement is a banner above the page header with news about the whole site or session, such as a trial ending, a degraded service, or a change of terms. For a passage inside a document, use 'Callout', which stays where it is placed and cannot be dismissed. The announcement is always a polite live region, whatever its 'tone'. 'role="alert"' is assertive and interrupts a screen reader, so an announcement served with the page would interrupt on every page load. The live region is its own part. When the announcement appears after the page has loaded, the message is written into the region one frame later, so screen readers read it reliably, and the region is emptied seven seconds later. While the region holds the copy, the message itself is hidden from screen readers, so it is in the page once. When the announcement is in the served HTML, the region stays empty and nothing is read out. The dismiss button fires 'helix-dismiss', and the announcement stays in the document, so remove it in your listener. The event is cancelable, and 'dismiss()' returns 'false' when a listener calls 'preventDefault()'. When your listener removes an announcement whose dismiss button has focus, focus moves to the dismiss button of the announcement beside it. With no other announcement beside it, move focus yourself, for example to the page's main heading. Set 'duration' to dismiss it after a time. The clock stops while the pointer or focus is on the announcement, and continues from what was left, so a reader partway through is not cut off. It stops while the page is hidden too, in another tab or a minimized window, so the message is not spent where nobody can see it. While the clock is stopped the announcement carries ':state(paused)'. When the time runs out it sends 'helix-dismiss', as the button does. */
15314
15725
  "helix-headless-announcement": DefineCustomElement<
15315
15726
  HelixHeadlessAnnouncement,
15316
15727
  HelixHeadlessAnnouncementVueProps,
@@ -15322,7 +15733,7 @@ export interface WcToolkitVueGlobalComponents {
15322
15733
  HelixHeadlessAppHeaderVueProps,
15323
15734
  HelixHeadlessAppHeaderVueEvents
15324
15735
  >;
15325
- /** Shows how a total is made up. Each numeric column of the table is a part, the parts add up to the total at each reading, and the top edge is that total. The thickness of a band is that part's amount. Use 'LineChart' with 'area' to show how each series moved: it fills each series from the floor separately, so the fills overlap. Use this chart to show the composition: it stacks the series. **The value axis always starts at zero**, as in 'BarChart', because a band's thickness is its value. For the same reason there is no streamgraph mode, which moves the baseline. To show how the composition changed, set 'share'. Band edges are straight between readings by default. A smoothed curve through one sum can dip below the curve through the sum beneath it, which draws a part as less than zero. Other curves: - 'curve="smooth"': for a stack read as an overall shape. - 'curve="step"': holds each reading and jumps at the midpoint, so stacked edges stay in order, as with 'straight'. Use it for a quantity that changes at a moment, such as a headcount or a price. 'share' draws each reading as 100 percent, so the top edge is flat and the bands show each part's share. Use it to see which part grew. The default shows whether the total grew. The drawing is hidden from screen readers. The text summary gives the latest reading's total and each part's share of it, and the table beside the chart has every number. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from reading to reading, Home and End go to the first and the last, and the up and down arrows move among the series of a reading. The tooltip follows, the 'live' part says the reading in words, and Escape puts the tooltip away. Every numeric column is a part, so leave a total column out of the table the chart reads, or it is counted twice. A negative reading is drawn as zero. */
15736
+ /** Shows how a total is made up. Each numeric column of the table is a part, the parts add up to the total at each reading, and the top edge is that total. The thickness of a band is that part's amount. Use 'LineChart' with 'area' to show how each series moved: it fills each series from the floor separately, so the fills overlap. Use this chart to show the composition: it stacks the series. **The value axis always starts at zero**, as in 'BarChart', because a band's thickness is its value. For the same reason there is no streamgraph mode, which moves the baseline. To show how the composition changed, set 'share'. Band edges are straight between readings by default. A smoothed curve through one sum can dip below the curve through the sum beneath it, which draws a part as less than zero. Other curves: - 'curve="smooth"': for a stack read as an overall shape. - 'curve="step"': holds each reading and jumps at the midpoint, so stacked edges stay in order, as with 'straight'. Use it for a quantity that changes at a moment, such as a headcount or a price. 'share' draws each reading as 100 percent, so the top edge is flat and the bands show each part's share. Use it to see which part grew. The default shows whether the total grew. 'overlap' draws every band from zero, one in front of another, so each part's own amount is its height: the first column is in front. Use it to compare the parts with each other; the scale then fits the largest part rather than the total. The drawing is hidden from screen readers. The text summary gives the latest reading's total and each part's share of it, and the table beside the chart has every number. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from reading to reading, Home and End go to the first and the last, and the up and down arrows move among the series of a reading. The tooltip follows, the 'live' part says the reading in words, and Escape puts the tooltip away. Every numeric column is a part, so leave a total column out of the table the chart reads, or it is counted twice. A negative reading is drawn as zero. */
15326
15737
  "helix-headless-area-chart": DefineCustomElement<
15327
15738
  HelixHeadlessAreaChart,
15328
15739
  HelixHeadlessAreaChartVueProps,
@@ -15334,13 +15745,13 @@ export interface WcToolkitVueGlobalComponents {
15334
15745
  HelixHeadlessAvatarGroupVueProps,
15335
15746
  HelixHeadlessAvatarGroupVueEvents
15336
15747
  >;
15337
- /** Shows 'src' until it fails to load. Without an image, or after a failure, the default slot is shown, and its own fallback is the initials. The host carries the accessible name, taken from 'name'. The '<img>' has an empty 'alt' and the initials are hidden from assistive technology, so the name is announced once. Set 'aria-label' on the host to override 'name' when a person's name does not describe what the avatar stands for. 'load' and 'error' are re-dispatched from the host, because they are not composed and would otherwise stop at the shadow boundary. */
15748
+ /** Shows 'src' until it fails to load. Without an image, or after a failure, the default slot is shown, and its own fallback is the initials. The host carries the accessible name, taken from 'name'. The '<img>' has an empty 'alt' and the initials are hidden from assistive technology, so the name is announced once. Set 'aria-label' on the host to override 'name' when a person's name does not describe what the avatar stands for. 'load' and 'error' are re-dispatched from the host, because they are not composed and would otherwise stop at the shadow boundary. 'status' says which of the two happened, for a listener that arrives after it, and the 'loading', 'loaded' and 'error' custom states say the same to a stylesheet. **On a server the avatar sends the picture's place**, an '<img>' that the browser fetches while it reads the page. The initials stand in only on the client: at once where the picture failed before the page hydrated, and after 'fallback-delay' where it is still on its way. 'load' or 'error' for a picture that settled before hydration is sent a task after the avatar hydrates, so a page's own scripts are listening by then. */
15338
15749
  "helix-headless-avatar": DefineCustomElement<
15339
15750
  HelixHeadlessAvatar,
15340
15751
  HelixHeadlessAvatarVueProps,
15341
15752
  HelixHeadlessAvatarVueEvents
15342
15753
  >;
15343
- /** Badge wraps the element it decorates and pins an indicator to its corner, so the wrapped element keeps its place in the layout. What the indicator shows depends on 'value': - A 'value' of zero shows no indicator. - No 'value' shows a dot. - Any other value shows the value. Above 'max', the indicator shows '{max}+', so its width stays the same as the count grows. A count is announced from its own text, and 'label' replaces that with a fuller name, such as '4 unread'. A dot needs a 'label'. Without one, the dot is a colored circle that screen readers do not announce. **A badge wrapped around a control is not part of the control's name.** It is a status of its own, read when it changes and when a reader moves to it, so focusing a button inside a badge announces the button's name alone. A reference from the control to the count would point into the badge's shadow root, which the platform does not allow. **Put the badge inside the control to have its count read with the control's name**, as Web Awesome and Shoelace do: '<button>Inbox <helix-badge value="8" label="8 unread"></helix-badge></button>' is the button "Inbox 8 unread", and stays current as the count changes. The styled tier's 'placement="inline"' draws the mark in the line for that case. */
15754
+ /** Badge wraps the element it decorates and pins an indicator to its corner, so the wrapped element keeps its place in the layout. What the indicator shows depends on 'value': - A 'value' of zero shows no indicator. - No 'value' shows a dot. - Any other value shows the value. Above 'max', the indicator shows '{max}+', so its width stays the same as the count grows. 'format-options' writes a count with 'Intl.NumberFormat', in 'locale': 'format-options='{"notation":"compact"}'' shows 1,200 as '1.2K'. Absent, the count is shown as it was given. A count is announced from its own text, and 'label' replaces that with a fuller name, such as '4 unread'. A dot needs a 'label'. Without one, the dot is a colored circle that screen readers do not announce. **A badge wrapped around a control describes it.** The control is the first element in the badge that takes focus, and its description is the badge's words, so focusing '<helix-badge value="8" label="{count} unread"><button>Inbox </button></helix-badge>' announces "Inbox, button, 8 unread", current as the count changes. A control that already has a description keeps its own. The count is also a status of its own, read when it changes. **Put the badge inside the control to have its count read with the control's name**, as Web Awesome and Shoelace do: '<button>Inbox <helix-badge value="8" label="8 unread"></helix-badge></button>' is the button "Inbox 8 unread", and stays current as the count changes. The styled tier's 'placement="inline"' draws the mark in the line for that case. */
15344
15755
  "helix-headless-badge": DefineCustomElement<
15345
15756
  HelixHeadlessBadge,
15346
15757
  HelixHeadlessBadgeVueProps,
@@ -15376,7 +15787,7 @@ export interface WcToolkitVueGlobalComponents {
15376
15787
  HelixHeadlessButtonGroupVueProps,
15377
15788
  HelixHeadlessButtonGroupVueEvents
15378
15789
  >;
15379
- /** Renders a real '<button>', so activation, focus, and other browser behavior come from the platform. **It never renders an anchor.** A router renders its own '<a>' to intercept a click, and it cannot render one inside the button's shadow root. For a link that looks like a button, use the base layer recipe on your own anchor: '<Link data-button="solid">' draws the same control. 'delegatesFocus' moves focus to the inner control. It is serialized into the server markup, so the button is reachable by keyboard before any JavaScript loads. The inner control is always 'type="button"', because a '<button type="submit">' inside a shadow root cannot submit a form outside it. To submit, the button calls 'requestSubmit()' on its form, which runs validation, unlike 'submit()'. A 'submit' listener reads 'event.submitter' as 'null', because the platform accepts only a native submit button there. The button's 'name' and 'value' are in the form data, so read them from 'new FormData(form)' to tell two submit buttons apart. As the first submit button in its form, it is the form's default button: Enter in a text field of the form presses it, as it presses a native one. Set 'pending' while the action a press started is still running. The button keeps focus and refuses presses, and a reader on it hears 'pending-label'. Every press that acts sends 'helix-press' with what pressed it in 'detail.pointerType': 'mouse', 'pen', 'touch', 'keyboard', or 'virtual' for a screen reader's press or a script's 'click()', as React Aria's 'onPress' does. It is sent once the press has done its own work, before 'click' reaches listeners on the element, and never for a disabled or pending button. **Keyboard.** Enter and Space press the button, as on a native one. */
15790
+ /** Renders a real '<button>', so activation, focus, and other browser behavior come from the platform. **It never renders an anchor.** A router renders its own '<a>' to intercept a click, and it cannot render one inside the button's shadow root. For a link that looks like a button, use the base layer recipe on your own anchor: '<Link data-button="solid">' draws the same control. 'delegatesFocus' moves focus to the inner control. It is serialized into the server markup, so the button is reachable by keyboard before any JavaScript loads. The inner control is always 'type="button"', because a '<button type="submit">' inside a shadow root cannot submit a form outside it. To submit, the button puts a hidden native submit button carrying its 'name', 'value' and 'form*' overrides into the form, calls 'requestSubmit()' with it, which runs validation, unlike 'submit()', and takes it out again, as Shoelace and Web Awesome do. A 'submit' listener reads that button as 'event.submitter', so 'event.submitter.value' and 'new FormData(form, event.submitter)' tell two submit buttons apart. As the first submit button in its form, it is the form's default button: Enter in a text field of the form presses it, as it presses a native one. Set 'pending' while the action a press started is still running. The button keeps focus and refuses presses, and a reader on it hears 'pending-label'. Every press that acts sends 'helix-press' with what pressed it in 'detail.pointerType': 'mouse', 'pen', 'touch', 'keyboard', or 'virtual' for a screen reader's press or a script's 'click()', as React Aria's 'onPress' does. It is sent once the press has done its own work, before 'click' reaches listeners on the element, and never for a disabled or pending button. **Keyboard.** Enter and Space press the button, as on a native one. */
15380
15791
  "helix-headless-button": DefineCustomElement<
15381
15792
  HelixHeadlessButton,
15382
15793
  HelixHeadlessButtonVueProps,
@@ -15406,7 +15817,7 @@ export interface WcToolkitVueGlobalComponents {
15406
15817
  HelixHeadlessCanvasVueProps,
15407
15818
  HelixHeadlessCanvasVueEvents
15408
15819
  >;
15409
- /** The header, body, and footer regions are slots, because they have no state, behavior, or API of their own. You bring your own markup, so a title can be a real '<h2>'. The host is the surface. The element itself takes the border, the radius, and the grid, so you style 'Card' directly and there is no wrapper part to reach through with '::part'. Name the card with 'label', as a Stat Group is named, or with 'aria-label' or 'aria-labelledby'. These are the only names that work with server rendering, because reading a title from the light DOM needs a DOM, and the server has none. 'label' is set through 'ElementInternals', so it writes no attribute onto the card. **A named card is a group**, so a reader entering it hears its name; an unnamed one has no role, since a group with no name only adds "group" to what a reader says. Each region's slot is a part of the same name, 'body' for the main content, as Web Awesome's card names its regions. A slot draws no box, so a part passes inherited properties to what is slotted, and a page wanting a box there gives it one with 'display'. 'header-actions' and 'footer-actions' hold controls at the end of the header's and the footer's line, as Web Awesome's card does. While one holds something, its line is a 'header-row' or 'footer-row' part; otherwise there is no wrapper and every region is a bare slot. A server cannot see slotted content, so served actions sit on their own line until the script runs. */
15820
+ /** The header, body, and footer regions are slots, because they have no state, behavior, or API of their own. You bring your own markup, so a title can be a real '<h2>'. The host is the surface. The element itself takes the border, the radius, and the grid, so you style 'Card' directly and there is no wrapper part to reach through with '::part'. Name the card with 'label', as a Stat Group is named, or with 'aria-label' or 'aria-labelledby'. These are the only names that work with server rendering, because reading a title from the light DOM needs a DOM, and the server has none. 'label' is set through 'ElementInternals', so it writes no attribute onto the card. **A named card is a group**, so a reader entering it hears its name; an unnamed one has no role, since a group with no name only adds "group" to what a reader says. Each region's slot is a part of the same name, 'body' for the main content, as Web Awesome's card names its regions. A slot draws no box, so a part passes inherited properties to what is slotted, and a page wanting a box there gives it one with 'display'. 'header-actions' and 'footer-actions' hold controls at the end of the header's and the footer's line, as Web Awesome's card does. While one holds something, its line is a 'header-row' or 'footer-row' part; otherwise there is no wrapper and every region is a bare slot. A server cannot see slotted content, so served actions sit on their own line until the script runs. **The card says which regions it holds**, as ':state(has-media)', ':state(has-header)' and ':state(has-footer)', so a sheet can draw a card with a header differently, as Web Awesome's 'with-header' does, with no attribute written onto the card. Read in the browser, so a served card carries none until the script runs. */
15410
15821
  "helix-headless-card": DefineCustomElement<
15411
15822
  HelixHeadlessCard,
15412
15823
  HelixHeadlessCardVueProps,
@@ -15430,7 +15841,7 @@ export interface WcToolkitVueGlobalComponents {
15430
15841
  HelixHeadlessChatMessageVueProps,
15431
15842
  HelixHeadlessChatMessageVueEvents
15432
15843
  >;
15433
- /** Chat has no positioning, no backdrop, and no trigger, so you can put it in any container, such as a page, a sidebar, a modal, or a floating panel. The transcript stays pinned to the bottom, including while a streamed answer grows, until the user scrolls more than 'threshold' away from it. With 'history' set to 'more', reaching the top fires 'helix-history'. Set 'loading' while you fetch, then prepend the older turns. The turn the user was reading stays in place on screen. The log is 'aria-live="off"'. A separate status region announces each new turn once, when it has finished arriving. It skips the user's own turns unless they failed to send, turns loaded as history, and the turns already there when the transcript opened. Pass the turns as children or as 'turns' data. Do not use both. Children render from the server and suit most conversations. 'turns' draws a long transcript one window at a time, so the log needs a block size of its own. **A conversation is built from three elements.** The chat holds the transcript, a 'Chat.Message' stands for each turn, and a 'Chat.Composer' sits in the 'composer' slot. When the user sends, 'helix-send' reaches the chat: add their turn with 'author="me"' and 'state="sending"', then set 'state' to 'sent' or 'failed' when your server answers. Add the reply as a turn with 'state="streaming"', write its text as it arrives, and set 'state' to 'sent' when it is complete. While the user types, the composer sends 'helix-typing', which you can pass on to the other side. When the other side types, set 'typing' to their name: the status band draws three dots and "Ada is typing" ('typing-label'), which a screen reader hears, and clearing it takes them away. Anything slotted into 'status' is drawn first. A screen reader names each turn by its author and its time, such as "You, 2 minutes ago". Set 'me-label' and 'message-label' to say it in your language, and give each turn by 'them' an 'author-label'. A turn with neither an author label nor a time is named by 'turn-label', "Message". A turn from 'turns' is drawn in the chat's shadow root, so style it through the forwarded 'message-*' parts. A turn by 'me' also gets each part with '-mine' added, and the turn's state adds 'message-meta-failed', 'message-content-sending', and 'message-content-streaming'. To style each participant differently, pass the turns as children. */
15844
+ /** Chat has no positioning, no backdrop, and no trigger, so you can put it in any container, such as a page, a sidebar, a modal, or a floating panel. The transcript stays pinned to the bottom, including while a streamed answer grows, until the user scrolls more than 'threshold' away from it. With 'history' set to 'more', reaching the top fires 'helix-history'. Set 'loading' while you fetch, then prepend the older turns. The turn the user was reading stays in place on screen. The log is 'aria-live="off"'. A separate status region announces each new turn once, when it has finished arriving. It skips the user's own turns unless they failed to send, turns loaded as history, and the turns already there when the transcript opened. Pass the turns as children or as 'turns' data. Do not use both. Children render from the server and suit most conversations. 'turns' draws a long transcript one window at a time, so the log needs a block size of its own. **A conversation is built from three elements.** The chat holds the transcript, a 'Chat.Message' stands for each turn, and a 'Chat.Composer' sits in the 'composer' slot. When the user sends, 'helix-send' reaches the chat: add their turn with 'author="me"' and 'state="sending"', then set 'state' to 'sent' or 'failed' when your server answers. Add the reply as a turn with 'state="streaming"', write its text as it arrives, and set 'state' to 'sent' when it is complete. While the user types, the composer sends 'helix-typing', which you can pass on to the other side. When the other side types, set 'typing' to their name: the status band draws three dots and "Ada is typing" ('typing-label'), which a screen reader hears, and clearing it takes them away. Anything slotted into 'status' is drawn first. A screen reader names each turn by its author and its time, such as "You, 2 minutes ago". Set 'me-label' and 'message-label' to say it in your language, and give each turn by 'them' an 'author-label'. A turn with neither an author label nor a time is named by 'turn-label', "Message". A turn from 'turns' is drawn in the chat's shadow root, so style it through the forwarded 'message-*' parts. A turn by 'me' also gets each part with '-mine' added, and the turn's state adds 'message-meta-failed', 'message-content-sending', and 'message-content-streaming'. To style each participant differently, give 'author-styles' the declarations for each author, such as '{"ada": "--chat-message-background-color: …"}': the message drawn for each of their turns takes them as its 'style', so the message's custom properties change for that author alone. Turns passed as children are styled by their 'author', such as 'helix-chat-message[author="ada"]'. */
15434
15845
  "helix-headless-chat": DefineCustomElement<
15435
15846
  HelixHeadlessChat,
15436
15847
  HelixHeadlessChatVueProps,
@@ -15448,7 +15859,7 @@ export interface WcToolkitVueGlobalComponents {
15448
15859
  HelixHeadlessCheckboxVueProps,
15449
15860
  HelixHeadlessCheckboxVueEvents
15450
15861
  >;
15451
- /** Renders a '<pre><code>' pair: 'pre' keeps the whitespace, and 'code' marks it as code. Long lines scroll inside the block and do not wrap, because a line break can be significant in code. A copy button is on by default. Set 'no-copy' to remove it. The button copies the slotted text, so there is no second copy of the code to keep in sync. For a fragment of code inside a sentence, use 'Code'. Set 'line-numbers' to number the lines in a gutter beside the code, hidden from the accessibility tree and left out of a copy. Set 'highlight' to a function that turns the code into highlighted markup, such as one wrapping Shiki or Prism, and the block draws what it returns; the code stays in the slot, so the copy button and the page's own text are the code as written. Set 'expandable' on a block whose height is capped, such as by '--code-block-max-block-size', and a button under it shows every line and then fewer again, as a docs site's long example does. The button is drawn only while the cap hides something, says whether the block is expanded, and the block carries ':state(expanded)' while it is. Set 'diff' to show a change. Put a unified diff, the output of 'git diff' or 'diff -u', in the same slot, and the block draws the lines it added and removed. The block never computes a diff itself. Line numbers come from the hunk headers and are hidden from the accessibility tree. Changed lines are '<ins>' and '<del>' with the '+' and '-' kept as text, so the change does not depend on color. Each file in the patch is its own block under its own name, and its copy button copies the new version of the file. 'variant="split"' shows the old version beside the new, each removal opposite its replacement. On the server, the slot renders as ordinary code, so a diff first appears as the patch text in a '<pre>'. The client makes the same first render, which keeps hydration clean, and draws the diff once it can read the content. Diff mode is experimental. The rest of the family is stable. */
15862
+ /** Renders a '<pre><code>' pair: 'pre' keeps the whitespace, and 'code' marks it as code. Long lines scroll inside the block and do not wrap, because a line break can be significant in code. A copy button is on by default. Set 'no-copy' to remove it. The button copies the slotted text, so there is no second copy of the code to keep in sync. For a fragment of code inside a sentence, use 'Code'. Set 'line-numbers' to number the lines in a gutter beside the code, hidden from the accessibility tree and left out of a copy. Set 'highlight' to a function that turns the code into highlighted markup, such as one wrapping Shiki or Prism, and the block draws what it returns; it is handed the block's 'language', so one function serves every block. The code stays in the slot, so the copy button and the page's own text are the code as written. Set 'expandable' on a block whose height is capped, such as by '--code-block-max-block-size', and a button under it shows every line and then fewer again, as a docs site's long example does. The button is drawn only while the cap hides something, says whether the block is expanded with 'aria-expanded', names the block it opens with 'aria-controls', and the block carries ':state(expanded)' while it is. Set 'diff' to show a change. Put a unified diff, the output of 'git diff' or 'diff -u', in the same slot, and the block draws the lines it added and removed. The block never computes a diff itself. Line numbers come from the hunk headers and are hidden from the accessibility tree. Changed lines are '<ins>' and '<del>' with the '+' and '-' kept as text, so the change does not depend on color. Each file in the patch is its own block under its own name, and its copy button copies the new version of the file. 'variant="split"' shows the old version beside the new, each removal opposite its replacement. On the server, the slot renders as ordinary code, so a diff first appears as the patch text in a '<pre>'. The client makes the same first render, which keeps hydration clean, and draws the diff once it can read the content. Diff mode is experimental. The rest of the family is stable. */
15452
15863
  "helix-headless-code-block": DefineCustomElement<
15453
15864
  HelixHeadlessCodeBlock,
15454
15865
  HelixHeadlessCodeBlockVueProps,
@@ -15484,7 +15895,7 @@ export interface WcToolkitVueGlobalComponents {
15484
15895
  HelixHeadlessCommandVueProps,
15485
15896
  HelixHeadlessCommandVueEvents
15486
15897
  >;
15487
- /** Copies text to the clipboard and confirms the copy. The platform gives no feedback for a clipboard write, so without a confirmation a press that copies looks the same as one that fails. The confirmation and the event wait for the write to finish. The browser can refuse a clipboard write, for example on an insecure origin, in a document that is not focused, or after a gesture that does not qualify. A refused write, or nothing to copy, names the button with 'error-label' for the same moment a copy shows 'copied-label', draws a cross, and sends 'helix-copy-error'. 'from' copies from another element on the page: its text, an attribute written 'id[attribute]', or a property written 'id.property', read at the press. It takes the place of 'value'. It replaces Button's render and its press, so it never submits a form or sends a command: 'type', 'command', 'commandfor' and the 'form*' overrides have no effect, and the 'start' and 'end' slots and the 'text' part are not rendered. An 'aria-label' on the element names it before a copy, in place of 'label'. */
15898
+ /** Copies text to the clipboard and confirms the copy. The platform gives no feedback for a clipboard write, so without a confirmation a press that copies looks the same as one that fails. The confirmation and the event wait for the write to finish. The browser can refuse a clipboard write, for example on an insecure origin, in a document that is not focused, or after a gesture that does not qualify. A refused write, or nothing to copy, names the button with 'error-label' for the same moment a copy shows 'copied-label', draws a cross, and sends 'helix-copy-error'. 'from' copies from another element on the page: its text, an attribute written 'id[attribute]', or a property written 'id.property', read at the press. It takes the place of 'value'. It replaces Button's render and its press, so it never submits a form or sends a command: 'type', 'command', 'commandfor' and the 'form*' overrides have no effect, and the 'start' and 'end' slots and the 'text' part are not rendered. An 'aria-label' on the element names it before a copy, in place of 'label'. **Keyboard.** Enter and Space copy, as they press a native button. The button is named 'label', or the host's 'aria-label', and its name changes to 'copied-label' or 'error-label' for the moment after a press, which is what a screen reader on it hears. The tooltip shows the same words. */
15488
15899
  "helix-headless-copy-button": DefineCustomElement<
15489
15900
  HelixHeadlessCopyButton,
15490
15901
  HelixHeadlessCopyButtonVueProps,
@@ -15508,7 +15919,7 @@ export interface WcToolkitVueGlobalComponents {
15508
15919
  HelixHeadlessDatePickerVueProps,
15509
15920
  HelixHeadlessDatePickerVueEvents
15510
15921
  >;
15511
- /** Each pair is its own element: the label is the '<dt>' and the value its '<dd>', and a screen reader hears them together however the list lays them out. The value is the default slot, because it varies and is often more than text, such as a tag, an avatar, or a link. The label is almost always text, so it is also a property. **For a label with several values, write each value as a '<dd>'**, such as the authors of a paper. The item then puts your '<dd>' elements after its '<dt>' in place of its own, so a screen reader hears one term and each of its descriptions, as in a native '<dl>'. A server cannot see your elements, so the served item wraps them in its own '<dd>' until it runs. */
15922
+ /** Each pair is its own element: the label is the '<dt>' and the value its '<dd>', and a screen reader hears them together however the list lays them out. The value is the default slot, because it varies and is often more than text, such as a tag, an avatar, or a link. The label is almost always text, so it is also a property. **For a label with several values, write each value as a '<dd>'**, such as the authors of a paper. The item then puts your '<dd>' elements after its '<dt>' in place of its own, so a screen reader hears one term and each of its descriptions, as in a native '<dl>'. A server cannot see your elements, so set 'several' as well, and the served item leaves them unwrapped too. Without it, the served item wraps them in its own '<dd>' until it runs. **Controls that act on the value**, such as a copy button, go in the 'actions' slot, drawn after the value inside its '<dd>', as Radix Themes' data list puts an icon button beside a value. A screen reader hears them as part of the description they act on. With several values, put each control inside the '<dd>' it acts on. */
15512
15923
  "helix-headless-description-list-item": DefineCustomElement<
15513
15924
  HelixHeadlessDescriptionListItem,
15514
15925
  HelixHeadlessDescriptionListItemVueProps,
@@ -15538,13 +15949,13 @@ export interface WcToolkitVueGlobalComponents {
15538
15949
  HelixHeadlessDonutChartVueProps,
15539
15950
  HelixHeadlessDonutChartVueEvents
15540
15951
  >;
15541
- /** Uses 'MixinControllerOpen', so 'open', 'defaultOpen', and the 'helix-before-open' and 'helix-before-close' events work the same way as on an accordion item. The drawer is modal by default, which means four things: - focus is trapped inside - Escape and a press outside close it - the page behind is covered - the page behind does not scroll A drawer with 'modal="false"' leaves the page usable and still closes on Escape, in a browser without 'closedby' as well. **A touch or a pen swipes it away**, toward the edge it came from, resolved against the writing direction. A swipe past halfway, or a quick one, closes it through the same request as every other way out. 'snap-points' lists the fractions of the panel a reader can leave on screen, such as '0.5 1' for a sheet that rests half open: it opens at the smallest, and a swipe settles at the nearest. While a swipe moves the panel, the distance is written on it as '--drawer-swipe-x' and '--drawer-swipe-y'. 'swipe="false"' turns swiping off. 'snap' is the snap point the panel rests at, and ':state(snapped)' is on the host while that is less than the whole panel. 'snapTo()' moves it to another. **Focus moving to a control past the window's edge opens the panel to its largest snap point**, so a reader moving through a half open sheet with 'Tab' never lands on a control they cannot see. Set 'dismissible' to draw a close control in the corner, labeled by 'dismiss-label', as 'Dialog' draws one. The panel's name is 'label' when you set it. Otherwise it is the heading in the 'header' slot, or the elements an 'aria-labelledby' on the host names. Content stays mounted when the drawer is closed, so it is in the server markup and can animate. A closed '<dialog>' is already out of the tab order and the accessibility tree, so the drawer does not write 'inert'. The 'role', 'aria-modal', and the scrim also come from the '<dialog>' element. 'drawer-root.ssr.spec.ts' checks that the panel has no hand-written 'inert' or 'role'. Open the drawer declaratively with the platform's invoker attributes: '''html <helix-headless-button commandfor="nav" command="--toggle">Menu</helix-headless-button> <helix-headless-drawer id="nav">…</helix-headless-drawer> ''' */
15952
+ /** Uses 'MixinControllerOpen', so 'open', 'defaultOpen', and the 'helix-before-open' and 'helix-before-close' events work the same way as on an accordion item. The drawer is modal by default, which means four things: - focus is trapped inside: 'Tab' from the last control goes to the first, and 'Shift+Tab' from the first to the last, as in 'Dialog' - Escape and a press outside close it - the page behind is covered - the page behind does not scroll A drawer with 'modal="false"' leaves the page usable and still closes on Escape, in a browser without 'closedby' as well. **A touch or a pen swipes it away**, toward the edge it came from, resolved against the writing direction. A swipe past halfway, or a quick one, closes it through the same request as every other way out. 'snap-points' lists the fractions of the panel a reader can leave on screen, such as '0.5 1' for a sheet that rests half open: it opens at the smallest, and a swipe settles at the nearest. While a swipe moves the panel, the distance is written on it as '--drawer-swipe-x' and '--drawer-swipe-y'. 'swipe="false"' turns swiping off. 'snap' is the snap point the panel rests at, and ':state(snapped)' is on the host while that is less than the whole panel. 'snapTo()' moves it to another. **Focus moving to a control past the window's edge opens the panel to its largest snap point**, so a reader moving through a half open sheet with 'Tab' never lands on a control they cannot see. Set 'dismissible' to draw a close control in the corner, labeled by 'dismiss-label', as 'Dialog' draws one. The panel's name is 'label' when you set it. Otherwise it is the heading in the 'header' slot, or the elements an 'aria-labelledby' on the host names. Content stays mounted when the drawer is closed, so it is in the server markup and can animate. A closed '<dialog>' is already out of the tab order and the accessibility tree, so the drawer does not write 'inert'. The 'role', 'aria-modal', and the scrim also come from the '<dialog>' element. 'drawer-root.ssr.spec.ts' checks that the panel has no hand-written 'inert' or 'role'. Open the drawer declaratively with the platform's invoker attributes: '''html <helix-headless-button commandfor="nav" command="--toggle">Menu</helix-headless-button> <helix-headless-drawer id="nav">…</helix-headless-drawer> ''' */
15542
15953
  "helix-headless-drawer": DefineCustomElement<
15543
15954
  HelixHeadlessDrawer,
15544
15955
  HelixHeadlessDrawerVueProps,
15545
15956
  HelixHeadlessDrawerVueEvents
15546
15957
  >;
15547
- /** A row that opens a page contains that page: the page's rows are this row's own children, assigned to the 'page' slot. There are no ids to wire, and moving a row moves its page with it. What the item renders depends on the stack: - On the page that is showing, it renders its row. - When its own page is showing, it renders only that page's rows. Its row belongs to the page above. - Otherwise it renders nothing. The rows stay in the light DOM untouched, so there is no state to keep. Choosing a row dispatches an event, and the stack decides whether that drills in or runs a command. A row that opens a page shows a caret after its text and sets 'aria-haspopup', the same way 'Menu' marks a row with a submenu. The server render leaves both out, because the server cannot see the children. */
15958
+ /** A row that opens a page contains that page: the page's rows are this row's own children, assigned to the 'page' slot. There are no ids to wire, and moving a row moves its page with it. What the item renders depends on the stack: - On the page that is showing, it renders its row. - When its own page is showing, it renders only that page's rows. Its row belongs to the page above. - When a page further down its own is showing, it renders its page's slot alone, so the rows below reach the page. - Otherwise it renders nothing. The rows stay in the light DOM untouched, so there is no state to keep. Choosing a row dispatches an event, and the stack decides whether that drills in or runs a command. A row that opens a page shows a caret after its text and sets 'aria-haspopup', the same way 'Menu' marks a row with a submenu. The server render leaves both out, because the server cannot see the children. The row is named by its label alone. Words in 'description', a line under the label, and in 'end' describe it instead, through 'aria-describedby', as 'Menu.Item' does: a reader hears "Theme", then "Dark". */
15548
15959
  "helix-headless-drilldown-item": DefineCustomElement<
15549
15960
  HelixHeadlessDrilldownItem,
15550
15961
  HelixHeadlessDrilldownItemVueProps,
@@ -15556,7 +15967,7 @@ export interface WcToolkitVueGlobalComponents {
15556
15967
  HelixHeadlessDrilldownVueProps,
15557
15968
  HelixHeadlessDrilldownVueEvents
15558
15969
  >;
15559
- /** Shows what would be in a region and the one action that would fill it, so an empty region does not look like one that failed to load. The message is announced, because an empty view often replaces content that was loading, and the announcement tells a screen reader user that the search returned nothing. It is announced from a status region of its own, which is rendered empty and filled a frame after the view appears. Screen readers read a region that arrives with its text already in it inconsistently. For the seven seconds the region holds its copy, the heading and the message are hidden from screen readers, so the words are in the page once. Every region is a bare slot. There is no 'empty-state-heading' or 'empty-state-actions' element: assign your own heading and actions to the slots. */
15970
+ /** Shows what would be in a region and the one action that would fill it, so an empty region does not look like one that failed to load. The message is announced, because an empty view often replaces content that was loading, and the announcement tells a screen reader user that the search returned nothing. It is announced from a status region of its own, which is rendered empty and filled a frame after the view appears. Screen readers read a region that arrives with its text already in it inconsistently. For the seven seconds the region holds its copy, the heading and the message are hidden from screen readers, so the words are in the page once. Every region is a bare slot. There is no 'empty-state-heading' or 'empty-state-actions' element: assign your own heading and actions to the slots. **Or give the heading as words.** 'heading' draws them in a 'heading' part that is a heading at 'heading-level', 3 where it is not set, so a page rendering from data or on a server gets a heading a reader finds in the outline without writing the element. A heading slotted in replaces it. */
15560
15971
  "helix-headless-empty": DefineCustomElement<
15561
15972
  HelixHeadlessEmpty,
15562
15973
  HelixHeadlessEmptyVueProps,
@@ -15568,7 +15979,7 @@ export interface WcToolkitVueGlobalComponents {
15568
15979
  HelixHeadlessFileInputVueProps,
15569
15980
  HelixHeadlessFileInputVueEvents
15570
15981
  >;
15571
- /** Shows one filter declared by a 'FilterField': the field, the operator, and the values, with a control to remove the filter. The operator is shown only when it is not the field's default: ''' Disposition refunded, chargeback default operator, hidden Disposition is not refunded chosen operator, shown Created after 1 Aug a scalar field has no default ''' Omit 'operator-label' for the field's default operator and pass it for every other operator. The code that builds the chip has the field, and the field defines its default. The chip shows a filter and does not apply it. Dismissing fires 'helix-dismiss' as a request, as on 'Tag' and 'Announcement'. The chip is your element in your list, so you remove it, which keeps your model and the document in step. Call 'preventDefault()' on 'helix-dismiss' to cancel the dismissal, which is also how you take control of the interaction for one press. 'requestChange' documents the pattern. To let the user change the operator, slot a menu trigger into 'operator'. With the text fallback, the operator is a label. The chip does not interpret operators: their meaning belongs to your domain, as 'FilterOperator' explains. */
15982
+ /** Shows one filter declared by a 'FilterField': the field, the operator, and the values, with a control to remove the filter. The operator is shown only when it is not the field's default: ''' Disposition refunded, chargeback default operator, hidden Disposition is not refunded chosen operator, shown Created after 1 Aug a scalar field has no default ''' Omit 'operator-label' for the field's default operator and pass it for every other operator. The code that builds the chip has the field, and the field defines its default. The chip shows a filter and does not apply it. Dismissing fires 'helix-dismiss' as a request, as on 'Tag' and 'Announcement'. The chip is your element in your list, so you remove it, which keeps your model and the document in step. Call 'preventDefault()' on 'helix-dismiss' to cancel the dismissal, which is also how you take control of the interaction for one press. 'requestChange' documents the pattern. **Keyboard.** The remove button is a tab stop of its own, and Enter or Space on it asks to remove the filter. In a 'FilterInput', Backspace in the empty field asks to remove the last chip. The remove button is named 'dismiss-label' followed by the chip's words, such as "Remove filter Status is not open", so a row of chips says which filter each button removes. Write '{label}' in 'dismiss-label' to put the words elsewhere. To let the user change the operator, slot a menu trigger into 'operator'. With the text fallback, the operator is a label. The chip does not interpret operators: their meaning belongs to your domain, as 'FilterOperator' explains. */
15572
15983
  "helix-headless-filter-chip": DefineCustomElement<
15573
15984
  HelixHeadlessFilterChip,
15574
15985
  HelixHeadlessFilterChipVueProps,
@@ -15598,7 +16009,7 @@ export interface WcToolkitVueGlobalComponents {
15598
16009
  HelixHeadlessFilterInputVueProps,
15599
16010
  HelixHeadlessFilterInputVueEvents
15600
16011
  >;
15601
- /** Formats a date with 'Intl' where it is shown, so you do not write the same 'Intl' call and options in your own code. **'elapsed' shows compact relative time for a feed**, such as "42m", "3h", or "1d". After six days it shows a date. In en-US, 'Intl.NumberFormat' narrow renders both 'minute' and 'month' as 'm', so a compact "3m" could mean three minutes or three months. 'elapsedTime' in 'helix/core' does the measurement. **'relative' shows the same reading in words**, such as "3 hours ago" at 'long', "3 hr. ago" at 'short' and "3h ago" at 'narrow', the styles 'sl-relative-time' offers. 'numeric="always"' says "1 day ago" where the default says "yesterday". **'date-style' and 'time-style' take each locale's own pattern**, such as "Tuesday, August 4, 2026" at 'full', and stand in for the separate fields, which 'Intl' refuses beside them. 'hour-cycle' sets a twelve or twenty-four hour clock either way. **The text refreshes on one timer shared by the page.** Each element schedules an update for when its current reading expires, and an element showing a date schedules none, so a long feed left open costs almost nothing. **The output is always '<time datetime>'**, so copy and paste and scripts parsing the page get the exact instant, whatever the visible text says. A screen reader reads the text, so an 'elapsed' reading is named in full, such as "3 hours ago", and carries the whole date as its title. **A date with no time, such as '2026-08-04', is that day everywhere.** It is formatted in UTC unless 'time-zone' says otherwise, as Date Input and Date Picker format their dates, so a reader west of UTC sees August 4 and not August 3. */
16012
+ /** Formats a date with 'Intl' where it is shown, so you do not write the same 'Intl' call and options in your own code. **'elapsed' shows compact relative time for a feed**, such as "42m", "3h", or "1d". After six days it shows a date. In en-US, 'Intl.NumberFormat' narrow renders both 'minute' and 'month' as 'm', so a compact "3m" could mean three minutes or three months. 'elapsedTime' in 'helix/core' does the measurement. **'relative' shows the same reading in words**, such as "3 hours ago" at 'long', "3 hr. ago" at 'short' and "3h ago" at 'narrow', the styles 'sl-relative-time' offers. 'numeric="always"' says "1 day ago" where the default says "yesterday". **'date-style' and 'time-style' take each locale's own pattern**, such as "Tuesday, August 4, 2026" at 'full', and stand in for the separate fields, which 'Intl' refuses beside them. 'hour-cycle' sets a twelve or twenty-four hour clock either way. **The text refreshes on one timer shared by the page.** Each element schedules an update for when its current reading expires, and an element showing a date schedules none, so a long feed left open costs almost nothing. 'frozen' draws the reading once and leaves it. **The output is always '<time datetime>'**, so copy and paste and scripts parsing the page get the exact instant, whatever the visible text says. A screen reader reads the text, so an 'elapsed' reading is named in full, such as "3 hours ago", and carries the whole date as its title. **A date with no time, such as '2026-08-04', is that day everywhere.** It is formatted in UTC unless 'time-zone' says otherwise, as Date Input and Date Picker format their dates, so a reader west of UTC sees August 4 and not August 3. */
15602
16013
  "helix-headless-format-date": DefineCustomElement<
15603
16014
  HelixHeadlessFormatDate,
15604
16015
  HelixHeadlessFormatDateVueProps,
@@ -15610,7 +16021,7 @@ export interface WcToolkitVueGlobalComponents {
15610
16021
  HelixHeadlessGraphVueProps,
15611
16022
  HelixHeadlessGraphVueEvents
15612
16023
  >;
15613
- /** A grid of cells, each colored by a tone. 'rows="1"' makes a status strip, and 'rows="7"' makes a contribution graph. GitHub's contribution graph uses five discrete levels, which a set of tones covers. Color in a heatmap is per cell. In every other Helix chart, color is per series, so ninety differently colored cells would need ninety series. **The data is a real '<table>' named by 'for'**, as in every Helix chart, and the table is the accessible representation. Hide it with 'data-hidden-visually', and screen readers still read it. A cell takes its tone from its own 'data-tone', or from 'thresholds' and 'tones' applied to its value. 'data-tone' wins, so when you already know a day was degraded, you can set the tone directly. **The headless tier does not resolve tone names.** A tone named 'success' writes '--heatmap-tone: var(--heatmap-tone-success)', and the styled tier or your own stylesheet defines that property. The headless tier does not use 'var(--helix-color-*)'. **The strip is read by key.** It takes focus once it has cells. The up and down arrows move a cell, the left and right arrows move a column, which is a week with 'rows="7"', and Home and End go to the first and the last. The tooltip follows, the 'live' part says the cell's row in words, and Escape puts the tooltip away. PageUp and PageDown move four columns, which is four weeks with 'rows="7"'. **The strip describes itself.** The 'overview' part says the busiest reading and the total of the readings drawn, "Busiest: 11 Jun 12; Total 84", and the strip is described by it, as every chart is by its summary. Hide it visually. The 'summary' slot is still yours, for words of your own. */
16024
+ /** A grid of cells, each colored by a tone. 'rows="1"' makes a status strip, and 'rows="7"' makes a contribution graph. GitHub's contribution graph uses five discrete levels, which a set of tones covers. Color in a heatmap is per cell. In every other Helix chart, color is per series, so ninety differently colored cells would need ninety series. **The data is a real '<table>' named by 'for'**, as in every Helix chart, and the table is the accessible representation. Hide it with 'data-hidden-visually', and screen readers still read it. A cell takes its tone from its own 'data-tone', or from 'thresholds' and 'tones' applied to its value. 'data-tone' wins, so when you already know a day was degraded, you can set the tone directly. **The headless tier does not resolve tone names.** A tone named 'success' writes '--heatmap-tone: var(--heatmap-tone-success)', and the styled tier or your own stylesheet defines that property. The headless tier does not use 'var(--helix-color-*)'. **The strip is read by key.** It takes focus once it has cells. The up and down arrows move a cell, the left and right arrows move a column, which is a week with 'rows="7"', and Home and End go to the first and the last. The tooltip follows, the 'live' part says the cell's row in words, and Escape puts the tooltip away. PageUp and PageDown move a month, to the same day, where each row's header carries its date as a '<time datetime>', and four columns otherwise, which is four weeks with 'rows="7"'. **The strip describes itself.** The 'overview' part says the busiest reading and the total of the readings drawn, "Busiest: 11 Jun, 12; Total 84", and the strip is described by it, as every chart is by its summary. Hide it visually. The 'summary' slot is still yours, for words of your own. **'selection-mode' lets a reader select cells**: 'single' one at a time and 'multiple' any number. Space, Enter or a press selects the cell the keys or the pointer rest on, or lets it go, and under 'multiple' Shift with an arrow, Home, End, PageUp or PageDown takes in every cell from the last one pressed to where the key went. 'value' holds the selected days, by the names their rows have in the table, separated by commas. A change asks with 'helix-before-change' and tells with 'change', and the 'selection' part says how many are selected, in 'selection-label'. */
15614
16025
  "helix-headless-heatmap": DefineCustomElement<
15615
16026
  HelixHeadlessHeatmap,
15616
16027
  HelixHeadlessHeatmapVueProps,
@@ -15622,7 +16033,7 @@ export interface WcToolkitVueGlobalComponents {
15622
16033
  HelixHeadlessIconButtonVueProps,
15623
16034
  HelixHeadlessIconButtonVueEvents
15624
16035
  >;
15625
- /** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers the whole set, so any name in it draws. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. A name with no match renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. */
16036
+ /** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers the whole set, so any name in it draws. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. A name with no match renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. **A decorative icon that is all a control holds is reported.** In a development build, a button or a link whose only content is an icon with no 'label', and which has no name of its own, warns 'missing-name' once, through the runtime channel every Helix warning uses. */
15626
16037
  "helix-headless-icon": DefineCustomElement<
15627
16038
  HelixHeadlessIcon,
15628
16039
  HelixHeadlessIconVueProps,
@@ -15634,19 +16045,19 @@ export interface WcToolkitVueGlobalComponents {
15634
16045
  HelixHeadlessImageVueProps,
15635
16046
  HelixHeadlessImageVueEvents
15636
16047
  >;
15637
- /** Renders a real '<input>', so the caret, selection, autofill, spellcheck, password managers, and a phone's on-screen keyboard all work natively. The field is in the server markup, so it works before any script loads. An input inside a shadow root does not submit with a form outside it, so the host is form-associated and reports its value through 'ElementInternals'. That also carries validity and handles a form reset. 'value' and 'defaultValue' work like 'checked' and 'defaultChecked'. 'value' is what is in the field now, and 'defaultValue' is the value from the markup, which a reset restores. Validity comes from the browser. 'type' and 'required' are set on the real input, and its 'validity' is copied to the host. 'validate' adds your own rule, run on every change once the browser finds nothing wrong, as React Aria's TextField 'validate' does. What it returns is the message the field shows once the user has edited it, and the message a submit raises. */
16048
+ /** Renders a real '<input>', so the caret, selection, autofill, spellcheck, password managers, and a phone's on-screen keyboard all work natively. The field is in the server markup, so it works before any script loads. An input inside a shadow root does not submit with a form outside it, so the host is form-associated and reports its value through 'ElementInternals'. That also carries validity and handles a form reset. 'value' and 'defaultValue' work like 'checked' and 'defaultChecked'. 'value' is what is in the field now, and 'defaultValue' is the value from the markup, which a reset restores. Validity comes from the browser. 'type' and 'required' are set on the real input, and its 'validity' is copied to the host. 'validate' adds your own rule, run on every change once the browser finds nothing wrong, as React Aria's TextField 'validate' does. What it returns is the message the field shows once the user has edited it, and the message a submit raises. **Keyboard.** The field's own keys are the platform's. Enter submits the form through its default button, as in a native field. The clear button under 'clearable' and the reveal button under 'reveal' are tab stops of their own after the field, so a keyboard reaches them. The inner input is named by 'label', or by a host 'aria-label', 'aria-labelledby' or '<label for>', and is described by the hint and the message, with 'aria-invalid' while a message shows. The clear button is named 'clear-label', and the reveal button 'reveal-label' with 'aria-pressed' while the password shows. */
15638
16049
  "helix-headless-input": DefineCustomElement<
15639
16050
  HelixHeadlessInput,
15640
16051
  HelixHeadlessInputVueProps,
15641
16052
  HelixHeadlessInputVueEvents
15642
16053
  >;
15643
- /** Renders a '<kbd>' element. Each element holds one key, except when you use 'keys'. For a sequence or a chord, write one element per key and put the separator between them as text, such as "then" or "plus". 'keys' renders the right glyphs for the platform. Given 'mod', it renders '⌘K' on Apple devices and 'Ctrl+K' everywhere else. A '⌘K' typed into a template is wrong for anyone on Windows. The element binds the shortcut only when 'within' is set. By default it draws the key and listens for nothing. **'for' names the control the shortcut works**, and the key writes its chord onto that control's 'aria-keyshortcuts', in the platform's words ('Meta+K' on an Apple keyboard, 'Control+K' elsewhere), so a screen reader announces the shortcut with the control. A chord the page wrote there itself is left alone, and the key takes back only what it added. 'caps' draws a chord as a key per key: each is a 'key' part and the '+' between two a 'separator' part, so a sheet can draw a cap for each. 'key-labels' renames any key, on every platform, such as 'key-labels='{"mod":"Command"}''. */
16054
+ /** Renders a '<kbd>' element. Each element holds one key, except when you use 'keys'. For a sequence or a chord, write one element per key and put the separator between them as text, such as "then" or "plus". 'keys' renders the right glyphs for the platform. Given 'mod', it renders '⌘K' on Apple devices and 'Ctrl+K' everywhere else. A '⌘K' typed into a template is wrong for anyone on Windows. The element binds the shortcut only when 'within' is set. By default it draws the key and listens for nothing. **'for' names the control the shortcut works**, and the key writes its chord onto that control's 'aria-keyshortcuts', in the platform's words ('Meta+K' on an Apple keyboard, 'Control+K' elsewhere), so a screen reader announces the shortcut with the control. A chord the page wrote there itself is left alone, and the key takes back only what it added. 'caps' draws a chord as a key per key: each is a 'key' part and the '+' between two a 'separator' part, so a sheet can draw a cap for each. 'key-labels' renames any key, on every platform, such as 'key-labels='{"mod":"Command"}''. On an Apple keyboard a word joins the next key with a hyphen, as in 'Command-K'. **'activate' makes the shortcut work the control 'for' names**, with no script: 'activate="focus"' moves focus to it, as '/' does to a search field, and 'activate="click"' presses it. It acts once 'helix-shortcut' has gone out and no listener canceled it, and only where 'within' listens. */
15644
16055
  "helix-headless-kbd": DefineCustomElement<
15645
16056
  HelixHeadlessKbd,
15646
16057
  HelixHeadlessKbdVueProps,
15647
16058
  HelixHeadlessKbdVueEvents
15648
16059
  >;
15649
- /** Renders a legend as a list, separate from any chart, so any chart can use one. Set 'for' to the table the chart reads, and the legend takes its entries from that table, so the two always match. 'entries' sets how the table is read: - 'series': one entry per data column, named by the header row. Use it for a line or bar chart. - 'categories': one entry per body row. Use it for a donut, whose slices are the rows and which has no axis to name them on. - 'measures': drops the first data column. Use it for a scatter. The table is resolved on the client. There is no server pass. **'toggles' makes each entry a button that hides its series.** Every chart reading the same table draws without a hidden series and fits its scale to the rest, and the series keeps its color. The button says whether its series is shown with 'aria-pressed'. The buttons are one tab stop: the arrow keys move between them, Home and End go to the first and the last, and a typed letter goes to the next name starting with it. 'hidden-series' holds the hidden names, so a page can start with some hidden or read which are. Two legends on one table show the same hidden series: the list written last wins, and the other legend takes it for its own entries. */
16060
+ /** Renders a legend as a list, separate from any chart, so any chart can use one. Set 'for' to the table the chart reads, and the legend takes its entries from that table, so the two always match. 'entries' sets how the table is read: - 'series': one entry per data column, named by the header row. Use it for a line or bar chart. - 'categories': one entry per body row. Use it for a donut, whose slices are the rows and which has no axis to name them on. - 'measures': drops the first data column. Use it for a scatter. The table is resolved on the client. There is no server pass. **'toggles' makes each entry a button that hides its series.** Every chart reading the same table draws without a hidden series and fits its scale to the rest, and the series keeps its color. The button says whether its series is shown with 'aria-pressed'. The buttons are a 'toolbar', named as the list is, and one tab stop: the arrow keys move between them, Home and End go to the first and the last, and a typed letter goes to the next name starting with it. 'hidden-series' holds the hidden names, so a page can start with some hidden or read which are. Two legends on one table show the same hidden series: the list written last wins, and the other legend takes it for its own entries. */
15650
16061
  "helix-headless-legend": DefineCustomElement<
15651
16062
  HelixHeadlessLegend,
15652
16063
  HelixHeadlessLegendVueProps,
@@ -15658,13 +16069,13 @@ export interface WcToolkitVueGlobalComponents {
15658
16069
  HelixHeadlessLightboxItemVueProps,
15659
16070
  HelixHeadlessLightboxItemVueEvents
15660
16071
  >;
15661
- /** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, a double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
16072
+ /** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, a double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. With 'controls', the viewer also draws zoom-out and zoom-in controls, for a pointer with no wheel and no second finger. Once a reader stops zooming, the live region says the new scale in the words of 'zoom-status-label', such as "Zoomed to 150%". Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
15662
16073
  "helix-headless-lightbox": DefineCustomElement<
15663
16074
  HelixHeadlessLightbox,
15664
16075
  HelixHeadlessLightboxVueProps,
15665
16076
  HelixHeadlessLightboxVueEvents
15666
16077
  >;
15667
- /** A line chart shows the shape of each series: where the readings went. The scale covers the range of the data. Including zero in the range of a series that moves between 980 and 1020 would flatten the line into a rule across the top of the box. 'BarChart' always starts at zero, because a bar's length is its value. Set 'zero' when the distance from zero is the point. Every series shares one scale, as in the bar chart. 'area' fills each series down to the floor on its own, so the fills overlap. For a total made of parts, use 'Area Chart', which stacks the series so the top edge is the total and each band is a share. The labels are HTML beside the drawing, as in 'BarChart'. Text inside an '<svg>' that fills its box scales with the box, so the same 'font-size' can render at 10px in a narrow chart and 43px in a wide one. The table is the accessible representation, and the drawing is hidden from screen readers, who get the numbers. The 'summary' part names the chart, from 'label' or the table's caption, and gives each series' latest reading. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from reading to reading, Home and End go to the first and the last, and the up and down arrows move among the series of a reading. The tooltip follows, the 'live' part says the reading in words, and Escape puts the tooltip away. */
16078
+ /** A line chart shows the shape of each series: where the readings went. The scale covers the range of the data. Including zero in the range of a series that moves between 980 and 1020 would flatten the line into a rule across the top of the box. 'BarChart' always starts at zero, because a bar's length is its value. Set 'zero' when the distance from zero is the point. Every series shares one scale, as in the bar chart. 'dashed' names the series drawn as a dashed line, such as a forecast or a target beside the readings: 'dashed="Forecast"'. Each takes a 'line-dashed' part beside 'line'. 'area' fills each series down to the floor on its own, so the fills overlap. For a total made of parts, use 'Area Chart', which stacks the series so the top edge is the total and each band is a share. The labels are HTML beside the drawing, as in 'BarChart'. Text inside an '<svg>' that fills its box scales with the box, so the same 'font-size' can render at 10px in a narrow chart and 43px in a wide one. The table is the accessible representation, and the drawing is hidden from screen readers, who get the numbers. The 'summary' part names the chart, from 'label' or the table's caption, and gives each series' latest reading. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from reading to reading, Home and End go to the first and the last, and the up and down arrows move among the series of a reading. The tooltip follows, the 'live' part says the reading in words, and Escape puts the tooltip away. */
15668
16079
  "helix-headless-line-chart": DefineCustomElement<
15669
16080
  HelixHeadlessLineChart,
15670
16081
  HelixHeadlessLineChartVueProps,
@@ -15676,13 +16087,13 @@ export interface WcToolkitVueGlobalComponents {
15676
16087
  HelixHeadlessListItemVueProps,
15677
16088
  HelixHeadlessListItemVueEvents
15678
16089
  >;
15679
- /** Sets 'role="list"' on the host, so a screen reader counts the rows and announces each one's position, such as "1 of 7". **'selection-mode' makes the list interactive**, in the way of a grid list: a grid of rows that is one tab stop. 'single' selects one row at a time and 'multiple' any number, and 'value' holds the selected rows' values, separated by commas. A change asks with 'helix-before-change' and tells with 'change'. 'none' selects nothing, so a press acts on the row. A 'disabled' row is passed over. Each row is named by its label and described by its description, so the words of the controls in 'end' are not read as part of its name. 'selection-behavior' says what a press does to the rows already selected. 'toggle', the default, adds or takes out the row. 'replace' selects the row alone, as a file list does, and the arrow keys carry the selection with them. Control or Command with a press then adds or takes out one row. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous row. Under 'replace', selects it. | | Home, End | Moves to the first or the last row. Under 'replace', selects it. | | A letter or a word | Moves to the next row whose words start with what you typed. | | Left, Right | Moves between the row and the controls in its 'end' slot. | | Space | Selects the row, or lets it go. | | Shift with Down, Up, Home, End or Space | Selects every row from the last one pressed, in 'multiple'. | | Control or Command with Down, Up, Home or End | Moves without selecting, under 'replace'. | | Control or Command with A | Selects every row, in 'multiple'. | | Enter | Acts on the row: follows its link, or sends 'helix-action' from it. | A press with Shift selects every row from the last one pressed, and a press with Control or Command adds or takes out one row under 'replace'. **Leave 'selection-mode' unset for a list a reader reads**, and set it for one a reader chooses from or acts on. The rows of an interactive list are grid rows, which hold controls as a list box option cannot. Give a control in 'end' 'tabindex="-1"' to leave it to the arrow keys and out of the tab order. 'start' and 'reversed' number an ordered list as '<ol>' does. The list writes where the numbers start and which way they run as '--list-first' and '--list-step' on its slot, which the styled tier counts from. Reversed with no 'start' counts down from the number of rows, which a server cannot know, so served markup counts from one until the list runs. */
16090
+ /** Sets 'role="list"' on the host, so a screen reader counts the rows and announces each one's position, such as "1 of 7". **'selection-mode' makes the list interactive**, in the way of a grid list: a grid of rows that is one tab stop. 'single' selects one row at a time and 'multiple' any number, and 'value' holds the selected rows' values, separated by commas. A change asks with 'helix-before-change' and tells with 'change'. 'none' selects nothing, so a press acts on the row. A 'disabled' row is passed over. Each row is named by its label and described by its description, so the words of the controls in 'end' are not read as part of its name. 'selection-behavior' says what a press does to the rows already selected. 'toggle', the default, adds or takes out the row. 'replace' selects the row alone, as a file list does, and the arrow keys carry the selection with them. Control or Command with a press then adds or takes out one row. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous row. Under 'replace', selects it. | | Home, End | Moves to the first or the last row. Under 'replace', selects it. | | Page Down, Page Up | Moves a box's height of rows, so the row at one edge lands at the other. Under 'replace', selects the row it lands on. | | A letter or a word | Moves to the next row whose words start with what you typed. | | Left, Right | Moves between the row and the controls in its 'end' slot. | | Space | Selects the row, or lets it go. | | Shift with Down, Up, Home, End, Page Down, Page Up or Space | Selects every row from the last one pressed, in 'multiple'. | | Control or Command with Down, Up, Home, End, Page Down or Page Up | Moves without selecting, under 'replace'. | | Control or Command with A | Selects every row, in 'multiple'. | | Escape | Lets go of every selected row, asking first, and keeps the key from the dialog or menu around the list. With nothing selected, the key goes on to them. | | Enter | Acts on the row: follows its link, or sends 'helix-action' from it. | A press with Shift selects every row from the last one pressed, and a press with Control or Command adds or takes out one row under 'replace'. **Leave 'selection-mode' unset for a list a reader reads**, and set it for one a reader chooses from or acts on. The rows of an interactive list are grid rows, which hold controls as a list box option cannot. Give a control in 'end' 'tabindex="-1"' to leave it to the arrow keys and out of the tab order. 'start' and 'reversed' number an ordered list as '<ol>' does. The list writes where the numbers start and which way they run as '--list-first' and '--list-step' on its slot, which the styled tier counts from. Reversed with no 'start' counts down from the number of rows, which a server cannot know, so served markup counts from one until the list runs. */
15680
16091
  "helix-headless-list": DefineCustomElement<
15681
16092
  HelixHeadlessList,
15682
16093
  HelixHeadlessListVueProps,
15683
16094
  HelixHeadlessListVueEvents
15684
16095
  >;
15685
- /** The listbox is the control, and options are its items. A Select is a listbox with a trigger in front of it, a Combobox is a listbox with a text input, and a command palette is a listbox in a dialog. They differ only in what opens the list and what filters it. With 'multiple' set, 'value' is a comma-separated string, like 'Checkbox.Group''s, because 'MixinControllerValue' holds a string. The form receives one entry per selected option, as a native '<select multiple>' sends it, so your server does not split on commas. Selected and active are separate. The selected option is the value. The active option is where the keyboard is: the arrow keys move it, and 'aria-activedescendant' points to it while focus stays on the list. The arrow keys, Home, End, PageUp and PageDown move the highlight, and typed letters move it to the next option whose words start with them. In a single-choice list the highlight is the choice unless 'manual' is set; then Enter, Space or a click chooses. With 'multiple', Space toggles the highlighted option, Shift with an arrow adds the option it moves to, Shift with Home or End adds every option from the highlight to that end, and Control+A or Command+A chooses every option, or none where all are chosen. In a filter field, Space, Home, End and letters edit the text. An option with 'href' is a link: Enter or a press follows it and selects nothing, and moving onto it with the arrows does not follow it. As a filter narrows the list, a screen reader hears how many options are left, such as "3 results", from 'result-label' and 'results-label'. A filter that leaves none says 'empty-text'. */
16096
+ /** The listbox is the control, and options are its items. A Select is a listbox with a trigger in front of it, a Combobox is a listbox with a text input, and a command palette is a listbox in a dialog. They differ only in what opens the list and what filters it. With 'multiple' set, 'value' is a comma-separated string, like 'Checkbox.Group''s, because 'MixinControllerValue' holds a string. The form receives one entry per selected option, as a native '<select multiple>' sends it, so your server does not split on commas. Selected and active are separate. The selected option is the value. The active option is where the keyboard is: the arrow keys move it, and 'aria-activedescendant' points to it while focus stays on the list. The arrow keys, Home, End, PageUp and PageDown move the highlight, and typed letters move it to the next option whose words start with them. In a single-choice list the highlight is the choice unless 'manual' is set; then Enter, Space or a click chooses. With 'multiple', Space toggles the highlighted option, Shift with an arrow adds the option it moves to, Shift with Home or End adds every option from the highlight to that end, and Control+A or Command+A chooses every option, or none where all are chosen. In a filter field, Space, Home, End and letters edit the text, and with 'multiple', Control with Shift and Home or End adds every option from the highlight to that end. An option with 'href' is a link: Enter or a press follows it and selects nothing, and moving onto it with the arrows does not follow it. As a filter narrows the list, a screen reader hears how many options are left, such as "3 results", from 'result-label' and 'results-label'. A filter that leaves none says 'empty-text'. */
15686
16097
  "helix-headless-listbox": DefineCustomElement<
15687
16098
  HelixHeadlessListbox,
15688
16099
  HelixHeadlessListboxVueProps,
@@ -15760,7 +16171,7 @@ export interface WcToolkitVueGlobalComponents {
15760
16171
  HelixHeadlessMapTerrainVueProps,
15761
16172
  HelixHeadlessMapTerrainVueEvents
15762
16173
  >;
15763
- /** A disclosure: a button that shows and hides a region of your own links. It does not use 'role="menu"' or 'menuitem', which are for application commands. Those roles take over the arrow keys, announce "menu" to someone looking for navigation, and put every link inside a role that is not a link. As a disclosure, middle clicks, modified clicks, and the status bar keep working. Use 'Menu' for a row of commands. It renders no links. A router renders its own anchors and cannot render them inside this shadow root, so the panel is a slot for the lists and headings you write. It opens on hover by default, and a press always opens it too. 'open-on' sets which. Hover is the default because in a navigation bar people expect to move along the row and see each section. When one panel opens in place of another, each says which way the reader moved, as Radix's 'data-motion' does. Moving toward the end of the bar, the one opening is ':state(from-end)' and the one closing is ':state(to-start)'; moving back, they are ':state(from-start)' and ':state(to-end)'. A stylesheet slides them on that. Start and end follow the reading direction, so on a right-to-left page the end is on the left. A panel that opens or closes on its own carries none of the four. A press on another megamenu's trigger hands over the same way as hovering it. While a panel is open its surface carries its own size, as '--megamenu-surface-inline-size' and '--megamenu-surface-block-size', and a panel that took over from another also carries that one's size, as '--megamenu-from-inline-size' and '--megamenu-from-block-size'. Radix's navigation menu publishes the same pair from its shared viewport, so a stylesheet can grow or shrink one panel into the next. Put megamenus in a 'Navigation' with 'arrows' and the arrow keys move between their triggers. Down Arrow on the trigger of an open panel moves focus to the panel's first link, Escape closes the panel and returns focus to its trigger, and Tab moves through the panel's links and closes it on the way out. The trigger says 'aria-expanded', and the panel is a group named by 'label'. */
16174
+ /** A disclosure: a button that shows and hides a region of your own links. It does not use 'role="menu"' or 'menuitem', which are for application commands. Those roles take over the arrow keys, announce "menu" to someone looking for navigation, and put every link inside a role that is not a link. As a disclosure, middle clicks, modified clicks, and the status bar keep working. Use 'Menu' for a row of commands. It renders no links. A router renders its own anchors and cannot render them inside this shadow root, so the panel is a slot for the lists and headings you write. It opens on hover by default, and a press always opens it too. 'open-on' sets which. Hover is the default because in a navigation bar people expect to move along the row and see each section. When one panel opens in place of another, each says which way the reader moved, as Radix's 'data-motion' does. Moving toward the end of the bar, the one opening is ':state(from-end)' and the one closing is ':state(to-start)'; moving back, they are ':state(from-start)' and ':state(to-end)'. A stylesheet slides them on that. Start and end follow the reading direction, so on a right-to-left page the end is on the left. A panel that opens or closes on its own carries none of the four. A press on another megamenu's trigger hands over the same way as hovering it. While a panel is open its surface carries its own size, as '--megamenu-surface-inline-size' and '--megamenu-surface-block-size', and a panel that took over from another also carries that one's size, as '--megamenu-from-inline-size' and '--megamenu-from-block-size'. Radix's navigation menu publishes the same pair from its shared viewport, so a stylesheet can grow or shrink one panel into the next. The panel's default slot is the 'columns' part and draws no box, so a sheet can give the columns one of their own. While a panel is open, an 'indicator' slot is rendered beside its trigger, as Radix's indicator marks the open one: slot a mark of your own, such as a bar or an arrow pointing at the panel, and it shows only while the panel is open. The styled tier rests it on the trigger's bottom edge. Left and Right Arrow move between the triggers of the megamenus beside this one, and Home and End go to the first and the last, as Radix's navigation menu does. In a 'Navigation', which holds them in a slot, the arrows are the navigation's, and move between its destinations under its 'arrows'. Down Arrow on the trigger of an open panel moves focus to the panel's first link, Escape closes the panel and returns focus to its trigger, and Tab moves through the panel's links and closes it on the way out. The trigger says 'aria-expanded', and the panel is a group named by 'label'. */
15764
16175
  "helix-headless-megamenu": DefineCustomElement<
15765
16176
  HelixHeadlessMegamenu,
15766
16177
  HelixHeadlessMegamenuVueProps,
@@ -15784,7 +16195,7 @@ export interface WcToolkitVueGlobalComponents {
15784
16195
  HelixHeadlessMenuSectionVueProps,
15785
16196
  HelixHeadlessMenuSectionVueEvents
15786
16197
  >;
15787
- /** A meter shows a level within a range. Use 'Progress' to show how far along a task is. A progress bar starts empty and ends full, and full is always the good end. For a meter, which end is good depends on what is measured. There is no 'indeterminate', because a meter always has a value. **Set 'low', 'high', and 'optimum'**, as defined in the HTML specification. 'low' and 'high' divide the range into a low band, a middle band, and a high band. 'optimum' sets the preferred band. The band next to it is fair, and the band two away is poor. */
16198
+ /** A meter shows a level within a range. Use 'Progress' to show how far along a task is. A progress bar starts empty and ends full, and full is always the good end. For a meter, which end is good depends on what is measured. There is no 'indeterminate', because a meter always has a value. **Set 'low', 'high', and 'optimum'**, as defined in the HTML specification. 'low' and 'high' divide the range into a low band, a middle band, and a high band. 'optimum' sets the preferred band. The band next to it is fair, and the band two away is poor. The band is a custom state on the meter, 'good', 'fair' or 'poor', beside 'over' and 'under' for a value past an end, so a page styles the meter around the fill as well as the fill. **'live' says the reading when it moves into another band**, such as "92%, Poor", in a polite region, for a meter whose value changes while a reader is on the page: a disk filling or a battery draining. The band's word comes from 'band-labels'. */
15788
16199
  "helix-headless-meter": DefineCustomElement<
15789
16200
  HelixHeadlessMeter,
15790
16201
  HelixHeadlessMeterVueProps,
@@ -15820,7 +16231,7 @@ export interface WcToolkitVueGlobalComponents {
15820
16231
  HelixHeadlessNumberInputVueProps,
15821
16232
  HelixHeadlessNumberInputVueEvents
15822
16233
  >;
15823
- /** Object Inspector shows a structured value, such as an API response, a config, or a raw record, as a read-only tree with each entry's type visible. Pass the object to 'value', or name a '<script type="application/json">' by id with 'for', the same source 'VirtualList' and the charts read. JSON text works with server rendering and with React hydration, which skips object properties. 'value' wins when both are set. **Keyboard.** The tree is one tab stop, and focus moves from row to row. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous row. | | Right | Opens a closed branch, or moves into an open one. Left on a right-to-left page. | | Left | Closes an open branch, or moves to the parent. Right on a right-to-left page. | | Home, End | Moves to the first or the last row. | | Enter, Space | Opens or closes a branch. | | '*' | Opens every branch beside the active row. | | A letter or a word | Moves to the next row whose key starts with what you typed. | | Command+C, Control+C | Copies the active row, where no text is selected. | The tree is a 'treegrid', as React Aria's Tree is: each entry is a 'row' with one cell, and carries its real level, position, and set size, including in a windowed tree. Nothing in it is chosen, so no row carries 'aria-selected', and a focused row is not announced as selected. A reader opening or closing a branch sends 'helix-before-open' or 'helix-before-close', which you can cancel, and then 'toggle' with 'newState' and 'oldState', as '<details>' does. The branch is the active row, and 'expanded' holds every open branch. '*' asks once for all the branches it opens. A script writing 'expanded' or 'active' sends nothing. 'active' is the active row's path, written the way a JSON Pointer writes it: the empty string for the root and '/meta/tags/0' for an entry under it. Moving to another row sends 'helix-before-activate', which you can cancel, and then 'helix-activate', both with the path. Writing 'active' moves there and opens the branches around it, and sends nothing. 'expanded' holds the open branches by path, and writing it opens those and closes the rest. A row that closes around the active one hands it to the nearest open branch. 'filter' narrows the tree to the entries whose key or value holds the text, ignoring case, and the branches that lead to them, which it opens. A matched branch keeps everything under it. Each matched row carries 'row-match', and a screen reader hears how many entries matched from 'result-label' and 'results-label'. 'filterable' adds a field that sets it: typing sends 'helix-filter', which you can cancel, and then 'helix-filtered', and Down moves from the field to the tree. A new 'value' keeps the branches a reader opened or closed, and the active row, where the new value still has them. A branch the old value did not have opens to 'default-depth'. The copy button copies the active row, a branch as JSON and a string as its text. So do Command+C and Control+C while the tree has focus and no text is selected. The button sits beside the tree, because assistive technology cannot reliably reach a button inside a tree item. 'windowed' draws only the rows in view, for values with thousands of entries. The box needs a height for windowing to work. The styled tier sets one, and in the headless tier you set it yourself. */
16234
+ /** Object Inspector shows a structured value, such as an API response, a config, or a raw record, as a read-only tree with each entry's type visible. Pass the object to 'value', or name a '<script type="application/json">' by id with 'for', the same source 'VirtualList' and the charts read. JSON text works with server rendering and with React hydration, which skips object properties. 'value' wins when both are set. **Keyboard.** The tree is one tab stop, and focus moves from row to row. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous row. | | Right | Opens a closed branch, or moves into an open one. Left on a right-to-left page. | | Left | Closes an open branch, or moves to the parent. Right on a right-to-left page. | | Home, End | Moves to the first or the last row. | | Page Down, Page Up | Moves a box's height of rows, so the row at one edge lands at the other. | | Enter, Space | Opens or closes a branch. | | '*' | Opens every branch beside the active row. | | A letter or a word | Moves to the next row whose key starts with what you typed. | | Command+C, Control+C | Copies the active row, where no text is selected. | The tree is a 'treegrid', as React Aria's Tree is: each entry is a 'row' with one cell, and carries its real level, position, and set size, including in a windowed tree. Nothing in it is chosen, so no row carries 'aria-selected', and a focused row is not announced as selected. A reader opening or closing a branch sends 'helix-before-open' or 'helix-before-close', which you can cancel, and then 'toggle' with 'newState' and 'oldState', as '<details>' does. The branch is the active row, and 'expanded' holds every open branch. '*' asks once for all the branches it opens. A script writing 'expanded' or 'active' sends nothing. 'active' is the active row's path, written the way a JSON Pointer writes it: the empty string for the root and '/meta/tags/0' for an entry under it. Moving to another row sends 'helix-before-activate', which you can cancel, and then 'helix-activate', both with the path. Writing 'active' moves there and opens the branches around it, and sends nothing. 'expanded' holds the open branches by path, and writing it opens those and closes the rest. A row that closes around the active one hands it to the nearest open branch. 'filter' narrows the tree to the entries whose key or value holds the text, ignoring case, and the branches that lead to them, which it opens. A matched branch keeps everything under it. Each matched row carries 'row-match', and a screen reader hears how many entries matched from 'result-label' and 'results-label'. 'filterable' adds a field that sets it: typing sends 'helix-filter', which you can cancel, and then 'helix-filtered', and Down moves from the field to the tree. A new 'value' keeps the branches a reader opened or closed, and the active row, where the new value still has them. A branch the old value did not have opens to 'default-depth'. The copy button copies the active row, a branch as JSON and a string as its text. So do Command+C and Control+C while the tree has focus and no text is selected. The button sits beside the tree, because assistive technology cannot reliably reach a button inside a tree item. 'windowed' draws only the rows in view, for values with thousands of entries. The box needs a height for windowing to work. The styled tier sets one, and in the headless tier you set it yourself. */
15824
16235
  "helix-headless-object-inspector": DefineCustomElement<
15825
16236
  HelixHeadlessObjectInspector,
15826
16237
  HelixHeadlessObjectInspectorVueProps,
@@ -15838,7 +16249,13 @@ export interface WcToolkitVueGlobalComponents {
15838
16249
  HelixHeadlessOptionVueProps,
15839
16250
  HelixHeadlessOptionVueEvents
15840
16251
  >;
15841
- /** Outline is a table of contents for a document. 'Navigation' does the same job for a site. The links are your own anchors. A router renders its own '<a>' and cannot render one inside the outline's shadow root, and the hrefs are fragments on the same page. Write the anchors flat, with 'data-level' for their depth, or nested in lists, '<ul><li><a>'. A screen reader hears the levels either way: the outline puts a flat run into lists inside list items of its own, nested by 'data-level', and leaves the links where they are. A link without 'data-level' is at the top level. A heading slotted into 'heading' names the navigation, in place of 'label'. In a contents rail with a scrollbar of its own, 'follow' keeps the link of the section in view showing as the reader scrolls the page. The current section is decided by the headings' positions. An 'IntersectionObserver' with a band near the top fails both ways: when headings are far apart, none is in the band and no section is marked, and when they are close together, several are in the band at once. */
16252
+ /** Sets one run of options apart from the next where a heading would say too much, as React Aria's ListBox takes a 'Separator': actions apart from choices in a command palette, say, or the options a reader uses most apart from the rest. It has 'role="separator"', so a screen reader can say where one run ends, and it is no stop: the arrow keys move from the option before it to the one after. The list hides it while a filter is narrowing the options, since a rule between two runs of which only some options are left separates nothing. */
16253
+ "helix-headless-option-separator": DefineCustomElement<
16254
+ HelixHeadlessOptionSeparator,
16255
+ HelixHeadlessOptionSeparatorVueProps,
16256
+ HelixHeadlessOptionSeparatorVueEvents
16257
+ >;
16258
+ /** Outline is a table of contents for a document. 'Navigation' does the same job for a site. The links are your own anchors. A router renders its own '<a>' and cannot render one inside the outline's shadow root, and the hrefs are fragments on the same page. Write the anchors flat, with 'data-level' for their depth, or nested in lists, '<ul><li><a>'. A screen reader hears the levels either way: the outline puts a flat run into lists inside list items of its own, nested by 'data-level', and leaves the links where they are. A link without 'data-level' is at the top level. A heading slotted into 'heading' names the navigation, in place of 'label'. In a contents rail with a scrollbar of its own, 'follow' keeps the link of the section in view showing as the reader scrolls the page. **Keyboard.** The links are your anchors, in the tab order as you wrote them, so the outline adds no keys of its own: Tab moves through the links and Enter follows one. Following a link moves focus to its section, so the next Tab goes on from the heading, also with 'behavior' set. **What a screen reader hears.** A navigation landmark named by 'label', "On this page", or by the slotted heading. The links are lists, nested by level, so a reader hears how many links a level holds and where each one is. The link to the section in view carries 'aria-current="location"', read as "current location", and it moves as the page scrolls without announcing, which would interrupt the reading it follows. The current section is decided by the headings' positions. An 'IntersectionObserver' with a band near the top fails both ways: when headings are far apart, none is in the band and no section is marked, and when they are close together, several are in the band at once. */
15842
16259
  "helix-headless-outline": DefineCustomElement<
15843
16260
  HelixHeadlessOutline,
15844
16261
  HelixHeadlessOutlineVueProps,
@@ -15850,7 +16267,7 @@ export interface WcToolkitVueGlobalComponents {
15850
16267
  HelixHeadlessPaginationVueProps,
15851
16268
  HelixHeadlessPaginationVueEvents
15852
16269
  >;
15853
- /** A separate element that you place beside 'Pagination', like 'Pagination.Summary', so you choose the direction and order of your footer. It uses 'Select', so it matches a table's filter dropdowns in the same footer, both open and closed. The caret is 'Select''s, so it follows 'currentColor', and the label is a real '<label for>' pointing at the trigger's id. The label sits on the same row as the select. 'Select''s host is a column, and an outer-tree rule overrides a ':host' rule, so the row layout needs no property on 'Select' and nothing added to your markup. An empty 'sizes' renders nothing and does not fall back to the built-in list. 'Pagination' does the same with a single page, and both report it through 'ElementInternals.states'. 'value' is the current size, and 'default-value' is the size from the markup. Changing it dispatches 'helix-before-change', and then 'input' and 'change' once the size has moved, as a native '<select>' sends them together. Re-querying and returning to page one is up to you, because only you know whether the current position should be kept. It takes part in a form. Give it a 'name' and the size in force is submitted under that name, so a 'GET' form carries it in the address beside the page. A form reset returns it to 'default-value', and 'disabled', or a disabled '<fieldset>' around it, turns the select off. */
16270
+ /** A separate element that you place beside 'Pagination', like 'Pagination.Summary', so you choose the direction and order of your footer. It uses 'Select', so it matches a table's filter dropdowns in the same footer, both open and closed. The caret is 'Select''s, so it follows 'currentColor', and the label is a real '<label for>' pointing at the trigger's id. A '<label for>' pointing at this element, or its own 'aria-label' or 'aria-labelledby', names the select in place of 'label', so a reader hears the page's words for it, and the select draws no label of its own beside the page's. The label sits on the same row as the select. 'Select''s host is a column, and an outer-tree rule overrides a ':host' rule, so the row layout needs no property on 'Select' and nothing added to your markup. An empty 'sizes' renders nothing and does not fall back to the built-in list. 'Pagination' does the same with a single page, and both report it through 'ElementInternals.states'. 'value' is the current size, and 'default-value' is the size from the markup. Changing it dispatches 'helix-before-change', and then 'input' and 'change' once the size has moved, as a native '<select>' sends them together. Re-querying and returning to page one is up to you, because only you know whether the current position should be kept. It takes part in a form. Give it a 'name' and the size in force is submitted under that name, so a 'GET' form carries it in the address beside the page. A form reset returns it to 'default-value', and 'disabled', or a disabled '<fieldset>' around it, turns the select off. */
15854
16271
  "helix-headless-pagination-size": DefineCustomElement<
15855
16272
  HelixHeadlessPaginationSize,
15856
16273
  HelixHeadlessPaginationSizeVueProps,
@@ -15862,7 +16279,7 @@ export interface WcToolkitVueGlobalComponents {
15862
16279
  HelixHeadlessPaginationSummaryVueProps,
15863
16280
  HelixHeadlessPaginationSummaryVueEvents
15864
16281
  >;
15865
- /** Each cell is its own '<input>', so every box has a real focus ring, caret, and tab stop. Input longer than one character is treated as a paste, in any cell. This covers pasting, a browser autofilling an SMS code, and a password manager, which all put the whole code into the focused box. A six-character code that arrives in cell three fills from cell three. The code is one value to a form. The cells are in a shadow root and submit nothing. The host is form-associated and submits the joined string, which also carries validity and responds to a form reset. Only the first cell has 'autocomplete="one-time-code"', because the hint applies to the whole field. 'autosubmit' submits the form once the last box is filled, through the form's default button where there is one. 'format' draws separators between the boxes, such as the dash in '###-###', as text a screen reader skips. Delete removes the character in the focused box and pulls the rest of the code back, as Backspace removes the one before it. The row of cells always runs left to right, with 'dir="ltr"', including in Arabic and Hebrew. The first box is the leftmost, a paste fills to the right, and the right arrow moves to the next box. The label, hint, and feedback follow the page's direction. **Keyboard.** Each box is a tab stop of its own, as each is a real input. | Key | What it does | |---|---| | A character | Fills the box and moves to the next one. A longer run is read as a paste. | | Left, Right | Moves to the box before or after. | | Home, End | Moves to the first box, or to the box after the last character. | | Backspace | In an empty box, clears the box before it and moves there. | | Delete | Removes the character in the box and pulls the rest of the code back. | | Enter | Submits the form. | The row has 'role="group"' and the field's name, and each box is named by 'cell-label', such as "Character 2 of 6". 'helix-complete' is a 'HelixCompleteEvent' sent once the last box is filled. */
16282
+ /** One real '<input>' holds the code, and the boxes are drawn from it, as Web Awesome's OTP input does. A screen reader meets one field, named by the label, and the code never sits in a row of separate fields. The boxes are hidden from it. The caret is drawn in the box it is in, and the box is marked with 'cell-active' while the field has focus. A filled box selects its character, so typing replaces it and moves on. Input longer than one character is treated as a paste. This covers pasting, a browser autofilling an SMS code, and a password manager. A six-character code pasted into an empty field fills from the first box. The code is one value to a form. The field is in a shadow root and submits nothing. The host is form-associated and submits the code, which also carries validity and responds to a form reset. The field carries 'autocomplete="one-time-code"', which lets a phone offer the code from a message. 'autosubmit' submits the form once the last box is filled, through the form's default button where there is one. 'format' draws separators between the boxes, such as the dash in '###-###', as text a screen reader skips. 'mask' makes the field a password field and draws 'mask-character' in each filled box, so the code is never drawn as text. The row of boxes always runs left to right, with 'dir="ltr"', including in Arabic and Hebrew. The first box is the leftmost, a paste fills to the right, and the right arrow moves to the next box. The label, hint, and feedback follow the page's direction. **Keyboard.** The field is one tab stop. | Key | What it does | |---|---| | A character | Fills the box and moves to the next one. A longer run is read as a paste. | | Left, Right | Moves to the box before or after. | | Home, End | Moves to the first box, or to the box after the last character. | | Backspace | Removes the character in the box, or in an empty box the one before it, and moves there. | | Delete | Removes the character in the box and pulls the rest of the code back. | | Enter | Submits the form. | The field is a text field, or a password field under 'mask', named by the label and described by the hint and the message, with 'aria-invalid' while a message shows and 'aria-required' under 'required'. 'helix-complete' is a 'HelixCompleteEvent' sent once the last box is filled. */
15866
16283
  "helix-headless-pin-input": DefineCustomElement<
15867
16284
  HelixHeadlessPinInput,
15868
16285
  HelixHeadlessPinInputVueProps,
@@ -15874,13 +16291,13 @@ export interface WcToolkitVueGlobalComponents {
15874
16291
  HelixHeadlessPopoverVueProps,
15875
16292
  HelixHeadlessPopoverVueEvents
15876
16293
  >;
15877
- /** Determinate by default. Set 'indeterminate' for a task whose total is not known yet. Use 'Loader' for a short wait or one with no place of its own on the page. The indeterminate bar runs a segment across the track and does not fill, so it shows that work is happening without claiming a proportion. 'aria-valuenow' is omitted in that state, which is the platform's signal for the same thing. The fill is a fraction of the track, written as a custom property. */
16294
+ /** Determinate by default. Set 'indeterminate' for a task whose total is not known yet. Use 'Loader' for a short wait or one with no place of its own on the page. The indeterminate bar runs a segment across the track and does not fill, so it shows that work is happening without claiming a proportion. 'aria-valuenow' is omitted in that state, which is the platform's signal for the same thing. The fill is a fraction of the track, written as a custom property. **Reaching 'max' is said and sent.** When the value arrives at 'max' from below, the bar says 'complete-label', "Complete" by default, in a polite 'live' region and sends 'helix-complete', so a reader hears that the work is done and a page can move on. A bar that starts full says nothing, and an empty 'complete-label' keeps it quiet. The 'complete' custom state is set while the bar is full. */
15878
16295
  "helix-headless-progress": DefineCustomElement<
15879
16296
  HelixHeadlessProgress,
15880
16297
  HelixHeadlessProgressVueProps,
15881
16298
  HelixHeadlessProgressVueEvents
15882
16299
  >;
15883
- /** The code is drawn as one '<path>'. Runs of adjacent dark modules are joined, so a row of eight is one horizontal move. A code of useful length has about a thousand modules, and an element for each would be a thousand nodes for one image. The element has 'role="img"' and an accessible name. Set the name to what the code is for. When you pass no name, the value is the name. Most codes hold a URL, and a URL read aloud gives the destination. The quiet zone of four modules is required by the specification, and a scanner rejects a code cropped to its edge. It is drawn inside the 'viewBox', so it stays at any size, including a size set in CSS. 'correction' sets how much of the code can be lost. At 'H' a code can lose thirty percent and still scan, so a mark in the center slot is safe. At 'L' the same mark makes the code unscannable. The default is 'M', and 'H' when the 'logo' slot is filled. A higher level holds fewer characters, so a value that fits at 'M' can be too long once a logo raises the level to 'H'. A value too long for the level draws no code: the element fires 'error', carries ':state(overflow)', and shows what is in the 'fallback' slot, such as the link written out. 'toSvg()', 'toPng()' and 'download()' give the drawn code as a file of its own, in the colors it is drawn in, with a slotted image or SVG logo where it sits, for a page that offers it to save or print, as Zag's download trigger does. */
16300
+ /** The code is drawn as one '<path>'. Runs of adjacent dark modules are joined, so a row of eight is one horizontal move. A code of useful length has about a thousand modules, and an element for each would be a thousand nodes for one image. The element has 'role="img"' and an accessible name. Set 'label' to what the code is for, such as "Open the menu". With no 'label', a code is named by 'code-label', "QR code", followed by its value where the value is a web address, which a URL read aloud makes a destination. Any other value is never read out: a code that sets up an authenticator or joins a network carries a secret in it. The quiet zone of four modules is required by the specification, and a scanner rejects a code cropped to its edge. It is drawn inside the 'viewBox', so it stays at any size, including a size set in CSS. 'correction' sets how much of the code can be lost. At 'H' a code can lose thirty percent and still scan, so a mark in the center slot is safe. At 'L' the same mark makes the code unscannable. The default is 'M', and 'H' when the 'logo' slot is filled. A higher level holds fewer characters, so a value that fits at 'M' can be too long once a logo raises the level to 'H'. A value too long for the level draws no code: the element fires 'error', carries ':state(overflow)', and shows what is in the 'fallback' slot, such as the link written out. 'toSvg()', 'toPng()' and 'download()' give the drawn code as a file of its own, in the colors it is drawn in, with a slotted image or SVG logo where it sits, for a page that offers it to save or print, as Zag's download trigger does. */
15884
16301
  "helix-headless-qr-code": DefineCustomElement<
15885
16302
  HelixHeadlessQrCode,
15886
16303
  HelixHeadlessQrCodeVueProps,
@@ -15892,7 +16309,7 @@ export interface WcToolkitVueGlobalComponents {
15892
16309
  HelixHeadlessQuoteVueProps,
15893
16310
  HelixHeadlessQuoteVueEvents
15894
16311
  >;
15895
- /** The group is the form control, and the radios are its options. A set of radios submits one answer, so the group owns the 'name', the 'value', and the validity. A radio outside a group is not a control. Checkboxes work the other way: each checkbox submits its own answer. 'MixinField' applies to the group for the same reason. The label, the hint, and the message describe the question, and the question belongs to the set. Selection moves up and state moves down. A radio dispatches an event when it is chosen, the group determines whether the choice stands, and the group writes 'selected' onto every radio. The group is the one source of which radio is on. 'value' is the current answer. 'defaultValue' is what the markup declared: the value until something is chosen, and where a reset returns. The two work like 'checked' and 'defaultChecked'. A choice sends its events in this order: 'helix-select' from the radio, then, a microtask later and only if nobody refused it, 'helix-before-change' from the group, and once the value has moved, 'input' and 'change'. The microtask is what lets a listener you add to the group after it connected refuse the 'helix-select'. A native radio sends 'input' and 'change' in the same task as the click. */
16312
+ /** The group is the form control, and the radios are its options. A set of radios submits one answer, so the group owns the 'name', the 'value', and the validity. A radio outside a group is not a control. Checkboxes work the other way: each checkbox submits its own answer. 'MixinField' applies to the group for the same reason. The label, the hint, and the message describe the question, and the question belongs to the set. Selection moves up and state moves down. A radio dispatches an event when it is chosen, the group determines whether the choice stands, and the group writes 'selected' onto every radio. The group is the one source of which radio is on. 'value' is the current answer. 'defaultValue' is what the markup declared: the value until something is chosen, and where a reset returns. The two work like 'checked' and 'defaultChecked'. A choice sends its events in this order: 'helix-select' from the radio, then, a microtask later and only if nobody refused it, 'helix-before-change' from the group, and once the value has moved, 'input' and 'change'. The microtask is what lets a listener you add to the group after it connected refuse the 'helix-select'. A native radio sends 'input' and 'change' in the same task as the click. **Keyboard.** The group is one tab stop: the chosen radio, or the first that can be chosen. | Key | What it does | |---|---| | Right, Down | Chooses the next radio, from the last back to the first. | | Left, Up | Chooses the radio before, from the first round to the last. | | Home, End | Chooses the first or the last radio. | | Space, Enter | Chooses the focused radio. | Left and Right swap on a right-to-left page, and a disabled radio is passed over. Under 'readonly' the arrows move focus and choose nothing. The group is a 'radiogroup' named by 'label', and each radio is a 'role="radio"' button with 'aria-checked'. */
15896
16313
  "helix-headless-radio-group": DefineCustomElement<
15897
16314
  HelixHeadlessRadioGroup,
15898
16315
  HelixHeadlessRadioGroupVueProps,
@@ -15904,13 +16321,13 @@ export interface WcToolkitVueGlobalComponents {
15904
16321
  HelixHeadlessRadioVueProps,
15905
16322
  HelixHeadlessRadioVueEvents
15906
16323
  >;
15907
- /** Supports half marks, so the value is not always an integer and the press targets are not the marks: five stars at a half step give ten places to press. The pointer handling and 'step' are built around half marks. A partial mark is the full mark, clipped. The filled marks are drawn over the empty marks and cut off partway, so any mark and any fraction work. A read-only rating displays a score, which is the most common use. It is announced as a displayed value and does not look disabled. With 'clearable', pressing the chosen score again, or Backspace or Delete on the marks, takes the rating back to unrated and sends 'helix-clear'. */
16324
+ /** Supports half marks, so the value is not always an integer and the press targets are not the marks: five stars at a half step give ten places to press. The pointer handling and 'step' are built around half marks. A partial mark is the full mark, clipped. The filled marks are drawn over the empty marks and cut off partway, so any mark and any fraction work. A read-only rating displays a score, which is the most common use. It is announced as a displayed value and does not look disabled. With 'clearable', pressing the chosen score again, or Backspace or Delete on the marks, takes the rating back to unrated and sends 'helix-clear'. **Keyboard.** The marks are one tab stop, on the chosen score or the first. | Key | What it does | |---|---| | Right, Down | Chooses the next score up, and stops at the highest. | | Left, Up | Chooses the next score down, and stops at the lowest. | | Home, End | Chooses the lowest or the highest score. | | Space, Enter | Chooses the focused score, or clears it under 'clearable' when it is already chosen. | | Backspace, Delete | Clears the rating, under 'clearable'. | Left and Right swap on a right-to-left page. The marks are a 'radiogroup' named by 'label', and each score is a 'radio' named by 'option-label', such as "3 out of 5". A read-only rating is one 'img' named by its score. */
15908
16325
  "helix-headless-rating": DefineCustomElement<
15909
16326
  HelixHeadlessRating,
15910
16327
  HelixHeadlessRatingVueProps,
15911
16328
  HelixHeadlessRatingVueEvents
15912
16329
  >;
15913
- /** A scatter chart shows how two measures relate. The table's first numeric column is measured across, every other numeric column is measured up, and each row is one point. A table of countries with an income column and a life expectancy column draws one point for each country. Each additional numeric column is another series, in its own color. Both axes are labeled, because both positions are values. The ticks sit at round numbers, and the range extends to them. 'trend' draws each series' line of best fit, by least squares, across the plot in the series' color. The summary gives each series' correlation coefficient and its number of points. The table has every number, and the drawing is hidden from screen readers. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from row to row in the table's order, Home and End go to the first and the last, and the up and down arrows move among the series of a row. The tooltip sits on that point, the 'live' part says the row in words, and Escape puts the tooltip away. Each point is a '<span>' placed by percentage over the drawing, as 'LineChart' places its end points, so points stay round when the drawing stretches. The plot runs left to right in every text direction, as a number line does. The plot, its axes, and the axis names sit in a 'plane' part with 'dir="ltr"'. The axis names carry 'dir="auto"', so a name in Arabic or Hebrew reads in its own direction. The summary and the tooltip bubble follow the page's direction. */
16330
+ /** A scatter chart shows how two measures relate. The table's first numeric column is measured across, every other numeric column is measured up, and each row is one point. A table of countries with an income column and a life expectancy column draws one point for each country. Each additional numeric column is another series, in its own color. Both axes are labeled, because both positions are values. The ticks sit at round numbers, and the range extends to them. 'trend' draws each series' line of best fit, by least squares, across the plot in the series' color. **'size-by' names a third measure, drawn as each point's size**, as a bubble chart does: 'size-by="Population"' takes that column out of the series and gives each point an area in proportion to its row's number there. The tooltip and the table still say the number. The summary gives each series' correlation coefficient and its number of points. The table has every number, and the drawing is hidden from screen readers. **The plot is read by key.** It takes focus, named by 'label' or the caption. The left and right arrows move from row to row in the table's order, Home and End go to the first and the last, and the up and down arrows move among the series of a row. The tooltip sits on that point, the 'live' part says the row in words, and Escape puts the tooltip away. Each point is a '<span>' placed by percentage over the drawing, as 'LineChart' places its end points, so points stay round when the drawing stretches. The plot runs left to right in every text direction, as a number line does. The plot, its axes, and the axis names sit in a 'plane' part with 'dir="ltr"'. The axis names carry 'dir="auto"', so a name in Arabic or Hebrew reads in its own direction. The summary and the tooltip bubble follow the page's direction. */
15914
16331
  "helix-headless-scatter-chart": DefineCustomElement<
15915
16332
  HelixHeadlessScatterChart,
15916
16333
  HelixHeadlessScatterChartVueProps,
@@ -15946,7 +16363,7 @@ export interface WcToolkitVueGlobalComponents {
15946
16363
  HelixHeadlessSliderVueProps,
15947
16364
  HelixHeadlessSliderVueEvents
15948
16365
  >;
15949
- /** Takes its numbers from the 'values' attribute. The other charts read a table, but a table behind a small trend line would be read aloud row by row. Set 'values' to the data and 'label' to the one sentence a screen reader announces. Use 'for' when a sparkline has a real table behind it. 'for' wins when both are set. Without a 'label' the sparkline is decorative and 'aria-hidden', for example beside a stat that already says "Sessions, 1,102". With a 'label' it is named by that sentence and read by key, as every chart is: the drawing takes focus, the arrow keys walk the readings, Home and End go to the first and the last, Escape puts the reading away, and the 'live' part says each reading with where it stands, such as "Mon: 12 (3 of 7)". A pointer resting on the drawing shows the reading under it: the 'cursor' part marks it and the 'readout' part writes it. 'marks' adds a mark on the highest and the lowest reading. A blank cell in a 'for' table is a gap in the line. Place it beside a 'Stat', because a change beside a figure is a second fact, as 'Stat''s own spec says. 'Trend' is composed the same way. The component writes the properties listed below, and the stylesheet that draws the sparkline reads them. Do not set them yourself. They carry numbers the component computes and CSS cannot, so a stylesheet can draw the sparkline without measuring anything. */
16366
+ /** Takes its numbers from the 'values' attribute. The other charts read a table, but a table behind a small trend line would be read aloud row by row. Set 'values' to the data and 'label' to the one sentence a screen reader announces. Use 'for' when a sparkline has a real table behind it. 'for' wins when both are set. Without a 'label' the sparkline is decorative and 'aria-hidden', for example beside a stat that already says "Sessions, 1,102". With a 'label' it is named by that sentence and read by key, as every chart is: the drawing takes focus, the arrow keys walk the readings, Home and End go to the first and the last, Escape puts the reading away, and the 'live' part says each reading with where it stands, such as "Mon: 12 (3 of 7)". **A named sparkline describes itself.** Beside its name, a screen reader hears what the readings come to, the first and the last, the highest and the lowest, in 'overview-label': "From 12 to 20, highest 30, lowest 8". An 'aria-label' on the element names it as 'label' does. A pointer resting on the drawing shows the reading under it: the 'cursor' part marks it and the 'readout' part writes it. 'marks' adds a mark on the highest and the lowest reading, and 'range' draws a band between two values, such as a normal range. A blank cell in a 'for' table is a gap in the line, and a reading alone between two blanks is a 'lone' mark. Place it beside a 'Stat', because a change beside a figure is a second fact, as 'Stat''s own spec says. 'Trend' is composed the same way. The component writes the properties listed below, and the stylesheet that draws the sparkline reads them. Do not set them yourself. They carry numbers the component computes and CSS cannot, so a stylesheet can draw the sparkline without measuring anything. */
15950
16367
  "helix-headless-sparkline": DefineCustomElement<
15951
16368
  HelixHeadlessSparkline,
15952
16369
  HelixHeadlessSparklineVueProps,
@@ -15982,7 +16399,7 @@ export interface WcToolkitVueGlobalComponents {
15982
16399
  HelixHeadlessStatVueProps,
15983
16400
  HelixHeadlessStatVueEvents
15984
16401
  >;
15985
- /** 'active' sets where the user is, and 'complete' stays on each step. Returning to stage one of three leaves stages one and two finished, so the root sets 'current' on the steps and never changes 'complete'. 'active' is optional. Without it, each step keeps its own 'current', so the sequence is correct in the server's markup, where the root cannot count its slotted children. 'linear' keeps a reader from passing a stage they have not finished, as Ark UI's linear steps do: a stage ahead is out of reach, and its button disabled, until every stage before it is 'complete' or 'optional'. Going back is always allowed. 'next()' and 'previous()' move one stage either way, under the same rules, for your own buttons. To check a stage before a reader moves on from it, set 'validate' to a function that answers whether the stage is valid, as Ark UI's 'isStepValid' does. Moving forward asks it about the stage the reader is on, and where it answers 'false' the reader stays and the stage is ':state(invalid)' until it answers 'true'. An 'optional' stage is not asked. 'helix-before-activate' is still sent for every move, for a check of your own. 'progress' is how far through the sequence is, from 0 to 100: the share of its stages that are 'complete'. The 'progress' part carries it as a 'progressbar' and as '--steps-progress', and is hidden until a stylesheet gives it a 'display', so a bar of your own costs nothing until you draw it. The sequence is ':state(complete)' once every stage is. The sequence is a list named by 'label', and each step a list item. The current stage's button says 'aria-current="step"', and a finished stage's button is described by its 'complete-label'. */
16402
+ /** 'active' sets where the user is, and 'complete' stays on each step. Returning to stage one of three leaves stages one and two finished, so the root sets 'current' on the steps and never changes 'complete'. 'active' is optional. Without it, each step keeps its own 'current', so the sequence is correct in the server's markup, where the root cannot count its slotted children. 'linear' keeps a reader from passing a stage they have not finished, as Ark UI's linear steps do: a stage ahead is out of reach, and its button disabled, until every stage before it is 'complete' or 'optional'. Going back is always allowed. 'next()' and 'previous()' move one stage either way, under the same rules, for your own buttons. To check a stage before a reader moves on from it, set 'validate' to a function that answers whether the stage is valid, as Ark UI's 'isStepValid' does. Moving forward asks it about the stage the reader is on, and where it answers 'false' the reader stays and the stage is ':state(invalid)' until it answers 'true'. An 'optional' stage is not asked. 'helix-before-activate' is still sent for every move, for a check of your own. 'progress' is how far through the sequence is, from 0 to 100: the share of its stages that are 'complete'. The 'progress' part carries it as a 'progressbar' and as '--steps-progress', and is hidden until a stylesheet gives it a 'display', so a bar of your own costs nothing until you draw it. A screen reader hears it as 'progress-label' says, "33% complete" unless set, as Ark UI's steps write it. The sequence is ':state(complete)' once every stage is. The sequence is a list named by 'label', and each step a list item. The current stage's button says 'aria-current="step"', and a finished stage's button is described by its 'complete-label'. */
15986
16403
  "helix-headless-steps": DefineCustomElement<
15987
16404
  HelixHeadlessSteps,
15988
16405
  HelixHeadlessStepsVueProps,
@@ -16018,7 +16435,7 @@ export interface WcToolkitVueGlobalComponents {
16018
16435
  HelixHeadlessTableVueProps,
16019
16436
  HelixHeadlessTableVueEvents
16020
16437
  >;
16021
- /** The row renders its cells straight through and lays out none of them, so a stylesheet can place them in the table's grid and every column lines up across rows. The row still exists as an element, so you can style it, hide it, or make it interactive. In a 'selectable' table the row draws a checkbox cell before its own cells, and 'value' is the key the table's 'selected' lists it by. */
16438
+ /** The row renders its cells straight through and lays out none of them, so a stylesheet can place them in the table's grid and every column lines up across rows. The row still exists as an element, so you can style it, hide it, or make it interactive. In a 'selectable' table the row draws a checkbox cell before its own cells, and 'value' is the key the table's 'selected' lists it by. **'href' makes the whole row a link**, as a row action does in React Aria's table: a press anywhere on the row follows it, except on a link or a control of the row's own, and Control, Command or Shift open it the way they open a link. A drag that selects text follows nothing. A row in a table is not a stop of its own, so put the same link in a cell, usually the row header, which is what the keyboard and a screen reader reach. */
16022
16439
  "helix-headless-table-row": DefineCustomElement<
16023
16440
  HelixHeadlessTableRow,
16024
16441
  HelixHeadlessTableRowVueProps,
@@ -16030,7 +16447,7 @@ export interface WcToolkitVueGlobalComponents {
16030
16447
  HelixHeadlessTabPanelVueProps,
16031
16448
  HelixHeadlessTabPanelVueEvents
16032
16449
  >;
16033
- /** Selection works through an event, the same as in the accordion and the tree. A tab dispatches 'helix-select', and the root pairs it with the panel of the same value. Nothing registers with anything, so tabs added later work with no extra setup. The tab list is a single tab stop, and the arrow keys move between tabs through 'KeyboardNavigationController', the same as in the radio and toggle groups. Selection follows focus, which suits a small set where showing a panel is cheap. Set 'manual' when showing a panel is expensive, so focus can move without selecting. 'orientation="vertical"' sets the tabs in a column beside the panels, and the tab list says 'aria-orientation="vertical"'. The arrow keys of both axes move between tabs either way. A tab with an 'href' is a link, for tabs that are pages of a site. Pressing it follows the link, and the arrow keys move focus without choosing, so arrowing past a tab never leaves the page. Mark the tab of the page you are on with 'selected', or set 'active' to its value. Each tab says which panel it controls through 'aria-controls', set as an element reference to the panel's host, where the engine has reflection. Keys, on the tab list: Left and Right Arrow move between tabs, and so do Up and Down; Home and End go to the first and the last. The horizontal arrows follow the reading direction, so on a right-to-left page Left moves on. Disabled tabs are passed over. Tab leaves the list for the selected panel, which is a tab stop only while it holds nothing focusable. The 'indicator' part moves to the selected tab and carries its place and size, so a mark of your own can be drawn there: style the part, or slot an element into 'indicator', which sits inside the part and reads the same properties. */
16450
+ /** Selection works through an event, the same as in the accordion and the tree. A tab dispatches 'helix-select', and the root pairs it with the panel of the same value. Nothing registers with anything, so tabs added later work with no extra setup. The tab list is a single tab stop, and the arrow keys move between tabs through 'KeyboardNavigationController', the same as in the radio and toggle groups. Selection follows focus, which suits a small set where showing a panel is cheap. Set 'manual' when showing a panel is expensive, so focus can move without selecting. 'orientation="vertical"' sets the tabs in a column beside the panels, and the tab list says 'aria-orientation="vertical"'. The arrow keys of both axes move between tabs either way. A tab with an 'href' is a link, for tabs that are pages of a site. Pressing it follows the link. Where any tab is a link, the arrow keys move focus without choosing on every tab of the list, as under 'manual', so arrowing past a tab never leaves the page and the list answers the keys one way. Mark the tab of the page you are on with 'selected', or set 'active' to its value. Each tab says which panel it controls through 'aria-controls', set as an element reference to the panel's host, where the engine has reflection. Keys, on the tab list: Left and Right Arrow move between tabs, and so do Up and Down; Home and End go to the first and the last. The horizontal arrows follow the reading direction, so on a right-to-left page Left moves on. Disabled tabs are passed over. Tab leaves the list for the selected panel, which is a tab stop only while it holds nothing focusable. The 'indicator' part moves to the selected tab and carries its place and size, so a mark of your own can be drawn there: style the part, or slot an element into 'indicator', which sits inside the part and reads the same properties. */
16034
16451
  "helix-headless-tabs": DefineCustomElement<
16035
16452
  HelixHeadlessTabs,
16036
16453
  HelixHeadlessTabsVueProps,
@@ -16042,7 +16459,7 @@ export interface WcToolkitVueGlobalComponents {
16042
16459
  HelixHeadlessTabVueProps,
16043
16460
  HelixHeadlessTabVueEvents
16044
16461
  >;
16045
- /** A part of 'Tag' that holds tags as one control: a grid of rows, one tab stop for the whole set. The arrow keys move between tags, Home and End go to the first and the last, and a typed letter goes to the next tag starting with it. Delete or Backspace removes the focused tag where it is 'dismissible', by sending its 'helix-dismiss': remove it from your list in the handler, and focus moves to the next tag, or the previous one after the last. 'selection-mode' lets a reader select tags, with Space, Enter or a press: 'single' selects one at a time and 'multiple' any number. 'value' holds the selected tags' values, separated by commas, and a change asks with 'helix-before-change' and tells with 'change'. Enter on a tag with an 'href' follows its link. A 'disabled' tag is passed over. A selected tag that is removed leaves 'value', which then sends 'change'. Name the set with 'label'. Each tag is named by its words alone, without its remove button. **Removing the last tag keeps focus in the group.** With no tags left the set is a 'group', and focus moves to its 'empty' part, which holds the 'empty' slot: put words there such as "No filters" for a reader to hear. */
16462
+ /** A part of 'Tag' that holds tags as one control: a grid of rows, one tab stop for the whole set. The arrow keys move between tags, Home and End go to the first and the last, and a typed letter goes to the next tag starting with it. Delete or Backspace removes the focused tag where it is 'dismissible', by sending its 'helix-dismiss': remove it from your list in the handler, and focus moves to the next tag, or the previous one after the last. 'selection-mode' lets a reader select tags, with Space, Enter or a press: 'single' selects one at a time and 'multiple' any number. 'value' holds the selected tags' values, separated by commas, and a change asks with 'helix-before-change' and tells with 'change'. Enter on a tag with an 'href' follows its link. A 'disabled' tag is passed over. A selected tag that is removed leaves 'value', which then sends 'change'. Name the set with 'label'. Each tag is named by its words alone, without its remove button. 'value' takes an array of values on the property as well, as React sets 'value={['Apple']}'; a press writes it back as a string. **Removing the last tag keeps focus in the group.** With no tags left the set is a 'group', and focus moves to its 'empty' part, which holds the 'empty' slot: put words there such as "No filters" for a reader to hear. With nothing slotted it says 'empty-label', "No tags". */
16046
16463
  "helix-headless-tag-group": DefineCustomElement<
16047
16464
  HelixHeadlessTagGroup,
16048
16465
  HelixHeadlessTagGroupVueProps,
@@ -16054,7 +16471,7 @@ export interface WcToolkitVueGlobalComponents {
16054
16471
  HelixHeadlessTagVueProps,
16055
16472
  HelixHeadlessTagVueEvents
16056
16473
  >;
16057
- /** Renders a '<textarea>', so the caret, selection, spellcheck, resize handle, and phone keyboard come from the platform. It is in the server markup, so the field works before any script loads. It is a separate element from 'Input' because Enter inserts a line break here. In a single-line field, Enter submits the form. 'rows' sets the starting height, and 'auto-grow' makes the field grow with its content. You can use both: 'rows' sets where an empty field begins. 'max-rows' stops the growth at that many lines, and the field scrolls past them. 'clearable' draws a button that empties the field while it holds text, and sends 'helix-clear', as 'Input' does. 'validate' adds your own rule, run on every change once the browser finds nothing wrong, as React Aria's TextField 'validate' does. */
16474
+ /** Renders a '<textarea>', so the caret, selection, spellcheck, resize handle, and phone keyboard come from the platform. It is in the server markup, so the field works before any script loads. It is a separate element from 'Input' because Enter inserts a line break here. In a single-line field, Enter submits the form. 'rows' sets the starting height, and 'auto-grow' makes the field grow with its content. You can use both: 'rows' sets where an empty field begins. 'max-rows' stops the growth at that many lines, and the field scrolls past them. 'clearable' draws a button that empties the field while it holds text, and sends 'helix-clear', as 'Input' does. 'validate' adds your own rule, run on every change once the browser finds nothing wrong, as React Aria's TextField 'validate' does. **Keyboard.** The field's own keys are the platform's, and Enter starts a new line. The clear button under 'clearable' is a tab stop of its own after the field. The inner textarea is named by 'label', or by a host 'aria-label', 'aria-labelledby' or '<label for>', and is described by the hint and the message, with 'aria-invalid' while a message shows. The clear button is named 'clear-label'. */
16058
16475
  "helix-headless-textarea": DefineCustomElement<
16059
16476
  HelixHeadlessTextarea,
16060
16477
  HelixHeadlessTextareaVueProps,
@@ -16090,19 +16507,19 @@ export interface WcToolkitVueGlobalComponents {
16090
16507
  HelixHeadlessTimelineVueProps,
16091
16508
  HelixHeadlessTimelineVueEvents
16092
16509
  >;
16093
- /** Each message is an element because it has a timeout, a tone, a dismiss control, and a lifetime that pauses. **Each item runs its own timer.** A timer held by the region would restart with each new message, and the last of three messages would stay for nine seconds. **Each message is an 'alertdialog' named by its words**, which is how a reader who moves into the stack hears which message they are on. Give it a 'heading' and a 'description', and the heading names it and the description describes it, for a message with a title and a line of detail. A 'danger' message is its own assertive live region, so it is announced at once; every other one is announced politely by the region. A touch or a pen swipes a message toward the end of the line, and past halfway, or quickly, dismisses it through the same 'helix-dismiss' as its control. While it moves, the distance is on the 'item' part as '--toast-swipe-x'. **Messages are inverted by default.** The item flips 'color-scheme', so a new message stands out from the page without using a color that carries meaning. */
16510
+ /** Each message is an element because it has a timeout, a tone, a dismiss control, and a lifetime that pauses. **Each item runs its own timer.** A timer held by the region would restart with each new message, and the last of three messages would stay for nine seconds. **Each message is an 'alertdialog' named by its words**, which is how a reader who moves into the stack hears which message they are on. Give it a 'heading' and a 'description', and the heading names it and the description describes it, for a message with a title and a line of detail. The region says each message once as it arrives, a 'danger' one assertively, so a message is never a live region of its own. A touch or a pen swipes a message toward the end of the line, and past halfway, or quickly, dismisses it through the same 'helix-dismiss' as its control. While it moves, the distance is on the 'item' part as '--toast-swipe-x'. **Messages are inverted by default.** The item flips 'color-scheme', so a new message stands out from the page without using a color that carries meaning. */
16094
16511
  "helix-headless-toast-item": DefineCustomElement<
16095
16512
  HelixHeadlessToastItem,
16096
16513
  HelixHeadlessToastItemVueProps,
16097
16514
  HelixHeadlessToastItemVueEvents
16098
16515
  >;
16099
- /** The region and its items are one family because a live region must be in the document before a message is added to it. Assistive technology often does not announce a region that arrives already holding its message. 'Radio.Group' is part of its family for the same reason. **The region is a landmark named by 'label', and a polite live region.** A 'danger' message is announced assertively, and every other one politely. Each message is an 'alertdialog' named by its words, so a reader who moves into the stack hears which message they are on. **'hotkey' takes focus to the stack and back**, F8 unless you set it, and 'label' says which key: '{hotkey}' in it is filled in, so the default name is "Notifications (F8)". Pressed while focus is in the stack, it gives focus back to where it was. **The region never creates or removes items.** You render items and remove them. An item requests closing with a cancelable 'helix-dismiss' event. A dismissed item hides itself and stays in the DOM, so your framework's state and the DOM stay in sync. It hides on its own unless you set 'open', which makes the state yours. **'add()' shows a message from script**, for a page with no framework state to render them from: it appends a message of the region's own tier and removes it once it has been dismissed and has finished leaving. Messages you render yourself stay yours, and the region never removes them. A touch or a pen swipes a message away toward the end of the line. **The stack is in the top layer.** The 'region' part is a 'popover="manual"' shown while a message is showing, and shown again above a modal dialog that opened after it. Position the 'region' part, which is the box in the top layer. While a modal 'Dialog', 'Drawer' or 'Lightbox' is open, the browser makes everything outside it inert, the stack included, so a message stays visible and its actions cannot be pressed. Where the browser has 'ariaNotify', a message that arrives then is announced through it. For a message with an action, render a second region inside the dialog. When a message with focus inside it is dismissed, focus moves to the next message, then the one before it, then back to where it was before it entered the stack. */
16516
+ /** The region and its items are one family because a live region must be in the document before a message is added to it. Assistive technology often does not announce a region that arrives already holding its message. 'Radio.Group' is part of its family for the same reason. **The region is a landmark named by 'label', and it says each message once as it arrives**: a 'danger' message assertively, and every other one politely. It says the word for the tone, the heading, the description and the text, and not the actions, through two live regions of its own, the 'live' parts, which it empties again a moment later. The stack itself is not a live region, so a message is never said twice, and changing the words of a message already showing says nothing. Each message is an 'alertdialog' named by its words, so a reader who moves into the stack hears which message they are on. **'hotkey' takes focus to the stack and back**, F8 unless you set it, and 'label' says which key: '{hotkey}' in it is filled in, so the default name is "Notifications (F8)". Pressed while focus is in the stack, it gives focus back to where it was. **The region never creates or removes items.** You render items and remove them. An item requests closing with a cancelable 'helix-dismiss' event. A dismissed item hides itself and stays in the DOM, so your framework's state and the DOM stay in sync. It hides on its own unless you set 'open', which makes the state yours. **'add()' shows a message from script**, for a page with no framework state to render them from: it appends a message of the region's own tier and removes it once it has been dismissed and has finished leaving. Messages you render yourself stay yours, and the region never removes them. A touch or a pen swipes a message away toward the end of the line. **The stack is in the top layer.** The 'region' part is a 'popover="manual"' shown while a message is showing, and shown again above a modal dialog that opened after it. Position the 'region' part, which is the box in the top layer. While a modal 'Dialog', 'Drawer' or 'Lightbox' is open, the browser makes everything outside it inert, the stack included, so a message stays visible and its actions cannot be pressed. Where the browser has 'ariaNotify', a message that arrives then is announced through it. For a message with an action, render a second region inside the dialog. When a message with focus inside it is dismissed, focus moves to the next message, then the one before it, then back to where it was before it entered the stack. */
16100
16517
  "helix-headless-toast": DefineCustomElement<
16101
16518
  HelixHeadlessToast,
16102
16519
  HelixHeadlessToastVueProps,
16103
16520
  HelixHeadlessToastVueEvents
16104
16521
  >;
16105
- /** The indicator is one element that moves to the selected item. A single moving object is easier to follow than a fill that swaps, and it shows where the selection came from. Its size and position are measured from the selected item and written to the indicator as custom properties, because labels have different lengths. Measurement happens on the client, so the server renders the indicator hidden and it fades in once measured. 'selection-mode="multiple"' makes the group a toolbar of buttons that each say whether they are pressed with 'aria-pressed', as React Aria's ToggleButtonGroup and Radix's ToggleGroup do. A press presses or releases one item, the arrow keys move focus without pressing, and 'value' is the pressed values, comma separated, which 'values' also gives as a list. Use 'values' where an item's value holds a comma. The form receives one entry per pressed value, and a page the browser brings back presses the same items again. The indicator stays hidden, and each pressed item is marked with ':state(pressed)'. Inside a toolbar it is a named group of that toolbar's controls instead, so a reader meets one toolbar. 'orientation="vertical"' runs the items down a column, says so to the accessibility tree, and the up and down arrows move between them. */
16522
+ /** The indicator is one element that moves to the selected item. A single moving object is easier to follow than a fill that swaps, and it shows where the selection came from. Its size and position are measured from the selected item and written to the indicator as custom properties, because labels have different lengths. Measurement happens on the client, so the server renders the indicator hidden and it fades in once measured. 'selection-mode="multiple"' makes the group a toolbar of buttons that each say whether they are pressed with 'aria-pressed', as React Aria's ToggleButtonGroup and Radix's ToggleGroup do. A press presses or releases one item, the arrow keys move focus without pressing, and 'value' is the pressed values, comma separated, which 'values' also gives as a list. Use 'values' where an item's value holds a comma. The form receives one entry per pressed value, and a page the browser brings back presses the same items again. The indicator stays hidden, and each pressed item is marked with ':state(pressed)'. Inside a toolbar it is a named group of that toolbar's controls instead, so a reader meets one toolbar. 'orientation="vertical"' runs the items down a column, says so to the accessibility tree, and the up and down arrows move between them. **Keyboard.** The group is one tab stop: the chosen item, or the first that can be chosen, as in a radio group, and in a multiple group the item focus was last on. | Key | What it does | |---|---| | Right, Down | Moves to the next item, from the last back to the first. In a single group, chooses it. | | Left, Up | Moves to the item before, from the first round to the last. In a single group, chooses it. | | Home, End | Moves to the first or the last item. In a single group, chooses it. | | Space, Enter | Chooses the focused item, or presses or releases it in a multiple group. | Left and Right swap on a right-to-left page, and a disabled item is passed over. A single group is a 'radiogroup' of items with 'role="radio"' and 'aria-checked'. A multiple group is a 'toolbar' of buttons with 'aria-pressed', or a 'group' inside a toolbar. The group is named by 'label' and carries 'aria-orientation' under 'orientation'. */
16106
16523
  "helix-headless-toggle-group": DefineCustomElement<
16107
16524
  HelixHeadlessToggleGroup,
16108
16525
  HelixHeadlessToggleGroupVueProps,
@@ -16114,19 +16531,19 @@ export interface WcToolkitVueGlobalComponents {
16114
16531
  HelixHeadlessToggleVueProps,
16115
16532
  HelixHeadlessToggleVueEvents
16116
16533
  >;
16117
- /** A toolbar holds a mix of controls, such as buttons, toggles, and menus. A button group holds one kind, so the two are separate components. The toolbar is one tab stop, and the arrow keys move between its controls, so three toolbars take three presses of Tab to pass. Any element the browser can focus counts as a control, including your own elements. A child that takes no focus, such as a divider, is skipped. A menu is reached at its trigger. Controls inside a plain wrapper, such as a 'Button Group', are each a stop of the toolbar's own, as React Aria's toolbar flattens a group: the arrows walk through the group's buttons and on past it, and the group takes no tab stop of its own. The arrows wrap from the last control to the first. Set 'stop-at-ends' to keep them at the ends, as Radix's 'loop' set to false does. A nested composite, such as a toggle group, is one stop on the toolbar's axis: the toolbar's arrows move past it, and the arrows across the toolbar move inside it. A composite with a 'focusable' property, as Toggle Group has, gives up its own tab stop while the toolbar's is elsewhere, so Tab stops once in the toolbar. A composite without one keeps its own tab stop. */
16534
+ /** A toolbar holds a mix of controls, such as buttons, toggles, and menus. A button group holds one kind, so the two are separate components. The toolbar is one tab stop, and the arrow keys move between its controls, so three toolbars take three presses of Tab to pass. Any element the browser can focus counts as a control, including your own elements. A child that takes no focus, such as a divider, is skipped. A menu is reached at its trigger. Controls inside a plain wrapper, such as a 'Button Group', are each a stop of the toolbar's own, as React Aria's toolbar flattens a group: the arrows walk through the group's buttons and on past it, and the group takes no tab stop of its own. The arrows wrap from the last control to the first. Set 'stop-at-ends' to keep them at the ends, as Radix's 'loop' set to false does. A toggle group of pressed buttons, 'selection-mode="multiple"', is walked through the same way, each toggle a stop on the toolbar's axis, as React Aria's toolbar walks its toggle buttons. Another nested composite, such as a radio-style toggle group, is one stop on the toolbar's axis: the toolbar's arrows move past it, and the arrows across the toolbar move inside it. A composite with a 'focusable' property, as Toggle Group has, gives up its own tab stop while the toolbar's is elsewhere, so Tab stops once in the toolbar. A composite without one keeps its own tab stop. A toolbar inside another toolbar, a Helix one or the page's own 'role="toolbar"', is a 'group' of the outer one, as React Aria's is: the outer toolbar's arrows walk through its controls and on past them, and it takes no keys and no tab stop of its own. A server renders it as a toolbar, having no parent to read, until it upgrades. */
16118
16535
  "helix-headless-toolbar": DefineCustomElement<
16119
16536
  HelixHeadlessToolbar,
16120
16537
  HelixHeadlessToolbarVueProps,
16121
16538
  HelixHeadlessToolbarVueEvents
16122
16539
  >;
16123
- /** The trigger is slotted and stays your own element. The bubble renders in the top layer through the popover API, so an ancestor with 'overflow: hidden' does not clip it and no 'z-index' is needed. 'FloatingController' positions it and flips it to another side when the preferred side does not fit. **The tooltip describes its trigger itself, in both forms.** Wrap the trigger, or place the tooltip beside it and name the trigger with 'for': '''html <helix-headless-button id="save">Save</helix-headless-button> <helix-headless-tooltip for="save" content="Save your work"></helix-headless-tooltip> ''' The link is an element reference on the control that takes focus, and it is never written into your markup before a reader has acted. A trigger that is a Helix component is described at once, inside its own shadow root. A plain element in your markup is described when a reader first points at it or focuses it, which is after any hydration, and only where you have written no 'aria-describedby' or 'aria-labelledby' of your own. Write 'aria-describedby' pointing at the tooltip yourself to have the link in the server's markup. Where the browser has no element references, write it yourself; the tooltip warns once on first open if nothing links the two. The tooltip shows on hover and on focus. It hides on pointer leave, on blur, on Escape, and when the trigger is activated. The pointer can move from the trigger onto the bubble and the bubble stays, unless you set 'hoverable="false"'. 'delay' is how long the pointer rests before it shows, and 'delay-out' how long it stays once the pointer leaves. Once one tooltip is showing, moving to another trigger shows its tooltip with no 'delay', and the first one hides. The same holds for 'skip-delay' milliseconds after a tooltip hides, 300 unless you set it. 'show-on="focus"' shows the tooltip on keyboard focus only, for a hint a pointer does not need. */
16540
+ /** The trigger is slotted and stays your own element. The bubble renders in the top layer through the popover API, so an ancestor with 'overflow: hidden' does not clip it and no 'z-index' is needed. 'FloatingController' positions it and flips it to another side when the preferred side does not fit. **The tooltip describes its trigger itself, in both forms.** Wrap the trigger, or place the tooltip beside it and name the trigger with 'for': '''html <helix-headless-button id="save">Save</helix-headless-button> <helix-headless-tooltip for="save" content="Save your work"></helix-headless-tooltip> ''' The link is an element reference on the control that takes focus, and it is never written into your markup before a reader has acted. A trigger that is a Helix component is described at once, inside its own shadow root. A plain element in your markup is described when a reader first points at it or focuses it, which is after any hydration, and only where you have written no 'aria-describedby' or 'aria-labelledby' of your own. Write 'aria-describedby' pointing at the tooltip yourself to have the link in the server's markup. Where the browser has no element references, write it yourself; the tooltip warns once on first open if nothing links the two. In the 'for' form the tooltip itself is out of the accessibility tree while its bubble is down, so a reader walking the page meets its words once, as the trigger's description. The tooltip shows on hover and on focus. It hides on pointer leave, on blur, on Escape, and when the trigger is activated. The pointer can move from the trigger onto the bubble and the bubble stays, unless you set 'hoverable="false"'. 'delay' is how long the pointer rests before it shows, and 'delay-out' how long it stays once the pointer leaves. Once one tooltip is showing, moving to another trigger shows its tooltip with no 'delay', and the first one hides. The same holds for 'skip-delay' milliseconds after a tooltip hides, 300 unless you set it. 'show-on="focus"' shows the tooltip on keyboard focus only, for a hint a pointer does not need. */
16124
16541
  "helix-headless-tooltip": DefineCustomElement<
16125
16542
  HelixHeadlessTooltip,
16126
16543
  HelixHeadlessTooltipVueProps,
16127
16544
  HelixHeadlessTooltipVueEvents
16128
16545
  >;
16129
- /** The root holds the order of the stops: which stop is current, what Next and Back do, and when the tour is finished. Each stop holds its target, and you write all the text. **The spotlight is a shadow.** The scrim is a box the size of the current target with a very large 'box-shadow' spread, and the shadow paints the darkness. A 'clip-path' on a full-screen scrim breaks as soon as an element between the scrim and the viewport is transformed. The root measures the target's position in the browser. Nothing is measured on the server, because a tour starts only on request. 'open', 'default-open', 'helix-before-open', 'helix-before-close' and 'toggle' work as they do on 'Dialog'. Setting 'open' starts the run, and 'skip()' and 'requestOpen(false)' end it early. The box the light falls on is on the 'spotlight' part as '--tour-spotlight-x', '--tour-spotlight-y', '--tour-spotlight-width' and '--tour-spotlight-height', for a sheet that draws its own light, such as a ring around the target. Each stop is told its place in the run, from 'progress-label', such as "2 of 5". It describes the stop's panel, so a screen reader says it at every stop, and 'progress' draws it in the panel as well. A dialog or a floating stop, which has nothing to light, is shown over the 'backdrop' part. At a 'wait' stop the run waits for that stop's target to be on the page, and moves on by itself. **Focus follows the run.** Opening moves focus to the first stop's panel, and moving on from a control in a stop moves it to the next one. Ending the tour puts focus back on the element that had it when the tour opened, unless you have moved it somewhere else on the page. A stop does not trap focus, so you can still 'Tab' out to the element it describes. */
16546
+ /** The root holds the order of the stops: which stop is current, what Next and Back do, and when the tour is finished. Each stop holds its target, and you write all the text. **The spotlight is a shadow.** The scrim is a box the size of the current target with a very large 'box-shadow' spread, and the shadow paints the darkness. A 'clip-path' on a full-screen scrim breaks as soon as an element between the scrim and the viewport is transformed. The root measures the target's position in the browser. Nothing is measured on the server, because a tour starts only on request. 'open', 'default-open', 'helix-before-open', 'helix-before-close' and 'toggle' work as they do on 'Dialog'. Setting 'open' starts the run, and 'skip()' and 'requestOpen(false)' end it early. The box the light falls on is on the 'spotlight' part as '--tour-spotlight-x', '--tour-spotlight-y', '--tour-spotlight-width' and '--tour-spotlight-height', for a sheet that draws its own light, such as a ring around the target. Each stop is told its place in the run, from 'progress-label', such as "2 of 5". It describes the stop's panel, so a screen reader says it at every stop, and 'progress' draws it in the panel as well. A dialog or a floating stop, which has nothing to light, is shown over the 'backdrop' part. At a 'wait' stop the run waits for that stop's target to be on the page, and moves on by itself. **Focus follows the run.** Opening moves focus to the first stop's panel, and moving on from a control in a stop moves it to the next one. Ending the tour puts focus back on the element that had it when the tour opened, unless you have moved it somewhere else on the page. A stop does not trap focus, so you can still 'Tab' out to the element it describes. **The arrow keys move between stops** while focus is in one: the arrow that points the way the line runs goes on, and the other goes back, so on a right-to-left page 'ArrowLeft' goes on. Neither finishes the tour at the last stop, and a text field in a stop keeps its own arrows. 'Escape' skips the tour. */
16130
16547
  "helix-headless-tour": DefineCustomElement<
16131
16548
  HelixHeadlessTour,
16132
16549
  HelixHeadlessTourVueProps,
@@ -16150,7 +16567,7 @@ export interface WcToolkitVueGlobalComponents {
16150
16567
  HelixHeadlessTreeVueProps,
16151
16568
  HelixHeadlessTreeVueEvents
16152
16569
  >;
16153
- /** A trend has three parts: a 'movement' of up, down, or neutral, the metric that moved, and a label for the period it moved over. The arrow shows the movement and its color shows whether the change is good. Movement and judgment are separate properties because they are separate facts. 'good' is unset by default, so a trend with no judgment is gray. For churn, latency, error rate, cost, and bounce rate, up is bad. Set the metric's polarity once with 'good', and the component picks the color from the movement. The judgment is also a custom state, 'better' or 'worse', for a sheet of your own. The movement is also written as a word, so a screen reader reads it. The styled tier hides 'part="direction"' visually and keeps it in the accessibility tree. The words are properties, 'up-label' through 'worse-label', so a page in another language can set its own. The arrow and any glyph slotted in its place are hidden from screen readers. Slot one glyph per movement into 'up-icon', 'down-icon' and 'neutral-icon', and the trend shows the one that matches; a glyph in 'icon' stands in for all three. Inside a 'Stat', put the trend in the stat's 'trend' slot so it is read with the figure it qualifies. The metric and the label are bare slots. An element that assigned its own slot on connect would add an attribute to its host after upgrade, which the React server markup did not have. */
16570
+ /** A trend has three parts: a 'movement' of up, down, or neutral, the metric that moved, and a label for the period it moved over. The arrow shows the movement and its color shows whether the change is good. Movement and judgment are separate properties because they are separate facts. 'good' is unset by default, so a trend with no judgment is gray. For churn, latency, error rate, cost, and bounce rate, up is bad. Set the metric's polarity once with 'good', and the component picks the color from the movement. The judgment is also a custom state, 'better' or 'worse', for a sheet of your own. The movement is also written as a word, so a screen reader reads it. The styled tier hides 'part="direction"' visually and keeps it in the accessibility tree. The words are properties, 'up-label' through 'worse-label', so a page in another language can set its own. The arrow and any glyph slotted in its place are hidden from screen readers. **Or give the change as a number.** 'value' is the signed change, such as '0.12' or '-8': its sign is the movement, and its size is written as the metric with 'Intl.NumberFormat', in 'locale' and with 'format-options', such as '{"style":"percent"}' for '12%'. 'movement' still wins when it is written. Without 'value' the metric is what the page slots. Slot one glyph per movement into 'up-icon', 'down-icon' and 'neutral-icon', and the trend shows the one that matches; a glyph in 'icon' stands in for all three. Inside a 'Stat', put the trend in the stat's 'trend' slot so it is read with the figure it qualifies. The metric and the label are bare slots. An element that assigned its own slot on connect would add an attribute to its host after upgrade, which the React server markup did not have. */
16154
16571
  "helix-headless-trend": DefineCustomElement<
16155
16572
  HelixHeadlessTrend,
16156
16573
  HelixHeadlessTrendVueProps,
@@ -16180,7 +16597,7 @@ export interface WcToolkitVueGlobalComponents {
16180
16597
  HelixHeadlessVideoVueProps,
16181
16598
  HelixHeadlessVideoVueEvents
16182
16599
  >;
16183
- /** The items arrive as data, in one of two ways: - 'items' takes an array. A framework sets it as a property, and React hydration keeps it. - 'for' names a '<script type="application/json">' that holds an array, which a server sends as markup. Each item is drawn into a row in one of two ways: - 'renderItem' is a function from an item and its index to the row's content: a Lit template, a string, or a DOM node. - A '<template>' child defines one row. 'data-field="name"' fills an element with the item's 'name' as text, and 'data-field-href="url"' writes the item's 'url' into 'href', the same for any attribute. A field may be a path of keys, such as 'author.name'. Rows are your markup in the light DOM, so your stylesheet styles them. **Keyboard.** The list is one tab stop. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous item. | | Home, End | Moves to the first or the last item. | | Page Down, Page Up | Moves by the number of items on screen. | | A letter or a word | Moves to the next item whose text starts with what you typed. | | Tab | Moves into the focused row's own links and buttons, then out of the list. | An item that is not drawn is scrolled into view and focused, so a keyboard reaches the whole set. When the row holding the tab stop scrolls away, the stop moves to the first row on screen. Typing matches each item's 'text-field', which is the first 'data-field' of the row template by default, or the item itself when it is a string or a number. Each row says its place in the whole set with 'aria-posinset' and 'aria-setsize', so a screen reader says "4,000 of 10,000". The row holding focus stays drawn when it scrolls out. **Selecting.** 'selection-mode' makes the list a list box a reader chooses from: 'single' selects one item and 'multiple' any number. Space or a press selects an item, Shift with Space, Up, Down, Home, End or a press takes in the items from the last one chosen, and Control or Command with A selects them all, in 'multiple'. 'value' holds the chosen items' keys, separated by commas, in the order of the set: 'key-field' names each item's key, and a string or a number item is its own key. A change asks with 'helix-before-change' and tells with 'change'. Each row is an 'option' marked 'aria-selected', so a row's own links and buttons are not reached there: keep those to a list without 'selection-mode'. **Loading more.** 'helix-range-change' fires as the items on screen change, and 'range' holds them. 'helix-load-more' fires once a reader is within one screen of the end, once for each length of the set: add to 'items' and it can fire again. While you fetch, set 'loading': the list is busy, and a row after the last item says "Loading more" ('loading-label', or your own content in the 'loading' slot). 'scrollToIndex' takes a reader to an item. **Row height.** Rows are placed by 'estimate' until they are drawn. Then the list reads the drawn rows' height once and places every row by it, so a wrong estimate still reaches the last item. Set 'measured' for rows of different heights. The list follows its source. A new 'items' array, an edit to the script's text, or a script replaced under the same id draws the new rows. A row that stays in view keeps its element as the list scrolls. The viewport scrolls on this tier. It carries 'data-scroller', and 'core' ships '[data-scroller] { overflow: auto }' into every shadow root, so 'scrollTop' works with no stylesheet. You still need to set a block size. */
16600
+ /** The items arrive as data, in one of two ways: - 'items' takes an array. A framework sets it as a property, and React hydration keeps it. - 'for' names a '<script type="application/json">' that holds an array, which a server sends as markup. Each item is drawn into a row in one of two ways: - 'renderItem' is a function from an item and its index to the row's content: a Lit template, a string, or a DOM node. - A '<template>' child defines one row. 'data-field="name"' fills an element with the item's 'name' as text, and 'data-field-href="url"' writes the item's 'url' into 'href', the same for any attribute. A field may be a path of keys, such as 'author.name'. Rows are your markup in the light DOM, so your stylesheet styles them. **A grid.** 'columns' lays the items out that many to a line, as a grid of equal columns, and windows the set a line at a time, as React Aria's grid layout does. Each item draws one element, a cell of the grid, and 'estimate' is the height of a line. Space the items with padding inside each one, which the list measures with the line. **Keyboard.** The list is one tab stop. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous item, or in a grid to the item in the same column on the next or the previous line. | | Right, Left | In a grid, moves to the next or the previous item along the line, the other way round on a right-to-left page. | | Home, End | Moves to the first or the last item. | | Page Down, Page Up | Moves by the number of items, or of lines in a grid, on screen. | | A letter or a word | Moves to the next item whose text starts with what you typed. | | Tab | Moves into the focused row's own links and buttons, then out of the list. | An item that is not drawn is scrolled into view and focused, so a keyboard reaches the whole set. When the row holding the tab stop scrolls away, the stop moves to the first row on screen. Typing matches each item's 'text-field', which is the first 'data-field' of the row template by default, or the item itself when it is a string or a number. Each row says its place in the whole set with 'aria-posinset' and 'aria-setsize', so a screen reader says "4,000 of 10,000". The row holding focus stays drawn when it scrolls out. **Selecting.** 'selection-mode' makes the list a list box a reader chooses from: 'single' selects one item and 'multiple' any number. Space or a press selects an item, Shift with Space, an arrow, Home, End or a press takes in the items from the last one chosen, and Control or Command with A selects them all, in 'multiple'. 'value' holds the chosen items' keys, separated by commas, in the order of the set: 'key-field' names each item's key, and a string or a number item is its own key. A change asks with 'helix-before-change' and tells with 'change'. Each row is an 'option' marked 'aria-selected', so a row's own links and buttons are not reached there: keep those to a list without 'selection-mode'. **Loading more.** 'helix-range-change' fires as the items on screen change, and 'range' holds them. 'helix-load-more' fires once a reader is within one screen of the end, once for each length of the set: add to 'items' and it can fire again. While you fetch, set 'loading': the list is busy, and a row after the last item says "Loading more" ('loading-label', or your own content in the 'loading' slot). 'scrollToIndex' takes a reader to an item. **Row height.** Rows are placed by 'estimate' until they are drawn. Then the list reads the drawn rows' height once and places every row by it, so a wrong estimate still reaches the last item. Set 'measured' for rows of different heights. The list follows its source. A new 'items' array, an edit to the script's text, or a script replaced under the same id draws the new rows. A row that stays in view keeps its element as the list scrolls. The viewport scrolls on this tier. It carries 'data-scroller', and 'core' ships '[data-scroller] { overflow: auto }' into every shadow root, so 'scrollTop' works with no stylesheet. You still need to set a block size. */
16184
16601
  "helix-headless-virtual-list": DefineCustomElement<
16185
16602
  HelixHeadlessVirtualList,
16186
16603
  HelixHeadlessVirtualListVueProps,