@fusion.dev/helix-headless 0.38.0 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24410,6 +24410,10 @@
24410
24410
  "description": "**The schema is markup and the data is a property.** Columns are declared as\n`helix-table-column` children, because a schema is small and something a\nreader should see in the HTML; rows are handed over as an array, because a\ntable that draws ten thousand elements cannot window them.\n\n```html\n<helix-data-table .rows=${rows} sort=\"name:asc\" page-size=\"20\">\n <helix-table-column field=\"name\" sortable>Name</helix-table-column>\n <helix-table-column field=\"size\" align=\"end\" sortable .cell=${bytes}>Size</helix-table-column>\n</helix-data-table>\n```\n\n`helix-table` takes rows as markup and is the right component for a table of\ntwelve things a person wrote out.\n\n**Sort and filter apply to the whole set, never the page.** Sorting the drawn\nwindow is correct on the first screen and wrong on every other one.\n\n**The cell values do not server-render.** The headings do, and the row\nelements do, but reading a cell needs the columns, and the columns are markup\nchildren Lit SSR does not hand this element. So a crawler sees a table of the\nright shape with nothing in it. That is the cost of the first paragraph: use\n`helix-table` where the served HTML has to carry the values.\n\n**`selectable` adds a column of checkboxes, keyed on `row-key`.** A row is\nselected by its identity rather than its position, so a selection survives a\nsort, a filter and a page. `selected` is the chosen keys, comma separated, the\nshape Listbox uses for a multiple choice, and like `sort` it is controlled\nwhen set and seeded by `default-selected`. The box in the heading selects every\nrow in the result, across pages, and shows a dash while only some are chosen.\nChoosing one of many, rather than several, is opening a row, and that is a\nlink or a button in a cell rather than a selection.\n\n**A reader can size and order the columns.** `resizable` on a column puts a\nseparator on its edge; `reorderable` on the table puts a grip on each heading\nthat has a `field`, moved by dragging or with the arrow keys. The order lands\nin `order` as fields, and the consumer's own markup is never rewritten: the\ntable assigns the headings to its header in that order instead.\n\n**`csv()` hands back the result as text**: every row the filter lets through,\nin the order on screen, in the columns on screen. Saving it is the page's\nbusiness, the same as any other file.",
24411
24411
  "name": "HelixHeadlessDataTable",
24412
24412
  "cssProperties": [
24413
+ {
24414
+ "description": "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.",
24415
+ "name": "--data-table-cell-align"
24416
+ },
24413
24417
  {
24414
24418
  "description": "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.",
24415
24419
  "name": "--data-table-template"
@@ -24473,7 +24477,7 @@
24473
24477
  "name": "checkbox-mark-indeterminate"
24474
24478
  },
24475
24479
  {
24476
- "description": "Shown when no rows match.",
24480
+ "description": "Shown when the result has nothing in it, whether it arrived empty or a filter emptied it. A result still on its way is `loading` instead, which wins over this.",
24477
24481
  "name": "empty"
24478
24482
  },
24479
24483
  {
@@ -25098,7 +25102,7 @@
25098
25102
  },
25099
25103
  "privacy": "protected",
25100
25104
  "readonly": true,
25101
- "description": "Emptiness is a fact about the data here, not about slotted children.",
25105
+ "description": "Emptiness is a fact about the data here, not about slotted children.\n\n**The page rather than the window**, which is the difference between the two\ncounts `view` carries and the reason this reads `available`. A windowed\ntable draws a slice, and a slice can be short of the rows that are there:\nasking whether *this* slice has rows says \"nothing matched\" about a result\nthat matched plenty.\n\nThe mixin's own answer counts children with no `slot`, which for this\nelement is the columns. Left in place, a table with columns and no data\nwould call itself full.",
25102
25106
  "inheritedFrom": {
25103
25107
  "name": "MixinCollection",
25104
25108
  "module": "src/mixins/mixin-collection/mixin-collection.ts"
@@ -25469,7 +25473,8 @@
25469
25473
  "text": "boolean"
25470
25474
  }
25471
25475
  }
25472
- ]
25476
+ ],
25477
+ "description": "One cell, carrying its column's edge as a fact rather than as a decision.\n\n**A fact published rather than a property chosen**, which is what\n`helix-table` does with the same attribute: what lining up *means*, a\n`justify-content` for a value that fits or a `text-align` for one that\nwraps, belongs to whoever draws the cell. Written here as an inline\n`text-align` it was this tier choosing, in the tier that ships no CSS, and a\nconsumer could not overrule it either, an inline declaration beating any\n`::part(cell)` rule they wrote.\n\nOnly the three edges reach it, `align` being a string anybody can write and\nthis being a style attribute: `edgeOf` is that guard, and `helix-table`\nholds the same value to the same three."
25473
25478
  },
25474
25479
  {
25475
25480
  "kind": "method",
@@ -26453,7 +26458,7 @@
26453
26458
  "helix": {
26454
26459
  "category": "data",
26455
26460
  "since": "0.1.0",
26456
- "status": "experimental",
26461
+ "status": "stable",
26457
26462
  "documentation": "https://fusion.dev/helix/components/data-table",
26458
26463
  "aliases": [
26459
26464
  "Grid",
@@ -30698,7 +30703,7 @@
30698
30703
  "text": "string"
30699
30704
  },
30700
30705
  "default": "''",
30701
- "description": "What the value is, for the common case of plain text.\n\nThe fallback of the `label` slot, so slotted content replaces it rather than\nappearing beside it.",
30706
+ "description": "What the value is called, for the common case of plain text.\n\nThe fallback of the `label` slot, so slotted content replaces it rather than\nappearing beside it. The value itself is the default slot: it is the half\nthat varies and is often more than text.",
30702
30707
  "attribute": "label"
30703
30708
  },
30704
30709
  {
@@ -31033,7 +31038,7 @@
31033
31038
  "text": "string"
31034
31039
  },
31035
31040
  "default": "''",
31036
- "description": "What the value is, for the common case of plain text.\n\nThe fallback of the `label` slot, so slotted content replaces it rather than\nappearing beside it.",
31041
+ "description": "What the value is called, for the common case of plain text.\n\nThe fallback of the `label` slot, so slotted content replaces it rather than\nappearing beside it. The value itself is the default slot: it is the half\nthat varies and is often more than text.",
31037
31042
  "fieldName": "label"
31038
31043
  }
31039
31044
  ],
@@ -31044,7 +31049,7 @@
31044
31049
  "summary": "One label and its value.",
31045
31050
  "helix": {
31046
31051
  "since": "0.1.0",
31047
- "status": "experimental",
31052
+ "status": "stable",
31048
31053
  "documentation": "https://fusion.dev/helix/components/description-list",
31049
31054
  "tier": "headless",
31050
31055
  "group": "BaseDescriptionList",
@@ -31459,7 +31464,7 @@
31459
31464
  "helix": {
31460
31465
  "category": "data",
31461
31466
  "since": "0.1.0",
31462
- "status": "experimental",
31467
+ "status": "stable",
31463
31468
  "documentation": "https://fusion.dev/helix/components/description-list",
31464
31469
  "aliases": [
31465
31470
  "Data list",
@@ -42749,7 +42754,7 @@
42749
42754
  "name": "cell"
42750
42755
  },
42751
42756
  {
42752
- "description": "Shown when the table has no readings in it.",
42757
+ "description": "Shown when the table has no readings in it, and not before the table can be read at all: on a server, and while hydrating what one sent, there is no document to resolve `for` in and nothing is known yet.",
42753
42758
  "name": "empty"
42754
42759
  },
42755
42760
  {
@@ -42859,7 +42864,7 @@
42859
42864
  "text": "string"
42860
42865
  },
42861
42866
  "default": "'No readings'",
42862
- "description": "Shown when the table has no readings in it.",
42867
+ "description": "Shown when the table has no readings in it.\n\nNever shown while the table cannot be read at all, which is a server render\nand the hydrating one after it: see `sourceKnown`.",
42863
42868
  "attribute": "empty-text"
42864
42869
  },
42865
42870
  {
@@ -42979,6 +42984,16 @@
42979
42984
  "description": "Every reading in the table, oldest first, as the table is written.\n\n**Not `readings`, which the mixin already has and which means a count.**\nTwo members of the same name meaning a number and an array is the kind of\ncollision that type-checks in one direction and reads wrong in both.",
42980
42985
  "readonly": true
42981
42986
  },
42987
+ {
42988
+ "kind": "field",
42989
+ "name": "sourceKnown",
42990
+ "type": {
42991
+ "text": "boolean"
42992
+ },
42993
+ "privacy": "private",
42994
+ "description": "Whether this render can tell a table with no readings from one it has not\nresolved yet.\n\n**Unknown is not empty, which is what an empty state must never say.**\n`for` names an id and resolving an id wants a document, so a server has\nnone and a hydrating render must not look either. Without this the server\ndrew \"No readings\" over a table holding ninety days of them, a crawler read\nthat sentence, and the strip flipped to a full one on hydration: the fault\n`MixinCollection` names for a slotted collection, arriving through the one\nchannel that mixin cannot see.\n\nThe same shape as `childrenKnown`, asked of a document rather than of a\ntree. An id that resolves to nothing in a browser is still known, and still\nempty: a `for` naming no table should say so rather than sit blank.",
42995
+ "readonly": true
42996
+ },
42982
42997
  {
42983
42998
  "kind": "field",
42984
42999
  "name": "rowCount",
@@ -43552,7 +43567,7 @@
43552
43567
  "text": "string"
43553
43568
  },
43554
43569
  "default": "'No readings'",
43555
- "description": "Shown when the table has no readings in it.",
43570
+ "description": "Shown when the table has no readings in it.\n\nNever shown while the table cannot be read at all, which is a server render\nand the hydrating one after it: see `sourceKnown`.",
43556
43571
  "fieldName": "emptyText"
43557
43572
  },
43558
43573
  {
@@ -43641,7 +43656,7 @@
43641
43656
  "helix": {
43642
43657
  "category": "charts",
43643
43658
  "since": "0.1.0",
43644
- "status": "experimental",
43659
+ "status": "stable",
43645
43660
  "documentation": "https://fusion.dev/helix/components/heatmap",
43646
43661
  "aliases": [
43647
43662
  "Contribution graph",
@@ -61510,9 +61525,8 @@
61510
61525
  "text": "boolean"
61511
61526
  },
61512
61527
  "default": "false",
61513
- "description": "Whether to leave the copy button off.\n\nNegative for the reason Code Block's is: a boolean attribute defaulting to\ntrue could never be turned off from markup.",
61514
- "attribute": "no-copy",
61515
- "reflects": true
61528
+ "description": "Whether to leave the copy button off.\n\nNegative for the reason Code Block's is: a boolean attribute defaulting to\ntrue could never be turned off from markup.\n\n**It does not reflect, where Code Block's does**, and the difference is what\nthe two sheets need. Code Block reserves the button's width with\n`:host(:not([no-copy]))`, so the attribute has to be there for a consumer\nwho set the property. This button is positioned out of the flow and takes no\nroom, so nothing selects on it, and reflection exists so that a selector can\nreach a value.",
61529
+ "attribute": "no-copy"
61516
61530
  },
61517
61531
  {
61518
61532
  "kind": "field",
@@ -61791,7 +61805,8 @@
61791
61805
  "text": "number"
61792
61806
  }
61793
61807
  }
61794
- ]
61808
+ ],
61809
+ "description": "One entry, named for its state where it holds one.\n\n**`row-active` and no attribute beside it.** Which row the keys are on is\ndrawn by a sheet and by nothing else: the accessibility tree hears it from\n`aria-activedescendant` on the tree, which points at this row's id, so an\nattribute would be a second spelling with no reader. The name is the one a\nconsumer can reach, nothing being able to follow `::part()` with an\nattribute selector."
61795
61810
  },
61796
61811
  {
61797
61812
  "kind": "method",
@@ -62181,7 +62196,7 @@
62181
62196
  "text": "boolean"
62182
62197
  },
62183
62198
  "default": "false",
62184
- "description": "Whether to leave the copy button off.\n\nNegative for the reason Code Block's is: a boolean attribute defaulting to\ntrue could never be turned off from markup.",
62199
+ "description": "Whether to leave the copy button off.\n\nNegative for the reason Code Block's is: a boolean attribute defaulting to\ntrue could never be turned off from markup.\n\n**It does not reflect, where Code Block's does**, and the difference is what\nthe two sheets need. Code Block reserves the button's width with\n`:host(:not([no-copy]))`, so the attribute has to be there for a consumer\nwho set the property. This button is positioned out of the flow and takes no\nroom, so nothing selects on it, and reflection exists so that a selector can\nreach a value.",
62185
62200
  "fieldName": "noCopy"
62186
62201
  },
62187
62202
  {
@@ -62202,7 +62217,7 @@
62202
62217
  "helix": {
62203
62218
  "category": "data",
62204
62219
  "since": "0.1.0",
62205
- "status": "experimental",
62220
+ "status": "stable",
62206
62221
  "documentation": "https://fusion.dev/helix/components/object-inspector",
62207
62222
  "aliases": [
62208
62223
  "JSON viewer",
@@ -85251,6 +85266,24 @@
85251
85266
  ],
85252
85267
  "description": "A dot path resolved against a row.\n\nWritten here rather than taken from a library, because the whole of what is\nneeded is \"walk the keys and stop at the first thing that is not an object\".\nReturns `undefined` for a path that does not resolve, which the table renders\nas an empty cell: a missing key is a hole in the data and drawing `undefined`\ninto a table tells a reader the software is broken rather than the row is."
85253
85268
  },
85269
+ {
85270
+ "kind": "function",
85271
+ "name": "edgeOf",
85272
+ "return": {
85273
+ "type": {
85274
+ "text": "string | undefined"
85275
+ }
85276
+ },
85277
+ "parameters": [
85278
+ {
85279
+ "name": "align",
85280
+ "type": {
85281
+ "text": "string | undefined"
85282
+ }
85283
+ }
85284
+ ],
85285
+ "description": "The edge a column names, where it names one of the three.\n\n**`align` is a string anybody can write**, the union on the property being a\ncompile-time claim and nothing else, and both tables put the value straight\ninto CSS: `helix-table` into a rule in each row's shadow root, `helix-data-table`\ninto the cell it draws. One guard, here with the property, rather than one in\neach table and only one of them written."
85286
+ },
85254
85287
  {
85255
85288
  "kind": "class",
85256
85289
  "description": "**The column is the source of both its heading and its track.** Add one and\nthe table has another track; remove one and it does not. Declaring the widths\nseparately, as a CSS track list on the table, leaves nothing tying the two\ntogether: a table with three headings and a two-track list renders without\ncomplaint, and a track list that is accidentally the headings is invalid CSS\nthe grid silently ignores, collapsing the whole table into one column.\n\n**It is also where every per-column fact goes**, which is the reason\n`helix-data-table` needs no column config object. `field` names the key the\ncell reads, `sortable` says a reader may reorder by it, `align` says which\nedge the values line up against, and `cell` takes a function for anything the\nfield alone cannot express. The schema is markup and the data is a property:\na schema is small, declarative, and something a reader should be able to see\nin the HTML, and data is large and windowed.\n\n**The same element serves both tables**, the markup one and the data one. It\nis identified by a flag rather than by `instanceof`, so a `helix-table-column`\nworks inside either without the two roots sharing anything else.\n\n**It generates no box of its own**, the same as a row: the heading is a grid\nitem of the table, so it lines up with the cells under it rather than sitting\nin a wrapper that has to be kept the same width.\n\n**`hidden` takes the column out of the grid**, its heading and its track\nboth, so the columns after it keep their own widths and every row keeps its\ncells under their headings. `hidden=\"until-found\"` keeps its track, the\nheading being left drawn, as every Helix element leaves one with that value.\n`helix-data-table` draws the cells, so it leaves out the ones under a hidden\ncolumn. A `helix-table`'s cells are markup the consumer wrote, so hide them\nwith the column, as removing a column means removing its cells: a row with a\ncell more than the table has tracks wraps into the next.\n\n**A heading that does something holds a control that does it.** The host is\nthe column header, and a header is not focusable, so a sortable heading is a\n`<button>` inside it: the pattern for a sortable table, and the only way a\nreader on a keyboard reaches the sort at all. A column a reader may resize\ncarries a `separator` on its end edge, moved by dragging it or with the arrow\nkeys, and a column in a table that lets a reader reorder its columns carries\na grip the table moves.",
@@ -85988,6 +86021,14 @@
85988
86021
  "module": "src/table/column/table-column.ts"
85989
86022
  }
85990
86023
  },
86024
+ {
86025
+ "kind": "js",
86026
+ "name": "edgeOf",
86027
+ "declaration": {
86028
+ "name": "edgeOf",
86029
+ "module": "src/table/column/table-column.ts"
86030
+ }
86031
+ },
85991
86032
  {
85992
86033
  "kind": "js",
85993
86034
  "name": "HelixHeadlessTableColumn",
@@ -53,7 +53,7 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
53
53
  * business, the same as any other file.
54
54
  *
55
55
  * @since 0.1.0
56
- * @status experimental
56
+ * @status stable
57
57
  * @category data
58
58
  * @aliases Grid, Result table, Data grid
59
59
  * @documentation https://fusion.dev/helix/components/data-table
@@ -82,7 +82,7 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
82
82
  * @csspart checkbox-mark - The tick, or the dash while some rows are selected.
83
83
  * @csspart checkbox-mark-checked - The mark while its box is checked, beside `checkbox-mark`.
84
84
  * @csspart checkbox-mark-indeterminate - The dash while only some rows are selected, beside `checkbox-mark`.
85
- * @csspart empty - Shown when no rows match.
85
+ * @csspart empty - Shown when the result has nothing in it, whether it arrived empty or a filter emptied it. A result still on its way is `loading` instead, which wins over this.
86
86
  * @csspart footer - The region below the grid.
87
87
  * @csspart head - The row the column headings sit in. `display: contents`, so it takes no space.
88
88
  * @csspart loading - Shown while the rows are still on their way.
@@ -106,6 +106,7 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
106
106
  * @csspart table - The grid.
107
107
  * @csspart toolbar - The region above the grid.
108
108
  *
109
+ * @cssproperty --data-table-cell-align - 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.
109
110
  * @cssproperty --data-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. `--data-table-columns` is the one to set.
110
111
  */
111
112
  export declare class HelixHeadlessDataTable extends HelixHeadlessDataTable_base {
@@ -451,7 +452,19 @@ export declare class HelixHeadlessDataTable extends HelixHeadlessDataTable_base
451
452
  * asking `view` for it would recurse through the clamp in `page`.
452
453
  */
453
454
  private get matched();
454
- /** Emptiness is a fact about the data here, not about slotted children. */
455
+ /**
456
+ * Emptiness is a fact about the data here, not about slotted children.
457
+ *
458
+ * **The page rather than the window**, which is the difference between the two
459
+ * counts `view` carries and the reason this reads `available`. A windowed
460
+ * table draws a slice, and a slice can be short of the rows that are there:
461
+ * asking whether *this* slice has rows says "nothing matched" about a result
462
+ * that matched plenty.
463
+ *
464
+ * The mixin's own answer counts children with no `slot`, which for this
465
+ * element is the columns. Left in place, a table with columns and no data
466
+ * would call itself full.
467
+ */
455
468
  protected get hasRows(): boolean;
456
469
  /**
457
470
  * Asks for a different order, and reports whether the request stood.
@@ -575,6 +588,21 @@ export declare class HelixHeadlessDataTable extends HelixHeadlessDataTable_base
575
588
  private announceSort;
576
589
  /** Columns arrive from the light DOM, which changes no property here. */
577
590
  private readonly handleSlotChange;
591
+ /**
592
+ * One cell, carrying its column's edge as a fact rather than as a decision.
593
+ *
594
+ * **A fact published rather than a property chosen**, which is what
595
+ * `helix-table` does with the same attribute: what lining up *means*, a
596
+ * `justify-content` for a value that fits or a `text-align` for one that
597
+ * wraps, belongs to whoever draws the cell. Written here as an inline
598
+ * `text-align` it was this tier choosing, in the tier that ships no CSS, and a
599
+ * consumer could not overrule it either, an inline declaration beating any
600
+ * `::part(cell)` rule they wrote.
601
+ *
602
+ * Only the three edges reach it, `align` being a string anybody can write and
603
+ * this being a style attribute: `edgeOf` is that guard, and `helix-table`
604
+ * holds the same value to the same three.
605
+ */
578
606
  private renderCell;
579
607
  /**
580
608
  * A checkbox, named for what it chooses, whose change the table takes.
@@ -10,7 +10,7 @@ import { nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { repeat } from 'lit/directives/repeat.js';
12
12
  import { html } from 'lit/static-html.js';
13
- import { at } from '../../table/column/table-column.js';
13
+ import { at, edgeOf } from '../../table/column/table-column.js';
14
14
  import '../../checkbox/index.js';
15
15
  import '../../pagination/index.js';
16
16
  import { arranged, cycle, format, ordered, parse, window_, } from './order.js';
@@ -353,7 +353,7 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
353
353
  })).length;
354
354
  }
355
355
  get hasRows() {
356
- return this.view.rows.length > 0;
356
+ return this.view.available > 0;
357
357
  }
358
358
  requestSort(next) {
359
359
  return requestChange({
@@ -547,10 +547,11 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
547
547
  }
548
548
  }
549
549
  renderCell(column, row, picked) {
550
+ const edge = edgeOf(column.align);
550
551
  return html `<span
551
552
  part="cell${picked ? ' cell-selected' : ''}"
552
553
  role="gridcell"
553
- style=${column.align ? `text-align: ${column.align}` : nothing}
554
+ style=${edge ? `--data-table-cell-align: ${edge}` : nothing}
554
555
  >${column.read(row)}</span
555
556
  >`;
556
557
  }
@@ -619,6 +620,7 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
619
620
  }
620
621
  render() {
621
622
  const { available, matched, rows } = this.view;
623
+ const filled = this.hasRows;
622
624
  const template = this.template;
623
625
  const columns = this.shownColumns;
624
626
  const pagination = this.tag('pagination');
@@ -638,7 +640,7 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
638
640
  : html `<slot name="columns" @slotchange=${this.handleSlotChange}></slot>`}
639
641
  </div>
640
642
  ${this.renderSpacer('before')}${this.renderRows(rows)}${this.renderSpacer('after')}
641
- ${this.renderStatus(available > 0)}
643
+ ${this.renderStatus(filled)}
642
644
  </div>
643
645
  <div part="footer">
644
646
  <slot name="footer"></slot>
@@ -13,7 +13,7 @@ import { type TemplateResult } from 'lit';
13
13
  * it is also a property.
14
14
  *
15
15
  * @since 0.1.0
16
- * @status experimental
16
+ * @status stable
17
17
  * @documentation https://fusion.dev/helix/components/description-list
18
18
  *
19
19
  * @slot - The value.
@@ -24,10 +24,11 @@ import { type TemplateResult } from 'lit';
24
24
  */
25
25
  export declare class HelixHeadlessDescriptionListItem extends HelixElement {
26
26
  /**
27
- * What the value is, for the common case of plain text.
27
+ * What the value is called, for the common case of plain text.
28
28
  *
29
29
  * The fallback of the `label` slot, so slotted content replaces it rather than
30
- * appearing beside it.
30
+ * appearing beside it. The value itself is the default slot: it is the half
31
+ * that varies and is often more than text.
31
32
  */
32
33
  label: string;
33
34
  protected render(): TemplateResult;
@@ -21,7 +21,7 @@ import { type TemplateResult } from 'lit';
21
21
  * `display: contents` alike.
22
22
  *
23
23
  * @since 0.1.0
24
- * @status experimental
24
+ * @status stable
25
25
  * @category data
26
26
  * @aliases Data list, Key-value list, Details, Properties
27
27
  * @documentation https://fusion.dev/helix/components/description-list
@@ -28,7 +28,7 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
28
28
  * here is the dependency the tiers exist to prevent.
29
29
  *
30
30
  * @since 0.1.0
31
- * @status experimental
31
+ * @status stable
32
32
  * @category charts
33
33
  * @aliases Contribution graph, Uptime strip, Calendar heatmap, Activity graph
34
34
  * @documentation https://fusion.dev/helix/components/heatmap
@@ -40,7 +40,7 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
40
40
  * @event {HelixResizeEvent} helix-resize - Fired when the number of cells drawn changes, carrying that number.
41
41
  *
42
42
  * @csspart cell - One reading.
43
- * @csspart empty - Shown when the table has no readings in it.
43
+ * @csspart empty - Shown when the table has no readings in it, and not before the table can be read at all: on a server, and while hydrating what one sent, there is no document to resolve `for` in and nothing is known yet.
44
44
  * @csspart end - The trailing slot's box.
45
45
  * @csspart footer - The three-slot row under the strip.
46
46
  * @csspart mark - The invisible point the tooltip is anchored to.
@@ -86,6 +86,9 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
86
86
  export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
87
87
  /**
88
88
  * Shown when the table has no readings in it.
89
+ *
90
+ * Never shown while the table cannot be read at all, which is a server render
91
+ * and the hydrating one after it: see `sourceKnown`.
89
92
  */
90
93
  emptyText: string;
91
94
  /**
@@ -201,6 +204,23 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
201
204
  * collision that type-checks in one direction and reads wrong in both.
202
205
  */
203
206
  private get points();
207
+ /**
208
+ * Whether this render can tell a table with no readings from one it has not
209
+ * resolved yet.
210
+ *
211
+ * **Unknown is not empty, which is what an empty state must never say.**
212
+ * `for` names an id and resolving an id wants a document, so a server has
213
+ * none and a hydrating render must not look either. Without this the server
214
+ * drew "No readings" over a table holding ninety days of them, a crawler read
215
+ * that sentence, and the strip flipped to a full one on hydration: the fault
216
+ * `MixinCollection` names for a slotted collection, arriving through the one
217
+ * channel that mixin cannot see.
218
+ *
219
+ * The same shape as `childrenKnown`, asked of a document rather than of a
220
+ * tree. An id that resolves to nothing in a browser is still known, and still
221
+ * empty: a `for` naming no table should say so rather than sit blank.
222
+ */
223
+ private get sourceKnown();
204
224
  /**
205
225
  * `rows` as a usable count, which is not always what the attribute says.
206
226
  *
@@ -38,6 +38,16 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
38
38
  get points() {
39
39
  return this.series[0]?.points ?? [];
40
40
  }
41
+ get sourceKnown() {
42
+ if (this.for === '') {
43
+ return true;
44
+ }
45
+ if (this.hydrating) {
46
+ return false;
47
+ }
48
+ const root = this.getRootNode();
49
+ return typeof root.getElementById === 'function';
50
+ }
41
51
  get rowCount() {
42
52
  return Math.max(1, Math.floor(this.rows) || 1);
43
53
  }
@@ -145,7 +155,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
145
155
  })}
146
156
  ${this.renderTooltip()}
147
157
  </div>
148
- ${cells.length === 0 ? html `<p part="empty">${this.emptyText}</p>` : nothing}
158
+ ${cells.length === 0 && this.sourceKnown ? html `<p part="empty">${this.emptyText}</p>` : nothing}
149
159
  <div part="footer">
150
160
  <span part="start"><slot name="start"></slot></span>
151
161
  <span part="summary"><slot name="summary"></slot></span>
@@ -54,7 +54,7 @@ interface Row {
54
54
  * gives it and a headless consumer has to.
55
55
  *
56
56
  * @since 0.1.0
57
- * @status experimental
57
+ * @status stable
58
58
  * @category data
59
59
  * @aliases JSON viewer, Object viewer, Inspector, Data explorer
60
60
  * @documentation https://fusion.dev/helix/components/object-inspector
@@ -120,6 +120,13 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
120
120
  *
121
121
  * Negative for the reason Code Block's is: a boolean attribute defaulting to
122
122
  * true could never be turned off from markup.
123
+ *
124
+ * **It does not reflect, where Code Block's does**, and the difference is what
125
+ * the two sheets need. Code Block reserves the button's width with
126
+ * `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
127
+ * who set the property. This button is positioned out of the flow and takes no
128
+ * room, so nothing selects on it, and reflection exists so that a selector can
129
+ * reach a value.
123
130
  */
124
131
  noCopy: boolean;
125
132
  /**
@@ -179,6 +186,16 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
179
186
  private readonly handleKeydown;
180
187
  private handleRowClick;
181
188
  private renderValue;
189
+ /**
190
+ * One entry, named for its state where it holds one.
191
+ *
192
+ * **`row-active` and no attribute beside it.** Which row the keys are on is
193
+ * drawn by a sheet and by nothing else: the accessibility tree hears it from
194
+ * `aria-activedescendant` on the tree, which points at this row's id, so an
195
+ * attribute would be a second spelling with no reader. The name is the one a
196
+ * consumer can reach, nothing being able to follow `::part()` with an
197
+ * attribute selector.
198
+ */
182
199
  private renderRow;
183
200
  /** The copy button, behind the seam Code Block's uses, so each tier renders its own. */
184
201
  protected renderCopyButton(row: Row | undefined): TemplateResult;
@@ -262,7 +262,6 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
262
262
  role="treeitem"
263
263
  id=${`row-${index}`}
264
264
  data-index=${index}
265
- ?data-active=${active}
266
265
  aria-level=${row.depth + 1}
267
266
  aria-posinset=${row.position}
268
267
  aria-setsize=${row.siblings}
@@ -331,7 +330,7 @@ __decorate([
331
330
  property()
332
331
  ], HelixHeadlessObjectInspector.prototype, "label", void 0);
333
332
  __decorate([
334
- property({ attribute: 'no-copy', reflect: true, type: Boolean })
333
+ property({ attribute: 'no-copy', type: Boolean })
335
334
  ], HelixHeadlessObjectInspector.prototype, "noCopy", void 0);
336
335
  __decorate([
337
336
  property({ attribute: false })
@@ -20,6 +20,16 @@ export type CellReader = (row: Readonly<Record<string, unknown>>) => unknown;
20
20
  * into a table tells a reader the software is broken rather than the row is.
21
21
  */
22
22
  export declare const at: (row: Readonly<Record<string, unknown>>, path: string) => unknown;
23
+ /**
24
+ * The edge a column names, where it names one of the three.
25
+ *
26
+ * **`align` is a string anybody can write**, the union on the property being a
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.
31
+ */
32
+ export declare const edgeOf: (align: string | undefined) => string | undefined;
23
33
  /**
24
34
  * @summary One column of a table: its heading, how wide it is, and what it reads.
25
35
  *
@@ -26,6 +26,8 @@ export const at = (row, path) => {
26
26
  }
27
27
  return cursor;
28
28
  };
29
+ const EDGES = new Set(['center', 'end', 'start']);
30
+ export const edgeOf = (align) => align && EDGES.has(align) ? align : undefined;
29
31
  let HelixHeadlessTableColumn = class HelixHeadlessTableColumn extends HelixElement {
30
32
  constructor() {
31
33
  super(...arguments);
@@ -1,6 +1,6 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
- import type { HelixHeadlessTableColumn } from '../column/table-column.js';
3
+ import { type HelixHeadlessTableColumn } from '../column/table-column.js';
4
4
  declare const HelixHeadlessTable_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & typeof HelixElement;
5
5
  /**
6
6
  * @summary Tabular data laid out on a grid.
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, MixinCollection } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- const EDGES = new Set(['center', 'end', 'start']);
10
+ import { edgeOf } from '../column/table-column.js';
11
11
  const tracksOf = (list, wanted) => {
12
12
  const words = [];
13
13
  let depth = 0;
@@ -119,9 +119,10 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
119
119
  if (typeof CSSStyleSheet === 'undefined' || !('replaceSync' in CSSStyleSheet.prototype)) {
120
120
  return;
121
121
  }
122
- const rules = this.tableColumns.flatMap((column, index) => column.align && EDGES.has(column.align)
123
- ? [`::slotted(:nth-child(${index + 1})) { --table-cell-align: ${column.align}; }`]
124
- : []);
122
+ const rules = this.tableColumns.flatMap((column, index) => {
123
+ const edge = edgeOf(column.align);
124
+ return edge ? [`::slotted(:nth-child(${index + 1})) { --table-cell-align: ${edge}; }`] : [];
125
+ });
125
126
  const text = ['::slotted(*) { --table-cell-align: initial; }', ...rules].join('\n');
126
127
  this.alignment ??= new CSSStyleSheet();
127
128
  if (text !== this.aligned) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-headless",
3
3
  "description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
4
- "version": "0.38.0",
4
+ "version": "0.39.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -46,14 +46,14 @@
46
46
  },
47
47
  "bugs": "https://github.com/project-fusion/fusion/issues",
48
48
  "dependencies": {
49
- "@fusion.dev/helix-core": "0.38.0",
50
- "@fusion.dev/helix-icons": "0.38.0",
49
+ "@fusion.dev/helix-core": "0.39.0",
50
+ "@fusion.dev/helix-icons": "0.39.0",
51
51
  "uqr": "^0.1.3"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@custom-elements-manifest/analyzer": "^0.11.0",
55
- "@fusion.dev/helix-cem": "0.38.0",
56
- "@fusion.dev/helix-testing": "0.38.0",
55
+ "@fusion.dev/helix-cem": "0.39.0",
56
+ "@fusion.dev/helix-testing": "0.39.0",
57
57
  "@fusion.dev/scripts": "0.0.0-dev",
58
58
  "@happy-dom/global-registrator": "^20.0.0",
59
59
  "@lit-labs/ssr": "^4.1.0",
package/types/jsx.d.ts CHANGED
@@ -162,6 +162,7 @@ import type {
162
162
  HelixSortEvent,
163
163
  HelixTourAskEvent,
164
164
  at,
165
+ edgeOf,
165
166
  fromMinutes,
166
167
  initialsOf,
167
168
  isTime,
@@ -5315,18 +5316,20 @@ reader makes in one of these. */
5315
5316
  };
5316
5317
 
5317
5318
  export type HelixHeadlessDescriptionListItemProps = {
5318
- /** What the value is, for the common case of plain text.
5319
+ /** What the value is called, for the common case of plain text.
5319
5320
 
5320
5321
  The fallback of the `label` slot, so slotted content replaces it rather than
5321
- appearing beside it. */
5322
+ appearing beside it. The value itself is the default slot: it is the half
5323
+ that varies and is often more than text. */
5322
5324
  label?: (HelixHeadlessDescriptionListItem["label"]) | undefined;
5323
5325
  };
5324
5326
 
5325
5327
  export type HelixHeadlessDescriptionListItemSolidJsProps = {
5326
- /** What the value is, for the common case of plain text.
5328
+ /** What the value is called, for the common case of plain text.
5327
5329
 
5328
5330
  The fallback of the `label` slot, so slotted content replaces it rather than
5329
- appearing beside it. */
5331
+ appearing beside it. The value itself is the default slot: it is the half
5332
+ that varies and is often more than text. */
5330
5333
  "prop:label"?: (HelixHeadlessDescriptionListItem["label"]) | undefined;
5331
5334
 
5332
5335
  /** Set the innerHTML of the element */
@@ -6941,9 +6944,15 @@ export type HelixHeadlessHeatmapHelixResizeElementEvent =
6941
6944
  HelixHeadlessHeatmapElementEvent<HelixResizeEvent>;
6942
6945
 
6943
6946
  export type HelixHeadlessHeatmapProps = {
6944
- /** Shown when the table has no readings in it. */
6947
+ /** Shown when the table has no readings in it.
6948
+
6949
+ Never shown while the table cannot be read at all, which is a server render
6950
+ and the hydrating one after it: see `sourceKnown`. */
6945
6951
  "empty-text"?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
6946
- /** Shown when the table has no readings in it. */
6952
+ /** Shown when the table has no readings in it.
6953
+
6954
+ Never shown while the table cannot be read at all, which is a server render
6955
+ and the hydrating one after it: see `sourceKnown`. */
6947
6956
  emptyText?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
6948
6957
  /** Space between cells, in CSS pixels, for the same reason `min-cell` is a
6949
6958
  number. */
@@ -7030,9 +7039,15 @@ words and is already written. */
7030
7039
  };
7031
7040
 
7032
7041
  export type HelixHeadlessHeatmapSolidJsProps = {
7033
- /** Shown when the table has no readings in it. */
7042
+ /** Shown when the table has no readings in it.
7043
+
7044
+ Never shown while the table cannot be read at all, which is a server render
7045
+ and the hydrating one after it: see `sourceKnown`. */
7034
7046
  "attr:empty-text"?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
7035
- /** Shown when the table has no readings in it. */
7047
+ /** Shown when the table has no readings in it.
7048
+
7049
+ Never shown while the table cannot be read at all, which is a server render
7050
+ and the hydrating one after it: see `sourceKnown`. */
7036
7051
  "prop:emptyText"?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
7037
7052
  /** Space between cells, in CSS pixels, for the same reason `min-cell` is a
7038
7053
  number. */
@@ -9979,12 +9994,26 @@ page's markup should not take the page down over a comma. */
9979
9994
  /** Whether to leave the copy button off.
9980
9995
 
9981
9996
  Negative for the reason Code Block's is: a boolean attribute defaulting to
9982
- true could never be turned off from markup. */
9997
+ true could never be turned off from markup.
9998
+
9999
+ **It does not reflect, where Code Block's does**, and the difference is what
10000
+ the two sheets need. Code Block reserves the button's width with
10001
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
10002
+ who set the property. This button is positioned out of the flow and takes no
10003
+ room, so nothing selects on it, and reflection exists so that a selector can
10004
+ reach a value. */
9983
10005
  "no-copy"?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
9984
10006
  /** Whether to leave the copy button off.
9985
10007
 
9986
10008
  Negative for the reason Code Block's is: a boolean attribute defaulting to
9987
- true could never be turned off from markup. */
10009
+ true could never be turned off from markup.
10010
+
10011
+ **It does not reflect, where Code Block's does**, and the difference is what
10012
+ the two sheets need. Code Block reserves the button's width with
10013
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
10014
+ who set the property. This button is positioned out of the flow and takes no
10015
+ room, so nothing selects on it, and reflection exists so that a selector can
10016
+ reach a value. */
9988
10017
  noCopy?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
9989
10018
  /** Whether to draw only the rows in view.
9990
10019
 
@@ -10029,12 +10058,26 @@ page's markup should not take the page down over a comma. */
10029
10058
  /** Whether to leave the copy button off.
10030
10059
 
10031
10060
  Negative for the reason Code Block's is: a boolean attribute defaulting to
10032
- true could never be turned off from markup. */
10061
+ true could never be turned off from markup.
10062
+
10063
+ **It does not reflect, where Code Block's does**, and the difference is what
10064
+ the two sheets need. Code Block reserves the button's width with
10065
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
10066
+ who set the property. This button is positioned out of the flow and takes no
10067
+ room, so nothing selects on it, and reflection exists so that a selector can
10068
+ reach a value. */
10033
10069
  "bool:no-copy"?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
10034
10070
  /** Whether to leave the copy button off.
10035
10071
 
10036
10072
  Negative for the reason Code Block's is: a boolean attribute defaulting to
10037
- true could never be turned off from markup. */
10073
+ true could never be turned off from markup.
10074
+
10075
+ **It does not reflect, where Code Block's does**, and the difference is what
10076
+ the two sheets need. Code Block reserves the button's width with
10077
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
10078
+ who set the property. This button is positioned out of the flow and takes no
10079
+ room, so nothing selects on it, and reflection exists so that a selector can
10080
+ reach a value. */
10038
10081
  "prop:noCopy"?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
10039
10082
  /** Whether to draw only the rows in view.
10040
10083
 
@@ -21275,6 +21318,7 @@ export type CustomElements = {
21275
21318
  *
21276
21319
  * CSS variables available for styling the component.
21277
21320
  *
21321
+ * - `--data-table-cell-align`: 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. (default: `undefined`)
21278
21322
  * - `--data-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. `--data-table-columns` is the one to set. (default: `undefined`)
21279
21323
  *
21280
21324
  * ## CSS Parts
@@ -21295,7 +21339,7 @@ export type CustomElements = {
21295
21339
  * - `checkbox-mark`: The tick, or the dash while some rows are selected.
21296
21340
  * - `checkbox-mark-checked`: The mark while its box is checked, beside `checkbox-mark`.
21297
21341
  * - `checkbox-mark-indeterminate`: The dash while only some rows are selected, beside `checkbox-mark`.
21298
- * - `empty`: Shown when no rows match.
21342
+ * - `empty`: Shown when the result has nothing in it, whether it arrived empty or a filter emptied it. A result still on its way is `loading` instead, which wins over this.
21299
21343
  * - `footer`: The region below the grid.
21300
21344
  * - `head`: The row the column headings sit in. `display: contents`, so it takes no space.
21301
21345
  * - `loading`: Shown while the rows are still on their way.
@@ -21878,10 +21922,11 @@ export type CustomElements = {
21878
21922
  *
21879
21923
  * Component attributes and properties that can be applied to the element or by using JavaScript.
21880
21924
  *
21881
- * - `label`: What the value is, for the common case of plain text.
21925
+ * - `label`: What the value is called, for the common case of plain text.
21882
21926
  *
21883
21927
  * The fallback of the `label` slot, so slotted content replaces it rather than
21884
- * appearing beside it.
21928
+ * appearing beside it. The value itself is the default slot: it is the half
21929
+ * that varies and is often more than text.
21885
21930
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
21886
21931
  *
21887
21932
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -23933,6 +23978,9 @@ export type CustomElements = {
23933
23978
  * Component attributes and properties that can be applied to the element or by using JavaScript.
23934
23979
  *
23935
23980
  * - `empty-text`/`emptyText`: Shown when the table has no readings in it.
23981
+ *
23982
+ * Never shown while the table cannot be read at all, which is a server render
23983
+ * and the hydrating one after it: see `sourceKnown`.
23936
23984
  * - `gap`: Space between cells, in CSS pixels, for the same reason `min-cell` is a
23937
23985
  * number.
23938
23986
  * - `min-cell`/`minCell`: The smallest a cell may get before the strip draws fewer of them, in CSS pixels.
@@ -24094,7 +24142,7 @@ export type CustomElements = {
24094
24142
  * Custom selectors for styling elements within the component.
24095
24143
  *
24096
24144
  * - `cell`: One reading.
24097
- * - `empty`: Shown when the table has no readings in it.
24145
+ * - `empty`: Shown when the table has no readings in it, and not before the table can be read at all: on a server, and while hydrating what one sent, there is no document to resolve `for` in and nothing is known yet.
24098
24146
  * - `end`: The trailing slot's box.
24099
24147
  * - `footer`: The three-slot row under the strip.
24100
24148
  * - `mark`: The invisible point the tooltip is anchored to.
@@ -26998,6 +27046,13 @@ export type CustomElements = {
26998
27046
  *
26999
27047
  * Negative for the reason Code Block's is: a boolean attribute defaulting to
27000
27048
  * true could never be turned off from markup.
27049
+ *
27050
+ * **It does not reflect, where Code Block's does**, and the difference is what
27051
+ * the two sheets need. Code Block reserves the button's width with
27052
+ * `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
27053
+ * who set the property. This button is positioned out of the flow and takes no
27054
+ * room, so nothing selects on it, and reflection exists so that a selector can
27055
+ * reach a value.
27001
27056
  * - `windowed`: Whether to draw only the rows in view.
27002
27057
  *
27003
27058
  * For a value of thousands of entries. Reflected, because the box it scrolls
@@ -38755,6 +38810,7 @@ export type CustomElementsSolidJs = {
38755
38810
  *
38756
38811
  * CSS variables available for styling the component.
38757
38812
  *
38813
+ * - `--data-table-cell-align`: 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. (default: `undefined`)
38758
38814
  * - `--data-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. `--data-table-columns` is the one to set. (default: `undefined`)
38759
38815
  *
38760
38816
  * ## CSS Parts
@@ -38775,7 +38831,7 @@ export type CustomElementsSolidJs = {
38775
38831
  * - `checkbox-mark`: The tick, or the dash while some rows are selected.
38776
38832
  * - `checkbox-mark-checked`: The mark while its box is checked, beside `checkbox-mark`.
38777
38833
  * - `checkbox-mark-indeterminate`: The dash while only some rows are selected, beside `checkbox-mark`.
38778
- * - `empty`: Shown when no rows match.
38834
+ * - `empty`: Shown when the result has nothing in it, whether it arrived empty or a filter emptied it. A result still on its way is `loading` instead, which wins over this.
38779
38835
  * - `footer`: The region below the grid.
38780
38836
  * - `head`: The row the column headings sit in. `display: contents`, so it takes no space.
38781
38837
  * - `loading`: Shown while the rows are still on their way.
@@ -39365,10 +39421,11 @@ export type CustomElementsSolidJs = {
39365
39421
  *
39366
39422
  * Component attributes and properties that can be applied to the element or by using JavaScript.
39367
39423
  *
39368
- * - `label`: What the value is, for the common case of plain text.
39424
+ * - `label`: What the value is called, for the common case of plain text.
39369
39425
  *
39370
39426
  * The fallback of the `label` slot, so slotted content replaces it rather than
39371
- * appearing beside it.
39427
+ * appearing beside it. The value itself is the default slot: it is the half
39428
+ * that varies and is often more than text.
39372
39429
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
39373
39430
  *
39374
39431
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -41448,6 +41505,9 @@ export type CustomElementsSolidJs = {
41448
41505
  * Component attributes and properties that can be applied to the element or by using JavaScript.
41449
41506
  *
41450
41507
  * - `empty-text`/`emptyText`: Shown when the table has no readings in it.
41508
+ *
41509
+ * Never shown while the table cannot be read at all, which is a server render
41510
+ * and the hydrating one after it: see `sourceKnown`.
41451
41511
  * - `gap`: Space between cells, in CSS pixels, for the same reason `min-cell` is a
41452
41512
  * number.
41453
41513
  * - `min-cell`/`minCell`: The smallest a cell may get before the strip draws fewer of them, in CSS pixels.
@@ -41609,7 +41669,7 @@ export type CustomElementsSolidJs = {
41609
41669
  * Custom selectors for styling elements within the component.
41610
41670
  *
41611
41671
  * - `cell`: One reading.
41612
- * - `empty`: Shown when the table has no readings in it.
41672
+ * - `empty`: Shown when the table has no readings in it, and not before the table can be read at all: on a server, and while hydrating what one sent, there is no document to resolve `for` in and nothing is known yet.
41613
41673
  * - `end`: The trailing slot's box.
41614
41674
  * - `footer`: The three-slot row under the strip.
41615
41675
  * - `mark`: The invisible point the tooltip is anchored to.
@@ -44564,6 +44624,13 @@ export type CustomElementsSolidJs = {
44564
44624
  *
44565
44625
  * Negative for the reason Code Block's is: a boolean attribute defaulting to
44566
44626
  * true could never be turned off from markup.
44627
+ *
44628
+ * **It does not reflect, where Code Block's does**, and the difference is what
44629
+ * the two sheets need. Code Block reserves the button's width with
44630
+ * `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
44631
+ * who set the property. This button is positioned out of the flow and takes no
44632
+ * room, so nothing selects on it, and reflection exists so that a selector can
44633
+ * reach a value.
44567
44634
  * - `windowed`: Whether to draw only the rows in view.
44568
44635
  *
44569
44636
  * For a value of thousands of entries. Reflected, because the box it scrolls
@@ -52205,6 +52272,8 @@ export type CustomCssProperties = {
52205
52272
  "--color-picker-saturation"?: (string) | undefined;
52206
52273
  /** A color to paint: the current one on the sample, a preset's on each preset. */
52207
52274
  "--color-picker-swatch"?: (string) | undefined;
52275
+ /** 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. */
52276
+ "--data-table-cell-align"?: (string) | undefined;
52208
52277
  /** 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. */
52209
52278
  "--data-table-template"?: (string) | undefined;
52210
52279
  /** How many month columns are drawn, capped at two. `--date-picker-columns` overrides it. */
package/types/vue.d.ts CHANGED
@@ -105,6 +105,7 @@ import type {
105
105
  HelixHeadlessSwitch,
106
106
  HelixHeadlessTableCell,
107
107
  at,
108
+ edgeOf,
108
109
  HelixHeadlessTableColumn,
109
110
  HelixHeadlessTable,
110
111
  HelixHeadlessTableRow,
@@ -2729,10 +2730,11 @@ export type HelixHeadlessDatePickerVueEvents = {
2729
2730
  };
2730
2731
 
2731
2732
  export type HelixHeadlessDescriptionListItemVueProps = {
2732
- /** What the value is, for the common case of plain text.
2733
+ /** What the value is called, for the common case of plain text.
2733
2734
 
2734
2735
  The fallback of the `label` slot, so slotted content replaces it rather than
2735
- appearing beside it. */
2736
+ appearing beside it. The value itself is the default slot: it is the half
2737
+ that varies and is often more than text. */
2736
2738
  label?: (HelixHeadlessDescriptionListItem["label"]) | undefined;
2737
2739
  };
2738
2740
 
@@ -3563,9 +3565,15 @@ export type HelixHeadlessHeatmapHelixResizeElementEvent =
3563
3565
  HelixHeadlessHeatmapElementEvent<HelixResizeEvent>;
3564
3566
 
3565
3567
  export type HelixHeadlessHeatmapVueProps = {
3566
- /** Shown when the table has no readings in it. */
3568
+ /** Shown when the table has no readings in it.
3569
+
3570
+ Never shown while the table cannot be read at all, which is a server render
3571
+ and the hydrating one after it: see `sourceKnown`. */
3567
3572
  "empty-text"?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
3568
- /** Shown when the table has no readings in it. */
3573
+ /** Shown when the table has no readings in it.
3574
+
3575
+ Never shown while the table cannot be read at all, which is a server render
3576
+ and the hydrating one after it: see `sourceKnown`. */
3569
3577
  emptyText?: (HelixHeadlessHeatmap["emptyText"]) | undefined;
3570
3578
  /** Space between cells, in CSS pixels, for the same reason `min-cell` is a
3571
3579
  number. */
@@ -5130,12 +5138,26 @@ page's markup should not take the page down over a comma. */
5130
5138
  /** Whether to leave the copy button off.
5131
5139
 
5132
5140
  Negative for the reason Code Block's is: a boolean attribute defaulting to
5133
- true could never be turned off from markup. */
5141
+ true could never be turned off from markup.
5142
+
5143
+ **It does not reflect, where Code Block's does**, and the difference is what
5144
+ the two sheets need. Code Block reserves the button's width with
5145
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
5146
+ who set the property. This button is positioned out of the flow and takes no
5147
+ room, so nothing selects on it, and reflection exists so that a selector can
5148
+ reach a value. */
5134
5149
  "no-copy"?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
5135
5150
  /** Whether to leave the copy button off.
5136
5151
 
5137
5152
  Negative for the reason Code Block's is: a boolean attribute defaulting to
5138
- true could never be turned off from markup. */
5153
+ true could never be turned off from markup.
5154
+
5155
+ **It does not reflect, where Code Block's does**, and the difference is what
5156
+ the two sheets need. Code Block reserves the button's width with
5157
+ `:host(:not([no-copy]))`, so the attribute has to be there for a consumer
5158
+ who set the property. This button is positioned out of the flow and takes no
5159
+ room, so nothing selects on it, and reflection exists so that a selector can
5160
+ reach a value. */
5139
5161
  noCopy?: (HelixHeadlessObjectInspector["noCopy"]) | undefined;
5140
5162
  /** Whether to draw only the rows in view.
5141
5163
 
@@ -8780,6 +8802,8 @@ export type CustomCssProperties = {
8780
8802
  "--color-picker-saturation"?: (string) | undefined;
8781
8803
  /** A color to paint: the current one on the sample, a preset's on each preset. */
8782
8804
  "--color-picker-swatch"?: (string) | undefined;
8805
+ /** 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. */
8806
+ "--data-table-cell-align"?: (string) | undefined;
8783
8807
  /** 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. */
8784
8808
  "--data-table-template"?: (string) | undefined;
8785
8809
  /** How many month columns are drawn, capped at two. `--date-picker-columns` overrides it. */