@fusion.dev/helix-headless 0.53.1 → 0.53.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 (71) hide show
  1. package/custom-elements.json +184 -193
  2. package/dist/accordion/item/accordion-item.d.ts +13 -13
  3. package/dist/accordion/root/accordion-root.d.ts +1 -1
  4. package/dist/area-chart/root/area-chart-root.js +1 -1
  5. package/dist/avatar/group/avatar-group.d.ts +11 -11
  6. package/dist/bar-chart/root/bar-chart-root.d.ts +1 -1
  7. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +6 -6
  8. package/dist/button/root/button-root.d.ts +1 -1
  9. package/dist/card/root/card-root.d.ts +1 -1
  10. package/dist/carousel/root/carousel-root.d.ts +19 -20
  11. package/dist/chat/composer/chat-composer.d.ts +6 -6
  12. package/dist/chat/root/chat-root.d.ts +9 -9
  13. package/dist/checkbox/root/checkbox-root.d.ts +2 -2
  14. package/dist/checkbox-group/root/checkbox-group-root.d.ts +4 -4
  15. package/dist/code-block/root/code-block-root.d.ts +5 -5
  16. package/dist/color-input/root/color-input-root.d.ts +3 -3
  17. package/dist/color-picker/root/color-picker-root.d.ts +14 -14
  18. package/dist/combobox/root/combobox-root.d.ts +9 -5
  19. package/dist/combobox/root/combobox-root.js +2 -3
  20. package/dist/command/root/command-root.d.ts +6 -7
  21. package/dist/data-table/root/data-table-root.d.ts +42 -41
  22. package/dist/data-table/root/order.d.ts +3 -3
  23. package/dist/date-input/root/date-input-root.d.ts +12 -11
  24. package/dist/dialog/root/dialog-root.d.ts +4 -4
  25. package/dist/donut-chart/root/donut-chart-root.d.ts +1 -1
  26. package/dist/drawer/root/drawer-root.d.ts +5 -5
  27. package/dist/filter-input/menu/filter-menu.d.ts +7 -1
  28. package/dist/filter-input/menu/filter-menu.js +2 -1
  29. package/dist/filter-input/root/filter-input-root.d.ts +13 -14
  30. package/dist/format-date/root/format-date-root.d.ts +6 -5
  31. package/dist/heatmap/root/heatmap-root.d.ts +11 -16
  32. package/dist/image/root/image-root.d.ts +4 -4
  33. package/dist/input/root/input-root.d.ts +7 -7
  34. package/dist/line-chart/root/line-chart-root.d.ts +1 -2
  35. package/dist/list/item/list-item.d.ts +6 -7
  36. package/dist/list/root/list-root.d.ts +4 -4
  37. package/dist/megamenu/root/megamenu-root.d.ts +4 -4
  38. package/dist/notifications/notification/notification.d.ts +10 -10
  39. package/dist/notifications/root/notifications-root.d.ts +1 -1
  40. package/dist/object-inspector/root/object-inspector-root.d.ts +10 -0
  41. package/dist/object-inspector/root/object-inspector-root.js +6 -3
  42. package/dist/option/root/option-root.d.ts +7 -8
  43. package/dist/pagination/root/pagination-root.d.ts +5 -5
  44. package/dist/pagination/size/pagination-size.d.ts +2 -1
  45. package/dist/pin-input/root/pin-input-root.d.ts +4 -4
  46. package/dist/popover/root/popover-root.d.ts +7 -6
  47. package/dist/radio/root/radio-root.d.ts +1 -1
  48. package/dist/speed-dial/root/speed-dial-root.d.ts +8 -9
  49. package/dist/stat/root/stat-root.d.ts +3 -3
  50. package/dist/steps/root/steps-root.d.ts +1 -1
  51. package/dist/steps/step/step.d.ts +5 -5
  52. package/dist/table/column/table-column.d.ts +28 -28
  53. package/dist/table/root/table-root.d.ts +14 -17
  54. package/dist/table/row/table-row.d.ts +4 -4
  55. package/dist/tabs/panel/tab-panel.d.ts +2 -2
  56. package/dist/time-input/root/time-input-root.d.ts +13 -13
  57. package/dist/time-picker/root/time-picker-root.d.ts +8 -8
  58. package/dist/toast/root/toast-root.d.ts +2 -2
  59. package/dist/toggle/root/toggle-root.d.ts +5 -5
  60. package/dist/tooltip/root/tooltip-root.d.ts +2 -2
  61. package/dist/tour/stop/tour-stop.d.ts +3 -3
  62. package/dist/tree/item/tree-item.d.ts +2 -2
  63. package/dist/tree/root/tree-root.d.ts +8 -7
  64. package/dist/tree/root/tree-root.js +1 -1
  65. package/dist/video-playlist/menu/video-playlist-menu.d.ts +7 -1
  66. package/dist/video-playlist/menu/video-playlist-menu.js +4 -2
  67. package/dist/video-playlist/root/video-playlist-root.d.ts +5 -5
  68. package/dist/video-playlist/root/video-playlist-root.js +2 -3
  69. package/package.json +5 -5
  70. package/types/jsx.d.ts +958 -990
  71. package/types/vue.d.ts +229 -244
package/types/vue.d.ts CHANGED
@@ -270,9 +270,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
270
270
  last reader did rather than what the author wrote. `:state(open)` carries
271
271
  the resolved state for stylesheets, which is what the mirror is for. */
272
272
  open?: (HelixHeadlessAccordionItem["open"]) | undefined;
273
- /** Initial open state for uncontrolled use, where nothing declared one. */
273
+ /** Whether the markup declared it open. Ignored once `open` is written. */
274
274
  "default-open"?: (HelixHeadlessAccordionItem["defaultOpen"]) | undefined;
275
- /** Initial open state for uncontrolled use, where nothing declared one. */
275
+ /** Whether the markup declared it open. Ignored once `open` is written. */
276
276
  defaultOpen?: (HelixHeadlessAccordionItem["defaultOpen"]) | undefined;
277
277
  };
278
278
 
@@ -459,13 +459,13 @@ export type HelixHeadlessAvatarGroupVueProps = {
459
459
  Unset shows all of them, which is what no limit means and is more useful
460
460
  than refusing to render.
461
461
 
462
- **Reflected, because the fold is a stylesheet rule and nothing else.** The
463
- styled tier hides past the limit with `:host([max="N"]) ::slotted(:nth-child(n + N+1))`,
464
- so the attribute *is* the mechanism: a `max` that reaches this property and
465
- never reaches the host matches no rule, and every avatar is drawn beside a
466
- count claiming some are hidden. Markup is the safe path and hides the fault;
467
- a script is the broken one, and React takes it for everyone, assigning a
468
- matching property rather than an attribute.
462
+ **Reflected, because the fold is a stylesheet rule and nothing else.** A
463
+ sheet hides past the limit one selector per value, as `FOLDS_UP_TO`
464
+ describes, so the attribute *is* the mechanism: a `max` that reaches this
465
+ property and never reaches the host matches no rule, and every avatar is
466
+ drawn beside a count claiming some are hidden. Markup is the safe path and
467
+ hides the fault; a script is the broken one, and React takes it for
468
+ everyone, assigning a matching property rather than an attribute.
469
469
 
470
470
  **Optional rather than defaulted, per the rule that a reflected property
471
471
  takes no default**: `max = 0` would stamp `max="0"` onto every host that
@@ -647,12 +647,12 @@ export type HelixHeadlessBreadcrumbVueProps = {
647
647
  current?: (HelixHeadlessBreadcrumb["current"]) | undefined;
648
648
  /** Where the crumb goes, and nothing where it is the current page.
649
649
 
650
- **Optional and reflected, because a stylesheet does select on it.**
651
- `breadcrumb.css` writes `:host(:not([href])) [part="link"]` to take the
652
- block padding off a crumb that is not a link, so the attribute is what
653
- decides how tall a crumb is. Unreflected, an `href` set from script reached
654
- the property, rendered the anchor, and left the host looking unlinked: the
655
- crumb drew at 20px where a markup twin drew at 28.
650
+ **Optional and reflected, because a stylesheet does select on it.** A sheet
651
+ writes `:host(:not([href])) [part="link"]` to take the block padding off a
652
+ crumb that is not a link, so the attribute is what decides how tall a crumb
653
+ is. Unreflected, an `href` set from script reached the property, rendered
654
+ the anchor, and left the host looking unlinked: the crumb drew at 20px
655
+ where a markup twin drew at 28.
656
656
 
657
657
  Optional rather than defaulted, which is the general rule that a reflected
658
658
  property takes no default: an `href` written onto every host would be a link
@@ -714,7 +714,7 @@ the trigger silently does nothing at all. A wrapper has to hand them down,
714
714
  the same way `label` becomes `aria-label` in there.
715
715
 
716
716
  ```html
717
- <helix-button commandfor="confirm" command="--show">Delete…</helix-button>
717
+ <helix-headless-button commandfor="confirm" command="--show">Delete…</helix-headless-button>
718
718
  ```
719
719
 
720
720
  `commandFor` spells its attribute out, because Lit lowercases a property
@@ -922,12 +922,11 @@ export type HelixHeadlessCarouselVueProps = {
922
922
  autoplay?: (HelixHeadlessCarousel["autoplay"]) | undefined;
923
923
  /** The slide in view, counted from zero.
924
924
 
925
- Reading gives the real slide, in either mode. Writing sets it, the way a
926
- script assigning to a native control does. Which mode the carousel is in is
927
- read once, at the first update, from whether anything had declared an
928
- `index` by then: declared, and the consumer owns it and the carousel only
929
- announces where it would have gone; not declared, and the carousel owns it
930
- and `default-index` says where it starts.
925
+ Reading gives the real slide. Writing always applies, the way a script
926
+ assigning to a native control does, and is a seed and a correction rather
927
+ than a claim of ownership: a consumer who wants the decision refuses the
928
+ `helix-select`. `default-index` is where the carousel starts until
929
+ something moves it.
931
930
 
932
931
  The same contract the four mixins carry, written out here rather than
933
932
  extracted, because a slide is addressed by position and every one of those
@@ -995,13 +994,13 @@ end while the slides stop moving a third of the way through.
995
994
  **The number is published to the styles rather than enumerated by them**,
996
995
  as `--carousel-per-view` on the track, which is what keeps a width and a
997
996
  count from disagreeing. A sheet can only name a value it wrote a rule for,
998
- so the styled tier enumerated `per-view="2"` through `5` and called five a
999
- judgment; above it the pane fell back to one across while this file went on
1000
- counting positions. Measured in Chromium over eight slides, six across gave
1001
- three dots, a pane taking the whole track and five slides reachable only by
1002
- dragging. Written from here there is no ceiling to exceed, and a consumer's
1003
- own sheet reads the same declaration the styled one does. `runEnd` publishes
1004
- its correction the same way and for the same reason.
997
+ so a sheet enumerating `per-view="2"` through `5` is a ceiling of five, and
998
+ above it the pane falls back to one across while this file goes on counting
999
+ positions. Measured in Chromium over eight slides against such a sheet, six
1000
+ across gave three dots, a pane taking the whole track and five slides
1001
+ reachable only by dragging. Published from here there is no ceiling to
1002
+ exceed, and every sheet reads the same declaration. `runEnd` publishes its
1003
+ correction the same way and for the same reason.
1005
1004
 
1006
1005
  **On the track and not on the host.** A custom property on the host is a
1007
1006
  reflected attribute by another name: it would arrive on upgrade, and a
@@ -1026,8 +1025,8 @@ inline the count would outrank the sheet that computes it, which is why an
1026
1025
  `auto` track is handed nothing. A count stays for the design that calls for
1027
1026
  exactly three.
1028
1027
 
1029
- The styled sheet says how it divides, and the headless `auto` example
1030
- carries the same three lines for a consumer writing their own.
1028
+ A sheet says how it divides, and the `auto` example here carries the same
1029
+ three lines for a consumer writing their own.
1031
1030
 
1032
1031
  **A value rather than the resting behavior**, which is what the
1033
1032
  responsiveness policy asks of every axis that a box decides: a splitter
@@ -1055,13 +1054,13 @@ end while the slides stop moving a third of the way through.
1055
1054
  **The number is published to the styles rather than enumerated by them**,
1056
1055
  as `--carousel-per-view` on the track, which is what keeps a width and a
1057
1056
  count from disagreeing. A sheet can only name a value it wrote a rule for,
1058
- so the styled tier enumerated `per-view="2"` through `5` and called five a
1059
- judgment; above it the pane fell back to one across while this file went on
1060
- counting positions. Measured in Chromium over eight slides, six across gave
1061
- three dots, a pane taking the whole track and five slides reachable only by
1062
- dragging. Written from here there is no ceiling to exceed, and a consumer's
1063
- own sheet reads the same declaration the styled one does. `runEnd` publishes
1064
- its correction the same way and for the same reason.
1057
+ so a sheet enumerating `per-view="2"` through `5` is a ceiling of five, and
1058
+ above it the pane falls back to one across while this file goes on counting
1059
+ positions. Measured in Chromium over eight slides against such a sheet, six
1060
+ across gave three dots, a pane taking the whole track and five slides
1061
+ reachable only by dragging. Published from here there is no ceiling to
1062
+ exceed, and every sheet reads the same declaration. `runEnd` publishes its
1063
+ correction the same way and for the same reason.
1065
1064
 
1066
1065
  **On the track and not on the host.** A custom property on the host is a
1067
1066
  reflected attribute by another name: it would arrive on upgrade, and a
@@ -1086,8 +1085,8 @@ inline the count would outrank the sheet that computes it, which is why an
1086
1085
  `auto` track is handed nothing. A count stays for the design that calls for
1087
1086
  exactly three.
1088
1087
 
1089
- The styled sheet says how it divides, and the headless `auto` example
1090
- carries the same three lines for a consumer writing their own.
1088
+ A sheet says how it divides, and the `auto` example here carries the same
1089
+ three lines for a consumer writing their own.
1091
1090
 
1092
1091
  **A value rather than the resting behavior**, which is what the
1093
1092
  responsiveness policy asks of every axis that a box decides: a splitter
@@ -1251,13 +1250,13 @@ pinned because a conversation opens at its most recent turn.
1251
1250
 
1252
1251
  **Not reflected, and the default is why.** A reflected property that
1253
1252
  defaults to true writes its attribute on upgrade whether or not the
1254
- consumer wrote one, so the server serves `<helix-chat label="x">` and the
1255
- client turns it into `<helix-chat label="x" pinned>`: a hydration mismatch a
1256
- React consumer reports and does not patch up. Nothing needs the attribute
1257
- either, because the one thing that changes with the pin is the way back, and
1258
- that is a part inside the shadow tree where a stylesheet can already reach
1259
- it. Measured rather than assumed: `label, pinned` after upgrade against
1260
- `label` from the server. */
1253
+ consumer wrote one, so the server serves `<helix-headless-chat label="x">`
1254
+ and the client turns it into `<helix-headless-chat label="x" pinned>`: a
1255
+ hydration mismatch a React consumer reports and does not patch up. Nothing
1256
+ needs the attribute either, because the one thing that changes with the pin
1257
+ is the way back, and that is a part inside the shadow tree where a
1258
+ stylesheet can already reach it. Measured rather than assumed: `label,
1259
+ pinned` after upgrade against `label` from the server. */
1261
1260
  pinned?: (HelixHeadlessChat["pinned"]) | undefined;
1262
1261
  /** How near the bottom still counts as being at it, in pixels.
1263
1262
 
@@ -1383,9 +1382,9 @@ Not reflected: the attribute is the consumer's input and stays as they
1383
1382
  wrote it, and `:state(checked)` carries the resolved state for
1384
1383
  stylesheets. */
1385
1384
  checked?: (HelixHeadlessCheckbox["checked"]) | undefined;
1386
- /** Initial checked state for uncontrolled use, where nothing declared one. */
1385
+ /** Whether the markup declared it checked, which is where a reset returns to. */
1387
1386
  "default-checked"?: (HelixHeadlessCheckbox["defaultChecked"]) | undefined;
1388
- /** Initial checked state for uncontrolled use, where nothing declared one. */
1387
+ /** Whether the markup declared it checked, which is where a reset returns to. */
1389
1388
  defaultChecked?: (HelixHeadlessCheckbox["defaultChecked"]) | undefined;
1390
1389
  /** What is wrong, in the reader's words rather than the browser's. */
1391
1390
  feedback?: (HelixHeadlessCheckbox["feedback"]) | undefined;
@@ -1452,11 +1451,11 @@ present, which is true. Measured, and it is why this is named the other way
1452
1451
  round. The platform already writes booleans like this for the same reason,
1453
1452
  `novalidate` and `nomodule` and `noreferrer` among them.
1454
1453
 
1455
- **Reflected, because the gutter is a stylesheet rule.** `code-block.css`
1456
- reserves the copy button's width with `:host(:not([no-copy]))`, so the
1457
- attribute is what decides whether the block pays for a control. Unreflected,
1458
- setting it from script takes the button away (`render` reads the property)
1459
- and leaves the 40px it stood in reserved.
1454
+ **Reflected, because the gutter is a stylesheet rule.** A sheet reserves
1455
+ the copy button's width with `:host(:not([no-copy]))`, so the attribute is
1456
+ what decides whether the block pays for a control. Unreflected, setting it
1457
+ from script takes the button away (`render` reads the property) and leaves
1458
+ the 40px it stood in reserved.
1460
1459
 
1461
1460
  A false boolean reflects as the attribute's absence, so this costs no
1462
1461
  `no-copy=""` on hosts that never asked for one, and the rule about a
@@ -1472,11 +1471,11 @@ present, which is true. Measured, and it is why this is named the other way
1472
1471
  round. The platform already writes booleans like this for the same reason,
1473
1472
  `novalidate` and `nomodule` and `noreferrer` among them.
1474
1473
 
1475
- **Reflected, because the gutter is a stylesheet rule.** `code-block.css`
1476
- reserves the copy button's width with `:host(:not([no-copy]))`, so the
1477
- attribute is what decides whether the block pays for a control. Unreflected,
1478
- setting it from script takes the button away (`render` reads the property)
1479
- and leaves the 40px it stood in reserved.
1474
+ **Reflected, because the gutter is a stylesheet rule.** A sheet reserves
1475
+ the copy button's width with `:host(:not([no-copy]))`, so the attribute is
1476
+ what decides whether the block pays for a control. Unreflected, setting it
1477
+ from script takes the button away (`render` reads the property) and leaves
1478
+ the 40px it stood in reserved.
1480
1479
 
1481
1480
  A false boolean reflects as the attribute's absence, so this costs no
1482
1481
  `no-copy=""` on hosts that never asked for one, and the rule about a
@@ -1573,9 +1572,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
1573
1572
  last reader did rather than what the author wrote. `:state(open)` carries
1574
1573
  the resolved state for stylesheets, which is what the mirror is for. */
1575
1574
  open?: (HelixHeadlessColorInput["open"]) | undefined;
1576
- /** Initial open state for uncontrolled use, where nothing declared one. */
1575
+ /** Whether the markup declared it open. Ignored once `open` is written. */
1577
1576
  "default-open"?: (HelixHeadlessColorInput["defaultOpen"]) | undefined;
1578
- /** Initial open state for uncontrolled use, where nothing declared one. */
1577
+ /** Whether the markup declared it open. Ignored once `open` is written. */
1579
1578
  defaultOpen?: (HelixHeadlessColorInput["defaultOpen"]) | undefined;
1580
1579
  /** The value the markup declared, which is where a reset returns to. */
1581
1580
  "default-value"?: (HelixHeadlessColorInput["defaultValue"]) | undefined;
@@ -1771,10 +1770,10 @@ letting it open would take a color from the reader and drop it. */
1771
1770
 
1772
1771
  **A color is exactly as requirable as a date**, which is the comparison
1773
1772
  that settles it: this element extends `HelixFormElement`, carries `name`
1774
- and reports its value, so a consumer writing
1775
- `<helix-color-picker name="brand" required>` inside a form has every reason
1776
- to expect the form to refuse an empty one. Its two siblings in the same
1777
- composition position, Date Picker and Time Picker, both check it.
1773
+ and reports its value, so a consumer writing `<helix-headless-color-picker
1774
+ name="brand" required>` inside a form has every reason to expect the form
1775
+ to refuse an empty one. Its two siblings in the same composition position,
1776
+ Date Picker and Time Picker, both check it.
1778
1777
 
1779
1778
  Written out rather than taken from `MixinField`, for the reason those two
1780
1779
  record: the mixin brings a label, a hint and a feedback region, and this is
@@ -1947,9 +1946,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
1947
1946
  last reader did rather than what the author wrote. `:state(open)` carries
1948
1947
  the resolved state for stylesheets, which is what the mirror is for. */
1949
1948
  open?: (HelixHeadlessCombobox["open"]) | undefined;
1950
- /** Initial open state for uncontrolled use, where nothing declared one. */
1949
+ /** Whether the markup declared it open. Ignored once `open` is written. */
1951
1950
  "default-open"?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
1952
- /** Initial open state for uncontrolled use, where nothing declared one. */
1951
+ /** Whether the markup declared it open. Ignored once `open` is written. */
1953
1952
  defaultOpen?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
1954
1953
  /** What the control is called once everything is showing. */
1955
1954
  "collapse-label"?: (HelixHeadlessCombobox["collapseLabel"]) | undefined;
@@ -2081,9 +2080,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
2081
2080
  last reader did rather than what the author wrote. `:state(open)` carries
2082
2081
  the resolved state for stylesheets, which is what the mirror is for. */
2083
2082
  open?: (HelixHeadlessCommand["open"]) | undefined;
2084
- /** Initial open state for uncontrolled use, where nothing declared one. */
2083
+ /** Whether the markup declared it open. Ignored once `open` is written. */
2085
2084
  "default-open"?: (HelixHeadlessCommand["defaultOpen"]) | undefined;
2086
- /** Initial open state for uncontrolled use, where nothing declared one. */
2085
+ /** Whether the markup declared it open. Ignored once `open` is written. */
2087
2086
  defaultOpen?: (HelixHeadlessCommand["defaultOpen"]) | undefined;
2088
2087
  };
2089
2088
 
@@ -2142,7 +2141,7 @@ the trigger silently does nothing at all. A wrapper has to hand them down,
2142
2141
  the same way `label` becomes `aria-label` in there.
2143
2142
 
2144
2143
  ```html
2145
- <helix-button commandfor="confirm" command="--show">Delete…</helix-button>
2144
+ <helix-headless-button commandfor="confirm" command="--show">Delete…</helix-headless-button>
2146
2145
  ```
2147
2146
 
2148
2147
  `commandFor` spells its attribute out, because Lit lowercases a property
@@ -2417,17 +2416,17 @@ refusing it leaves the selection as it was. */
2417
2416
 
2418
2417
  **It announces nothing, and that is not an omission.** Nothing in this
2419
2418
  element ever asks for a different page size: a size selector is
2420
- `helix-pagination-size`, which a consumer puts in the `footer` slot and
2421
- answers themselves. Routing this through `requestChange` would announce an
2422
- event the element never has cause to fire. */
2419
+ `PaginationSize`, which a consumer puts in the `footer` slot and answers
2420
+ themselves. Routing this through `requestChange` would announce an event
2421
+ the element never has cause to fire. */
2423
2422
  "page-size"?: (HelixHeadlessDataTable["pageSize"] | `${number}`) | undefined;
2424
2423
  /** How many rows a page holds. Zero is every row, which is what "no paging" means.
2425
2424
 
2426
2425
  **It announces nothing, and that is not an omission.** Nothing in this
2427
2426
  element ever asks for a different page size: a size selector is
2428
- `helix-pagination-size`, which a consumer puts in the `footer` slot and
2429
- answers themselves. Routing this through `requestChange` would announce an
2430
- event the element never has cause to fire. */
2427
+ `PaginationSize`, which a consumer puts in the `footer` slot and answers
2428
+ themselves. Routing this through `requestChange` would announce an event
2429
+ the element never has cause to fire. */
2431
2430
  pageSize?: (HelixHeadlessDataTable["pageSize"]) | undefined;
2432
2431
  /** How many rows the whole result has, where this element cannot count them.
2433
2432
 
@@ -2649,9 +2648,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
2649
2648
  last reader did rather than what the author wrote. `:state(open)` carries
2650
2649
  the resolved state for stylesheets, which is what the mirror is for. */
2651
2650
  open?: (HelixHeadlessDateInput["open"]) | undefined;
2652
- /** Initial open state for uncontrolled use, where nothing declared one. */
2651
+ /** Whether the markup declared it open. Ignored once `open` is written. */
2653
2652
  "default-open"?: (HelixHeadlessDateInput["defaultOpen"]) | undefined;
2654
- /** Initial open state for uncontrolled use, where nothing declared one. */
2653
+ /** Whether the markup declared it open. Ignored once `open` is written. */
2655
2654
  defaultOpen?: (HelixHeadlessDateInput["defaultOpen"]) | undefined;
2656
2655
  /** What the control is called once everything is showing. */
2657
2656
  "collapse-label"?: (HelixHeadlessDateInput["collapseLabel"]) | undefined;
@@ -3004,9 +3003,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
3004
3003
  last reader did rather than what the author wrote. `:state(open)` carries
3005
3004
  the resolved state for stylesheets, which is what the mirror is for. */
3006
3005
  open?: (HelixHeadlessDialog["open"]) | undefined;
3007
- /** Initial open state for uncontrolled use, where nothing declared one. */
3006
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3008
3007
  "default-open"?: (HelixHeadlessDialog["defaultOpen"]) | undefined;
3009
- /** Initial open state for uncontrolled use, where nothing declared one. */
3008
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3010
3009
  defaultOpen?: (HelixHeadlessDialog["defaultOpen"]) | undefined;
3011
3010
  /** What the dialog closed with, the way `<dialog>` reports it.
3012
3011
 
@@ -3077,7 +3076,7 @@ thickness decides is arithmetic done here and published as
3077
3076
  `--donut-chart-stroke`, which is a number a rule can do sums with where the
3078
3077
  word is not. Reflected, it wrote a value onto every host a script had set
3079
3078
  it on for nothing to read. `sweep` beside it is the converse and reflects,
3080
- because three rules select on it. */
3079
+ because the styled sheet selects on it. */
3081
3080
  hole?: (HelixHeadlessDonutChart["hole"]) | undefined;
3082
3081
  /** How much of the circle the whole occupies.
3083
3082
 
@@ -3170,10 +3169,10 @@ not, rather than shown or hidden by CSS. */
3170
3169
  modal?: (HelixHeadlessDrawer["modal"]) | undefined;
3171
3170
  /** Which edge the drawer comes from.
3172
3171
 
3173
- Unset is `end`, which the styled tier reads as `:host(:not([placement]))`
3174
- beside `:host([placement="end"])` rather than as a value written here: a
3172
+ Unset is `end`, and it stays unset rather than being written down: a
3175
3173
  default assigned to the property would reflect onto every host and put a
3176
- `placement="end"` into markup no consumer wrote. */
3174
+ `placement="end"` into markup no consumer wrote. So what this tier
3175
+ guarantees is the absence, and a sheet selects on it. */
3177
3176
  placement?: (HelixHeadlessDrawer["placement"]) | undefined;
3178
3177
  /** Whether the element is open.
3179
3178
 
@@ -3188,9 +3187,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
3188
3187
  last reader did rather than what the author wrote. `:state(open)` carries
3189
3188
  the resolved state for stylesheets, which is what the mirror is for. */
3190
3189
  open?: (HelixHeadlessDrawer["open"]) | undefined;
3191
- /** Initial open state for uncontrolled use, where nothing declared one. */
3190
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3192
3191
  "default-open"?: (HelixHeadlessDrawer["defaultOpen"]) | undefined;
3193
- /** Initial open state for uncontrolled use, where nothing declared one. */
3192
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3194
3193
  defaultOpen?: (HelixHeadlessDrawer["defaultOpen"]) | undefined;
3195
3194
  /** What the dialog closed with, the way `<dialog>` reports it.
3196
3195
 
@@ -3606,9 +3605,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
3606
3605
  last reader did rather than what the author wrote. `:state(open)` carries
3607
3606
  the resolved state for stylesheets, which is what the mirror is for. */
3608
3607
  open?: (HelixHeadlessFilterInput["open"]) | undefined;
3609
- /** Initial open state for uncontrolled use, where nothing declared one. */
3608
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3610
3609
  "default-open"?: (HelixHeadlessFilterInput["defaultOpen"]) | undefined;
3611
- /** Initial open state for uncontrolled use, where nothing declared one. */
3610
+ /** Whether the markup declared it open. Ignored once `open` is written. */
3612
3611
  defaultOpen?: (HelixHeadlessFilterInput["defaultOpen"]) | undefined;
3613
3612
  /** What the control is called once everything is showing. */
3614
3613
  "collapse-label"?: (HelixHeadlessFilterInput["collapseLabel"]) | undefined;
@@ -3701,11 +3700,12 @@ renders nothing rather than the epoch, which is what parsing an empty string
3701
3700
  would give.
3702
3701
 
3703
3702
  **The element's own text is read as a fallback, and only in a browser.**
3704
- `<helix-format-date elapsed>2026-08-27T01:00:00Z</helix-format-date>` is the
3705
- spelling that reads best in markup, and it cannot be the only one: measured
3706
- against Lit's server shim, `textContent`, `children`, `firstChild` and
3707
- `querySelector` are all `undefined` there, so a server has no way to see it.
3708
- An element rendered on a server needs the attribute; one rendered in a
3703
+ `<helix-headless-format-date
3704
+ elapsed>2026-08-27T01:00:00Z</helix-headless-format-date>` is the spelling
3705
+ that reads best in markup, and it cannot be the only one: measured against
3706
+ Lit's server shim, `textContent`, `children`, `firstChild` and
3707
+ `querySelector` are all `undefined` there, so a server has no way to see
3708
+ it. An element rendered on a server needs the attribute; one rendered in a
3709
3709
  browser may use either. */
3710
3710
  date?: (HelixHeadlessFormatDate["date"]) | undefined;
3711
3711
  /** How the day of the month is written, where a date is shown. */
@@ -3779,12 +3779,12 @@ so a number written here that disagrees with the sheet is a promise the
3779
3779
  consumer has to keep by hand, and the one number a summary is told to trust
3780
3780
  is the one it gets wrong.
3781
3781
 
3782
- The strip measures itself, so `--heatmap-cell-inline-size` and `--heatmap-gap` are
3783
- enough on their own and these two are the estimate used until the first
3784
- measurement lands. Writing the attribute pins the value and stops the
3785
- measurement being consulted, which is what a container query or a transition
3786
- on the cell size wants, where what is drawn this frame is not what the
3787
- arithmetic should plan around.
3782
+ The strip measures itself, so sizing the cells in a sheet is enough on its
3783
+ own and these two are the estimate used until the first measurement lands.
3784
+ Writing the attribute pins the value and stops the measurement being
3785
+ consulted, which is what a container query or a transition on the cell size
3786
+ wants, where what is drawn this frame is not what the arithmetic should
3787
+ plan around.
3788
3788
 
3789
3789
  Zero turns the dropping off altogether, which is right for a strip in a
3790
3790
  container that cannot get narrow. */
@@ -3797,12 +3797,12 @@ so a number written here that disagrees with the sheet is a promise the
3797
3797
  consumer has to keep by hand, and the one number a summary is told to trust
3798
3798
  is the one it gets wrong.
3799
3799
 
3800
- The strip measures itself, so `--heatmap-cell-inline-size` and `--heatmap-gap` are
3801
- enough on their own and these two are the estimate used until the first
3802
- measurement lands. Writing the attribute pins the value and stops the
3803
- measurement being consulted, which is what a container query or a transition
3804
- on the cell size wants, where what is drawn this frame is not what the
3805
- arithmetic should plan around.
3800
+ The strip measures itself, so sizing the cells in a sheet is enough on its
3801
+ own and these two are the estimate used until the first measurement lands.
3802
+ Writing the attribute pins the value and stops the measurement being
3803
+ consulted, which is what a container query or a transition on the cell size
3804
+ wants, where what is drawn this frame is not what the arithmetic should
3805
+ plan around.
3806
3806
 
3807
3807
  Zero turns the dropping off altogether, which is right for a strip in a
3808
3808
  container that cannot get narrow. */
@@ -3864,7 +3864,7 @@ the trigger silently does nothing at all. A wrapper has to hand them down,
3864
3864
  the same way `label` becomes `aria-label` in there.
3865
3865
 
3866
3866
  ```html
3867
- <helix-button commandfor="confirm" command="--show">Delete…</helix-button>
3867
+ <helix-headless-button commandfor="confirm" command="--show">Delete…</helix-headless-button>
3868
3868
  ```
3869
3869
 
3870
3870
  `commandFor` spells its attribute out, because Lit lowercases a property
@@ -4095,10 +4095,10 @@ Read-only to a consumer: it is a report rather than a setting.
4095
4095
  **Mirrored to `data-status`, and not reflected as `status`.** It is element
4096
4096
  state, so reflecting it puts the element's own bookkeeping into the markup
4097
4097
  a consumer rendered: React reads the attribute appearing at upgrade as a
4098
- hydration mismatch, and a serialized `<helix-image status="loaded">` pasted
4099
- back declares that a picture has arrived which this element has never
4100
- fetched. The `data-` name is the library's answer to both, being a name a
4101
- re-parse cannot mistake for a declaration, and it is what `data-closed` on
4098
+ hydration mismatch, and a host pasted back carrying `status="loaded"`
4099
+ declares that a picture has arrived which this element has never fetched.
4100
+ The `data-` name is the library's answer to both, being a name a re-parse
4101
+ cannot mistake for a declaration, and it is what `data-closed` on
4102
4102
  `Toast.Item` already does. A picture arrives after somebody fetched it,
4103
4103
  which puts this on the safe side of hydration: a fact that can be true on
4104
4104
  the *first* update mirrors to a custom state instead, which is what
@@ -4165,20 +4165,20 @@ Not a label: it goes when typing starts. */
4165
4165
  **The attribute is `readonly`, which is the platform's spelling.** A
4166
4166
  camelCase property needs an explicit `attribute`, and dash-casing a word
4167
4167
  HTML writes as one costs what an attribute always costs here: nothing
4168
- warns. `<helix-input readonly>` is what anybody who has written HTML types;
4169
- against `read-only` it parses to no property at all, and the field stays
4170
- editable with no error anywhere. Measured on the dash-cased form, `readOnly`
4171
- came back `false`. */
4168
+ warns. `<helix-headless-input readonly>` is what anybody who has written
4169
+ HTML types; against `read-only` it parses to no property at all, and the
4170
+ field stays editable with no error anywhere. Measured on the dash-cased
4171
+ form, `readOnly` came back `false`. */
4172
4172
  readonly?: (HelixHeadlessInput["readOnly"]) | undefined;
4173
4173
  /** Whether the field refuses input while still submitting its value.
4174
4174
 
4175
4175
  **The attribute is `readonly`, which is the platform's spelling.** A
4176
4176
  camelCase property needs an explicit `attribute`, and dash-casing a word
4177
4177
  HTML writes as one costs what an attribute always costs here: nothing
4178
- warns. `<helix-input readonly>` is what anybody who has written HTML types;
4179
- against `read-only` it parses to no property at all, and the field stays
4180
- editable with no error anywhere. Measured on the dash-cased form, `readOnly`
4181
- came back `false`. */
4178
+ warns. `<helix-headless-input readonly>` is what anybody who has written
4179
+ HTML types; against `read-only` it parses to no property at all, and the
4180
+ field stays editable with no error anywhere. Measured on the dash-cased
4181
+ form, `readOnly` came back `false`. */
4182
4182
  readOnly?: (HelixHeadlessInput["readOnly"]) | undefined;
4183
4183
  /** Whether a password field offers a toggle that shows what was typed.
4184
4184
 
@@ -4199,9 +4199,9 @@ The state is `aria-pressed`, not this. */
4199
4199
 
4200
4200
  **Not reflected.** Reflection exists so a selector can reach a value, and
4201
4201
  no stylesheet in this repository selects on `type`. Reflecting it writes
4202
- `type="text"` onto every `<helix-input>` ever rendered, an attribute no
4203
- consumer's markup has, which is the fault the area rules write up under
4204
- `Button`'s `href`, `target` and `rel`.
4202
+ `type="text"` onto every `<helix-headless-input>` ever rendered, an
4203
+ attribute no consumer's markup has, which is the fault the area rules write
4204
+ up under `Button`'s `href`, `target` and `rel`.
4205
4205
 
4206
4206
  Nothing reads it from the attribute either. The real `<input>` inside takes
4207
4207
  it as a property binding, which is what makes the keyboard and the
@@ -4415,8 +4415,7 @@ beside it for instance. `ring` lets the ground through, for a chart drawn
4415
4415
  over something busy. `triangle` points along the axis and reads as "and
4416
4416
  onward" rather than as a second claim about the data.
4417
4417
 
4418
- The shapes come from
4419
- `helix/styled/src/shared/chart/terminus.css`, the same sheet `Sparkline` takes, so
4418
+ The shapes come from one shared sheet, the same one `Sparkline` takes, so
4420
4419
  the set is identical wherever one appears. **Which is why every value is
4421
4420
  named here.** `Sparkline` shipped `square` implemented, drawn, asserted and
4422
4421
  undocumented until the cohort before this one; this family reads the same
@@ -4497,10 +4496,10 @@ has to survive with the stylesheet turned off.
4497
4496
  label?: (HelixHeadlessList["label"]) | undefined;
4498
4497
  /** Which markers an ordered list draws, in `<ol type>`'s own five values.
4499
4498
 
4500
- Reflected, because this is one of the things a stylesheet selects on and
4501
- the styled tier maps each to a `list-style-type`. The platform's spellings
4502
- rather than the CSS ones, so `<helix-list kind="ordered" type="i">` is what
4503
- a consumer would have written on an `<ol>`.
4499
+ Reflected, because this is one of the things a stylesheet selects on, each
4500
+ value mapping to a `list-style-type`. The platform's spellings rather than
4501
+ the CSS ones, so `<helix-headless-list kind="ordered" type="i">` is what a
4502
+ consumer would have written on an `<ol>`.
4504
4503
 
4505
4504
  **`start` and `reversed` are both absent and neither can be done here.**
4506
4505
  This renders no `<ol>`: the rows are slotted and numbered by the CSS
@@ -4763,9 +4762,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
4763
4762
  last reader did rather than what the author wrote. `:state(open)` carries
4764
4763
  the resolved state for stylesheets, which is what the mirror is for. */
4765
4764
  open?: (HelixHeadlessMegamenu["open"]) | undefined;
4766
- /** Initial open state for uncontrolled use, where nothing declared one. */
4765
+ /** Whether the markup declared it open. Ignored once `open` is written. */
4767
4766
  "default-open"?: (HelixHeadlessMegamenu["defaultOpen"]) | undefined;
4768
- /** Initial open state for uncontrolled use, where nothing declared one. */
4767
+ /** Whether the markup declared it open. Ignored once `open` is written. */
4769
4768
  defaultOpen?: (HelixHeadlessMegamenu["defaultOpen"]) | undefined;
4770
4769
  };
4771
4770
 
@@ -4921,9 +4920,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
4921
4920
  last reader did rather than what the author wrote. `:state(open)` carries
4922
4921
  the resolved state for stylesheets, which is what the mirror is for. */
4923
4922
  open?: (HelixHeadlessMenu["open"]) | undefined;
4924
- /** Initial open state for uncontrolled use, where nothing declared one. */
4923
+ /** Whether the markup declared it open. Ignored once `open` is written. */
4925
4924
  "default-open"?: (HelixHeadlessMenu["defaultOpen"]) | undefined;
4926
- /** Initial open state for uncontrolled use, where nothing declared one. */
4925
+ /** Whether the markup declared it open. Ignored once `open` is written. */
4927
4926
  defaultOpen?: (HelixHeadlessMenu["defaultOpen"]) | undefined;
4928
4927
  };
4929
4928
 
@@ -5084,9 +5083,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
5084
5083
  last reader did rather than what the author wrote. `:state(open)` carries
5085
5084
  the resolved state for stylesheets, which is what the mirror is for. */
5086
5085
  open?: (HelixHeadlessNotificationGroup["open"]) | undefined;
5087
- /** Initial open state for uncontrolled use, where nothing declared one. */
5086
+ /** Whether the markup declared it open. Ignored once `open` is written. */
5088
5087
  "default-open"?: (HelixHeadlessNotificationGroup["defaultOpen"]) | undefined;
5089
- /** Initial open state for uncontrolled use, where nothing declared one. */
5088
+ /** Whether the markup declared it open. Ignored once `open` is written. */
5090
5089
  defaultOpen?: (HelixHeadlessNotificationGroup["defaultOpen"]) | undefined;
5091
5090
  };
5092
5091
 
@@ -5125,10 +5124,10 @@ this element then owns.
5125
5124
 
5126
5125
  **Not reflected.** Unread is a visual state, which is why the four mixins
5127
5126
  mirror theirs, but the mirror may not be the property's own attribute:
5128
- `<helix-notification default-read>` comes back from a server without `read`
5129
- and would gain it on the first update, which React reports as a hydration
5130
- mismatch, and which a copy of the serialized element re-parses as a
5131
- declaration. `:state(read)` is what the stylesheet reads.
5127
+ `<helix-headless-notification default-read>` comes back from a server
5128
+ without `read` and would gain it on the first update, which React reports
5129
+ as a hydration mismatch, and which a copy of the serialized element
5130
+ re-parses as a declaration. `:state(read)` is what the stylesheet reads.
5132
5131
  `hydration.dom.spec.ts` holds it. */
5133
5132
  read?: (HelixHeadlessNotification["read"]) | undefined;
5134
5133
  /** State to open with, where nothing declared one. */
@@ -5437,11 +5436,10 @@ Written by the listbox. */
5437
5436
  /** A second destination for this row, taken with the modifier held.
5438
5437
 
5439
5438
  **An attribute rather than a second row, which is the whole point.** A
5440
- palette of eighty-eight components that offered each of them a reference
5441
- page and a sandbox as separate entries would be a palette of a hundred and
5442
- seventy-six, and one earns its keep by getting a reader to one thing in
5443
- three keystrokes. The row already carries the first destination, so the
5444
- second belongs beside it.
5439
+ palette that offered every component a reference page and a sandbox as
5440
+ separate entries would be twice as long, and one earns its keep by getting
5441
+ a reader to one thing in three keystrokes. The row already carries the
5442
+ first destination, so the second belongs beside it.
5445
5443
 
5446
5444
  Declared here and acted on by whatever owns the list, the same division
5447
5445
  selection already uses: an option says what it is and the listbox decides
@@ -5511,7 +5509,7 @@ attribute and the state is the property.
5511
5509
  **The attribute, read when it is asked for, and never a snapshot taken in
5512
5510
  the constructor.** A field initializer runs there, and an element the HTML
5513
5511
  parser created has none of its attributes yet at that moment: measured on
5514
- this element, on `Radio` and on `Toggle`, `<helix-option value="a"
5512
+ this element, on `Radio` and on `Toggle`, `<helix-headless-option value="a"
5515
5513
  selected>` reported `defaultSelected` as `false` both from parsed markup
5516
5514
  and from `createElement` followed by `setAttribute`, which is every way a
5517
5515
  consumer writes one. The snapshot could only ever be true for an element
@@ -5859,10 +5857,10 @@ other end is going to reject. A consumer whose codes really do carry
5859
5857
  marked letters wants `text`, which judges nothing.
5860
5858
 
5861
5859
  **Not reflected**: nothing selects on it, so reflecting only writes
5862
- `type="numeric"` onto every `<helix-pin-input>` ever rendered, an attribute
5863
- no consumer's markup had. The area rules carry the sentence "reflect only
5864
- what CSS selects on". The real inputs take it as a binding, which is what
5865
- makes the keyboard follow. */
5860
+ `type="numeric"` onto every `<helix-headless-pin-input>` ever rendered, an
5861
+ attribute no consumer's markup had. The area rules carry the sentence
5862
+ "reflect only what CSS selects on". The real inputs take it as a binding,
5863
+ which is what makes the keyboard follow. */
5866
5864
  type?: (HelixHeadlessPinInput["type"]) | undefined;
5867
5865
  /** The value the markup declared, which is where a reset returns to. */
5868
5866
  "default-value"?: (HelixHeadlessPinInput["defaultValue"]) | undefined;
@@ -5956,9 +5954,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
5956
5954
  last reader did rather than what the author wrote. `:state(open)` carries
5957
5955
  the resolved state for stylesheets, which is what the mirror is for. */
5958
5956
  open?: (HelixHeadlessPopover["open"]) | undefined;
5959
- /** Initial open state for uncontrolled use, where nothing declared one. */
5957
+ /** Whether the markup declared it open. Ignored once `open` is written. */
5960
5958
  "default-open"?: (HelixHeadlessPopover["defaultOpen"]) | undefined;
5961
- /** Initial open state for uncontrolled use, where nothing declared one. */
5959
+ /** Whether the markup declared it open. Ignored once `open` is written. */
5962
5960
  defaultOpen?: (HelixHeadlessPopover["defaultOpen"]) | undefined;
5963
5961
  };
5964
5962
 
@@ -6196,7 +6194,7 @@ attribute and the state is the property.
6196
6194
  **The attribute, read when it is asked for, and never a snapshot taken in
6197
6195
  the constructor.** A field initializer runs there, and an element the HTML
6198
6196
  parser created has none of its attributes yet at that moment: measured on
6199
- this element, on `Option` and on `Toggle`, `<helix-radio value="a"
6197
+ this element, on `Option` and on `Toggle`, `<helix-headless-radio value="a"
6200
6198
  selected>` reported `defaultSelected` as `false` both from parsed markup
6201
6199
  and from `createElement` followed by `setAttribute`, which is every way a
6202
6200
  consumer writes one. The snapshot could only ever be true for an element
@@ -6495,9 +6493,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
6495
6493
  last reader did rather than what the author wrote. `:state(open)` carries
6496
6494
  the resolved state for stylesheets, which is what the mirror is for. */
6497
6495
  open?: (HelixHeadlessSelect["open"]) | undefined;
6498
- /** Initial open state for uncontrolled use, where nothing declared one. */
6496
+ /** Whether the markup declared it open. Ignored once `open` is written. */
6499
6497
  "default-open"?: (HelixHeadlessSelect["defaultOpen"]) | undefined;
6500
- /** Initial open state for uncontrolled use, where nothing declared one. */
6498
+ /** Whether the markup declared it open. Ignored once `open` is written. */
6501
6499
  defaultOpen?: (HelixHeadlessSelect["defaultOpen"]) | undefined;
6502
6500
  /** The value the markup declared, which is where a reset returns to. */
6503
6501
  "default-value"?: (HelixHeadlessSelect["defaultValue"]) | undefined;
@@ -6842,9 +6840,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
6842
6840
  last reader did rather than what the author wrote. `:state(open)` carries
6843
6841
  the resolved state for stylesheets, which is what the mirror is for. */
6844
6842
  open?: (HelixHeadlessSpeedDial["open"]) | undefined;
6845
- /** Initial open state for uncontrolled use, where nothing declared one. */
6843
+ /** Whether the markup declared it open. Ignored once `open` is written. */
6846
6844
  "default-open"?: (HelixHeadlessSpeedDial["defaultOpen"]) | undefined;
6847
- /** Initial open state for uncontrolled use, where nothing declared one. */
6845
+ /** Whether the markup declared it open. Ignored once `open` is written. */
6848
6846
  defaultOpen?: (HelixHeadlessSpeedDial["defaultOpen"]) | undefined;
6849
6847
  };
6850
6848
 
@@ -6992,9 +6990,9 @@ the headline and the label is a caption under it.
6992
6990
  The row directions set them side by side, for a figure in a line of text or
6993
6991
  a narrow strip where a stacked pair would be two lines of almost nothing.
6994
6992
 
6995
- A property rather than a `helix-flex` around it, because the unit has to
6996
- stay on the value's baseline whichever way the pair goes, and only this
6997
- element knows which of its children the unit belongs to.
6993
+ A property rather than a `Flex` around it, because the unit has to stay on
6994
+ the value's baseline whichever way the pair goes, and only this element
6995
+ knows which of its children the unit belongs to.
6998
6996
 
6999
6997
  **Optional rather than defaulted to `column`, which is not a style
7000
6998
  preference.** A reflecting property with a default writes its attribute onto
@@ -7061,11 +7059,11 @@ Writing always applies, so `<helix-tabs active="one">` starts on that
7061
7059
  tab, and `default-active` is how markup says where to start without
7062
7060
  naming the current one. */
7063
7061
  active?: (HelixHeadlessSteps["active"]) | undefined;
7064
- /** Initial item for uncontrolled use.
7062
+ /** Which item the markup declared current.
7065
7063
 
7066
7064
  Ignored once `active` is written. */
7067
7065
  "default-active"?: (HelixHeadlessSteps["defaultActive"]) | undefined;
7068
- /** Initial item for uncontrolled use.
7066
+ /** Which item the markup declared current.
7069
7067
 
7070
7068
  Ignored once `active` is written. */
7071
7069
  defaultActive?: (HelixHeadlessSteps["defaultActive"]) | undefined;
@@ -7126,9 +7124,9 @@ Not reflected: the attribute is the consumer's input and stays as they
7126
7124
  wrote it, and `:state(checked)` carries the resolved state for
7127
7125
  stylesheets. */
7128
7126
  checked?: (HelixHeadlessSwitch["checked"]) | undefined;
7129
- /** Initial checked state for uncontrolled use, where nothing declared one. */
7127
+ /** Whether the markup declared it checked, which is where a reset returns to. */
7130
7128
  "default-checked"?: (HelixHeadlessSwitch["defaultChecked"]) | undefined;
7131
- /** Initial checked state for uncontrolled use, where nothing declared one. */
7129
+ /** Whether the markup declared it checked, which is where a reset returns to. */
7132
7130
  defaultChecked?: (HelixHeadlessSwitch["defaultChecked"]) | undefined;
7133
7131
  /** What is wrong, in the reader's words rather than the browser's. */
7134
7132
  feedback?: (HelixHeadlessSwitch["feedback"]) | undefined;
@@ -7194,15 +7192,15 @@ export type HelixHeadlessTableColumnHelixBeforeResizeElementEvent =
7194
7192
  export type HelixHeadlessTableColumnVueProps = {
7195
7193
  /** Which edge the values line up against.
7196
7194
 
7197
- `end` is what a column of numbers wants, so digits of the same magnitude sit
7198
- above each other. Left unset the cell inherits the table's own alignment,
7199
- which is `start` for text in either writing direction. `helix-data-table`
7200
- aligns the cells it draws. A `helix-table`'s cells are markup the consumer
7201
- wrote, so the table writes nothing onto them: it publishes the edge to each
7202
- cell under this column as `--table-cell-align`, which `@fusion.dev/helix`
7203
- reads. The heading is this element's own, and `@fusion.dev/helix` sets it to
7204
- the same edge in either table. `end` is the inline end, so in a
7205
- right-to-left table it is the left.
7195
+ `end` is what a column of numbers wants, so digits of the same magnitude
7196
+ sit above each other. Left unset the cell inherits the table's own
7197
+ alignment, which is `start` for text in either writing direction.
7198
+ `DataTable` aligns the cells it draws. A `Table`'s cells are markup the
7199
+ consumer wrote, so the table writes nothing onto them: it publishes the
7200
+ edge to each cell under this column as `--table-cell-align`, which
7201
+ `@fusion.dev/helix` reads. The heading is this element's own, and
7202
+ `@fusion.dev/helix` sets it to the same edge in either table. `end` is the
7203
+ inline end, so in a right-to-left table it is the left.
7206
7204
 
7207
7205
  **Reflected, because the heading is drawn by a stylesheet and has no other
7208
7206
  way to learn it.** Set as a property, which is how React sets it, an
@@ -7249,8 +7247,8 @@ onto its host. */
7249
7247
  /** The track this column takes, as CSS.
7250
7248
 
7251
7249
  A single track value, so anything valid in `grid-template-columns` works:
7252
- `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track
7253
- in its place in a `helix-table`'s `columns`, where that table sets one, and
7250
+ `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in
7251
+ its place in a `Table`'s `columns`, where that table sets one, and
7254
7252
  otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
7255
7253
  Set here, it wins over that list, which is what lets a reader resize a
7256
7254
  column in a table that set one.
@@ -7296,15 +7294,14 @@ export type HelixHeadlessTableColumnVueEvents = {
7296
7294
  export type HelixHeadlessTableVueProps = {
7297
7295
  /** The column widths as one track list, written once on the table.
7298
7296
 
7299
- With `helix-table-column` children, each track sizes the column in its
7300
- place, a hidden column counted, so hiding one takes its track with it and
7301
- the rest keep theirs. The columns decide how many tracks there are and this
7302
- list only how wide: a track past the last column is dropped, and a column
7303
- past the last track shares what is left. With no columns declared it is
7304
- the whole track list. Tracks count as the grid counts them, so
7305
- `minmax(0, 1fr)` is one and `repeat(2, 8rem)` is two, and one the grid
7306
- would refuse leaves its column at the default rather than taking the table
7307
- down to one column.
7297
+ With `TableColumn` children, each track sizes the column in its place, a
7298
+ hidden column counted, so hiding one takes its track with it and the rest
7299
+ keep theirs. The columns decide how many tracks there are and this list
7300
+ only how wide: a track past the last column is dropped, and a column past
7301
+ the last track shares what is left. With no columns declared it is the
7302
+ whole track list. Tracks count as the grid counts them, so `minmax(0, 1fr)`
7303
+ is one and `repeat(2, 8rem)` is two, and one the grid would refuse leaves
7304
+ its column at the default rather than taking the table down to one column.
7308
7305
 
7309
7306
  **A column's own `width` wins over its track here.** The width is written
7310
7307
  on the column it sizes, which is the more particular statement, and it is
@@ -7318,13 +7315,11 @@ to walk, so a render there knows of no columns and this attribute is the
7318
7315
  whole answer: a table given one lays its grid out in the first paint, and a
7319
7316
  table sized only by its columns is one track wide until it upgrades.
7320
7317
 
7321
- **`helix-data-table` has none of this, and should not.** Its columns are
7322
- its schema rather than an option, so there is always a column to write a
7323
- `width` on and a list here would be a second way to say what that says.
7324
- This table's cells are markup, and a table written as rows of cells with no
7325
- `helix-table-column` in it has nowhere else to be sized from. Both families
7326
- take the same CSS hook, `--table-columns` and `--data-table-columns`, which
7327
- wins over whichever list the element worked out. */
7318
+ **Data Table has none of this, and should not.** Its columns are its schema
7319
+ rather than an option, so there is always a column to write a `width` on
7320
+ and a list here would be a second way to say what that says. This table's
7321
+ cells are markup, and a table written as rows of cells with no column
7322
+ declared in it has nowhere else to be sized from. */
7328
7323
  columns?: (HelixHeadlessTable["columns"]) | undefined;
7329
7324
  /** Accessible name for the table. */
7330
7325
  label?: (HelixHeadlessTable["label"]) | undefined;
@@ -7419,11 +7414,11 @@ Writing always applies, so `<helix-tabs active="one">` starts on that
7419
7414
  tab, and `default-active` is how markup says where to start without
7420
7415
  naming the current one. */
7421
7416
  active?: (HelixHeadlessTabs["active"]) | undefined;
7422
- /** Initial item for uncontrolled use.
7417
+ /** Which item the markup declared current.
7423
7418
 
7424
7419
  Ignored once `active` is written. */
7425
7420
  "default-active"?: (HelixHeadlessTabs["defaultActive"]) | undefined;
7426
- /** Initial item for uncontrolled use.
7421
+ /** Which item the markup declared current.
7427
7422
 
7428
7423
  Ignored once `active` is written. */
7429
7424
  defaultActive?: (HelixHeadlessTabs["defaultActive"]) | undefined;
@@ -7679,8 +7674,8 @@ Absent uses the runtime's own. */
7679
7674
 
7680
7675
  Absent is one. `range` holds a start and an end, `multiple` holds any
7681
7676
  number, and both are carried as one comma-separated value, which is what a
7682
- form submits. `helix-time-picker` carries the longer note on the interaction and on
7683
- why a wheel cannot do either. */
7677
+ form submits. `TimePicker` carries the longer note on the interaction and
7678
+ on why a wheel cannot do either. */
7684
7679
  mode?: (HelixHeadlessTimeInput["mode"]) | undefined;
7685
7680
  /** What the field says before a time is in it. */
7686
7681
  placeholder?: (HelixHeadlessTimeInput["placeholder"]) | undefined;
@@ -7709,7 +7704,7 @@ never something this element would refuse to read back. */
7709
7704
  `list` offers whole times, which is what a product with slots or opening
7710
7705
  hours has. `wheels` splits them into an hour, a minute and a meridiem where
7711
7706
  the locale uses one, which is the only way to reach `23:45` without
7712
- scrolling most of a day. `helix-time-picker` carries the longer note on the trade.
7707
+ scrolling most of a day. `TimePicker` carries the longer note on the trade.
7713
7708
 
7714
7709
  **Optional rather than defaulted, which is not a style preference.** A
7715
7710
  reflecting property with a default writes its attribute onto every host the
@@ -7755,9 +7750,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
7755
7750
  last reader did rather than what the author wrote. `:state(open)` carries
7756
7751
  the resolved state for stylesheets, which is what the mirror is for. */
7757
7752
  open?: (HelixHeadlessTimeInput["open"]) | undefined;
7758
- /** Initial open state for uncontrolled use, where nothing declared one. */
7753
+ /** Whether the markup declared it open. Ignored once `open` is written. */
7759
7754
  "default-open"?: (HelixHeadlessTimeInput["defaultOpen"]) | undefined;
7760
- /** Initial open state for uncontrolled use, where nothing declared one. */
7755
+ /** Whether the markup declared it open. Ignored once `open` is written. */
7761
7756
  defaultOpen?: (HelixHeadlessTimeInput["defaultOpen"]) | undefined;
7762
7757
  /** What the control is called once everything is showing. */
7763
7758
  "collapse-label"?: (HelixHeadlessTimeInput["collapseLabel"]) | undefined;
@@ -7899,7 +7894,7 @@ Absent uses the runtime's own. */
7899
7894
 
7900
7895
  Absent is one. `range` holds a start and an end with everything between
7901
7896
  them shown as part of the answer, `multiple` holds any number, and both are
7902
- carried as one comma-separated value: the same shape `helix-date-picker` uses,
7897
+ carried as one comma-separated value: the same shape `DatePicker` uses,
7903
7898
  because it is the same question asked of a different unit.
7904
7899
 
7905
7900
  **A range is two picks, and a third starts over.** That is the calendar's
@@ -8123,7 +8118,7 @@ where they were would not be a stack.
8123
8118
  **Optional, and bottom-end is the absence of it.** Reflecting *and*
8124
8119
  defaulting is the pair that writes onto a host: every toast region anybody
8125
8120
  rendered would gain a `placement="bottom-end"` nobody typed, which a React
8126
- consumer's server markup does not have. The styled sheet carries the resting
8121
+ consumer's server markup does not have. A sheet carries the resting
8127
8122
  arrangement in its own `:host` rule and the selectors describe only the
8128
8123
  departures, which is what `orientation` does. */
8129
8124
  placement?: (HelixHeadlessToast["placement"]) | undefined;
@@ -8265,11 +8260,11 @@ attribute and the state is the property.
8265
8260
  **The attribute, read when it is asked for, and never a snapshot taken in
8266
8261
  the constructor.** A field initializer runs there, and an element the HTML
8267
8262
  parser created has none of its attributes yet at that moment: measured on
8268
- this element, on `Option` and on `Radio`, `<helix-toggle value="light"
8269
- selected>` reported `defaultSelected` as `false` both from parsed markup
8270
- and from `createElement` followed by `setAttribute`, which is every way a
8271
- consumer writes one. The snapshot could only ever be true for an element
8272
- already in the document when `customElements.define` ran.
8263
+ this element, on `Option` and on `Radio`, `<helix-headless-toggle
8264
+ value="light" selected>` reported `defaultSelected` as `false` both from
8265
+ parsed markup and from `createElement` followed by `setAttribute`, which is
8266
+ every way a consumer writes one. The snapshot could only ever be true for
8267
+ an element already in the document when `customElements.define` ran.
8273
8268
 
8274
8269
  Nothing overwrites it either, which is what makes reading it late correct
8275
8270
  rather than merely later: `selected` does not reflect, for the reason
@@ -8408,9 +8403,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
8408
8403
  last reader did rather than what the author wrote. `:state(open)` carries
8409
8404
  the resolved state for stylesheets, which is what the mirror is for. */
8410
8405
  open?: (HelixHeadlessTooltip["open"]) | undefined;
8411
- /** Initial open state for uncontrolled use, where nothing declared one. */
8406
+ /** Whether the markup declared it open. Ignored once `open` is written. */
8412
8407
  "default-open"?: (HelixHeadlessTooltip["defaultOpen"]) | undefined;
8413
- /** Initial open state for uncontrolled use, where nothing declared one. */
8408
+ /** Whether the markup declared it open. Ignored once `open` is written. */
8414
8409
  defaultOpen?: (HelixHeadlessTooltip["defaultOpen"]) | undefined;
8415
8410
  };
8416
8411
 
@@ -8599,9 +8594,9 @@ hydration, or diffed by a framework, it comes back holding whatever the
8599
8594
  last reader did rather than what the author wrote. `:state(open)` carries
8600
8595
  the resolved state for stylesheets, which is what the mirror is for. */
8601
8596
  open?: (HelixHeadlessTreeItem["open"]) | undefined;
8602
- /** Initial open state for uncontrolled use, where nothing declared one. */
8597
+ /** Whether the markup declared it open. Ignored once `open` is written. */
8603
8598
  "default-open"?: (HelixHeadlessTreeItem["defaultOpen"]) | undefined;
8604
- /** Initial open state for uncontrolled use, where nothing declared one. */
8599
+ /** Whether the markup declared it open. Ignored once `open` is written. */
8605
8600
  defaultOpen?: (HelixHeadlessTreeItem["defaultOpen"]) | undefined;
8606
8601
  /** Depth from the root, counted by the tree so indentation needs no CSS nesting.
8607
8602
 
@@ -8711,11 +8706,11 @@ Writing always applies, so `<helix-tabs active="one">` starts on that
8711
8706
  tab, and `default-active` is how markup says where to start without
8712
8707
  naming the current one. */
8713
8708
  active?: (HelixHeadlessTree["active"]) | undefined;
8714
- /** Initial item for uncontrolled use.
8709
+ /** Which item the markup declared current.
8715
8710
 
8716
8711
  Ignored once `active` is written. */
8717
8712
  "default-active"?: (HelixHeadlessTree["defaultActive"]) | undefined;
8718
- /** Initial item for uncontrolled use.
8713
+ /** Which item the markup declared current.
8719
8714
 
8720
8715
  Ignored once `active` is written. */
8721
8716
  defaultActive?: (HelixHeadlessTree["defaultActive"]) | undefined;
@@ -8839,11 +8834,11 @@ Writing always applies, so `<helix-tabs active="one">` starts on that
8839
8834
  tab, and `default-active` is how markup says where to start without
8840
8835
  naming the current one. */
8841
8836
  active?: (HelixHeadlessVideoPlaylist["active"]) | undefined;
8842
- /** Initial item for uncontrolled use.
8837
+ /** Which item the markup declared current.
8843
8838
 
8844
8839
  Ignored once `active` is written. */
8845
8840
  "default-active"?: (HelixHeadlessVideoPlaylist["defaultActive"]) | undefined;
8846
- /** Initial item for uncontrolled use.
8841
+ /** Which item the markup declared current.
8847
8842
 
8848
8843
  Ignored once `active` is written. */
8849
8844
  defaultActive?: (HelixHeadlessVideoPlaylist["defaultActive"]) | undefined;
@@ -9142,7 +9137,7 @@ export type HelixHeadlessVirtualListVueEvents = {};
9142
9137
  export type CustomCssProperties = {
9143
9138
  /** How wide an axis column is drawn, in `ch`, from the widest number on it. Written on the axis itself, and only where the categories run along the bottom: turned sideways an axis is a row and takes a line's height instead. */
9144
9139
  "--bar-chart-axis"?: (string) | undefined;
9145
- /** The color of the secondary axis when one series owns it. It resolves a `--helix-color-series-*` token, so on the headless tier alone it names something that is not there. #138. */
9140
+ /** The color of the secondary axis, where one series owns it. Written by the component from that series' `--chart-series-*`, so it promises the series color and nothing more: whatever that hook resolves to is what the axis is drawn in. */
9146
9141
  "--bar-chart-secondary"?: (string) | undefined;
9147
9142
  /** The gradient a bar would take, named per bar so the styled tier can point `fill` at it. Drawn whatever the treatment and used only where `wash="gradient"` asks for it. */
9148
9143
  "--chart-bar-wash"?: (string) | undefined;
@@ -9166,24 +9161,14 @@ export type CustomCssProperties = {
9166
9161
  "--color-picker-saturation"?: (string) | undefined;
9167
9162
  /** A color to paint: the current one on the sample, a preset's on each preset. */
9168
9163
  "--color-picker-swatch"?: (string) | undefined;
9169
- /** The edge the column a cell sits under is set to, `start`, `center` or `end`, and unset under a column that sets none. Written by the component onto each cell it draws, read by the sheet that paints one; `helix-table` publishes `--table-cell-align` for the same attribute on the cells a consumer wrote, under its own family's name. */
9164
+ /** The edge the column a cell sits under is set to, `start`, `center` or `end`, and unset under a column that sets none. Written by the component onto each cell it draws, read by the sheet that paints one; Table publishes `--table-cell-align` for the same attribute on the cells a consumer wrote, under its own family's name. */
9170
9165
  "--data-table-cell-align"?: (string) | undefined;
9171
- /** The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet. `--data-table-columns` is the one to set. */
9166
+ /** The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet. A column's `width` is the one to set. */
9172
9167
  "--data-table-template"?: (string) | undefined;
9173
9168
  /** How many month columns are drawn, capped at two. `--date-picker-columns` overrides it. */
9174
9169
  "--date-picker-column-count"?: (string) | undefined;
9175
9170
  /** How thick the ring is drawn, derived from `hole`. */
9176
9171
  "--donut-chart-stroke"?: (string) | undefined;
9177
- /** How tall a cell is. A row of a tall thin cell is what a status page draws. */
9178
- "--heatmap-cell-height"?: (string) | undefined;
9179
- /** How wide a cell is. The strip fits as many as the container allows. */
9180
- "--heatmap-cell-inline-size"?: (string) | undefined;
9181
- /** How far a cell's corners are rounded. */
9182
- "--heatmap-cell-radius"?: (string) | undefined;
9183
- /** The size a cell wants on both axes, where neither is given its own. */
9184
- "--heatmap-cell-size"?: (string) | undefined;
9185
- /** Space between cells. Zero is a continuous field rather than a grid of tiles. */
9186
- "--heatmap-gap"?: (string) | undefined;
9187
9172
  /** How many rows the strip lays out. Written by the component from the data, read by the tier that draws it. */
9188
9173
  "--heatmap-rows"?: (string) | undefined;
9189
9174
  /** The tone of the cell this is set on. Written by the component, read by the sheet that paints. */
@@ -9258,7 +9243,7 @@ export type CustomCssProperties = {
9258
9243
  "--splitter-position"?: (string) | undefined;
9259
9244
  /** The edge the column this cell sits under is set to, `start`, `center` or `end`, and unset under a column that sets none. Written by the table around it, since the cell is the consumer's markup and nothing is written onto it; read by the sheet that draws the cell, where `justify-content` and `text-align` both take it as it comes and both follow the writing direction. */
9260
9245
  "--table-cell-align"?: (string) | undefined;
9261
- /** The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet. `--table-columns` is the one to set. */
9246
+ /** The column track list this element worked out from the columns declared in it. Written by the component, read by the sheet that paints: a stylesheet takes it to lay the grid out, and setting it does nothing, because the component writes it inline on the very element that reads it and an inline declaration beats any sheet. `columns` is the one to set. */
9262
9247
  "--table-template"?: (string) | undefined;
9263
9248
  /** How long this message stays, in milliseconds, for a progress hint. */
9264
9249
  "--toast-duration"?: (string) | undefined;
@@ -9282,7 +9267,7 @@ export interface WcToolkitVueGlobalComponents {
9282
9267
  HelixHeadlessAccordionItemVueProps,
9283
9268
  HelixHeadlessAccordionItemVueEvents
9284
9269
  >;
9285
- /** Holds the mode and nothing else. The item that was clicked is what coordinates: it walks up to the nearest accordion, reads the mode off it, and closes its peers itself. Coordination is structural, not a subscription. 'helix-before-open' does not bubble and is not composed, because overlays nest and an inner one's lifecycle must never read as the outer one's, so an accordion cannot learn that a child opened by listening for it. Membership resolves on demand, so there is no registry to keep in step: an item added a second after render coordinates on its first click. Items are matched with 'instanceof HelixHeadlessAccordionItem', never by tag name. Matching 'helix-accordion-item' would tie this tier to the styled one. The keyboard listener is the controller's and is attached on connect, so none of it runs on the server, where there is no tree to walk and no events to hear. */
9270
+ /** Holds the mode and nothing else. The item that was clicked is what coordinates: it walks up to the nearest accordion, reads the mode off it, and closes its peers itself. Coordination is structural, not a subscription. 'helix-before-open' does not bubble and is not composed, because overlays nest and an inner one's lifecycle must never read as the outer one's, so an accordion cannot learn that a child opened by listening for it. Membership resolves on demand, so there is no registry to keep in step: an item added a second after render coordinates on its first click. Items are matched with 'instanceof HelixHeadlessAccordionItem', never by tag name, so this tier does not learn about the styled one. The keyboard listener is the controller's and is attached on connect, so none of it runs on the server, where there is no tree to walk and no events to hear. */
9286
9271
  "helix-headless-accordion": DefineCustomElement<
9287
9272
  HelixHeadlessAccordion,
9288
9273
  HelixHeadlessAccordionVueProps,
@@ -9366,7 +9351,7 @@ export interface WcToolkitVueGlobalComponents {
9366
9351
  HelixHeadlessCalloutVueProps,
9367
9352
  HelixHeadlessCalloutVueEvents
9368
9353
  >;
9369
- /** Regions are slots rather than separate elements, because a header, body, and footer carry no state, no behavior, and no API of their own. Slotting them costs one custom element instead of five and lets the consumer bring their own markup, so a title can be a real '<h2>' rather than an emulated one. The host is the surface. A wrapper '<div part="container">' would be a second box doing nothing the host cannot: the element itself takes the border, the radius, and the grid, and a consumer styles 'helix-card' rather than reaching through '::part'. One node instead of two, on every card on the page. Name the card with 'aria-label' or 'aria-labelledby'. That is the only naming that survives server rendering: reading a title out of the light DOM needs a DOM, and the server has none. */
9354
+ /** Regions are slots rather than separate elements, because a header, body, and footer carry no state, no behavior, and no API of their own. Slotting them costs one custom element instead of five and lets the consumer bring their own markup, so a title can be a real '<h2>' rather than an emulated one. The host is the surface. A wrapper '<div part="container">' would be a second box doing nothing the host cannot: the element itself takes the border, the radius, and the grid, and a consumer styles 'Card' rather than reaching through '::part'. One node instead of two, on every card on the page. Name the card with 'aria-label' or 'aria-labelledby'. That is the only naming that survives server rendering: reading a title out of the light DOM needs a DOM, and the server has none. */
9370
9355
  "helix-headless-card": DefineCustomElement<
9371
9356
  HelixHeadlessCard,
9372
9357
  HelixHeadlessCardVueProps,
@@ -9420,7 +9405,7 @@ export interface WcToolkitVueGlobalComponents {
9420
9405
  HelixHeadlessCodeVueProps,
9421
9406
  HelixHeadlessCodeVueEvents
9422
9407
  >;
9423
- /** **The picker is 'helix-color-picker', not a second one written here.** It owns the square, the ramps, the eyedropper and the syntax toggle, and it is worth having on its own: a settings pane wants a picker flat on the page with nothing to open. This element is the field, the overlay, and the form. Exactly the arrangement Date Input has with 'helix-date-picker'. **Typed as well as picked, and the typing is the reason this is not '<input type="color">'.** The native control gives a free picker and takes nearly all styling with it, which is a fair trade until a product needs the panel to match everything around it. What is kept from the native one is the part worth keeping: a real text field, so a reader who has the hex pastes it and never opens anything. **Every syntax is read; the one 'format' names is written.** '#f00', '#ff0000', 'rgb(255 0 0)', 'rgba(255,0,0,.5)', 'rgb(255 0 0 / 50%)' and 'hsl(0 100% 50%)' are all colors, and a field that refuses one because it prefers another is arguing with the person using it. What the field *shows* is the value itself, for the reason Date Input gives about its dates: half-typed input does not survive a round trip through a formatter. The custom property below is written by this component and never set by a consumer: it carries a value this element resolved and CSS cannot, which is what lets a stylesheet on this tier paint the swatch without parsing anything itself. */
9408
+ /** **The picker is 'ColorPicker', not a second one written here.** It owns the square, the ramps, the eyedropper and the syntax toggle, and it is worth having on its own: a settings pane wants a picker flat on the page with nothing to open. This element is the field, the overlay, and the form. Exactly the arrangement Date Input has with 'DatePicker'. **Typed as well as picked, and the typing is the reason this is not '<input type="color">'.** The native control gives a free picker and takes nearly all styling with it, which is a fair trade until a product needs the panel to match everything around it. What is kept from the native one is the part worth keeping: a real text field, so a reader who has the hex pastes it and never opens anything. **Every syntax is read; the one 'format' names is written.** '#f00', '#ff0000', 'rgb(255 0 0)', 'rgba(255,0,0,.5)', 'rgb(255 0 0 / 50%)' and 'hsl(0 100% 50%)' are all colors, and a field that refuses one because it prefers another is arguing with the person using it. What the field *shows* is the value itself, for the reason Date Input gives about its dates: half-typed input does not survive a round trip through a formatter. The custom property below is written by this component and never set by a consumer: it carries a value this element resolved and CSS cannot, which is what lets a stylesheet on this tier paint the swatch without parsing anything itself. */
9424
9409
  "helix-headless-color-input": DefineCustomElement<
9425
9410
  HelixHeadlessColorInput,
9426
9411
  HelixHeadlessColorInputVueProps,
@@ -9432,13 +9417,13 @@ export interface WcToolkitVueGlobalComponents {
9432
9417
  HelixHeadlessColorPickerVueProps,
9433
9418
  HelixHeadlessColorPickerVueEvents
9434
9419
  >;
9435
- /** **The list is 'helix-listbox', and the filtering is its own.** It owns narrowing, the empty state, the highlight, 'aria-activedescendant' and scrolling an option into view. What is left for this element is the field, the panel and the traffic between them. **The text and the value are two things.** What a reader types is a filter: it narrows the list and is thrown away. The value is whichever option they then choose, and the field is rewritten to that option's words once they have. The filter is cleared on close, so a reopened control does not start from the last visit's leftovers. **Focus stays in the field, which is the whole of what a combobox is.** The arrows move the list without leaving the text, through the listbox's public 'navigate'. 'role="combobox"' is on the input rather than on a wrapper, because the thing the pattern describes is the text field. **With 'multiple', the chosen options are tags in the field**, one object per answer, each with its own remove control. The panel stays open while more than one can be chosen and the filter clears on each choice, so the next pick starts from the whole list. **'creatable' announces, and does not write.** The options are the consumer's light DOM and nothing here puts an element into it: a component that grew the consumer's markup would be one their framework re-renders over. It offers the row and fires the event; adding the option is the consumer's. */
9420
+ /** **The list is 'Listbox', and the filtering is its own.** It owns narrowing, the empty state, the highlight, 'aria-activedescendant' and scrolling an option into view. What is left for this element is the field, the panel and the traffic between them. **The text and the value are two things.** What a reader types is a filter: it narrows the list and is thrown away. The value is whichever option they then choose, and the field is rewritten to that option's words once they have. The filter is cleared on close, so a reopened control does not start from the last visit's leftovers. **Focus stays in the field, which is the whole of what a combobox is.** The arrows move the list without leaving the text, through the listbox's public 'navigate'. 'role="combobox"' is on the input rather than on a wrapper, because the thing the pattern describes is the text field. **With 'multiple', the chosen options are tags in the field**, one object per answer, each with its own remove control. The panel stays open while more than one can be chosen and the filter clears on each choice, so the next pick starts from the whole list. **'creatable' announces, and does not write.** The options are the consumer's light DOM and nothing here puts an element into it: a component that grew the consumer's markup would be one their framework re-renders over. It offers the row and fires the event; adding the option is the consumer's. */
9436
9421
  "helix-headless-combobox": DefineCustomElement<
9437
9422
  HelixHeadlessCombobox,
9438
9423
  HelixHeadlessComboboxVueProps,
9439
9424
  HelixHeadlessComboboxVueEvents
9440
9425
  >;
9441
- /** **The list is 'helix-listbox', filtering and all.** Listbox already owns narrowing, the empty state, the highlight over what matched, 'aria-activedescendant', scrolling an option into view and the keyboard that moves between them. Its own note says a command palette is that list again with something different opening it, and this is that something: a dialog, and a key that summons it. **The value is not kept.** A palette runs a command and forgets it: nothing here is a form control and nothing is submitted, so what it reports is that an option was chosen, once, with 'helix-select'. A consumer that wants the last command remembered is a consumer with somewhere better to keep it. **The hotkey is global and the element does not have to be open to hear it.** The listener is on the document, because the point of a palette is that it answers from wherever the reader is, including from inside another control's text field. 'mod' is Command on a Mac and Control elsewhere, resolved here so a consumer writes one thing. The filter is emptied as the palette closes, for the reason Combobox and Select both record: a control reopened still narrowed by the last visit's search is one whose second use starts from the first one's leftovers, and a palette is used far more often than either. */
9426
+ /** **The list is 'Listbox', filtering and all.** Listbox already owns narrowing, the empty state, the highlight over what matched, 'aria-activedescendant', scrolling an option into view and the keyboard that moves between them. Its own note says a command palette is that list again with something different opening it, and this is that something: a dialog, and a key that summons it. **The value is not kept.** A palette runs a command and forgets it: nothing here is a form control and nothing is submitted, so what it reports is that an option was chosen, once, with 'helix-select'. A consumer that wants the last command remembered is a consumer with somewhere better to keep it. **The hotkey is global and the element does not have to be open to hear it.** The listener is on the document, because the point of a palette is that it answers from wherever the reader is, including from inside another control's text field. 'mod' is Command on a Mac and Control elsewhere, resolved here so a consumer writes one thing. The filter is emptied as the palette closes, for the reason Combobox and Select both record: a control reopened still narrowed by the last visit's search is one whose second use starts from the first one's leftovers, and a palette is used far more often than either. */
9442
9427
  "helix-headless-command": DefineCustomElement<
9443
9428
  HelixHeadlessCommand,
9444
9429
  HelixHeadlessCommandVueProps,
@@ -9450,13 +9435,13 @@ export interface WcToolkitVueGlobalComponents {
9450
9435
  HelixHeadlessCopyButtonVueProps,
9451
9436
  HelixHeadlessCopyButtonVueEvents
9452
9437
  >;
9453
- /** **The schema is markup and the data is a property.** Columns are declared as 'helix-table-column' children, because a schema is small and something a reader should see in the HTML; rows are handed over as an array, because a table that draws ten thousand elements cannot window them. '''html <helix-data-table .rows=${rows} sort="name:asc" page-size="20"> <helix-table-column field="name" sortable>Name</helix-table-column> <helix-table-column field="size" align="end" sortable .cell=${bytes}>Size</helix-table-column> </helix-data-table> ''' 'helix-table' takes rows as markup and is the right component for a table of twelve things a person wrote out. **Sort and filter apply to the whole set, never the page.** Sorting the drawn window is correct on the first screen and wrong on every other one. **The cell values do not server-render.** The headings do, and the row elements do, but reading a cell needs the columns, and the columns are markup children Lit SSR does not hand this element. So a crawler sees a table of the right shape with nothing in it. That is the cost of the first paragraph: use 'helix-table' where the served HTML has to carry the values. **'selectable' adds a column of checkboxes, keyed on 'row-key'.** A row is selected by its identity rather than its position, so a selection survives a sort, a filter and a page. 'selected' is the chosen keys, comma separated, the shape Listbox uses for a multiple choice, and like 'sort' it is controlled when set and seeded by 'default-selected'. The box in the heading selects every row in the result, across pages, and shows a dash while only some are chosen. Choosing one of many, rather than several, is opening a row, and that is a link or a button in a cell rather than a selection. **A reader can size and order the columns.** 'resizable' on a column puts a separator on its edge; 'reorderable' on the table puts a grip on each heading that has a 'field', moved by dragging or with the arrow keys. The order lands in 'order' as fields, and the consumer's own markup is never rewritten: the table assigns the headings to its header in that order instead. **'csv()' hands back the result as text**: every row the filter lets through, in the order on screen, in the columns on screen. Saving it is the page's business, the same as any other file. **There is no 'columns' attribute here, and 'helix-table' has one.** The difference is what a column is in each: here it is the schema, so a table without one has nothing to read a row with, and every column is a place to write a 'width'. A 'helix-table' holds cells a consumer wrote and can be written with no column at all, so its 'columns' is where such a table is sized from. Written on this element the attribute is inert, which is the trap worth knowing when moving between the two. What both take is the CSS hook, '--data-table-columns' here and '--table-columns' there. */
9438
+ /** **The schema is markup and the data is a property.** Columns are declared as 'TableColumn' children, because a schema is small and something a reader should see in the HTML; rows are handed over as an array, because a table that draws ten thousand elements cannot window them. '''html <helix-headless-data-table .rows=${rows} sort="name:asc" page-size="20"> <helix-headless-table-column field="name" sortable>Name</helix-headless-table-column> <helix-headless-table-column field="size" align="end" sortable .cell=${bytes}>Size</helix-headless-table-column> </helix-headless-data-table> ''' 'Table' takes rows as markup and is the right component for a table of twelve things a person wrote out. **Sort and filter apply to the whole set, never the page.** Sorting the drawn window is correct on the first screen and wrong on every other one. **The cell values do not server-render.** The headings do, and the row elements do, but reading a cell needs the columns, and the columns are markup children Lit SSR does not hand this element. So a crawler sees a table of the right shape with nothing in it. That is the cost of the first paragraph: use 'Table' where the served HTML has to carry the values. **'selectable' adds a column of checkboxes, keyed on 'row-key'.** A row is selected by its identity rather than its position, so a selection survives a sort, a filter and a page. 'selected' is the chosen keys, comma separated, the shape Listbox uses for a multiple choice, and like 'sort' writing it applies while 'default-selected' is what the markup declared. The box in the heading selects every row in the result, across pages, and shows a dash while only some are chosen. Choosing one of many, rather than several, is opening a row, and that is a link or a button in a cell rather than a selection. **A reader can size and order the columns.** 'resizable' on a column puts a separator on its edge; 'reorderable' on the table puts a grip on each heading that has a 'field', moved by dragging or with the arrow keys. The order lands in 'order' as fields, and the consumer's own markup is never rewritten: the table assigns the headings to its header in that order instead. **'csv()' hands back the result as text**: every row the filter lets through, in the order on screen, in the columns on screen. Saving it is the page's business, the same as any other file. **There is no 'columns' attribute here, and Table has one.** The difference is what a column is in each: here it is the schema, so a table without one has nothing to read a row with, and every column is a place to write a 'width'. A Table holds cells a consumer wrote and can be written with no column at all, so its 'columns' is where such a table is sized from. Written on this element the attribute is inert, which is the trap worth knowing when moving between the two. */
9454
9439
  "helix-headless-data-table": DefineCustomElement<
9455
9440
  HelixHeadlessDataTable,
9456
9441
  HelixHeadlessDataTableVueProps,
9457
9442
  HelixHeadlessDataTableVueEvents
9458
9443
  >;
9459
- /** **The calendar is 'helix-date-picker', not a second one written here.** It already knows about months, ranges, disabled days, the first day of the week and every keyboard rule a grid owes a reader. This element is the field, the overlay, and the translation between them. **Typed as well as picked, and the typing is why it is not '<input type="date">'.** The native control gives a free picker and a free locale and takes almost all styling with it. What is kept from it is the part worth keeping: a real text field. */
9444
+ /** **The calendar is 'DatePicker', not a second one written here.** It already knows about months, ranges, disabled days, the first day of the week and every keyboard rule a grid owes a reader. This element is the field, the overlay, and the translation between them. **Typed as well as picked, and the typing is why it is not '<input type="date">'.** The native control gives a free picker and a free locale and takes almost all styling with it. What is kept from it is the part worth keeping: a real text field. */
9460
9445
  "helix-headless-date-input": DefineCustomElement<
9461
9446
  HelixHeadlessDateInput,
9462
9447
  HelixHeadlessDateInputVueProps,
@@ -9498,7 +9483,7 @@ export interface WcToolkitVueGlobalComponents {
9498
9483
  HelixHeadlessDonutChartVueProps,
9499
9484
  HelixHeadlessDonutChartVueEvents
9500
9485
  >;
9501
- /** Takes 'MixinControllerOpen', so 'open', 'defaultOpen' and the 'helix-before-open' and 'helix-before-close' requests behave exactly as they do on an accordion item, and a consumer already knows the API. Modal by default, which is three things together and not one: focus is trapped inside, Escape and an outside press close it, and the page behind is covered. A panel with the look of a modal and none of its behavior is worse than an inline one, because it invites the reader to treat it as blocking. Content stays mounted when closed, so it is in the server's markup and can animate. A closed '<dialog>' is already out of the tab order and out of the accessibility tree, so nothing here writes 'inert'. The 'role', the 'aria-modal' and the scrim come from the element too, and 'drawer-root.ssr.spec.ts' asserts the panel carries no hand-written 'inert' and no hand-written 'role'. Opened declaratively with the platform's invoker attributes: '''html <helix-button commandfor="nav" command="--toggle">Menu</helix-button> <helix-drawer id="nav">…</helix-drawer> ''' */
9486
+ /** Takes 'MixinControllerOpen', so 'open', 'defaultOpen' and the 'helix-before-open' and 'helix-before-close' requests behave exactly as they do on an accordion item, and a consumer already knows the API. Modal by default, which is three things together and not one: focus is trapped inside, Escape and an outside press close it, and the page behind is covered. A panel with the look of a modal and none of its behavior is worse than an inline one, because it invites the reader to treat it as blocking. Content stays mounted when closed, so it is in the server's markup and can animate. A closed '<dialog>' is already out of the tab order and out of the accessibility tree, so nothing here writes 'inert'. The 'role', the 'aria-modal' and the scrim come from the element too, and 'drawer-root.ssr.spec.ts' asserts the panel carries no hand-written 'inert' and no hand-written 'role'. Opened declaratively with the platform's invoker attributes: '''html <helix-headless-button commandfor="nav" command="--toggle">Menu</helix-headless-button> <helix-headless-drawer id="nav">…</helix-headless-drawer> ''' */
9502
9487
  "helix-headless-drawer": DefineCustomElement<
9503
9488
  HelixHeadlessDrawer,
9504
9489
  HelixHeadlessDrawerVueProps,
@@ -9552,7 +9537,7 @@ export interface WcToolkitVueGlobalComponents {
9552
9537
  HelixHeadlessFilterOperatorVueProps,
9553
9538
  HelixHeadlessFilterOperatorVueEvents
9554
9539
  >;
9555
- /** **The tokens are the consumer's own elements, slotted.** What a filter narrows by belongs to the consumer's model rather than to this element: a facet with a prefix, a saved query, a range. So they are slotted rather than rendered from a list of strings, and removing one is a request this element makes rather than a change it applies. Combobox is the other way round, and that is the difference between the two: its tokens are a view of a selection it owns, drawn from options it was handed. **'value' is the text being typed, not the tokens**, which is what makes this a field a consumer can listen to. Every keystroke announces 'input' with the text on the element, so a table narrows as the reader types. The tokens need no reporting back, being markup the consumer already holds. Backspace on an empty field asks the last token to go, through the same 'helix-dismiss' its own remove control fires, so a consumer who handled the pointer has already handled the keyboard. **It reads what was declared, and nothing that was not.** Write 'FilterField's (usually inside the 'FilterMenu' slotted into 'start', so the picker and the text work off one set), and Enter reads the box against them: 'disposition:refunded,settled' and '-disposition:refunded' announce 'helix-facet', exactly as ticking those values in the picker would, and the text they were read from goes. Everything else stays where it was typed, so 'refund tuesday disposition:settled' is a filter and a search at once. 'grammar.ts' carries the whole rule and is worth reading before relying on it; the short version is that Helix owns the punctuation and the consumer owns every word in it. A field with no 'FilterField' in it parses nothing, which is the behavior this had before it could. **A field whose values cannot be listed belongs here rather than in the picker.** 'assignee:ada' is a filter and nobody wants to enumerate every name in the company, but a menu page for it would have nothing on it to press. Written directly inside this element it is read by the grammar and never offered as a page: unslotted, so nothing draws it, which is the same trick 'FilterField' already plays on its own children. **It can suggest what to type next, and deciding what to suggest is still the consumer's.** Slot 'helix-option' elements into 'suggestions' and the field shows them, moves through them with the arrows, and lets Enter press one; the option fires its own 'helix-select' and the consumer decides what choosing meant. Keys before a colon and values after it are the same panel with different contents, and 'readFilterText' is exported for a consumer narrowing that panel against what a reader has half typed. **The panel opens when there is something in it and closes when there is not**, rather than on a choice. A reader who picks a key wants its values next, and closing on the choice would shut the panel between two renders. Use 'selectionStart' and 'setSelectionRange' to write a completion back and put the caret after it, or the next parse reads the wrong term. **Three things here have three different owners, and only one of them is a controlled property.** 'value' is the text, and it is uncontrolled by default: the reader types, the element applies it, and 'input' says so. **Writing 'value' does not take that over.** It is a seed and a correction, so a consumer who sets it and then expects the field to hold still will watch the next keystroke overwrite them. Ownership is taken by refusing 'helix-before-change' and writing the value you want, which is the same shape every field in this library uses and is worth saying out loud here because the property looks like React's. 'default-value' seeds the field without claiming anything. 'open' is the suggestions panel, and it is the ordinary controlled pair: refuse 'helix-before-open' or 'helix-before-close' to take the decision, and 'default-open' to seed it. The tokens are neither, because they are not state. They are the consumer's own elements in a slot, so there is nothing for this to own and nothing to report back: a token goes when the consumer removes it from their markup, having been asked by 'helix-dismiss'. **A 'FilterChip' naming a declared field is asked differently**, and it has to be: the picker holds what is ticked, so a chip that removed itself without telling it left the value ticked in a list nobody could see was wrong. That dismissal is answered as the field being filtered by nothing, so it arrives as 'helix-facet' like every other change and the chip goes because the filter went. */
9540
+ /** **The tokens are the consumer's own elements, slotted.** What a filter narrows by belongs to the consumer's model rather than to this element: a facet with a prefix, a saved query, a range. So they are slotted rather than rendered from a list of strings, and removing one is a request this element makes rather than a change it applies. Combobox is the other way round, and that is the difference between the two: its tokens are a view of a selection it owns, drawn from options it was handed. **'value' is the text being typed, not the tokens**, which is what makes this a field a consumer can listen to. Every keystroke announces 'input' with the text on the element, so a table narrows as the reader types. The tokens need no reporting back, being markup the consumer already holds. Backspace on an empty field asks the last token to go, through the same 'helix-dismiss' its own remove control fires, so a consumer who handled the pointer has already handled the keyboard. **It reads what was declared, and nothing that was not.** Write 'FilterField's (usually inside the 'FilterMenu' slotted into 'start', so the picker and the text work off one set), and Enter reads the box against them: 'disposition:refunded,settled' and '-disposition:refunded' announce 'helix-facet', exactly as ticking those values in the picker would, and the text they were read from goes. Everything else stays where it was typed, so 'refund tuesday disposition:settled' is a filter and a search at once. 'grammar.ts' carries the whole rule and is worth reading before relying on it; the short version is that Helix owns the punctuation and the consumer owns every word in it. A field with no 'FilterField' in it parses nothing, which is the behavior this had before it could. **A field whose values cannot be listed belongs here rather than in the picker.** 'assignee:ada' is a filter and nobody wants to enumerate every name in the company, but a menu page for it would have nothing on it to press. Written directly inside this element it is read by the grammar and never offered as a page: unslotted, so nothing draws it, which is the same trick 'FilterField' already plays on its own children. **It can suggest what to type next, and deciding what to suggest is still the consumer's.** Slot options into 'suggestions' and the field shows them, moves through them with the arrows, and lets Enter press one; the option fires its own 'helix-select' and the consumer decides what choosing meant. Keys before a colon and values after it are the same panel with different contents, and 'readFilterText' is exported for a consumer narrowing that panel against what a reader has half typed. **The panel opens when there is something in it and closes when there is not**, rather than on a choice. A reader who picks a key wants its values next, and closing on the choice would shut the panel between two renders. Use 'selectionStart' and 'setSelectionRange' to write a completion back and put the caret after it, or the next parse reads the wrong term. **Three things here have three different owners.** 'value' is the text: the reader types, the element applies it, and 'input' says so. **Writing 'value' does not take that over.** It is a seed and a correction, so a consumer who sets it and then expects the field to hold still will watch the next keystroke overwrite them. Ownership is taken by refusing 'helix-before-change' and writing the value you want, which is the same shape every field in this library uses and is worth saying out loud here because the property looks like React's. 'default-value' seeds the field without claiming anything. 'open' is the suggestions panel, and it is the ordinary pair: refuse 'helix-before-open' or 'helix-before-close' to take the decision, and 'default-open' to seed it. The tokens are neither, because they are not state. They are the consumer's own elements in a slot, so there is nothing for this to own and nothing to report back: a token goes when the consumer removes it from their markup, having been asked by 'helix-dismiss'. **A 'FilterChip' naming a declared field is asked differently**, and it has to be: the picker holds what is ticked, so a chip that removed itself without telling it left the value ticked in a list nobody could see was wrong. That dismissal is answered as the field being filtered by nothing, so it arrives as 'helix-facet' like every other change and the chip goes because the filter went. */
9556
9541
  "helix-headless-filter-input": DefineCustomElement<
9557
9542
  HelixHeadlessFilterInput,
9558
9543
  HelixHeadlessFilterInputVueProps,
@@ -9672,7 +9657,7 @@ export interface WcToolkitVueGlobalComponents {
9672
9657
  HelixHeadlessNotificationGroupVueProps,
9673
9658
  HelixHeadlessNotificationGroupVueEvents
9674
9659
  >;
9675
- /** A notification is a toast that did not go away. 'helix-toast' is deliberately the opposite of this: a live region whose items carry a 'duration' and whose root never creates or destroys anything. What makes this its own family is the state each item carries rather than the arrangement it sits in: read and unread, a timestamp that has to stay correct, and an action a reader can take later. **The row is a label, a caption under it, and one trailing column that holds either the time or the controls.** A feed is scanned rather than read, so the thing that happened gets the first line on its own and everything qualifying it goes under. The time and the controls occupy the same place because a reader wants exactly one of them at a time: the time while they are scanning, and what they can do about it once they have stopped on a row. **The timestamp is 'helix-format-date'**, which is where the reading, the '<time datetime>' and the shared timer now live. It was implemented here, and a component that formats a date is not a fact about notifications: Chat wanted the same thing and had its own copy of half of it. **Read state is reported, not invented.** Marking something read is usually a round trip, and a component that flips its own state and then hears the request failed has told the reader something untrue. 'helix-read' is cancelable, and a 'read' set by the consumer makes this element defer entirely. */
9660
+ /** A notification is a toast that did not go away. 'Toast' is deliberately the opposite of this: a live region whose items carry a 'duration' and whose root never creates or destroys anything. What makes this its own family is the state each item carries rather than the arrangement it sits in: read and unread, a timestamp that has to stay correct, and an action a reader can take later. **The row is a label, a caption under it, and one trailing column that holds either the time or the controls.** A feed is scanned rather than read, so the thing that happened gets the first line on its own and everything qualifying it goes under. The time and the controls occupy the same place because a reader wants exactly one of them at a time: the time while they are scanning, and what they can do about it once they have stopped on a row. **The timestamp is 'FormatDate'**, which is where the reading, the '<time datetime>' and the shared timer now live. It was implemented here, and a component that formats a date is not a fact about notifications: Chat wanted the same thing and had its own copy of half of it. **Read state is reported, not invented.** Marking something read is usually a round trip, and a component that flips its own state and then hears the request failed has told the reader something untrue. 'helix-read' is cancelable, and a 'read' set by the consumer makes this element defer entirely. */
9676
9661
  "helix-headless-notification": DefineCustomElement<
9677
9662
  HelixHeadlessNotification,
9678
9663
  HelixHeadlessNotificationVueProps,
@@ -9714,13 +9699,13 @@ export interface WcToolkitVueGlobalComponents {
9714
9699
  HelixHeadlessOutlineVueProps,
9715
9700
  HelixHeadlessOutlineVueEvents
9716
9701
  >;
9717
- /** **The component is the truncation.** Given a page and a total it works out which numbers to show and where the runs break, so this is data-driven rather than composed: '<helix-pagination page="4" pages="12">' rather than twelve slotted children a consumer keeps in step with their own query. **The width does not change as you page.** The run around the current page is 'siblings' either side, and grows to absorb a gap slot at a boundary, so the control holds the same number of slots from the first page to the last. Anything that lets the count vary moves the buttons under the pointer between one click and the next. **A gap is only drawn where it hides more than one page, and a gap is a control.** It goes to the middle of the run it stands over, which is the binary-search step: any page in a set of any size is a handful of presses. **'href' is what makes these links.** Set it and every page renders an '<a>' with '{page}' filled in, so the output is crawlable, a middle click opens a tab, and the address bar is the state. Left unset they are buttons, which is right for a table paging in place. Either way the click announces 'helix-navigate' first, and 'preventDefault()' stops the navigation as well as the change, which is how a router takes over. **'helix-navigate' and not 'helix-change'.** Moving to page four chooses nothing; it moves the view over a result that has not changed. **The count and the page-size control are their own elements.** 'Pagination.Summary' and 'Pagination.Size' sit beside this one, because a slot can only offer one place: at one end of one row, in one order. */
9702
+ /** **The component is the truncation.** Given a page and a total it works out which numbers to show and where the runs break, so this is data-driven rather than composed: '<helix-headless-pagination page="4" pages="12">' rather than twelve slotted children a consumer keeps in step with their own query. **The width does not change as you page.** The run around the current page is 'siblings' either side, and grows to absorb a gap slot at a boundary, so the control holds the same number of slots from the first page to the last. Anything that lets the count vary moves the buttons under the pointer between one click and the next. **A gap is only drawn where it hides more than one page, and a gap is a control.** It goes to the middle of the run it stands over, which is the binary-search step: any page in a set of any size is a handful of presses. **'href' is what makes these links.** Set it and every page renders an '<a>' with '{page}' filled in, so the output is crawlable, a middle click opens a tab, and the address bar is the state. Left unset they are buttons, which is right for a table paging in place. Either way the click announces 'helix-navigate' first, and 'preventDefault()' stops the navigation as well as the change, which is how a router takes over. **'helix-navigate' and not 'helix-change'.** Moving to page four chooses nothing; it moves the view over a result that has not changed. **The count and the page-size control are their own elements.** 'Pagination.Summary' and 'Pagination.Size' sit beside this one, because a slot can only offer one place: at one end of one row, in one order. */
9718
9703
  "helix-headless-pagination": DefineCustomElement<
9719
9704
  HelixHeadlessPagination,
9720
9705
  HelixHeadlessPaginationVueProps,
9721
9706
  HelixHeadlessPaginationVueEvents
9722
9707
  >;
9723
- /** Its own element beside 'Pagination' rather than a slot inside it, for the reason 'Pagination.Summary' is: a footer's direction and order are the consumer's, and a control that can only sit at one end of one row has taken that decision for them. **'Select', not a native '<select>'.** Two dropdowns identical closed and different open meet each other in the same footer as a table's filters. The caret is 'Select''s rather than a color literal baked into a data URI, because a background image cannot read 'currentColor', and the label is a real '<label for>' against the trigger's own id. **The label sits on the row, not above it.** 'Select''s host is a column, and an outer-tree rule beats a ':host' rule, so turning it into a row needs no property on 'Select' and nothing written into the consumer's markup. **An empty 'sizes' renders nothing**, rather than falling back to the built-in list, which would be a component overruling a consumer who said "none". Same rule as 'Pagination' over a single page, and reported the same way, through 'ElementInternals.states' rather than an attribute the server never wrote. 'value' is the controlled property and 'default-value' seeds one this owns. Changing it announces 'helix-before-change'; re-querying and moving back to page one is the consumer's, because only they know whether the reader's position should survive it. */
9708
+ /** Its own element beside 'Pagination' rather than a slot inside it, for the reason 'Pagination.Summary' is: a footer's direction and order are the consumer's, and a control that can only sit at one end of one row has taken that decision for them. **'Select', not a native '<select>'.** Two dropdowns identical closed and different open meet each other in the same footer as a table's filters. The caret is 'Select''s rather than a color literal baked into a data URI, because a background image cannot read 'currentColor', and the label is a real '<label for>' against the trigger's own id. **The label sits on the row, not above it.** 'Select''s host is a column, and an outer-tree rule beats a ':host' rule, so turning it into a row needs no property on 'Select' and nothing written into the consumer's markup. **An empty 'sizes' renders nothing**, rather than falling back to the built-in list, which would be a component overruling a consumer who said "none". Same rule as 'Pagination' over a single page, and reported the same way, through 'ElementInternals.states' rather than an attribute the server never wrote. 'value' is the size the control holds and 'default-value' is what the markup declared. Changing it announces 'helix-before-change'; re-querying and moving back to page one is the consumer's, because only they know whether the reader's position should survive it. */
9724
9709
  "helix-headless-pagination-size": DefineCustomElement<
9725
9710
  HelixHeadlessPaginationSize,
9726
9711
  HelixHeadlessPaginationSizeVueProps,
@@ -9828,7 +9813,7 @@ export interface WcToolkitVueGlobalComponents {
9828
9813
  HelixHeadlessSpeedDialItemVueProps,
9829
9814
  HelixHeadlessSpeedDialItemVueEvents
9830
9815
  >;
9831
- /** **A menu, and deliberately not a new one.** Its rows are commands, which is what 'role="menu"' and 'menuitem' exist for, so this takes them and takes the behavior with them: the arrow keys are 'KeyboardNavigationController', the panel is 'PopoverController', and open and closed is 'MixinControllerOpen'. 'Menu' is built from the same pieces. What is not shared is what actually differs: a dial has no submenus, no headers, no checkable rows and no long list to type ahead through, and shipping it as an appearance of 'Menu' would mean defining what a dial with a submenu in it does. **The trigger is a control the consumer slots**, and the floating action button is the usual one: 'helix-icon-button' with 'shape="circle"' and 'raised'. There is no 'helix-fab', because it would re-declare 'emphasis', 'tone', 'label' and a size around a control that already has all four. A round raised button is a shape, and where it sits is 'data-dock' in the base layer. **Nothing is reserved from the keyboard.** A menu that drills has to keep the horizontal pair for going in and coming back; a dial goes nowhere, so all four arrows move through the actions and a reader who guesses either axis is answered. That is the controller's own house position, and this is a component with no reason to argue with it. */
9816
+ /** **A menu, and deliberately not a new one.** Its rows are commands, which is what 'role="menu"' and 'menuitem' exist for, so this takes them and takes the behavior with them: the arrow keys are 'KeyboardNavigationController', the panel is 'PopoverController', and open and closed is 'MixinControllerOpen'. 'Menu' is built from the same pieces. What is not shared is what actually differs: a dial has no submenus, no headers, no checkable rows and no long list to type ahead through, and shipping it as an appearance of 'Menu' would mean defining what a dial with a submenu in it does. **The trigger is a control the consumer slots**, and the floating action button is the usual one: 'IconButton' with 'shape="circle"' and 'raised'. There is no 'helix-fab', because it would re-declare 'emphasis', 'tone', 'label' and a size around a control that already has all four. A round raised button is a shape, and where it sits is 'data-dock' in the base layer. **Nothing is reserved from the keyboard.** A menu that drills has to keep the horizontal pair for going in and coming back; a dial goes nowhere, so all four arrows move through the actions and a reader who guesses either axis is answered. That is the controller's own house position, and this is a component with no reason to argue with it. */
9832
9817
  "helix-headless-speed-dial": DefineCustomElement<
9833
9818
  HelixHeadlessSpeedDial,
9834
9819
  HelixHeadlessSpeedDialVueProps,
@@ -9858,7 +9843,7 @@ export interface WcToolkitVueGlobalComponents {
9858
9843
  HelixHeadlessStepsVueProps,
9859
9844
  HelixHeadlessStepsVueEvents
9860
9845
  >;
9861
- /** **The name is a button, and only the name.** The marker is 'aria-hidden' decoration, so wrapping it would add hit area and no meaning. It is 'helix-button' rather than a '<button>' this element resets: the hover wash, the focus ring and the disabled treatment are decisions the button carries. **It says nothing about where a reader may go.** Every step is pressable and announces itself with 'helix-select'; refusing the ones ahead is 'disabled', which the consumer sets, because only they know whether a form can be skipped. **The marker is a slot whose fallback is the state.** A finished stage shows a check, the current one a target, one not yet reached an empty ring. Exactly one is rendered, chosen from the step's own two booleans, rather than three with two hidden in CSS: the accessibility tree would otherwise carry marks that are not there. */
9846
+ /** **The name is a button, and only the name.** The marker is 'aria-hidden' decoration, so wrapping it would add hit area and no meaning. It is 'Button' rather than a '<button>' this element resets: the hover wash, the focus ring and the disabled treatment are decisions the button carries. **It says nothing about where a reader may go.** Every step is pressable and announces itself with 'helix-select'; refusing the ones ahead is 'disabled', which the consumer sets, because only they know whether a form can be skipped. **The marker is a slot whose fallback is the state.** A finished stage shows a check, the current one a target, one not yet reached an empty ring. Exactly one is rendered, chosen from the step's own two booleans, rather than three with two hidden in CSS: the accessibility tree would otherwise carry marks that are not there. */
9862
9847
  "helix-headless-step": DefineCustomElement<
9863
9848
  HelixHeadlessStep,
9864
9849
  HelixHeadlessStepVueProps,
@@ -9876,7 +9861,7 @@ export interface WcToolkitVueGlobalComponents {
9876
9861
  HelixHeadlessTableCellVueProps,
9877
9862
  HelixHeadlessTableCellVueEvents
9878
9863
  >;
9879
- /** **The column is the source of both its heading and its track.** Add one and the table has another track; remove one and it does not. That is what ties the two together, and a table-level track list on its own does not: a list that is accidentally the headings is invalid CSS a grid ignores in silence, drawing the whole table as one column. 'helix-table''s 'columns' is dealt out a track at a time against the columns declared under it, so a heading among the widths costs its own column a width and no more, and a list longer or shorter than the columns is trimmed or shared rather than being a second count of them. A column's own 'width' wins over the track in its place. **It is also where every per-column fact goes**, which is the reason 'helix-data-table' needs no column config object. 'field' names the key the cell reads, 'sortable' says a reader may reorder by it, 'align' says which edge the values line up against, and 'cell' takes a function for anything the field alone cannot express. The schema is markup and the data is a property: a schema is small, declarative, and something a reader should be able to see in the HTML, and data is large and windowed. **The same element serves both tables**, the markup one and the data one. It is identified by a flag rather than by 'instanceof', so a 'helix-table-column' works inside either without the two roots sharing anything else. **It generates no box of its own**, the same as a row: the heading is a grid item of the table, so it lines up with the cells under it rather than sitting in a wrapper that has to be kept the same width. **'hidden' takes the column out of the grid**, its heading and its track both, so the columns after it keep their own widths and every row keeps its cells under their headings. 'hidden="until-found"' keeps its track, the heading being left drawn, as every Helix element leaves one with that value. 'helix-data-table' draws the cells, so it leaves out the ones under a hidden column. A 'helix-table''s cells are markup the consumer wrote, so hide them with the column, as removing a column means removing its cells: a row with a cell more than the table has tracks wraps into the next. **A heading that does something holds a control that does it.** The host is the column header, and a header is not focusable, so a sortable heading is a '<button>' inside it: the pattern for a sortable table, and the only way a reader on a keyboard reaches the sort at all. A column a reader may resize carries a 'separator' on its end edge, moved by dragging it or with the arrow keys, and a column in a table that lets a reader reorder its columns carries a grip the table moves. */
9864
+ /** **The column is the source of both its heading and its track.** Add one and the table has another track; remove one and it does not. That is what ties the two together, and a table-level track list on its own does not: a list that is accidentally the headings is invalid CSS a grid ignores in silence, drawing the whole table as one column. 'Table''s 'columns' is dealt out a track at a time against the columns declared under it, so a heading among the widths costs its own column a width and no more, and a list longer or shorter than the columns is trimmed or shared rather than being a second count of them. A column's own 'width' wins over the track in its place. **It is also where every per-column fact goes**, which is the reason 'DataTable' needs no column config object. 'field' names the key the cell reads, 'sortable' says a reader may reorder by it, 'align' says which edge the values line up against, and 'cell' takes a function for anything the field alone cannot express. The schema is markup and the data is a property: a schema is small, declarative, and something a reader should be able to see in the HTML, and data is large and windowed. **The same element serves both tables**, the markup one and the data one. It is identified by a flag rather than by 'instanceof', so a 'TableColumn' works inside either without the two roots sharing anything else. **It generates no box of its own**, the same as a row: the heading is a grid item of the table, so it lines up with the cells under it rather than sitting in a wrapper that has to be kept the same width. **'hidden' takes the column out of the grid**, its heading and its track both, so the columns after it keep their own widths and every row keeps its cells under their headings. 'hidden="until-found"' keeps its track, the heading being left drawn, as every Helix element leaves one with that value. 'DataTable' draws the cells, so it leaves out the ones under a hidden column. A 'Table''s cells are markup the consumer wrote, so hide them with the column, as removing a column means removing its cells: a row with a cell more than the table has tracks wraps into the next. **A heading that does something holds a control that does it.** The host is the column header, and a header is not focusable, so a sortable heading is a '<button>' inside it: the pattern for a sortable table, and the only way a reader on a keyboard reaches the sort at all. A column a reader may resize carries a 'separator' on its end edge, moved by dragging it or with the arrow keys, and a column in a table that lets a reader reorder its columns carries a grip the table moves. */
9880
9865
  "helix-headless-table-column": DefineCustomElement<
9881
9866
  HelixHeadlessTableColumn,
9882
9867
  HelixHeadlessTableColumnVueProps,
@@ -9888,7 +9873,7 @@ export interface WcToolkitVueGlobalComponents {
9888
9873
  HelixHeadlessTableVueProps,
9889
9874
  HelixHeadlessTableVueEvents
9890
9875
  >;
9891
- /** 'display: contents' in the styled tier, so the row's cells become items of the table's own grid and every column lines up across every row. The row still exists as an element, which is what a '<table>' gives away when its cells are laid out by the table algorithm. */
9876
+ /** The row renders its cells straight through and lays out none of them, so a sheet can take them into the table's own grid and every column lines up across every row. The row still exists as an element, which is what a '<table>' gives away when its cells are laid out by the table algorithm. */
9892
9877
  "helix-headless-table-row": DefineCustomElement<
9893
9878
  HelixHeadlessTableRow,
9894
9879
  HelixHeadlessTableRowVueProps,
@@ -9924,13 +9909,13 @@ export interface WcToolkitVueGlobalComponents {
9924
9909
  HelixHeadlessTextareaVueProps,
9925
9910
  HelixHeadlessTextareaVueEvents
9926
9911
  >;
9927
- /** **The list is 'helix-time-picker', not a second one written here.** It is worth having on its own, flat in a settings pane with nothing to open, and this element is the field, the overlay and the form. Exactly the arrangement Input Date has with 'helix-date-picker' and Color Input with 'helix-color-picker'. **Typed as well as picked, and that is the division the list depends on.** A list at a step offers the times a product actually has, and the field is how a reader says '09:07'. Neither is a worse version of the other: without the field a step is a cage, and without the list every common time is typed out. **The value is 'HH:mm' on a twenty-four hour clock, always**, because that is what a form submits, what 'min' and 'max' compare against, and what sorts as a string. What the field *shows* is the reader's own convention while it is idle, and the value itself once the caret is in it: the same separation Input Date draws, and for the same reason, which is that '2:30 PM' cannot be typed back and 'Intl' has no parser to make it so. */
9912
+ /** **The list is 'TimePicker', not a second one written here.** It is worth having on its own, flat in a settings pane with nothing to open, and this element is the field, the overlay and the form. Exactly the arrangement Input Date has with 'DatePicker' and Color Input with 'ColorPicker'. **Typed as well as picked, and that is the division the list depends on.** A list at a step offers the times a product actually has, and the field is how a reader says '09:07'. Neither is a worse version of the other: without the field a step is a cage, and without the list every common time is typed out. **The value is 'HH:mm' on a twenty-four hour clock, always**, because that is what a form submits, what 'min' and 'max' compare against, and what sorts as a string. What the field *shows* is the reader's own convention while it is idle, and the value itself once the caret is in it: the same separation Input Date draws, and for the same reason, which is that '2:30 PM' cannot be typed back and 'Intl' has no parser to make it so. */
9928
9913
  "helix-headless-time-input": DefineCustomElement<
9929
9914
  HelixHeadlessTimeInput,
9930
9915
  HelixHeadlessTimeInputVueProps,
9931
9916
  HelixHeadlessTimeInputVueEvents
9932
9917
  >;
9933
- /** **A list rather than three wheels**, and the reason is what a list already is. 'helix-listbox' brings the keyboard, the typeahead, the scroll into view and the announcement of a set of options, and a time at a step is a set of options. Three little wheels for hours, minutes and a meridiem are three controls to build, three to test, and a tab stop each for something a reader answers once. **A step is what makes it a list at all.** Fifteen minutes is ninety-six rows, which a reader scrolls or types into; one minute is one thousand four hundred and forty, which is a listbox in name only. So the list is for the times a product actually offers, and arbitrary times are the field's job in Input Time, the same division Date Input draws between typing a date and using the calendar. **The value is 'HH:mm' on a twenty-four hour clock, always.** That is what a form submits and what 'min' and 'max' compare against, and it sorts as a string, which is the whole reason the shape is that one. What each row *says* is the reader's own convention, from 'Intl'. **The chosen row is marked in the markup, not worked out on upgrade.** The listbox is handed the answer as '.value', and lit-ssr serializes no property binding, so a served 'value="09:30"' shipped ninety-six rows with nothing on any of them saying which one it was: the mark arrived when the listbox upgraded and ran 'place'. So each option is given 'selected' as well, which is an attribute binding and does serve, and which the listbox then agrees with rather than fights, 'place' writing the same answer from the same value. 'selected' is the declaration a consumer writes on 'Option' anywhere else in the library, and Date Picker expresses its own choice as markup for the same reason: a picker whose answer is invisible until a script runs is a picker whose answer is not served at all. Both readings do it, the list and the wheels, a wheel being a listbox like the list is. */
9918
+ /** **A list rather than three wheels**, and the reason is what a list already is. 'Listbox' brings the keyboard, the typeahead, the scroll into view and the announcement of a set of options, and a time at a step is a set of options. Three little wheels for hours, minutes and a meridiem are three controls to build, three to test, and a tab stop each for something a reader answers once. **A step is what makes it a list at all.** Fifteen minutes is ninety-six rows, which a reader scrolls or types into; one minute is one thousand four hundred and forty, which is a listbox in name only. So the list is for the times a product actually offers, and arbitrary times are the field's job in Input Time, the same division Date Input draws between typing a date and using the calendar. **The value is 'HH:mm' on a twenty-four hour clock, always.** That is what a form submits and what 'min' and 'max' compare against, and it sorts as a string, which is the whole reason the shape is that one. What each row *says* is the reader's own convention, from 'Intl'. **The chosen row is marked in the markup, not worked out on upgrade.** The listbox is handed the answer as '.value', and lit-ssr serializes no property binding, so a served 'value="09:30"' shipped ninety-six rows with nothing on any of them saying which one it was: the mark arrived when the listbox upgraded and ran 'place'. So each option is given 'selected' as well, which is an attribute binding and does serve, and which the listbox then agrees with rather than fights, 'place' writing the same answer from the same value. 'selected' is the declaration a consumer writes on 'Option' anywhere else in the library, and Date Picker expresses its own choice as markup for the same reason: a picker whose answer is invisible until a script runs is a picker whose answer is not served at all. Both readings do it, the list and the wheels, a wheel being a listbox like the list is. */
9934
9919
  "helix-headless-time-picker": DefineCustomElement<
9935
9920
  HelixHeadlessTimePicker,
9936
9921
  HelixHeadlessTimePickerVueProps,
@@ -9978,7 +9963,7 @@ export interface WcToolkitVueGlobalComponents {
9978
9963
  HelixHeadlessToolbarVueProps,
9979
9964
  HelixHeadlessToolbarVueEvents
9980
9965
  >;
9981
- /** The trigger is slotted and stays the consumer's own element. The bubble is rendered here, in the top layer through the popover API, so it clears any ancestor with 'overflow: hidden' without a 'z-index' anywhere. Position comes from 'FloatingController', which flips to another side when the preferred one does not fit. **Two forms, and they are not equivalent for a screen reader.** Wrapping is the convenience form and is right where the bubble decorates a control that already says what it is: nothing here can describe a slotted trigger, an IDREF being unable to cross a shadow boundary. 'for' is the form that works. The tooltip sits *beside* the trigger in the consumer's own tree and names it by id, so an IDREF between them is legal in the ordinary way: '''html <helix-button id="save" aria-describedby="save-tip">Save</helix-button> <helix-tooltip id="save-tip" for="save" content="Save your work"></helix-tooltip> ''' The reference points at *this host*, not at the bubble in its shadow root: the description is computed from the flat tree, which descends into shadow content on its own. **The consumer writes that 'aria-describedby', and nothing here writes it for them.** Setting it at runtime is a hydration mismatch React will not patch up. 'for' audits itself on first open and warns once where it is missing. It shows on hover and on focus, and hides on leave, on blur, on Escape, and once the trigger has been activated: the hint is spent when the control has been used. */
9966
+ /** The trigger is slotted and stays the consumer's own element. The bubble is rendered here, in the top layer through the popover API, so it clears any ancestor with 'overflow: hidden' without a 'z-index' anywhere. Position comes from 'FloatingController', which flips to another side when the preferred one does not fit. **Two forms, and they are not equivalent for a screen reader.** Wrapping is the convenience form and is right where the bubble decorates a control that already says what it is: nothing here can describe a slotted trigger, an IDREF being unable to cross a shadow boundary. 'for' is the form that works. The tooltip sits *beside* the trigger in the consumer's own tree and names it by id, so an IDREF between them is legal in the ordinary way: '''html <helix-headless-button id="save" aria-describedby="save-tip">Save</helix-headless-button> <helix-headless-tooltip id="save-tip" for="save" content="Save your work"></helix-headless-tooltip> ''' The reference points at *this host*, not at the bubble in its shadow root: the description is computed from the flat tree, which descends into shadow content on its own. **The consumer writes that 'aria-describedby', and nothing here writes it for them.** Setting it at runtime is a hydration mismatch React will not patch up. 'for' audits itself on first open and warns once where it is missing. It shows on hover and on focus, and hides on leave, on blur, on Escape, and once the trigger has been activated: the hint is spent when the control has been used. */
9982
9967
  "helix-headless-tooltip": DefineCustomElement<
9983
9968
  HelixHeadlessTooltip,
9984
9969
  HelixHeadlessTooltipVueProps,
@@ -9990,7 +9975,7 @@ export interface WcToolkitVueGlobalComponents {
9990
9975
  HelixHeadlessTourVueProps,
9991
9976
  HelixHeadlessTourVueEvents
9992
9977
  >;
9993
- /** A stop names a target with 'for' and holds whatever the consumer puts in it. It owns no content of its own, which is the whole shape of this family: the tour abstracts the three things that are genuinely hard, and the words are the consumer's. What it does own: - **Where the panel goes.** Anchored to the target through the same floating pass every other overlay here uses. - **That it is on top.** A popover, so it is in the top layer. A tour points at things inside dialogs, inside scrollers, inside anything with a stacking context, and a panel in the ordinary flow loses to all three. - **When it shows.** Which is 'current', and which the root decides. What it does not own is the heading, the paragraph, the picture and the layout. Slot a 'helix-card', or a heading and a line of prose, or anything else. Fixed 'title' and 'body' parts would be a component deciding what a tour is allowed to say. **The buttons are slot fallback, so the common case costs nothing and the uncommon one is possible.** Write nothing and get Back, Next and Skip already wired. Slot 'actions' and they are yours, driven by 'next()', 'back()' and 'skip()' on the root, which are public for exactly that. **'for' is an id, the same as 'Tooltip''s.** The target is elsewhere on the page, and an id is the one reference a consumer can write in markup without holding an element. Resolved against the root node, so a stop inside a shadow tree points at a target in that tree. */
9978
+ /** A stop names a target with 'for' and holds whatever the consumer puts in it. It owns no content of its own, which is the whole shape of this family: the tour abstracts the three things that are genuinely hard, and the words are the consumer's. What it does own: - **Where the panel goes.** Anchored to the target through the same floating pass every other overlay here uses. - **That it is on top.** A popover, so it is in the top layer. A tour points at things inside dialogs, inside scrollers, inside anything with a stacking context, and a panel in the ordinary flow loses to all three. - **When it shows.** Which is 'current', and which the root decides. What it does not own is the heading, the paragraph, the picture and the layout. Slot a 'Card', or a heading and a line of prose, or anything else. Fixed 'title' and 'body' parts would be a component deciding what a tour is allowed to say. **The buttons are slot fallback, so the common case costs nothing and the uncommon one is possible.** Write nothing and get Back, Next and Skip already wired. Slot 'actions' and they are yours, driven by 'next()', 'back()' and 'skip()' on the root, which are public for exactly that. **'for' is an id, the same as 'Tooltip''s.** The target is elsewhere on the page, and an id is the one reference a consumer can write in markup without holding an element. Resolved against the root node, so a stop inside a shadow tree points at a target in that tree. */
9994
9979
  "helix-headless-tour-stop": DefineCustomElement<
9995
9980
  HelixHeadlessTourStop,
9996
9981
  HelixHeadlessTourStopVueProps,