From f47cff2564eb94c4343a7ef46605cbc097f69588 Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia Date: Tue, 25 Jun 2024 16:15:12 +0700 Subject: [PATCH 1/7] Add horizontal scroll for markdown table Add horizontal scroll for markdown table when using `tableColumnWidth: FixedColumnWidth(width)` --- packages/flutter_markdown/CHANGELOG.md | 4 +++ .../flutter_markdown/lib/src/builder.dart | 29 +++++++++++++++---- .../flutter_markdown/lib/src/style_sheet.dart | 12 ++++++++ packages/flutter_markdown/pubspec.yaml | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index f787fabbc054..3680ba9387f1 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.3 + +* Add horizontal scroll 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. diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 8e7c98abdc26..75d82ae2b3dd 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -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 FlexColumnWidth) { + child = _buildTable(); + } else { + final ScrollController tableScrollController = ScrollController(); + child = Scrollbar( + controller: tableScrollController, + child: SingleChildScrollView( + controller: tableScrollController, + scrollDirection: Axis.horizontal, + padding: styleSheet.tablePadding, + child: _buildTable(), + ), + ); + } } else if (tag == 'blockquote') { _isInBlockquote = false; child = DecoratedBox( @@ -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 parts = src.split('#'); if (parts.isEmpty) { diff --git a/packages/flutter_markdown/lib/src/style_sheet.dart b/packages/flutter_markdown/lib/src/style_sheet.dart index f3b570aeb914..3923e618ff36 100644 --- a/packages/flutter_markdown/lib/src/style_sheet.dart +++ b/packages/flutter_markdown/lib/src/style_sheet.dart @@ -38,6 +38,7 @@ class MarkdownStyleSheet { this.tableHead, this.tableBody, this.tableHeadAlign, + this.tablePadding, this.tableBorder, this.tableColumnWidth, this.tableCellsPadding, @@ -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, ), @@ -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), @@ -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, ), @@ -371,6 +375,7 @@ class MarkdownStyleSheet { TextStyle? tableHead, TextStyle? tableBody, TextAlign? tableHeadAlign, + EdgeInsets? tablePadding, TableBorder? tableBorder, TableColumnWidth? tableColumnWidth, EdgeInsets? tableCellsPadding, @@ -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, @@ -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, @@ -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; @@ -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 && @@ -798,6 +809,7 @@ class MarkdownStyleSheet { tableHead, tableBody, tableHeadAlign, + tablePadding, tableBorder, tableColumnWidth, tableCellsPadding, diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index f7b58ed28888..ecfd21ea000e 100644 --- a/packages/flutter_markdown/pubspec.yaml +++ b/packages/flutter_markdown/pubspec.yaml @@ -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 From 496a8d14bd6434242ea26f1f700e2dfd8b5b51de Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia <36687028+phong010198@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:13:23 +0700 Subject: [PATCH 2/7] Change allowing scroll condition --- packages/flutter_markdown/lib/src/builder.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 75d82ae2b3dd..0706453a01d4 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -438,9 +438,7 @@ class MarkdownBuilder implements md.NodeVisitor { ); } } else if (tag == 'table') { - if (styleSheet.tableColumnWidth is FlexColumnWidth) { - child = _buildTable(); - } else { + if (styleSheet.tableColumnWidth is FixedColumnWidth) { final ScrollController tableScrollController = ScrollController(); child = Scrollbar( controller: tableScrollController, @@ -451,6 +449,8 @@ class MarkdownBuilder implements md.NodeVisitor { child: _buildTable(), ), ); + } else { + child = _buildTable(); } } else if (tag == 'blockquote') { _isInBlockquote = false; From 9b1e5e5620503ac05e2f6498d16a4fe50f903fe9 Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia Date: Wed, 26 Jun 2024 08:31:10 +0700 Subject: [PATCH 3/7] Add table scroll test --- .../test/scrollable_test.dart | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/packages/flutter_markdown/test/scrollable_test.dart b/packages/flutter_markdown/test/scrollable_test.dart index 23092328f00d..1042a6fa98a8 100644 --- a/packages/flutter_markdown/test/scrollable_test.dart +++ b/packages/flutter_markdown/test/scrollable_test.dart @@ -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 widgets = tester.allWidgets; + final Iterable scrollViews = + widgets.whereType(); + 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 widgets = tester.allWidgets; + final Iterable scrollViews = + widgets.whereType(); + expect(scrollViews, hasLength(2)); + expect(scrollViews.first.controller, isNotNull); + expect(scrollViews.last.controller, isNotNull); + expect(scrollViews.first.controller, + isNot(equals(scrollViews.last.controller))); + }, + ); }); } From 43cfc85a33051534eb44177cf509159dd2fa31fc Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia Date: Tue, 25 Jun 2024 16:15:12 +0700 Subject: [PATCH 4/7] Add horizontal scroll for markdown table Add horizontal scroll for markdown table when using `tableColumnWidth: FixedColumnWidth(width)` --- packages/flutter_markdown/CHANGELOG.md | 4 +++ .../flutter_markdown/lib/src/builder.dart | 29 +++++++++++++++---- .../flutter_markdown/lib/src/style_sheet.dart | 12 ++++++++ packages/flutter_markdown/pubspec.yaml | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index f787fabbc054..3680ba9387f1 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.3 + +* Add horizontal scroll 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. diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 8e7c98abdc26..75d82ae2b3dd 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -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 FlexColumnWidth) { + child = _buildTable(); + } else { + final ScrollController tableScrollController = ScrollController(); + child = Scrollbar( + controller: tableScrollController, + child: SingleChildScrollView( + controller: tableScrollController, + scrollDirection: Axis.horizontal, + padding: styleSheet.tablePadding, + child: _buildTable(), + ), + ); + } } else if (tag == 'blockquote') { _isInBlockquote = false; child = DecoratedBox( @@ -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 parts = src.split('#'); if (parts.isEmpty) { diff --git a/packages/flutter_markdown/lib/src/style_sheet.dart b/packages/flutter_markdown/lib/src/style_sheet.dart index f3b570aeb914..3923e618ff36 100644 --- a/packages/flutter_markdown/lib/src/style_sheet.dart +++ b/packages/flutter_markdown/lib/src/style_sheet.dart @@ -38,6 +38,7 @@ class MarkdownStyleSheet { this.tableHead, this.tableBody, this.tableHeadAlign, + this.tablePadding, this.tableBorder, this.tableColumnWidth, this.tableCellsPadding, @@ -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, ), @@ -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), @@ -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, ), @@ -371,6 +375,7 @@ class MarkdownStyleSheet { TextStyle? tableHead, TextStyle? tableBody, TextAlign? tableHeadAlign, + EdgeInsets? tablePadding, TableBorder? tableBorder, TableColumnWidth? tableColumnWidth, EdgeInsets? tableCellsPadding, @@ -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, @@ -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, @@ -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; @@ -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 && @@ -798,6 +809,7 @@ class MarkdownStyleSheet { tableHead, tableBody, tableHeadAlign, + tablePadding, tableBorder, tableColumnWidth, tableCellsPadding, diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index f7b58ed28888..ecfd21ea000e 100644 --- a/packages/flutter_markdown/pubspec.yaml +++ b/packages/flutter_markdown/pubspec.yaml @@ -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 From 2f42fbea492daaae664a5d18dd31dfef927d8a3d Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia <36687028+phong010198@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:13:23 +0700 Subject: [PATCH 5/7] Change allowing scroll condition --- packages/flutter_markdown/lib/src/builder.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 75d82ae2b3dd..0706453a01d4 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -438,9 +438,7 @@ class MarkdownBuilder implements md.NodeVisitor { ); } } else if (tag == 'table') { - if (styleSheet.tableColumnWidth is FlexColumnWidth) { - child = _buildTable(); - } else { + if (styleSheet.tableColumnWidth is FixedColumnWidth) { final ScrollController tableScrollController = ScrollController(); child = Scrollbar( controller: tableScrollController, @@ -451,6 +449,8 @@ class MarkdownBuilder implements md.NodeVisitor { child: _buildTable(), ), ); + } else { + child = _buildTable(); } } else if (tag == 'blockquote') { _isInBlockquote = false; From 913ed15b9f4a223f191a6c9d4554515a992fd519 Mon Sep 17 00:00:00 2001 From: Phong_NguyenGia Date: Wed, 26 Jun 2024 08:31:10 +0700 Subject: [PATCH 6/7] Add table scroll test --- .../test/scrollable_test.dart | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/packages/flutter_markdown/test/scrollable_test.dart b/packages/flutter_markdown/test/scrollable_test.dart index 23092328f00d..1042a6fa98a8 100644 --- a/packages/flutter_markdown/test/scrollable_test.dart +++ b/packages/flutter_markdown/test/scrollable_test.dart @@ -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 widgets = tester.allWidgets; + final Iterable scrollViews = + widgets.whereType(); + 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 widgets = tester.allWidgets; + final Iterable scrollViews = + widgets.whereType(); + expect(scrollViews, hasLength(2)); + expect(scrollViews.first.controller, isNotNull); + expect(scrollViews.last.controller, isNotNull); + expect(scrollViews.first.controller, + isNot(equals(scrollViews.last.controller))); + }, + ); }); } From eb826417a9fd5500dfea13b935478a7000182b88 Mon Sep 17 00:00:00 2001 From: Tarrin Neal Date: Fri, 28 Jun 2024 16:39:00 -0700 Subject: [PATCH 7/7] Update CHANGELOG.md --- packages/flutter_markdown/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index 3680ba9387f1..2b42efadc5ff 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.7.3 -* Add horizontal scroll for table when using `tableColumnWidth: FixedColumnWidth(width)`. +* Adds horizontal scrolling for table when using `tableColumnWidth: FixedColumnWidth(width)`. ## 0.7.2+1