Context
This is leaf L2 of epic #19658, blocked by #19661 (the geometry model). Mounted rows get their real heights by measuring the displayed text in place.
The Problem
Content-sized mode needs each mounted row's natural height: the maximum across its declared wrapping text columns, in every body. The constrained outer row and cell are not a natural-content oracle, because cells inherit the row's height and rows are contain: strict.
The Architectural Reality
- The cell:
.neo-grid-cell is display: flex, align-items: center, height: inherit, padding: 2px 10px 2px, with 1px bottom and right borders, border-box (Body.scss).
- The flex trap (epic review, Stage 4): inside a flex cell, a block child is a flex item, and its automatic minimum width is its longest word.
overflow-wrap: break-word then never breaks a long word, which overflows instead. D#19645 probe 2 showed that a flex cell missed 43 of 900 cases and a block cell missed 0.
- The read:
DomAccess.getLayoutRect({id: [...]}) measures transform-immune layout boxes in one batch with one forced layout.
The Fix
- Declared columns: a column flag (name settled at intake, e.g.
wrapText: true) declares a height-driving text column.
- The text container: in content-sized mode a declared cell renders its text in a block container with
white-space: normal, overflow-wrap: break-word and height: auto. Either the cell becomes display: block in this mode, or the container gets min-width: 0; flex: 1 1 auto, so long words break.
- The measurement: after a mount or update, the App Worker requests the layout rects of the mounted text containers in one batch. It adds the cell's vertical padding and border, takes the maximum per row across columns and bodies, and feeds #19661's height setter.
- The generation fence: each request carries a view/record/layout generation (content, width and font context), and a response whose generation no longer matches is dropped. Recycled slots never write a stale record.
Contract Ledger
| Target surface |
Source of authority |
Proposed behavior |
Fallback / edge case |
Docs |
Evidence |
| Column flag declaring a height-driving text column |
#19658 |
Only declared columns drive height; others take the row height |
Without declared columns, rows keep the estimate |
JSDoc |
Unit + e2e |
| Content-sized cell CSS |
Epic review Stage 4 |
Long words break inside the column width |
— |
SCSS comment |
Spec with a word longer than the column |
| Measurement generation fence |
D#19645 (Sophie 18878897) |
Stale responses are dropped |
— |
JSDoc |
Recycled-slot spec |
Acceptance Criteria
Out of Scope
Rows and columns not yet mounted, measure-ahead, and font-arrival invalidation (L3); scroll correction (L4).
Avoided Traps
- Measuring the constrained row or cell box, which only reports its imposed height.
- A per-row main-thread
ResizeObserver that writes heights: the App Worker owns geometry, and main only reports observations.
- Calling a stateful renderer a second time just to size it.
Related
#19658 · #19661 (blocked by) · D#19645 · #19515 / #19643 (announce files before branching)
unowned-rationale: open for any peer; the epic steward (Ada) picks it up otherwise.
Origin Session ID: daac81df-5205-405e-a3af-aec56e5cca45
Context
This is leaf L2 of epic #19658, blocked by #19661 (the geometry model). Mounted rows get their real heights by measuring the displayed text in place.
The Problem
Content-sized mode needs each mounted row's natural height: the maximum across its declared wrapping text columns, in every body. The constrained outer row and cell are not a natural-content oracle, because cells inherit the row's height and rows are
contain: strict.The Architectural Reality
.neo-grid-cellisdisplay: flex,align-items: center,height: inherit,padding: 2px 10px 2px, with 1px bottom and right borders,border-box(Body.scss).overflow-wrap: break-wordthen never breaks a long word, which overflows instead. D#19645 probe 2 showed that a flex cell missed 43 of 900 cases and a block cell missed 0.DomAccess.getLayoutRect({id: [...]})measures transform-immune layout boxes in one batch with one forced layout.The Fix
wrapText: true) declares a height-driving text column.white-space: normal,overflow-wrap: break-wordandheight: auto. Either the cell becomesdisplay: blockin this mode, or the container getsmin-width: 0; flex: 1 1 auto, so long words break.Contract Ledger
Acceptance Criteria
Out of Scope
Rows and columns not yet mounted, measure-ahead, and font-arrival invalidation (L3); scroll correction (L4).
Avoided Traps
ResizeObserverthat writes heights: the App Worker owns geometry, and main only reports observations.Related
#19658 · #19661 (blocked by) · D#19645 · #19515 / #19643 (announce files before branching)
unowned-rationale: open for any peer; the epic steward (Ada) picks it up otherwise.
Origin Session ID: daac81df-5205-405e-a3af-aec56e5cca45