feat(grid): equal-height rows via items-stretch (#126)#137
Conversation
A Wind grid renders as a Wrap and sizes each cell to its own content, so a row where one card is taller than its siblings ends up ragged (CSS Grid stretches them by default). Adding items-stretch now builds the grid as a Column of IntrinsicHeight Rows: each row's cells are Expanded (even width) with CrossAxisAlignment.stretch, so every cell matches the tallest in its row. The last row is padded with empty slots so columns stay aligned. Cells size from their own content; h-full on a stretched cell is unsupported (it inserts a LayoutBuilder that asserts under IntrinsicHeight - the intrinsic-sizing limitation documented in #129). The default Wrap grid is unchanged when items-stretch is absent. Post-change sync: w_div/grid_stretch_test (equalize, even width, ragged row, default-unaffected), doc/layout/grid.md Equal-Height Rows section (cross-links the sizing limitation), example grid_cols KPI-card demo, skill (SKILL.md layout/grid mentions + tokens.md + layouts.md, version 2.8.0), CHANGELOG. Closes #126
|
Warning Review limit reached
Next review available in: 12 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds an opt-in equal-height row mode for Wind’s grid layout to mirror CSS Grid’s align-items: stretch, addressing ragged card rows when one cell is taller.
Changes:
- Implement
items-stretchhandling forgridinWDiv, rendering aColumnofIntrinsicHeightRows withExpandedcells for equal-height rows. - Add widget tests covering stretched height equalization, width distribution, ragged final-row behavior, and the default (non-stretch) grid path.
- Update docs, example page, skill references, and changelog to document and demonstrate the new behavior and the
IntrinsicHeight/h-fullcaveat.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/src/widgets/w_div.dart | Adds items-stretch grid rendering via IntrinsicHeight row grouping and padded final rows. |
| test/widgets/w_div/grid_stretch_test.dart | New regression tests validating items-stretch grid behavior and default grid behavior. |
| doc/layout/grid.md | Documents equal-height rows via items-stretch and warns about h-full + intrinsic sizing. |
| example/lib/pages/layout/grid_cols.dart | Adds an example section demonstrating equal-height KPI stat cards using items-stretch. |
| skills/wind-ui/SKILL.md | Bumps skill version and documents items-stretch grid behavior in guidance text. |
| skills/wind-ui/references/tokens.md | Updates grid-cols-N reference to mention items-stretch equal-height behavior and caveat. |
| skills/wind-ui/references/layouts.md | Updates layout reference note to include items-stretch equal-height rows and intrinsic-sizing caveat. |
| CHANGELOG.md | Adds an entry describing items-stretch equal-height grid rows and limitations. |
- grid-cols-0 (the parser regex allows 0) divided by zero in the Wrap itemWidth and never advanced the items-stretch row loop (start += cols), hanging the build. Clamp cols to a floor of 1 at the source so both the Wrap and stretch paths are safe. Covered by a no-hang test. - Rename the grid_stretch_test wrap helper to the repo-standard wrapWithTheme.
|
Both addressed:
@coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
gh pr view 137 --repo fluttersdk/wind --json files,additions,deletions,title,body | head -c 3000
echo "---"
gh pr diff 137 --repo fluttersdk/wind | head -c 20000Length of output: 23264 🏁 Script executed: #!/bin/bash
set -euo pipefail
gh pr diff 137 --repo fluttersdk/wind | sed -n '1,400p' | tail -c 8000Length of output: 8241 🏁 Script executed: #!/bin/bash
set -euo pipefail
gh pr diff 137 --repo fluttersdk/wind | sed -n '/grid-cols-0/,/^$/p' | head -c 4000Length of output: 4421 🏁 Script executed: gh pr diff 137 --repo fluttersdk/wind | grep -n "grid-cols-0\|no.hang\|no-hang"Length of output: 527 Confirmed — the
This all looks solid. Triggering a full review pass now to make sure nothing else needs attention. ✅ Action performedReview finished.
|
| ) | ||
| ``` | ||
|
|
||
| The stretch already equalizes height, so cells should size from their own content. Do **not** put `h-full` on a stretched grid cell: that inserts an internal `LayoutBuilder`, which asserts under the `IntrinsicHeight` the equal-height grid uses (see the [intrinsic-sizing limitation](./sizing.md#intrinsic-sizing-limitation)). |
…etch # Conflicts: # CHANGELOG.md
|
The @coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
gh pr view 137 --repo fluttersdk/wind --json mergeable,mergeStateStatus,commits --jq '.mergeable, .mergeStateStatus'
echo "---diff for sizing.md link---"
gh pr diff 137 --repo fluttersdk/wind | grep -n "intrinsic-sizing-limitation" -A2 -B2 || true
echo "---check anchor exists in doc file---"
gh api repos/fluttersdk/wind/contents/doc/layout/sizing.md --jq '.content' | base64 -d | grep -n "intrinsic-sizing-limitation" -A2 -B2 || true
echo "---CHANGELOG check---"
gh pr diff 137 --repo fluttersdk/wind | grep -n "CHANGELOG" -A5 | head -c 3000Length of output: 3652 Confirmed. The Triggering a full review pass now. ✅ Action performedReview finished.
|
… assert (#139) (#140) * fix(grid): stretch unequal flex-col cells without the IntrinsicHeight assert grid items-stretch (#126/#137) crashed with "RenderBox was not laid out" (rooted at RenderIntrinsicHeight -> "LayoutBuilder does not support returning intrinsic dimensions") whenever it had to STRETCH an unequal cell whose content is a flex flex-col (a card): such a cell carries a LayoutBuilder (cross-axis stretch / h-full / basis-*), and IntrinsicHeight queries child intrinsics, which LayoutBuilder cannot answer. So the feature crashed exactly the unequal-height case it exists for. Replace IntrinsicHeight + Row(stretch) with WindEqualHeightRow, a RenderObject that measures each cell with a real loose-height layout and re-lays it tight to the row's max height. Real layout is what LayoutBuilder supports, so flex-col cells stretch correctly. Each cell also gets an equal share of the width (matching the fixed column count). Bonus: h-full inside a stretched cell now resolves too. Post-change sync: wind_equal_height_row_test (stretch, width split, spacing setter, LayoutBuilder child, hit-test, unbounded-width, empty) + grid _stretch_test #139 case; doc/layout/grid.md, skill (tokens.md + layouts.md, version 2.8.1), CHANGELOG. Closes #139 * fix(grid): harden WindEqualHeightRow per PR #140 review - Validate spacing (finite, non-negative) in both the widget constructor and the render-object setter (debug asserts). - Honor the incoming height constraint: cells stretch to maxHeight.clamp(minHeight, maxHeight), not just the measured tallest, so a parent-imposed tight/min height stays consistent with the cells. - Update the stale _buildStretchGrid dartdoc (was still describing the old IntrinsicHeight + h-full caveat). - Make the LayoutBuilder-child test assert the actual stretched height (80) instead of a vacuous non-null check.
Summary
Fixes #126. A Wind
gridrenders as aWrapand sizes each cell to its own content, so a row where one card is taller leaves the others short (CSS Grid's default isalign-items: stretch). A KPI stat-card row with one card that has a delta line rendered ragged.Fix
Adding
items-stretchto agridnow builds it as aColumnofIntrinsicHeightRows: each row's cells areExpanded(even width) withCrossAxisAlignment.stretch, so every cell matches the tallest in its row. The final short row is padded with emptyExpandedslots so columns stay aligned. The defaultWrapgrid is unchanged whenitems-stretchis absent.Cells size from their own content.
h-fullon a stretched cell is unsupported (it inserts aLayoutBuilderthat asserts underIntrinsicHeight— the intrinsic-sizing limitation documented in #129); the stretch already equalizes height, so it is unnecessary.Tests
test/widgets/w_div/grid_stretch_test.dart: cells stretch to the tallest (short 40 → 120), cells divide width evenly (292 each at 600 − gap), a ragged final row does not crash and keeps column width, and the default grid keeps intrinsic heights.Definition of done
dart analyze: clean (lib + test + example).dart format: no diff.flutter test: 1555 pass (1 pre-existing skip), coverage 91.4% ≥ 90%.doc/layout/grid.md(Equal-Height Rows section, cross-links the sizing limitation), examplegrid_colsKPI-card demo, skill (SKILL.md§4/§9/§11 +tokens.md+references/layouts.md, version 2.8.0),CHANGELOG.md. README not touched (within the existing layout/grid surface).