@fusion.dev/helix-headless 0.174.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 +198 -59
- package/dist/app-header/root/app-header-root.d.ts +2 -1
- package/dist/app-header/root/app-header-root.js +6 -1
- package/dist/button/root/button-root.d.ts +6 -1
- package/dist/button/root/button-root.js +1 -0
- package/dist/command/root/command-root.d.ts +4 -2
- package/dist/command/root/command-root.js +1 -0
- package/dist/date-picker/root/date-picker-root.d.ts +6 -0
- package/dist/date-picker/root/date-picker-root.js +7 -1
- package/dist/dialog/form-method.d.ts +12 -0
- package/dist/dialog/form-method.js +13 -0
- package/dist/dialog/root/dialog-root.d.ts +1 -9
- package/dist/dialog/root/dialog-root.js +2 -11
- package/dist/drawer/root/drawer-root.d.ts +2 -0
- package/dist/drawer/root/drawer-root.js +6 -0
- 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/dist/lightbox/item/lightbox-item.d.ts +1 -0
- package/dist/lightbox/root/lightbox-root.d.ts +25 -5
- package/dist/lightbox/root/lightbox-root.js +33 -10
- package/dist/notifications/group/notification-group.js +2 -2
- package/dist/notifications/notification/notification.js +4 -5
- package/dist/notifications/root/notifications-root.d.ts +4 -3
- package/dist/notifications/root/notifications-root.js +1 -1
- package/dist/pagination/root/pagination-root.d.ts +2 -1
- package/dist/pagination/root/pagination-root.js +6 -1
- package/dist/tooltip/root/tooltip-root.d.ts +5 -2
- package/dist/tooltip/root/tooltip-root.js +11 -11
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +102 -72
- package/types/vue.d.ts +13 -14
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. */
|
|
@@ -17398,7 +17394,8 @@ Written by the root, which is the only thing that sees the set. */
|
|
|
17398
17394
|
/** The item's name. It names the item's group, and fills `{label}` in the
|
|
17399
17395
|
lightbox's `status-label`. */
|
|
17400
17396
|
label?: (HelixHeadlessLightboxItem["label"]) | undefined;
|
|
17401
|
-
/** The item's identifier. The root compares its `active` value against it.
|
|
17397
|
+
/** The item's identifier. The root compares its `active` value against it.
|
|
17398
|
+
Without one, the item is named by its place in the set, counted from 1. */
|
|
17402
17399
|
value?: (HelixHeadlessLightboxItem["value"]) | undefined;
|
|
17403
17400
|
};
|
|
17404
17401
|
|
|
@@ -17410,7 +17407,8 @@ Written by the root, which is the only thing that sees the set. */
|
|
|
17410
17407
|
/** The item's name. It names the item's group, and fills `{label}` in the
|
|
17411
17408
|
lightbox's `status-label`. */
|
|
17412
17409
|
"prop:label"?: (HelixHeadlessLightboxItem["label"]) | undefined;
|
|
17413
|
-
/** The item's identifier. The root compares its `active` value against it.
|
|
17410
|
+
/** The item's identifier. The root compares its `active` value against it.
|
|
17411
|
+
Without one, the item is named by its place in the set, counted from 1. */
|
|
17414
17412
|
"prop:value"?: (HelixHeadlessLightboxItem["value"]) | undefined;
|
|
17415
17413
|
|
|
17416
17414
|
/** Set the innerHTML of the element */
|
|
@@ -43330,8 +43328,10 @@ export type CustomElements = {
|
|
|
43330
43328
|
* the full list. Combobox and Select do the same. As typing narrows the list, a
|
|
43331
43329
|
* screen reader hears how many commands are left, such as "3 commands".
|
|
43332
43330
|
*
|
|
43333
|
-
* **Keyboard.** Focus goes to the filter field as the palette opens,
|
|
43334
|
-
*
|
|
43331
|
+
* **Keyboard.** Focus goes to the filter field as the palette opens, with no
|
|
43332
|
+
* command highlighted, as in React Aria's Autocomplete, so Enter runs nothing
|
|
43333
|
+
* until you type or press Down. Typing highlights the first command left, and
|
|
43334
|
+
* the highlight moves through the commands while you type.
|
|
43335
43335
|
*
|
|
43336
43336
|
* | Key | What it does |
|
|
43337
43337
|
* |---|---|
|
|
@@ -47187,6 +47187,10 @@ export type CustomElements = {
|
|
|
47187
47187
|
* `Notification` does for a read. Call `preventDefault()` on `helix-facet` to
|
|
47188
47188
|
* cancel the change.
|
|
47189
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
|
+
*
|
|
47190
47194
|
* ## Attributes & Properties
|
|
47191
47195
|
*
|
|
47192
47196
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
@@ -47441,7 +47445,7 @@ export type CustomElements = {
|
|
|
47441
47445
|
* | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. |
|
|
47442
47446
|
* | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. |
|
|
47443
47447
|
* | Home, End | Highlights the first or the last suggestion while the panel is open. |
|
|
47444
|
-
* | 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. |
|
|
47445
47449
|
* | Backspace | In an empty field, asks the last token to go. |
|
|
47446
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. |
|
|
47447
47451
|
* | Left, Right on a token | Move between the tokens, and past the last back to the text. |
|
|
@@ -47450,7 +47454,8 @@ export type CustomElements = {
|
|
|
47450
47454
|
* **Typed filters.** The field parses only the fields you declare. Write
|
|
47451
47455
|
* `FilterField` elements, usually inside the `FilterMenu` slotted into `start`,
|
|
47452
47456
|
* so the picker and the text share one set. On Enter, the field reads the text
|
|
47453
|
-
* 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
|
|
47454
47459
|
* `helix-facet` exactly as ticking those values in the picker would, and the
|
|
47455
47460
|
* parsed text is removed. Everything else stays, so `refund tuesday
|
|
47456
47461
|
* disposition:settled` is a filter and a search at once. Helix defines the
|
|
@@ -47463,6 +47468,12 @@ export type CustomElements = {
|
|
|
47463
47468
|
* nothing draws it and the menu has no page for it, and the grammar still reads
|
|
47464
47469
|
* it.
|
|
47465
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
|
+
*
|
|
47466
47477
|
* **Suggestions.** Slot options into `suggestions` and the field shows them,
|
|
47467
47478
|
* moves through them with the arrow keys, and presses one on Enter. The option
|
|
47468
47479
|
* fires its own `helix-select`, and you decide what choosing it means. Keys
|
|
@@ -48983,8 +48994,11 @@ export type CustomElements = {
|
|
|
48983
48994
|
* a dark background. Shapes that set their own `fill` or `stroke` are
|
|
48984
48995
|
* unaffected.
|
|
48985
48996
|
*
|
|
48986
|
-
* **A name is looked up in a registry.** The family's entry registers
|
|
48987
|
-
*
|
|
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,
|
|
48988
49002
|
* `@fusion.dev/helix-headless/icon/root`, registers none: a page that imports
|
|
48989
49003
|
* it and calls `registerIcons` with the glyphs it names ships those and no
|
|
48990
49004
|
* others. `registerIconLibrary` resolves names under a prefix of your own,
|
|
@@ -49029,12 +49043,10 @@ export type CustomElements = {
|
|
|
49029
49043
|
* - `name`: The name of the icon in the Helix set.
|
|
49030
49044
|
*
|
|
49031
49045
|
* **A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
49032
|
-
* so it is what markup can carry, and resolving one means an index
|
|
49033
|
-
*
|
|
49034
|
-
*
|
|
49035
|
-
*
|
|
49036
|
-
* element from `icon/root` and registers the glyphs it names, or hands over
|
|
49037
|
-
* 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.
|
|
49038
49050
|
*
|
|
49039
49051
|
* A name written `prefix:name` asks the library registered under that
|
|
49040
49052
|
* prefix.
|
|
@@ -49867,6 +49879,7 @@ export type CustomElements = {
|
|
|
49867
49879
|
* - `label`: The item's name. It names the item's group, and fills `{label}` in the
|
|
49868
49880
|
* lightbox's `status-label`.
|
|
49869
49881
|
* - `value`: The item's identifier. The root compares its `active` value against it.
|
|
49882
|
+
* Without one, the item is named by its place in the set, counted from 1.
|
|
49870
49883
|
* - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
|
|
49871
49884
|
*
|
|
49872
49885
|
* **Named `whenSettled` because `settled` is taken four times over**, by
|
|
@@ -49926,7 +49939,9 @@ export type CustomElements = {
|
|
|
49926
49939
|
*
|
|
49927
49940
|
* A lightbox shows one item at a time and has no scrolling track, so `active`
|
|
49928
49941
|
* holds the current item, as in `Tabs`. The arrow keys change the item while
|
|
49929
|
-
* focus stays in the dialog.
|
|
49942
|
+
* focus stays in the dialog. `active` names an item by its `value`, and an
|
|
49943
|
+
* item with no `value` by its place, counted from 1, as in `Steps`, so a set
|
|
49944
|
+
* written without values moves and `helix-activate` says `1`, `2` and so on.
|
|
49930
49945
|
*
|
|
49931
49946
|
* Set `controls` for the viewer's own previous, next and close controls, named
|
|
49932
49947
|
* by `previous-label`, `next-label` and `dismiss-label`, whose glyphs you can
|
|
@@ -49943,9 +49958,9 @@ export type CustomElements = {
|
|
|
49943
49958
|
* `--lightbox-pan-x` and `--lightbox-pan-y`, written only while zoomed, and a
|
|
49944
49959
|
* swipe moves to the next item only while the item is at its own size. With
|
|
49945
49960
|
* `controls`, the viewer also draws zoom-out and zoom-in controls, for a
|
|
49946
|
-
* pointer with no wheel and no second finger. Once a reader stops zooming,
|
|
49947
|
-
* live region says the new scale in
|
|
49948
|
-
* "Zoomed to 150%".
|
|
49961
|
+
* pointer with no wheel and no second finger. Once a reader stops zooming, and
|
|
49962
|
+
* at once for a key or a zoom control, the live region says the new scale in
|
|
49963
|
+
* the words of `zoom-status-label`, such as "Zoomed to 150%".
|
|
49949
49964
|
*
|
|
49950
49965
|
* Each item is a slide: a `group` with the role description in
|
|
49951
49966
|
* `slide-role-label`, named by its `label` or by `slide-label`. A touch or a pen
|
|
@@ -50108,15 +50123,10 @@ export type CustomElements = {
|
|
|
50108
50123
|
* - `previous() => void`: Shows the previous item. Before the first item, it shows the last when
|
|
50109
50124
|
* `loop` is set.
|
|
50110
50125
|
* - `toggleFullscreen() => void`: Makes the viewer fill the screen, or exits fullscreen.
|
|
50111
|
-
* - `requestActive(next: string, cause?: string) => boolean`: Requests a new
|
|
50126
|
+
* - `requestActive(next: string, cause?: string) => boolean`: Requests a new shown item, and returns whether it moved.
|
|
50112
50127
|
*
|
|
50113
|
-
*
|
|
50114
|
-
*
|
|
50115
|
-
* by the time this runs, so refusing is simply not writing: there is
|
|
50116
|
-
* nothing to put back. Nobody refusing means the set updates itself,
|
|
50117
|
-
* whether or not a consumer declared `active`, a declared property being a
|
|
50118
|
-
* seed and a correction. `cause` says why, where the family names its
|
|
50119
|
-
* causes, and reaches the event as `detail.cause`.
|
|
50128
|
+
* Where `active` names nothing, it is first written with the item on
|
|
50129
|
+
* screen, so `helix-activate` names the item you saw as `previous`.
|
|
50120
50130
|
* - `requestOpen(next: boolean) => boolean`: Requests that the element open or close, and returns whether the change
|
|
50121
50131
|
* was applied.
|
|
50122
50132
|
*
|
|
@@ -53905,8 +53915,9 @@ export type CustomElements = {
|
|
|
53905
53915
|
* the items and written to an attribute, so a stylesheet and a badge can both
|
|
53906
53916
|
* use it without counting.
|
|
53907
53917
|
*
|
|
53908
|
-
* **The feed is one `Tab` stop for its rows.**
|
|
53909
|
-
*
|
|
53918
|
+
* **The feed is one `Tab` stop for its rows.** It is an APG feed: the list is
|
|
53919
|
+
* a `feed`, busy while `loading` is set, and each row is an `article` that
|
|
53920
|
+
* takes focus itself and is read by its label. `ArrowDown` and `ArrowUp` move to the next and the
|
|
53910
53921
|
* previous row, `Home` and `End` to the first and the last, and `PageDown` and
|
|
53911
53922
|
* `PageUp` move a row on or back from anywhere inside one, as in the APG feed
|
|
53912
53923
|
* pattern. The controls inside a row stay in the `Tab` order. Set `total` when
|
|
@@ -54086,7 +54097,7 @@ export type CustomElements = {
|
|
|
54086
54097
|
* - `error`: Shown while `load-error` is set, under any rows there are, in place of the empty and loading lines.
|
|
54087
54098
|
* - `footer`: The region below the list.
|
|
54088
54099
|
* - `header`: The region above the list.
|
|
54089
|
-
* - `list`: The list itself.
|
|
54100
|
+
* - `list`: The list itself, a `feed` whose rows are its articles.
|
|
54090
54101
|
* - `live`: A copy of the empty, loading and error messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.
|
|
54091
54102
|
* - `loading`: Shown while the feed is loading.
|
|
54092
54103
|
* - `mark-all`: The control that marks everything read.
|
|
@@ -63950,8 +63961,11 @@ export type CustomElements = {
|
|
|
63950
63961
|
* markup is described when you first point at it or focus it, so a screen
|
|
63951
63962
|
* reader in reading mode meets it with no description until then. Where the
|
|
63952
63963
|
* browser has no element references, nothing links the two, and the tooltip
|
|
63953
|
-
* warns once on first open. The tooltip can also wrap its trigger
|
|
63954
|
-
*
|
|
63964
|
+
* warns once on first open. The tooltip can also wrap its trigger. A Helix
|
|
63965
|
+
* component inside is described at once, and a plain element as in the `for`
|
|
63966
|
+
* form: when you first point at it or focus it, or at rest where it names the
|
|
63967
|
+
* tooltip's `id` in its own `aria-describedby`, which a reference to the
|
|
63968
|
+
* element around it allows. In the
|
|
63955
63969
|
* `for` form the tooltip itself is out of the accessibility tree while its
|
|
63956
63970
|
* bubble is down, so you meet its words once, as the trigger's description.
|
|
63957
63971
|
* A trigger whose name is already the tooltip's words, such as an icon button
|
|
@@ -72718,8 +72732,10 @@ export type CustomElementsSolidJs = {
|
|
|
72718
72732
|
* the full list. Combobox and Select do the same. As typing narrows the list, a
|
|
72719
72733
|
* screen reader hears how many commands are left, such as "3 commands".
|
|
72720
72734
|
*
|
|
72721
|
-
* **Keyboard.** Focus goes to the filter field as the palette opens,
|
|
72722
|
-
*
|
|
72735
|
+
* **Keyboard.** Focus goes to the filter field as the palette opens, with no
|
|
72736
|
+
* command highlighted, as in React Aria's Autocomplete, so Enter runs nothing
|
|
72737
|
+
* until you type or press Down. Typing highlights the first command left, and
|
|
72738
|
+
* the highlight moves through the commands while you type.
|
|
72723
72739
|
*
|
|
72724
72740
|
* | Key | What it does |
|
|
72725
72741
|
* |---|---|
|
|
@@ -76610,6 +76626,10 @@ export type CustomElementsSolidJs = {
|
|
|
76610
76626
|
* `Notification` does for a read. Call `preventDefault()` on `helix-facet` to
|
|
76611
76627
|
* cancel the change.
|
|
76612
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
|
+
*
|
|
76613
76633
|
* ## Attributes & Properties
|
|
76614
76634
|
*
|
|
76615
76635
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
@@ -76866,7 +76886,7 @@ export type CustomElementsSolidJs = {
|
|
|
76866
76886
|
* | Enter | Presses the highlighted suggestion. With none highlighted, reads the typed filters into chips, or submits the form when there are none. |
|
|
76867
76887
|
* | Down, Up | Moves the highlight through the suggestions, wrapping, and opens the panel. |
|
|
76868
76888
|
* | Home, End | Highlights the first or the last suggestion while the panel is open. |
|
|
76869
|
-
* | 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. |
|
|
76870
76890
|
* | Backspace | In an empty field, asks the last token to go. |
|
|
76871
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. |
|
|
76872
76892
|
* | Left, Right on a token | Move between the tokens, and past the last back to the text. |
|
|
@@ -76875,7 +76895,8 @@ export type CustomElementsSolidJs = {
|
|
|
76875
76895
|
* **Typed filters.** The field parses only the fields you declare. Write
|
|
76876
76896
|
* `FilterField` elements, usually inside the `FilterMenu` slotted into `start`,
|
|
76877
76897
|
* so the picker and the text share one set. On Enter, the field reads the text
|
|
76878
|
-
* 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
|
|
76879
76900
|
* `helix-facet` exactly as ticking those values in the picker would, and the
|
|
76880
76901
|
* parsed text is removed. Everything else stays, so `refund tuesday
|
|
76881
76902
|
* disposition:settled` is a filter and a search at once. Helix defines the
|
|
@@ -76888,6 +76909,12 @@ export type CustomElementsSolidJs = {
|
|
|
76888
76909
|
* nothing draws it and the menu has no page for it, and the grammar still reads
|
|
76889
76910
|
* it.
|
|
76890
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
|
+
*
|
|
76891
76918
|
* **Suggestions.** Slot options into `suggestions` and the field shows them,
|
|
76892
76919
|
* moves through them with the arrow keys, and presses one on Enter. The option
|
|
76893
76920
|
* fires its own `helix-select`, and you decide what choosing it means. Keys
|
|
@@ -78417,8 +78444,11 @@ export type CustomElementsSolidJs = {
|
|
|
78417
78444
|
* a dark background. Shapes that set their own `fill` or `stroke` are
|
|
78418
78445
|
* unaffected.
|
|
78419
78446
|
*
|
|
78420
|
-
* **A name is looked up in a registry.** The family's entry registers
|
|
78421
|
-
*
|
|
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,
|
|
78422
78452
|
* `@fusion.dev/helix-headless/icon/root`, registers none: a page that imports
|
|
78423
78453
|
* it and calls `registerIcons` with the glyphs it names ships those and no
|
|
78424
78454
|
* others. `registerIconLibrary` resolves names under a prefix of your own,
|
|
@@ -78463,12 +78493,10 @@ export type CustomElementsSolidJs = {
|
|
|
78463
78493
|
* - `name`: The name of the icon in the Helix set.
|
|
78464
78494
|
*
|
|
78465
78495
|
* **A lookup, and the reason both this and `icon` exist.** A name is a string,
|
|
78466
|
-
* so it is what markup can carry, and resolving one means an index
|
|
78467
|
-
*
|
|
78468
|
-
*
|
|
78469
|
-
*
|
|
78470
|
-
* element from `icon/root` and registers the glyphs it names, or hands over
|
|
78471
|
-
* 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.
|
|
78472
78500
|
*
|
|
78473
78501
|
* A name written `prefix:name` asks the library registered under that
|
|
78474
78502
|
* prefix.
|
|
@@ -79316,6 +79344,7 @@ export type CustomElementsSolidJs = {
|
|
|
79316
79344
|
* - `label`: The item's name. It names the item's group, and fills `{label}` in the
|
|
79317
79345
|
* lightbox's `status-label`.
|
|
79318
79346
|
* - `value`: The item's identifier. The root compares its `active` value against it.
|
|
79347
|
+
* Without one, the item is named by its place in the set, counted from 1.
|
|
79319
79348
|
* - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
|
|
79320
79349
|
*
|
|
79321
79350
|
* **Named `whenSettled` because `settled` is taken four times over**, by
|
|
@@ -79376,7 +79405,9 @@ export type CustomElementsSolidJs = {
|
|
|
79376
79405
|
*
|
|
79377
79406
|
* A lightbox shows one item at a time and has no scrolling track, so `active`
|
|
79378
79407
|
* holds the current item, as in `Tabs`. The arrow keys change the item while
|
|
79379
|
-
* focus stays in the dialog.
|
|
79408
|
+
* focus stays in the dialog. `active` names an item by its `value`, and an
|
|
79409
|
+
* item with no `value` by its place, counted from 1, as in `Steps`, so a set
|
|
79410
|
+
* written without values moves and `helix-activate` says `1`, `2` and so on.
|
|
79380
79411
|
*
|
|
79381
79412
|
* Set `controls` for the viewer's own previous, next and close controls, named
|
|
79382
79413
|
* by `previous-label`, `next-label` and `dismiss-label`, whose glyphs you can
|
|
@@ -79393,9 +79424,9 @@ export type CustomElementsSolidJs = {
|
|
|
79393
79424
|
* `--lightbox-pan-x` and `--lightbox-pan-y`, written only while zoomed, and a
|
|
79394
79425
|
* swipe moves to the next item only while the item is at its own size. With
|
|
79395
79426
|
* `controls`, the viewer also draws zoom-out and zoom-in controls, for a
|
|
79396
|
-
* pointer with no wheel and no second finger. Once a reader stops zooming,
|
|
79397
|
-
* live region says the new scale in
|
|
79398
|
-
* "Zoomed to 150%".
|
|
79427
|
+
* pointer with no wheel and no second finger. Once a reader stops zooming, and
|
|
79428
|
+
* at once for a key or a zoom control, the live region says the new scale in
|
|
79429
|
+
* the words of `zoom-status-label`, such as "Zoomed to 150%".
|
|
79399
79430
|
*
|
|
79400
79431
|
* Each item is a slide: a `group` with the role description in
|
|
79401
79432
|
* `slide-role-label`, named by its `label` or by `slide-label`. A touch or a pen
|
|
@@ -79558,15 +79589,10 @@ export type CustomElementsSolidJs = {
|
|
|
79558
79589
|
* - `previous() => void`: Shows the previous item. Before the first item, it shows the last when
|
|
79559
79590
|
* `loop` is set.
|
|
79560
79591
|
* - `toggleFullscreen() => void`: Makes the viewer fill the screen, or exits fullscreen.
|
|
79561
|
-
* - `requestActive(next: string, cause?: string) => boolean`: Requests a new
|
|
79592
|
+
* - `requestActive(next: string, cause?: string) => boolean`: Requests a new shown item, and returns whether it moved.
|
|
79562
79593
|
*
|
|
79563
|
-
*
|
|
79564
|
-
*
|
|
79565
|
-
* by the time this runs, so refusing is simply not writing: there is
|
|
79566
|
-
* nothing to put back. Nobody refusing means the set updates itself,
|
|
79567
|
-
* whether or not a consumer declared `active`, a declared property being a
|
|
79568
|
-
* seed and a correction. `cause` says why, where the family names its
|
|
79569
|
-
* causes, and reaches the event as `detail.cause`.
|
|
79594
|
+
* Where `active` names nothing, it is first written with the item on
|
|
79595
|
+
* screen, so `helix-activate` names the item you saw as `previous`.
|
|
79570
79596
|
* - `requestOpen(next: boolean) => boolean`: Requests that the element open or close, and returns whether the change
|
|
79571
79597
|
* was applied.
|
|
79572
79598
|
*
|
|
@@ -83412,8 +83438,9 @@ export type CustomElementsSolidJs = {
|
|
|
83412
83438
|
* the items and written to an attribute, so a stylesheet and a badge can both
|
|
83413
83439
|
* use it without counting.
|
|
83414
83440
|
*
|
|
83415
|
-
* **The feed is one `Tab` stop for its rows.**
|
|
83416
|
-
*
|
|
83441
|
+
* **The feed is one `Tab` stop for its rows.** It is an APG feed: the list is
|
|
83442
|
+
* a `feed`, busy while `loading` is set, and each row is an `article` that
|
|
83443
|
+
* takes focus itself and is read by its label. `ArrowDown` and `ArrowUp` move to the next and the
|
|
83417
83444
|
* previous row, `Home` and `End` to the first and the last, and `PageDown` and
|
|
83418
83445
|
* `PageUp` move a row on or back from anywhere inside one, as in the APG feed
|
|
83419
83446
|
* pattern. The controls inside a row stay in the `Tab` order. Set `total` when
|
|
@@ -83593,7 +83620,7 @@ export type CustomElementsSolidJs = {
|
|
|
83593
83620
|
* - `error`: Shown while `load-error` is set, under any rows there are, in place of the empty and loading lines.
|
|
83594
83621
|
* - `footer`: The region below the list.
|
|
83595
83622
|
* - `header`: The region above the list.
|
|
83596
|
-
* - `list`: The list itself.
|
|
83623
|
+
* - `list`: The list itself, a `feed` whose rows are its articles.
|
|
83597
83624
|
* - `live`: A copy of the empty, loading and error messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.
|
|
83598
83625
|
* - `loading`: Shown while the feed is loading.
|
|
83599
83626
|
* - `mark-all`: The control that marks everything read.
|
|
@@ -93583,8 +93610,11 @@ export type CustomElementsSolidJs = {
|
|
|
93583
93610
|
* markup is described when you first point at it or focus it, so a screen
|
|
93584
93611
|
* reader in reading mode meets it with no description until then. Where the
|
|
93585
93612
|
* browser has no element references, nothing links the two, and the tooltip
|
|
93586
|
-
* warns once on first open. The tooltip can also wrap its trigger
|
|
93587
|
-
*
|
|
93613
|
+
* warns once on first open. The tooltip can also wrap its trigger. A Helix
|
|
93614
|
+
* component inside is described at once, and a plain element as in the `for`
|
|
93615
|
+
* form: when you first point at it or focus it, or at rest where it names the
|
|
93616
|
+
* tooltip's `id` in its own `aria-describedby`, which a reference to the
|
|
93617
|
+
* element around it allows. In the
|
|
93588
93618
|
* `for` form the tooltip itself is out of the accessibility tree while its
|
|
93589
93619
|
* bubble is down, so you meet its words once, as the trigger's description.
|
|
93590
93620
|
* A trigger whose name is already the tooltip's words, such as an icon button
|
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. */
|
|
@@ -8897,7 +8895,8 @@ Written by the root, which is the only thing that sees the set. */
|
|
|
8897
8895
|
/** The item's name. It names the item's group, and fills `{label}` in the
|
|
8898
8896
|
lightbox's `status-label`. */
|
|
8899
8897
|
label?: (HelixHeadlessLightboxItem["label"]) | undefined;
|
|
8900
|
-
/** The item's identifier. The root compares its `active` value against it.
|
|
8898
|
+
/** The item's identifier. The root compares its `active` value against it.
|
|
8899
|
+
Without one, the item is named by its place in the set, counted from 1. */
|
|
8901
8900
|
value?: (HelixHeadlessLightboxItem["value"]) | undefined;
|
|
8902
8901
|
};
|
|
8903
8902
|
|
|
@@ -19282,7 +19281,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19282
19281
|
HelixHeadlessComboboxVueProps,
|
|
19283
19282
|
HelixHeadlessComboboxVueEvents
|
|
19284
19283
|
>;
|
|
19285
|
-
/** The list is a 'Listbox', which handles filtering, the empty state, the match highlight, 'aria-activedescendant', scrolling an option into view, and moving between options with the keyboard. The palette adds a dialog and a hotkey that opens it. The palette keeps no value. It is not a form control and submits nothing. Choosing an option dispatches 'helix-select' once. To remember the last command, store it yourself. An option with 'href' is a link to a page, which the browser follows once the palette has closed. The hotkey listener is on the document, so the hotkey works from anywhere on the page, including inside another control's text field, whether or not the palette is open. 'mod' means Command on a Mac and Control elsewhere, so you write one binding. With 'inline', the palette is drawn in the page with no dialog, as a search over a list that is always shown. **Pages.** A command can open a page of commands of its own, as a palette offers "Change theme" and then the themes. Give the option 'opens' with a name, and slot the page's commands as 'page:' and that name: '''html <helix-command> <helix-option value="theme" opens="theme">Change theme</helix-option> <helix-option value="dark" slot="page:theme">Dark</helix-option> <helix-option value="light" slot="page:theme">Light</helix-option> </helix-command> ''' Choosing the opener says 'helix-select' with its value, and canceling it keeps the page that is shown. The list then shows the page, named by the opener's words, and a screen reader hears those words. Backspace in an empty filter goes back, and a screen reader hears the name of the page it goes back to. 'page' says which page is shown. The filter is cleared when the palette closes, so each opening starts from the full list. Combobox and Select do the same. As typing narrows the list, a screen reader hears how many commands are left, such as "3 commands". **Keyboard.** Focus goes to the filter field as the palette opens, and the highlight moves through the commands while you type. | Key | What it does | |---|---| | 'hotkey', Command or Control with K by default | Opens the palette from anywhere on the page, or closes it. With 'inline', puts focus in its filter field. | | Down, Up | Moves the highlight to the next or the previous command, round from the last to the first. | | Page Down, Page Up | Moves the highlight by as many commands as the list shows at once. | | Home, End | Move the caret in the filter field. With 'home-end="list"', move the highlight to the first or the last command. | | Left, Right | Move the caret in the filter field. | | Enter | Runs the highlighted command, or follows it where it is a link, and closes the palette. On a command with 'opens', shows its page. | | Command or Control with Enter | Takes the highlighted command's 'alternate' destination, where it has one. | | Backspace | In an empty filter on a page, goes back to the page before. | | Escape | Clears the filter. With the filter empty, closes the palette and puts focus back where it was. | | Tab | Stays in the palette, which is modal. With 'inline', moves on through the page. | **ARIA.** The palette is a modal 'dialog' named by 'label', or with 'inline' no dialog at all. Inside it the filter field is a text field with 'aria-autocomplete="list"', 'aria-controls' on the list, and 'aria-activedescendant' on the highlighted command, as the field of React Aria's 'Autocomplete' is. The commands are a 'listbox' of 'option's. How many commands typing left, the empty text and the loading text are said in a polite live region. */
|
|
19284
|
+
/** The list is a 'Listbox', which handles filtering, the empty state, the match highlight, 'aria-activedescendant', scrolling an option into view, and moving between options with the keyboard. The palette adds a dialog and a hotkey that opens it. The palette keeps no value. It is not a form control and submits nothing. Choosing an option dispatches 'helix-select' once. To remember the last command, store it yourself. An option with 'href' is a link to a page, which the browser follows once the palette has closed. The hotkey listener is on the document, so the hotkey works from anywhere on the page, including inside another control's text field, whether or not the palette is open. 'mod' means Command on a Mac and Control elsewhere, so you write one binding. With 'inline', the palette is drawn in the page with no dialog, as a search over a list that is always shown. **Pages.** A command can open a page of commands of its own, as a palette offers "Change theme" and then the themes. Give the option 'opens' with a name, and slot the page's commands as 'page:' and that name: '''html <helix-command> <helix-option value="theme" opens="theme">Change theme</helix-option> <helix-option value="dark" slot="page:theme">Dark</helix-option> <helix-option value="light" slot="page:theme">Light</helix-option> </helix-command> ''' Choosing the opener says 'helix-select' with its value, and canceling it keeps the page that is shown. The list then shows the page, named by the opener's words, and a screen reader hears those words. Backspace in an empty filter goes back, and a screen reader hears the name of the page it goes back to. 'page' says which page is shown. The filter is cleared when the palette closes, so each opening starts from the full list. Combobox and Select do the same. As typing narrows the list, a screen reader hears how many commands are left, such as "3 commands". **Keyboard.** Focus goes to the filter field as the palette opens, with no command highlighted, as in React Aria's Autocomplete, so Enter runs nothing until you type or press Down. Typing highlights the first command left, and the highlight moves through the commands while you type. | Key | What it does | |---|---| | 'hotkey', Command or Control with K by default | Opens the palette from anywhere on the page, or closes it. With 'inline', puts focus in its filter field. | | Down, Up | Moves the highlight to the next or the previous command, round from the last to the first. | | Page Down, Page Up | Moves the highlight by as many commands as the list shows at once. | | Home, End | Move the caret in the filter field. With 'home-end="list"', move the highlight to the first or the last command. | | Left, Right | Move the caret in the filter field. | | Enter | Runs the highlighted command, or follows it where it is a link, and closes the palette. On a command with 'opens', shows its page. | | Command or Control with Enter | Takes the highlighted command's 'alternate' destination, where it has one. | | Backspace | In an empty filter on a page, goes back to the page before. | | Escape | Clears the filter. With the filter empty, closes the palette and puts focus back where it was. | | Tab | Stays in the palette, which is modal. With 'inline', moves on through the page. | **ARIA.** The palette is a modal 'dialog' named by 'label', or with 'inline' no dialog at all. Inside it the filter field is a text field with 'aria-autocomplete="list"', 'aria-controls' on the list, and 'aria-activedescendant' on the highlighted command, as the field of React Aria's 'Autocomplete' is. The commands are a 'listbox' of 'option's. How many commands typing left, the empty text and the loading text are said in a polite live region. */
|
|
19286
19285
|
"helix-headless-command": DefineCustomElement<
|
|
19287
19286
|
HelixHeadlessCommand,
|
|
19288
19287
|
HelixHeadlessCommandVueProps,
|
|
@@ -19384,7 +19383,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19384
19383
|
HelixHeadlessFilterFieldVueProps,
|
|
19385
19384
|
HelixHeadlessFilterFieldVueEvents
|
|
19386
19385
|
>;
|
|
19387
|
-
/** 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'. */
|
|
19388
19387
|
"helix-headless-filter-menu": DefineCustomElement<
|
|
19389
19388
|
HelixHeadlessFilterMenu,
|
|
19390
19389
|
HelixHeadlessFilterMenuVueProps,
|
|
@@ -19396,7 +19395,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19396
19395
|
HelixHeadlessFilterOperatorVueProps,
|
|
19397
19396
|
HelixHeadlessFilterOperatorVueEvents
|
|
19398
19397
|
>;
|
|
19399
|
-
/** 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. */
|
|
19400
19399
|
"helix-headless-filter-input": DefineCustomElement<
|
|
19401
19400
|
HelixHeadlessFilterInput,
|
|
19402
19401
|
HelixHeadlessFilterInputVueProps,
|
|
@@ -19426,7 +19425,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19426
19425
|
HelixHeadlessIconButtonVueProps,
|
|
19427
19426
|
HelixHeadlessIconButtonVueEvents
|
|
19428
19427
|
>;
|
|
19429
|
-
/** 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. */
|
|
19430
19429
|
"helix-headless-icon": DefineCustomElement<
|
|
19431
19430
|
HelixHeadlessIcon,
|
|
19432
19431
|
HelixHeadlessIconVueProps,
|
|
@@ -19462,7 +19461,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19462
19461
|
HelixHeadlessLightboxItemVueProps,
|
|
19463
19462
|
HelixHeadlessLightboxItemVueEvents
|
|
19464
19463
|
>;
|
|
19465
|
-
/** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, and so does a trackpad pinch or the wheel with Ctrl held, about the point under the pointer. A double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about and the wheel moves it. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. With 'controls', the viewer also draws zoom-out and zoom-in controls, for a pointer with no wheel and no second finger. Once a reader stops zooming, the live region says the new scale in the words of 'zoom-status-label', such as "Zoomed to 150%". Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. A press on the empty area around the item closes the viewer, as a press on the backdrop does. Under 'max-zoom', a press beside the item zooms on a double press and closes nothing, and only the space outside the viewport closes the viewer. A press that dragged closes nothing. **Keyboard.** Opening moves focus to the viewer itself, which a screen reader names. | Key | What it does | |---|---| | Right, Down | Shows the next item. On a right-to-left page, Left does. While the item is zoomed, the arrows move about it instead. | | Left, Up | Shows the previous item. | | Home, End | Shows the first or the last item. | | '+', '-', '0' | Zooms in, zooms out, and puts the item back at its own size, where 'max-zoom' allows zooming. | | Tab, Shift+Tab | Moves through the controls in the viewer, from the last round to the first and from the first round to the last. | | Escape | Closes the viewer. A 'helix-before-close' listener can refuse. | A development build warns when a viewer opens with no 'label'. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
|
|
19464
|
+
/** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. 'active' names an item by its 'value', and an item with no 'value' by its place, counted from 1, as in 'Steps', so a set written without values moves and 'helix-activate' says '1', '2' and so on. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, and so does a trackpad pinch or the wheel with Ctrl held, about the point under the pointer. A double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about and the wheel moves it. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. With 'controls', the viewer also draws zoom-out and zoom-in controls, for a pointer with no wheel and no second finger. Once a reader stops zooming, and at once for a key or a zoom control, the live region says the new scale in the words of 'zoom-status-label', such as "Zoomed to 150%". Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. A press on the empty area around the item closes the viewer, as a press on the backdrop does. Under 'max-zoom', a press beside the item zooms on a double press and closes nothing, and only the space outside the viewport closes the viewer. A press that dragged closes nothing. **Keyboard.** Opening moves focus to the viewer itself, which a screen reader names. | Key | What it does | |---|---| | Right, Down | Shows the next item. On a right-to-left page, Left does. While the item is zoomed, the arrows move about it instead. | | Left, Up | Shows the previous item. | | Home, End | Shows the first or the last item. | | '+', '-', '0' | Zooms in, zooms out, and puts the item back at its own size, where 'max-zoom' allows zooming. | | Tab, Shift+Tab | Moves through the controls in the viewer, from the last round to the first and from the first round to the last. | | Escape | Closes the viewer. A 'helix-before-close' listener can refuse. | A development build warns when a viewer opens with no 'label'. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
|
|
19466
19465
|
"helix-headless-lightbox": DefineCustomElement<
|
|
19467
19466
|
HelixHeadlessLightbox,
|
|
19468
19467
|
HelixHeadlessLightboxVueProps,
|
|
@@ -19612,7 +19611,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19612
19611
|
HelixHeadlessNotificationVueProps,
|
|
19613
19612
|
HelixHeadlessNotificationVueEvents
|
|
19614
19613
|
>;
|
|
19615
|
-
/** Notifications are slotted children. Each one is your own markup, with an avatar, a link, or a button in it. Feeds usually hold tens of items, so writing them out lets an item hold anything. The list does not virtualize. Windowing needs the list to own the data, and here you own it, so N notifications are N elements. For a feed of thousands, use a data table with a custom cell. Read state is reported to you. Marking read goes from the root to the item and from the item to you, so a canceled 'helix-read' changes nothing, and if you own 'read', nothing changes until you set it. 'unread' is derived from the items and written to an attribute, so a stylesheet and a badge can both use it without counting. **The feed is one 'Tab' stop for its rows.**
|
|
19614
|
+
/** Notifications are slotted children. Each one is your own markup, with an avatar, a link, or a button in it. Feeds usually hold tens of items, so writing them out lets an item hold anything. The list does not virtualize. Windowing needs the list to own the data, and here you own it, so N notifications are N elements. For a feed of thousands, use a data table with a custom cell. Read state is reported to you. Marking read goes from the root to the item and from the item to you, so a canceled 'helix-read' changes nothing, and if you own 'read', nothing changes until you set it. 'unread' is derived from the items and written to an attribute, so a stylesheet and a badge can both use it without counting. **The feed is one 'Tab' stop for its rows.** It is an APG feed: the list is a 'feed', busy while 'loading' is set, and each row is an 'article' that takes focus itself and is read by its label. 'ArrowDown' and 'ArrowUp' move to the next and the previous row, 'Home' and 'End' to the first and the last, and 'PageDown' and 'PageUp' move a row on or back from anywhere inside one, as in the APG feed pattern. The controls inside a row stay in the 'Tab' order. Set 'total' when the feed holds one page of a longer list, and each row says its place in the whole of it. **Keyboard.** | Key | What it does | |---|---| | Down, Up | On a row, moves to the next or the previous row. | | Home, End | On a row, moves to the first or the last row. | | Page Down, Page Up | From anywhere in a row, moves to the next or the previous row. | | Control+End | From anywhere in the feed, moves to the first control after it on the page. | | Control+Home | From anywhere in the feed, moves to the nearest control before it on the page. | | Tab | Moves through the controls in a row, and on out of the feed. | **A notification that arrives says so.** Unread rows added above the rows there were are counted in the live region, "1 new notification", in 'arrived-label'. Rows that arrive while 'loading' is set say nothing, so set it while a page is on its way. **'load-more' adds a button after the list** that sends 'helix-load-more', for a feed that holds one page of a longer list. Append the next page, set 'loading' while it is on its way, and take 'load-more' off once there is nothing more. While the feed is loading the button stays, so focus stays on it, and it is 'aria-disabled' and sends nothing. **'load-error' says a page could not be fetched**, such as "Could not load notifications": it shows under the rows there are, in the 'error' part, in place of the empty and loading lines, and a screen reader hears it. Clear it when you ask again. */
|
|
19616
19615
|
"helix-headless-notifications": DefineCustomElement<
|
|
19617
19616
|
HelixHeadlessNotifications,
|
|
19618
19617
|
HelixHeadlessNotificationsVueProps,
|
|
@@ -19936,7 +19935,7 @@ export interface WcToolkitVueGlobalComponents {
|
|
|
19936
19935
|
HelixHeadlessToolbarVueProps,
|
|
19937
19936
|
HelixHeadlessToolbarVueEvents
|
|
19938
19937
|
>;
|
|
19939
|
-
/** The trigger stays your own element. The bubble renders in the top layer through the popover API, so an ancestor with 'overflow: hidden' does not clip it and no 'z-index' is needed. 'FloatingController' positions it and flips it to another side when the preferred side does not fit. **Place the tooltip beside its trigger, name the trigger with 'for', and name the tooltip in the trigger's 'aria-describedby'.** The description is then in your own markup, so it is in the server's HTML and in the accessibility tree at rest, in every browser, before anyone points at the trigger or focuses it: '''html <helix-headless-button aria-describedby="save-tip" id="save">Save</helix-headless-button> <helix-headless-tooltip content="Save your work" for="save" id="save-tip"></helix-headless-tooltip> ''' Without the attribute, the tooltip links itself through an element reference on the control that takes focus, and it never writes into your markup before you act, so hydration stays intact. A trigger that is a Helix component is described at once, inside its own shadow root. A plain element in your markup is described when you first point at it or focus it, so a screen reader in reading mode meets it with no description until then. Where the browser has no element references, nothing links the two, and the tooltip warns once on first open. The tooltip can also wrap its trigger
|
|
19938
|
+
/** The trigger stays your own element. The bubble renders in the top layer through the popover API, so an ancestor with 'overflow: hidden' does not clip it and no 'z-index' is needed. 'FloatingController' positions it and flips it to another side when the preferred side does not fit. **Place the tooltip beside its trigger, name the trigger with 'for', and name the tooltip in the trigger's 'aria-describedby'.** The description is then in your own markup, so it is in the server's HTML and in the accessibility tree at rest, in every browser, before anyone points at the trigger or focuses it: '''html <helix-headless-button aria-describedby="save-tip" id="save">Save</helix-headless-button> <helix-headless-tooltip content="Save your work" for="save" id="save-tip"></helix-headless-tooltip> ''' Without the attribute, the tooltip links itself through an element reference on the control that takes focus, and it never writes into your markup before you act, so hydration stays intact. A trigger that is a Helix component is described at once, inside its own shadow root. A plain element in your markup is described when you first point at it or focus it, so a screen reader in reading mode meets it with no description until then. Where the browser has no element references, nothing links the two, and the tooltip warns once on first open. The tooltip can also wrap its trigger. A Helix component inside is described at once, and a plain element as in the 'for' form: when you first point at it or focus it, or at rest where it names the tooltip's 'id' in its own 'aria-describedby', which a reference to the element around it allows. In the 'for' form the tooltip itself is out of the accessibility tree while its bubble is down, so you meet its words once, as the trigger's description. A trigger whose name is already the tooltip's words, such as an icon button named Settings under a tooltip reading Settings, is not described by them again. The tooltip shows on hover and on focus. It hides on pointer leave, on blur, on Escape, and when the trigger is activated. The pointer can move from the trigger onto the bubble and the bubble stays, unless you set 'hoverable="false"'. 'delay' is how long the pointer rests before it shows, and 'delay-out' how long it stays once the pointer leaves. Once one tooltip is showing, moving to another trigger shows its tooltip with no 'delay', and the first one hides. The same holds for 'skip-delay' milliseconds after a tooltip hides, 300 unless you set it. 'show-on="focus"' shows the tooltip on keyboard focus only, for a hint a pointer does not need. */
|
|
19940
19939
|
"helix-headless-tooltip": DefineCustomElement<
|
|
19941
19940
|
HelixHeadlessTooltip,
|
|
19942
19941
|
HelixHeadlessTooltipVueProps,
|