@fusion.dev/helix-headless 0.163.0 → 0.165.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 (47) hide show
  1. package/custom-elements.json +1068 -46
  2. package/dist/callout/root/callout-root.d.ts +43 -4
  3. package/dist/callout/root/callout-root.js +58 -2
  4. package/dist/code-block/patch.d.ts +42 -0
  5. package/dist/code-block/patch.js +118 -0
  6. package/dist/code-block/root/code-block-root.d.ts +37 -1
  7. package/dist/code-block/root/code-block-root.js +57 -9
  8. package/dist/color-picker/root/color-picker-root.d.ts +7 -3
  9. package/dist/color-picker/root/color-picker-root.js +7 -4
  10. package/dist/combobox/root/combobox-root.d.ts +1 -0
  11. package/dist/combobox/root/combobox-root.js +10 -1
  12. package/dist/data-table/root/data-table-root.d.ts +1 -0
  13. package/dist/data-table/root/data-table-root.js +1 -0
  14. package/dist/date-input/root/date-input-root.d.ts +3 -3
  15. package/dist/date-input/root/date-input-root.js +8 -5
  16. package/dist/element-events.generated.js +7 -1
  17. package/dist/format-date/root/format-date-root.d.ts +3 -1
  18. package/dist/format-date/root/format-date-root.js +4 -1
  19. package/dist/lightbox/item/lightbox-item.js +3 -1
  20. package/dist/lightbox/root/lightbox-root.d.ts +28 -0
  21. package/dist/lightbox/root/lightbox-root.js +21 -2
  22. package/dist/number-input/root/number-input-root.d.ts +32 -9
  23. package/dist/number-input/root/number-input-root.js +53 -9
  24. package/dist/object-inspector/root/object-inspector-root.d.ts +23 -0
  25. package/dist/object-inspector/root/object-inspector-root.js +19 -1
  26. package/dist/option/root/index.d.ts +1 -0
  27. package/dist/option/root/index.js +1 -0
  28. package/dist/table/grid-controller.d.ts +7 -0
  29. package/dist/table/grid-controller.js +15 -1
  30. package/dist/table/root/table-root.d.ts +10 -0
  31. package/dist/table/root/table-root.js +18 -1
  32. package/dist/tag/root/index.d.ts +1 -0
  33. package/dist/tag/root/index.js +1 -0
  34. package/dist/time-input/root/time-input-root.d.ts +4 -3
  35. package/dist/time-input/root/time-input-root.js +5 -4
  36. package/dist/time-picker/root/time-picker-root.d.ts +1 -1
  37. package/dist/time-picker/root/time-picker-root.js +5 -2
  38. package/dist/video/root/video-root.js +2 -1
  39. package/dist/video-playlist/item/video-playlist-item.d.ts +8 -0
  40. package/dist/video-playlist/item/video-playlist-item.js +7 -0
  41. package/dist/video-playlist/root/video-playlist-root.d.ts +60 -0
  42. package/dist/video-playlist/root/video-playlist-root.js +55 -1
  43. package/lint.json +1 -1
  44. package/package.json +5 -5
  45. package/types/jsx.d.ts +388 -40
  46. package/types/vue.d.ts +95 -13
  47. package/types/words.d.ts +58 -0
package/types/vue.d.ts CHANGED
@@ -1555,6 +1555,11 @@ none.
1555
1555
  takes away, where every button was "Dismiss". A label without `{label}` is
1556
1556
  read as written. */
1557
1557
  dismissLabel?: (HelixHeadlessCallout["dismissLabel"]) | undefined;
1558
+ /** Whether the callout is showing. A dismissal nobody canceled turns it
1559
+ false and the callout hides itself, and setting it true shows the callout
1560
+ again. Not reflected: open is the resting state, so an `open` attribute
1561
+ would appear on markup a server sent without it. */
1562
+ open?: (HelixHeadlessCallout["open"]) | undefined;
1558
1563
  /** What kind of attention the passage needs.
1559
1564
 
1560
1565
  `tone` is the axis for what a thing means, and this is a subset of it: a
@@ -1591,7 +1596,7 @@ out keeps its English, and `tone-label` wins over both.
1591
1596
  };
1592
1597
 
1593
1598
  export type HelixHeadlessCalloutVueEvents = {
1594
- /** The dismiss button was pressed. The callout does not remove itself, so remove it in response. Cancelable. */
1599
+ /** The dismiss button was pressed. Unless a listener cancels it, the callout hides itself, and a listener may remove it instead. Cancelable: cancel it to keep the callout showing. */
1595
1600
  "helix-dismiss": HelixHeadlessCalloutHelixDismissElementEvent;
1596
1601
  };
1597
1602
 
@@ -3175,6 +3180,14 @@ app.ts", as `code-name-label` puts it. */
3175
3180
  "collapse-label"?: (HelixHeadlessCodeBlock["collapseLabel"]) | undefined;
3176
3181
  /** The expand button's words while the block shows every line. */
3177
3182
  collapseLabel?: (HelixHeadlessCodeBlock["collapseLabel"]) | undefined;
3183
+ /** In a diff, how many unchanged lines to keep beside each change. Each
3184
+ longer run of unchanged lines is folded behind a button that shows it.
3185
+ Unset shows every line the diff holds. */
3186
+ "context-lines"?: (HelixHeadlessCodeBlock["contextLines"] | `${number}`) | undefined;
3187
+ /** In a diff, how many unchanged lines to keep beside each change. Each
3188
+ longer run of unchanged lines is folded behind a button that shows it.
3189
+ Unset shows every line the diff holds. */
3190
+ contextLines?: (HelixHeadlessCodeBlock["contextLines"]) | undefined;
3178
3191
  /** The copy button's name and tooltip text after a copy. */
3179
3192
  "copied-label"?: (HelixHeadlessCodeBlock["copiedLabel"]) | undefined;
3180
3193
  /** The copy button's name and tooltip text after a copy. */
@@ -3213,6 +3226,14 @@ block lays out. Not for a diff, whose files each scroll on their own. */
3213
3226
  "expand-label"?: (HelixHeadlessCodeBlock["expandLabel"]) | undefined;
3214
3227
  /** The expand button's words while the cap hides lines. */
3215
3228
  expandLabel?: (HelixHeadlessCodeBlock["expandLabel"]) | undefined;
3229
+ /** The words of a button that hides a run of unchanged lines it showed, in a
3230
+ diff with `context-lines`. `{count}` is how many, and each language
3231
+ writes the forms it has. */
3232
+ "hide-unchanged-label"?: (HelixHeadlessCodeBlock["hideUnchangedLabel"]) | undefined;
3233
+ /** The words of a button that hides a run of unchanged lines it showed, in a
3234
+ diff with `context-lines`. `{count}` is how many, and each language
3235
+ writes the forms it has. */
3236
+ hideUnchangedLabel?: (HelixHeadlessCodeBlock["hideUnchangedLabel"]) | undefined;
3216
3237
  /** The block's name, usually a file name, drawn in the header.
3217
3238
 
3218
3239
  Absent, the block is named by `language` where there is one. In a diff,
@@ -3288,6 +3309,12 @@ A false boolean reflects as the attribute's absence, so this costs no
3288
3309
  reflected property taking no default is satisfied by the default being
3289
3310
  `false`. */
3290
3311
  noCopy?: (HelixHeadlessCodeBlock["noCopy"]) | undefined;
3312
+ /** The words of a button that shows a folded run of unchanged lines, in a
3313
+ diff with `context-lines`. `{count}` is how many. */
3314
+ "show-unchanged-label"?: (HelixHeadlessCodeBlock["showUnchangedLabel"]) | undefined;
3315
+ /** The words of a button that shows a folded run of unchanged lines, in a
3316
+ diff with `context-lines`. `{count}` is how many. */
3317
+ showUnchangedLabel?: (HelixHeadlessCodeBlock["showUnchangedLabel"]) | undefined;
3291
3318
  /** How a diff's two versions are arranged. It has no effect without `diff`.
3292
3319
 
3293
3320
  Absent is unified, each removal above its replacement, which fits any
@@ -7322,7 +7349,9 @@ place of the date: `long` ("3 hours ago"), `short` ("3 hr. ago") or
7322
7349
  `narrow` ("3h ago").
7323
7350
 
7324
7351
  The reading refreshes as it goes stale, as `elapsed` does, and the whole
7325
- date is its title. `elapsed` wins where both are set. */
7352
+ date is its title. `elapsed` wins where both are set. Written with no
7353
+ value, as `elapsed` is, or with a style `Intl` does not know, it reads
7354
+ `long`. */
7326
7355
  relative?: (HelixHeadlessFormatDate["relative"]) | undefined;
7327
7356
  /** How the second is written, where a time of day is shown. */
7328
7357
  second?: (HelixHeadlessFormatDate["second"]) | undefined;
@@ -11327,10 +11356,11 @@ one they already know. */
11327
11356
  invalid, as it is in a native number field.
11328
11357
 
11329
11358
  Unset, a step moves by one, or by one percent under a percent format, and
11330
- a typed number is rounded to the smallest amount `format-options` shows
11331
- rather than to whole steps, as React Aria's NumberField does: a field
11332
- showing dollars keeps the cents typed into it. Without `format-options`
11333
- the grid is whole numbers, as in a native number field. */
11359
+ a typed number is rounded to the smallest amount the format shows, as
11360
+ React Aria's NumberField does: a field showing dollars keeps the cents
11361
+ typed into it, and one with no `format-options` keeps three decimal
11362
+ places. `any` puts the number on no grid, as it does in a native number
11363
+ field: a step moves by one, and any number in range is valid. */
11334
11364
  step?: (HelixHeadlessNumberInput["step"]) | undefined;
11335
11365
  /** The message the browser shows when the number is off the step grid, with
11336
11366
  `{below}` and `{above}` filled in with the nearest valid values, written in
@@ -11550,6 +11580,12 @@ reader sees the shape of the value before its contents. `0` starts with the
11550
11580
  root closed; a large number opens everything, which on a big value is the
11551
11581
  wall of text this exists to avoid. */
11552
11582
  defaultDepth?: (HelixHeadlessObjectInspector["defaultDepth"]) | undefined;
11583
+ /** What the tree says while there is no value to show, such as before a
11584
+ fetch answers. The `empty` slot replaces it. */
11585
+ "empty-label"?: (HelixHeadlessObjectInspector["emptyLabel"]) | undefined;
11586
+ /** What the tree says while there is no value to show, such as before a
11587
+ fetch answers. The `empty` slot replaces it. */
11588
+ emptyLabel?: (HelixHeadlessObjectInspector["emptyLabel"]) | undefined;
11553
11589
  /** Text the tree is narrowed to: the entries whose key or value holds it,
11554
11590
  ignoring case, and the branches that lead to them. Empty shows everything. */
11555
11591
  filter?: (HelixHeadlessObjectInspector["filter"]) | undefined;
@@ -11619,6 +11655,12 @@ who set the property. This button is positioned out of the flow and takes no
11619
11655
  room, so nothing selects on it, and reflection exists so that a selector can
11620
11656
  reach a value. */
11621
11657
  noCopy?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
11658
+ /** What the tree says while a filter matched no entry. The `empty` slot
11659
+ replaces it. */
11660
+ "no-matches-label"?: (HelixHeadlessObjectInspector["noMatchesLabel"]) | undefined;
11661
+ /** What the tree says while a filter matched no entry. The `empty` slot
11662
+ replaces it. */
11663
+ noMatchesLabel?: (HelixHeadlessObjectInspector["noMatchesLabel"]) | undefined;
11622
11664
  /** What a screen reader hears when a filter matches one entry, where
11623
11665
  `results-label` should not say it. `{count}` is the count. */
11624
11666
  "result-label"?: (HelixHeadlessObjectInspector["resultLabel"]) | undefined;
@@ -17728,17 +17770,43 @@ export type HelixHeadlessVideoPlaylistHelixActivateElementEvent =
17728
17770
  /** `helix-before-activate` event type */
17729
17771
  export type HelixHeadlessVideoPlaylistHelixBeforeActivateElementEvent =
17730
17772
  HelixHeadlessVideoPlaylistElementEvent<HelixBeforeActivateEvent>;
17773
+ /** `helix-before-reorder` event type */
17774
+ export type HelixHeadlessVideoPlaylistHelixBeforeReorderElementEvent =
17775
+ HelixHeadlessVideoPlaylistElementEvent<HelixBeforeReorderEvent>;
17731
17776
  /** `helix-end` event type */
17732
17777
  export type HelixHeadlessVideoPlaylistHelixEndElementEvent =
17733
17778
  HelixHeadlessVideoPlaylistElementEvent<HelixEndEvent>;
17779
+ /** `helix-reorder` event type */
17780
+ export type HelixHeadlessVideoPlaylistHelixReorderElementEvent =
17781
+ HelixHeadlessVideoPlaylistElementEvent<HelixReorderEvent>;
17734
17782
 
17735
17783
  export type HelixHeadlessVideoPlaylistVueProps = {
17784
+ /** What screen readers hear when a move is put back, in a `reorderable`
17785
+ playlist. `{name}` is the entry's words. */
17786
+ "canceled-label"?: (HelixHeadlessVideoPlaylist["canceledLabel"]) | undefined;
17787
+ /** What screen readers hear when a move is put back, in a `reorderable`
17788
+ playlist. `{name}` is the entry's words. */
17789
+ canceledLabel?: (HelixHeadlessVideoPlaylist["canceledLabel"]) | undefined;
17790
+ /** What screen readers hear when a moved entry is let go, in a `reorderable`
17791
+ playlist. `{name}` is the entry's words. */
17792
+ "dropped-label"?: (HelixHeadlessVideoPlaylist["droppedLabel"]) | undefined;
17793
+ /** What screen readers hear when a moved entry is let go, in a `reorderable`
17794
+ playlist. `{name}` is the entry's words. */
17795
+ droppedLabel?: (HelixHeadlessVideoPlaylist["droppedLabel"]) | undefined;
17736
17796
  /** What the playlist says while it has no entries. The `empty` slot replaces it. */
17737
17797
  "empty-label"?: (HelixHeadlessVideoPlaylist["emptyLabel"]) | undefined;
17738
17798
  /** What the playlist says while it has no entries. The `empty` slot replaces it. */
17739
17799
  emptyLabel?: (HelixHeadlessVideoPlaylist["emptyLabel"]) | undefined;
17740
17800
  /** The list's name, read by screen readers. */
17741
17801
  label?: (HelixHeadlessVideoPlaylist["label"]) | undefined;
17802
+ /** What screen readers hear each time a key moves an entry, in a
17803
+ `reorderable` playlist. `{name}` is the entry's words, `{position}` its
17804
+ new place, counting from 1, and `{count}` the number of entries. */
17805
+ "moved-label"?: (HelixHeadlessVideoPlaylist["movedLabel"]) | undefined;
17806
+ /** What screen readers hear each time a key moves an entry, in a
17807
+ `reorderable` playlist. `{name}` is the entry's words, `{position}` its
17808
+ new place, counting from 1, and `{count}` the number of entries. */
17809
+ movedLabel?: (HelixHeadlessVideoPlaylist["movedLabel"]) | undefined;
17742
17810
  /** Stays on an entry when its clip ends, where the playlist would otherwise
17743
17811
  play the next one. The player's controls, a press, and `next()` still
17744
17812
  move. `repeat="one"` still plays the entry again. */
@@ -17747,6 +17815,12 @@ move. `repeat="one"` still plays the entry again. */
17747
17815
  play the next one. The player's controls, a press, and `next()` still
17748
17816
  move. `repeat="one"` still plays the entry again. */
17749
17817
  noAdvance?: (HelixHeadlessVideoPlaylist["noAdvance"]) | undefined;
17818
+ /** What screen readers hear when a pointer picks up an entry, in a
17819
+ `reorderable` playlist. `{name}` is the entry's words. */
17820
+ "picked-up-label"?: (HelixHeadlessVideoPlaylist["pickedUpLabel"]) | undefined;
17821
+ /** What screen readers hear when a pointer picks up an entry, in a
17822
+ `reorderable` playlist. `{name}` is the entry's words. */
17823
+ pickedUpLabel?: (HelixHeadlessVideoPlaylist["pickedUpLabel"]) | undefined;
17750
17824
  /** What the live region says when the playlist moves to another entry.
17751
17825
  `{title}` is the entry's name.
17752
17826
 
@@ -17761,6 +17835,10 @@ playlist starts the next one, and the only other trace of that is the
17761
17835
  playlist starts the next one, and the only other trace of that is the
17762
17836
  `aria-current` on a button the reader is not on. */
17763
17837
  playingLabel?: (HelixHeadlessVideoPlaylist["playingLabel"]) | undefined;
17838
+ /** Lets a reader move the entries, with Alt and the arrow keys or by
17839
+ dragging one. The playlist moves no entry itself: you move your entries
17840
+ on `helix-reorder`. */
17841
+ reorderable?: (HelixHeadlessVideoPlaylist["reorderable"]) | undefined;
17764
17842
  /** What happens when an entry ends with no next one to go to. `one` plays the
17765
17843
  same entry again, and `all` goes from the last entry back to the first.
17766
17844
  Absent, the playlist stops on the last entry and sends `helix-end`.
@@ -17797,8 +17875,12 @@ export type HelixHeadlessVideoPlaylistVueEvents = {
17797
17875
  "helix-activate": HelixHeadlessVideoPlaylistHelixActivateElementEvent;
17798
17876
  /** The current entry is about to change, and `detail.cause` says why: `press`, `next`, `previous`, `ended`, or `removed`. Cancelable: cancel it to keep the current entry. */
17799
17877
  "helix-before-activate": HelixHeadlessVideoPlaylistHelixBeforeActivateElementEvent;
17878
+ /** An entry was moved to a new place, in a `reorderable` playlist, with every entry's value in the new order in `detail.keys`. Cancelable: cancel it to keep the entry where it is. */
17879
+ "helix-before-reorder": HelixHeadlessVideoPlaylistHelixBeforeReorderElementEvent;
17800
17880
  /** The last entry finished playing, and the playlist stopped there. Not sent while `repeat` is set. */
17801
17881
  "helix-end": HelixHeadlessVideoPlaylistHelixEndElementEvent;
17882
+ /** Fired after `helix-before-reorder` when nobody canceled it. Move your entries to the order in `keys`. Cancelable: cancel it to say the move did not happen. */
17883
+ "helix-reorder": HelixHeadlessVideoPlaylistHelixReorderElementEvent;
17802
17884
  };
17803
17885
 
17804
17886
  /** `HelixHeadlessVideo` component event */
@@ -18708,7 +18790,7 @@ export interface WcToolkitVueGlobalComponents {
18708
18790
  HelixHeadlessButtonVueProps,
18709
18791
  HelixHeadlessButtonVueEvents
18710
18792
  >;
18711
- /** 'tone' is on the headless tier because it carries meaning. It picks the icon and the icon region's accessible name, so a screen reader announces "Error" for an error callout whether or not the color is seen. Set 'tone-label' to say the name in another language. The icon is the fallback content of a slot. Slot your own icon to replace it, and the default disappears with no extra check. The tone's name stays on the region around it. Set 'dismissible' for a note a reader may put away, as Shoelace's 'closable' alert does. The button fires 'helix-dismiss' and the callout stays until a listener removes it, so the page decides whether it comes back. A callout sets a passage apart inside a document and is read where it sits. For page-level chrome above the masthead that is a live region and can be dismissed, use 'Announcement'. */
18793
+ /** 'tone' is on the headless tier because it carries meaning. It picks the icon and the icon region's accessible name, so a screen reader announces "Error" for an error callout whether or not the color is seen. Set 'tone-label' to say the name in another language. The icon is the fallback content of a slot. Slot your own icon to replace it, and the default disappears with no extra check. The tone's name stays on the region around it. Set 'dismissible' for a note a reader may put away, as Shoelace's 'closable' alert does. The button fires 'helix-dismiss', and unless a listener cancels it the callout hides itself: 'open' turns false, ':state(exiting)' holds while its exit animations run, and then it is 'hidden'. Remove it in your listener to take it out of the page, or set 'open' to show it again, which holds ':state(entering)' while it comes back. Focus on its dismiss button moves to the next callout's, or to the tab stop beside it, once it hides. A callout sets a passage apart inside a document and is read where it sits. For page-level chrome above the masthead that is a live region and can be dismissed, use 'Announcement'. */
18712
18794
  "helix-headless-callout": DefineCustomElement<
18713
18795
  HelixHeadlessCallout,
18714
18796
  HelixHeadlessCalloutVueProps,
@@ -18774,7 +18856,7 @@ export interface WcToolkitVueGlobalComponents {
18774
18856
  HelixHeadlessCheckboxVueProps,
18775
18857
  HelixHeadlessCheckboxVueEvents
18776
18858
  >;
18777
- /** 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 'mark-lines' to mark lines a reader should look at, such as '2, 4-6': the block draws a band behind each run, placed where the lines are laid out, so it follows a highlighter's markup and lines that wrap. Set 'wrap' to wrap long lines rather than scroll them; a gutter then numbers each line where it starts. Set 'wrappable' for a button in the header that turns 'wrap' on and off, pressed while the lines wrap. The header holds the name, the 'actions' slot, and the copy button. Slot a control into 'actions', such as a button that sets 'wrap' or one that opens the code in an editor, and the block draws a header for it even with no name. 'copy-icon' and 'copied-icon' replace the copy button's two icons. 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. **A block that scrolls is a tab stop.** While its lines run past its width or its cap, the scroller is a region named for the block, such as "Code, app.ts", that Tab reaches, so a keyboard scrolls it with the arrow keys in every browser. Chromium and Firefox make a scrolling box focusable on their own, and Safari does not. A block that fits is no stop at all. **The code the block draws is marked untranslated**, 'translate="no"' on its '<pre>', so a page translator leaves highlighted lines and a diff as written. Code in the slot takes its translation mode from the element, which writes nothing onto itself, so set 'translate="no"' on the element to keep a translator off plain code too. 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. */
18859
+ /** 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 'mark-lines' to mark lines a reader should look at, such as '2, 4-6': the block draws a band behind each run, placed where the lines are laid out, so it follows a highlighter's markup and lines that wrap. Set 'wrap' to wrap long lines rather than scroll them; a gutter then numbers each line where it starts. Set 'wrappable' for a button in the header that turns 'wrap' on and off, pressed while the lines wrap. The header holds the name, the 'actions' slot, and the copy button. Slot a control into 'actions', such as a button that sets 'wrap' or one that opens the code in an editor, and the block draws a header for it even with no name. 'copy-icon' and 'copied-icon' replace the copy button's two icons. 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. Where a removed line is paired with the added line that replaced it, the words each does not share with the other are the 'changed' part, so the eye goes to what changed within the line. 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. 'context-lines' folds each long run of unchanged lines, keeping that many beside each change, behind a button that shows them and hides them again, as a code host draws a diff written with more context than a reader needs. **A block that scrolls is a tab stop.** While its lines run past its width or its cap, the scroller is a region named for the block, such as "Code, app.ts", that Tab reaches, so a keyboard scrolls it with the arrow keys in every browser. Chromium and Firefox make a scrolling box focusable on their own, and Safari does not. A block that fits is no stop at all. **The code the block draws is marked untranslated**, 'translate="no"' on its '<pre>', so a page translator leaves highlighted lines and a diff as written. Code in the slot takes its translation mode from the element, which writes nothing onto itself, so set 'translate="no"' on the element to keep a translator off plain code too. 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. */
18778
18860
  "helix-headless-code-block": DefineCustomElement<
18779
18861
  HelixHeadlessCodeBlock,
18780
18862
  HelixHeadlessCodeBlockVueProps,
@@ -18792,13 +18874,13 @@ export interface WcToolkitVueGlobalComponents {
18792
18874
  HelixHeadlessColorInputVueProps,
18793
18875
  HelixHeadlessColorInputVueEvents
18794
18876
  >;
18795
- /** The picker on its own, with no field around it, for a settings pane or a toolbar. Color Input shows this element in a panel behind a text field. The saturation and brightness square is two '<input type="range">' elements, laid over the square and made invisible, and the handle is drawn from their values. The keyboard behavior, the announcements, and the touch targets come from the platform, and there is no 'role="application"'. The picker works in HSB and derives the value from it. A value set from outside is read into the model once. Black is 'brightness: 0', which has no hue or saturation, so a model read back from the value would turn red into gray after you drag to the bottom of the square and back. The square is one tab stop. In it, the up and down arrows move brightness and the left and right arrows move saturation, and PageUp and PageDown move brightness by ten. The picker sends 'input' as the color moves and 'change' when a drag, a key, a typed value or a preset settles it, as '<input type="color">' does. A screen reader hears the color's name, such as "vibrant red", after the two numbers on the square and after the number on the hue ramp, and each preset is named by its color. The opacity ramp is heard as a percentage. Set 'color-words' to speak the names in another language. 'label' names the picker, which is then a group with that name, and the square's ramps say it before their own, as "Brand, Saturation". 'hint' writes help under the picker, which the square, the ramps and the value field are described by. Inside Color Input the field carries both. The presets are a listbox with the current color selected, and one tab stop. The arrow keys move between them, Home and End go to the ends, and Enter, Space or a press chooses one. */
18877
+ /** The picker on its own, with no field around it, for a settings pane or a toolbar. Color Input shows this element in a panel behind a text field. The saturation and brightness square is two '<input type="range">' elements, laid over the square and made invisible, and the handle is drawn from their values. The keyboard behavior, the announcements, and the touch targets come from the platform, and there is no 'role="application"'. The picker works in HSB and derives the value from it. A value set from outside is read into the model once. Black is 'brightness: 0', which has no hue or saturation, so a model read back from the value would turn red into gray after you drag to the bottom of the square and back. The square is one tab stop. In it, the up and down arrows move brightness and the left and right arrows move saturation, by ten with Shift. PageUp and PageDown move brightness by ten, and Home and End move saturation by ten, turned on a right-to-left page as the arrows are, as React Aria's ColorArea does. The picker sends 'input' as the color moves and 'change' when a drag, a key, a typed value or a preset settles it, as '<input type="color">' does. A screen reader hears the color's name, such as "vibrant red", after the two numbers on the square and after the number on the hue ramp, and each preset is named by its color. The opacity ramp is heard as a percentage. Set 'color-words' to speak the names in another language. 'label' names the picker, which is then a group with that name, and the square's ramps say it before their own, as "Brand, Saturation". 'hint' writes help under the picker, which the square, the ramps and the value field are described by. Inside Color Input the field carries both. The presets are a listbox with the current color selected, and one tab stop. The arrow keys move between them, Home and End go to the ends, and Enter, Space or a press chooses one. */
18796
18878
  "helix-headless-color-picker": DefineCustomElement<
18797
18879
  HelixHeadlessColorPicker,
18798
18880
  HelixHeadlessColorPickerVueProps,
18799
18881
  HelixHeadlessColorPickerVueEvents
18800
18882
  >;
18801
- /** The list is a 'Listbox', which handles filtering, the empty state, the highlight, 'aria-activedescendant', and scrolling an option into view. This element handles the field, the panel, and the communication between them. The typed text and the value are separate. The text is a filter: it narrows the list and is then discarded. The value is the option you choose, and the field then shows that option's text. The filter clears on close, so a reopened combobox starts from the whole list. Focus stays in the text field. The arrow keys move through the list with the listbox's public 'navigate' method. As typing narrows the list, a screen reader hears how many options are left, such as "3 results". Emptying the field and leaving it clears a single choice. **Keyboard.** | Key | What it does | |---|---| | Down, Up | On a closed field, opens the list on the chosen option, or the first or the last. In the open list, moves the highlight, round from the last option to the first. | | Page Down, Page Up | In the open list, moves the highlight by as many options as the list shows at once. | | Enter | Chooses the highlighted option. With nothing left in the list, creates what was typed with 'creatable', or takes it with 'allows-custom-value'. On a closed field, submits the form. | | Escape | Closes the list and puts the chosen words back. On a closed field, a second Escape clears a single choice. | | Tab | Closes the list and moves on. | | Backspace | With 'multiple', on an empty field, removes the last tag. | | Left | With 'multiple', with the caret at the start of the text, moves to the last tag's remove button. Right on a right-to-left page. | | Left, Right on a tag | Move between the tags, and past the last back to the text. | | Delete, Backspace on a tag | Removes the tag. | | Space, Home, End, letters | Edit the text. | **ARIA.** The input is the 'combobox', named by the label, with 'aria-expanded', 'aria-controls' naming the list, 'aria-autocomplete' ('both' with 'suggest', 'list' otherwise) and 'aria-activedescendant' on the highlighted option. The list is the listbox 'Listbox' describes. On Apple devices, where VoiceOver does not read the option the field points to, the field says it in a live region as the highlight moves, says how many options there are as the list opens, and says a choice once it is made, as React Aria's combobox does there. Set 'autocomplete' to let a browser's autofill choose an option. With 'multiple', each chosen option is a tag in the field with its own remove control. The text is the field's one tab stop, and the arrow keys reach the tags from it. The panel stays open and the filter clears after each choice, so the next choice starts from the whole list. With 'creatable', the combobox offers a create row and fires 'helix-create'. It does not add the option. The options are your light DOM, and your framework would re-render over an element the combobox inserted, so add the option in your event handler. */
18883
+ /** The list is a 'Listbox', which handles filtering, the empty state, the highlight, 'aria-activedescendant', and scrolling an option into view. This element handles the field, the panel, and the communication between them. The typed text and the value are separate. The text is a filter: it narrows the list and is then discarded. The value is the option you choose, and the field then shows that option's text. The filter clears on close, so a reopened combobox starts from the whole list. Focus stays in the text field. The arrow keys move through the list with the listbox's public 'navigate' method. As typing narrows the list, a screen reader hears how many options are left, such as "3 results". Emptying the field and leaving it clears a single choice. **Keyboard.** | Key | What it does | |---|---| | Down, Up | On a closed field, opens the list on the chosen option, or the first or the last. In the open list, moves the highlight, round from the last option to the first. | | Alt with Down, Alt with Up | Opens the list without moving the highlight, and closes it, choosing nothing. | | Page Down, Page Up | In the open list, moves the highlight by as many options as the list shows at once. | | Enter | Chooses the highlighted option. With nothing left in the list, creates what was typed with 'creatable', or takes it with 'allows-custom-value'. On a closed field, submits the form. | | Escape | Closes the list and puts the chosen words back. On a closed field, a second Escape clears a single choice. | | Tab | Closes the list and moves on. | | Backspace | With 'multiple', on an empty field, removes the last tag. | | Left | With 'multiple', with the caret at the start of the text, moves to the last tag's remove button. Right on a right-to-left page. | | Left, Right on a tag | Move between the tags, and past the last back to the text. | | Delete, Backspace on a tag | Removes the tag. | | Space, Home, End, letters | Edit the text. | **ARIA.** The input is the 'combobox', named by the label, with 'aria-expanded', 'aria-controls' naming the list, 'aria-autocomplete' ('both' with 'suggest', 'list' otherwise) and 'aria-activedescendant' on the highlighted option. The list is the listbox 'Listbox' describes. On Apple devices, where VoiceOver does not read the option the field points to, the field says it in a live region as the highlight moves, says how many options there are as the list opens, and says a choice once it is made, as React Aria's combobox does there. Set 'autocomplete' to let a browser's autofill choose an option. With 'multiple', each chosen option is a tag in the field with its own remove control. The text is the field's one tab stop, and the arrow keys reach the tags from it. The panel stays open and the filter clears after each choice, so the next choice starts from the whole list. With 'creatable', the combobox offers a create row and fires 'helix-create'. It does not add the option. The options are your light DOM, and your framework would re-render over an element the combobox inserted, so add the option in your event handler. */
18802
18884
  "helix-headless-combobox": DefineCustomElement<
18803
18885
  HelixHeadlessCombobox,
18804
18886
  HelixHeadlessComboboxVueProps,
@@ -19140,7 +19222,7 @@ export interface WcToolkitVueGlobalComponents {
19140
19222
  HelixHeadlessNotificationsVueProps,
19141
19223
  HelixHeadlessNotificationsVueEvents
19142
19224
  >;
19143
- /** A separate family from 'Input''s 'type="number"'. It renders two buttons, binds four keys 'Input' does not, and handles clamping and stepping. The field is 'type="text"' with 'inputmode="decimal"'. Tested in a real browser, 'type="number"' fails in three ways: - Typing '12e' gives a '.value' of '""', so the element cannot see what you typed. A 'type="text"' field keeps '"12e"'. - The mouse wheel over a focused field changes the value, for example from 5 to 4, when you only meant to scroll the page. - 'selectionStart' is 'null', so the caret cannot be managed. 'inputmode="decimal"' keeps the numeric keypad on phones. 'format-options' shows the number with 'Intl.NumberFormat' in 'locale', as a currency, a percent or a unit, while the field is not being edited. Focus shows the number itself, and a typed '$1,200' or '25%' is read back with the same options. The value stays the plain number: '1200', or '0.25' for 25%. The locale's group separators are read in every field, so '1,234' is a number in 'en-US'. The field and its two buttons sit in a 'role="group"' named by the label, and the field carries 'role-label', "number field" in English, as its 'aria-roledescription', as React Aria's NumberField does. On iOS and iPadOS the field is a plain text field, with no 'role="spinbutton"', which VoiceOver reads as a slider you cannot type in, and no role description, so VoiceOver says the field is required. React Aria's NumberField does the same. Validity follows the platform's rules: 'min', 'max', and 'step' are checked and reported through the host's own 'setValidity', under the platform's flag names. Stepping is separate from typing, so a number is not corrected while you type it. While you type, the form holds the number the text reads as, so a field showing '$2,500.50' gives the form 2500.5, and text that is not a number gives it nothing, as a native number field does. Holding a stepper button down steps once, then again after 400 milliseconds, then every 60 milliseconds until you let go, as React Aria's NumberField does. **Keyboard.** The field is one tab stop, and the stepper buttons are not in the tab order. | Key | What it does | |---|---| | Up, Down | Steps the value up or down by 'step'. | | Page Up, Page Down | Steps by 'large-step' steps, ten by default. | | Home, End | Goes to 'min' or 'max', where there is one. Without one, moves the caret. | | Enter | Commits the typed number and submits the form, as a native field does. | The field has 'role="spinbutton"' with 'aria-valuenow', 'aria-valuemin', 'aria-valuemax', and the formatted text in 'aria-valuetext'. */
19225
+ /** A separate family from 'Input''s 'type="number"'. It renders two buttons, binds four keys 'Input' does not, and handles clamping and stepping. The field is 'type="text"' with an 'inputmode' for a number. Tested in a real browser, 'type="number"' fails in three ways: - Typing '12e' gives a '.value' of '""', so the element cannot see what you typed. A 'type="text"' field keeps '"12e"'. - The mouse wheel over a focused field changes the value, for example from 5 to 4, when you only meant to scroll the page. - 'selectionStart' is 'null', so the caret cannot be managed. 'inputmode' keeps a numeric keypad on phones, chosen as React Aria's NumberField chooses it: a keypad with a minus key where the number can be negative, and one with a decimal separator where the format shows a fraction. An iPhone has no keypad with a minus key, so a field that can be negative takes the full keyboard there. 'format-options' shows the number with 'Intl.NumberFormat' in 'locale', as a currency, a percent or a unit, while the field is not being edited. Focus shows the number itself, and a typed '$1,200' or '25%' is read back with the same options. The value stays the plain number: '1200', or '0.25' for 25%. The locale's group separators are read in every field, so '1,234' is a number in 'en-US'. The field and its two buttons sit in a 'role="group"' named by the label, and the field carries 'role-label', "number field" in English, as its 'aria-roledescription', as React Aria's NumberField does. On iOS and iPadOS the field is a plain text field, with no 'role="spinbutton"', which VoiceOver reads as a slider you cannot type in, and no role description, so VoiceOver says the field is required. React Aria's NumberField does the same. Validity follows the platform's rules: 'min', 'max', and 'step' are checked and reported through the host's own 'setValidity', under the platform's flag names. Stepping is separate from typing, so a number is not corrected while you type it. While you type, the form holds the number the text reads as, so a field showing '$2,500.50' gives the form 2500.5, and text that is not a number gives it nothing, as a native number field does. Holding a stepper button down steps once, then again after 400 milliseconds, then every 60 milliseconds until you let go, as React Aria's NumberField does. **Keyboard.** The field is one tab stop, and the stepper buttons are not in the tab order. | Key | What it does | |---|---| | Up, Down | Steps the value up or down by 'step'. | | Page Up, Page Down | Steps by 'large-step' steps, ten by default. | | Home, End | Goes to 'min' or 'max', where there is one. Without one, moves the caret. | | Enter | Commits the typed number and submits the form, as a native field does. | The field has 'role="spinbutton"' with 'aria-valuenow', 'aria-valuemin', 'aria-valuemax', and the formatted text in 'aria-valuetext'. */
19144
19226
  "helix-headless-number-input": DefineCustomElement<
19145
19227
  HelixHeadlessNumberInput,
19146
19228
  HelixHeadlessNumberInputVueProps,
@@ -19350,7 +19432,7 @@ export interface WcToolkitVueGlobalComponents {
19350
19432
  HelixHeadlessTableColumnVueProps,
19351
19433
  HelixHeadlessTableColumnVueEvents
19352
19434
  >;
19353
- /** Lays out the rows on a CSS grid, so every column lines up across rows and each row stays a real element that can be styled, hidden, or made interactive. A '<table>' layout aligns columns but limits almost everything else. A grid of elements has no table structure for assistive technology, so the roles are set explicitly: 'table', 'row', 'cell', 'columnheader', and 'rowheader' for a 'header' cell in a row of values. Rows are 'display: contents', so their cells become items of the one grid. **Sorting.** A column with 'sortable' and a 'field' draws its heading as a button that sorts the rows by the text of its cells, numbers by their value. Your markup is not reordered: the table draws the rows in the sorted order. 1. Each press cycles the column through ascending, descending, and the order the rows were written in, which keeps a server's own ranking reachable. 2. 'helix-sort' asks first, with 'field:direction', or empty for the written order. Refuse it to keep the order, or to sort the rows yourself and set 'sort'. 3. 'helix-sorted' follows once the order stands, and 'sort' holds it. 4. The heading carries 'aria-sort', and a screen reader hears 'sorted-label' ("Sorted by Name, ascending") or 'unsorted-label' from a polite region. Tab reaches each sort button, and Enter or Space presses it. The 'heading' slot names the table: slot a heading or a line of text into it, and the table is named by its words. An 'aria-label' or 'aria-labelledby' on the host wins over it. **Selecting.** 'selectable' adds a column of checkboxes. 1. Each row is known by its 'value', or by its place among the rows where it has none, and 'selected' holds the chosen keys, comma separated, the same shape 'DataTable' uses. 'default-selected' is where it starts. 2. A row's checkbox is named by 'select-row-label' ("Select {row}") with the words of the row's first cell. The checkbox in the heading selects every row, and shows a dash while only some are chosen. 3. 'helix-select' asks first, with every key the change would leave. Refuse it to keep the selection. 'helix-selected' follows once it stands. 4. A chosen row takes ':state(selected)', and a screen reader hears 'selected-label' ("2 selected") from a polite region. Tab reaches each checkbox, and Space ticks it. To act on one row, put a link or a button in a cell, or give the row an 'href'. 'selection-mode="single"' selects one row at a time: ticking a row lets go of the one before, the heading holds no checkbox, and Shift and Control with A take in nothing more. 'selection-behavior="replace"' makes a press on a row, anywhere but its own controls, select it alone, as a file list does, and in a 'grid' table the arrow keys carry the selection with them. Control or Command with a press adds or takes out the row, and with an arrow moves without selecting. Shift with a press takes in the rows from the one last chosen. **Nesting rows.** A row with 'parent' sits under the row of that key, as a file sits in a folder. The table then draws a column of disclosure buttons, under a heading named by 'expand-column-label': a row with rows under it has a button named by 'expand-row-label' ("Expand {row}") that says with 'aria-expanded' whether it is open, and the rows under a shut row are not drawn. 'expanded' holds the open rows' keys, comma separated, and 'default-expanded' is where it starts. A press asks with 'helix-before-toggle' and tells with 'helix-toggle', both from the row, so you can refuse it or load the rows on the way. A sort orders the rows under each row among themselves, and in a 'grid' table the table is a 'treegrid' whose rows say their depth. **Moving rows.** 'reorderable' adds a column of grips before the checkboxes, under a heading named by 'row-grips-label'. 1. Each row is known by its 'value', or by its place among the rows where it has none, as for selecting. Give rows a 'value' when they move, so a key stays with its row. 2. A grip is a button named by 'move-row-label' ("Move {row}") with the words of the row's first cell. Drag it to move its row, and the page scrolls near an edge. Or press it with Space, Enter, or a click to pick the row up, move it with Up, Down, Home, and End, and press it again to drop it. A click on another row drops it there, and Escape puts it back. 3. 'helix-before-reorder' asks first, and 'helix-reorder' follows with 'keys', every row's key in the new order. **You move the rows**: the table moves no element of yours, and focus goes back to the moved row's grip once you have. 4. Each step is said in the table's live region, in words you can change: 'picked-up-label', 'moved-label', 'dropped-label', and 'canceled-label'. The grips do nothing while a sort is set. **A grid.** 'grid' makes the table one tab stop that the arrow keys move through cell by cell, the headings included, as React Aria's table is. The table is then a 'grid' and each value a 'gridcell', and the table gives every cell a 'tabindex' so focus can rest on it: set 'grid' only where the cells may carry one. | Key | What it does | |---|---| | Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. | | Down, Up | Moves one row, the headings included. | | Home, End | Moves to the first or the last cell of the row. | | Control with Home or End | Moves to the first or the last cell of the table. | | Page Down, Page Up | Moves by the rows that fit in view. | | Enter, F2 | Moves into the cell's links and controls. Escape or F2 moves back to the cell, and Tab moves between the controls of one cell. | | Enter on a cell of a row with 'href' | Follows the row's link. | | Enter, Space on a sortable heading | Sorts by the column. | | Space on a row, Enter or Space on its checkbox cell | Selects the row, in a 'selectable' table. | | Enter or Space on a disclosure cell | Shows or hides the rows under the row, in a table whose rows nest. | | Enter or Space on a grip cell | Picks the row up, or drops it, in a 'reorderable' table. Up, Down, Home, and End move a row picked up, and Escape puts it back. | | Down, Up, Page Down, Page Up under 'selection-behavior="replace"' | Selects the row it moves to alone. Control or Command with the key moves without selecting. | | Shift with Down or Up | Selects the rows it moves across, in a 'selectable' table. | | Shift with Space | Selects every row from the one last chosen, in a 'selectable' table. | | Control or Command with A | Selects every row, in a 'selectable' table. | | A letter or a word | Moves to the next row whose first cell starts with what you typed. | | Tab | Leaves the table. | **Loading more.** 'load-more' sends 'helix-load-more' once the end of the table comes within a screen of view, in the box that scrolls it or the page, once for each number of rows: add rows and it can send it again. Set 'loading' while you fetch, and the table asks for nothing until it clears. When the rows did not load, set 'error-text', such as "The orders did not load", and put a button that tries again in the 'error' slot. The line shows after the rows in place of the empty and loading lines, the live region says it, and the table takes the 'error' state. Clear it once you try again. The CSS custom properties listed for this component are written by it and read by the stylesheet that draws it. Do not set them. Each holds a number the component computes and CSS cannot, so the stylesheet can draw the table without measuring anything. */
19435
+ /** Lays out the rows on a CSS grid, so every column lines up across rows and each row stays a real element that can be styled, hidden, or made interactive. A '<table>' layout aligns columns but limits almost everything else. A grid of elements has no table structure for assistive technology, so the roles are set explicitly: 'table', 'row', 'cell', 'columnheader', and 'rowheader' for a 'header' cell in a row of values. Rows are 'display: contents', so their cells become items of the one grid. **Sorting.** A column with 'sortable' and a 'field' draws its heading as a button that sorts the rows by the text of its cells, numbers by their value. Your markup is not reordered: the table draws the rows in the sorted order. 1. Each press cycles the column through ascending, descending, and the order the rows were written in, which keeps a server's own ranking reachable. 2. 'helix-sort' asks first, with 'field:direction', or empty for the written order. Refuse it to keep the order, or to sort the rows yourself and set 'sort'. 3. 'helix-sorted' follows once the order stands, and 'sort' holds it. 4. The heading carries 'aria-sort', and a screen reader hears 'sorted-label' ("Sorted by Name, ascending") or 'unsorted-label' from a polite region. Tab reaches each sort button, and Enter or Space presses it. The 'heading' slot names the table: slot a heading or a line of text into it, and the table is named by its words. An 'aria-label' or 'aria-labelledby' on the host wins over it. **Selecting.** 'selectable' adds a column of checkboxes. 1. Each row is known by its 'value', or by its place among the rows where it has none, and 'selected' holds the chosen keys, comma separated, the same shape 'DataTable' uses. 'default-selected' is where it starts. 2. A row's checkbox is named by 'select-row-label' ("Select {row}") with the words of the row's first cell. The checkbox in the heading selects every row, and shows a dash while only some are chosen. 3. 'helix-select' asks first, with every key the change would leave. Refuse it to keep the selection. 'helix-selected' follows once it stands. 4. A chosen row takes ':state(selected)', and a screen reader hears 'selected-label' ("2 selected") from a polite region. Tab reaches each checkbox, and Space ticks it. To act on one row, put a link or a button in a cell, or give the row an 'href'. 'selection-mode="single"' selects one row at a time: ticking a row lets go of the one before, the heading holds no checkbox, and Shift and Control with A take in nothing more. 'selection-behavior="replace"' makes a press on a row, anywhere but its own controls, select it alone, as a file list does, and in a 'grid' table the arrow keys carry the selection with them. Control or Command with a press adds or takes out the row, and with an arrow moves without selecting. Shift with a press takes in the rows from the one last chosen. **Nesting rows.** A row with 'parent' sits under the row of that key, as a file sits in a folder. The table then draws a column of disclosure buttons, under a heading named by 'expand-column-label': a row with rows under it has a button named by 'expand-row-label' ("Expand {row}") that says with 'aria-expanded' whether it is open, and the rows under a shut row are not drawn. 'expanded' holds the open rows' keys, comma separated, and 'default-expanded' is where it starts. A press asks with 'helix-before-toggle' and tells with 'helix-toggle', both from the row, so you can refuse it or load the rows on the way. A sort orders the rows under each row among themselves, and in a 'grid' table the table is a 'treegrid' whose rows say their depth. **Moving rows.** 'reorderable' adds a column of grips before the checkboxes, under a heading named by 'row-grips-label'. 1. Each row is known by its 'value', or by its place among the rows where it has none, as for selecting. Give rows a 'value' when they move, so a key stays with its row. 2. A grip is a button named by 'move-row-label' ("Move {row}") with the words of the row's first cell. Drag it to move its row, and the page scrolls near an edge. Or press it with Space, Enter, or a click to pick the row up, move it with Up, Down, Home, and End, and press it again to drop it. A click on another row drops it there, and Escape puts it back. 3. 'helix-before-reorder' asks first, and 'helix-reorder' follows with 'keys', every row's key in the new order. **You move the rows**: the table moves no element of yours, and focus goes back to the moved row's grip once you have. 4. Each step is said in the table's live region, in words you can change: 'picked-up-label', 'moved-label', 'dropped-label', and 'canceled-label'. The grips do nothing while a sort is set. **A grid.** 'grid' makes the table one tab stop that the arrow keys move through cell by cell, the headings included, as React Aria's table is. The table is then a 'grid' and each value a 'gridcell', and the table gives every cell a 'tabindex' so focus can rest on it: set 'grid' only where the cells may carry one. | Key | What it does | |---|---| | Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. | | Down, Up | Moves one row, the headings included. | | Home, End | Moves to the first or the last cell of the row. | | Control with Home or End | Moves to the first or the last cell of the table. | | Page Down, Page Up | Moves by the rows that fit in view. | | Enter, F2 | Moves into the cell's links and controls. Escape or F2 moves back to the cell, and Tab moves between the controls of one cell. | | Enter on a cell of a row with 'href' | Follows the row's link. | | Enter, Space on a sortable heading | Sorts by the column. | | Space on a row, Enter or Space on its checkbox cell | Selects the row, in a 'selectable' table. | | Enter or Space on a disclosure cell | Shows or hides the rows under the row, in a table whose rows nest. | | Right on a disclosure cell | Shows the rows under a shut row, and otherwise moves one cell along the row. Left does, on a right-to-left page. | | Left on a disclosure cell | Hides the rows under an open row, and moves to the row this one sits under from any other. | | Enter or Space on a grip cell | Picks the row up, or drops it, in a 'reorderable' table. Up, Down, Home, and End move a row picked up, and Escape puts it back. | | Down, Up, Page Down, Page Up under 'selection-behavior="replace"' | Selects the row it moves to alone. Control or Command with the key moves without selecting. | | Shift with Down or Up | Selects the rows it moves across, in a 'selectable' table. | | Shift with Space | Selects every row from the one last chosen, in a 'selectable' table. | | Control or Command with A | Selects every row, in a 'selectable' table. | | A letter or a word | Moves to the next row whose first cell starts with what you typed. | | Tab | Leaves the table. | **Loading more.** 'load-more' sends 'helix-load-more' once the end of the table comes within a screen of view, in the box that scrolls it or the page, once for each number of rows: add rows and it can send it again. Set 'loading' while you fetch, and the table asks for nothing until it clears. When the rows did not load, set 'error-text', such as "The orders did not load", and put a button that tries again in the 'error' slot. The line shows after the rows in place of the empty and loading lines, the live region says it, and the table takes the 'error' state. Clear it once you try again. The CSS custom properties listed for this component are written by it and read by the stylesheet that draws it. Do not set them. Each holds a number the component computes and CSS cannot, so the stylesheet can draw the table without measuring anything. */
19354
19436
  "helix-headless-table": DefineCustomElement<
19355
19437
  HelixHeadlessTable,
19356
19438
  HelixHeadlessTableVueProps,
@@ -19506,7 +19588,7 @@ export interface WcToolkitVueGlobalComponents {
19506
19588
  HelixHeadlessVideoPlaylistMenuVueProps,
19507
19589
  HelixHeadlessVideoPlaylistMenuVueEvents
19508
19590
  >;
19509
- /** **You slot the player**, so it keeps your appearance, extra controls, captions, and poster treatment. 'Sandbox' takes its preview and 'Menu' its trigger the same way. **Entries are markup.** React skips properties it would set imperatively during hydration, so an array property on a custom element is missing on the first paint of a server-rendered page. 'using-the-elements.mdx' has the measurement. Markup also makes each entry a real button with its name inside. **The playlist does not play media.** It sets 'src' on the player and tracks which entry is current. The current entry moves when: - an entry is pressed, - the player dispatches 'helix-next' or 'helix-previous', or - the player reaches the end. On 'ended' the playlist advances and the next clip starts playing, because the user already pressed play once. 'no-advance' turns that off, and the playlist stays on the entry that ended. 'repeat' decides what happens at the end: 'one' plays the same entry again, and 'all' goes from the last entry back to the first. Without it, the playlist stops on the last entry and sends 'helix-end'. 'shuffle' plays the entries in a random order, starting from the one that is current, and 'previous' retraces that order. **'helix-before-activate' says why the playlist is moving**, in 'detail.cause': 'press' for an entry or a menu choice, 'next' and 'previous' for the player's controls and the methods, 'ended' at the end of a clip, and 'removed' when the current entry leaves the playlist. Cancel an 'ended' move to show your own "Up next" countdown, then call 'next()'. **Removing the current entry moves the playlist on**, to the entry after it, or to the one before it when it was the last. A clip that was playing keeps playing in the entry that takes its place. **The player is named by the current entry**, and the device's own media controls show the entry as the title. A player you gave a 'label' keeps your name, and only the title follows the entry. **Keyboard.** The entries take one stop in the tab order: the entry you last focused, or the current entry before you have focused one. Enter or Space plays it. The arrow keys move focus to the entry before or after, and Home and End to the first and the last, passing over disabled entries. The current entry carries 'aria-current'. While focus is on the player, the player's own keys work, and 'Video' lists them, and Shift with N or P plays the next or the previous entry. The player's previous and next controls move through the entries in the same order the playlist does. **What a screen reader hears.** A list named by 'label', with a button for each entry. When the playlist moves to another entry, by a press, by the player's controls, or at the end of a clip, a live region says 'playing-label', "Now playing" and the entry's name. */
19591
+ /** **You slot the player**, so it keeps your appearance, extra controls, captions, and poster treatment. 'Sandbox' takes its preview and 'Menu' its trigger the same way. **Entries are markup.** React skips properties it would set imperatively during hydration, so an array property on a custom element is missing on the first paint of a server-rendered page. 'using-the-elements.mdx' has the measurement. Markup also makes each entry a real button with its name inside. **The playlist does not play media.** It sets 'src' on the player and tracks which entry is current. The current entry moves when: - an entry is pressed, - the player dispatches 'helix-next' or 'helix-previous', or - the player reaches the end. On 'ended' the playlist advances and the next clip starts playing, because the user already pressed play once. 'no-advance' turns that off, and the playlist stays on the entry that ended. 'repeat' decides what happens at the end: 'one' plays the same entry again, and 'all' goes from the last entry back to the first. Without it, the playlist stops on the last entry and sends 'helix-end'. 'shuffle' plays the entries in a random order, starting from the one that is current, and 'previous' retraces that order. **'helix-before-activate' says why the playlist is moving**, in 'detail.cause': 'press' for an entry or a menu choice, 'next' and 'previous' for the player's controls and the methods, 'ended' at the end of a clip, and 'removed' when the current entry leaves the playlist. Cancel an 'ended' move to show your own "Up next" countdown, then call 'next()'. **Removing the current entry moves the playlist on**, to the entry after it, or to the one before it when it was the last. A clip that was playing keeps playing in the entry that takes its place. **The player is named by the current entry**, and the device's own media controls show the entry as the title. A player you gave a 'label' keeps your name, and only the title follows the entry. **Keyboard.** The entries take one stop in the tab order: the entry you last focused, or the current entry before you have focused one. Enter or Space plays it. The arrow keys move focus to the entry before or after, and Home and End to the first and the last, passing over disabled entries. The current entry carries 'aria-current'. While focus is on the player, the player's own keys work, and 'Video' lists them, and Shift with N or P plays the next or the previous entry. The player's previous and next controls move through the entries in the same order the playlist does. **Moving entries.** 'reorderable' lets a reader change the order of the queue: - Alt with Up or Down moves the focused entry a place, and Alt with Home or End moves it to either end, as the APG's rearrangeable listbox does. Focus stays on it. - A pointer drags an entry, with a drop indicator, and the page scrolls near an edge. A press that does not travel still plays the entry. - A drop sends 'helix-before-reorder', which you can refuse, and then 'helix-reorder', whose 'keys' hold every entry's 'value' in the new order. **You move the entries**: the playlist moves no element of yours, and the next entry is the one after the current entry in the order you leave. - Each move is said in the live region, in words you can change: 'moved-label', 'dropped-label', 'canceled-label', and 'picked-up-label'. **What a screen reader hears.** A list named by 'label', with a button for each entry. When the playlist moves to another entry, by a press, by the player's controls, or at the end of a clip, a live region says 'playing-label', "Now playing" and the entry's name. */
19510
19592
  "helix-headless-video-playlist": DefineCustomElement<
19511
19593
  HelixHeadlessVideoPlaylist,
19512
19594
  HelixHeadlessVideoPlaylistVueProps,
package/types/words.d.ts CHANGED
@@ -623,6 +623,21 @@ declare module '@fusion.dev/helix-core' {
623
623
  * English: `Show all lines`
624
624
  */
625
625
  expandLabel: Message
626
+ /**
627
+ * The words of a button that hides a run of unchanged lines it showed, in a
628
+ * diff with `context-lines`. `{count}` is how many, and each language
629
+ * writes the forms it has.
630
+ *
631
+ * English: `{count, plural, one {Hide # unchanged line} other {Hide # unchanged lines}}`
632
+ */
633
+ hideUnchangedLabel: Message
634
+ /**
635
+ * The words of a button that shows a folded run of unchanged lines, in a
636
+ * diff with `context-lines`. `{count}` is how many.
637
+ *
638
+ * English: `{count, plural, one {Show # unchanged line} other {Show # unchanged lines}}`
639
+ */
640
+ showUnchangedLabel: Message
626
641
  /**
627
642
  * The wrap button's name, which it keeps whether it is pressed or not.
628
643
  *
@@ -2460,6 +2475,13 @@ declare module '@fusion.dev/helix-core' {
2460
2475
  * English: `Copy value`
2461
2476
  */
2462
2477
  copyValueLabel: Message
2478
+ /**
2479
+ * What the tree says while there is no value to show, such as before a
2480
+ * fetch answers. The `empty` slot replaces it.
2481
+ *
2482
+ * English: `Nothing to show`
2483
+ */
2484
+ emptyLabel: Message
2463
2485
  /**
2464
2486
  * The filter field's placeholder and accessible name.
2465
2487
  *
@@ -2482,6 +2504,13 @@ declare module '@fusion.dev/helix-core' {
2482
2504
  * English: `{count, plural, one {# key} other {# keys}}`
2483
2505
  */
2484
2506
  keysLabel: Message
2507
+ /**
2508
+ * What the tree says while a filter matched no entry. The `empty` slot
2509
+ * replaces it.
2510
+ *
2511
+ * English: `No matches`
2512
+ */
2513
+ noMatchesLabel: Message
2485
2514
  /**
2486
2515
  * What a screen reader hears when a filter matches entries. `{count}` is
2487
2516
  * how many, written in the locale, and each language writes the forms it
@@ -3629,6 +3658,20 @@ declare module '@fusion.dev/helix-core' {
3629
3658
  volumeLabel: Message
3630
3659
  }
3631
3660
  'helix-video-playlist': {
3661
+ /**
3662
+ * What screen readers hear when a move is put back, in a `reorderable`
3663
+ * playlist. `{name}` is the entry's words.
3664
+ *
3665
+ * English: `Canceled`
3666
+ */
3667
+ canceledLabel: Message
3668
+ /**
3669
+ * What screen readers hear when a moved entry is let go, in a `reorderable`
3670
+ * playlist. `{name}` is the entry's words.
3671
+ *
3672
+ * English: `Dropped`
3673
+ */
3674
+ droppedLabel: Message
3632
3675
  /**
3633
3676
  * What the playlist says while it has no entries. The `empty` slot replaces it.
3634
3677
  *
@@ -3641,6 +3684,21 @@ declare module '@fusion.dev/helix-core' {
3641
3684
  * English: `Playlist`
3642
3685
  */
3643
3686
  label: Message
3687
+ /**
3688
+ * What screen readers hear each time a key moves an entry, in a
3689
+ * `reorderable` playlist. `{name}` is the entry's words, `{position}` its
3690
+ * new place, counting from 1, and `{count}` the number of entries.
3691
+ *
3692
+ * English: `{name} moved to position {position} of {count}`
3693
+ */
3694
+ movedLabel: Message
3695
+ /**
3696
+ * What screen readers hear when a pointer picks up an entry, in a
3697
+ * `reorderable` playlist. `{name}` is the entry's words.
3698
+ *
3699
+ * English: `Picked up {name}`
3700
+ */
3701
+ pickedUpLabel: Message
3644
3702
  /**
3645
3703
  * What the live region says when the playlist moves to another entry.
3646
3704
  * `{title}` is the entry's name.