Skip to content

Commit

Permalink
[flutter_markdown] Add horizontal scroll for markdown table (#6983)
Browse files Browse the repository at this point in the history
Add horizontal scroll for markdown table when using `tableColumnWidth: FixedColumnWidth(width)`

Fix [flutter/flutter#129052](flutter/flutter#129052)
  • Loading branch information
phong010198 authored Jun 28, 2024
1 parent d43a827 commit 9fc8627
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 7 deletions.
4 changes: 4 additions & 0 deletions packages/flutter_markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.7.3

* Adds horizontal scrolling for table when using `tableColumnWidth: FixedColumnWidth(width)`.

## 0.7.2+1

* Fixes a crash caused by text selection when `selectable` is true and `onSelectionChanged` is null.
Expand Down
29 changes: 23 additions & 6 deletions packages/flutter_markdown/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,20 @@ class MarkdownBuilder implements md.NodeVisitor {
);
}
} else if (tag == 'table') {
child = Table(
defaultColumnWidth: styleSheet.tableColumnWidth!,
defaultVerticalAlignment: styleSheet.tableVerticalAlignment,
border: styleSheet.tableBorder,
children: _tables.removeLast().rows,
);
if (styleSheet.tableColumnWidth is FixedColumnWidth) {
final ScrollController tableScrollController = ScrollController();
child = Scrollbar(
controller: tableScrollController,
child: SingleChildScrollView(
controller: tableScrollController,
scrollDirection: Axis.horizontal,
padding: styleSheet.tablePadding,
child: _buildTable(),
),
);
} else {
child = _buildTable();
}
} else if (tag == 'blockquote') {
_isInBlockquote = false;
child = DecoratedBox(
Expand Down Expand Up @@ -558,6 +566,15 @@ class MarkdownBuilder implements md.NodeVisitor {
_lastVisitedTag = tag;
}

Table _buildTable() {
return Table(
defaultColumnWidth: styleSheet.tableColumnWidth!,
defaultVerticalAlignment: styleSheet.tableVerticalAlignment,
border: styleSheet.tableBorder,
children: _tables.removeLast().rows,
);
}

Widget _buildImage(String src, String? title, String? alt) {
final List<String> parts = src.split('#');
if (parts.isEmpty) {
Expand Down
12 changes: 12 additions & 0 deletions packages/flutter_markdown/lib/src/style_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class MarkdownStyleSheet {
this.tableHead,
this.tableBody,
this.tableHeadAlign,
this.tablePadding,
this.tableBorder,
this.tableColumnWidth,
this.tableCellsPadding,
Expand Down Expand Up @@ -134,6 +135,7 @@ class MarkdownStyleSheet {
tableHead: const TextStyle(fontWeight: FontWeight.w600),
tableBody: theme.textTheme.bodyMedium,
tableHeadAlign: TextAlign.center,
tablePadding: const EdgeInsets.only(bottom: 4.0),
tableBorder: TableBorder.all(
color: theme.dividerColor,
),
Expand Down Expand Up @@ -231,6 +233,7 @@ class MarkdownStyleSheet {
),
tableBody: theme.textTheme.textStyle,
tableHeadAlign: TextAlign.center,
tablePadding: const EdgeInsets.only(bottom: 8),
tableBorder: TableBorder.all(color: CupertinoColors.separator, width: 0),
tableColumnWidth: const FlexColumnWidth(),
tableCellsPadding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
Expand Down Expand Up @@ -312,6 +315,7 @@ class MarkdownStyleSheet {
tableHead: const TextStyle(fontWeight: FontWeight.w600),
tableBody: theme.textTheme.bodyMedium,
tableHeadAlign: TextAlign.center,
tablePadding: const EdgeInsets.only(bottom: 4.0),
tableBorder: TableBorder.all(
color: theme.dividerColor,
),
Expand Down Expand Up @@ -371,6 +375,7 @@ class MarkdownStyleSheet {
TextStyle? tableHead,
TextStyle? tableBody,
TextAlign? tableHeadAlign,
EdgeInsets? tablePadding,
TableBorder? tableBorder,
TableColumnWidth? tableColumnWidth,
EdgeInsets? tableCellsPadding,
Expand Down Expand Up @@ -436,6 +441,7 @@ class MarkdownStyleSheet {
tableHead: tableHead ?? this.tableHead,
tableBody: tableBody ?? this.tableBody,
tableHeadAlign: tableHeadAlign ?? this.tableHeadAlign,
tablePadding: tablePadding ?? this.tablePadding,
tableBorder: tableBorder ?? this.tableBorder,
tableColumnWidth: tableColumnWidth ?? this.tableColumnWidth,
tableCellsPadding: tableCellsPadding ?? this.tableCellsPadding,
Expand Down Expand Up @@ -502,6 +508,7 @@ class MarkdownStyleSheet {
tableHead: tableHead!.merge(other.tableHead),
tableBody: tableBody!.merge(other.tableBody),
tableHeadAlign: other.tableHeadAlign,
tablePadding: other.tablePadding,
tableBorder: other.tableBorder,
tableColumnWidth: other.tableColumnWidth,
tableCellsPadding: other.tableCellsPadding,
Expand Down Expand Up @@ -620,6 +627,9 @@ class MarkdownStyleSheet {
/// The [TextAlign] to use for `th` elements.
final TextAlign? tableHeadAlign;

/// The padding to use for `table` elements.
final EdgeInsets? tablePadding;

/// The [TableBorder] to use for `table` elements.
final TableBorder? tableBorder;

Expand Down Expand Up @@ -740,6 +750,7 @@ class MarkdownStyleSheet {
other.tableHead == tableHead &&
other.tableBody == tableBody &&
other.tableHeadAlign == tableHeadAlign &&
other.tablePadding == tablePadding &&
other.tableBorder == tableBorder &&
other.tableColumnWidth == tableColumnWidth &&
other.tableCellsPadding == tableCellsPadding &&
Expand Down Expand Up @@ -798,6 +809,7 @@ class MarkdownStyleSheet {
tableHead,
tableBody,
tableHeadAlign,
tablePadding,
tableBorder,
tableColumnWidth,
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.2+1
version: 0.7.3

environment:
sdk: ^3.3.0
Expand Down
64 changes: 64 additions & 0 deletions packages/flutter_markdown/test/scrollable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,69 @@ void defineTests() {
]);
},
);

testWidgets(
'table',
(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 FixedColumnWidth(150),
),
),
),
),
);

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 {
const String data = '|Header 1|Header 2|Header 3|'
'\n|-----|-----|-----|'
'\n|Col 1|Col 2|Col 3|'
'\n'
'\n|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 FixedColumnWidth(150),
),
),
),
),
);

final Iterable<Widget> widgets = tester.allWidgets;
final Iterable<SingleChildScrollView> scrollViews =
widgets.whereType<SingleChildScrollView>();
expect(scrollViews, hasLength(2));
expect(scrollViews.first.controller, isNotNull);
expect(scrollViews.last.controller, isNotNull);
expect(scrollViews.first.controller,
isNot(equals(scrollViews.last.controller)));
},
);
});
}

0 comments on commit 9fc8627

Please sign in to comment.