@fusion.dev/helix-headless 0.175.0 → 0.176.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.
- package/custom-elements.json +58 -17
- package/dist/filter-input/index.d.ts +0 -1
- package/dist/filter-input/index.js +0 -1
- package/dist/filter-input/menu/filter-menu.d.ts +4 -0
- package/dist/filter-input/menu/index.d.ts +1 -0
- package/dist/filter-input/menu/index.js +1 -0
- package/dist/filter-input/root/filter-input-root.d.ts +26 -2
- package/dist/filter-input/root/filter-input-root.js +39 -5
- package/dist/icon/all/index.d.ts +1 -0
- package/dist/icon/all/index.js +4 -0
- package/dist/icon/root/icon-root.d.ts +9 -8
- package/dist/icon/root/icon-root.js +4 -2
- package/dist/icon/set.js +16 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +52 -32
- package/types/vue.d.ts +7 -9
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-headless",
|
|
3
3
|
"description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.176.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
},
|
|
50
50
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@fusion.dev/helix-core": "0.
|
|
53
|
-
"@fusion.dev/helix-icons": "0.
|
|
52
|
+
"@fusion.dev/helix-core": "0.176.0",
|
|
53
|
+
"@fusion.dev/helix-icons": "0.176.0",
|
|
54
54
|
"uqr": "^0.1.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@fusion.dev/helix-cem": "0.
|
|
58
|
-
"@fusion.dev/helix-testing": "0.
|
|
57
|
+
"@fusion.dev/helix-cem": "0.176.0",
|
|
58
|
+
"@fusion.dev/helix-testing": "0.176.0",
|
|
59
59
|
"@fusion.dev/scripts": "0.0.0-dev",
|
|
60
60
|
"@happy-dom/global-registrator": "^20.14.5",
|
|
61
61
|
"@lit-labs/ssr": "^4.1.0",
|
package/types/jsx.d.ts
CHANGED
|
@@ -16290,12 +16290,10 @@ disagreeing with its own name for every reader who meant the left. */
|
|
|
16290
16290
|
/** The name of the icon in the Helix set.
|
|
16291
16291
|
|
|
16292
16292
|
**A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
16293
|
-
so it is what markup can carry, and resolving one means an index
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
element from `icon/root` and registers the glyphs it names, or hands over
|
|
16298
|
-
the value instead.
|
|
16293
|
+
so it is what markup can carry, and resolving one means an index that no
|
|
16294
|
+
bundler can shake. The family's entry indexes a small set, `icon/all`
|
|
16295
|
+
indexes the whole set at 15 kB, and `icon/root` indexes nothing, for a
|
|
16296
|
+
page that registers the glyphs it names or hands over the value instead.
|
|
16299
16297
|
|
|
16300
16298
|
A name written `prefix:name` asks the library registered under that
|
|
16301
16299
|
prefix. */
|
|
@@ -16339,12 +16337,10 @@ disagreeing with its own name for every reader who meant the left. */
|
|
|
16339
16337
|
/** The name of the icon in the Helix set.
|
|
16340
16338
|
|
|
16341
16339
|
**A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
16342
|
-
so it is what markup can carry, and resolving one means an index
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
element from `icon/root` and registers the glyphs it names, or hands over
|
|
16347
|
-
the value instead.
|
|
16340
|
+
so it is what markup can carry, and resolving one means an index that no
|
|
16341
|
+
bundler can shake. The family's entry indexes a small set, `icon/all`
|
|
16342
|
+
indexes the whole set at 15 kB, and `icon/root` indexes nothing, for a
|
|
16343
|
+
page that registers the glyphs it names or hands over the value instead.
|
|
16348
16344
|
|
|
16349
16345
|
A name written `prefix:name` asks the library registered under that
|
|
16350
16346
|
prefix. */
|
|
@@ -47191,6 +47187,10 @@ export type CustomElements = {
|
|
|
47191
47187
|
* `Notification` does for a read. Call `preventDefault()` on `helix-facet` to
|
|
47192
47188
|
* cancel the change.
|
|
47193
47189
|
*
|
|
47190
|
+
* Imported from its own entry, `@fusion.dev/helix-headless/filter-input/menu`, which registers
|
|
47191
|
+
* it with the `Menu` it draws its pages with. The family's entry leaves it out,
|
|
47192
|
+
* so a field without a picker does not carry `Menu`.
|
|
47193
|
+
*
|
|
47194
47194
|
* ## Attributes & Properties
|
|
47195
47195
|
*
|
|
47196
47196
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
@@ -47445,7 +47445,7 @@ export type CustomElements = {
|
|
|
47445
47445
|
* | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. |
|
|
47446
47446
|
* | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. |
|
|
47447
47447
|
* | Home, End | Highlights the first or the last suggestion while the panel is open. |
|
|
47448
|
-
* | Escape | Closes the panel and stops there, so a dialog around the field stays open. |
|
|
47448
|
+
* | Escape | Closes the panel and stops there, so a dialog around the field stays open. With the panel closed, empties the text. In an empty field, does nothing, so the page hears it. |
|
|
47449
47449
|
* | Backspace | In an empty field, asks the last token to go. |
|
|
47450
47450
|
* | 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. |
|
|
47451
47451
|
* | Left, Right on a token | Move between the tokens, and past the last back to the text. |
|
|
@@ -47454,7 +47454,8 @@ export type CustomElements = {
|
|
|
47454
47454
|
* **Typed filters.** The field parses only the fields you declare. Write
|
|
47455
47455
|
* `FilterField` elements, usually inside the `FilterMenu` slotted into `start`,
|
|
47456
47456
|
* so the picker and the text share one set. On Enter, the field reads the text
|
|
47457
|
-
* against them
|
|
47457
|
+
* against them, and a paste is read the same way as soon as it lands.
|
|
47458
|
+
* `disposition:refunded,settled` and `-disposition:refunded` fire
|
|
47458
47459
|
* `helix-facet` exactly as ticking those values in the picker would, and the
|
|
47459
47460
|
* parsed text is removed. Everything else stays, so `refund tuesday
|
|
47460
47461
|
* disposition:settled` is a filter and a search at once. Helix defines the
|
|
@@ -47467,6 +47468,12 @@ export type CustomElements = {
|
|
|
47467
47468
|
* nothing draws it and the menu has no page for it, and the grammar still reads
|
|
47468
47469
|
* it.
|
|
47469
47470
|
*
|
|
47471
|
+
* **The picker has an entry of its own.** `FilterMenu` draws its pages with
|
|
47472
|
+
* `Menu`, which a field without a picker does not need, so this family's entry
|
|
47473
|
+
* leaves it out. A page that writes one imports
|
|
47474
|
+
* `@fusion.dev/helix/filter-input/menu` as well, and a picker written without it
|
|
47475
|
+
* is reported once the page has loaded, with the entry to add.
|
|
47476
|
+
*
|
|
47470
47477
|
* **Suggestions.** Slot options into `suggestions` and the field shows them,
|
|
47471
47478
|
* moves through them with the arrow keys, and presses one on Enter. The option
|
|
47472
47479
|
* fires its own `helix-select`, and you decide what choosing it means. Keys
|
|
@@ -48987,8 +48994,11 @@ export type CustomElements = {
|
|
|
48987
48994
|
* a dark background. Shapes that set their own `fill` or `stroke` are
|
|
48988
48995
|
* unaffected.
|
|
48989
48996
|
*
|
|
48990
|
-
* **A name is looked up in a registry.** The family's entry registers
|
|
48991
|
-
*
|
|
48997
|
+
* **A name is looked up in a registry.** The family's entry registers a small
|
|
48998
|
+
* set: the four carets, `arrow-left`, `arrow-right`, `check`, `x`, `plus`,
|
|
48999
|
+
* `minus`, `magnifying-glass`, `info` and `warning`. `icon/all` registers the
|
|
49000
|
+
* whole set, so any name in it draws, and a name that resolves to nothing
|
|
49001
|
+
* says to import it. The element's own entry,
|
|
48992
49002
|
* `@fusion.dev/helix-headless/icon/root`, registers none: a page that imports
|
|
48993
49003
|
* it and calls `registerIcons` with the glyphs it names ships those and no
|
|
48994
49004
|
* others. `registerIconLibrary` resolves names under a prefix of your own,
|
|
@@ -49033,12 +49043,10 @@ export type CustomElements = {
|
|
|
49033
49043
|
* - `name`: The name of the icon in the Helix set.
|
|
49034
49044
|
*
|
|
49035
49045
|
* **A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
49036
|
-
* so it is what markup can carry, and resolving one means an index
|
|
49037
|
-
*
|
|
49038
|
-
*
|
|
49039
|
-
*
|
|
49040
|
-
* element from `icon/root` and registers the glyphs it names, or hands over
|
|
49041
|
-
* the value instead.
|
|
49046
|
+
* so it is what markup can carry, and resolving one means an index that no
|
|
49047
|
+
* bundler can shake. The family's entry indexes a small set, `icon/all`
|
|
49048
|
+
* indexes the whole set at 15 kB, and `icon/root` indexes nothing, for a
|
|
49049
|
+
* page that registers the glyphs it names or hands over the value instead.
|
|
49042
49050
|
*
|
|
49043
49051
|
* A name written `prefix:name` asks the library registered under that
|
|
49044
49052
|
* prefix.
|
|
@@ -76618,6 +76626,10 @@ export type CustomElementsSolidJs = {
|
|
|
76618
76626
|
* `Notification` does for a read. Call `preventDefault()` on `helix-facet` to
|
|
76619
76627
|
* cancel the change.
|
|
76620
76628
|
*
|
|
76629
|
+
* Imported from its own entry, `@fusion.dev/helix-headless/filter-input/menu`, which registers
|
|
76630
|
+
* it with the `Menu` it draws its pages with. The family's entry leaves it out,
|
|
76631
|
+
* so a field without a picker does not carry `Menu`.
|
|
76632
|
+
*
|
|
76621
76633
|
* ## Attributes & Properties
|
|
76622
76634
|
*
|
|
76623
76635
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
@@ -76874,7 +76886,7 @@ export type CustomElementsSolidJs = {
|
|
|
76874
76886
|
* | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. |
|
|
76875
76887
|
* | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. |
|
|
76876
76888
|
* | Home, End | Highlights the first or the last suggestion while the panel is open. |
|
|
76877
|
-
* | Escape | Closes the panel and stops there, so a dialog around the field stays open. |
|
|
76889
|
+
* | Escape | Closes the panel and stops there, so a dialog around the field stays open. With the panel closed, empties the text. In an empty field, does nothing, so the page hears it. |
|
|
76878
76890
|
* | Backspace | In an empty field, asks the last token to go. |
|
|
76879
76891
|
* | 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. |
|
|
76880
76892
|
* | Left, Right on a token | Move between the tokens, and past the last back to the text. |
|
|
@@ -76883,7 +76895,8 @@ export type CustomElementsSolidJs = {
|
|
|
76883
76895
|
* **Typed filters.** The field parses only the fields you declare. Write
|
|
76884
76896
|
* `FilterField` elements, usually inside the `FilterMenu` slotted into `start`,
|
|
76885
76897
|
* so the picker and the text share one set. On Enter, the field reads the text
|
|
76886
|
-
* against them
|
|
76898
|
+
* against them, and a paste is read the same way as soon as it lands.
|
|
76899
|
+
* `disposition:refunded,settled` and `-disposition:refunded` fire
|
|
76887
76900
|
* `helix-facet` exactly as ticking those values in the picker would, and the
|
|
76888
76901
|
* parsed text is removed. Everything else stays, so `refund tuesday
|
|
76889
76902
|
* disposition:settled` is a filter and a search at once. Helix defines the
|
|
@@ -76896,6 +76909,12 @@ export type CustomElementsSolidJs = {
|
|
|
76896
76909
|
* nothing draws it and the menu has no page for it, and the grammar still reads
|
|
76897
76910
|
* it.
|
|
76898
76911
|
*
|
|
76912
|
+
* **The picker has an entry of its own.** `FilterMenu` draws its pages with
|
|
76913
|
+
* `Menu`, which a field without a picker does not need, so this family's entry
|
|
76914
|
+
* leaves it out. A page that writes one imports
|
|
76915
|
+
* `@fusion.dev/helix/filter-input/menu` as well, and a picker written without it
|
|
76916
|
+
* is reported once the page has loaded, with the entry to add.
|
|
76917
|
+
*
|
|
76899
76918
|
* **Suggestions.** Slot options into `suggestions` and the field shows them,
|
|
76900
76919
|
* moves through them with the arrow keys, and presses one on Enter. The option
|
|
76901
76920
|
* fires its own `helix-select`, and you decide what choosing it means. Keys
|
|
@@ -78425,8 +78444,11 @@ export type CustomElementsSolidJs = {
|
|
|
78425
78444
|
* a dark background. Shapes that set their own `fill` or `stroke` are
|
|
78426
78445
|
* unaffected.
|
|
78427
78446
|
*
|
|
78428
|
-
* **A name is looked up in a registry.** The family's entry registers
|
|
78429
|
-
*
|
|
78447
|
+
* **A name is looked up in a registry.** The family's entry registers a small
|
|
78448
|
+
* set: the four carets, `arrow-left`, `arrow-right`, `check`, `x`, `plus`,
|
|
78449
|
+
* `minus`, `magnifying-glass`, `info` and `warning`. `icon/all` registers the
|
|
78450
|
+
* whole set, so any name in it draws, and a name that resolves to nothing
|
|
78451
|
+
* says to import it. The element's own entry,
|
|
78430
78452
|
* `@fusion.dev/helix-headless/icon/root`, registers none: a page that imports
|
|
78431
78453
|
* it and calls `registerIcons` with the glyphs it names ships those and no
|
|
78432
78454
|
* others. `registerIconLibrary` resolves names under a prefix of your own,
|
|
@@ -78471,12 +78493,10 @@ export type CustomElementsSolidJs = {
|
|
|
78471
78493
|
* - `name`: The name of the icon in the Helix set.
|
|
78472
78494
|
*
|
|
78473
78495
|
* **A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
78474
|
-
* so it is what markup can carry, and resolving one means an index
|
|
78475
|
-
*
|
|
78476
|
-
*
|
|
78477
|
-
*
|
|
78478
|
-
* element from `icon/root` and registers the glyphs it names, or hands over
|
|
78479
|
-
* the value instead.
|
|
78496
|
+
* so it is what markup can carry, and resolving one means an index that no
|
|
78497
|
+
* bundler can shake. The family's entry indexes a small set, `icon/all`
|
|
78498
|
+
* indexes the whole set at 15 kB, and `icon/root` indexes nothing, for a
|
|
78499
|
+
* page that registers the glyphs it names or hands over the value instead.
|
|
78480
78500
|
*
|
|
78481
78501
|
* A name written `prefix:name` asks the library registered under that
|
|
78482
78502
|
* prefix.
|
package/types/vue.d.ts
CHANGED
|
@@ -8332,12 +8332,10 @@ disagreeing with its own name for every reader who meant the left. */
|
|
|
8332
8332
|
/** The name of the icon in the Helix set.
|
|
8333
8333
|
|
|
8334
8334
|
**A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
8335
|
-
so it is what markup can carry, and resolving one means an index
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
element from `icon/root` and registers the glyphs it names, or hands over
|
|
8340
|
-
the value instead.
|
|
8335
|
+
so it is what markup can carry, and resolving one means an index that no
|
|
8336
|
+
bundler can shake. The family's entry indexes a small set, `icon/all`
|
|
8337
|
+
indexes the whole set at 15 kB, and `icon/root` indexes nothing, for a
|
|
8338
|
+
page that registers the glyphs it names or hands over the value instead.
|
|
8341
8339
|
|
|
8342
8340
|
A name written `prefix:name` asks the library registered under that
|
|
8343
8341
|
prefix. */
|
|
@@ -19385,7 +19383,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19385
19383
|
HelixHeadlessFilterFieldVueProps,
|
|
19386
19384
|
HelixHeadlessFilterFieldVueEvents
|
|
19387
19385
|
>;
|
|
19388
|
-
/** Reads the 'FilterField' declarations inside it and renders a two-level menu: the fields, and under each field its operators and values. The menu does not interpret what a field means. '''html <helix-headless-filter-menu label="Filter"> <helix-headless-filter-field name="disposition" label="Disposition"> <helix-headless-option value="refunded">Refunded</helix-headless-option> </helix-headless-filter-field> </helix-headless-filter-menu> ''' That field declares no operators, so it offers 'is any of' and 'is none of', the two the typed grammar supports. The menu and the typed text offer the same filters because both read 'FilterField.vocabulary'. Declare other operators on the field when you need them. Ticking a value applies the filter immediately. There is no Apply button. Each tick fires 'helix-facet' with the field's whole set of values, so results narrow as the user works. Unticking the last value fires an empty set, which is your cue to remove the chip. The operator is chosen in the menu. 'helix-facet' carries an empty 'operatorLabel' when the operator is the field's default, which is the value a chip's 'operator-label' expects, so the operator segment appears only for a non-default choice. The menu decides this because it is the only element that reads both the field and its operators. An operator's 'arity' sets what appears under it: - 'arity="none"', such as 'is empty' or 'is set', offers no values and clears any that were ticked. The operator is the whole filter. - 'arity="one"' offers the values as a single choice. Pressing another value replaces the choice, and pressing the chosen value clears it. 'helix-facet' includes 'arity', so you can tell an empty filter from no filter. The menu applies nothing. The chips are your markup and the rows are your data, so the menu fires the event and leaves the change to you, as 'Notification' does for a read. Call 'preventDefault()' on 'helix-facet' to cancel the change. */
|
|
19386
|
+
/** Reads the 'FilterField' declarations inside it and renders a two-level menu: the fields, and under each field its operators and values. The menu does not interpret what a field means. '''html <helix-headless-filter-menu label="Filter"> <helix-headless-filter-field name="disposition" label="Disposition"> <helix-headless-option value="refunded">Refunded</helix-headless-option> </helix-headless-filter-field> </helix-headless-filter-menu> ''' That field declares no operators, so it offers 'is any of' and 'is none of', the two the typed grammar supports. The menu and the typed text offer the same filters because both read 'FilterField.vocabulary'. Declare other operators on the field when you need them. Ticking a value applies the filter immediately. There is no Apply button. Each tick fires 'helix-facet' with the field's whole set of values, so results narrow as the user works. Unticking the last value fires an empty set, which is your cue to remove the chip. The operator is chosen in the menu. 'helix-facet' carries an empty 'operatorLabel' when the operator is the field's default, which is the value a chip's 'operator-label' expects, so the operator segment appears only for a non-default choice. The menu decides this because it is the only element that reads both the field and its operators. An operator's 'arity' sets what appears under it: - 'arity="none"', such as 'is empty' or 'is set', offers no values and clears any that were ticked. The operator is the whole filter. - 'arity="one"' offers the values as a single choice. Pressing another value replaces the choice, and pressing the chosen value clears it. 'helix-facet' includes 'arity', so you can tell an empty filter from no filter. The menu applies nothing. The chips are your markup and the rows are your data, so the menu fires the event and leaves the change to you, as 'Notification' does for a read. Call 'preventDefault()' on 'helix-facet' to cancel the change. Imported from its own entry, '@fusion.dev/helix-headless/filter-input/menu', which registers it with the 'Menu' it draws its pages with. The family's entry leaves it out, so a field without a picker does not carry 'Menu'. */
|
|
19389
19387
|
"helix-headless-filter-menu": DefineCustomElement<
|
|
19390
19388
|
HelixHeadlessFilterMenu,
|
|
19391
19389
|
HelixHeadlessFilterMenuVueProps,
|
|
@@ -19397,7 +19395,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19397
19395
|
HelixHeadlessFilterOperatorVueProps,
|
|
19398
19396
|
HelixHeadlessFilterOperatorVueEvents
|
|
19399
19397
|
>;
|
|
19400
|
-
/** 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, which is the field's one tab stop. The text names the highlighted suggestion as its 'aria-activedescendant', and the arrow keys reach the tokens. | 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. Set 'chips' and the field adds, updates, and removes those chips itself, from every 'helix-facet' you do not cancel. */
|
|
19398
|
+
/** 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, which is the field's one tab stop. The text names the highlighted suggestion as its 'aria-activedescendant', and the arrow keys reach the tokens. | 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. With the panel closed, empties the text. In an empty field, does nothing, so the page hears it. | | 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, and a paste is read the same way as soon as it lands. '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. **The picker has an entry of its own.** 'FilterMenu' draws its pages with 'Menu', which a field without a picker does not need, so this family's entry leaves it out. A page that writes one imports '@fusion.dev/helix/filter-input/menu' as well, and a picker written without it is reported once the page has loaded, with the entry to add. **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. Set 'chips' and the field adds, updates, and removes those chips itself, from every 'helix-facet' you do not cancel. */
|
|
19401
19399
|
"helix-headless-filter-input": DefineCustomElement<
|
|
19402
19400
|
HelixHeadlessFilterInput,
|
|
19403
19401
|
HelixHeadlessFilterInputVueProps,
|
|
@@ -19427,7 +19425,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19427
19425
|
HelixHeadlessIconButtonVueProps,
|
|
19428
19426
|
HelixHeadlessIconButtonVueEvents
|
|
19429
19427
|
>;
|
|
19430
|
-
/** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers the whole set, so any name in it draws. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. **Or point 'src' at an SVG file**, such as 'src="/icons/rocket.svg"', and the element fetches it and draws its shapes in 'currentColor' where the file does not color them. A file is fetched once a page, however many icons name it, and 'load' fires when it is drawn. Scripts, event handlers and 'javascript:' links in the file are taken out before it is drawn. A server fetches nothing, so a served icon with a 'src' is drawn once the script runs. A name with no match, or a 'src' that is no SVG, renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. **A decorative icon that is all a control holds is reported.** In a development build, a button or a link whose only content is an icon with no 'label', and which has no name of its own, warns 'missing-name' once, through the runtime channel every Helix warning uses. */
|
|
19428
|
+
/** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers a small set: the four carets, 'arrow-left', 'arrow-right', 'check', 'x', 'plus', 'minus', 'magnifying-glass', 'info' and 'warning'. 'icon/all' registers the whole set, so any name in it draws, and a name that resolves to nothing says to import it. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. **Or point 'src' at an SVG file**, such as 'src="/icons/rocket.svg"', and the element fetches it and draws its shapes in 'currentColor' where the file does not color them. A file is fetched once a page, however many icons name it, and 'load' fires when it is drawn. Scripts, event handlers and 'javascript:' links in the file are taken out before it is drawn. A server fetches nothing, so a served icon with a 'src' is drawn once the script runs. A name with no match, or a 'src' that is no SVG, renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. **A decorative icon that is all a control holds is reported.** In a development build, a button or a link whose only content is an icon with no 'label', and which has no name of its own, warns 'missing-name' once, through the runtime channel every Helix warning uses. */
|
|
19431
19429
|
"helix-headless-icon": DefineCustomElement<
|
|
19432
19430
|
HelixHeadlessIcon,
|
|
19433
19431
|
HelixHeadlessIconVueProps,
|