Skip to content

Table: baseline-aligned cells ignore rowSpan #193626

Description

@hm21

Follow-up to #177102 (colSpan / rowSpan support in TableCell), tracking the TODO(hm21) in the baseline case of RenderTable.performLayout. Agreed as a follow-up in the review: #177102 (comment)

Steps to reproduce

  1. Check out the branch of feat(table): add support for colSpan and rowSpan in TableCell #177102.
  2. Build a baseline-aligned Table in which a TableCell(rowSpan: 2) is taller than the row it starts in (code sample below).
  3. Compare the row heights.

Expected results

A spanning cell is sized like the other alignments: it does not add its height to the row it starts in, and the rows it covers only grow if the cell needs more room than they provide. For baseline alignment, close to HTML's vertical-align: baseline on a rowspan cell, that means:

  • the cell aligns its baseline with the baseline of the first row, so only its ascent counts toward that row's beforeBaselineDistance;
  • its descent is not added to the first row. Once the first row's baseline is known, the height the cell needs from the top of that row is recorded for the last row it covers, the same way top, middle and bottom rowSpan cells are handled.

In the sample, row 0 is 50 tall (ascent 45 of T, descent 5 of A) and row 1 is 20 tall. T reaches from 0 to 60, into row 1. The table is 70 tall.

Actual results

The baseline case never looks at rowSpan, so the whole height of the cell goes into the row it starts in:

row0=60.0 row1=20.0 table=80.0
T=Rect.fromLTRB(0.0, 0.0, 100.0, 60.0)
A=Rect.fromLTRB(100.0, 30.0, 200.0, 50.0)

The same applies to a baseline-aligned cell without a real baseline (it is top-aligned, but its height also goes into its first row).

Code sample

Code sample
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('baseline-aligned cell with rowSpan', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Align(
          alignment: Alignment.topLeft,
          child: Table(
            defaultColumnWidth: const FixedColumnWidth(100),
            defaultVerticalAlignment: TableCellVerticalAlignment.baseline,
            textBaseline: TextBaseline.alphabetic,
            children: const <TableRow>[
              TableRow(
                children: <Widget>[
                  TableCell(rowSpan: 2, child: Text('T', style: TextStyle(fontSize: 60))),
                  Text('A', style: TextStyle(fontSize: 20)),
                ],
              ),
              TableRow(
                children: <Widget>[
                  TableCell.none,
                  Text('B', style: TextStyle(fontSize: 20)),
                ],
              ),
            ],
          ),
        ),
      ),
    );
    final RenderTable table = tester.renderObject(find.byType(Table));
    debugPrint(
      'row0=${table.getRowBox(0).height} row1=${table.getRowBox(1).height} '
      'table=${table.size.height}',
    );
  });
}

Flutter Doctor output

Framework at 664fb94 (branch of #177102, based on master 3829a94). Not reproducible on master yet, since rowSpan only exists on that branch. The test font (FlutterTest) makes a 60 pixel line 60 tall with its baseline at 45.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    frameworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions