Skip to content

feat(grid): equal-height rows via items-stretch (#126)#137

Merged
anilcancakir merged 3 commits into
masterfrom
feat/grid-items-stretch
Jul 1, 2026
Merged

feat(grid): equal-height rows via items-stretch (#126)#137
anilcancakir merged 3 commits into
masterfrom
feat/grid-items-stretch

Conversation

@anilcancakir

Copy link
Copy Markdown
Collaborator

Summary

Fixes #126. A Wind grid renders as a Wrap and sizes each cell to its own content, so a row where one card is taller leaves the others short (CSS Grid's default is align-items: stretch). A KPI stat-card row with one card that has a delta line rendered ragged.

Fix

Adding items-stretch to a grid now builds it 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 final short row is padded with empty Expanded slots so columns stay aligned. The default Wrap grid is unchanged when items-stretch is absent.

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 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%.
  • Post-change sync: doc/layout/grid.md (Equal-Height Rows section, cross-links the sizing limitation), example grid_cols KPI-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).

Note: SKILL.md 2.8.0 bump overlaps with the sibling PRs (#130-#136); whichever merges last takes a trivial one-line version conflict (keep 2.8.0). This PR pairs naturally with #136 (the intrinsic-sizing limitation it references).

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
Copilot AI review requested due to automatic review settings June 30, 2026 23:00
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@anilcancakir, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 07269f08-f3d6-4e96-b8ea-845fd1d4209f

📥 Commits

Reviewing files that changed from the base of the PR and between 79c984e and 36668cb.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • doc/layout/grid.md
  • example/lib/pages/layout/grid_cols.dart
  • lib/src/widgets/w_div.dart
  • skills/wind-ui/SKILL.md
  • skills/wind-ui/references/layouts.md
  • skills/wind-ui/references/tokens.md
  • test/widgets/w_div/grid_stretch_test.dart
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/grid-items-stretch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-stretch handling for grid in WDiv, rendering a Column of IntrinsicHeight Rows with Expanded cells 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-full caveat.

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.

Comment thread lib/src/widgets/w_div.dart
Comment thread test/widgets/w_div/grid_stretch_test.dart Outdated
- 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.
@anilcancakir

Copy link
Copy Markdown
Collaborator Author

Both addressed:

  • grid-cols-0 hang: clamped cols to a floor of 1 at the source in _buildGridStructure, so both the Wrap (/0 itemWidth) and the items-stretch row loop (start += cols) are safe. Added a no-hang test for grid-cols-0 items-stretch.
  • Renamed the wrap test helper to the repo-standard wrapWithTheme.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
🧩 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 20000

Length of output: 23264


🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr diff 137 --repo fluttersdk/wind | sed -n '1,400p' | tail -c 8000

Length 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 4000

Length 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 grid-cols-0 no-hang test exists at line 407 of test/widgets/w_div/grid_stretch_test.dart ('grid-cols-0 is clamped to 1 and does not hang'), using grid grid-cols-0 gap-2 items-stretch to exercise the clamp under the stretch path.

@anilcancakir Both fixes are verified in the diff:

  • grid-cols-0 hang: lib/src/widgets/w_div.dart clamps cols = rawCols < 1 ? 1 : rawCols right at the source in _buildGridStructure, before both the Wrap itemWidth division and the _buildStretchGrid row loop (start += cols) run — so neither path can divide by zero or hang.
  • Test helper rename: wrapwrapWithTheme is applied consistently across grid_stretch_test.dart.
  • New regression test: 'grid-cols-0 is clamped to 1 and does not hang' exercises grid grid-cols-0 gap-2 items-stretch directly.

This all looks solid. Triggering a full review pass now to make sure nothing else needs attention.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread doc/layout/grid.md
)
```

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)).
@anilcancakir

Copy link
Copy Markdown
Collaborator Author

The sizing.md#intrinsic-sizing-limitation link is now valid: the target section was added in #136, which is merged, and this branch is updated from master (the anchor <a name="intrinsic-sizing-limitation"> is present). Also merged master (CHANGELOG conflict resolved, all entries kept). grid-cols-0 clamp + helper rename already in place.

@coderabbitai review

@anilcancakir anilcancakir merged commit 3fd0f84 into master Jul 1, 2026
5 of 6 checks passed
@anilcancakir anilcancakir deleted the feat/grid-items-stretch branch July 1, 2026 00:07
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
🧩 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 3000

Length of output: 3652


Confirmed. The intrinsic-sizing-limitation anchor exists in doc/layout/sizing.md (Line 171), matching the link target in this PR's grid.md update (Line 52), and the CHANGELOG.md diff shows the merge conflict was resolved cleanly with both this PR's entry and prior entries (#125, #123) intact. Merge status reads as UNKNOWN via the API (GitHub hasn't recomputed mergeability yet), but that's just a transient GitHub state and not a concern from the diff content itself.

Triggering a full review pass now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

anilcancakir added a commit that referenced this pull request Jul 1, 2026
… 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

grid does not stretch cells to equal height (no items-stretch for grid)

2 participants