@fusion.dev/helix-headless 0.108.0 → 0.108.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.
@@ -102702,7 +102702,7 @@
102702
102702
  "text": "string"
102703
102703
  },
102704
102704
  "default": "''",
102705
- "description": "The track this column takes, as CSS.\n\nA single track value, so anything valid in `grid-template-columns` works:\n`16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in\nits place in a `Table`'s `columns`, where that table sets one, and\notherwise shares what is left over equally, as `minmax(max-content, 1fr)`.\nSet here, it wins over that list, which is what lets a reader resize a\ncolumn in a table that set one.\n\n**The floor is `max-content`, never `0` and never `min-content`.** A zero\nfloor lets a track shrink under its own content: at 375 the columns squeeze\nto 75px and `eu-central-1` wraps across lines, which reads as corrupt data\nrather than as a table that ran out of room. A `min-content` floor still\nbreaks it, a hyphen being a wrap opportunity.\n\nThe overflow has somewhere to go: `@fusion.dev/helix` scrolls the table's\nown box, so a long value pushes past the container and the table scrolls\ninstead of the value being destroyed. Measured at 375: tracks of 192, 89 and\n102 against a 343 box, so the table scrolls 384 and the page does not move.\n\nThe cost is that a column of prose asks for its longest paragraph on one\nline, so a column holding sentences rather than values wants\n`width=\"minmax(0, 1fr)\"` to opt back into wrapping. A headless consumer owns\nthe overflow either way, that being paint, and gets the honest track list.",
102705
+ "description": "The track this column takes, as CSS.\n\nA single track value, so anything valid in `grid-template-columns` works:\n`16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in\nits place in a `Table`'s `columns`, where that table sets one, and\notherwise shares what is left over equally, as `minmax(max-content, 1fr)`.\nSet here, it wins over that list, which is what lets a reader resize a\ncolumn in a table that set one.\n\n**A `Table` fits the columns that set neither to what they hold.** Once\nany of them holds a sentence, the columns of short values keep\n`max-content` and the columns of sentences wrap, above a floor of `14ch`,\neach taking a share of the room in proportion to its text. A table of\nvalues alone keeps the default.\n\n**The floor is `max-content`, never `0` and never `min-content`.** A zero\nfloor lets a track shrink under its own content: at 375 the columns squeeze\nto 75px and `eu-central-1` wraps across lines, which reads as corrupt data\nrather than as a table that ran out of room. A `min-content` floor still\nbreaks it, a hyphen being a wrap opportunity.\n\nThe overflow has somewhere to go: `@fusion.dev/helix` scrolls the table's\nown box, so a long value pushes past the container and the table scrolls\ninstead of the value being destroyed. Measured at 375: tracks of 192, 89 and\n102 against a 343 box, so the table scrolls 384 and the page does not move.\n\nA column of sentences does not pay for this: the table sees the sentences\nand lets that column wrap. A headless consumer owns the overflow either\nway, that being paint, and gets the honest track list.",
102706
102706
  "attribute": "width"
102707
102707
  },
102708
102708
  {
@@ -103314,7 +103314,7 @@
103314
103314
  "text": "string"
103315
103315
  },
103316
103316
  "default": "''",
103317
- "description": "The track this column takes, as CSS.\n\nA single track value, so anything valid in `grid-template-columns` works:\n`16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in\nits place in a `Table`'s `columns`, where that table sets one, and\notherwise shares what is left over equally, as `minmax(max-content, 1fr)`.\nSet here, it wins over that list, which is what lets a reader resize a\ncolumn in a table that set one.\n\n**The floor is `max-content`, never `0` and never `min-content`.** A zero\nfloor lets a track shrink under its own content: at 375 the columns squeeze\nto 75px and `eu-central-1` wraps across lines, which reads as corrupt data\nrather than as a table that ran out of room. A `min-content` floor still\nbreaks it, a hyphen being a wrap opportunity.\n\nThe overflow has somewhere to go: `@fusion.dev/helix` scrolls the table's\nown box, so a long value pushes past the container and the table scrolls\ninstead of the value being destroyed. Measured at 375: tracks of 192, 89 and\n102 against a 343 box, so the table scrolls 384 and the page does not move.\n\nThe cost is that a column of prose asks for its longest paragraph on one\nline, so a column holding sentences rather than values wants\n`width=\"minmax(0, 1fr)\"` to opt back into wrapping. A headless consumer owns\nthe overflow either way, that being paint, and gets the honest track list.",
103317
+ "description": "The track this column takes, as CSS.\n\nA single track value, so anything valid in `grid-template-columns` works:\n`16rem`, `auto`, `minmax(0, 2fr)`. Left unset the column takes the track in\nits place in a `Table`'s `columns`, where that table sets one, and\notherwise shares what is left over equally, as `minmax(max-content, 1fr)`.\nSet here, it wins over that list, which is what lets a reader resize a\ncolumn in a table that set one.\n\n**A `Table` fits the columns that set neither to what they hold.** Once\nany of them holds a sentence, the columns of short values keep\n`max-content` and the columns of sentences wrap, above a floor of `14ch`,\neach taking a share of the room in proportion to its text. A table of\nvalues alone keeps the default.\n\n**The floor is `max-content`, never `0` and never `min-content`.** A zero\nfloor lets a track shrink under its own content: at 375 the columns squeeze\nto 75px and `eu-central-1` wraps across lines, which reads as corrupt data\nrather than as a table that ran out of room. A `min-content` floor still\nbreaks it, a hyphen being a wrap opportunity.\n\nThe overflow has somewhere to go: `@fusion.dev/helix` scrolls the table's\nown box, so a long value pushes past the container and the table scrolls\ninstead of the value being destroyed. Measured at 375: tracks of 192, 89 and\n102 against a 343 box, so the table scrolls 384 and the page does not move.\n\nA column of sentences does not pay for this: the table sees the sentences\nand lets that column wrap. A headless consumer owns the overflow either\nway, that being paint, and gets the honest track list.",
103318
103318
  "fieldName": "width"
103319
103319
  },
103320
103320
  {
@@ -103524,6 +103524,31 @@
103524
103524
  "description": "The track list, from the columns if there are any.\n\nRead from the DOM rather than kept, so adding or removing a column needs\nnothing else to be told. A hidden column takes no track: left in, the\nheader row had a heading fewer than the grid had tracks, the first cell\nfilled the gap, and every row after it began a column late. Falls back to\nthe `columns` string for a table that declares no columns, and to a single\ntrack for one that declares neither.",
103525
103525
  "readonly": true
103526
103526
  },
103527
+ {
103528
+ "kind": "method",
103529
+ "name": "fitted",
103530
+ "privacy": "private",
103531
+ "return": {
103532
+ "type": {
103533
+ "text": "string[]"
103534
+ }
103535
+ },
103536
+ "parameters": [
103537
+ {
103538
+ "name": "declared",
103539
+ "type": {
103540
+ "text": "HelixHeadlessTableColumn[]"
103541
+ }
103542
+ },
103543
+ {
103544
+ "name": "listed",
103545
+ "type": {
103546
+ "text": "string[]"
103547
+ }
103548
+ }
103549
+ ],
103550
+ "description": "Tracks for the columns that set nothing, from how much text each holds.\n\n**A column of sentences wraps and a column of values does not.** Every\ncolumn left at `minmax(max-content, 1fr)` asks for its longest cell on one\nline, which is right for `eu-central-1` and wrong for a description: the\ntable grows as wide as its longest sentence and scrolls, on a phone and on\na desktop alike. So once any column holds more than `SHORT` characters,\nthe short columns keep `max-content`, and each long one wraps above a\n`FLOOR`, taking a share of the room in proportion to its text.\n\nA table with no long column keeps the default, so a table of values lays\nout as it always has. A column's `width` and a track in `columns` are both\nstatements an author made, and each wins over this.\n\nCharacters stand in for width. They only have to rank columns against each\nother, and a count needs no layout, so it reads the same before paint as\nafter. Sampled, so a table of thousands of rows reads `SAMPLE` of them."
103551
+ },
103527
103552
  {
103528
103553
  "kind": "field",
103529
103554
  "name": "handleSlotChange",
@@ -103538,7 +103563,7 @@
103538
103563
  },
103539
103564
  "privacy": "private",
103540
103565
  "default": "undefined",
103541
- "description": "Watches the light DOM for rows and columns arriving, leaving and moving.\n\n**A manually assigned slot does not announce them**, the same gap `Chat`\nand `Carousel` watch for. Under `slotAssignment: 'manual'` only `assign`\nchanges an assignment, so a row appended after the first render reached no\nslot and drew nowhere, and a column moved to another place lost its\nassignment on the way out and never got it back: measured in Chromium, both\n`assignedSlot` null a render later. A table whose definition loaded before\nits markup was parsed drew no columns at all, having rendered before any\narrived."
103566
+ "description": "Watches the light DOM for rows and columns arriving, leaving and moving.\n\n**A manually assigned slot does not announce them**, the same gap `Chat`\nand `Carousel` watch for. Under `slotAssignment: 'manual'` only `assign`\nchanges an assignment, so a row appended after the first render reached no\nslot and drew nowhere, and a column moved to another place lost its\nassignment on the way out and never got it back: measured in Chromium, both\n`assignedSlot` null a render later. A table whose definition loaded before\nits markup was parsed drew no columns at all, having rendered before any\narrived.\n\n**The cells' text too, all the way down.** The columns that set no width\nare sized from what their cells say, so a cell whose text changes can\nchange the track it sits in."
103542
103567
  },
103543
103568
  {
103544
103569
  "kind": "field",
@@ -208,6 +208,12 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
208
208
  * Set here, it wins over that list, which is what lets a reader resize a
209
209
  * column in a table that set one.
210
210
  *
211
+ * **A `Table` fits the columns that set neither to what they hold.** Once
212
+ * any of them holds a sentence, the columns of short values keep
213
+ * `max-content` and the columns of sentences wrap, above a floor of `14ch`,
214
+ * each taking a share of the room in proportion to its text. A table of
215
+ * values alone keeps the default.
216
+ *
211
217
  * **The floor is `max-content`, never `0` and never `min-content`.** A zero
212
218
  * floor lets a track shrink under its own content: at 375 the columns squeeze
213
219
  * to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -219,10 +225,9 @@ export declare class HelixHeadlessTableColumn extends HelixElement {
219
225
  * instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
220
226
  * 102 against a 343 box, so the table scrolls 384 and the page does not move.
221
227
  *
222
- * The cost is that a column of prose asks for its longest paragraph on one
223
- * line, so a column holding sentences rather than values wants
224
- * `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
225
- * the overflow either way, that being paint, and gets the honest track list.
228
+ * A column of sentences does not pay for this: the table sees the sentences
229
+ * and lets that column wrap. A headless consumer owns the overflow either
230
+ * way, that being paint, and gets the honest track list.
226
231
  */
227
232
  width: string;
228
233
  /**
@@ -85,6 +85,26 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
85
85
  * track for one that declares neither.
86
86
  */
87
87
  private get template();
88
+ /**
89
+ * Tracks for the columns that set nothing, from how much text each holds.
90
+ *
91
+ * **A column of sentences wraps and a column of values does not.** Every
92
+ * column left at `minmax(max-content, 1fr)` asks for its longest cell on one
93
+ * line, which is right for `eu-central-1` and wrong for a description: the
94
+ * table grows as wide as its longest sentence and scrolls, on a phone and on
95
+ * a desktop alike. So once any column holds more than `SHORT` characters,
96
+ * the short columns keep `max-content`, and each long one wraps above a
97
+ * `FLOOR`, taking a share of the room in proportion to its text.
98
+ *
99
+ * A table with no long column keeps the default, so a table of values lays
100
+ * out as it always has. A column's `width` and a track in `columns` are both
101
+ * statements an author made, and each wins over this.
102
+ *
103
+ * Characters stand in for width. They only have to rank columns against each
104
+ * other, and a count needs no layout, so it reads the same before paint as
105
+ * after. Sampled, so a table of thousands of rows reads `SAMPLE` of them.
106
+ */
107
+ private fitted;
88
108
  private readonly handleSlotChange;
89
109
  /**
90
110
  * Watches the light DOM for rows and columns arriving, leaving and moving.
@@ -97,6 +117,10 @@ export declare class HelixHeadlessTable extends HelixHeadlessTable_base {
97
117
  * `assignedSlot` null a render later. A table whose definition loaded before
98
118
  * its markup was parsed drew no columns at all, having rendered before any
99
119
  * arrived.
120
+ *
121
+ * **The cells' text too, all the way down.** The columns that set no width
122
+ * are sized from what their cells say, so a cell whose text changes can
123
+ * change the track it sits in.
100
124
  */
101
125
  private watcher;
102
126
  connectedCallback(): void;
@@ -35,6 +35,10 @@ const tracksOf = (list, wanted) => {
35
35
  }
36
36
  return tracks.slice(0, wanted);
37
37
  };
38
+ const SHORT = 32;
39
+ const FLOOR = '14ch';
40
+ const SAMPLE = 200;
41
+ const lengthOf = (element) => (element?.textContent ?? '').replace(/\s+/g, ' ').trim().length;
38
42
  let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixElement) {
39
43
  constructor() {
40
44
  super(...arguments);
@@ -56,14 +60,42 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
56
60
  return this.columns;
57
61
  }
58
62
  const listed = tracksOf(this.columns, declared.length);
63
+ const fitted = this.fitted(declared, listed);
59
64
  return declared
60
- .flatMap((column, index) => column.shown ? [column.width ? column.track : listed[index] || column.track] : [])
65
+ .flatMap((column, index) => column.shown
66
+ ? [column.width ? column.track : listed[index] || fitted[index] || column.track]
67
+ : [])
61
68
  .join(' ');
62
69
  }
70
+ fitted(declared, listed) {
71
+ const open = declared.map((column, index) => column.shown && !column.width && !listed[index]);
72
+ if (!open.includes(true)) {
73
+ return [];
74
+ }
75
+ const widths = declared.map((column) => lengthOf(column));
76
+ for (const row of this.slotted.slice(0, SAMPLE)) {
77
+ for (const [at, width] of widths.entries()) {
78
+ widths[at] = Math.max(width, lengthOf(row.children[at]));
79
+ }
80
+ }
81
+ const long = widths.filter((width, at) => open[at] && width > SHORT);
82
+ if (long.length === 0) {
83
+ return [];
84
+ }
85
+ const narrowest = Math.min(...long);
86
+ return widths.map((width, at) => {
87
+ if (!open[at]) {
88
+ return '';
89
+ }
90
+ return width > SHORT
91
+ ? `minmax(${FLOOR}, ${Number((width / narrowest).toFixed(2))}fr)`
92
+ : 'max-content';
93
+ });
94
+ }
63
95
  connectedCallback() {
64
96
  super.connectedCallback();
65
97
  this.watcher = new MutationObserver(() => this.requestUpdate());
66
- this.watcher.observe(this, { childList: true });
98
+ this.watcher.observe(this, { characterData: true, childList: true, subtree: true });
67
99
  }
68
100
  disconnectedCallback() {
69
101
  super.disconnectedCallback();
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.108.0",
4
+ "version": "0.108.2",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -46,13 +46,13 @@
46
46
  },
47
47
  "bugs": "https://github.com/project-fusion/fusion/issues",
48
48
  "dependencies": {
49
- "@fusion.dev/helix-core": "0.108.0",
50
- "@fusion.dev/helix-icons": "0.108.0",
49
+ "@fusion.dev/helix-core": "0.108.2",
50
+ "@fusion.dev/helix-icons": "0.108.2",
51
51
  "uqr": "^0.1.3"
52
52
  },
53
53
  "devDependencies": {
54
- "@fusion.dev/helix-cem": "0.108.0",
55
- "@fusion.dev/helix-testing": "0.108.0",
54
+ "@fusion.dev/helix-cem": "0.108.2",
55
+ "@fusion.dev/helix-testing": "0.108.2",
56
56
  "@fusion.dev/scripts": "0.0.0-dev",
57
57
  "@happy-dom/global-registrator": "^20.0.0",
58
58
  "@lit-labs/ssr": "^4.1.0",
package/types/jsx.d.ts CHANGED
@@ -17932,6 +17932,12 @@ otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
17932
17932
  Set here, it wins over that list, which is what lets a reader resize a
17933
17933
  column in a table that set one.
17934
17934
 
17935
+ **A `Table` fits the columns that set neither to what they hold.** Once
17936
+ any of them holds a sentence, the columns of short values keep
17937
+ `max-content` and the columns of sentences wrap, above a floor of `14ch`,
17938
+ each taking a share of the room in proportion to its text. A table of
17939
+ values alone keeps the default.
17940
+
17935
17941
  **The floor is `max-content`, never `0` and never `min-content`.** A zero
17936
17942
  floor lets a track shrink under its own content: at 375 the columns squeeze
17937
17943
  to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -17943,10 +17949,9 @@ own box, so a long value pushes past the container and the table scrolls
17943
17949
  instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
17944
17950
  102 against a 343 box, so the table scrolls 384 and the page does not move.
17945
17951
 
17946
- The cost is that a column of prose asks for its longest paragraph on one
17947
- line, so a column holding sentences rather than values wants
17948
- `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
17949
- the overflow either way, that being paint, and gets the honest track list. */
17952
+ A column of sentences does not pay for this: the table sees the sentences
17953
+ and lets that column wrap. A headless consumer owns the overflow either
17954
+ way, that being paint, and gets the honest track list. */
17950
17955
  width?: (HelixHeadlessTableColumn["width"]) | undefined;
17951
17956
  /** The text screen readers announce for the column's width. `{width}` is
17952
17957
  replaced with the width. */
@@ -18096,6 +18101,12 @@ otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
18096
18101
  Set here, it wins over that list, which is what lets a reader resize a
18097
18102
  column in a table that set one.
18098
18103
 
18104
+ **A `Table` fits the columns that set neither to what they hold.** Once
18105
+ any of them holds a sentence, the columns of short values keep
18106
+ `max-content` and the columns of sentences wrap, above a floor of `14ch`,
18107
+ each taking a share of the room in proportion to its text. A table of
18108
+ values alone keeps the default.
18109
+
18099
18110
  **The floor is `max-content`, never `0` and never `min-content`.** A zero
18100
18111
  floor lets a track shrink under its own content: at 375 the columns squeeze
18101
18112
  to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -18107,10 +18118,9 @@ own box, so a long value pushes past the container and the table scrolls
18107
18118
  instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
18108
18119
  102 against a 343 box, so the table scrolls 384 and the page does not move.
18109
18120
 
18110
- The cost is that a column of prose asks for its longest paragraph on one
18111
- line, so a column holding sentences rather than values wants
18112
- `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
18113
- the overflow either way, that being paint, and gets the honest track list. */
18121
+ A column of sentences does not pay for this: the table sees the sentences
18122
+ and lets that column wrap. A headless consumer owns the overflow either
18123
+ way, that being paint, and gets the honest track list. */
18114
18124
  "prop:width"?: (HelixHeadlessTableColumn["width"]) | undefined;
18115
18125
  /** The text screen readers announce for the column's width. `{width}` is
18116
18126
  replaced with the width. */
@@ -38388,6 +38398,12 @@ export type CustomElements = {
38388
38398
  * Set here, it wins over that list, which is what lets a reader resize a
38389
38399
  * column in a table that set one.
38390
38400
  *
38401
+ * **A `Table` fits the columns that set neither to what they hold.** Once
38402
+ * any of them holds a sentence, the columns of short values keep
38403
+ * `max-content` and the columns of sentences wrap, above a floor of `14ch`,
38404
+ * each taking a share of the room in proportion to its text. A table of
38405
+ * values alone keeps the default.
38406
+ *
38391
38407
  * **The floor is `max-content`, never `0` and never `min-content`.** A zero
38392
38408
  * floor lets a track shrink under its own content: at 375 the columns squeeze
38393
38409
  * to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -38399,10 +38415,9 @@ export type CustomElements = {
38399
38415
  * instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
38400
38416
  * 102 against a 343 box, so the table scrolls 384 and the page does not move.
38401
38417
  *
38402
- * The cost is that a column of prose asks for its longest paragraph on one
38403
- * line, so a column holding sentences rather than values wants
38404
- * `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
38405
- * the overflow either way, that being paint, and gets the honest track list.
38418
+ * A column of sentences does not pay for this: the table sees the sentences
38419
+ * and lets that column wrap. A headless consumer owns the overflow either
38420
+ * way, that being paint, and gets the honest track list.
38406
38421
  * - `width-label`/`widthLabel`: The text screen readers announce for the column's width. `{width}` is
38407
38422
  * replaced with the width.
38408
38423
  * - `cell`: A function that reads the cell's content from a row, for cells that `field`
@@ -58458,6 +58473,12 @@ export type CustomElementsSolidJs = {
58458
58473
  * Set here, it wins over that list, which is what lets a reader resize a
58459
58474
  * column in a table that set one.
58460
58475
  *
58476
+ * **A `Table` fits the columns that set neither to what they hold.** Once
58477
+ * any of them holds a sentence, the columns of short values keep
58478
+ * `max-content` and the columns of sentences wrap, above a floor of `14ch`,
58479
+ * each taking a share of the room in proportion to its text. A table of
58480
+ * values alone keeps the default.
58481
+ *
58461
58482
  * **The floor is `max-content`, never `0` and never `min-content`.** A zero
58462
58483
  * floor lets a track shrink under its own content: at 375 the columns squeeze
58463
58484
  * to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -58469,10 +58490,9 @@ export type CustomElementsSolidJs = {
58469
58490
  * instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
58470
58491
  * 102 against a 343 box, so the table scrolls 384 and the page does not move.
58471
58492
  *
58472
- * The cost is that a column of prose asks for its longest paragraph on one
58473
- * line, so a column holding sentences rather than values wants
58474
- * `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
58475
- * the overflow either way, that being paint, and gets the honest track list.
58493
+ * A column of sentences does not pay for this: the table sees the sentences
58494
+ * and lets that column wrap. A headless consumer owns the overflow either
58495
+ * way, that being paint, and gets the honest track list.
58476
58496
  * - `width-label`/`widthLabel`: The text screen readers announce for the column's width. `{width}` is
58477
58497
  * replaced with the width.
58478
58498
  * - `cell`: A function that reads the cell's content from a row, for cells that `field`
package/types/vue.d.ts CHANGED
@@ -9254,6 +9254,12 @@ otherwise shares what is left over equally, as `minmax(max-content, 1fr)`.
9254
9254
  Set here, it wins over that list, which is what lets a reader resize a
9255
9255
  column in a table that set one.
9256
9256
 
9257
+ **A `Table` fits the columns that set neither to what they hold.** Once
9258
+ any of them holds a sentence, the columns of short values keep
9259
+ `max-content` and the columns of sentences wrap, above a floor of `14ch`,
9260
+ each taking a share of the room in proportion to its text. A table of
9261
+ values alone keeps the default.
9262
+
9257
9263
  **The floor is `max-content`, never `0` and never `min-content`.** A zero
9258
9264
  floor lets a track shrink under its own content: at 375 the columns squeeze
9259
9265
  to 75px and `eu-central-1` wraps across lines, which reads as corrupt data
@@ -9265,10 +9271,9 @@ own box, so a long value pushes past the container and the table scrolls
9265
9271
  instead of the value being destroyed. Measured at 375: tracks of 192, 89 and
9266
9272
  102 against a 343 box, so the table scrolls 384 and the page does not move.
9267
9273
 
9268
- The cost is that a column of prose asks for its longest paragraph on one
9269
- line, so a column holding sentences rather than values wants
9270
- `width="minmax(0, 1fr)"` to opt back into wrapping. A headless consumer owns
9271
- the overflow either way, that being paint, and gets the honest track list. */
9274
+ A column of sentences does not pay for this: the table sees the sentences
9275
+ and lets that column wrap. A headless consumer owns the overflow either
9276
+ way, that being paint, and gets the honest track list. */
9272
9277
  width?: (HelixHeadlessTableColumn["width"]) | undefined;
9273
9278
  /** The text screen readers announce for the column's width. `{width}` is
9274
9279
  replaced with the width. */