Unverified Commit d907a262 authored by Ben Konyi's avatar Ben Konyi Committed by GitHub

Fixed issue where PaginatedDataTable would not fill the width of its containing Card (#48531)

parent 31f399f9
...@@ -426,75 +426,82 @@ class PaginatedDataTableState extends State<PaginatedDataTable> { ...@@ -426,75 +426,82 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
]); ]);
// CARD // CARD
return Card( return LayoutBuilder(
semanticContainer: false, builder: (BuildContext context, BoxConstraints constraints) {
child: Column( return Card(
crossAxisAlignment: CrossAxisAlignment.stretch, semanticContainer: false,
children: <Widget>[ child: Column(
Semantics( crossAxisAlignment: CrossAxisAlignment.stretch,
container: true, children: <Widget>[
child: DefaultTextStyle( Semantics(
// These typographic styles aren't quite the regular ones. We pick the closest ones from the regular container: true,
// list and then tweak them appropriately. child: DefaultTextStyle(
// See https://material.io/design/components/data-tables.html#tables-within-cards // These typographic styles aren't quite the regular ones. We pick the closest ones from the regular
style: _selectedRowCount > 0 ? themeData.textTheme.subhead.copyWith(color: themeData.accentColor) // list and then tweak them appropriately.
: themeData.textTheme.title.copyWith(fontWeight: FontWeight.w400), // See https://material.io/design/components/data-tables.html#tables-within-cards
child: IconTheme.merge( style: _selectedRowCount > 0 ? themeData.textTheme.subhead.copyWith(color: themeData.accentColor)
data: const IconThemeData( : themeData.textTheme.title.copyWith(fontWeight: FontWeight.w400),
opacity: 0.54 child: IconTheme.merge(
), data: const IconThemeData(
child: Ink( opacity: 0.54
height: 64.0, ),
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null, child: Ink(
child: Padding( height: 64.0,
padding: EdgeInsetsDirectional.only(start: startPadding, end: 14.0), color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
child: Row( child: Padding(
mainAxisAlignment: MainAxisAlignment.end, padding: EdgeInsetsDirectional.only(start: startPadding, end: 14.0),
children: headerWidgets, child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: headerWidgets,
),
),
), ),
), ),
), ),
), ),
), SingleChildScrollView(
), scrollDirection: Axis.horizontal,
SingleChildScrollView( dragStartBehavior: widget.dragStartBehavior,
scrollDirection: Axis.horizontal, child: ConstrainedBox(
dragStartBehavior: widget.dragStartBehavior, constraints: BoxConstraints(minWidth: constraints.minWidth),
child: DataTable( child: DataTable(
key: _tableKey, key: _tableKey,
columns: widget.columns, columns: widget.columns,
sortColumnIndex: widget.sortColumnIndex, sortColumnIndex: widget.sortColumnIndex,
sortAscending: widget.sortAscending, sortAscending: widget.sortAscending,
onSelectAll: widget.onSelectAll, onSelectAll: widget.onSelectAll,
dataRowHeight: widget.dataRowHeight, dataRowHeight: widget.dataRowHeight,
headingRowHeight: widget.headingRowHeight, headingRowHeight: widget.headingRowHeight,
horizontalMargin: widget.horizontalMargin, horizontalMargin: widget.horizontalMargin,
columnSpacing: widget.columnSpacing, columnSpacing: widget.columnSpacing,
showCheckboxColumn: widget.showCheckboxColumn, rows: _getRows(_firstRowIndex, widget.rowsPerPage),
rows: _getRows(_firstRowIndex, widget.rowsPerPage), ),
), ),
),
DefaultTextStyle(
style: footerTextStyle,
child: IconTheme.merge(
data: const IconThemeData(
opacity: 0.54
), ),
child: Container( DefaultTextStyle(
height: 56.0, style: footerTextStyle,
child: SingleChildScrollView( child: IconTheme.merge(
dragStartBehavior: widget.dragStartBehavior, data: const IconThemeData(
scrollDirection: Axis.horizontal, opacity: 0.54
reverse: true, ),
child: Row( child: Container(
children: footerWidgets, // TODO(bkonyi): this won't handle text zoom correctly, https://github.com/flutter/flutter/issues/48522
height: 56.0,
child: SingleChildScrollView(
dragStartBehavior: widget.dragStartBehavior,
scrollDirection: Axis.horizontal,
reverse: true,
child: Row(
children: footerWidgets,
),
),
), ),
), ),
), ),
), ],
), ),
], );
), },
); );
} }
} }
...@@ -50,6 +50,9 @@ class TestDataSource extends DataTableSource { ...@@ -50,6 +50,9 @@ class TestDataSource extends DataTableSource {
} }
void main() { void main() {
final TestWidgetsFlutterBinding binding =
TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
testWidgets('PaginatedDataTable paging', (WidgetTester tester) async { testWidgets('PaginatedDataTable paging', (WidgetTester tester) async {
final TestDataSource source = TestDataSource(); final TestDataSource source = TestDataSource();
...@@ -382,6 +385,16 @@ void main() { ...@@ -382,6 +385,16 @@ void main() {
const double _defaultColumnSpacing = 56.0; const double _defaultColumnSpacing = 56.0;
const double _customHorizontalMargin = 10.0; const double _customHorizontalMargin = 10.0;
const double _customColumnSpacing = 15.0; const double _customColumnSpacing = 15.0;
const double _width = 400;
const double _height = 400;
final Size originalSize = binding.renderView.size;
// Ensure the containing Card is small enough that we don't expand too
// much, resulting in our custom margin being ignored.
await binding.setSurfaceSize(const Size(_width, _height));
final TestDataSource source = TestDataSource( final TestDataSource source = TestDataSource(
onSelectChanged: (bool value) {}, onSelectChanged: (bool value) {},
); );
...@@ -527,6 +540,9 @@ void main() { ...@@ -527,6 +540,9 @@ void main() {
tester.getRect(padding).right - tester.getRect(cellContent).right, tester.getRect(padding).right - tester.getRect(cellContent).right,
_customHorizontalMargin, _customHorizontalMargin,
); );
// Reset the surface size.
await binding.setSurfaceSize(originalSize);
}); });
testWidgets('PaginatedDataTable custom horizontal padding - no checkbox', (WidgetTester tester) async { testWidgets('PaginatedDataTable custom horizontal padding - no checkbox', (WidgetTester tester) async {
...@@ -651,4 +667,63 @@ void main() { ...@@ -651,4 +667,63 @@ void main() {
_customHorizontalMargin, _customHorizontalMargin,
); );
}); });
testWidgets('PaginatedDataTable table fills Card width', (WidgetTester tester) async {
final TestDataSource source = TestDataSource();
// Note: 800 is wide enough to ensure that all of the columns fit in the
// Card. The DataTable can be larger than its containing Card, but this test
// is only concerned with ensuring the DataTable is at least as wide as the
// Card.
const double _originalWidth = 800;
const double _expandedWidth = 1600;
const double _height = 400;
final Size originalSize = binding.renderView.size;
Widget buildWidget() => MaterialApp(
home: PaginatedDataTable(
header: const Text('Test table'),
source: source,
rowsPerPage: 2,
availableRowsPerPage: const <int>[
2, 4, 8, 16,
],
onRowsPerPageChanged: (int rowsPerPage) {},
onPageChanged: (int rowIndex) {},
columns: const <DataColumn>[
DataColumn(label: Text('Name')),
DataColumn(label: Text('Calories'), numeric: true),
DataColumn(label: Text('Generation')),
],
),
);
await binding.setSurfaceSize(const Size(_originalWidth, _height));
await tester.pumpWidget(buildWidget());
// Widths should be equal before we resize...
expect(
tester.renderObject<RenderBox>(find.byType(DataTable).first).size.width,
moreOrLessEquals(
tester.renderObject<RenderBox>(find.byType(Card).first).size.width)
);
await binding.setSurfaceSize(const Size(_expandedWidth, _height));
await tester.pumpWidget(buildWidget());
final double cardWidth = tester.renderObject<RenderBox>(find.byType(Card).first).size.width;
// ... and should still be equal after the resize.
expect(
tester.renderObject<RenderBox>(find.byType(DataTable).first).size.width,
moreOrLessEquals(cardWidth)
);
// Double check to ensure we actually resized the surface properly.
expect(cardWidth, moreOrLessEquals(_expandedWidth));
// Reset the surface size.
await binding.setSurfaceSize(originalSize);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment