@fusion.dev/helix-headless 0.149.0 → 0.150.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 (35) hide show
  1. package/custom-elements.json +471 -45
  2. package/dist/button/root/button-root.d.ts +5 -0
  3. package/dist/button/root/button-root.js +3 -0
  4. package/dist/color-input/root/color-input-root.d.ts +1 -0
  5. package/dist/color-picker/root/color-picker-root.js +1 -0
  6. package/dist/combobox/root/combobox-root.d.ts +12 -1
  7. package/dist/combobox/root/combobox-root.js +8 -0
  8. package/dist/copy-button/root/copy-button-root.d.ts +4 -3
  9. package/dist/copy-button/root/copy-button-root.js +5 -1
  10. package/dist/date-input/root/date-input-root.d.ts +1 -0
  11. package/dist/element-events.generated.js +1 -1
  12. package/dist/filter-input/chip/filter-chip.d.ts +2 -1
  13. package/dist/filter-input/root/filter-input-root.d.ts +5 -0
  14. package/dist/filter-input/root/filter-input-root.js +7 -0
  15. package/dist/number-input/root/number-input-root.d.ts +6 -0
  16. package/dist/number-input/root/number-input-root.js +14 -3
  17. package/dist/option/root/option-root.d.ts +17 -8
  18. package/dist/option/root/option-root.js +18 -4
  19. package/dist/radio/group/radio-group.d.ts +8 -1
  20. package/dist/radio/group/radio-group.js +15 -1
  21. package/dist/slider/root/slider-root.d.ts +8 -0
  22. package/dist/slider/root/slider-root.js +6 -3
  23. package/dist/tag/group/tag-group.d.ts +22 -1
  24. package/dist/tag/group/tag-group.js +63 -3
  25. package/dist/tag/root/tag-root.d.ts +9 -0
  26. package/dist/tag/root/tag-root.js +5 -1
  27. package/dist/time-input/root/time-input-root.d.ts +1 -0
  28. package/dist/toggle/group/toggle-group.d.ts +6 -0
  29. package/dist/toggle/group/toggle-group.js +16 -1
  30. package/dist/toggle/root/toggle-root.d.ts +21 -3
  31. package/dist/toggle/root/toggle-root.js +22 -5
  32. package/lint.json +1 -1
  33. package/package.json +7 -7
  34. package/types/jsx.d.ts +160 -58
  35. package/types/vue.d.ts +28 -16
package/types/vue.d.ts CHANGED
@@ -10608,14 +10608,10 @@ between them makes a reader parse the punctuation to find where the name
10608
10608
  ends. Matching still reads the label, so what somebody types is matched
10609
10609
  against the name rather than against prose about it.
10610
10610
 
10611
- **A property and not a slot, which is the departure worth explaining.** The
10612
- area rules say a content property is its slot's fallback, and that holds for
10613
- a region always drawn: `Avatar`'s initials, `Tooltip`'s text. This one is
10614
- usually absent, and a wrapped slot generates a box whether or not it is
10615
- filled, so every option without a caption would carry an empty line. The
10616
- detection that would avoid it does not exist, `:host(:has())` being invalid
10617
- and the server having no children to inspect. A property is known at render
10618
- time, so the component can decline to draw the box at all.
10611
+ For a caption richer than a string, slot it into `description`. The
10612
+ property is that slot's fallback inside the `description` part. With no
10613
+ property the slot is drawn bare, which takes no box while it is empty, so
10614
+ an option without a caption carries no empty line.
10619
10615
 
10620
10616
  It does not reflect, per the rule that payload state stays off the host: a
10621
10617
  string is not a fact a selector needs. */
@@ -10703,6 +10699,13 @@ name is the fault `TreeItem` avoids by mirroring to `data-selected`.
10703
10699
  Splitting them means moving what every stylesheet selects on, which is a
10704
10700
  change of its own rather than a property being added. */
10705
10701
  defaultSelected?: (HelixHeadlessOption["defaultSelected"]) | undefined;
10702
+ /** Whether the option says it is selected while the keyboard is on it.
10703
+
10704
+ Written by a control whose list holds suggestions, such as `FilterInput`:
10705
+ nothing there stays chosen, so the row the keyboard is on is the
10706
+ selection, as the APG combobox's list with selection that follows focus
10707
+ says. No attribute: it is coordination between elements. */
10708
+ selectionFollowsActive?: (HelixHeadlessOption["selectionFollowsActive"]) | undefined;
10706
10709
  };
10707
10710
 
10708
10711
  export type HelixHeadlessOptionVueEvents = {
@@ -13798,6 +13801,13 @@ Absent is the tag's own words, its category first. */
13798
13801
  value?: (HelixHeadlessTag["value"]) | undefined;
13799
13802
  /** Whether the element shows a control that dismisses it. */
13800
13803
  dismissible?: (HelixHeadlessTag["dismissible"]) | undefined;
13804
+ /** Whether the remove button is a tab stop of its own, outside a `Tag.Group`.
13805
+
13806
+ A field that holds tags as its tokens, such as a `multiple` Combobox,
13807
+ writes `false`: the field's text is its one tab stop, and the arrow keys
13808
+ move from the text to the tags. No attribute: it is coordination between
13809
+ elements, as `focusable` is. */
13810
+ dismissTabStop?: (HelixHeadlessTag["dismissTabStop"]) | undefined;
13801
13811
  /** Whether the tag holds its group's tab stop.
13802
13812
 
13803
13813
  Written by `Tag.Group` on every tag it holds, and unset outside one, which
@@ -15035,8 +15045,8 @@ name is the fault `TreeItem` avoids by mirroring to `data-selected`.
15035
15045
  Splitting them means moving what every stylesheet selects on, which is a
15036
15046
  change of its own rather than a property being added. */
15037
15047
  defaultSelected?: (HelixHeadlessToggle["defaultSelected"]) | undefined;
15038
- /** Whether the item holds the group's tab stop. Unset, the chosen item holds
15039
- it.
15048
+ /** Whether the item holds the group's tab stop. Unset, no group holds the
15049
+ item, and it is a toggle button with a tab stop of its own.
15040
15050
 
15041
15051
  Written by the group on every item: `true` for the chosen item, or for the
15042
15052
  first item that can be chosen while there is no selection to carry the
@@ -15053,6 +15063,8 @@ Written by the group, like `selected`, so no attribute. */
15053
15063
  };
15054
15064
 
15055
15065
  export type HelixHeadlessToggleVueEvents = {
15066
+ /** Fired after a toggle button on its own is pressed or released. */
15067
+ change: HelixHeadlessToggleElementEvent;
15056
15068
  /** Fired when the item is chosen. Cancelable: call `preventDefault()` to keep the current choice. */
15057
15069
  "helix-select": HelixHeadlessToggleHelixSelectElementEvent;
15058
15070
  };
@@ -16795,7 +16807,7 @@ export interface WcToolkitVueGlobalComponents {
16795
16807
  HelixHeadlessColorPickerVueProps,
16796
16808
  HelixHeadlessColorPickerVueEvents
16797
16809
  >;
16798
- /** 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. | | 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 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. */
16810
+ /** 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. */
16799
16811
  "helix-headless-combobox": DefineCustomElement<
16800
16812
  HelixHeadlessCombobox,
16801
16813
  HelixHeadlessComboboxVueProps,
@@ -16807,7 +16819,7 @@ export interface WcToolkitVueGlobalComponents {
16807
16819
  HelixHeadlessCommandVueProps,
16808
16820
  HelixHeadlessCommandVueEvents
16809
16821
  >;
16810
- /** 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. */
16822
+ /** 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. The same words are said in a live region, so a screen reader hears the result, and the tooltip shows them. */
16811
16823
  "helix-headless-copy-button": DefineCustomElement<
16812
16824
  HelixHeadlessCopyButton,
16813
16825
  HelixHeadlessCopyButtonVueProps,
@@ -16891,7 +16903,7 @@ export interface WcToolkitVueGlobalComponents {
16891
16903
  HelixHeadlessFileInputVueProps,
16892
16904
  HelixHeadlessFileInputVueEvents
16893
16905
  >;
16894
- /** 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. */
16906
+ /** 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 arrow keys move between the field and the chips, and Delete or Backspace on a chip asks to remove it. 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. */
16895
16907
  "helix-headless-filter-chip": DefineCustomElement<
16896
16908
  HelixHeadlessFilterChip,
16897
16909
  HelixHeadlessFilterChipVueProps,
@@ -16915,7 +16927,7 @@ export interface WcToolkitVueGlobalComponents {
16915
16927
  HelixHeadlessFilterOperatorVueProps,
16916
16928
  HelixHeadlessFilterOperatorVueEvents
16917
16929
  >;
16918
- /** Tokens are your own elements, slotted in. A filter can be a facet with a prefix, a saved query, or a range, and these belong to your model, so the element does not render tokens from a list of strings. Removing a token is a request the element fires, and you apply it. Combobox works the other way: its tokens show a selection it owns, drawn from the options it was given. 'value' is the typed text. Every keystroke fires 'input' with the text on the element, so a table can narrow as the user types. Backspace in an empty field fires 'helix-dismiss' on the last token, the same event its remove control fires, so one handler covers the pointer and the keyboard. **What a form receives.** The text under 'name', and then one more entry under 'name' for each token, in the order the tokens stand: | Token | Entry | |---|---| | Any element with a 'value' attribute | The value as written: 'saved:mine' | | 'FilterChip' with 'name' and values | 'status:open,pending' | | The same, with 'operator="none"' (what a typed '-status:' makes) | '-status:open,pending' | | The same, with any other 'operator' except 'any' | 'created[after]:2024' | | A token with neither | Nothing | The values are the chip's text outside its 'field' and 'operator' slots, with the spaces around each comma removed. A server splits an entry at its first colon, reads a leading '-' as the negation, and reads a word in brackets before the colon as the comparison. **Keyboard.** Focus stays in the text. The text names the highlighted suggestion as its 'aria-activedescendant'. | Key | What it does | |---|---| | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. | | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. | | Home, End | Highlights the first or the last suggestion while the panel is open. | | Escape | Closes the panel and stops there, so a dialog around the field stays open. | | Backspace | In an empty field, asks the last token to go. | **Typed filters.** The field parses only the fields you declare. Write 'FilterField' elements, usually inside the 'FilterMenu' slotted into 'start', so the picker and the text share one set. On Enter, the field reads the text against them. 'disposition:refunded,settled' and '-disposition:refunded' fire 'helix-facet' exactly as ticking those values in the picker would, and the parsed text is removed. Everything else stays, so 'refund tuesday disposition:settled' is a filter and a search at once. Helix defines the punctuation and you define every word. 'grammar.ts' has the full rule, so read it before you rely on it. A field with no 'FilterField' in it parses nothing. A field whose values cannot be listed, such as 'assignee:ada', goes directly inside this element, outside the menu. It is not assigned to a slot, so nothing draws it and the menu has no page for it, and the grammar still reads it. **Suggestions.** Slot options into 'suggestions' and the field shows them, moves through them with the arrow keys, and presses one on Enter. The option fires its own 'helix-select', and you decide what choosing it means. Keys before a colon and values after it use the same panel with different contents. 'filter-suggestions' narrows the panel to the options whose words hold the term at the caret, after its colon, ignoring case and accents, and hides the rest. 'readFilterText' is exported so you can narrow it yourself against partly typed text. While the panel is open, a reader hears how many suggestions it offers. The panel opens when it has options and closes when it has none, and a choice does not close it, so after picking a key you see its values next. Use 'selectionStart' and 'setSelectionRange' to write a completion back and put the caret after it, or the next parse reads the wrong term. **State.** Three things have three different owners: - 'value' is the text. The user types, the element applies it, and 'input' reports it. Setting 'value' seeds or corrects the text, and the next keystroke overwrites it, even in React. To control the value, cancel 'helix-before-change' and write the value you want, as with every field in this library. 'default-value' seeds the field. - 'open' is the suggestions panel. Cancel 'helix-before-open' or 'helix-before-close' to control it, and use 'default-open' to seed it. - Tokens are your elements in a slot and hold no state. A token goes when you remove it from your markup after 'helix-dismiss'. A 'FilterChip' naming a declared field works differently, because the picker holds what is ticked and removing the chip alone would leave its value ticked in the hidden menu. Its dismissal is treated as the field being filtered by nothing, so it fires 'helix-facet' like every other change, and the chip goes when the filter goes. */
16930
+ /** Tokens are your own elements, slotted in. A filter can be a facet with a prefix, a saved query, or a range, and these belong to your model, so the element does not render tokens from a list of strings. Removing a token is a request the element fires, and you apply it. Combobox works the other way: its tokens show a selection it owns, drawn from the options it was given. 'value' is the typed text. Every keystroke fires 'input' with the text on the element, so a table can narrow as the user types. Backspace in an empty field fires 'helix-dismiss' on the last token, the same event its remove control fires, so one handler covers the pointer and the keyboard. **What a form receives.** The text under 'name', and then one more entry under 'name' for each token, in the order the tokens stand: | Token | Entry | |---|---| | Any element with a 'value' attribute | The value as written: 'saved:mine' | | 'FilterChip' with 'name' and values | 'status:open,pending' | | The same, with 'operator="none"' (what a typed '-status:' makes) | '-status:open,pending' | | The same, with any other 'operator' except 'any' | 'created[after]:2024' | | A token with neither | Nothing | The values are the chip's text outside its 'field' and 'operator' slots, with the spaces around each comma removed. A server splits an entry at its first colon, reads a leading '-' as the negation, and reads a word in brackets before the colon as the comparison. **Keyboard.** Focus stays in the text. The text names the highlighted suggestion as its 'aria-activedescendant'. | Key | What it does | |---|---| | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. | | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. | | Home, End | Highlights the first or the last suggestion while the panel is open. | | Escape | Closes the panel and stops there, so a dialog around the field stays open. | | Backspace | In an empty field, asks the last token to go. | | Left | With the caret at the start of the text, moves to the last token's remove button. Right on a right-to-left page. | | Left, Right on a token | Move between the tokens, and past the last back to the text. | | Delete, Backspace on a token | Asks the token to go. | **Typed filters.** The field parses only the fields you declare. Write 'FilterField' elements, usually inside the 'FilterMenu' slotted into 'start', so the picker and the text share one set. On Enter, the field reads the text against them. 'disposition:refunded,settled' and '-disposition:refunded' fire 'helix-facet' exactly as ticking those values in the picker would, and the parsed text is removed. Everything else stays, so 'refund tuesday disposition:settled' is a filter and a search at once. Helix defines the punctuation and you define every word. 'grammar.ts' has the full rule, so read it before you rely on it. A field with no 'FilterField' in it parses nothing. A field whose values cannot be listed, such as 'assignee:ada', goes directly inside this element, outside the menu. It is not assigned to a slot, so nothing draws it and the menu has no page for it, and the grammar still reads it. **Suggestions.** Slot options into 'suggestions' and the field shows them, moves through them with the arrow keys, and presses one on Enter. The option fires its own 'helix-select', and you decide what choosing it means. Keys before a colon and values after it use the same panel with different contents. 'filter-suggestions' narrows the panel to the options whose words hold the term at the caret, after its colon, ignoring case and accents, and hides the rest. 'readFilterText' is exported so you can narrow it yourself against partly typed text. While the panel is open, a reader hears how many suggestions it offers. The panel opens when it has options and closes when it has none, and a choice does not close it, so after picking a key you see its values next. Use 'selectionStart' and 'setSelectionRange' to write a completion back and put the caret after it, or the next parse reads the wrong term. **State.** Three things have three different owners: - 'value' is the text. The user types, the element applies it, and 'input' reports it. Setting 'value' seeds or corrects the text, and the next keystroke overwrites it, even in React. To control the value, cancel 'helix-before-change' and write the value you want, as with every field in this library. 'default-value' seeds the field. - 'open' is the suggestions panel. Cancel 'helix-before-open' or 'helix-before-close' to control it, and use 'default-open' to seed it. - Tokens are your elements in a slot and hold no state. A token goes when you remove it from your markup after 'helix-dismiss'. A 'FilterChip' naming a declared field works differently, because the picker holds what is ticked and removing the chip alone would leave its value ticked in the hidden menu. Its dismissal is treated as the field being filtered by nothing, so it fires 'helix-facet' like every other change, and the chip goes when the filter goes. */
16919
16931
  "helix-headless-filter-input": DefineCustomElement<
16920
16932
  HelixHeadlessFilterInput,
16921
16933
  HelixHeadlessFilterInputVueProps,
@@ -17377,7 +17389,7 @@ export interface WcToolkitVueGlobalComponents {
17377
17389
  HelixHeadlessTabVueProps,
17378
17390
  HelixHeadlessTabVueEvents
17379
17391
  >;
17380
- /** 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". */
17392
+ /** 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. In 'multiple', Shift with an arrow, Home or End selects the range from the tag last pressed to the tag focus moves to, and Control or Command with A selects every tag that is not disabled. '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". Where only disabled tags are left, the first of them holds the tab stop and takes focus, so the reader stays in the set. */
17381
17393
  "helix-headless-tag-group": DefineCustomElement<
17382
17394
  HelixHeadlessTagGroup,
17383
17395
  HelixHeadlessTagGroupVueProps,
@@ -17443,7 +17455,7 @@ export interface WcToolkitVueGlobalComponents {
17443
17455
  HelixHeadlessToggleGroupVueProps,
17444
17456
  HelixHeadlessToggleGroupVueEvents
17445
17457
  >;
17446
- /** Renders a '<button role="radio">' for use as a form control. In a group with 'selection-mode="multiple"' it is a '<button>' that says whether it is pressed with 'aria-pressed'. Do not use it for navigation. For navigation, use links marked with 'aria-current' and styled by the 'data-navigation-item' recipe in the base layer. The recipe has the same look, and links are not announced as choices. */
17458
+ /** Renders a '<button role="radio">' for use as a form control. In a group with 'selection-mode="multiple"' it is a '<button>' that says whether it is pressed with 'aria-pressed'. **On its own, outside a 'Toggle.Group', it is a toggle button**, as React Aria's 'ToggleButton': a '<button>' with 'aria-pressed'. A press, Enter or Space sends 'helix-select', which you can cancel, then flips 'selected' and sends 'change'. Write 'selected' in the markup to start it pressed. Do not use it for navigation. For navigation, use links marked with 'aria-current' and styled by the 'data-navigation-item' recipe in the base layer. The recipe has the same look, and links are not announced as choices. */
17447
17459
  "helix-headless-toggle": DefineCustomElement<
17448
17460
  HelixHeadlessToggle,
17449
17461
  HelixHeadlessToggleVueProps,