From db5607395608ffcd727bc5c15469abd826d9ce41 Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Tue, 18 Aug 2026 19:32:31 -0400 Subject: [PATCH 1/7] feat(mix): add content-sized GridTrack.auto() rows GridBox could not express a grid whose rows size to their tallest child. The only workaround, autoRows(GridTrack.fixed(n)), silently truncated any child taller than the declared track, so a scroll view of unknown-height content had no correct option. Add GridTrack.auto(), valid in rows and autoRows, and default an omitted autoRows to it so implicit rows match CSS's grid-auto-rows: auto. Columns still reject auto; content-sized columns need a separate two-axis design. RenderMixGrid keeps the one-pass path for fixed/fr grids. When any effective row is auto, children in those rows are measured at their resolved column width with a loose height, each row takes its tallest measurement, and the final pass lays every child into the stretched cell. Live layout, dry layout, and vertical intrinsics share that geometry through Flutter's ChildLayouter helpers, following RenderTable's pattern. The wire format gains a fieldless {"type":"auto"} track as an additive v1 discriminator, accepted on rows and autoRows only. BREAKING CHANGE: a GridBox that needed more rows than it declared used to throw; it now lays out with content-sized implicit rows. This applies both when no rows are declared and when explicit rows undershoot the child count. --- packages/mix/CHANGELOG.md | 17 + packages/mix/README.md | 8 +- packages/mix/doc/grid-layout.md | 85 +- packages/mix/example/.gitignore | 1 + packages/mix/example/README.md | 4 +- packages/mix/example/lib/grid_example.dart | 37 +- .../test/goldens/grid_catalog_compact.png | Bin 63179 -> 74177 bytes .../test/goldens/grid_catalog_wide.png | Bin 45446 -> 61593 bytes .../example/test/grid_box_example_test.dart | 40 + packages/mix/lib/src/layout/grid_box.dart | 24 +- .../mix/lib/src/layout/grid_box_spec.dart | 46 +- packages/mix/lib/src/layout/grid_track.dart | 44 +- .../src/layout/internal/grid_geometry.dart | 7 +- .../src/layout/internal/grid_validation.dart | 3 +- packages/mix/lib/src/layout/render_grid.dart | 277 ++++-- .../mix/test/src/layout/grid_box_test.dart | 866 ++++++++++++++++-- .../src/layout/grid_layout_property_test.dart | 79 +- .../test/src/layout/grid_public_api_test.dart | 30 + packages/mix_protocol/CHANGELOG.md | 2 + packages/mix_protocol/GUIDE.md | 2 +- packages/mix_protocol/WIRE_CONTRACT.md | 6 +- .../lib/src/schema/grid_box_styler_codec.dart | 30 +- .../lib/src/schema/wire_discriminators.dart | 1 + .../src/tokens/token_reference_walker.dart | 2 + .../test/grid_box_styler_codec_test.dart | 100 ++ .../test/schema_export_golden_test.dart | 31 +- .../test/styler_round_trip_test.dart | 2 +- skills/mix/SKILL.md | 2 +- skills/mix/references/fluent-api.md | 2 +- skills/mix/references/layout.md | 36 +- skills/mix/references/styler-api-policy.md | 2 +- 31 files changed, 1580 insertions(+), 206 deletions(-) create mode 100644 packages/mix/example/.gitignore diff --git a/packages/mix/CHANGELOG.md b/packages/mix/CHANGELOG.md index c16eb1aba..d967cc2d9 100644 --- a/packages/mix/CHANGELOG.md +++ b/packages/mix/CHANGELOG.md @@ -2,6 +2,10 @@ ### New features +- **GridTrack.auto():** Vertical auto tracks for explicit `rows` and + `autoRows`. `auto` is vertical-only; columns still reject it. Existing + explicit fixed/`fr` layouts keep a single child layout per pass. Auto-row + children may be measured and then stretched. - **Generated Styler field metadata:** Every generated Styler now exposes its complete source-field inventory through `StylerFieldMetadata.$stylerFieldNames`, allowing schema tooling to validate @@ -9,6 +13,19 @@ previously generated Stylers do not implement this capability until they opt in or are regenerated. +### Breaking changes + +- **Omitted GridBox autoRows no longer throws:** Previously, children that + needed more rows than were declared required an explicit `autoRows` track + or the grid threw. Omitted `autoRows` now defaults to `GridTrack.auto()`, + so implicit rows size to their tallest child — both when no rows are + declared and when some explicit rows exist but are not enough. Fractional + rows still require a bounded height. Fixed tracks remain hard constraints. + Because the new default opts a Grid into the measure-then-stretch pass, + nesting compounds it: a leaf inside one auto Grid is laid out twice, and + inside three nested auto Grids eight times. Give inner levels fixed rows + once their heights are known. + ## 2.2.0-beta.4 ### Fixes diff --git a/packages/mix/README.md b/packages/mix/README.md index 9f6bd176b..89c6aefb6 100644 --- a/packages/mix/README.md +++ b/packages/mix/README.md @@ -165,14 +165,14 @@ the runnable [WrapBox example](example/README.md). ### Grid Layouts -`GridBox` uses fixed and fractional tracks and can adapt to the width offered by -its own parent. Dot shorthand keeps nested track and breakpoint declarations -compact: +`GridBox` uses fixed and fractional columns plus vertical auto rows, and can +adapt to the width offered by its own parent. Dot shorthand keeps nested track +and breakpoint declarations compact. Omit `autoRows` (or set `.autoRows(.auto())`) +when row height should follow the tallest child: ```dart final GridBoxStyler dashboardGrid = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)) .onConstraints( .maxWidth(720), .equalColumns(1).gap(12), diff --git a/packages/mix/doc/grid-layout.md b/packages/mix/doc/grid-layout.md index 21bf24126..1c20d925f 100644 --- a/packages/mix/doc/grid-layout.md +++ b/packages/mix/doc/grid-layout.md @@ -1,8 +1,9 @@ # Grid layout -`GridBox` arranges children in row-major order using fixed and fractional -tracks. Its style supports ordinary Mix variants and modifiers, plus -`onConstraints` for layout decisions based on the Grid's own available space. +`GridBox` arranges children in row-major order using fixed, fractional, and +vertical auto tracks. Its style supports ordinary Mix variants and modifiers, +plus `onConstraints` for layout decisions based on the Grid's own available +space. ## Basic usage @@ -12,16 +13,19 @@ entry point, then chain the remaining geometry: ```dart final GridBoxStyler style = .equalColumns(3) .gap(16) - .autoRows(.fixed(160)); + .autoRows(.auto()); GridBox(style: style, children: cards); ``` -`GridTrack.fixed(size)` keeps its logical-pixel size. `GridTrack.fr(fraction)` -receives that fraction of the free space left after fixed tracks and gaps. -For example, with 300 pixels of remaining space, `[.fr(2), .fr(1)]` produces -tracks of 200 and 100 pixels. Fractional tracks require a bounded parent extent -on their axis. Use `columns` directly when tracks are intentionally mixed: +`GridTrack.fixed(size)` keeps its logical-pixel size and is a hard constraint: +children in a fixed row are stretched or clipped to that height. `GridTrack.fr(fraction)` +receives that fraction of the free space left after fixed tracks, auto tracks, +and gaps. For example, with 300 pixels of remaining space, `[.fr(2), .fr(1)]` +produces tracks of 200 and 100 pixels. Fractional tracks require a bounded +parent extent on their axis. `GridTrack.auto()` is vertical-only: the row +sizes to its tallest child's natural height at the resolved column width. +Use `columns` directly when tracks are intentionally mixed: ```dart final GridBoxStyler sidebarAndContent = .columns([ @@ -38,7 +42,6 @@ the bounded maximum size offered to this Grid: ```dart final GridBoxStyler cardGrid = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)) .onConstraints( .maxWidth(760), .equalColumns(2).gap(12), @@ -69,22 +72,41 @@ Two GridBoxes on the same screen can therefore select different Children fill columns from left to right, then continue on the next row. Provide explicit `rows` for known row geometry, or `autoRows` for each repeated -row needed beyond the explicit list: +row needed beyond the explicit list. Omitted `autoRows` defaults to +`GridTrack.auto()`, so a two-column Grid with no row declaration sizes each +implicit row to its tallest child: ```dart -final GridBoxStyler gallery = .equalColumns(2).rows([ +final GridBoxStyler gallery = .equalColumns(2).gap(12); + +final GridBoxStyler mixed = .equalColumns(2).rows([ .fixed(180), -]).autoRows(.fixed(180)).columnGap(12).rowGap(12); +]).autoRows(.auto()).columnGap(12).rowGap(12); ``` -With five children and two columns, the example needs three rows: the first -uses the explicit 180-pixel row and the next two repeat `autoRows`. When -`rows` is empty, every required row uses `autoRows`. +With five children and two columns, `mixed` needs three rows: the first uses +the explicit 180-pixel row and the next two repeat `autoRows`. When `rows` is +empty, every required row uses `autoRows` (or `auto` when it is omitted). + +Use `GridTrack.auto()` — or omit `autoRows` — in a vertical +`SingleChildScrollView` when child heights are unknown. Auto-row children are +measured at their column width, then laid out again into the stretched cell so +shorter siblings fill the row. That extra measure pass runs only for children +in auto rows; explicit fixed/`fr` Grids still lay each child out once. + +Nesting compounds that cost. Each auto-row level measures its subtree and then +lays it out again, so the passes multiply rather than add: a leaf inside one +auto Grid is laid out twice, and inside three nested auto Grids it is laid out +eight times. For deep hierarchies, prefer a single Grid, or give the inner +levels fixed rows once their heights are known. -If children require more rows than declared and `autoRows` is absent, GridBox -reports an actionable layout error rather than guessing a content-sizing rule. -Use fixed rows on an unbounded vertical axis such as `SingleChildScrollView`. -Fractional rows and fractional `autoRows` require bounded height. +Fixed rows stay hard heights. Fractional rows and fractional `autoRows` still +require bounded height. Auto rows require children with a finite natural +height; `Expanded`, `Spacer`, or another expanding child inside an auto row +in a scroll view is an error. + +`GridTrack.auto()` is rejected on `columns`. Content-sized columns need a +separate two-axis design and are not part of this API. ## Design tokens @@ -151,6 +173,7 @@ Animation compatibility is positional: - fixed tracks interpolate with fixed tracks; - fractional tracks interpolate with fractional tracks; +- auto tracks stay compatible with auto tracks; - the two track lists must keep the same length and track kinds; - compatible `autoRows`, `columnGap`, and `rowGap` values interpolate too. @@ -179,11 +202,27 @@ contained: final GridBoxStyler clipped = .clipBehavior(.hardEdge); ``` +Auto rows are diagnosed the same way. Measured row heights that add up to more +than a bounded parent offers overflow the Grid's box and report the same +indicator, so putting tall content in a bounded parent is still visible rather +than silent. + +A child that outgrows its own cell is not diagnosed. The Grid compares its +total track extent against the space the parent offered; it never asks whether +an individual child fits the cell it was given. A fixed track is therefore a +hard constraint in exactly the way a tight `SizedBox` is, and content taller +than that track is constrained without a warning. This is deliberate: probing +every fixed cell for its natural height would cost a speculative measure pass +per child and would break children that require a bounded height. Use `auto` +rows whenever the content height is unknown, and keep `.fixed(...)` for cells +where constraining the child is the intent. + ## Current track model -GridBox intentionally supports fixed and fractional tracks with row-major -auto-placement. Content-sized tracks, spans, named areas, direction-aware -placement, and baseline alignment are not part of the current API. +GridBox supports fixed and fractional tracks on both axes and content-sized +`auto` tracks on rows only, with row-major auto-placement. Content-sized +columns, spans, named areas, direction-aware placement, and baseline alignment +are not part of the current API. Run the card, dashboard, gallery, and animation examples from `packages/mix/example`: diff --git a/packages/mix/example/.gitignore b/packages/mix/example/.gitignore new file mode 100644 index 000000000..02a517ea2 --- /dev/null +++ b/packages/mix/example/.gitignore @@ -0,0 +1 @@ +test/failures/ diff --git a/packages/mix/example/README.md b/packages/mix/example/README.md index e4ce2fb4c..5486ec7bf 100644 --- a/packages/mix/example/README.md +++ b/packages/mix/example/README.md @@ -24,7 +24,6 @@ rather than the viewport: ```dart final GridBoxStyler cardGrid = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)) .onConstraints( .maxWidth(760), .equalColumns(2).gap(12), @@ -45,7 +44,8 @@ columns to one. Compact GridBox dashboard

-The same track model handles repeated product cards and a denser media gallery: +The card catalog omits `autoRows` so implicit rows size to unequal copy. The +media gallery keeps fixed automatic rows for a dense, even tile height:

Wide GridBox card catalog diff --git a/packages/mix/example/lib/grid_example.dart b/packages/mix/example/lib/grid_example.dart index 7c8dcf73b..9724888d6 100644 --- a/packages/mix/example/lib/grid_example.dart +++ b/packages/mix/example/lib/grid_example.dart @@ -444,50 +444,58 @@ class CatalogGridPreview extends StatelessWidget { Widget build(BuildContext context) { final GridBoxStyler style = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)) .onConstraints(.maxWidth(760), .equalColumns(2).gap(12)) - .onConstraints( - .maxWidth(520), - .equalColumns(1).gap(10).autoRows(.fixed(190)), - ); + .onConstraints(.maxWidth(520), .equalColumns(1).gap(10)); return GridBox( key: const Key('catalog-grid'), style: style, children: const [ _ProductCard( + key: Key('catalog-card-0'), 'Canvas tote', r'$48', + 'A roomy everyday bag.', Icons.shopping_bag_rounded, Color(0xFFE9E6FF), ), _ProductCard( + key: Key('catalog-card-1'), 'Desk lamp', r'$72', + 'Adjustable arm and a warm-dim LED. Built for late editing sessions when the rest of the room has gone dark.', Icons.light_rounded, Color(0xFFFFE9D8), ), _ProductCard( + key: Key('catalog-card-2'), 'Travel mug', r'$32', + 'Keeps coffee hot through a standup.', Icons.coffee_rounded, Color(0xFFDDF4EE), ), _ProductCard( + key: Key('catalog-card-3'), 'Studio clock', r'$64', + 'Quiet sweep, high-contrast face.', Icons.schedule_rounded, Color(0xFFDDEBFA), ), _ProductCard( + key: Key('catalog-card-4'), 'Wool throw', r'$96', + 'Heavyweight merino for the couch.', Icons.bed_rounded, Color(0xFFF6E2EB), ), _ProductCard( + key: Key('catalog-card-5'), 'Plant stand', r'$58', + 'Three-tier oak riser.', Icons.eco_rounded, Color(0xFFE4F2D8), ), @@ -497,10 +505,18 @@ class CatalogGridPreview extends StatelessWidget { } class _ProductCard extends StatelessWidget { - const _ProductCard(this.name, this.price, this.icon, this.tint); + const _ProductCard( + this.name, + this.price, + this.blurb, + this.icon, + this.tint, { + super.key, + }); final String name; final String price; + final String blurb; final IconData icon; final Color tint; @@ -508,6 +524,7 @@ class _ProductCard extends StatelessWidget { Widget build(BuildContext context) { return _CardSurface( child: Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( @@ -519,15 +536,15 @@ class _ProductCard extends StatelessWidget { ), child: Icon(icon, color: const Color(0xFF3C3D4A)), ), - const Spacer(), + const SizedBox(height: 16), Text( name, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w700), ), const SizedBox(height: 4), - const Text( - 'Essential collection', - style: TextStyle(color: Color(0xFF77798A), fontSize: 12), + Text( + blurb, + style: const TextStyle(color: Color(0xFF77798A), fontSize: 12), ), const SizedBox(height: 12), Row( diff --git a/packages/mix/example/test/goldens/grid_catalog_compact.png b/packages/mix/example/test/goldens/grid_catalog_compact.png index 880faeabece3d2499de43bf7f5944449429856ca..a50877f4a2cd80b0094e60a3ffbb5ba8e68e32f0 100644 GIT binary patch literal 74177 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ΞRg#*BymcQxT8MP{a#s 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≀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 UInt{PC0@KzQ`SP{U$+YSA8HokS^xk5 diff --git a/packages/mix/example/test/grid_box_example_test.dart b/packages/mix/example/test/grid_box_example_test.dart index 86d24595f..ff479a080 100644 --- a/packages/mix/example/test/grid_box_example_test.dart +++ b/packages/mix/example/test/grid_box_example_test.dart @@ -28,6 +28,12 @@ void main() { await tester.tap(find.text('Compact')); await tester.pumpAndSettle(); expect(tester.getSize(find.byKey(const Key('catalog-grid'))).width, 334); + expect( + tester.getSize(find.byKey(const Key('catalog-card-1'))).height, + greaterThan( + tester.getSize(find.byKey(const Key('catalog-card-0'))).height, + ), + ); await tester.tap(find.text('Media gallery')); await tester.pumpAndSettle(); @@ -38,6 +44,40 @@ void main() { expect(find.byKey(const Key('animated-grid')), findsOneWidget); }); + testWidgets( + 'catalog rows follow unequal card content instead of one height', + (tester) async { + await tester.binding.setSurfaceSize(const Size(1200, 900)); + addTearDown(() => tester.binding.setSurfaceSize(null)); + + await tester.pumpWidget( + const MaterialApp( + home: Material( + child: Center( + child: SizedBox(width: 1120, child: CatalogGridPreview()), + ), + ), + ), + ); + + final rowZero = tester + .getSize(find.byKey(const Key('catalog-card-0'))) + .height; + final rowOne = tester + .getSize(find.byKey(const Key('catalog-card-3'))) + .height; + expect(rowZero, isNot(rowOne)); + expect( + tester.getSize(find.byKey(const Key('catalog-card-1'))).height, + rowZero, + ); + expect( + tester.getSize(find.byKey(const Key('catalog-card-4'))).height, + rowOne, + ); + }, + ); + testWidgets('animation example interpolates tracks, rows, and gaps', ( tester, ) async { diff --git a/packages/mix/lib/src/layout/grid_box.dart b/packages/mix/lib/src/layout/grid_box.dart index 06f9dfb51..c2102014b 100644 --- a/packages/mix/lib/src/layout/grid_box.dart +++ b/packages/mix/lib/src/layout/grid_box.dart @@ -39,6 +39,9 @@ class GridBoxStyler extends MixStyler final List? $rows; /// Unresolved track repeated for rows required beyond [$rows]. + /// + /// `null` means no override. Resolved geometry defaults omitted automatic + /// rows to [GridTrack.auto]. final GridTrack? $autoRows; /// Unresolved logical-pixel gap between columns. @@ -95,8 +98,10 @@ class GridBoxStyler extends MixStyler /// Creates a style that repeats [autoRows] for undeclared rows. /// /// Children are placed row-major. Each row needed beyond [rows] uses this - /// track. A fixed track works on an unbounded vertical axis, such as a - /// vertical scroll view; a fractional track requires bounded height. + /// track. Omitted [autoRows] defaults to [GridTrack.auto] on the complete + /// resolved geometry, so implicit rows size to their tallest child. A + /// fixed track is a hard height; a fractional track requires bounded + /// height. factory GridBoxStyler.autoRows(GridTrack autoRows) => GridBoxStyler(autoRows: autoRows); @@ -143,6 +148,9 @@ class GridBoxStyler extends MixStyler merge(GridBoxStyler(rows: value)); /// Sets the track repeated for each row required beyond explicit [rows]. + /// + /// Use [GridTrack.auto] for unknown content height. Omit this method to + /// get the same default on implicit rows. GridBoxStyler autoRows(GridTrack value) => merge(GridBoxStyler(autoRows: value)); @@ -184,11 +192,12 @@ class GridBoxStyler extends MixStyler /// Adds implicit animation to compatible Grid geometry changes. /// - /// Fixed sizes, fractional weights, row tracks, `autoRows`, and gaps - /// interpolate when their topology is compatible. Track-count or track-kind - /// changes, clipping, and constraint patches snap at the midpoint. A local - /// [onConstraints] branch switch remains immediate because it occurs during - /// layout without producing a new resolved style. + /// Fixed sizes, fractional weights, row tracks, compatible `autoRows`, and + /// gaps interpolate when their topology is compatible. Auto-to-auto stays + /// constant. Track-count or track-kind changes, clipping, and constraint + /// patches snap at the midpoint. A local [onConstraints] branch switch + /// remains immediate because it occurs during layout without producing a + /// new resolved style. @override GridBoxStyler animate(AnimationConfig value) => merge(GridBoxStyler(animation: value)); @@ -310,6 +319,7 @@ GridTrack _resolveGridTrack(BuildContext context, GridTrack track) { FrGridTrack(:final fraction) => GridTrack.fr( _resolveGridDouble(context, fraction), ), + AutoGridTrack() => track, }; } diff --git a/packages/mix/lib/src/layout/grid_box_spec.dart b/packages/mix/lib/src/layout/grid_box_spec.dart index 51ecd0566..23bed9370 100644 --- a/packages/mix/lib/src/layout/grid_box_spec.dart +++ b/packages/mix/lib/src/layout/grid_box_spec.dart @@ -127,6 +127,9 @@ final class GridBoxSpec extends Spec with Diagnosticable { final List rows; /// Track repeated for each row required beyond [rows]. + /// + /// `null` means no override. Resolved geometry defaults omitted automatic + /// rows to [GridTrack.auto]. final GridTrack? autoRows; /// Logical-pixel gap between adjacent columns. @@ -205,11 +208,12 @@ final class GridBoxSpec extends Spec with Diagnosticable { /// Interpolates compatible Grid geometry toward [other]. /// - /// Fixed tracks interpolate with fixed tracks and fractional tracks with - /// fractional tracks when their lists have the same length and kinds. - /// Gaps also interpolate. Incompatible track lists, nullable or mismatched - /// [autoRows], [clipBehavior], and [constraintBranches] switch at `t = 0.5`. - /// Progress outside the `0...1` interval is clamped so geometry stays valid. + /// Fixed tracks interpolate with fixed tracks, fractional tracks with + /// fractional tracks, and auto tracks with auto tracks when their lists + /// have the same length and kinds. Gaps also interpolate. Incompatible + /// track lists, nullable or mismatched [autoRows], [clipBehavior], and + /// [constraintBranches] switch at `t = 0.5`. Progress outside the `0...1` + /// interval is clamped so geometry stays valid. @override GridBoxSpec lerp(GridBoxSpec? other, double t) { if (other == null) return this; @@ -297,6 +301,7 @@ bool _gridTracksAreCompatible(GridTrack start, GridTrack end) { return switch ((start, end)) { (FixedGridTrack(), FixedGridTrack()) => true, (FrGridTrack(), FrGridTrack()) => true, + (AutoGridTrack(), AutoGridTrack()) => true, _ => false, }; } @@ -313,6 +318,7 @@ GridTrack _lerpCompatibleGridTrack(GridTrack start, GridTrack end, double t) { FrGridTrack(fraction: final endFraction), ) => GridTrack.fr(ui.lerpDouble(startFraction, endFraction, t)!), + (AutoGridTrack(), AutoGridTrack()) => start, _ => throw StateError('Grid track interpolation requires matching types.'), }; } @@ -328,9 +334,9 @@ void _validateGridSpecGeometry(GridBoxSpec spec) { } _validateTracks(columns, axisLabel: 'columns'); - _validateTracks(spec.rows, axisLabel: 'rows'); + _validateTracks(spec.rows, axisLabel: 'rows', allowAuto: true); if (spec.autoRows case final track?) { - _validateTracks([track], axisLabel: 'autoRows'); + _validateTracks([track], axisLabel: 'autoRows', allowAuto: true); } _validateGap(spec.columnGap, label: 'columnGap'); _validateGap(spec.rowGap, label: 'rowGap'); @@ -371,10 +377,14 @@ void _validateGridSpecGeometry(GridBoxSpec spec) { _validateTracks(patchColumns, axisLabel: 'patch.columns'); } if (patchRows != null) { - _validateTracks(patchRows, axisLabel: 'patch.rows'); + _validateTracks(patchRows, axisLabel: 'patch.rows', allowAuto: true); } if (patchAutoRows != null) { - _validateTracks([patchAutoRows], axisLabel: 'patch.autoRows'); + _validateTracks( + [patchAutoRows], + axisLabel: 'patch.autoRows', + allowAuto: true, + ); } if (patchColumnGap != null) { _validateGap(patchColumnGap, label: 'patch.columnGap'); @@ -464,7 +474,11 @@ GridLayoutPatch _snapshotPatch(GridLayoutPatch patch) { ); } -void _validateTracks(List tracks, {required String axisLabel}) { +void _validateTracks( + List tracks, { + required String axisLabel, + bool allowAuto = false, +}) { for (var i = 0; i < tracks.length; i++) { final track = tracks[i]; switch (track) { @@ -489,6 +503,18 @@ void _validateTracks(List tracks, {required String axisLabel}) { ErrorHint('Use GridTrack.fr with a finite fraction > 0.'), ]); } + case AutoGridTrack(): + if (!allowAuto) { + throw FlutterError.fromParts([ + ErrorSummary('GridTrack.auto() is only valid for rows.'), + ErrorDescription('$axisLabel[$i] used GridTrack.auto().'), + ErrorHint( + 'GridTrack.auto() is vertical-only. Use it in rows or autoRows ' + 'after column widths are known. Content-sized columns are not ' + 'supported.', + ), + ]); + } } } } diff --git a/packages/mix/lib/src/layout/grid_track.dart b/packages/mix/lib/src/layout/grid_track.dart index 795d7be21..161f3675a 100644 --- a/packages/mix/lib/src/layout/grid_track.dart +++ b/packages/mix/lib/src/layout/grid_track.dart @@ -2,8 +2,20 @@ import 'package:flutter/foundation.dart'; /// How a grid track is sized. /// -/// Grid currently supports fixed and fractional tracks. Content-sized tracks +/// Rows accept fixed, fractional, and content-sized [GridTrack.auto] tracks. +/// Columns accept only fixed and fractional tracks; content-sized columns /// are intentionally outside this API. +/// +/// One type covers both axes, so "auto is rows-only" is a runtime rule +/// (see `_validateTracks` in `grid_box_spec.dart`) rather than a compile-time +/// one. Splitting this into row and column hierarchies was considered and +/// rejected: it would not remove the equivalent check in the wire codec — +/// JSON is untyped, so the schema must reject `auto` under `columns` +/// regardless of the Dart type — and the factories below have static type +/// `GridTrack`, so axis-specific lists would force duplicate factories or +/// give up the dot-shorthand (`.columns([.fr(1)])`) this API is built around. +/// The trade is one runtime throw against those two costs; do not "simplify" +/// this into a split without re-checking both. @immutable sealed class GridTrack { /// Creates the base value for a concrete Grid track. @@ -18,11 +30,16 @@ sealed class GridTrack { /// A track with [fraction] shares of the remaining free space. /// - /// Remaining space is calculated after fixed tracks and gaps. For example, - /// `fr(2)` receives twice as much remaining space as `fr(1)`. [fraction] - /// must resolve to a finite value greater than zero, and the track's axis - /// must be bounded. + /// Remaining space is calculated after fixed tracks, auto tracks, and gaps. + /// For example, `fr(2)` receives twice as much remaining space as `fr(1)`. + /// [fraction] must resolve to a finite value greater than zero, and the + /// track's axis must be bounded. const factory GridTrack.fr(double fraction) = FrGridTrack; + + /// A vertical track sized to the tallest child assigned to that row. + /// + /// Valid only in `rows` and `autoRows`. Column tracks reject this kind. + const factory GridTrack.auto() = AutoGridTrack; } /// Track with a fixed size in logical pixels. @@ -71,3 +88,20 @@ final class FrGridTrack extends GridTrack { @override int get hashCode => fraction.hashCode; } + +/// Vertical track sized to the tallest assigned child's natural height. +@immutable +final class AutoGridTrack extends GridTrack { + /// Creates a content-sized row track. + const AutoGridTrack(); + + @override + bool operator ==(Object other) => + identical(this, other) || other is AutoGridTrack; + + @override + String toString() => 'GridTrack.auto()'; + + @override + int get hashCode => runtimeType.hashCode; +} diff --git a/packages/mix/lib/src/layout/internal/grid_geometry.dart b/packages/mix/lib/src/layout/internal/grid_geometry.dart index d475fa4b7..9085c8762 100644 --- a/packages/mix/lib/src/layout/internal/grid_geometry.dart +++ b/packages/mix/lib/src/layout/internal/grid_geometry.dart @@ -7,11 +7,14 @@ import '../grid_track.dart'; import 'grid_validation.dart'; /// Geometry after branch selection and before track sizing and placement. +/// +/// Omitted [autoRows] becomes [GridTrack.auto] here. Styler and patch fields +/// stay nullable so a missing value still means “no override.” @immutable final class GridResolvedGeometry { final List columns; final List rows; - final GridTrack? autoRows; + final GridTrack autoRows; final double columnGap; final double rowGap; @@ -61,7 +64,7 @@ extension GridBoxSpecGeometry on GridBoxSpec { return GridResolvedGeometry( columns: resolvedColumns, rows: resolvedRows, - autoRows: resolvedAutoRows, + autoRows: resolvedAutoRows ?? const GridTrack.auto(), columnGap: resolvedColumnGap, rowGap: resolvedRowGap, ); diff --git a/packages/mix/lib/src/layout/internal/grid_validation.dart b/packages/mix/lib/src/layout/internal/grid_validation.dart index 40ae032e3..f131bcf40 100644 --- a/packages/mix/lib/src/layout/internal/grid_validation.dart +++ b/packages/mix/lib/src/layout/internal/grid_validation.dart @@ -8,6 +8,7 @@ String gridTracksToString(List tracks) { switch (track) { FixedGridTrack(:final size) => 'GridTrack.fixed($size)', FrGridTrack(:final fraction) => 'GridTrack.fr($fraction)', + AutoGridTrack() => 'GridTrack.auto()', }, ].join(', '); } @@ -38,7 +39,7 @@ void rejectFractionalGridTracksOnUnboundedAxis({ '• Replace fractional tracks with GridTrack.fixed on this axis.\n' '• Place the grid under a bounded constraint ' '(SizedBox, Expanded in a bounded Flex, etc.).\n' - '• Content-sized tracks are not supported by GridBox.', + '• Use GridTrack.auto() for content-sized rows (not columns).', ), ]); } diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 44fabecc1..9b69a1a62 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -1,3 +1,5 @@ +import 'dart:math' as math; + import 'package:flutter/foundation.dart' show precisionErrorTolerance; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; @@ -7,22 +9,27 @@ import 'grid_track.dart'; import 'internal/grid_geometry.dart'; import 'internal/grid_validation.dart'; -/// Computes concrete track sizes for fixed + fr tracks under a free-space axis. +/// Computes concrete track sizes for fixed, auto, and fr tracks. /// -/// Shared by live layout and dry layout so both paths return the same sizes. +/// Auto tracks contribute [autoExtents] at the matching index, then remaining +/// free space is shared by fractional tracks. Shared by live layout, dry +/// layout, and the fixed/fr fast path. List computeTrackSizes({ required List tracks, required double freeSpace, required double gap, + List? autoExtents, }) { if (tracks.isEmpty) return const []; var fixedSum = 0.0; var frSum = 0.0; - for (final track in tracks) { - switch (track) { + for (var index = 0; index < tracks.length; index++) { + switch (tracks[index]) { case FixedGridTrack(:final size): fixedSum += size; + case AutoGridTrack(): + fixedSum += _autoExtentAt(autoExtents, index); case FrGridTrack(:final fraction): frSum += fraction; } @@ -36,14 +43,32 @@ List computeTrackSizes({ final frUnit = frSum > 0 ? remaining / frSum : 0.0; return [ - for (final track in tracks) - switch (track) { + for (var index = 0; index < tracks.length; index++) + switch (tracks[index]) { FixedGridTrack(:final size) => size, + AutoGridTrack() => _autoExtentAt(autoExtents, index), FrGridTrack(:final fraction) => frUnit * fraction, }, ]; } +double _autoExtentAt(List? autoExtents, int index) { + if (autoExtents == null || index >= autoExtents.length) { + throw FlutterError.fromParts([ + ErrorSummary('GridTrack.auto() requires a measured row extent.'), + ErrorDescription( + 'Track $index is auto but no measured height was provided.', + ), + ErrorHint( + 'Measure auto-row children at their column width before resolving ' + 'row sizes.', + ), + ]); + } + + return autoExtents[index]; +} + /// Total size along an axis for the given track sizes and gap. double axisExtent(List sizes, double gap) { if (sizes.isEmpty) return 0; @@ -102,34 +127,28 @@ class GridLayoutResult { }); } -/// Computes grid geometry without touching children. +/// Computes grid geometry from tracks, gaps, and optional auto-row extents. /// -/// Children are placed row-major into a matrix of [columns] × enough rows. -/// Track sizes use only fixed/fr rules and parent constraints — no content -/// measurement in the currently supported track model. +/// Children are placed row-major into a matrix of [columns] × [rows]. +/// [rows] must already include implicit tracks. Callers that grow rows from +/// [childCount] resolve that list first so live and shared layout cannot +/// disagree. When no row is [GridTrack.auto], sizes use only fixed/fr rules +/// and parent constraints. Auto rows consume [autoRowHeights] at the matching +/// row index before remaining bounded height is given to fractional rows. /// -/// When [childCount] is 0 and [rows] is empty, no auto rows are produced. -/// When children exceed the explicit row capacity, [autoRows] provides the -/// repeated track used for every additional row. +/// When [childCount] is 0 and [rows] is empty, no automatic rows are produced. GridLayoutResult computeGridLayout({ required BoxConstraints constraints, required List columns, required List rows, - GridTrack? autoRows, required double columnGap, required double rowGap, required int childCount, + List? autoRowHeights, }) { assert(columns.isNotEmpty, 'Grid requires at least one column track.'); final colCount = columns.length; - final effectiveRows = _resolveEffectiveRows( - constraints: constraints, - columnCount: colCount, - rows: rows, - autoRows: autoRows, - childCount: childCount, - ); // Resolve free space: prefer max constraint when finite; else min. final freeWidth = constraints.hasBoundedWidth @@ -145,9 +164,10 @@ GridLayoutResult computeGridLayout({ gap: columnGap, ); final rowSizes = computeTrackSizes( - tracks: effectiveRows, + tracks: rows, freeSpace: freeHeight, gap: rowGap, + autoExtents: autoRowHeights, ); final intrinsicWidth = axisExtent(columnSizes, columnGap); @@ -180,31 +200,18 @@ GridLayoutResult computeGridLayout({ ); } -List _resolveEffectiveRows({ +/// Expands explicit [rows] with [autoRows] until every child has a row. +List _resolveEffectiveGridRows({ required BoxConstraints constraints, required int columnCount, required List rows, - required GridTrack? autoRows, + required GridTrack autoRows, required int childCount, }) { final requiredRowCount = childCount == 0 ? 0 : ((childCount + columnCount - 1) ~/ columnCount); final missingRowCount = requiredRowCount - rows.length; - if (missingRowCount > 0 && autoRows == null) { - throw FlutterError.fromParts([ - ErrorSummary('Grid auto-placement requires an autoRows track.'), - ErrorDescription( - '$childCount children across $columnCount columns require ' - '$requiredRowCount rows, but only ${rows.length} explicit rows were ' - 'provided.', - ), - ErrorHint( - 'Provide enough explicit rows or set autoRows to the GridTrack used ' - 'for each additional row.', - ), - ]); - } if (missingRowCount > 0 && autoRows is FrGridTrack && !constraints.hasBoundedHeight) { @@ -217,26 +224,25 @@ List _resolveEffectiveRows({ 'but autoRows is $autoRows.', ), ErrorHint( - 'Use GridTrack.fixed for autoRows or place the grid under a bounded ' - 'height.', + 'Use GridTrack.fixed or GridTrack.auto() for autoRows, or place the ' + 'grid under a bounded height.', ), ]); } - final effectiveRows = [ + return [ ...rows, - if (missingRowCount > 0) ...List.filled(missingRowCount, autoRows!), + if (missingRowCount > 0) ...List.filled(missingRowCount, autoRows), ]; - - return effectiveRows; } /// Multi-child render object for [GridBoxSpec]. /// -/// Supports fixed + fr tracks, row/column gaps, row-major auto-placement, and -/// render-time constraint branch selection via [GridBoxSpec]. Fixed-track -/// overflow is diagnosed on both axes and optionally clipped by the spec. -/// Excludes spans, named areas, content-sized tracks, RTL, and baseline. +/// Supports fixed, fractional, and vertical auto tracks, row/column gaps, +/// row-major auto-placement, and render-time constraint branch selection via +/// [GridBoxSpec]. Fixed-track overflow is diagnosed on both axes and +/// optionally clipped by the spec. Excludes spans, named areas, content-sized +/// columns, RTL, and baseline. class RenderMixGrid extends RenderBox with ContainerRenderObjectMixin, @@ -252,24 +258,96 @@ class RenderMixGrid extends RenderBox addAll(children); } - GridLayoutResult _compute(BoxConstraints constraints) { + GridLayoutResult _compute( + BoxConstraints constraints, { + required ChildLayouter measureChild, + }) { final geometry = _spec.resolveGeometryForConstraints(constraints); + final effectiveRows = _resolveEffectiveGridRows( + constraints: constraints, + columnCount: geometry.columns.length, + rows: geometry.rows, + autoRows: geometry.autoRows, + childCount: childCount, + ); + final autoRowHeights = _hasAutoTrack(effectiveRows) + ? _measureAutoRowHeights( + constraints: constraints, + geometry: geometry, + effectiveRows: effectiveRows, + measureChild: measureChild, + ) + : null; return computeGridLayout( constraints: constraints, columns: geometry.columns, - rows: geometry.rows, - autoRows: geometry.autoRows, + rows: effectiveRows, columnGap: geometry.columnGap, rowGap: geometry.rowGap, childCount: childCount, + autoRowHeights: autoRowHeights, + ); + } + + List _measureAutoRowHeights({ + required BoxConstraints constraints, + required GridResolvedGeometry geometry, + required List effectiveRows, + required ChildLayouter measureChild, + }) { + final freeWidth = constraints.hasBoundedWidth + ? constraints.maxWidth + : constraints.minWidth; + final columnSizes = computeTrackSizes( + tracks: geometry.columns, + freeSpace: freeWidth, + gap: geometry.columnGap, ); + final heights = List.filled(effectiveRows.length, 0); + final columnCount = geometry.columns.length; + + var index = 0; + var child = firstChild; + while (child != null) { + final row = index ~/ columnCount; + if (row < effectiveRows.length && effectiveRows[row] is AutoGridTrack) { + final column = index % columnCount; + final measured = _measureAutoRowChild( + child: child, + row: row, + constraints: BoxConstraints.tightFor(width: columnSizes[column]), + measureChild: measureChild, + ); + heights[row] = math.max(heights[row], measured.height); + } + child = (child.parentData! as MultiChildLayoutParentData).nextSibling; + index++; + } + + return heights; + } + + Size _measureAutoRowChild({ + required RenderBox child, + required int row, + required BoxConstraints constraints, + required ChildLayouter measureChild, + }) { + final measured = measureChild(child, constraints); + if (!measured.height.isFinite) { + throw _autoRowNeedsFiniteHeight(row, 'height ${measured.height}'); + } + + return measured; } - /// Intrinsic extent for fixed-only tracks after branch selection. + /// Intrinsic extent after branch selection. /// /// Fractional tracks on the queried axis throw the same actionable - /// [FlutterError] as unbounded layout (no LayoutBuilder cascade). + /// [FlutterError] as unbounded layout (no LayoutBuilder cascade). Vertical + /// auto rows use each child's max intrinsic height at the resolved column + /// width. double _computeIntrinsicExtent({ required Axis axis, required double crossExtent, @@ -285,7 +363,7 @@ class RenderMixGrid extends RenderBox final geometry = _spec.resolveGeometryForConstraints(constraints); final effectiveTracks = axis == .horizontal ? geometry.columns - : _resolveEffectiveRows( + : _resolveEffectiveGridRows( constraints: constraints, columnCount: geometry.columns.length, rows: geometry.rows, @@ -299,11 +377,24 @@ class RenderMixGrid extends RenderBox constraints: constraints, ); + if (axis == .vertical && _hasAutoTrack(effectiveTracks)) { + return _computeAutoRowIntrinsicHeight( + geometry: geometry, + effectiveRows: effectiveTracks, + width: crossExtent, + ); + } + var sum = 0.0; for (final track in effectiveTracks) { switch (track) { case FixedGridTrack(:final size): sum += size; + // An auto track never reaches here — the branch above returns first, + // and columns reject auto during validation. The case exists only to + // satisfy the sealed exhaustiveness check. A fractional track has no + // intrinsic contribution because its size comes from free space. + case AutoGridTrack(): case FrGridTrack(): break; } @@ -316,6 +407,50 @@ class RenderMixGrid extends RenderBox return sum; } + double _computeAutoRowIntrinsicHeight({ + required GridResolvedGeometry geometry, + required List effectiveRows, + required double width, + }) { + final columnSizes = computeTrackSizes( + tracks: geometry.columns, + freeSpace: width.isFinite ? width : 0.0, + gap: geometry.columnGap, + ); + final columnCount = geometry.columns.length; + final autoRowHeights = List.filled(effectiveRows.length, 0); + + // Mirrors _measureAutoRowHeights so the intrinsic answer and the laid-out + // size are derived the same way; only the per-child measurement differs. + var index = 0; + var child = firstChild; + while (child != null) { + final row = index ~/ columnCount; + if (row < effectiveRows.length && effectiveRows[row] is AutoGridTrack) { + final column = index % columnCount; + autoRowHeights[row] = math.max( + autoRowHeights[row], + child.getMaxIntrinsicHeight(columnSizes[column]), + ); + } + child = (child.parentData! as MultiChildLayoutParentData).nextSibling; + index++; + } + + final rowExtents = [ + for (var row = 0; row < effectiveRows.length; row++) + switch (effectiveRows[row]) { + FixedGridTrack(:final size) => size, + AutoGridTrack() => autoRowHeights[row], + // Fractional rows draw from free space, which an intrinsic query + // has none of. + FrGridTrack() => 0.0, + }, + ]; + + return axisExtent(rowExtents, geometry.rowGap); + } + bool get _hasVisualOverflow => _contentSize.width - size.width > precisionErrorTolerance || _contentSize.height - size.height > precisionErrorTolerance; @@ -362,12 +497,18 @@ class RenderMixGrid extends RenderBox @override Size computeDryLayout(BoxConstraints constraints) { - return _compute(constraints).size; + return _compute( + constraints, + measureChild: ChildLayoutHelper.dryLayoutChild, + ).size; } @override void performLayout() { - final result = _compute(constraints); + final result = _compute( + constraints, + measureChild: ChildLayoutHelper.layoutChild, + ); size = result.size; _contentSize = result.contentSize; assert(result.cells.length == childCount); @@ -427,8 +568,8 @@ class RenderMixGrid extends RenderBox 'Clip.none deliberately leaves overflow visible.', ), ErrorHint( - 'Content-sized tracks and implicit content-sized rows are not ' - 'supported by GridBox.', + 'Use GridTrack.auto() for unknown content height. Fixed tracks are ' + 'hard constraints and do not grow to fit overflowing children.', ), ], ); @@ -456,6 +597,26 @@ class RenderMixGrid extends RenderBox } } +bool _hasAutoTrack(Iterable tracks) => + tracks.any((track) => track is AutoGridTrack); + +FlutterError _autoRowNeedsFiniteHeight(int row, Object cause) { + return FlutterError.fromParts([ + ErrorSummary('Grid auto rows require children with a finite height.'), + ErrorDescription( + 'A child in row $row could not determine a finite height under ' + 'unbounded vertical constraints.', + ), + ErrorDescription('$cause'), + ErrorHint( + 'Auto rows measure children at their column width with a loose ' + 'height. Use finite-height content such as text or intrinsic boxes. ' + 'Do not place Expanded, Spacer, or fractional-height layout inside ' + 'an auto row in a vertical scroll view.', + ), + ]); +} + /// Internal widget host for [RenderMixGrid]. class MixGrid extends MultiChildRenderObjectWidget { const MixGrid({super.key, required this.spec, super.children}); diff --git a/packages/mix/test/src/layout/grid_box_test.dart b/packages/mix/test/src/layout/grid_box_test.dart index 1be4c6fc7..0dd4fcffe 100644 --- a/packages/mix/test/src/layout/grid_box_test.dart +++ b/packages/mix/test/src/layout/grid_box_test.dart @@ -1,5 +1,7 @@ // ignore_for_file: implementation_imports +import 'dart:math' as math; + import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -52,8 +54,11 @@ void main() { final result = computeGridLayout( constraints: const BoxConstraints(maxWidth: 100), columns: const [GridTrack.fixed(100)], - rows: const [], - autoRows: const GridTrack.fixed(40), + rows: const [ + GridTrack.fixed(40), + GridTrack.fixed(40), + GridTrack.fixed(40), + ], columnGap: 0, rowGap: 8, childCount: 3, @@ -63,70 +68,73 @@ void main() { expect(result.size, const Size(100, 136)); }); - test('missing auto rows reports the undeclared row strategy', () { - expect( - () => computeGridLayout( - constraints: const BoxConstraints(maxWidth: 100, maxHeight: 200), - columns: const [GridTrack.fixed(100)], - rows: const [], + test( + 'auto rows use provided measured heights before fractional remainder', + () { + final result = computeGridLayout( + constraints: const BoxConstraints.tightFor(width: 200, height: 200), + columns: const [GridTrack.fr(1), GridTrack.fr(1)], + rows: const [GridTrack.auto(), GridTrack.auto()], columnGap: 0, - rowGap: 0, - childCount: 1, - ), - throwsA( - isA() - .having( - (error) => error.toString(), - 'message', - contains('autoRows'), - ) - .having( - (error) => error.toString(), - 'message', - isNot(contains('fractional')), - ), - ), - ); - }); + rowGap: 10, + childCount: 4, + autoRowHeights: const [40, 70], + ); + + expect(result.rowSizes, [40.0, 70.0]); + expect(result.cells[2].offset.dy, 50); + expect(result.contentSize.height, 120); + }, + ); test('fractional auto rows name the configured track when unbounded', () { - expect( - () => computeGridLayout( - constraints: const BoxConstraints(maxWidth: 100), + final child = RenderConstrainedBox( + additionalConstraints: const BoxConstraints.tightFor( + width: 10, + height: 10, + ), + ); + final render = RenderMixGrid( + spec: GridBoxSpec( columns: const [GridTrack.fixed(100)], - rows: const [], autoRows: const GridTrack.fr(1), - columnGap: 0, - rowGap: 0, - childCount: 1, - ), - throwsA( - isA() - .having( - (error) => error.toString(), - 'message', - contains('autoRows'), - ) - .having( - (error) => error.toString(), - 'message', - contains('bounded height'), - ) - .having( - (error) => error.toString(), - 'message', - contains('GridTrack.fr(1'), - ), ), + children: [child], ); + try { + expect( + () => render.getDryLayout(const BoxConstraints(maxWidth: 100)), + throwsA( + isA() + .having( + (error) => error.toString(), + 'message', + contains('autoRows'), + ) + .having( + (error) => error.toString(), + 'message', + contains('bounded height'), + ) + .having( + (error) => error.toString(), + 'message', + contains('GridTrack.fr(1'), + ), + ), + ); + } finally { + render.removeAll(); + render.dispose(); + child.dispose(); + } }); test('row-major auto-placement', () { final result = computeGridLayout( constraints: const BoxConstraints.tightFor(width: 300, height: 200), columns: const [GridTrack.fr(1), GridTrack.fr(1), GridTrack.fr(1)], - rows: const [], - autoRows: const GridTrack.fr(1), + rows: const [GridTrack.fr(1), GridTrack.fr(1)], columnGap: 0, rowGap: 0, childCount: 5, @@ -448,6 +456,31 @@ void main() { expect(start.lerp(differentCount, 0.49).columns, start.columns); expect(start.lerp(differentCount, 0.5).columns, differentCount.columns); }); + + test('lerp keeps auto-to-auto stable and snaps auto-to-numeric', () { + final auto = GridBoxSpec( + columns: const [GridTrack.fixed(100)], + rows: const [GridTrack.auto()], + autoRows: const GridTrack.auto(), + ); + final alsoAuto = GridBoxSpec( + columns: const [GridTrack.fixed(100)], + rows: const [GridTrack.auto()], + autoRows: const GridTrack.auto(), + ); + final fixed = GridBoxSpec( + columns: const [GridTrack.fixed(100)], + rows: const [GridTrack.fixed(40)], + autoRows: const GridTrack.fixed(20), + ); + + expect(auto.lerp(alsoAuto, 0.5).rows, const [GridTrack.auto()]); + expect(auto.lerp(alsoAuto, 0.5).autoRows, const GridTrack.auto()); + expect(auto.lerp(fixed, 0.49).rows, const [GridTrack.auto()]); + expect(auto.lerp(fixed, 0.49).autoRows, const GridTrack.auto()); + expect(auto.lerp(fixed, 0.5).rows, const [GridTrack.fixed(40)]); + expect(auto.lerp(fixed, 0.5).autoRows, const GridTrack.fixed(20)); + }); }); group('GridBoxSpec validation', () { @@ -1494,6 +1527,705 @@ void main() { }, ); }); + + group('content-sized auto rows', () { + test('resolved geometry defaults omitted autoRows to auto', () { + final spec = GridBoxSpec( + columns: const [GridTrack.fr(1), GridTrack.fr(1)], + ); + final geometry = spec.resolveGeometryForConstraints( + const BoxConstraints.tightFor(width: 400, height: 200), + ); + + expect(geometry.autoRows, const GridTrack.auto()); + }); + + testWidgets('omitted autoRows sizes implicit rows to content', ( + tester, + ) async { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: GridBox( + style: GridBoxStyler( + columns: [GridTrack.fr(1), GridTrack.fr(1)], + ), + children: [ + SizedBox(key: Key('a'), height: 30), + SizedBox(key: Key('b'), height: 50), + SizedBox(key: Key('c'), height: 20), + ], + ), + ), + ), + ), + ); + + expect(tester.takeException(), isNull); + final render = tester.renderObject(find.byType(MixGrid)); + expect(render.size, const Size(200, 70)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 50)); + expect(tester.getSize(find.byKey(const Key('b'))), const Size(100, 50)); + expect(tester.getSize(find.byKey(const Key('c'))), const Size(100, 20)); + expect( + tester.getTopLeft(find.byKey(const Key('c'))).dy, + tester.getTopLeft(find.byKey(const Key('a'))).dy + 50, + ); + }); + + testWidgets('explicit autoRows and rows use the same content rule', ( + tester, + ) async { + Future pump(GridBoxStyler style) async { + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 120, + child: GridBox( + style: style, + children: const [ + SizedBox(key: Key('left'), height: 18), + SizedBox(key: Key('right'), height: 42), + ], + ), + ), + ), + ), + ); + + return tester.renderObject(find.byType(MixGrid)).size; + } + + final omitted = await pump( + const GridBoxStyler(columns: [GridTrack.fr(1), GridTrack.fr(1)]), + ); + final automatic = await pump( + const GridBoxStyler( + columns: [GridTrack.fr(1), GridTrack.fr(1)], + autoRows: GridTrack.auto(), + ), + ); + final explicit = await pump( + const GridBoxStyler( + columns: [GridTrack.fr(1), GridTrack.fr(1)], + rows: [GridTrack.auto()], + ), + ); + + expect(omitted, const Size(120, 42)); + expect(automatic, omitted); + expect(explicit, omitted); + }); + + testWidgets( + 'scroll-view two-column auto rows size to independently measured text', + (tester) async { + const texts = [ + 'Short', + 'This catalog card wraps to several lines at a 194-pixel width so the first row is taller than a single line.', + 'A medium-length product blurb that still wraps once.', + 'Tiny', + ]; + const gap = 12.0; + const width = 400.0; + const cellWidth = 194.0; + + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: width, + height: 600, + child: SingleChildScrollView( + child: GridBox( + style: const GridBoxStyler( + columns: [GridTrack.fr(1), GridTrack.fr(1)], + columnGap: gap, + rowGap: gap, + ), + children: [ + for (var index = 0; index < texts.length; index++) + Text(texts[index], key: Key('copy-$index')), + ], + ), + ), + ), + ), + ), + ); + + expect(tester.takeException(), isNull); + final render = tester.renderObject(find.byType(MixGrid)); + final naturalHeights = [ + for (var index = 0; index < texts.length; index++) + tester + .renderObject(find.byKey(Key('copy-$index'))) + .getDryLayout(const BoxConstraints.tightFor(width: cellWidth)) + .height, + ]; + final firstRow = math.max(naturalHeights[0], naturalHeights[1]); + final secondRow = math.max(naturalHeights[2], naturalHeights[3]); + final firstOrigin = tester.getTopLeft(find.byKey(const Key('copy-0'))); + final secondOrigin = tester.getTopLeft(find.byKey(const Key('copy-2'))); + + // Guards the fixture rather than the Grid: the assertions below are + // written against measured text, so if font metrics ever made every + // string fit one line they would all still pass while proving nothing + // about content sizing. Both rows must stay genuinely unequal, and + // each row must be taller than its shortest member. + expect(firstRow, greaterThan(secondRow)); + expect(firstRow, greaterThan(naturalHeights[0])); + expect(secondRow, greaterThan(naturalHeights[3])); + + expect( + tester.getSize(find.byKey(const Key('copy-0'))).width, + cellWidth, + ); + expect( + tester.getSize(find.byKey(const Key('copy-0'))).height, + firstRow, + ); + expect( + tester.getSize(find.byKey(const Key('copy-1'))).height, + firstRow, + ); + expect( + tester.getSize(find.byKey(const Key('copy-2'))).height, + secondRow, + ); + expect(secondOrigin.dy, firstOrigin.dy + firstRow + gap); + expect(render.size, Size(width, firstRow + gap + secondRow)); + }, + ); + + testWidgets('mixed auto and fixed rows keep both rules', (tester) async { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + child: GridBox( + style: GridBoxStyler( + columns: [GridTrack.fixed(100)], + rows: [GridTrack.auto(), GridTrack.fixed(50)], + ), + children: [ + SizedBox(key: Key('auto'), height: 24), + SizedBox(key: Key('fixed'), height: 10), + ], + ), + ), + ), + ), + ); + + expect( + tester.getSize(find.byKey(const Key('auto'))), + const Size(100, 24), + ); + expect( + tester.getSize(find.byKey(const Key('fixed'))), + const Size(100, 50), + ); + expect( + tester.renderObject(find.byType(MixGrid)).size, + const Size(100, 74), + ); + }); + + testWidgets('mixed auto and fr rows consume remaining bounded height', ( + tester, + ) async { + Future pump({required bool tight}) async { + final grid = GridBox( + style: const GridBoxStyler( + columns: [GridTrack.fixed(100)], + rows: [GridTrack.auto(), GridTrack.fr(1)], + rowGap: 10, + ), + children: const [ + SizedBox(key: Key('auto'), height: 40), + SizedBox(key: Key('flex')), + ], + ); + + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: tight + ? SizedBox(width: 100, height: 200, child: grid) + : SizedBox( + width: 100, + height: 200, + child: OverflowBox( + maxHeight: 200, + minHeight: 0, + alignment: Alignment.topLeft, + child: grid, + ), + ), + ), + ), + ); + } + + await pump(tight: true); + expect(tester.getSize(find.byKey(const Key('auto'))).height, 40); + expect(tester.getSize(find.byKey(const Key('flex'))).height, 150); + + await pump(tight: false); + expect(tester.getSize(find.byKey(const Key('auto'))).height, 40); + expect(tester.getSize(find.byKey(const Key('flex'))).height, 150); + }); + + testWidgets( + 'auto-row content that exceeds a bounded parent still overflows', + (tester) async { + final overflowErrors = []; + final previousOnError = FlutterError.onError; + FlutterError.onError = overflowErrors.add; + try { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + height: 40, + child: GridBox( + style: GridBoxStyler(columns: [GridTrack.fixed(100)]), + children: [SizedBox(height: 90)], + ), + ), + ), + ), + ); + } finally { + FlutterError.onError = previousOnError; + } + + expect(overflowErrors, isNotEmpty); + expect( + overflowErrors.first.exception.toString(), + contains('RenderMixGrid overflowed'), + ); + expect( + tester.renderObject(find.byType(MixGrid)).size, + const Size(100, 40), + ); + }, + ); + + testWidgets( + 'onConstraints remeasures auto rows at the new cell width without rebuilds', + (tester) async { + await tester.binding.setSurfaceSize(const Size(800, 600)); + addTearDown(() => tester.binding.setSurfaceSize(null)); + + var childBuilds = 0; + final children = [ + Builder( + builder: (context) { + childBuilds++; + + return const _WidthDrivenHeight( + key: Key('wide-child'), + factor: 0.5, + ); + }, + ), + ]; + final grid = MixGrid( + spec: GridBoxSpec( + columns: const [GridTrack.fr(1), GridTrack.fr(1)], + constraintBranches: [ + GridConstraintBranch( + breakpoint: Breakpoint.maxWidth(500), + patch: const GridLayoutPatch(columns: [GridTrack.fr(1)]), + ), + ], + ), + children: children, + ); + + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox(width: 700, height: 400, child: grid), + ), + ), + ); + + expect(childBuilds, 1); + expect(tester.getSize(find.byKey(const Key('wide-child'))).height, 175); + + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox(width: 400, height: 400, child: grid), + ), + ), + ); + + expect(childBuilds, 1); + expect(tester.getSize(find.byKey(const Key('wide-child'))).height, 200); + }, + ); + + testWidgets('auto-row children are laid out twice; others once', ( + tester, + ) async { + await tester.pumpWidget( + MaterialApp( + home: Center( + child: SizedBox( + width: 100, + height: 200, + child: MixGrid( + spec: GridBoxSpec( + columns: const [GridTrack.fixed(100)], + rows: const [GridTrack.auto(), GridTrack.fixed(40)], + ), + children: const [ + _LayoutCallCounter(key: Key('auto')), + _LayoutCallCounter(key: Key('fixed')), + ], + ), + ), + ), + ), + ); + + final counters = tester + .renderObjectList<_RenderLayoutCallCounter>( + find.byType(_LayoutCallCounter), + ) + .toList(); + expect(counters[0].layoutCount, 2); + expect(counters[1].layoutCount, 1); + }); + + testWidgets('live and dry sizes match for deterministic auto-row boxes', ( + tester, + ) async { + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: MixGrid( + spec: GridBoxSpec( + columns: const [GridTrack.fixed(100), GridTrack.fixed(100)], + autoRows: const GridTrack.auto(), + rowGap: 8, + ), + children: const [ + SizedBox(height: 20), + SizedBox(height: 36), + SizedBox(height: 12), + ], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + final dry = render.getDryLayout(const BoxConstraints(maxWidth: 200)); + expect(render.size, const Size(200, 56)); + expect(dry, render.size); + }); + + testWidgets('vertical intrinsic height is the per-row max plus gaps', ( + tester, + ) async { + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: MixGrid( + spec: GridBoxSpec( + columns: const [GridTrack.fr(1), GridTrack.fr(1)], + rowGap: 8, + ), + children: const [ + SizedBox(height: 20), + SizedBox(height: 36), + SizedBox(height: 12), + ], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + expect(render.getMaxIntrinsicHeight(200), 56); + expect(render.getMinIntrinsicHeight(200), 56); + }); + + testWidgets('incomplete last auto row stays well-defined', (tester) async { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: GridBox( + style: GridBoxStyler( + columns: [GridTrack.fr(1), GridTrack.fr(1)], + rowGap: 6, + ), + children: [ + SizedBox(height: 10), + SizedBox(height: 14), + SizedBox(key: Key('last'), height: 22), + ], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + expect(render.size, const Size(200, 42)); + expect( + tester.getSize(find.byKey(const Key('last'))), + const Size(100, 22), + ); + }); + + testWidgets( + 'a child that cannot dry-layout reports Flutter dry-layout failure', + (tester) async { + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + height: 200, + child: GridBox( + style: const GridBoxStyler(columns: [GridTrack.fixed(200)]), + children: [ + LayoutBuilder( + builder: (context, constraints) { + return const SizedBox(height: 40); + }, + ), + ], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + expect( + () => render.getDryLayout( + const BoxConstraints.tightFor(width: 200, height: 200), + ), + throwsA( + isA() + .having( + (error) => error.toString(), + 'message', + contains('dry layout'), + ) + .having( + (error) => error.toString(), + 'message', + isNot(contains('finite height')), + ), + ), + ); + }, + ); + + testWidgets( + 'an expanding auto-row child reports Flutter unbounded-flex error', + (tester) async { + final captured = []; + final previousOnError = FlutterError.onError; + FlutterError.onError = (details) { + captured.add(details.exceptionAsString()); + }; + try { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: SingleChildScrollView( + child: GridBox( + style: GridBoxStyler(columns: [GridTrack.fr(1)]), + children: [ + Column(children: [Expanded(child: SizedBox())]), + ], + ), + ), + ), + ), + ), + ); + } finally { + FlutterError.onError = previousOnError; + } + final leftover = tester.takeException(); + if (leftover != null) { + captured.add(leftover.toString()); + } + + final messages = captured.join('\n'); + expect(messages, contains('non-zero flex')); + expect(messages, contains('incoming height constraints are unbounded')); + expect( + messages, + isNot(contains('Grid auto rows require children with a finite height')), + ); + }, + ); + + testWidgets( + 'an auto-row child that throws StateError reports that StateError', + (tester) async { + final captured = []; + final previousOnError = FlutterError.onError; + FlutterError.onError = (details) { + captured.add(details.exceptionAsString()); + }; + try { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: GridBox( + style: GridBoxStyler(columns: [GridTrack.fixed(200)]), + children: [_ThrowingLayoutBox()], + ), + ), + ), + ), + ); + } finally { + FlutterError.onError = previousOnError; + } + final leftover = tester.takeException(); + if (leftover != null) { + captured.add(leftover.toString()); + } + + final messages = captured.join('\n'); + expect(messages, contains('child-specific bug: index out of range')); + expect( + messages, + isNot(contains('Grid auto rows require children with a finite height')), + ); + }, + ); + + testWidgets( + 'a child that does not implement computeDryLayout reports Flutter dry-layout failure', + (tester) async { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + height: 200, + child: GridBox( + style: GridBoxStyler(columns: [GridTrack.fixed(200)]), + children: [_NoDryLayoutBox()], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + expect( + () => render.getDryLayout( + const BoxConstraints.tightFor(width: 200, height: 200), + ), + throwsA( + isA() + .having( + (error) => error.toString(), + 'message', + contains('does not implement "computeDryLayout"'), + ) + .having( + (error) => error.toString(), + 'message', + isNot(contains('finite height')), + ), + ), + ); + }, + ); + + testWidgets( + 'omitted autoRows grows a content-sized row beyond explicit rows', + (tester) async { + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + child: GridBox( + style: GridBoxStyler( + columns: [GridTrack.fixed(100)], + rows: [GridTrack.fixed(40)], + ), + children: [ + SizedBox(height: 10), + SizedBox(key: Key('tall'), height: 72), + ], + ), + ), + ), + ), + ); + + final render = tester.renderObject(find.byType(MixGrid)); + expect(render.size.height, isNot(40)); + expect(render.size.height, 112); + expect( + tester.getSize(find.byKey(const Key('tall'))), + const Size(100, 72), + ); + }, + ); + }); +} + +class _WidthDrivenHeight extends StatelessWidget { + const _WidthDrivenHeight({super.key, required this.factor}); + + final double factor; + + @override + Widget build(BuildContext context) { + return AspectRatio(aspectRatio: 1 / factor); + } } class _LayoutCallCounter extends SingleChildRenderObjectWidget { @@ -1514,3 +2246,31 @@ class _RenderLayoutCallCounter extends RenderProxyBox { super.layout(constraints, parentUsesSize: parentUsesSize); } } + +class _ThrowingLayoutBox extends LeafRenderObjectWidget { + const _ThrowingLayoutBox(); + + @override + RenderBox createRenderObject(BuildContext context) => _RenderThrowingLayout(); +} + +class _RenderThrowingLayout extends RenderBox { + @override + void performLayout() { + throw StateError('child-specific bug: index out of range'); + } +} + +class _NoDryLayoutBox extends LeafRenderObjectWidget { + const _NoDryLayoutBox(); + + @override + RenderBox createRenderObject(BuildContext context) => _RenderNoDryLayout(); +} + +class _RenderNoDryLayout extends RenderBox { + @override + void performLayout() { + size = constraints.constrain(const Size(10, 10)); + } +} diff --git a/packages/mix/test/src/layout/grid_layout_property_test.dart b/packages/mix/test/src/layout/grid_layout_property_test.dart index 700e7460e..83705adf8 100644 --- a/packages/mix/test/src/layout/grid_layout_property_test.dart +++ b/packages/mix/test/src/layout/grid_layout_property_test.dart @@ -40,8 +40,7 @@ void main() { final result = computeGridLayout( constraints: constraints, columns: columns, - rows: rows, - autoRows: autoRows, + rows: effectiveRows, columnGap: columnGap, rowGap: rowGap, childCount: childCount, @@ -111,6 +110,82 @@ void main() { } } }); + + test('seeded auto rows size to the per-row child maximum', () { + const seed = 0x4155544F; + const iterations = 200; + final random = Random(seed); + + for (var iteration = 0; iteration < iterations; iteration++) { + final columnCount = 1 + random.nextInt(4); + final childCount = 1 + random.nextInt(12); + final requiredRows = (childCount + columnCount - 1) ~/ columnCount; + final childHeights = List.generate( + childCount, + (_) => 8 + random.nextInt(80).toDouble(), + ); + final expectedRows = List.filled(requiredRows, 0); + for (var index = 0; index < childCount; index++) { + final row = index ~/ columnCount; + expectedRows[row] = max(expectedRows[row], childHeights[index]); + } + final rowGap = random.nextInt(17).toDouble(); + final width = 80.0 + random.nextInt(401); + final constraints = BoxConstraints(maxWidth: width); + final reason = 'seed=$seed iteration=$iteration'; + + final result = computeGridLayout( + constraints: constraints, + columns: List.filled(columnCount, const GridTrack.fr(1)), + rows: List.filled(requiredRows, const GridTrack.auto()), + columnGap: 0, + rowGap: rowGap, + childCount: childCount, + autoRowHeights: expectedRows, + ); + + expect(result.rowSizes, expectedRows, reason: reason); + expect( + result.contentSize.height, + closeTo(_extent(expectedRows, rowGap), 1e-8), + reason: reason, + ); + expect(result.cells, hasLength(childCount), reason: reason); + for (var index = 0; index < result.cells.length; index++) { + final cell = result.cells[index]; + expect(cell.row, index ~/ columnCount, reason: reason); + expect( + cell.offset.dy, + closeTo(_origin(result.rowSizes, rowGap, cell.row), 1e-8), + reason: reason, + ); + expect(cell.size.height, expectedRows[cell.row], reason: reason); + } + + final children = [ + for (final height in childHeights) + RenderConstrainedBox( + additionalConstraints: BoxConstraints.tightFor(height: height), + ), + ]; + final render = RenderMixGrid( + spec: GridBoxSpec( + columns: List.filled(columnCount, const GridTrack.fr(1)), + rowGap: rowGap, + ), + children: children, + ); + final drySize = render.getDryLayout(constraints); + render.layout(constraints); + expect(render.size, drySize, reason: reason); + expect(render.size.height, result.contentSize.height, reason: reason); + render.removeAll(); + render.dispose(); + for (final child in children) { + child.dispose(); + } + } + }); } List _tracks(Random random, int count) { diff --git a/packages/mix/test/src/layout/grid_public_api_test.dart b/packages/mix/test/src/layout/grid_public_api_test.dart index 622d48ec8..e9315d0ab 100644 --- a/packages/mix/test/src/layout/grid_public_api_test.dart +++ b/packages/mix/test/src/layout/grid_public_api_test.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart' show FlutterError; import 'package:flutter/widgets.dart' show Clip; import 'package:flutter_test/flutter_test.dart'; import 'package:mix/mix.dart'; @@ -43,6 +44,35 @@ void main() { ); }); + test('GridTrack.auto is a fieldless row track', () { + expect(const GridTrack.auto(), const AutoGridTrack()); + expect(const GridTrack.auto(), const GridTrack.auto()); + expect(const GridTrack.auto().toString(), 'GridTrack.auto()'); + expect( + const GridBoxStyler().autoRows(.auto()).$autoRows, + const GridTrack.auto(), + ); + expect(const GridBoxStyler().rows([.auto()]).$rows, const [ + GridTrack.auto(), + ]); + expect( + () => GridBoxSpec(columns: const [GridTrack.auto()]), + throwsA( + isA() + .having( + (error) => error.toString(), + 'message', + contains('vertical-only'), + ) + .having( + (error) => error.toString(), + 'message', + contains('rows or autoRows'), + ), + ), + ); + }); + test('equalColumns creates repeated one-fraction tracks', () { final GridBoxStyler factory = .equalColumns(3); final chained = GridBoxStyler().equalColumns(2); diff --git a/packages/mix_protocol/CHANGELOG.md b/packages/mix_protocol/CHANGELOG.md index 622f9769b..1e32e10bc 100644 --- a/packages/mix_protocol/CHANGELOG.md +++ b/packages/mix_protocol/CHANGELOG.md @@ -2,6 +2,8 @@ ### New features +- Added additive v1 `{"type":"auto"}` Grid tracks for `rows`, `autoRows`, and + constraint patches. Auto tracks have no token references. - Added immutable, deterministic package-contributed styler vocabularies, namespaced versioned discriminators, explicit `MixProtocol.compose`, and an Ack-free codec-authoring façade. diff --git a/packages/mix_protocol/GUIDE.md b/packages/mix_protocol/GUIDE.md index fd2cc55cb..cd3ecd113 100644 --- a/packages/mix_protocol/GUIDE.md +++ b/packages/mix_protocol/GUIDE.md @@ -172,7 +172,7 @@ local constraint branches carry a `Breakpoint` plus a geometry-only patch: { "type": "fixed", "size": 220 }, { "type": "fr", "fraction": 2 } ], - "autoRows": { "type": "fixed", "size": 96 }, + "autoRows": { "type": "auto" }, "columnGap": 16, "rowGap": 12, "constraintBranches": [ diff --git a/packages/mix_protocol/WIRE_CONTRACT.md b/packages/mix_protocol/WIRE_CONTRACT.md index 7073f2981..9de759912 100644 --- a/packages/mix_protocol/WIRE_CONTRACT.md +++ b/packages/mix_protocol/WIRE_CONTRACT.md @@ -305,10 +305,12 @@ A Grid track is one of: ```json { "type": "fixed", "size": 220 } { "type": "fr", "fraction": 2 } +{ "type": "auto" } ``` -Fixed `size` is non-negative. Fractional `fraction` is greater than zero. Each -numeric value also accepts the standard numeric token form. Space tokens are +Fixed `size` is non-negative. Fractional `fraction` is greater than zero. +`auto` is fieldless and valid on `rows` and `autoRows` only. Each numeric +value also accepts the standard numeric token form. Space tokens are recommended for fixed sizes and gaps; double tokens are recommended for fractional weights: diff --git a/packages/mix_protocol/lib/src/schema/grid_box_styler_codec.dart b/packages/mix_protocol/lib/src/schema/grid_box_styler_codec.dart index 8ede3f7ab..31ebc2d6c 100644 --- a/packages/mix_protocol/lib/src/schema/grid_box_styler_codec.dart +++ b/packages/mix_protocol/lib/src/schema/grid_box_styler_codec.dart @@ -13,7 +13,7 @@ SchemaObject gridBoxStylerSchema({ }) { final columns = directField>( 'columns', - Ack.list(_gridTrackCodec()).nonEmpty(), + Ack.list(_gridTrackCodec(allowAuto: false)).nonEmpty(), (value) => value.$columns, schemaSemantics: const SchemaFieldSemantics( doubleTokenPaths: [ @@ -24,7 +24,7 @@ SchemaObject gridBoxStylerSchema({ ); final rows = directField>( 'rows', - Ack.list(_gridTrackCodec()), + Ack.list(_gridTrackCodec(allowAuto: true)), (value) => value.$rows, schemaSemantics: const SchemaFieldSemantics( doubleTokenPaths: [ @@ -35,7 +35,7 @@ SchemaObject gridBoxStylerSchema({ ); final autoRows = directField( 'autoRows', - _gridTrackCodec(), + _gridTrackCodec(allowAuto: true), (value) => value.$autoRows, schemaSemantics: const SchemaFieldSemantics( doubleTokenPaths: [ @@ -106,7 +106,7 @@ SchemaObject gridBoxStylerSchema({ ); } -AckSchema _gridTrackCodec() { +AckSchema _gridTrackCodec({required bool allowAuto}) { return Ack.discriminated( discriminatorKey: 'type', schemas: { @@ -138,6 +138,20 @@ AckSchema _gridTrackCodec() { return {'fraction': track.fraction}; }, ), + if (allowAuto) + gridTrackTypeAuto: Ack.object({}).codec( + decode: (_) => const GridTrack.auto(), + encode: (track) { + if (track is! AutoGridTrack) { + throw UnsupportedEncodeValueError( + track, + 'Expected AutoGridTrack.', + ); + } + + return const {}; + }, + ), }, ); } @@ -185,9 +199,11 @@ AckSchema _gridBreakpointCodec() { AckSchema _gridLayoutPatchCodec() { return Ack.object({ - 'columns': Ack.list(_gridTrackCodec()).nonEmpty().optional(), - 'rows': Ack.list(_gridTrackCodec()).optional(), - 'autoRows': _gridTrackCodec().optional(), + 'columns': Ack.list( + _gridTrackCodec(allowAuto: false), + ).nonEmpty().optional(), + 'rows': Ack.list(_gridTrackCodec(allowAuto: true)).optional(), + 'autoRows': _gridTrackCodec(allowAuto: true).optional(), 'columnGap': nonNegativeDoubleTokenCodec().optional(), 'rowGap': nonNegativeDoubleTokenCodec().optional(), }) diff --git a/packages/mix_protocol/lib/src/schema/wire_discriminators.dart b/packages/mix_protocol/lib/src/schema/wire_discriminators.dart index ed2f122b0..fcab1e1ab 100644 --- a/packages/mix_protocol/lib/src/schema/wire_discriminators.dart +++ b/packages/mix_protocol/lib/src/schema/wire_discriminators.dart @@ -12,6 +12,7 @@ const schemaTypeGridBox = 'grid_box'; const gridTrackTypeFixed = 'fixed'; const gridTrackTypeFraction = 'fr'; +const gridTrackTypeAuto = 'auto'; const modifierTypeAlign = 'align'; const modifierTypeAspectRatio = 'aspect_ratio'; diff --git a/packages/mix_protocol/lib/src/tokens/token_reference_walker.dart b/packages/mix_protocol/lib/src/tokens/token_reference_walker.dart index 72b71e0a3..d4900e606 100644 --- a/packages/mix_protocol/lib/src/tokens/token_reference_walker.dart +++ b/packages/mix_protocol/lib/src/tokens/token_reference_walker.dart @@ -316,6 +316,8 @@ final class _TokenReferenceWalker { visit(size); case FrGridTrack(:final fraction): visit(fraction); + case AutoGridTrack(): + return; case null: return; } diff --git a/packages/mix_protocol/test/grid_box_styler_codec_test.dart b/packages/mix_protocol/test/grid_box_styler_codec_test.dart index 9dc19a1fb..9aa244eeb 100644 --- a/packages/mix_protocol/test/grid_box_styler_codec_test.dart +++ b/packages/mix_protocol/test/grid_box_styler_codec_test.dart @@ -74,6 +74,103 @@ void main() { }); }); + test('grid_box round-trips fieldless auto tracks without token refs', () { + final payload = { + 'v': 1, + 'type': 'grid_box', + 'columns': [ + {'type': 'fr', 'fraction': 1.0}, + {'type': 'fr', 'fraction': 1.0}, + ], + 'rows': [ + {'type': 'auto'}, + ], + 'autoRows': {'type': 'auto'}, + 'constraintBranches': [ + { + 'breakpoint': {'maxWidth': 520.0}, + 'patch': { + 'autoRows': {'type': 'auto'}, + 'rows': [ + {'type': 'auto'}, + ], + }, + }, + ], + }; + + final decoded = decode(payload); + + expect(encode(decoded), payload); + expect(decoded.$rows, const [GridTrack.auto()]); + expect(decoded.$autoRows, const GridTrack.auto()); + expect( + decoded.$constraintBranches!.single.patch.autoRows, + const GridTrack.auto(), + ); + expect(tokenReferencesOf(decoded), isEmpty); + }); + + test('lenient decode drops the smallest unrecognized grid track', () { + (GridBoxStyler, List) lenient(JsonMap payload) { + final result = contract.decodeStyle( + payload, + options: const MixProtocolDecodeOptions( + mode: MixProtocolDecodeMode.lenient, + ), + ); + + return switch (result) { + MixProtocolSuccess(:final value, :final warnings) => ( + value, + [for (final warning in warnings) warning.path], + ), + MixProtocolFailure(:final errors) => fail('$errors'), + }; + } + + // A list entry loses only that entry; sibling tracks survive. + final (rowStyle, rowWarnings) = lenient({ + 'v': 1, + 'type': 'grid_box', + 'columns': [ + {'type': 'fr', 'fraction': 1.0}, + ], + 'rows': [ + {'type': 'fixed', 'size': 40.0}, + {'type': 'minmax', 'min': 1.0, 'max': 2.0}, + ], + }); + expect(rowWarnings, ['/rows/1/type']); + expect(rowStyle.$rows, const [GridTrack.fixed(40)]); + + // A scalar field loses the whole field, which resolves back to the + // implicit GridTrack.auto() default rather than a decode failure. + final (autoStyle, autoWarnings) = lenient({ + 'v': 1, + 'type': 'grid_box', + 'columns': [ + {'type': 'fr', 'fraction': 1.0}, + ], + 'autoRows': {'type': 'minmax', 'min': 1.0, 'max': 2.0}, + }); + expect(autoWarnings, ['/autoRows/type']); + expect(autoStyle.$autoRows, isNull); + + // `auto` is unrecognized under columns, so lenient mode drops that column + // instead of failing the way strict mode does. + final (columnStyle, columnWarnings) = lenient({ + 'v': 1, + 'type': 'grid_box', + 'columns': [ + {'type': 'fr', 'fraction': 1.0}, + {'type': 'auto'}, + ], + }); + expect(columnWarnings, ['/columns/1/type']); + expect(columnStyle.$columns, const [GridTrack.fr(1)]); + }); + test('runtime grid style round-trips without losing branch order', () { final style = GridBoxStyler( columns: const [GridTrack.fixed(200), GridTrack.fr(2)], @@ -186,6 +283,9 @@ void main() { 'infinite fraction': [ {'type': 'fr', 'fraction': double.infinity}, ], + 'auto column': [ + {'type': 'auto'}, + ], }; for (final MapEntry(key: label, value: columns) in invalidFields.entries) { diff --git a/packages/mix_protocol/test/schema_export_golden_test.dart b/packages/mix_protocol/test/schema_export_golden_test.dart index 65c89298d..e10e0a6ec 100644 --- a/packages/mix_protocol/test/schema_export_golden_test.dart +++ b/packages/mix_protocol/test/schema_export_golden_test.dart @@ -8,7 +8,7 @@ void main() { test('core schema export has a byte-for-byte v1 fingerprint', () { final encoded = jsonEncode(mixProtocol.exportStyleJsonSchema()); - expect(_fnv1a64(utf8.encode(encoded)), -531352329917363246); + expect(_fnv1a64(utf8.encode(encoded)), -7566329063571446550); }); test('schema export structurally describes every built-in branch', () { @@ -264,6 +264,20 @@ void main() { isTrue, reason: 'grid_box tracks accept numeric tokens', ); + expect( + _matchesJsonSchema(_object(gridProperties['rows']), [ + {'type': 'auto'}, + ], definitions), + isTrue, + reason: 'grid_box rows accept fieldless auto tracks', + ); + expect( + _matchesJsonSchema(_object(gridProperties['autoRows']), { + 'type': 'auto', + }, definitions), + isTrue, + reason: 'grid_box autoRows accepts fieldless auto tracks', + ); for (final field in ['columnGap', 'rowGap']) { expect( _matchesJsonSchema(_object(gridProperties[field]), { @@ -290,6 +304,21 @@ void main() { isTrue, reason: 'grid_box constraint patches accept numeric tokens', ); + expect( + _matchesJsonSchema(_object(gridProperties['constraintBranches']), [ + { + 'breakpoint': {'maxWidth': 600}, + 'patch': { + 'autoRows': {'type': 'auto'}, + 'rows': [ + {'type': 'auto'}, + ], + }, + }, + ], definitions), + isTrue, + reason: 'grid_box constraint patches accept fieldless auto tracks', + ); expect( _matchesJsonSchema( _object(_properties(branchesByType['flex']!)['spacing']), diff --git a/packages/mix_protocol/test/styler_round_trip_test.dart b/packages/mix_protocol/test/styler_round_trip_test.dart index 632715356..176a8b84b 100644 --- a/packages/mix_protocol/test/styler_round_trip_test.dart +++ b/packages/mix_protocol/test/styler_round_trip_test.dart @@ -201,7 +201,7 @@ void main() { expectRoundTrips( GridBoxStyler( columns: const [GridTrack.fixed(220), GridTrack.fr(2)], - autoRows: const GridTrack.fixed(96), + autoRows: const GridTrack.auto(), columnGap: 16, rowGap: 12, clipBehavior: Clip.hardEdge, diff --git a/skills/mix/SKILL.md b/skills/mix/SKILL.md index 17f90c357..b7238b352 100644 --- a/skills/mix/SKILL.md +++ b/skills/mix/SKILL.md @@ -62,7 +62,7 @@ Resolution pipeline: `StyleWidget` → `StyleBuilder` → merge active variants | `FlexBoxStyler` | `FlexBoxSpec` | `FlexBox`/`RowBox`/`ColumnBox` | `Column`/`Row` + `Container` | | `WrapStyler` | `WrapSpec` | — (layout) | `Wrap` | | `WrapBoxStyler` | `WrapBoxSpec` | `WrapBox` | `Wrap` + `Container` | -| `GridBoxStyler` | `GridBoxSpec` | `GridBox` | Fixed/`fr` track grid | +| `GridBoxStyler` | `GridBoxSpec` | `GridBox` | Fixed/`fr` columns; fixed/`fr`/auto rows | | `StackStyler` | `StackSpec` | — (layout) | `Stack` | | `StackBoxStyler` | `StackBoxSpec` | `StackBox` | `Stack` + `Container` | | `IconStyler` | `IconSpec` | `StyledIcon` | `Icon` | diff --git a/skills/mix/references/fluent-api.md b/skills/mix/references/fluent-api.md index 0c1a7b1ac..4f3ccf7e8 100644 --- a/skills/mix/references/fluent-api.md +++ b/skills/mix/references/fluent-api.md @@ -153,7 +153,7 @@ selection. Prefer an explicitly typed factory initializer: ```dart final GridBoxStyler grid = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)); + .autoRows(.auto()); ``` Use `columns`, `equalColumns`, `rows`, `autoRows`, `gap`, `columnGap`, diff --git a/skills/mix/references/layout.md b/skills/mix/references/layout.md index 4348390bd..c9c23968a 100644 --- a/skills/mix/references/layout.md +++ b/skills/mix/references/layout.md @@ -29,7 +29,7 @@ installed version exposes the referenced classes. | One child with size, padding, constraints, or decoration | `Box` + `BoxStyler` | Owns single-child box styling | | One non-wrapping horizontal or vertical sequence | `RowBox`, `ColumnBox`, or `FlexBox` + `FlexBoxStyler` | Combines Flex geometry with outer Box styling | | Intrinsic items that should flow onto additional runs | `WrapBox` + `WrapBoxStyler` | Models tags, chips, and button groups without fixed tracks | -| Explicit two-dimensional rows and columns | `GridBox` + `GridBoxStyler` | Models dashboards, card catalogs, and galleries with fixed/`fr` tracks | +| Explicit two-dimensional rows and columns | `GridBox` + `GridBoxStyler` | Models dashboards, card catalogs, and galleries with fixed/`fr` columns and fixed, `fr`, or auto rows | | Overlapping or positioned children | `StackBox` + `StackBoxStyler` | Combines Stack geometry with outer Box styling | Prefer the simplest primitive that represents the layout semantics. Do not use @@ -123,7 +123,7 @@ shorthand to make its topology visible: ```dart final GridBoxStyler cardGridStyle = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)); + .autoRows(.auto()); GridBox(style: cardGridStyle, children: cards); ``` @@ -141,9 +141,14 @@ final GridBoxStyler reportGridStyle = .columns([ Interpret tracks as follows: -- `.fixed(240)` consumes 240 logical pixels and does not shrink. -- `.fr(2)` receives twice the remaining space of `.fr(1)` after fixed tracks - and gaps. +- `.fixed(240)` consumes 240 logical pixels and does not shrink. On a row it + is a hard height: children stretch or clip to that cell. +- `.fr(2)` receives twice the remaining space of `.fr(1)` after fixed tracks, + auto tracks, and gaps. +- `.auto()` is vertical-only and sizes the row to its tallest child's natural + height at the resolved column width. Auto-row children are measured, then + laid out again into the stretched cell. That extra pass is only for children + in auto rows. - Fractional columns require bounded width. - Fractional rows and fractional `autoRows` require bounded height. @@ -151,20 +156,24 @@ Interpret tracks as follows: Children fill columns left to right, then advance row by row. Provide enough explicit `.rows([...])` tracks for every required row or set `.autoRows(...)` -for the remaining rows. A non-empty Grid with no applicable row track reports -an error instead of guessing content-sized geometry. +for the remaining rows. Omitted `autoRows` defaults to `.auto()`, so a +non-empty Grid with columns and no row declaration sizes implicit rows to +content. ```dart final GridBoxStyler galleryStyle = .equalColumns(2) .rows([.fixed(180)]) - .autoRows(.fixed(180)) + .autoRows(.auto()) .columnGap(12) .rowGap(12); ``` With five children and two columns, this Grid needs three rows. The first uses the explicit track and the next two repeat `autoRows`. In a vertical -`SingleChildScrollView`, use fixed row tracks because height is unbounded. +`SingleChildScrollView`, omit `autoRows` or use `.autoRows(.auto())`. Keep +`.fixed(...)` only when clipping or constraining height is intentional. Auto +rows require finite-height children; do not put `Expanded` or `Spacer` in an +auto row inside a scroll view. ### Respond to the offered container @@ -174,7 +183,6 @@ by its own parent: ```dart final GridBoxStyler responsiveCards = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)) .onConstraints( .maxWidth(760), .equalColumns(2).gap(12), @@ -203,13 +211,13 @@ size through `MediaQuery`. Two Grids in the same viewport can select different Use responsive `GridBox` for: - metric dashboards whose panels collapse from four to two to one column; -- product catalogs with equal card widths and repeated fixed row heights; +- product catalogs with equal card widths and content-sized or fixed rows; - media galleries with aligned tracks and controlled clipping; - asymmetric report layouts using fixed sidebar tracks plus fractional content; - nested components that should respond to their container rather than the whole device viewport. -Avoid the current Grid API when the design requires content-sized tracks, +Avoid the current Grid API when the design requires content-sized columns, spans, named areas, masonry packing, direction-aware placement, or baseline alignment. Those features are intentionally outside the current contract. Use a more suitable Flutter layout or redesign the track model rather than @@ -230,8 +238,8 @@ final GridBoxStyler animatedGrid = .columns([ ``` Keep track lists the same length and keep each positional track kind compatible -(`fixed` with `fixed`, `fr` with `fr`) for continuous interpolation. Compatible -rows, `autoRows`, and gaps interpolate too. Track-count or track-kind changes, +(`fixed` with `fixed`, `fr` with `fr`, `auto` with `auto`) for continuous +interpolation. Compatible rows, `autoRows`, and gaps interpolate too. Track-count or track-kind changes, clipping, and constraint-patch lists switch at the midpoint. A live `onConstraints` branch change remains immediate because selection happens during layout rather than creating a new animation target. diff --git a/skills/mix/references/styler-api-policy.md b/skills/mix/references/styler-api-policy.md index faf12ec50..ea7d3751e 100644 --- a/skills/mix/references/styler-api-policy.md +++ b/skills/mix/references/styler-api-policy.md @@ -41,7 +41,7 @@ case in the current API: // CORRECT — the declared type supplies shorthand context final GridBoxStyler cards = .equalColumns(3) .gap(16) - .autoRows(.fixed(220)); + .autoRows(.auto()); // WRONG — no contextual type for the leading shorthand final cards = .equalColumns(3); From 60c2cf70165866eae5fbe90d62215400c75926b8 Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Tue, 18 Aug 2026 20:11:39 -0400 Subject: [PATCH 2/7] fix(mix): satisfy format, DCM, and chart schema golden Three CI failures from the auto-rows change: - dart format left two over-long isNot(contains(...)) assertions in grid_box_test.dart unwrapped. - DCM's arguments-ordering rule requires child/children last (lints_with_dcm.yaml), but _measureAutoRowChild declared and passed child first. - mix_chart_protocol composes the core vocabulary, so its exported v1 schema fingerprint moved when the grid_box branch gained the auto track kind. Verified the delta is confined to grid_box: "auto" appears in exactly one of the 26 exported branches. --- packages/mix/lib/src/layout/render_grid.dart | 4 ++-- packages/mix/test/src/layout/grid_box_test.dart | 8 ++++++-- .../test/mix_chart_vocabulary_test.dart | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 9b69a1a62..198ea4bf1 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -314,10 +314,10 @@ class RenderMixGrid extends RenderBox if (row < effectiveRows.length && effectiveRows[row] is AutoGridTrack) { final column = index % columnCount; final measured = _measureAutoRowChild( - child: child, row: row, constraints: BoxConstraints.tightFor(width: columnSizes[column]), measureChild: measureChild, + child: child, ); heights[row] = math.max(heights[row], measured.height); } @@ -329,10 +329,10 @@ class RenderMixGrid extends RenderBox } Size _measureAutoRowChild({ - required RenderBox child, required int row, required BoxConstraints constraints, required ChildLayouter measureChild, + required RenderBox child, }) { final measured = measureChild(child, constraints); if (!measured.height.isFinite) { diff --git a/packages/mix/test/src/layout/grid_box_test.dart b/packages/mix/test/src/layout/grid_box_test.dart index 0dd4fcffe..56188156d 100644 --- a/packages/mix/test/src/layout/grid_box_test.dart +++ b/packages/mix/test/src/layout/grid_box_test.dart @@ -2095,7 +2095,9 @@ void main() { expect(messages, contains('incoming height constraints are unbounded')); expect( messages, - isNot(contains('Grid auto rows require children with a finite height')), + isNot( + contains('Grid auto rows require children with a finite height'), + ), ); }, ); @@ -2135,7 +2137,9 @@ void main() { expect(messages, contains('child-specific bug: index out of range')); expect( messages, - isNot(contains('Grid auto rows require children with a finite height')), + isNot( + contains('Grid auto rows require children with a finite height'), + ), ); }, ); diff --git a/packages/mix_chart_protocol/test/mix_chart_vocabulary_test.dart b/packages/mix_chart_protocol/test/mix_chart_vocabulary_test.dart index d61d2e404..a02ddb43b 100644 --- a/packages/mix_chart_protocol/test/mix_chart_vocabulary_test.dart +++ b/packages/mix_chart_protocol/test/mix_chart_vocabulary_test.dart @@ -519,7 +519,7 @@ void main() { expect( _fnv1a64(utf8.encode(jsonEncode(schema))), - 3081541222728341371, + -1622746188329387277, reason: 'Changing this fingerprint changes the declared chart v1 schema.', ); From 9b86051e6175632dbfed12cdc05974a1142c1a0a Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Wed, 19 Aug 2026 10:16:31 -0400 Subject: [PATCH 3/7] fix(mix): keep auto rows inside the grid relayout boundary A fully tight cell constraint made every child its own relayout boundary, so a child-only change never reached RenderMixGrid and the auto row kept the height measured on its first layout pass. Give auto-row children a loose max height with parentUsesSize so the row re-measures, and leave fixed/fr rows on the tight cell that is their documented contract. Carry the resolved row tracks on GridLayoutResult so performLayout can tell the two cases apart, and inline the single-use measure helper. --- packages/mix/lib/src/layout/render_grid.dart | 54 +++++---- .../mix/test/src/layout/grid_box_test.dart | 104 ++++++++++++++++++ 2 files changed, 138 insertions(+), 20 deletions(-) diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 198ea4bf1..19696ee04 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -116,6 +116,12 @@ class GridLayoutResult { final Size contentSize; final List columnSizes; final List rowSizes; + + /// Row tracks after implicit rows were resolved, parallel to [rowSizes]. + /// + /// [RenderMixGrid.performLayout] needs the track *kind*, not just the size, + /// to decide which children may keep a tight cell constraint. + final List rowTracks; final List cells; const GridLayoutResult({ @@ -123,6 +129,7 @@ class GridLayoutResult { required this.contentSize, required this.columnSizes, required this.rowSizes, + required this.rowTracks, required this.cells, }); } @@ -196,6 +203,7 @@ GridLayoutResult computeGridLayout({ contentSize: Size(intrinsicWidth, intrinsicHeight), columnSizes: columnSizes, rowSizes: rowSizes, + rowTracks: rows, cells: cells, ); } @@ -313,12 +321,13 @@ class RenderMixGrid extends RenderBox final row = index ~/ columnCount; if (row < effectiveRows.length && effectiveRows[row] is AutoGridTrack) { final column = index % columnCount; - final measured = _measureAutoRowChild( - row: row, - constraints: BoxConstraints.tightFor(width: columnSizes[column]), - measureChild: measureChild, - child: child, + final measured = measureChild( + child, + BoxConstraints.tightFor(width: columnSizes[column]), ); + if (!measured.height.isFinite) { + throw _autoRowNeedsFiniteHeight(row, 'height ${measured.height}'); + } heights[row] = math.max(heights[row], measured.height); } child = (child.parentData! as MultiChildLayoutParentData).nextSibling; @@ -328,20 +337,6 @@ class RenderMixGrid extends RenderBox return heights; } - Size _measureAutoRowChild({ - required int row, - required BoxConstraints constraints, - required ChildLayouter measureChild, - required RenderBox child, - }) { - final measured = measureChild(child, constraints); - if (!measured.height.isFinite) { - throw _autoRowNeedsFiniteHeight(row, 'height ${measured.height}'); - } - - return measured; - } - /// Intrinsic extent after branch selection. /// /// Fractional tracks on the queried axis throw the same actionable @@ -518,7 +513,26 @@ class RenderMixGrid extends RenderBox while (child != null) { final parentData = child.parentData! as MultiChildLayoutParentData; final cell = result.cells[index]; - child.layout(BoxConstraints.tight(cell.size), parentUsesSize: false); + final isAutoRow = result.rowTracks[cell.row] is AutoGridTrack; + // An auto row's height is derived from this child, so the child must + // stay inside the grid's relayout boundary. A fully tight constraint + // would make the child its own boundary (see RenderObject.layout), so a + // later child-only change would never reach the grid and the row would + // keep the height measured on the first pass. An unbounded max height + // keeps the constraint loose enough to propagate, while the min height + // still stretches shorter siblings to fill the row. Fixed and fr rows + // keep the tight cell: their height never depends on the child, and + // tightness is the documented hard-constraint contract. + child.layout( + isAutoRow + ? BoxConstraints( + minWidth: cell.size.width, + maxWidth: cell.size.width, + minHeight: cell.size.height, + ) + : BoxConstraints.tight(cell.size), + parentUsesSize: isAutoRow, + ); parentData.offset = cell.offset; child = parentData.nextSibling; index++; diff --git a/packages/mix/test/src/layout/grid_box_test.dart b/packages/mix/test/src/layout/grid_box_test.dart index 56188156d..0199dab82 100644 --- a/packages/mix/test/src/layout/grid_box_test.dart +++ b/packages/mix/test/src/layout/grid_box_test.dart @@ -2218,6 +2218,110 @@ void main() { ); }, ); + + testWidgets('an auto row re-measures when only the child changes', ( + tester, + ) async { + // A tight cell constraint would make the child its own relayout + // boundary, so a child-only change would never reach the grid and the + // row would keep its first measured height. + Widget build(double height) => MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + child: GridBox( + style: const GridBoxStyler(columns: [GridTrack.fixed(100)]), + children: [SizedBox(key: const Key('a'), height: height)], + ), + ), + ), + ); + + await tester.pumpWidget(build(30)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 30)); + expect( + tester.renderObject(find.byType(MixGrid)).size.height, + 30, + ); + + await tester.pumpWidget(build(80)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 80)); + expect( + tester.renderObject(find.byType(MixGrid)).size.height, + 80, + ); + + await tester.pumpWidget(build(15)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 15)); + expect( + tester.renderObject(find.byType(MixGrid)).size.height, + 15, + ); + }); + + testWidgets('an auto-row child still stretches to fill the taller row', ( + tester, + ) async { + // The auto-row cell is loose on max height so the child stays inside the + // grid's relayout boundary. Min height must still stretch the child, and + // the child must distribute that stretched extent internally. + await tester.pumpWidget( + const MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 200, + child: GridBox( + style: GridBoxStyler( + columns: [GridTrack.fixed(100), GridTrack.fixed(100)], + ), + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(key: Key('top'), height: 10, width: 10), + SizedBox(key: Key('bottom'), height: 10, width: 10), + ], + ), + SizedBox(key: Key('tall'), height: 90), + ], + ), + ), + ), + ), + ); + + expect(tester.getSize(find.byKey(const Key('tall'))).height, 90); + expect(tester.getTopLeft(find.byKey(const Key('top'))).dy, 0); + expect(tester.getTopLeft(find.byKey(const Key('bottom'))).dy, 80); + }); + + testWidgets('a fixed row still hard-constrains a changing child', ( + tester, + ) async { + Widget build(double height) => MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + child: GridBox( + style: const GridBoxStyler( + columns: [GridTrack.fixed(100)], + rows: [GridTrack.fixed(40)], + ), + children: [SizedBox(key: const Key('a'), height: height)], + ), + ), + ), + ); + + await tester.pumpWidget(build(10)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 40)); + + await tester.pumpWidget(build(90)); + expect(tester.getSize(find.byKey(const Key('a'))), const Size(100, 40)); + }); }); } From 1c0107b3ee24181c70466a9625d267fa191045f7 Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Wed, 19 Aug 2026 10:20:52 -0400 Subject: [PATCH 4/7] chore(mix): tighten grid auto-row docs and comments Move the GridTrack design rationale out of the published dartdoc into a maintainer comment: it named a private helper and argued against a future refactor, neither of which belongs on pub.dev. Replace the only curly quotes in the Dart sources, rewrite two awkward autoRows doc sentences, drop the stringified Object parameter on the auto-row error helper, and rewrap two markdown lines that broke the wrap width their files otherwise keep. --- packages/mix/doc/grid-layout.md | 6 ++--- packages/mix/lib/src/layout/grid_box.dart | 11 +++++----- .../mix/lib/src/layout/grid_box_spec.dart | 4 ++-- packages/mix/lib/src/layout/grid_track.dart | 22 +++++++++---------- .../src/layout/internal/grid_geometry.dart | 2 +- packages/mix/lib/src/layout/render_grid.dart | 6 ++--- skills/mix/references/layout.md | 5 +++-- 7 files changed, 27 insertions(+), 29 deletions(-) diff --git a/packages/mix/doc/grid-layout.md b/packages/mix/doc/grid-layout.md index 1c20d925f..4d52c6132 100644 --- a/packages/mix/doc/grid-layout.md +++ b/packages/mix/doc/grid-layout.md @@ -19,9 +19,9 @@ GridBox(style: style, children: cards); ``` `GridTrack.fixed(size)` keeps its logical-pixel size and is a hard constraint: -children in a fixed row are stretched or clipped to that height. `GridTrack.fr(fraction)` -receives that fraction of the free space left after fixed tracks, auto tracks, -and gaps. For example, with 300 pixels of remaining space, `[.fr(2), .fr(1)]` +children in a fixed row are stretched or clipped to that height. +`GridTrack.fr(fraction)` receives that fraction of the free space left after +fixed tracks, auto tracks, and gaps. For example, with 300 pixels of remaining space, `[.fr(2), .fr(1)]` produces tracks of 200 and 100 pixels. Fractional tracks require a bounded parent extent on their axis. `GridTrack.auto()` is vertical-only: the row sizes to its tallest child's natural height at the resolved column width. diff --git a/packages/mix/lib/src/layout/grid_box.dart b/packages/mix/lib/src/layout/grid_box.dart index c2102014b..07693a639 100644 --- a/packages/mix/lib/src/layout/grid_box.dart +++ b/packages/mix/lib/src/layout/grid_box.dart @@ -40,8 +40,8 @@ class GridBoxStyler extends MixStyler /// Unresolved track repeated for rows required beyond [$rows]. /// - /// `null` means no override. Resolved geometry defaults omitted automatic - /// rows to [GridTrack.auto]. + /// `null` means no override, in which case implicit rows use + /// [GridTrack.auto]. final GridTrack? $autoRows; /// Unresolved logical-pixel gap between columns. @@ -98,10 +98,9 @@ class GridBoxStyler extends MixStyler /// Creates a style that repeats [autoRows] for undeclared rows. /// /// Children are placed row-major. Each row needed beyond [rows] uses this - /// track. Omitted [autoRows] defaults to [GridTrack.auto] on the complete - /// resolved geometry, so implicit rows size to their tallest child. A - /// fixed track is a hard height; a fractional track requires bounded - /// height. + /// track. Omitting it leaves implicit rows on [GridTrack.auto], so they + /// size to their tallest child. A fixed track is a hard height; a + /// fractional track requires bounded height. factory GridBoxStyler.autoRows(GridTrack autoRows) => GridBoxStyler(autoRows: autoRows); diff --git a/packages/mix/lib/src/layout/grid_box_spec.dart b/packages/mix/lib/src/layout/grid_box_spec.dart index 23bed9370..9c8dcfdad 100644 --- a/packages/mix/lib/src/layout/grid_box_spec.dart +++ b/packages/mix/lib/src/layout/grid_box_spec.dart @@ -128,8 +128,8 @@ final class GridBoxSpec extends Spec with Diagnosticable { /// Track repeated for each row required beyond [rows]. /// - /// `null` means no override. Resolved geometry defaults omitted automatic - /// rows to [GridTrack.auto]. + /// `null` means no override, in which case implicit rows use + /// [GridTrack.auto]. final GridTrack? autoRows; /// Logical-pixel gap between adjacent columns. diff --git a/packages/mix/lib/src/layout/grid_track.dart b/packages/mix/lib/src/layout/grid_track.dart index 161f3675a..cdcbb7306 100644 --- a/packages/mix/lib/src/layout/grid_track.dart +++ b/packages/mix/lib/src/layout/grid_track.dart @@ -4,18 +4,16 @@ import 'package:flutter/foundation.dart'; /// /// Rows accept fixed, fractional, and content-sized [GridTrack.auto] tracks. /// Columns accept only fixed and fractional tracks; content-sized columns -/// are intentionally outside this API. -/// -/// One type covers both axes, so "auto is rows-only" is a runtime rule -/// (see `_validateTracks` in `grid_box_spec.dart`) rather than a compile-time -/// one. Splitting this into row and column hierarchies was considered and -/// rejected: it would not remove the equivalent check in the wire codec — -/// JSON is untyped, so the schema must reject `auto` under `columns` -/// regardless of the Dart type — and the factories below have static type -/// `GridTrack`, so axis-specific lists would force duplicate factories or -/// give up the dot-shorthand (`.columns([.fr(1)])`) this API is built around. -/// The trade is one runtime throw against those two costs; do not "simplify" -/// this into a split without re-checking both. +/// are intentionally outside this API. Because one type covers both axes, +/// "auto is rows-only" is enforced at runtime rather than by the type system. +// Design note, deliberately not part of the published API docs: splitting this +// into row and column hierarchies was considered and rejected. It would not +// remove the equivalent check in the wire codec — JSON is untyped, so the +// schema must reject `auto` under `columns` regardless of the Dart type — and +// the factories below have static type `GridTrack`, so axis-specific lists +// would force duplicate factories or give up the dot-shorthand +// (`.columns([.fr(1)])`) this API is built around. The trade is one runtime +// throw against those two costs; do not split without re-checking both. @immutable sealed class GridTrack { /// Creates the base value for a concrete Grid track. diff --git a/packages/mix/lib/src/layout/internal/grid_geometry.dart b/packages/mix/lib/src/layout/internal/grid_geometry.dart index 9085c8762..11c1bcc8e 100644 --- a/packages/mix/lib/src/layout/internal/grid_geometry.dart +++ b/packages/mix/lib/src/layout/internal/grid_geometry.dart @@ -9,7 +9,7 @@ import 'grid_validation.dart'; /// Geometry after branch selection and before track sizing and placement. /// /// Omitted [autoRows] becomes [GridTrack.auto] here. Styler and patch fields -/// stay nullable so a missing value still means “no override.” +/// stay nullable so a missing value still means "no override". @immutable final class GridResolvedGeometry { final List columns; diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 19696ee04..4efeed3c5 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -326,7 +326,7 @@ class RenderMixGrid extends RenderBox BoxConstraints.tightFor(width: columnSizes[column]), ); if (!measured.height.isFinite) { - throw _autoRowNeedsFiniteHeight(row, 'height ${measured.height}'); + throw _autoRowNeedsFiniteHeight(row, measured.height); } heights[row] = math.max(heights[row], measured.height); } @@ -614,14 +614,14 @@ class RenderMixGrid extends RenderBox bool _hasAutoTrack(Iterable tracks) => tracks.any((track) => track is AutoGridTrack); -FlutterError _autoRowNeedsFiniteHeight(int row, Object cause) { +FlutterError _autoRowNeedsFiniteHeight(int row, double measuredHeight) { return FlutterError.fromParts([ ErrorSummary('Grid auto rows require children with a finite height.'), ErrorDescription( 'A child in row $row could not determine a finite height under ' 'unbounded vertical constraints.', ), - ErrorDescription('$cause'), + ErrorDescription('Measured height: $measuredHeight'), ErrorHint( 'Auto rows measure children at their column width with a loose ' 'height. Use finite-height content such as text or intrinsic boxes. ' diff --git a/skills/mix/references/layout.md b/skills/mix/references/layout.md index c9c23968a..1763db06a 100644 --- a/skills/mix/references/layout.md +++ b/skills/mix/references/layout.md @@ -239,8 +239,9 @@ final GridBoxStyler animatedGrid = .columns([ Keep track lists the same length and keep each positional track kind compatible (`fixed` with `fixed`, `fr` with `fr`, `auto` with `auto`) for continuous -interpolation. Compatible rows, `autoRows`, and gaps interpolate too. Track-count or track-kind changes, -clipping, and constraint-patch lists switch at the midpoint. A live +interpolation. Compatible rows, `autoRows`, and gaps interpolate too. +Track-count or track-kind changes, clipping, and constraint-patch lists +switch at the midpoint. A live `onConstraints` branch change remains immediate because selection happens during layout rather than creating a new animation target. From 88374df1b8b44c46cd777439d8e85ab07523a626 Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Wed, 19 Aug 2026 12:01:27 -0400 Subject: [PATCH 5/7] perf(mix): reuse the auto-row measure pass for children that fill the row An auto-row child was always laid out a second time, because the final constraint differed from the measure-pass one only in minHeight (0 -> row height). RenderObject.layout could not take its early return, so the whole subtree relaid out even when the measure already produced the row height. Hand a child that already fills its row the exact constraint it was measured with. That covers at least the tallest child of every auto row and every child of a single-child row, so nested auto grids stop multiplying layout passes per level: a leaf inside three nested auto Grids goes from 8 relayouts to 1. Only children shorter than the row are laid out again to stretch them. The relayout-boundary rationale moves into _cellConstraints, with a note to keep the constraint identical to the measure-pass one. _RenderLayoutCallCounter now counts performLayout executions, not just layout calls; the old assertion stayed green through the extra pass because layout() is still called twice, it just early-returns now. Also correct the CHANGELOG, doc/grid-layout.md, and the layout skill reference, which documented the 2^n nesting cost as inherent, and mark the unreachable fractional branch in _computeAutoRowIntrinsicHeight as such. --- packages/mix/CHANGELOG.md | 8 +- packages/mix/doc/grid-layout.md | 20 +-- packages/mix/lib/src/layout/render_grid.dart | 65 ++++++--- .../mix/test/src/layout/grid_box_test.dart | 125 +++++++++++++++++- skills/mix/references/layout.md | 7 +- 5 files changed, 184 insertions(+), 41 deletions(-) diff --git a/packages/mix/CHANGELOG.md b/packages/mix/CHANGELOG.md index d967cc2d9..596a310b7 100644 --- a/packages/mix/CHANGELOG.md +++ b/packages/mix/CHANGELOG.md @@ -21,10 +21,10 @@ so implicit rows size to their tallest child — both when no rows are declared and when some explicit rows exist but are not enough. Fractional rows still require a bounded height. Fixed tracks remain hard constraints. - Because the new default opts a Grid into the measure-then-stretch pass, - nesting compounds it: a leaf inside one auto Grid is laid out twice, and - inside three nested auto Grids eight times. Give inner levels fixed rows - once their heights are known. + The new default opts a Grid into a measure pass, after which only a child + shorter than its resolved row is laid out again to stretch it; a child that + already fills its row reuses the measure pass, so nesting auto Grids does + not compound the cost. ## 2.2.0-beta.4 diff --git a/packages/mix/doc/grid-layout.md b/packages/mix/doc/grid-layout.md index 4d52c6132..93b919863 100644 --- a/packages/mix/doc/grid-layout.md +++ b/packages/mix/doc/grid-layout.md @@ -90,15 +90,17 @@ empty, every required row uses `autoRows` (or `auto` when it is omitted). Use `GridTrack.auto()` — or omit `autoRows` — in a vertical `SingleChildScrollView` when child heights are unknown. Auto-row children are -measured at their column width, then laid out again into the stretched cell so -shorter siblings fill the row. That extra measure pass runs only for children -in auto rows; explicit fixed/`fr` Grids still lay each child out once. - -Nesting compounds that cost. Each auto-row level measures its subtree and then -lays it out again, so the passes multiply rather than add: a leaf inside one -auto Grid is laid out twice, and inside three nested auto Grids it is laid out -eight times. For deep hierarchies, prefer a single Grid, or give the inner -levels fixed rows once their heights are known. +measured at their column width, and a child shorter than the resolved row is +then laid out a second time so it fills the row. A child that already fills +its row — always the tallest, and every child when a row holds one — is handed +back the constraint it was measured with, so its subtree is not relaid out. +That measure pass runs only for children in auto rows; explicit fixed/`fr` +Grids still lay each child out once. + +Nesting therefore stays flat rather than compounding: a leaf inside three +nested auto Grids is laid out once, the same as inside one. The extra pass is +paid only by the shorter siblings a row actually has to stretch, so rows of +uneven children cost more than uniform ones. Fixed rows stay hard heights. Fractional rows and fractional `autoRows` still require bounded height. Auto rows require children with a finite natural diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 4efeed3c5..3728b3125 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -437,8 +437,11 @@ class RenderMixGrid extends RenderBox switch (effectiveRows[row]) { FixedGridTrack(:final size) => size, AutoGridTrack() => autoRowHeights[row], - // Fractional rows draw from free space, which an intrinsic query - // has none of. + // A fractional row never reaches here: an intrinsic height query is + // always built with an unbounded max height, and + // rejectFractionalGridTracksOnUnboundedAxis has already thrown on + // these tracks. The case exists only to satisfy the sealed + // exhaustiveness check; 0.0 matches what free space would give. FrGridTrack() => 0.0, }, ]; @@ -446,6 +449,47 @@ class RenderMixGrid extends RenderBox return axisExtent(rowExtents, geometry.rowGap); } + /// Final layout constraint for [child] in [cell], used by [performLayout]. + /// + /// Fixed and fr rows keep the tight cell: their height never depends on the + /// child, and tightness is the documented hard-constraint contract. + /// + /// An auto row's height is derived from its children, so those children must + /// stay inside the grid's relayout boundary. A fully tight constraint would + /// make the child its own boundary (see [RenderObject.layout]), so a later + /// child-only change would never reach the grid and the row would keep the + /// height measured on the first pass. Leaving max height unbounded keeps the + /// constraint loose enough to propagate, while the min height stretches + /// shorter siblings to fill the row. + /// + /// A child that already fills its row gets back the *exact* constraint + /// [_measureAutoRowHeights] used, so [RenderObject.layout] takes its + /// `!_needsLayout && constraints == _constraints` early return instead of + /// running the subtree a second time. That covers at least the tallest child + /// of every auto row, and every child of a single-child row — which is what + /// stops nested auto grids from multiplying layout passes per level. Keep + /// this constraint identical to the measure-pass one; widening it here would + /// silently reintroduce the second pass. + BoxConstraints _cellConstraints( + RenderBox child, + GridCellGeometry cell, { + required bool isAutoRow, + }) { + if (!isAutoRow) return BoxConstraints.tight(cell.size); + // Safe to read: auto-row children were laid out with parentUsesSize during + // the measure pass. A row's height is the max of those measurements, so + // `>=` only ever matches a child that needs no stretching. + if (child.size.height >= cell.size.height) { + return BoxConstraints.tightFor(width: cell.size.width); + } + + return BoxConstraints( + minWidth: cell.size.width, + maxWidth: cell.size.width, + minHeight: cell.size.height, + ); + } + bool get _hasVisualOverflow => _contentSize.width - size.width > precisionErrorTolerance || _contentSize.height - size.height > precisionErrorTolerance; @@ -514,23 +558,8 @@ class RenderMixGrid extends RenderBox final parentData = child.parentData! as MultiChildLayoutParentData; final cell = result.cells[index]; final isAutoRow = result.rowTracks[cell.row] is AutoGridTrack; - // An auto row's height is derived from this child, so the child must - // stay inside the grid's relayout boundary. A fully tight constraint - // would make the child its own boundary (see RenderObject.layout), so a - // later child-only change would never reach the grid and the row would - // keep the height measured on the first pass. An unbounded max height - // keeps the constraint loose enough to propagate, while the min height - // still stretches shorter siblings to fill the row. Fixed and fr rows - // keep the tight cell: their height never depends on the child, and - // tightness is the documented hard-constraint contract. child.layout( - isAutoRow - ? BoxConstraints( - minWidth: cell.size.width, - maxWidth: cell.size.width, - minHeight: cell.size.height, - ) - : BoxConstraints.tight(cell.size), + _cellConstraints(child, cell, isAutoRow: isAutoRow), parentUsesSize: isAutoRow, ); parentData.offset = cell.offset; diff --git a/packages/mix/test/src/layout/grid_box_test.dart b/packages/mix/test/src/layout/grid_box_test.dart index 0199dab82..a45da368b 100644 --- a/packages/mix/test/src/layout/grid_box_test.dart +++ b/packages/mix/test/src/layout/grid_box_test.dart @@ -1882,7 +1882,7 @@ void main() { }, ); - testWidgets('auto-row children are laid out twice; others once', ( + testWidgets('a child that already fills its auto row is not relaid out', ( tester, ) async { await tester.pumpWidget( @@ -1897,8 +1897,8 @@ void main() { rows: const [GridTrack.auto(), GridTrack.fixed(40)], ), children: const [ - _LayoutCallCounter(key: Key('auto')), - _LayoutCallCounter(key: Key('fixed')), + _LayoutCallCounter(key: Key('auto'), height: 30), + _LayoutCallCounter(key: Key('fixed'), height: 10), ], ), ), @@ -1911,8 +1911,82 @@ void main() { find.byType(_LayoutCallCounter), ) .toList(); + // The auto-row child is measured, then handed the same constraint again + // so RenderObject.layout early-returns: two calls, one relayout. expect(counters[0].layoutCount, 2); + expect(counters[0].performLayoutCount, 1); expect(counters[1].layoutCount, 1); + expect(counters[1].performLayoutCount, 1); + }); + + testWidgets('a shorter auto-row sibling is relaid out to fill the row', ( + tester, + ) async { + await tester.pumpWidget( + MaterialApp( + home: Center( + child: SizedBox( + width: 200, + child: MixGrid( + spec: GridBoxSpec( + columns: const [GridTrack.fixed(100), GridTrack.fixed(100)], + ), + children: const [ + _LayoutCallCounter(key: Key('short'), height: 20), + _LayoutCallCounter(key: Key('tall'), height: 60), + ], + ), + ), + ), + ), + ); + + final counters = tester + .renderObjectList<_RenderLayoutCallCounter>( + find.byType(_LayoutCallCounter), + ) + .toList(); + expect(counters[0].performLayoutCount, 2, reason: 'stretched to 60'); + expect(counters[1].performLayoutCount, 1, reason: 'already 60 tall'); + expect(tester.getSize(find.byKey(const Key('short'))).height, 60); + }); + + testWidgets('nesting auto grids does not multiply leaf layout passes', ( + tester, + ) async { + // The measure pass hands each level the same constraint its parent used, + // so a leaf that fills its row stays at one relayout no matter how deep + // the nesting goes. Without that, cost is 2^depth. + Widget nest(int depth) { + Widget current = const _LayoutCallCounter(key: Key('leaf'), height: 25); + for (var level = 0; level < depth; level++) { + current = GridBox( + style: const GridBoxStyler(columns: [GridTrack.fixed(100)]), + children: [current], + ); + } + + return current; + } + + for (final depth in [1, 2, 3]) { + // Force a fresh render object so counts never carry across depths. + await tester.pumpWidget(const SizedBox()); + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox(width: 100, child: nest(depth)), + ), + ), + ); + + final leaf = tester.renderObject<_RenderLayoutCallCounter>( + find.byKey(const Key('leaf')), + ); + expect(leaf.performLayoutCount, 1, reason: 'depth=$depth'); + expect(tester.getSize(find.byKey(const Key('leaf'))).height, 25); + } }); testWidgets('live and dry sizes match for deterministic auto-row boxes', ( @@ -2336,23 +2410,60 @@ class _WidthDrivenHeight extends StatelessWidget { } } -class _LayoutCallCounter extends SingleChildRenderObjectWidget { - const _LayoutCallCounter({super.key}); +class _LayoutCallCounter extends LeafRenderObjectWidget { + const _LayoutCallCounter({super.key, this.height = 0}); + + /// Natural height, so the counter can act as a tall or short auto-row child. + final double height; @override _RenderLayoutCallCounter createRenderObject(BuildContext context) { - return _RenderLayoutCallCounter(); + return _RenderLayoutCallCounter(height); + } + + @override + void updateRenderObject( + BuildContext context, + _RenderLayoutCallCounter renderObject, + ) { + renderObject.naturalHeight = height; } } -class _RenderLayoutCallCounter extends RenderProxyBox { +class _RenderLayoutCallCounter extends RenderBox { + _RenderLayoutCallCounter(this._naturalHeight); + + double _naturalHeight; + int layoutCount = 0; + /// Times the subtree actually relaid out. + /// + /// [layout] can be called without doing any work when the constraints are + /// unchanged, so this is the metric that tracks real cost. + int performLayoutCount = 0; + + set naturalHeight(double value) { + if (_naturalHeight == value) return; + _naturalHeight = value; + markNeedsLayout(); + } + @override void layout(Constraints constraints, {bool parentUsesSize = false}) { layoutCount++; super.layout(constraints, parentUsesSize: parentUsesSize); } + + @override + Size computeDryLayout(BoxConstraints constraints) => + constraints.constrain(Size(constraints.minWidth, _naturalHeight)); + + @override + void performLayout() { + performLayoutCount++; + size = computeDryLayout(constraints); + } } class _ThrowingLayoutBox extends LeafRenderObjectWidget { diff --git a/skills/mix/references/layout.md b/skills/mix/references/layout.md index 1763db06a..65090b83b 100644 --- a/skills/mix/references/layout.md +++ b/skills/mix/references/layout.md @@ -146,9 +146,10 @@ Interpret tracks as follows: - `.fr(2)` receives twice the remaining space of `.fr(1)` after fixed tracks, auto tracks, and gaps. - `.auto()` is vertical-only and sizes the row to its tallest child's natural - height at the resolved column width. Auto-row children are measured, then - laid out again into the stretched cell. That extra pass is only for children - in auto rows. + height at the resolved column width. Auto-row children are measured at that + width; only a child shorter than the resolved row is laid out again to + stretch it. That extra pass is only for children in auto rows, and nesting + auto Grids does not compound it. - Fractional columns require bounded width. - Fractional rows and fractional `autoRows` require bounded height. From e924e03dee67bc58bf293031d5f3816e9e0895ea Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Wed, 19 Aug 2026 13:35:24 -0400 Subject: [PATCH 6/7] test(mix): pin auto-row relayout to a child-driven height change The existing relayout test drives height from a parent rebuild, which reaches the grid through the widget tree whatever constraint the cell carries. That does not isolate the invariant it claims to protect. This one changes height entirely below the grid via the child's own setState, with GridBoxSpec untouched so MixGrid.updateRenderObject no-ops. The only route back to the grid is markNeedsLayout propagating past the child, which a tight cell would stop by making the child its own relayout boundary. That models the real reported case: an async image or an expanding tile inside a scroll view. Verified as a real guard: restoring the pre-fix constraint (tight cell, parentUsesSize false) fails it with the row stuck at its first measured height, 30 where 90 is expected. --- .../mix/test/src/layout/grid_box_test.dart | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/mix/test/src/layout/grid_box_test.dart b/packages/mix/test/src/layout/grid_box_test.dart index a45da368b..f93a712ca 100644 --- a/packages/mix/test/src/layout/grid_box_test.dart +++ b/packages/mix/test/src/layout/grid_box_test.dart @@ -2334,6 +2334,44 @@ void main() { ); }); + testWidgets('an auto row grows when a child resizes itself via setState', ( + tester, + ) async { + // The test above drives the height from a parent rebuild, which reaches + // the grid through the widget tree regardless of the constraint. This + // one changes height entirely below the grid, with GridBoxSpec untouched + // so MixGrid.updateRenderObject no-ops. The only path back to the grid is + // markNeedsLayout propagating past the child, which a tight cell would + // have stopped by making the child its own relayout boundary. Models the + // real case: an async image or an expanding tile inside a scroll view. + final key = GlobalKey<_ResizableState>(); + await tester.pumpWidget( + MaterialApp( + home: Align( + alignment: Alignment.topLeft, + child: SizedBox( + width: 100, + child: GridBox( + style: const GridBoxStyler(columns: [GridTrack.fixed(100)]), + children: [_Resizable(key: key, initialHeight: 30)], + ), + ), + ), + ), + ); + + final grid = tester.renderObject(find.byType(MixGrid)); + expect(grid.size.height, 30); + + key.currentState!.setHeight(90); + await tester.pump(); + expect(grid.size.height, 90, reason: 'row must follow the child upward'); + + key.currentState!.setHeight(20); + await tester.pump(); + expect(grid.size.height, 20, reason: 'and back down'); + }); + testWidgets('an auto-row child still stretches to fill the taller row', ( tester, ) async { @@ -2466,6 +2504,25 @@ class _RenderLayoutCallCounter extends RenderBox { } } +/// Changes its own height from below the grid, without any parent rebuild. +class _Resizable extends StatefulWidget { + const _Resizable({super.key, required this.initialHeight}); + + final double initialHeight; + + @override + State<_Resizable> createState() => _ResizableState(); +} + +class _ResizableState extends State<_Resizable> { + late double _height = widget.initialHeight; + + void setHeight(double value) => setState(() => _height = value); + + @override + Widget build(BuildContext context) => SizedBox(height: _height); +} + class _ThrowingLayoutBox extends LeafRenderObjectWidget { const _ThrowingLayoutBox(); From 3a1a847dde4b563eb5479b1033ca67408496b5ba Mon Sep 17 00:00:00 2001 From: Leo Farias Date: Wed, 19 Aug 2026 13:52:45 -0400 Subject: [PATCH 7/7] docs(mix): sharpen the grid auto-row changelog entries The feature entry hedged ("may be measured and then stretched") and repeated the layout-pass accounting that the breaking-change entry also carried, while neither said what an auto row actually does or when to reach for one. State the behaviour once, in the feature entry, and give the breaking entry what a breaking note is for: the migration. A reader who relied on the throw to catch an under-declared Grid now gets told to declare rows or set autoRows. Also drop a redundant clause from _cellConstraints: a single-child row's only child is by definition its tallest, so naming both cases said one thing twice. --- packages/mix/CHANGELOG.md | 28 ++++++++++---------- packages/mix/lib/src/layout/render_grid.dart | 9 +++---- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/mix/CHANGELOG.md b/packages/mix/CHANGELOG.md index 596a310b7..39c880a9c 100644 --- a/packages/mix/CHANGELOG.md +++ b/packages/mix/CHANGELOG.md @@ -2,10 +2,12 @@ ### New features -- **GridTrack.auto():** Vertical auto tracks for explicit `rows` and - `autoRows`. `auto` is vertical-only; columns still reject it. Existing - explicit fixed/`fr` layouts keep a single child layout per pass. Auto-row - children may be measured and then stretched. +- **`GridTrack.auto()`:** Content-sized row tracks for `rows` and `autoRows`. + An auto row sizes to its tallest child's natural height at the resolved + column width, then stretches shorter children to fill the row. Use it — or + omit `autoRows` — when child heights are unknown, such as a card grid in a + scroll view. `auto` is vertical-only; `columns` rejects it. Grids built only + from fixed and `fr` tracks are unaffected and still lay each child out once. - **Generated Styler field metadata:** Every generated Styler now exposes its complete source-field inventory through `StylerFieldMetadata.$stylerFieldNames`, allowing schema tooling to validate @@ -15,16 +17,14 @@ ### Breaking changes -- **Omitted GridBox autoRows no longer throws:** Previously, children that - needed more rows than were declared required an explicit `autoRows` track - or the grid threw. Omitted `autoRows` now defaults to `GridTrack.auto()`, - so implicit rows size to their tallest child — both when no rows are - declared and when some explicit rows exist but are not enough. Fractional - rows still require a bounded height. Fixed tracks remain hard constraints. - The new default opts a Grid into a measure pass, after which only a child - shorter than its resolved row is laid out again to stretch it; a child that - already fills its row reuses the measure pass, so nesting auto Grids does - not compound the cost. +- **Omitted GridBox `autoRows` no longer throws:** Children needing more rows + than were declared previously required an explicit `autoRows` track, or the + Grid threw. Omitted `autoRows` now defaults to `GridTrack.auto()`, so + implicit rows size to their tallest child — both when no rows are declared + and when explicit rows run out. Fractional rows still require a bounded + height, and fixed tracks remain hard constraints. If you relied on the throw + to catch an under-declared Grid, declare `rows` explicitly or set `autoRows` + to the track you want repeated. ## 2.2.0-beta.4 diff --git a/packages/mix/lib/src/layout/render_grid.dart b/packages/mix/lib/src/layout/render_grid.dart index 3728b3125..2a48ac912 100644 --- a/packages/mix/lib/src/layout/render_grid.dart +++ b/packages/mix/lib/src/layout/render_grid.dart @@ -465,11 +465,10 @@ class RenderMixGrid extends RenderBox /// A child that already fills its row gets back the *exact* constraint /// [_measureAutoRowHeights] used, so [RenderObject.layout] takes its /// `!_needsLayout && constraints == _constraints` early return instead of - /// running the subtree a second time. That covers at least the tallest child - /// of every auto row, and every child of a single-child row — which is what - /// stops nested auto grids from multiplying layout passes per level. Keep - /// this constraint identical to the measure-pass one; widening it here would - /// silently reintroduce the second pass. + /// running the subtree a second time. Every auto row has at least one such + /// child, which is what stops nested auto grids from multiplying layout + /// passes per level. Keep this constraint identical to the measure-pass one; + /// widening it here would silently reintroduce the second pass. BoxConstraints _cellConstraints( RenderBox child, GridCellGeometry cell, {