@fusion.dev/helix-headless 0.53.0 → 0.53.2

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 (77) hide show
  1. package/custom-elements.json +141 -141
  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 +14 -14
  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/root/checkbox-root.js +1 -1
  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 +25 -5
  19. package/dist/combobox/root/combobox-root.js +6 -4
  20. package/dist/command/root/command-root.d.ts +6 -7
  21. package/dist/data-table/root/data-table-root.d.ts +61 -38
  22. package/dist/data-table/root/data-table-root.js +8 -3
  23. package/dist/data-table/root/order.d.ts +3 -3
  24. package/dist/date-input/root/date-input-root.d.ts +12 -11
  25. package/dist/dialog/root/dialog-root.d.ts +4 -4
  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 +6 -6
  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/option/root/option-root.d.ts +3 -3
  41. package/dist/pagination/root/pagination-root.d.ts +2 -2
  42. package/dist/pin-input/root/pin-input-root.d.ts +4 -4
  43. package/dist/popover/root/popover-root.d.ts +7 -6
  44. package/dist/radio/root/radio-root.d.ts +12 -2
  45. package/dist/radio/root/radio-root.js +5 -1
  46. package/dist/select/root/select-root.d.ts +24 -0
  47. package/dist/select/root/select-root.js +4 -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/switch/root/switch-root.js +1 -1
  53. package/dist/table/column/table-column.d.ts +28 -28
  54. package/dist/table/root/table-root.d.ts +14 -17
  55. package/dist/table/row/table-row.d.ts +4 -4
  56. package/dist/tabs/panel/tab-panel.d.ts +2 -2
  57. package/dist/tabs/root/tabs-root.js +11 -4
  58. package/dist/tabs/tab/tab.d.ts +11 -1
  59. package/dist/tabs/tab/tab.js +5 -1
  60. package/dist/time-input/root/time-input-root.d.ts +13 -13
  61. package/dist/time-picker/root/time-picker-root.d.ts +8 -8
  62. package/dist/toast/root/toast-root.d.ts +2 -2
  63. package/dist/toggle/root/toggle-root.d.ts +16 -6
  64. package/dist/toggle/root/toggle-root.js +5 -1
  65. package/dist/tooltip/root/tooltip-root.d.ts +2 -2
  66. package/dist/tour/stop/tour-stop.d.ts +3 -3
  67. package/dist/tree/item/tree-item.d.ts +2 -2
  68. package/dist/tree/item/tree-item.js +4 -3
  69. package/dist/tree/root/tree-root.d.ts +8 -7
  70. package/dist/tree/root/tree-root.js +9 -5
  71. package/dist/video-playlist/menu/video-playlist-menu.d.ts +7 -1
  72. package/dist/video-playlist/menu/video-playlist-menu.js +4 -2
  73. package/dist/video-playlist/root/video-playlist-root.d.ts +5 -5
  74. package/dist/video-playlist/root/video-playlist-root.js +2 -3
  75. package/package.json +5 -5
  76. package/types/jsx.d.ts +754 -780
  77. package/types/vue.d.ts +172 -185
@@ -6,8 +6,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
6
6
  * @description
7
7
  * **The component is the truncation.** Given a page and a total it works out
8
8
  * which numbers to show and where the runs break, so this is data-driven rather
9
- * than composed: `<helix-pagination page="4" pages="12">` rather than twelve
10
- * slotted children a consumer keeps in step with their own query.
9
+ * than composed: `<helix-headless-pagination page="4" pages="12">` rather than
10
+ * twelve slotted children a consumer keeps in step with their own query.
11
11
  *
12
12
  * **The width does not change as you page.** The run around the current page is
13
13
  * `siblings` either side, and grows to absorb a gap slot at a boundary, so the
@@ -110,10 +110,10 @@ export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
110
110
  * marked letters wants `text`, which judges nothing.
111
111
  *
112
112
  * **Not reflected**: nothing selects on it, so reflecting only writes
113
- * `type="numeric"` onto every `<helix-pin-input>` ever rendered, an attribute
114
- * no consumer's markup had. The area rules carry the sentence "reflect only
115
- * what CSS selects on". The real inputs take it as a binding, which is what
116
- * makes the keyboard follow.
113
+ * `type="numeric"` onto every `<helix-headless-pin-input>` ever rendered, an
114
+ * attribute no consumer's markup had. The area rules carry the sentence
115
+ * "reflect only what CSS selects on". The real inputs take it as a binding,
116
+ * which is what makes the keyboard follow.
117
117
  */
118
118
  type: PinType;
119
119
  /** Focus is delegated, so the host is never the focus target. */
@@ -64,12 +64,13 @@ export declare class HelixHeadlessPopover extends HelixHeadlessPopover_base {
64
64
  * The invoker that last opened the panel, when a command did.
65
65
  *
66
66
  * Kept because the `source` a command hands the handlers is needed twice
67
- * over. It is the anchor: the styled host is a boxless `display: contents`
68
- * element, so a popover opened by a command outside it would otherwise open
69
- * against the window origin. And the outside-press dismissal has to know the
70
- * invoker is part of the control, the press firing on `pointerdown` and the
71
- * command arriving on the `click` after it, or a `--toggle` button outside
72
- * the host closes the panel and immediately reopens it, for ever.
67
+ * over. It is the anchor: the host is not a box to position against, a sheet
68
+ * being free to give it none, so a popover opened by a command outside it
69
+ * would otherwise open against the window origin. And the outside-press
70
+ * dismissal has to know the invoker is part of the control, the press firing
71
+ * on `pointerdown` and the command arriving on the `click` after it, or a
72
+ * `--toggle` button outside the host closes the panel and immediately reopens
73
+ * it, for ever.
73
74
  */
74
75
  private invoker;
75
76
  protected readonly commands: CommandController;
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessRadio_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
4
4
  /**
5
5
  * @summary One choice in a radio group.
@@ -54,7 +54,7 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
54
54
  * **The attribute, read when it is asked for, and never a snapshot taken in
55
55
  * the constructor.** A field initializer runs there, and an element the HTML
56
56
  * parser created has none of its attributes yet at that moment: measured on
57
- * this element, on `Option` and on `Toggle`, `<helix-radio value="a"
57
+ * this element, on `Option` and on `Toggle`, `<helix-headless-radio value="a"
58
58
  * selected>` reported `defaultSelected` as `false` both from parsed markup
59
59
  * and from `createElement` followed by `setAttribute`, which is every way a
60
60
  * consumer writes one. The snapshot could only ever be true for an element
@@ -89,6 +89,16 @@ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
89
89
  * same reason.
90
90
  */
91
91
  focusable: boolean;
92
+ /**
93
+ * Asks for the render that follows a hydration, so the stop stops being every
94
+ * choice's.
95
+ *
96
+ * `tabindex` reads `childrenKnown` and a hydrating render is one where that is
97
+ * false, which is what keeps the hydrating render the server's. Nothing else
98
+ * would ask: the group writes an already-false `focusable` onto every choice
99
+ * but one, which changes nothing and so re-renders nothing.
100
+ */
101
+ protected firstUpdated(changed: PropertyValues): void;
92
102
  protected render(): TemplateResult;
93
103
  }
94
104
  declare global {
@@ -18,6 +18,10 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
18
18
  set defaultSelected(next) {
19
19
  this.toggleAttribute('selected', next);
20
20
  }
21
+ firstUpdated(changed) {
22
+ super.firstUpdated(changed);
23
+ this.finishHydration();
24
+ }
21
25
  render() {
22
26
  return html `<button
23
27
  part="item"
@@ -25,7 +29,7 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
25
29
  role="radio"
26
30
  aria-checked=${this.selected ? 'true' : 'false'}
27
31
  ?disabled=${this.disabled}
28
- tabindex=${this.selected || this.focusable ? '0' : '-1'}
32
+ tabindex=${this.selected || this.focusable || !this.childrenKnown ? '0' : '-1'}
29
33
  @click=${() => this.select()}
30
34
  >
31
35
  <span part="box"><span part="mark" aria-hidden="true"></span></span>
@@ -134,6 +134,30 @@ export declare class HelixHeadlessSelect extends HelixHeadlessSelect_base {
134
134
  * `slotchange`, which a declarative shadow root fires before anything listens,
135
135
  * so a hydrated select kept "Choose" for good. Nothing on a server or while
136
136
  * hydrating what one sent, which drew the placeholder too.
137
+ *
138
+ * **And the placeholder is a statement, so a render that cannot read the
139
+ * words does not make it.** "Choose" means nothing is chosen. `value` is an
140
+ * attribute and a server has it, the words are the children's and a server
141
+ * has none, so a `<helix-select default-value="two">` served "Choose" over an
142
+ * answer the consumer had already given: false to a reader, and false to a
143
+ * crawler, on every select in the library's own examples. Where a value is
144
+ * declared and the word for it cannot be read, the trigger says nothing and
145
+ * keeps its box, which is the answer this library reaches for everywhere it
146
+ * cannot tell empty from unknown. `firstUpdated` asks for the render that
147
+ * fills it in.
148
+ *
149
+ * The placeholder still stands where there is genuinely no value, which is
150
+ * what it is for and the one case a server can be sure of.
151
+ *
152
+ * **`nothing` and never `''`, which is the difference between a word that
153
+ * arrives and one that never does.** Lit's hydration primes a child part with
154
+ * whatever the render computed, and `''` is a primitive, so `_commitText`
155
+ * takes the branch that assumes the server left a text node to overwrite.
156
+ * There is none, the write lands on the closing part marker's comment data,
157
+ * and the trigger stays empty for the life of the page: measured by
158
+ * `check:spec:dsd`, which caught all nine of these and showed a blank select
159
+ * beside a client's "Option Two". `nothing` primes the sentinel instead, so
160
+ * the commit creates the text node it needs.
137
161
  */
138
162
  private get display();
139
163
  /** Closes the list and puts focus back where it came from. */
@@ -74,7 +74,10 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
74
74
  const words = optionsAmong(this.knownChildren)
75
75
  .filter((option) => chosen.has(option.value))
76
76
  .map((option) => option.text);
77
- return words.length > 0 ? words.join(', ') : this.placeholder;
77
+ if (words.length > 0) {
78
+ return words.join(', ');
79
+ }
80
+ return chosen.size > 0 && !this.childrenKnown ? nothing : this.placeholder;
78
81
  }
79
82
  close() {
80
83
  if (!this.open) {
@@ -15,11 +15,10 @@ declare const HelixHeadlessSpeedDial_base: (new (...args: any[]) => import("@fus
15
15
  * mean defining what a dial with a submenu in it does.
16
16
  *
17
17
  * **The trigger is a control the consumer slots**, and the floating action
18
- * button is the usual one: `helix-icon-button` with `shape="circle"` and
19
- * `raised`. There is no `helix-fab`, because it would re-declare `emphasis`,
20
- * `tone`, `label` and a size around a control that already has all four. A
21
- * round raised button is a shape, and where it sits is `data-dock` in the base
22
- * layer.
18
+ * button is the usual one: `IconButton` with `shape="circle"` and `raised`.
19
+ * There is no `helix-fab`, because it would re-declare `emphasis`, `tone`,
20
+ * `label` and a size around a control that already has all four. A round raised
21
+ * button is a shape, and where it sits is `data-dock` in the base layer.
23
22
  *
24
23
  * **Nothing is reserved from the keyboard.** A menu that drills has to keep the
25
24
  * horizontal pair for going in and coming back; a dial goes nowhere, so all four
@@ -105,10 +104,10 @@ export declare class HelixHeadlessSpeedDial extends HelixHeadlessSpeedDial_base
105
104
  *
106
105
  * **This is the case the tier rule blocks and a render method unblocks.** A
107
106
  * bare `<button>` is what the headless tier can write: it must not reach for
108
- * `helix-button`, which lives a tier above and would make `headless` depend
109
- * on `styled`. So the base draws the plain control and a tier that has buttons
110
- * of its own overrides this to use one. Written inline, the only way
111
- * to change it would be to reimplement the template, panel and all.
107
+ * `Button`, which lives a tier above and would make `headless` depend on
108
+ * `styled`. So the base draws the plain control and a tier that has buttons
109
+ * of its own overrides this to use one. Written inline, the only way to
110
+ * change it would be to reimplement the template, panel and all.
112
111
  */
113
112
  protected renderTrigger(): TemplateResult;
114
113
  protected render(): TemplateResult;
@@ -35,9 +35,9 @@ export declare class HelixHeadlessStat extends HelixElement {
35
35
  * The row directions set them side by side, for a figure in a line of text or
36
36
  * a narrow strip where a stacked pair would be two lines of almost nothing.
37
37
  *
38
- * A property rather than a `helix-flex` around it, because the unit has to
39
- * stay on the value's baseline whichever way the pair goes, and only this
40
- * element knows which of its children the unit belongs to.
38
+ * A property rather than a `Flex` around it, because the unit has to stay on
39
+ * the value's baseline whichever way the pair goes, and only this element
40
+ * knows which of its children the unit belongs to.
41
41
  *
42
42
  * **Optional rather than defaulted to `column`, which is not a style
43
43
  * preference.** A reflecting property with a default writes its attribute onto
@@ -22,7 +22,7 @@ declare const HelixHeadlessSteps_base: (new (...args: any[]) => import("@fusion.
22
22
  * @aliases Stepper, Wizard, Progress steps
23
23
  * @documentation https://fusion.dev/helix/components/steps
24
24
  *
25
- * @slot - The steps, which are `helix-step` elements.
25
+ * @slot - The steps.
26
26
  *
27
27
  * @event {HelixActivateEvent} helix-activate - Fired once the current one has moved, so the element already holds it.
28
28
  * @event {HelixBeforeActivateEvent} helix-before-activate - Fired before the active step changes. Cancelable: refusing it takes the decision and nothing moves.
@@ -6,9 +6,9 @@ import '../../button/index.js';
6
6
  *
7
7
  * @description
8
8
  * **The name is a button, and only the name.** The marker is `aria-hidden`
9
- * decoration, so wrapping it would add hit area and no meaning. It is
10
- * `helix-button` rather than a `<button>` this element resets: the hover wash,
11
- * the focus ring and the disabled treatment are decisions the button carries.
9
+ * decoration, so wrapping it would add hit area and no meaning. It is `Button`
10
+ * rather than a `<button>` this element resets: the hover wash, the focus ring
11
+ * and the disabled treatment are decisions the button carries.
12
12
  *
13
13
  * **It says nothing about where a reader may go.** Every step is pressable and
14
14
  * announces itself with `helix-select`; refusing the ones ahead is `disabled`,
@@ -27,7 +27,7 @@ import '../../button/index.js';
27
27
  * @documentation https://fusion.dev/helix/components/steps
28
28
  *
29
29
  * @slot - The step's name.
30
- * @slot content - What the stage holds. Always rendered here, a tier with no stylesheet having nothing to fold it with; the styled tier opens it on the current step down a column, and a row has no space under a step to open it into.
30
+ * @slot content - What the stage holds. Always rendered here, a tier with no stylesheet having nothing to fold it with, so whether it is folded away is the sheet's answer and not this tier's.
31
31
  * @slot description - A line under the name, for what the stage is for.
32
32
  * @slot marker - Replaces the number, or the check a complete step shows.
33
33
  *
@@ -36,7 +36,7 @@ import '../../button/index.js';
36
36
  * @csspart body - The name and its description.
37
37
  * @csspart content - What the stage holds, while it is open.
38
38
  * @csspart description - The line under it.
39
- * @csspart label - The step's name, which is a `helix-button`.
39
+ * @csspart label - The step's name, which is a control.
40
40
  * @csspart label-button - The inner control.
41
41
  * @csspart lead - The half line arriving from the step before.
42
42
  * @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
@@ -47,7 +47,7 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
47
47
  part="control"
48
48
  type="checkbox"
49
49
  role="switch"
50
- .checked=${this.checked}
50
+ .checked=${this.checked || nothing}
51
51
  ?disabled=${this.isDisabled}
52
52
  ?required=${this.required}
53
53
  aria-describedby=${this.describedBy ?? nothing}
@@ -25,9 +25,9 @@ export declare const at: (row: Readonly<Record<string, unknown>>, path: string)
25
25
  *
26
26
  * **`align` is a string anybody can write**, the union on the property being a
27
27
  * compile-time claim and nothing else, and both tables put the value straight
28
- * into CSS: `helix-table` into a rule in each row's shadow root, `helix-data-table`
29
- * into the cell it draws. One guard, here with the property, rather than one in
30
- * each table and only one of them written.
28
+ * into CSS: `Table` into a rule in each row's shadow root, `DataTable` into the
29
+ * cell it draws. One guard, here with the property, rather than one in each
30
+ * table and only one of them written.
31
31
  */
32
32
  export declare const edgeOf: (align: string | undefined) => string | undefined;
33
33
  /**
@@ -38,23 +38,23 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
38
38
  * the table has another track; remove one and it does not. That is what ties
39
39
  * the two together, and a table-level track list on its own does not: a list
40
40
  * that is accidentally the headings is invalid CSS a grid ignores in silence,
41
- * drawing the whole table as one column. `helix-table`'s `columns` is dealt out
42
- * a track at a time against the columns declared under it, so a heading among
43
- * the widths costs its own column a width and no more, and a list longer or
44
- * shorter than the columns is trimmed or shared rather than being a second
45
- * count of them. A column's own `width` wins over the track in its place.
41
+ * drawing the whole table as one column. `Table`'s `columns` is dealt out a
42
+ * track at a time against the columns declared under it, so a heading among the
43
+ * widths costs its own column a width and no more, and a list longer or shorter
44
+ * than the columns is trimmed or shared rather than being a second count of
45
+ * them. A column's own `width` wins over the track in its place.
46
46
  *
47
47
  * **It is also where every per-column fact goes**, which is the reason
48
- * `helix-data-table` needs no column config object. `field` names the key the
49
- * cell reads, `sortable` says a reader may reorder by it, `align` says which
50
- * edge the values line up against, and `cell` takes a function for anything the
48
+ * `DataTable` needs no column config object. `field` names the key the cell
49
+ * reads, `sortable` says a reader may reorder by it, `align` says which edge
50
+ * the values line up against, and `cell` takes a function for anything the
51
51
  * field alone cannot express. The schema is markup and the data is a property:
52
52
  * a schema is small, declarative, and something a reader should be able to see
53
53
  * in the HTML, and data is large and windowed.
54
54
  *
55
55
  * **The same element serves both tables**, the markup one and the data one. It
56
- * is identified by a flag rather than by `instanceof`, so a `helix-table-column`
57
- * works inside either without the two roots sharing anything else.
56
+ * is identified by a flag rather than by `instanceof`, so a `TableColumn` works
57
+ * inside either without the two roots sharing anything else.
58
58
  *
59
59
  * **It generates no box of its own**, the same as a row: the heading is a grid
60
60
  * item of the table, so it lines up with the cells under it rather than sitting
@@ -64,10 +64,10 @@ export declare const edgeOf: (align: string | undefined) => string | undefined;
64
64
  * both, so the columns after it keep their own widths and every row keeps its
65
65
  * cells under their headings. `hidden="until-found"` keeps its track, the
66
66
  * heading being left drawn, as every Helix element leaves one with that value.
67
- * `helix-data-table` draws the cells, so it leaves out the ones under a hidden
68
- * column. A `helix-table`'s cells are markup the consumer wrote, so hide them
69
- * with the column, as removing a column means removing its cells: a row with a
70
- * cell more than the table has tracks wraps into the next.
67
+ * `DataTable` draws the cells, so it leaves out the ones under a hidden column.
68
+ * A `Table`'s cells are markup the consumer wrote, so hide them with the
69
+ * column, as removing a column means removing its cells: a row with a cell more
70
+ * than the table has tracks wraps into the next.
71
71
  *
72
72
  * **A heading that does something holds a control that does it.** The host is
73
73
  * the column header, and a header is not focusable, so a sortable heading is a
@@ -99,15 +99,15 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
99
99
  /**
100
100
  * Which edge the values line up against.
101
101
  *
102
- * `end` is what a column of numbers wants, so digits of the same magnitude sit
103
- * above each other. Left unset the cell inherits the table's own alignment,
104
- * which is `start` for text in either writing direction. `helix-data-table`
105
- * aligns the cells it draws. A `helix-table`'s cells are markup the consumer
106
- * wrote, so the table writes nothing onto them: it publishes the edge to each
107
- * cell under this column as `--table-cell-align`, which `@fusion.dev/helix`
108
- * reads. The heading is this element's own, and `@fusion.dev/helix` sets it to
109
- * the same edge in either table. `end` is the inline end, so in a
110
- * right-to-left table it is the left.
102
+ * `end` is what a column of numbers wants, so digits of the same magnitude
103
+ * sit above each other. Left unset the cell inherits the table's own
104
+ * alignment, which is `start` for text in either writing direction.
105
+ * `DataTable` aligns the cells it draws. A `Table`'s cells are markup the
106
+ * consumer wrote, so the table writes nothing onto them: it publishes the
107
+ * edge to each cell under this column as `--table-cell-align`, which
108
+ * `@fusion.dev/helix` reads. The heading is this element's own, and
109
+ * `@fusion.dev/helix` sets it to the same edge in either table. `end` is the
110
+ * inline end, so in a right-to-left table it is the left.
111
111
  *
112
112
  * **Reflected, because the heading is drawn by a stylesheet and has no other
113
113
  * way to learn it.** Set as a property, which is how React sets it, an
@@ -181,8 +181,8 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
181
181
  * The track this column takes, as CSS.
182
182
  *
183
183
  * A single track value, so anything valid in `grid-template-columns` works:
184
- * `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track
185
- * in its place in a `helix-table`'s `columns`, where that table sets one, and
184
+ * `16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in
185
+ * its place in a `Table`'s `columns`, where that table sets one, and
186
186
  * otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
187
187
  * Set here, it wins over that list, which is what lets a reader resize a
188
188
  * column in a table that set one.
@@ -34,21 +34,20 @@ declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.
34
34
  * @csspart loading - Shown while the rows are still on their way.
35
35
  * @csspart table - The grid.
36
36
  *
37
- * @cssproperty --table-template - 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.
37
+ * @cssproperty --table-template - 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.
38
38
  */
39
39
  export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
40
40
  /**
41
41
  * The column widths as one track list, written once on the table.
42
42
  *
43
- * With `helix-table-column` children, each track sizes the column in its
44
- * place, a hidden column counted, so hiding one takes its track with it and
45
- * the rest keep theirs. The columns decide how many tracks there are and this
46
- * list only how wide: a track past the last column is dropped, and a column
47
- * past the last track shares what is left. With no columns declared it is
48
- * the whole track list. Tracks count as the grid counts them, so
49
- * `minmax(0, 1fr)` is one and `repeat(2, 8rem)` is two, and one the grid
50
- * would refuse leaves its column at the default rather than taking the table
51
- * down to one column.
43
+ * With `TableColumn` children, each track sizes the column in its place, a
44
+ * hidden column counted, so hiding one takes its track with it and the rest
45
+ * keep theirs. The columns decide how many tracks there are and this list
46
+ * only how wide: a track past the last column is dropped, and a column past
47
+ * the last track shares what is left. With no columns declared it is the
48
+ * whole track list. Tracks count as the grid counts them, so `minmax(0, 1fr)`
49
+ * is one and `repeat(2, 8rem)` is two, and one the grid would refuse leaves
50
+ * its column at the default rather than taking the table down to one column.
52
51
  *
53
52
  * **A column's own `width` wins over its track here.** The width is written
54
53
  * on the column it sizes, which is the more particular statement, and it is
@@ -62,13 +61,11 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
62
61
  * whole answer: a table given one lays its grid out in the first paint, and a
63
62
  * table sized only by its columns is one track wide until it upgrades.
64
63
  *
65
- * **`helix-data-table` has none of this, and should not.** Its columns are
66
- * its schema rather than an option, so there is always a column to write a
67
- * `width` on and a list here would be a second way to say what that says.
68
- * This table's cells are markup, and a table written as rows of cells with no
69
- * `helix-table-column` in it has nowhere else to be sized from. Both families
70
- * take the same CSS hook, `--table-columns` and `--data-table-columns`, which
71
- * wins over whichever list the element worked out.
64
+ * **Data Table has none of this, and should not.** Its columns are its schema
65
+ * rather than an option, so there is always a column to write a `width` on
66
+ * and a list here would be a second way to say what that says. This table's
67
+ * cells are markup, and a table written as rows of cells with no column
68
+ * declared in it has nowhere else to be sized from.
72
69
  */
73
70
  columns: string;
74
71
  /**
@@ -4,10 +4,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
4
4
  * @summary One row of a table.
5
5
  *
6
6
  * @description
7
- * `display: contents` in the styled tier, so the row's cells become items of
8
- * the table's own grid and every column lines up across every row. The row
9
- * still exists as an element, which is what a `<table>` gives away when its
10
- * cells are laid out by the table algorithm.
7
+ * The row renders its cells straight through and lays out none of them, so a
8
+ * sheet can take them into the table's own grid and every column lines up
9
+ * across every row. The row still exists as an element, which is what a
10
+ * `<table>` gives away when its cells are laid out by the table algorithm.
11
11
  *
12
12
  * @since 0.1.0
13
13
  * @status stable
@@ -52,8 +52,8 @@ export declare class HelixHeadlessTabPanel extends HelixElement {
52
52
  * a choice nobody made. `ElementInternals` holds it instead.
53
53
  *
54
54
  * The attribute still seeds the property, which is what
55
- * `<helix-tab-panel selected>` in a consumer's markup means. Only the write
56
- * back is gone.
55
+ * `<helix-headless-tab-panel selected>` in a consumer's markup means. Only
56
+ * the write back is gone.
57
57
  */
58
58
  protected willUpdate(changed: PropertyValues): void;
59
59
  protected render(): TemplateResult;
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessTabPanel } from '../panel/tab-panel.js';
@@ -47,12 +47,19 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
47
47
  const declared = this.active === '' ? tabs.find((tab) => tab.selected) : undefined;
48
48
  const value = (declared ?? this.resolveActive(tabs))?.value ?? '';
49
49
  for (const tab of tabs) {
50
- tab.selected = tab.value === value;
50
+ const selected = tab.value === value;
51
+ whenHydrated(tab, () => {
52
+ tab.selected = selected;
53
+ });
51
54
  }
52
55
  const names = new Map(tabs.map((tab) => [tab.value, (tab.textContent ?? '').trim()]));
53
56
  for (const panel of this.panels) {
54
- panel.selected = panel.value === value;
55
- panel.label = names.get(panel.value) ?? '';
57
+ const selected = panel.value === value;
58
+ const label = names.get(panel.value) ?? '';
59
+ whenHydrated(panel, () => {
60
+ panel.selected = selected;
61
+ panel.label = label;
62
+ });
56
63
  }
57
64
  }
58
65
  connectedCallback() {
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
4
4
  /**
5
5
  * @summary One tab in a tab list.
@@ -27,6 +27,16 @@ declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.de
27
27
  */
28
28
  export declare class HelixHeadlessTab extends HelixHeadlessTab_base {
29
29
  protected itemPart: string;
30
+ /**
31
+ * Asks for the render that follows a hydration, so the stop stops being every
32
+ * tab's.
33
+ *
34
+ * `tabindex` reads `childrenKnown` and a hydrating render is one where that is
35
+ * false, which is what keeps the hydrating render the server's. Nothing else
36
+ * would ask: the root writes an already-false `selected` onto an unchosen tab,
37
+ * which changes nothing and so re-renders nothing.
38
+ */
39
+ protected firstUpdated(changed: PropertyValues): void;
30
40
  protected render(): TemplateResult;
31
41
  }
32
42
  declare global {
@@ -11,6 +11,10 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
11
11
  super(...arguments);
12
12
  this.itemPart = 'tab';
13
13
  }
14
+ firstUpdated(changed) {
15
+ super.firstUpdated(changed);
16
+ this.finishHydration();
17
+ }
14
18
  render() {
15
19
  return html `<button
16
20
  part="tab"
@@ -18,7 +22,7 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinSelectableItem(HelixE
18
22
  type="button"
19
23
  aria-selected=${this.selected ? 'true' : 'false'}
20
24
  ?disabled=${this.disabled}
21
- tabindex=${this.selected ? '0' : '-1'}
25
+ tabindex=${this.selected || !this.childrenKnown ? '0' : '-1'}
22
26
  @click=${() => this.select()}
23
27
  >
24
28
  <slot></slot>
@@ -8,10 +8,10 @@ declare const HelixHeadlessTimeInput_base: (new (...args: any[]) => import("@fus
8
8
  * @summary A time, typed or picked from a list.
9
9
  *
10
10
  * @description
11
- * **The list is `helix-time-picker`, not a second one written here.** It is worth
11
+ * **The list is `TimePicker`, not a second one written here.** It is worth
12
12
  * having on its own, flat in a settings pane with nothing to open, and this
13
13
  * element is the field, the overlay and the form. Exactly the arrangement Input
14
- * Date has with `helix-date-picker` and Color Input with `helix-color-picker`.
14
+ * Date has with `DatePicker` and Color Input with `ColorPicker`.
15
15
  *
16
16
  * **Typed as well as picked, and that is the division the list depends on.** A
17
17
  * list at a step offers the times a product actually has, and the field is how a
@@ -120,8 +120,8 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
120
120
  *
121
121
  * Absent is one. `range` holds a start and an end, `multiple` holds any
122
122
  * number, and both are carried as one comma-separated value, which is what a
123
- * form submits. `helix-time-picker` carries the longer note on the interaction and on
124
- * why a wheel cannot do either.
123
+ * form submits. `TimePicker` carries the longer note on the interaction and
124
+ * on why a wheel cannot do either.
125
125
  */
126
126
  mode?: 'multiple' | 'range';
127
127
  /**
@@ -185,7 +185,7 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
185
185
  * `list` offers whole times, which is what a product with slots or opening
186
186
  * hours has. `wheels` splits them into an hour, a minute and a meridiem where
187
187
  * the locale uses one, which is the only way to reach `23:45` without
188
- * scrolling most of a day. `helix-time-picker` carries the longer note on the trade.
188
+ * scrolling most of a day. `TimePicker` carries the longer note on the trade.
189
189
  *
190
190
  * **Optional rather than defaulted, which is not a style preference.** A
191
191
  * reflecting property with a default writes its attribute onto every host the
@@ -218,14 +218,14 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
218
218
  * Slot fallback, so a consumer replaces it by slotting; and a method, so the
219
219
  * tier above replaces it by overriding.
220
220
  *
221
- * **A named import rather than `<helix-icon>`**, on three counts.
222
- * `helix-icon` indexes the whole icon map at runtime, `icons[this.name]`, and
223
- * no bundler can shake a runtime lookup, so every consumer of any component
224
- * that renders one ships all 50kB of path data; a named import ships one
225
- * path. The import is checked when the package compiles, where a `name`
226
- * string is checked only by a later name lookup. And `helix-icon` is not
227
- * registered on the headless tier at all, which registers `helix-headless-icon`,
228
- * so a headless consumer gets an inert unknown element and no mark whatsoever.
221
+ * **A named import rather than `<helix-headless-icon>`**, on three counts.
222
+ * `Icon` indexes the whole icon map at runtime, `icons[this.name]`, and no
223
+ * bundler can shake a runtime lookup, so every consumer of any component that
224
+ * renders one ships all 50kB of path data; a named import ships one path. The
225
+ * import is checked when the package compiles, where a `name` string is
226
+ * checked only by a later name lookup. And `Icon` is not registered on the
227
+ * headless tier at all, which registers `helix-headless-icon`, so a headless
228
+ * consumer gets an inert unknown element and no mark whatsoever.
229
229
  */
230
230
  protected renderTrigger(): TemplateResult;
231
231
  protected render(): TemplateResult;
@@ -25,8 +25,8 @@ declare const HelixHeadlessTimePicker_base: (new (...args: any[]) => import("@fu
25
25
  *
26
26
  * @description
27
27
  * **A list rather than three wheels**, and the reason is what a list already
28
- * is. `helix-listbox` brings the keyboard, the typeahead, the scroll into view
29
- * and the announcement of a set of options, and a time at a step is a set of
28
+ * is. `Listbox` brings the keyboard, the typeahead, the scroll into view and
29
+ * the announcement of a set of options, and a time at a step is a set of
30
30
  * options. Three little wheels for hours, minutes and a meridiem are three
31
31
  * controls to build, three to test, and a tab stop each for something a reader
32
32
  * answers once.
@@ -145,7 +145,7 @@ export declare class HelixHeadlessTimePicker extends HelixHeadlessTimePicker_bas
145
145
  *
146
146
  * Absent is one. `range` holds a start and an end with everything between
147
147
  * them shown as part of the answer, `multiple` holds any number, and both are
148
- * carried as one comma-separated value: the same shape `helix-date-picker` uses,
148
+ * carried as one comma-separated value: the same shape `DatePicker` uses,
149
149
  * because it is the same question asked of a different unit.
150
150
  *
151
151
  * **A range is two picks, and a third starts over.** That is the calendar's
@@ -335,11 +335,11 @@ export declare class HelixHeadlessTimePicker extends HelixHeadlessTimePicker_bas
335
335
  /**
336
336
  * Reveals once the wheels, or the list and its rows, have rendered themselves.
337
337
  *
338
- * `updated` is this element's own moment, and each wheel is a `helix-listbox`
339
- * that was created during this very render: its first update has been
340
- * scheduled and has not run, so it has no rows and no height and `reveal`
341
- * measures zero and gives up. Measured on a standalone picker, every column
342
- * sat at `scrollTop: 0` with the answer nine rows down, which reads as a wheel
338
+ * `updated` is this element's own moment, and each wheel is a `Listbox` that
339
+ * was created during this very render: its first update has been scheduled
340
+ * and has not run, so it has no rows and no height and `reveal` measures zero
341
+ * and gives up. Measured on a standalone picker, every column sat at
342
+ * `scrollTop: 0` with the answer nine rows down, which reads as a wheel
343
343
  * showing the wrong time rather than as one that failed to scroll.
344
344
  *
345
345
  * Whatever opens a panel calls `reveal` again afterwards, for the separate
@@ -34,7 +34,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
34
34
  * @aliases Toaster, Snackbar
35
35
  * @documentation https://fusion.dev/helix/components/toast
36
36
  *
37
- * @slot - The messages, as `helix-toast-item` elements.
37
+ * @slot - The messages.
38
38
  *
39
39
  * @event {HelixDismissEvent} helix-dismiss - A message asking to go, by its control or by its timer, dispatched by the message and heard here because the stack is what a consumer holds. Cancelable: refusing it takes the decision and the message stays.
40
40
  *
@@ -55,7 +55,7 @@ export declare class HelixHeadlessToast extends HelixElement {
55
55
  * **Optional, and bottom-end is the absence of it.** Reflecting *and*
56
56
  * defaulting is the pair that writes onto a host: every toast region anybody
57
57
  * rendered would gain a `placement="bottom-end"` nobody typed, which a React
58
- * consumer's server markup does not have. The styled sheet carries the resting
58
+ * consumer's server markup does not have. A sheet carries the resting
59
59
  * arrangement in its own `:host` rule and the selectors describe only the
60
60
  * departures, which is what `orientation` does.
61
61
  */