@fusion.dev/helix-headless 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/custom-elements.json +39 -39
  2. package/dist/app-header/root/app-header-root.d.ts +8 -28
  3. package/dist/avatar/group/avatar-group.d.ts +5 -30
  4. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
  5. package/dist/chat/root/chat-root.d.ts +9 -28
  6. package/dist/color-picker/root/color-picker-root.d.ts +10 -28
  7. package/dist/combobox/root/combobox-root.d.ts +18 -60
  8. package/dist/copy-button/root/copy-button-root.d.ts +6 -21
  9. package/dist/data-table/root/data-table-root.d.ts +9 -32
  10. package/dist/date-input/root/date-input-root.d.ts +5 -21
  11. package/dist/date-picker/root/date-picker-root.d.ts +10 -35
  12. package/dist/dialog/root/dialog-root.d.ts +7 -29
  13. package/dist/donut-chart/root/donut-chart-root.d.ts +5 -25
  14. package/dist/file-input/root/file-input-root.d.ts +5 -22
  15. package/dist/heatmap/root/heatmap-root.d.ts +13 -36
  16. package/dist/image/root/image-root.d.ts +5 -22
  17. package/dist/input/root/input-root.d.ts +11 -29
  18. package/dist/kbd/root/kbd-root.d.ts +8 -26
  19. package/dist/legend/root/legend-root.d.ts +6 -24
  20. package/dist/listbox/root/listbox-root.d.ts +4 -26
  21. package/dist/megamenu/root/megamenu-root.d.ts +7 -39
  22. package/dist/meter/root/meter-root.d.ts +6 -24
  23. package/dist/number-input/root/number-input-root.d.ts +11 -20
  24. package/dist/outline/root/outline-root.d.ts +8 -27
  25. package/dist/pagination/root/pagination-root.d.ts +21 -54
  26. package/dist/pagination/summary/pagination-summary.d.ts +10 -31
  27. package/dist/progress/root/progress-root.d.ts +4 -21
  28. package/dist/rating/root/rating-root.d.ts +8 -31
  29. package/dist/slider/root/slider-root.d.ts +9 -32
  30. package/dist/splitter/root/splitter-root.d.ts +17 -85
  31. package/dist/steps/root/steps-root.d.ts +8 -26
  32. package/dist/steps/step/step.d.ts +11 -41
  33. package/dist/toast/item/toast-item.d.ts +6 -30
  34. package/dist/toggle/group/toggle-group.d.ts +7 -25
  35. package/dist/tooltip/root/tooltip-root.d.ts +14 -36
  36. package/dist/tour/root/tour-root.d.ts +6 -29
  37. package/dist/tree/item/tree-item.d.ts +13 -35
  38. package/dist/video/root/video-root.d.ts +12 -40
  39. package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -25
  40. package/dist/virtual-list/root/virtual-list-root.d.ts +5 -44
  41. package/package.json +17 -18
  42. package/{jsx.d.ts → types/jsx.d.ts} +724 -2537
  43. package/{vue.d.ts → types/vue.d.ts} +39 -39
  44. /package/{svelte.d.ts → types/svelte.d.ts} +0 -0
@@ -5,39 +5,18 @@ import { type TemplateResult } from 'lit';
5
5
  *
6
6
  * @description
7
7
  * Its own element rather than a part of `Pagination`, so a consumer decides
8
- * where it goes. Inside the run it could only ever be at one end of one row;
9
- * beside it, it goes above, below, in a table's caption, or on the other side of
10
- * the page, and the direction and order of the whole footer are the consumer's.
8
+ * where it goes: above, below, in a table's caption, or on the other side of
9
+ * the page. Inside the run it could only ever be at one end of one row.
11
10
  *
12
- * **It repeats `page`, `page-size` and `total`, and the cost of that is skew
13
- * rather than verbosity.** Those three come from the consumer's own query, so
14
- * writing them on two elements is one variable used twice; what it risks is the
15
- * two disagreeing, and a count reading `76-100 of 248` beside a run showing page
16
- * 7 is the same failure this element's own clamping exists to prevent, arriving
17
- * from the outside instead.
11
+ * **It repeats `page`, `page-size` and `total`, and the cost of that is skew.**
12
+ * Those three come from the consumer's own query, so writing them on two
13
+ * elements is one variable used twice; what it risks is the two disagreeing.
18
14
  *
19
- * **Nothing removes it at this level, and that was measured rather than
20
- * assumed.** A coordinating root can only reach children the consumer laid out
21
- * by writing attributes onto them, which a framework reports as a hydration
22
- * error, or through context, which is dead on a server: `@lit/context`
23
- * subscribes from `connectedCallback`, and Lit SSR does not call it, so every
24
- * value is `undefined` in exactly the render this element exists to be part of.
25
- * Confirmed against Lit SSR directly. The fork is real: children in the light
26
- * DOM mean the consumer owns the layout and no root can feed them; children in a
27
- * shadow root mean a root feeds them by ordinary binding and owns the layout.
28
- *
29
- * **It resolves one level up, at a composite, and the state is why.** `page`,
30
- * `page-size` and `total` are facts about a *result*, not about a pagination, so
31
- * the element that should hold them once is the one that holds the result: a
32
- * data table composing a pagination inside itself, rather than a pagination root
33
- * invented to hold three pagination elements together. That root would have been
34
- * plumbing; a table's paging state is the thing itself. And because a composite
35
- * renders its parts into its own shadow root, it lands on the side of the fork
36
- * where binding works and the server renders, at no cost to anyone.
37
- *
38
- * Renders nothing without a `total` and a `page-size`. A wrong count is worse
39
- * than none: it is the one number in a footer a reader cannot check against
40
- * anything else on screen.
15
+ * **Nothing removes that at this level, and it was measured.** A coordinating
16
+ * root can only reach light-DOM children by writing attributes onto them, which
17
+ * a framework reports as a hydration error, or through context, which is dead
18
+ * on a server: `@lit/context` subscribes from `connectedCallback`, and Lit SSR
19
+ * does not call it.
41
20
  *
42
21
  * @since 0.1.0
43
22
  * @status experimental
@@ -5,32 +5,15 @@ import { type PropertyValues, type TemplateResult } from 'lit';
5
5
  *
6
6
  * @description
7
7
  * Determinate by default, and `indeterminate` for a task whose total is not
8
- * known yet. `Loader` is still the right answer where the wait is short or has
9
- * no place of its own on the page; a bar earns its width where the work is the
10
- * subject of the region it sits in.
8
+ * known yet. `Loader` is still right where the wait is short or has no place of
9
+ * its own on the page.
11
10
  *
12
11
  * A bar that fills at a made-up rate would be a bar that lies, so the
13
12
  * indeterminate one does not fill: it runs a segment across the track, which
14
- * says work is happening and claims no proportion at all. `aria-valuenow` is
15
- * omitted with it, which is the platform's own signal for the same thing.
13
+ * says work is happening and claims no proportion. `aria-valuenow` is omitted
14
+ * with it, which is the platform's own signal for the same thing.
16
15
  *
17
16
  * **The fill is a fraction of the track, written as a custom property.**
18
- * `--progress-fraction` is derived from `value` and `max` rather than measured,
19
- * so it renders on a server with no layout and needs nothing after upgrade. That
20
- * is what keeps it out of the class of geometry this library writes only on the
21
- * client. A consumer never sets it: it carries a number this element computed
22
- * and CSS cannot, which is what lets a stylesheet draw the thing without
23
- * measuring anything itself.
24
- *
25
- * **`value` is clamped, and out-of-range input is not an error.** A count that
26
- * runs past its own total is ordinary in real applications, and a bar that
27
- * overflows its track or reports `aria-valuenow` above `aria-valuemax` is worse
28
- * than one that reads as finished.
29
- *
30
- * Semantics are on the host through `ElementInternals`, the same as everywhere
31
- * else: a `role` in the shadow root announces correctly and leaves the host
32
- * anonymous to anything walking the light DOM, and a `role` written onto the
33
- * host as an attribute is one a server's markup never had.
34
17
  *
35
18
  * @since 0.1.0
36
19
  * @status stable
@@ -7,39 +7,16 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
7
7
  * @description
8
8
  * **Half marks decide the shape.** Supporting them means the value is not an
9
9
  * integer and the targets are not the marks: five stars at a half step is ten
10
- * places to press, and a mark that is filled to the middle. The pointer handling
11
- * and `step` are both built around that rather than added over it.
10
+ * places to press. The pointer handling and `step` are built around that
11
+ * rather than added over it.
12
12
  *
13
- * **A partial mark is the whole mark, clipped.** Not a second glyph filled to
14
- * the middle: that needs a matching pair drawn for every mark anybody uses, and
15
- * the moment a consumer wants a heart or a circle they need to draw one too. The
16
- * fill is the same marks over the same marks, cut off partway, so any mark works
17
- * and any fraction does.
13
+ * **A partial mark is the whole mark, clipped**, not a second glyph filled to
14
+ * the middle: the fill is the same marks over the same marks, cut off partway,
15
+ * so any mark works and any fraction does.
18
16
  *
19
- * **Read-only is not this control grayed out, it is a different thing.** The
20
- * commoner use is showing a score nobody is being asked for, a product's
21
- * average, and that is not a control at all: it takes no focus, answers no keys,
22
- * has no options to choose between, and reads as one thing rather than as five.
23
- * So `readonly` is `role="img"` with the score in its name, where the control is
24
- * a radio group. A disabled control is still a control and still says so; this
25
- * is not one.
26
- *
27
- * **Moving is choosing here**, which is the radio group's reading and the
28
- * opposite of `Menu`'s: arriving at four stars *is* rating it four, because
29
- * nothing else follows and there is nothing to confirm. That is what
30
- * `KeyboardNavigationController` takes `selects` for, and why this can use it
31
- * where a menu cannot.
32
- *
33
- * **The mark is a stylesheet's, not a slot's.** A slot projects its content
34
- * once, and there are two layers of marks here: slotting a star would put it in
35
- * the track or the fill and leave the other empty. So the mark is a shape the
36
- * styled tier masks with, which is also what lets a partial one be a clip of the
37
- * whole rather than a second drawing of it.
38
- *
39
- * The properties below are written by this component and read by whoever draws
40
- * it. A consumer sets none of them: they carry a number this element computed
41
- * and CSS cannot, which is what lets a stylesheet on this tier draw the thing
42
- * without measuring anything itself.
17
+ * **Read-only is not this control grayed out.** The commoner use is showing a
18
+ * score nobody is being asked for, which is a reading rather than a disabled
19
+ * input, and it is announced as one.
43
20
  *
44
21
  * @since 0.1.0
45
22
  * @status experimental
@@ -6,45 +6,22 @@ declare const HelixHeadlessSlider_base: (new (...args: any[]) => import("@fusion
6
6
  *
7
7
  * @description
8
8
  * A real `<input type="range">`, so the drag, the arrow keys, Home and End, the
9
- * page keys and the touch target are all the platform's. Every one of those is
10
- * a thing a hand-built slider gets wrong, and the last is the one nobody
9
+ * page keys and the touch target are the platform's. The last is the one nobody
11
10
  * notices: a native range has a hit area larger than its thumb, sized by the
12
11
  * platform for a finger.
13
12
  *
14
13
  * **The value is a string, like every other form control's.** A range submits
15
14
  * text and `MixinControllerValue` holds text, so the number is a reading of the
16
- * value rather than the value itself. `valueAsNumber` is there for anything
17
- * doing arithmetic on it.
15
+ * value. `valueAsNumber` is there for arithmetic.
18
16
  *
19
- * **Marks are drawn rather than left to `<datalist>`.** A datalist's ticks
20
- * cannot be styled at all, and Firefox does not render them for a range at all,
21
- * so the platform's version is a mark that looks like someone else's design
22
- * where it appears and no mark where it does not. Drawing them costs the
23
- * semantics nothing, because a mark is decoration: what a reader can actually
24
- * land on is `step`, which the input enforces whether or not anything is drawn.
17
+ * **Marks are drawn rather than left to `<datalist>`**, whose ticks cannot be
18
+ * styled and which Firefox does not render for a range at all. A mark is
19
+ * decoration; what a reader can land on is `step`, which the input enforces
20
+ * whether or not anything is drawn. `markers` is a count rather than a flag, so
21
+ * a slider from zero to a hundred cannot silently ask for a hundred and one.
25
22
  *
26
- * `markers` is a count rather than a flag tied to `step`. A flag reads well
27
- * until a slider from zero to a hundred stepping by one asks for a hundred and
28
- * one ticks, and then it is either noise or a silent refusal to draw. A number
29
- * is what the reader sees, so it cannot surprise anyone.
30
- *
31
- * **A range is two of them, not a hand-built one.** There is no native
32
- * two-thumb range, so two are stacked on one track and each thumb keeps its own
33
- * drag, its own arrow keys, its own Home and End and its own finger-sized hit
34
- * area. Rebuilding would throw away every argument this component is made of,
35
- * to gain a second handle.
36
- *
37
- * Crossing is stopped in the handler rather than by the bounds, and that is not
38
- * the obvious way round. Giving the lower input `max` of the upper reads well
39
- * and breaks the drawing: an input's thumb sits at a fraction of *its own*
40
- * range, so a lower thumb bounded at the upper one paints against a shorter
41
- * track and the two stop lining up. Both inputs span the whole range and the
42
- * values are clamped against each other on the way in.
43
- *
44
- * The properties below are written by this component and read by whoever draws
45
- * it. A consumer sets none of them: they carry a number this element computed
46
- * and CSS cannot, which is what lets a stylesheet on this tier draw the thing
47
- * without measuring anything itself.
23
+ * **A range is two of them.** There is no native two-thumb range, so two are
24
+ * stacked on one track and each thumb keeps its own.
48
25
  *
49
26
  * @since 0.1.0
50
27
  * @status experimental
@@ -4,101 +4,33 @@ import { type PropertyValues, type TemplateResult } from 'lit';
4
4
  * @summary Two panes and a divider the reader can move.
5
5
  *
6
6
  * @description
7
- * **One axis, and nesting is how you get two.** The sandbox this was taken from
8
- * moves a cross: a divider down the middle, another across the bottom, and a
9
- * corner that moves both. That is a layout rather than a component, and every
10
- * part of it that is worth sharing is one divider between two panes. A splitter
11
- * inside a splitter gives the cross back, and gives the three-pane and the
12
- * four-pane arrangements it never had.
7
+ * **One axis, and nesting is how you get two.** A splitter inside a splitter
8
+ * gives back the cross, and gives the three-pane and four-pane arrangements a
9
+ * single divider never had.
13
10
  *
14
11
  * **Where two of them cross there is a corner, and it moves both.** A splitter
15
- * slotted into a pane of another, at right angles to it, has one end of its
16
- * divider sitting exactly on the other's. That end grows a handle: `move` under
17
- * the pointer, both arrow axes on the keyboard, and a drag that carries the two
18
- * positions at once.
12
+ * slotted into a pane of another, at right angles to it, grows a handle at the
13
+ * crossing: `move` under the pointer, both arrow axes on the keyboard, and a
14
+ * drag that carries the two positions at once. It appears at `firstUpdated`
15
+ * rather than in the served markup, being an affordance rather than content,
16
+ * and a splitter with no corner yet is a splitter with two working dividers.
19
17
  *
20
- * **The outer splitter draws it and the nested one announces itself upward.**
21
- * The nested one drawing its own is the tempting version, since it already
22
- * knows where its divider begins and needs no measurement of the other, and it
23
- * is clipped: the crossing lies on the boundary between a pane and the divider
24
- * beside it, a handle centered there reaches back over the boundary, and a pane
25
- * is `overflow: auto`. Exactly half the corner is cut off. The outer separator
26
- * is the one element that already straddles the seam, so the corner belongs in
27
- * it.
28
- *
29
- * That makes the channel between the two a single call in a single direction:
30
- * `cross(child, at)` says where the child crosses, `moveTo` drives either one,
31
- * and neither reads the other's state. The child is what calls it, because a
32
- * parent cannot poll for a child that has not upgraded yet.
33
- *
34
- * The one number it carries is a percentage rather than a measurement, which is
35
- * what keeps either of them from measuring the other, and it assumes the nested
36
- * splitter fills its pane. That is what slotting one into a pane does. Give the
37
- * nested splitter its own inset, or wrap it in something smaller than the pane,
38
- * and the corner is drawn where the crossing would be rather than where it is.
39
- *
40
- * **It is a client-side enhancement and says so.** Finding the parent means
41
- * inspecting the tree, which a server cannot do, so the corner appears at
42
- * `firstUpdated` and never in the served markup. That is allowed for exactly
43
- * this: it is an affordance rather than content, and a splitter with no corner
44
- * yet is a splitter with two working dividers.
45
- *
46
- * Where two dividers are parallel there is no corner, because there is nothing
47
- * to take hold of. Where they cross without a corner, the inner divider takes
48
- * the pointer: every separator sits on the same layer, so a tie goes to document
49
- * order and a deeper splitter is always later.
50
- *
51
- * **A divider that is moving says so, whoever is moving it.** `:hover` cannot
52
- * carry that: a drag holds the pointer through capture and a fast one leaves the
53
- * target behind, and a corner moves the nested divider while the reader is on
54
- * the crossing, nowhere near it. So a drag in progress is a state, and both
55
- * dividers a corner moves are lit for as long as it moves them.
56
- *
57
- * **The divider is a real `role="separator"` with `aria-valuenow`, moved by the
58
- * arrow keys as well as by pointer.** A divider only a mouse can move is
59
- * unusable without one, which is the reason the sandbox's carries the same, and
60
- * `Home` and `End` take it to its bounds.
18
+ * **The divider is a real `role="separator"` with `aria-valuenow`**, moved by
19
+ * the arrow keys as well as by pointer, with `Home` and `End` taking it to its
20
+ * bounds. A drag in progress is a state rather than `:hover`, so both dividers
21
+ * a corner moves are lit for as long as it moves them.
61
22
  *
62
23
  * **It goes where it is put, all the way to either end.** `min` and `max` are
63
24
  * nothing and everything unless a consumer says otherwise, because a divider
64
- * that stops dead short of the edge gives a reader no way to put a pane away.
65
- * Where a pane should keep a sliver of itself, only whoever put the tabs on it
66
- * knows how much, so they say so.
25
+ * that stops short of the edge gives a reader no way to put a pane away.
67
26
  *
68
27
  * **A pane can be shut, and that is not the same as a divider at the edge.**
69
28
  * The geometry is identical and the knowledge is not: only a shut pane knows
70
29
  * where to open back to. So `collapsed` is a second state rather than a reading
71
- * of the position, and the position it opens to is simply the one collapsing
72
- * never overwrote. `collapsed-size` keeps a sliver showing where a pane has a
73
- * tab strip worth leaving, and collapse overrides `min` and `max`, which is
74
- * what those are for: they keep a pane from vanishing by accident, and this is
75
- * the deliberate version.
76
- *
77
- * The two are kept in step in one direction only: a drag that settles on the
78
- * collapsed size latches shut, and any move opens it again. Otherwise a reader
79
- * could drag a pane closed and the consumer's own button would still be
80
- * offering to close it.
81
- *
82
- * A pane shut to nothing is told apart from one shut to a sliver, because the
83
- * two want different dividers: a sliver still has a boundary worth drawing, and
84
- * nothing leaves the divider sitting on the container's own edge.
85
- *
86
- * **The box is measured once, when a drag starts.** Measuring per move is a
87
- * forced layout on every pointer event, in the middle of a gesture whose whole
88
- * job is to stay ahead of the pointer, and nothing about the box moves while the
89
- * divider does.
90
- *
91
- * **`helix-before-resize` fires when it settles, not while it moves.** A drag is a
92
- * stream of positions and only the one it ends at is a preference; announcing
93
- * each would ask a consumer to write to storage a hundred times to record one
94
- * decision. Nothing is stored here either: where a preference lives, and whether
95
- * it should be kept at all, is the consumer's to decide, and a component writing
96
- * to storage on its own would be deciding for all of them under a key it chose.
97
- *
98
- * The properties below are written by this component and read by whoever draws
99
- * it. A consumer sets none of them: they carry a number this element computed
100
- * and CSS cannot, which is what lets a stylesheet on this tier draw the thing
101
- * without measuring anything itself.
30
+ * of the position, and the position it opens to is the one collapsing never
31
+ * overwrote. `collapsed-size` keeps a sliver showing where a pane has a tab
32
+ * strip worth leaving, and collapse overrides `min` and `max`, which is what
33
+ * those are for.
102
34
  *
103
35
  * @since 0.1.0
104
36
  * @status experimental
@@ -5,34 +5,16 @@ declare const HelixHeadlessSteps_base: (new (...args: any[]) => import("@fusion.
5
5
  * @summary A sequence of stages, and where the reader is in it.
6
6
  *
7
7
  * @description
8
- * **`active` names where the reader is. `complete` stays on each step.** They
9
- * are two different facts and only one of them is positional. Deriving both
10
- * from a position is the obvious design and it is wrong the first time anybody
11
- * steps back: return to stage one of three and stages one and two are still
12
- * finished, while "everything before the active one" says only the first is.
13
- * So this element drives `current` and never touches `complete`.
8
+ * **`active` names where the reader is. `complete` stays on each step.** Only
9
+ * one of them is positional: return to stage one of three and stages one and
10
+ * two are still finished, where "everything before the active one" says only
11
+ * the first is. So this element drives `current` and never touches `complete`.
14
12
  *
15
13
  * **`active` is optional, and a sequence without it still renders.** Left
16
- * unset, each step's own `current` stands and nothing here overwrites it, which
17
- * is what lets the whole sequence be right in the server's markup: this element
18
- * would have to count its slotted children to know which one is third, and the
19
- * server has no children to count. Set it, and it wins, because it is a
20
- * statement about the sequence where the attribute on a step is a statement
21
- * about one step.
22
- *
23
- * That is also why the numbering is not JavaScript. It is a CSS counter in the
24
- * tier above, which the browser resolves at layout with no script at all, so
25
- * the third step reads "3" in the server's own markup.
26
- *
27
- * **The connector belongs to the step, not to the list.** Each one draws the
28
- * line that arrives at it and hides it when it is first, the same arrangement
29
- * Breadcrumbs uses for its separator and for the same reason: a line drawn
30
- * between items needs either an index or a parent that counts, and drawing it
31
- * on the item needs neither.
32
- *
33
- * `role="list"` on the host rather than an `<ol>` in the shadow root. The steps
34
- * are the consumer's elements in the light DOM, so an `<ol>` here would be a
35
- * list whose items are somewhere else.
14
+ * unset, each step's own `current` stands, which is what lets the whole
15
+ * sequence be right in the server's markup: this element would have to count
16
+ * its slotted children to know which is third, and the server has none to
17
+ * count.
36
18
  *
37
19
  * @since 0.1.0
38
20
  * @status experimental
@@ -5,51 +5,21 @@ import '../../button/index.js';
5
5
  * @summary One stage in a sequence.
6
6
  *
7
7
  * @description
8
- * **The name is a button, and only the name.** A stepper is something a reader
9
- * goes back through, and the thing they reach for is the name of the stage. The
10
- * marker is `aria-hidden` decoration, so wrapping it in the button would add
11
- * hit area and no meaning: the accessible name would be the text either way,
12
- * and what is pressable would stop being the same shape as what is readable.
8
+ * **The name is a button, and only the name.** The marker is `aria-hidden`
9
+ * decoration, so wrapping it would add hit area and no meaning. It is
10
+ * `helix-button` rather than a `<button>` this element resets: the hover wash,
11
+ * the focus ring and the disabled treatment are decisions the button carries.
13
12
  *
14
- * It is `helix-button`, not a `<button>` this element resets and dresses: the
15
- * hover wash, the focus ring and the disabled treatment are decisions the
16
- * button already carries. `ghost` is the quiet shape, transparent until it is
17
- * pointed at.
18
- *
19
- * It says nothing about where a reader may go. Every step is pressable and
13
+ * **It says nothing about where a reader may go.** Every step is pressable and
20
14
  * announces itself with `helix-select`; refusing the ones ahead is `disabled`,
21
- * which the consumer sets because only the consumer knows whether a form can be
22
- * skipped. A component that guessed would be wrong on the first wizard that
23
- * lets you jump to the end.
15
+ * which the consumer sets, because only they know whether a form can be
16
+ * skipped.
24
17
  *
25
18
  * **The marker is a slot whose fallback is the state.** A finished stage shows
26
- * a check, the current one a target, and one not yet reached an empty ring:
27
- * three marks that say what a reader wants to know without a legend. A consumer
28
- * who wants their own fills the slot instead.
29
- *
30
- * The step renders exactly one of the three, chosen from its own two booleans.
31
- * Rendering all three and hiding two in CSS would work and is worse: the
32
- * accessibility tree would carry marks that are not there, and the markup would
33
- * say three things about a stage that is one.
34
- *
35
- * Numbering belongs to the tier above. `numeric` hides the mark and shows a CSS
36
- * counter, which the browser resolves at layout, so the digit costs no script
37
- * and is right in the server's markup however the steps are ordered. Nothing
38
- * here knows which appearance is in use.
39
- *
40
- * **`complete` and `current` are separate, and both can be false.** A stage
41
- * that is neither is one the reader has not reached, which is the majority of
42
- * any sequence and therefore the state that needs no attribute. They can also
43
- * both be true: a reader who steps back into a finished stage is in it and has
44
- * finished it, and a stepper that forgets the second is one that loses its
45
- * checks the moment somebody reviews their answers.
46
- *
47
- * **The `content` slot opens on the current step, and only down a column.** A
48
- * row has no room under a step to put a form in, and stretching one to fit
49
- * would set every step's height by the tallest. `current` is what opens it, so
50
- * the state that says where the reader is is also the state that shows them the
51
- * stage: one attribute, no second flag to keep in step with it, and it renders
52
- * open on the server rather than after hydration.
19
+ * a check, the current one a target, one not yet reached an empty ring. Exactly
20
+ * one is rendered, chosen from the step's own two booleans, rather than three
21
+ * with two hidden in CSS: the accessibility tree would otherwise carry marks
22
+ * that are not there.
53
23
  *
54
24
  * @since 0.1.0
55
25
  * @status experimental
@@ -6,40 +6,16 @@ declare const HelixHeadlessToastItem_base: (new (...args: any[]) => import("@fus
6
6
  *
7
7
  * @description
8
8
  * An element rather than a slot, because it carries a timeout, a tone, a
9
- * dismiss control and a lifetime that pauses: behavior, state and API, which
10
- * is the test for whether a region becomes an element in this library.
9
+ * dismiss control and a lifetime that pauses: behavior, state and API.
11
10
  *
12
11
  * **The timer is the item's own.** Held by the region, one message arriving
13
12
  * would restart another's, so a stack of three would go from three seconds each
14
- * to nine for the last one. Each message is on its own clock from the moment it
15
- * is rendered.
13
+ * to nine for the last.
16
14
  *
17
- * **A message is the opposite of the page it is over.** Inverted by default,
18
- * because a thing arriving in a corner has to be told apart from the page in
19
- * the moment before it is read, and inverting does that without spending a
20
- * color that means something. It is a flip of `color-scheme` rather than a
21
- * named inverse surface: every token in the subtree re-resolves, so a `Retry`
22
- * a consumer slots in comes out right without knowing where it is. `Tooltip`
23
- * can name the inverse surface directly because it holds no controls; this
24
- * cannot. Set `data-color-mode` on the region to take the page's mode instead.
25
- *
26
- * **No duration means it stays.** That is the safe default rather than the
27
- * common one: anything carrying an action has to still be there when the reader
28
- * decides to take it, and a component cannot tell from the outside whether the
29
- * message it was given is disposable.
30
- *
31
- * **The clock stops while it is being read.** Hover pauses it, and so does
32
- * focus landing anywhere inside, which is the case that matters more: a
33
- * keyboard reader tabbing towards the action in a toast is exactly the person a
34
- * timer must not race. Both resume where they left off rather than starting
35
- * again, so a message half-read does not get a full second life every time a
36
- * pointer crosses it.
37
- *
38
- * **Going away is a request, never an act.** It dispatches a cancelable
39
- * `helix-dismiss` and does nothing else: the consumer owns the list, so the
40
- * item removing itself would leave the two disagreeing. Auto-dismiss and the
41
- * dismiss control raise the same event, so a consumer handles one path and not
42
- * two.
15
+ * **A message is the opposite of the page it is over.** Inverted by default, so
16
+ * a thing arriving in a corner is told apart from the page before it is read,
17
+ * and by a flip of `color-scheme` rather than by spending a color that means
18
+ * something.
43
19
  *
44
20
  * @since 0.1.0
45
21
  * @status experimental
@@ -6,32 +6,14 @@ declare const HelixHeadlessToggleGroup_base: (new (...args: any[]) => import("@f
6
6
  *
7
7
  * @description
8
8
  * The indicator is one element that travels, not a background that appears on
9
- * whichever item is current. That difference is the whole point: a fill that
10
- * swaps is two things changing at once and reads as a flicker, while one that
11
- * moves is a single object the eye follows, and it says where the selection
12
- * came from as well as where it went.
9
+ * whichever item is current. A fill that swaps is two things changing at once
10
+ * and reads as a flicker; one that moves is a single object the eye follows,
11
+ * and it says where the selection came from as well as where it went.
13
12
  *
14
- * Its whole box is measured from the selected item and written onto
15
- * the indicator as custom properties, because labels are different lengths and
16
- * no proportion of the group is the right answer. Measurement is client-side by
17
- * necessity, so the server renders the indicator hidden and it fades in once it
18
- * has somewhere to be, which is the harmless direction: it appears rather than
19
- * jumping from a wrong place.
20
- *
21
- * A radio group, and only that. Navigation is links marked with `aria-current`
22
- * and styled by the `data-navigation-item` recipe: radio semantics would announce a
23
- * set of destinations as a set of choices. A tab controls a panel.
24
- *
25
- * Being a radio group, it is a form control, and it says so through
26
- * `HelixFormElement`: it reports its value under a `name`, comes back to the
27
- * markup's choice on reset, and restores the one a reader made when the browser
28
- * brings a form back.
29
- *
30
- * The semantics were already right: the host has carried `role="radiogroup"`
31
- * and the items `role="radio"` from the start. What none of it did was reach a
32
- * form. A button in a shadow root submits nothing whatever its role, so the
33
- * value has to be reported by the host, which is the only thing a form can
34
- * see.
13
+ * Its box is measured from the selected item and written onto the indicator as
14
+ * custom properties, labels being different lengths. Measurement is client-side
15
+ * by necessity, so the server renders the indicator hidden and it fades in once
16
+ * it has somewhere to be, which is the harmless direction.
35
17
  *
36
18
  * @since 0.1.0
37
19
  * @status experimental
@@ -7,57 +7,35 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
7
7
  * @description
8
8
  * The trigger is slotted and stays the consumer's own element. The bubble is
9
9
  * rendered here, in the top layer through the popover API, so it clears any
10
- * ancestor with `overflow: hidden` without a `z-index` anywhere.
10
+ * ancestor with `overflow: hidden` without a `z-index` anywhere. Position comes
11
+ * from `FloatingController`, which flips to another side when the preferred one
12
+ * does not fit.
11
13
  *
12
- * Position comes from `FloatingController`, which flips to another side when
13
- * the preferred one does not fit and slides along it to stay in view.
14
- *
15
- * **Two forms, and they are not equivalent for a screen reader.**
16
- *
17
- * Wrapping is the convenience form and is right where the bubble decorates a
18
- * control that already says what it is. The trigger stays the consumer's own
19
- * element, slotted, and nothing here can describe it: an IDREF cannot cross a
20
- * shadow boundary, an element reference is valid only into the same tree or a
21
- * shadow-including *ancestor* (the bubble's tree is neither, it is inward), and
22
- * a string on the trigger means writing to markup the consumer server-rendered.
23
- * All three measured.
14
+ * **Two forms, and they are not equivalent for a screen reader.** Wrapping is
15
+ * the convenience form and is right where the bubble decorates a control that
16
+ * already says what it is: nothing here can describe a slotted trigger, an
17
+ * IDREF being unable to cross a shadow boundary.
24
18
  *
25
19
  * `for` is the form that works. The tooltip sits *beside* the trigger in the
26
- * consumer's own tree and names it by id, so both are in one tree and an IDREF
27
- * between them is legal in the ordinary way:
20
+ * consumer's own tree and names it by id, so an IDREF between them is legal in
21
+ * the ordinary way:
28
22
  *
29
23
  * ```html
30
24
  * <helix-button id="save" aria-describedby="save-tip">Save</helix-button>
31
25
  * <helix-tooltip id="save-tip" for="save" content="Save your work"></helix-tooltip>
32
26
  * ```
33
27
  *
34
- * Note that the reference points at *this host*, not at the bubble inside its
35
- * shadow root: the description is computed from the flat tree, which descends
36
- * into shadow content on its own.
28
+ * The reference points at *this host*, not at the bubble in its shadow root:
29
+ * the description is computed from the flat tree, which descends into shadow
30
+ * content on its own.
37
31
  *
38
32
  * **The consumer writes that `aria-describedby`, and nothing here writes it for
39
- * them.** WebAwesome and Spectrum Web Components both do write it, with
40
- * `setAttribute` on the trigger at runtime, which is the one thing this library
41
- * declines everywhere: React rendered that element on the server without the
42
- * attribute and reports a mismatch it will not patch up. Two ids in the markup
43
- * is the whole cost of the version that is correct before any JavaScript runs.
44
- *
45
- * Because it is the consumer's line to write, it is also theirs to forget, so
46
- * `for` audits itself on first open and says so once, rather than on every
47
- * open, since a warning that repeats is one people learn to filter out.
33
+ * them.** Setting it at runtime is a hydration mismatch React will not patch
34
+ * up. `for` audits itself on first open and warns once where it is missing.
48
35
  *
49
36
  * It shows on hover and on focus, and hides on leave, on blur, on Escape, and
50
37
  * once the trigger has been activated: the hint is spent when the control has
51
38
  * been used.
52
- * A tooltip that answers only the pointer is one a keyboard reader never sees.
53
- *
54
- * The pointer waits out `delay` first, or sweeping a row of controls flashes a
55
- * tooltip for each of them. Focus does not wait: a keyboard reader landing on a
56
- * control has already committed to it.
57
- *
58
- * Open state comes from `MixinControllerOpen`, so it announces `helix-before-open` and
59
- * `helix-before-close` like every other overlay here, and a consumer can drive it with
60
- * `open` where they need to.
61
39
  *
62
40
  * @since 0.1.0
63
41
  * @status experimental