Skip to content

[flutter_markdown] Allow tables to be scrollable with IntrinsicColumnWidth #8526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/flutter_markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.7.6

* Adds horizontal scrolling for table when using `tableColumnWidth: IntrinsicColumnWidth()`.
* Adds styleSheet option `tableScrollbarThumbVisibility` for setting the `thumbVisibility` on tables' `ScrollBar`.

## 0.7.5

* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
Expand Down
4 changes: 3 additions & 1 deletion packages/flutter_markdown/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,14 @@ class MarkdownBuilder implements md.NodeVisitor {
);
}
} else if (tag == 'table') {
if (styleSheet.tableColumnWidth is FixedColumnWidth) {
if (styleSheet.tableColumnWidth is FixedColumnWidth ||
styleSheet.tableColumnWidth is IntrinsicColumnWidth) {
child = _ScrollControllerBuilder(
builder: (BuildContext context,
ScrollController tableScrollController, Widget? child) {
return Scrollbar(
controller: tableScrollController,
thumbVisibility: styleSheet.tableScrollbarThumbVisibility,
child: SingleChildScrollView(
controller: tableScrollController,
scrollDirection: Axis.horizontal,
Expand Down
7 changes: 7 additions & 0 deletions packages/flutter_markdown/lib/src/style_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class MarkdownStyleSheet {
this.tablePadding,
this.tableBorder,
this.tableColumnWidth,
this.tableScrollbarThumbVisibility,
this.tableCellsPadding,
this.tableCellsDecoration,
this.tableVerticalAlignment = TableCellVerticalAlignment.middle,
Expand Down Expand Up @@ -375,6 +376,7 @@ class MarkdownStyleSheet {
EdgeInsets? tablePadding,
TableBorder? tableBorder,
TableColumnWidth? tableColumnWidth,
bool? tableScrollbarThumbVisibility,
EdgeInsets? tableCellsPadding,
Decoration? tableCellsDecoration,
TableCellVerticalAlignment? tableVerticalAlignment,
Expand Down Expand Up @@ -441,6 +443,7 @@ class MarkdownStyleSheet {
tablePadding: tablePadding ?? this.tablePadding,
tableBorder: tableBorder ?? this.tableBorder,
tableColumnWidth: tableColumnWidth ?? this.tableColumnWidth,
tableScrollbarThumbVisibility: tableScrollbarThumbVisibility,
tableCellsPadding: tableCellsPadding ?? this.tableCellsPadding,
tableCellsDecoration: tableCellsDecoration ?? this.tableCellsDecoration,
tableVerticalAlignment:
Expand Down Expand Up @@ -508,6 +511,7 @@ class MarkdownStyleSheet {
tablePadding: other.tablePadding,
tableBorder: other.tableBorder,
tableColumnWidth: other.tableColumnWidth,
tableScrollbarThumbVisibility: other.tableScrollbarThumbVisibility,
tableCellsPadding: other.tableCellsPadding,
tableCellsDecoration: other.tableCellsDecoration,
tableVerticalAlignment: other.tableVerticalAlignment,
Expand Down Expand Up @@ -633,6 +637,9 @@ class MarkdownStyleSheet {
/// The [TableColumnWidth] to use for `th` and `td` elements.
final TableColumnWidth? tableColumnWidth;

/// The scrollbar thumbVisibility when the table is scrollable.
final bool? tableScrollbarThumbVisibility;

/// The padding to use for `th` and `td` elements.
final EdgeInsets? tableCellsPadding;

Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_markdown/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
version: 0.7.5
version: 0.7.6

environment:
sdk: ^3.4.0
Expand Down
30 changes: 29 additions & 1 deletion packages/flutter_markdown/test/scrollable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void defineTests() {
);

testWidgets(
'table',
'table with fixed column width',
(WidgetTester tester) async {
const String data = '|Header 1|Header 2|Header 3|'
'\n|-----|-----|-----|'
Expand All @@ -140,6 +140,34 @@ void defineTests() {
},
);

testWidgets(
'table with intrinsic column width',
(WidgetTester tester) async {
const String data = '|Header 1|Header 2|Header 3|'
'\n|-----|-----|-----|'
'\n|Col 1|Col 2|Col 3|';
await tester.pumpWidget(
boilerplate(
MediaQuery(
data: const MediaQueryData(),
child: MarkdownBody(
data: data,
styleSheet: MarkdownStyleSheet(
tableColumnWidth: const IntrinsicColumnWidth(),
),
),
),
),
);

final Iterable<Widget> widgets = tester.allWidgets;
final Iterable<SingleChildScrollView> scrollViews =
widgets.whereType<SingleChildScrollView>();
expect(scrollViews, isNotEmpty);
expect(scrollViews.first.controller, isNotNull);
},
);

testWidgets(
'two tables use different scroll controllers',
(WidgetTester tester) async {
Expand Down
44 changes: 44 additions & 0 deletions packages/flutter_markdown/test/table_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,50 @@ void defineTests() {
},
);

testWidgets(
'table scrollbar thumbVisibility should follow stylesheet',
(WidgetTester tester) async {
final ThemeData theme =
ThemeData.light().copyWith(textTheme: textTheme);

const String data = '|Header|\n|----|\n|Column|';
const bool tableScrollbarThumbVisibility = true;
final MarkdownStyleSheet style = MarkdownStyleSheet.fromTheme(theme)
.copyWith(
tableColumnWidth: const FixedColumnWidth(100),
tableScrollbarThumbVisibility: tableScrollbarThumbVisibility);

await tester.pumpWidget(
boilerplate(MarkdownBody(data: data, styleSheet: style)));

final Scrollbar scrollbar = tester.widget(find.byType(Scrollbar));

expect(scrollbar.thumbVisibility, tableScrollbarThumbVisibility);
},
);

testWidgets(
'table scrollbar thumbVisibility should follow stylesheet',
(WidgetTester tester) async {
final ThemeData theme =
ThemeData.light().copyWith(textTheme: textTheme);

const String data = '|Header|\n|----|\n|Column|';
const bool tableScrollbarThumbVisibility = false;
final MarkdownStyleSheet style = MarkdownStyleSheet.fromTheme(theme)
.copyWith(
tableColumnWidth: const FixedColumnWidth(100),
tableScrollbarThumbVisibility: tableScrollbarThumbVisibility);

await tester.pumpWidget(
boilerplate(MarkdownBody(data: data, styleSheet: style)));

final Scrollbar scrollbar = tester.widget(find.byType(Scrollbar));

expect(scrollbar.thumbVisibility, tableScrollbarThumbVisibility);
},
);

testWidgets(
'table with last row of empty table cells',
(WidgetTester tester) async {
Expand Down