From d87cd9fe1bef9d5b6799473082f8c1090b605fd1 Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Mon, 25 Mar 2024 12:59:46 +0900 Subject: [PATCH 1/6] Add custom bullet list demo and update home screen --- .../lib/demos/custom_bullet_list_demo.dart | 76 +++++++++++++++++++ .../example/lib/screens/home_screen.dart | 2 + 2 files changed, 78 insertions(+) create mode 100644 packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart diff --git a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart new file mode 100644 index 000000000000..a3408ffb8a11 --- /dev/null +++ b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart @@ -0,0 +1,76 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// TODO(goderbauer): Restructure the examples to avoid this ignore, https://github.com/flutter/flutter/issues/110208. +// ignore_for_file: avoid_implementing_value_types + +import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import '../shared/markdown_demo_widget.dart'; + +// ignore_for_file: public_member_api_docs + +const String _markdownData = ''' +# Custom Ordered List Demo + +## Unordered List + +- first +- second + - first + - first + - second + - first + - second + +## Ordered List + +1. first +2. second + 1. first + 1. first + 2. second + 1. first + 1. second +'''; + +const String _notes = ''' +# Custom Bullet List Demo +--- + +## Overview + +This is the custom bullet list demo. This demo shows how to customize the bullet list style. +This demo example is being preserved for reference purposes. +'''; + +class CustomBulletListDemo extends StatelessWidget + implements MarkdownDemoWidget { + const CustomBulletListDemo({super.key}); + + static const String _title = 'Custom Bullet List Demo'; + + @override + String get title => CustomBulletListDemo._title; + + @override + String get description => 'Shows how to customize the bullet list style.'; + + @override + Future get data => Future.value(_markdownData); + + @override + Future get notes => Future.value(_notes); + + @override + Widget build(BuildContext context) { + return const Scaffold( + body: SafeArea( + child: Markdown( + data: _markdownData, + ), + ), + ); + } +} diff --git a/packages/flutter_markdown/example/lib/screens/home_screen.dart b/packages/flutter_markdown/example/lib/screens/home_screen.dart index 8933ee57ea4d..23ad62f60832 100644 --- a/packages/flutter_markdown/example/lib/screens/home_screen.dart +++ b/packages/flutter_markdown/example/lib/screens/home_screen.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import '../demos/basic_markdown_demo.dart'; import '../demos/centered_header_demo.dart'; +import '../demos/custom_bullet_list_demo.dart'; import '../demos/extended_emoji_demo.dart'; import '../demos/markdown_body_shrink_wrap_demo.dart'; import '../demos/minimal_markdown_demo.dart'; @@ -30,6 +31,7 @@ class HomeScreen extends StatelessWidget { OriginalMarkdownDemo(), const CenteredHeaderDemo(), const MarkdownBodyShrinkWrapDemo(), + const CustomBulletListDemo(), ]; @override From c626764591f77c2fde2c10afa6e3b40d5dfa753f Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Mon, 25 Mar 2024 16:54:59 +0900 Subject: [PATCH 2/6] Add nest level on custom bullet builder --- .../lib/demos/custom_bullet_list_demo.dart | 7 ++- .../flutter_markdown/lib/src/builder.dart | 7 ++- packages/flutter_markdown/lib/src/widget.dart | 6 +- packages/flutter_markdown/test/list_test.dart | 60 ++++++++++++++++++- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart index a3408ffb8a11..20147579c40c 100644 --- a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart +++ b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart @@ -65,10 +65,15 @@ class CustomBulletListDemo extends StatelessWidget @override Widget build(BuildContext context) { - return const Scaffold( + return Scaffold( body: SafeArea( child: Markdown( data: _markdownData, + bulletBuilder: (int index, BulletStyle style, int nestLevel) => + switch (style) { + BulletStyle.unorderedList => const Text('・'), + BulletStyle.orderedList => Text('${index + 1}-$nestLevel.'), + }, ), ), ); diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 739520588db7..b9e65f9dd3ee 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -611,8 +611,11 @@ class MarkdownBuilder implements md.NodeVisitor { if (bulletBuilder != null) { return Padding( padding: styleSheet.listBulletPadding!, - child: bulletBuilder!(index, - isUnordered ? BulletStyle.unorderedList : BulletStyle.orderedList), + child: bulletBuilder!( + index, + isUnordered ? BulletStyle.unorderedList : BulletStyle.orderedList, + _listIndents.length - 1, + ), ); } diff --git a/packages/flutter_markdown/lib/src/widget.dart b/packages/flutter_markdown/lib/src/widget.dart index 38ffbdcc32ef..2c500190ed73 100644 --- a/packages/flutter_markdown/lib/src/widget.dart +++ b/packages/flutter_markdown/lib/src/widget.dart @@ -46,7 +46,11 @@ typedef MarkdownCheckboxBuilder = Widget Function(bool value); /// Signature for custom bullet widget. /// /// Used by [MarkdownWidget.bulletBuilder] -typedef MarkdownBulletBuilder = Widget Function(int index, BulletStyle style); +typedef MarkdownBulletBuilder = Widget Function( + int index, + BulletStyle style, + int nestLevel, +); /// Enumeration sent to the user when calling [MarkdownBulletBuilder] /// diff --git a/packages/flutter_markdown/test/list_test.dart b/packages/flutter_markdown/test/list_test.dart index 05464e7b93fc..5213520b428b 100644 --- a/packages/flutter_markdown/test/list_test.dart +++ b/packages/flutter_markdown/test/list_test.dart @@ -94,6 +94,35 @@ void defineTests() { ]); }, ); + + testWidgets('custom bullet builder', (WidgetTester tester) async { + const String data = + '* Item 1\n * Item 2\n * Item 3\n * Item 4\n* Item 5'; + Widget builder(int index, BulletStyle style, int nestLevel) => Text( + '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'} $nestLevel', + ); + + await tester.pumpWidget( + boilerplate( + Markdown(data: data, bulletBuilder: builder), + ), + ); + + final Iterable widgets = tester.allWidgets; + + expectTextStrings(widgets, [ + '0 unordered 0', + 'Item 1', + '0 unordered 1', + 'Item 2', + '0 unordered 2', + 'Item 3', + '1 unordered 1', + 'Item 4', + '1 unordered 0', + 'Item 5', + ]); + }); }); group('Ordered List', () { @@ -135,6 +164,35 @@ void defineTests() { final Iterable widgets = tester.allWidgets; expectTextStrings(widgets, ['1.', 'one', 'two']); }); + + testWidgets('custom bullet builder', (WidgetTester tester) async { + const String data = + '1. Item 1\n 1. Item 2\n 1. Item 3\n 1. Item 4\n1. Item 5'; + Widget builder(int index, BulletStyle style, int nestLevel) => Text( + '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'} $nestLevel', + ); + + await tester.pumpWidget( + boilerplate( + Markdown(data: data, bulletBuilder: builder), + ), + ); + + final Iterable widgets = tester.allWidgets; + + expectTextStrings(widgets, [ + '0 ordered 0', + 'Item 1', + '0 ordered 1', + 'Item 2', + '0 ordered 2', + 'Item 3', + '1 ordered 1', + 'Item 4', + '1 ordered 0', + 'Item 5', + ]); + }); }); group('Task List', () { @@ -161,7 +219,7 @@ void defineTests() { testWidgets('custom bullet builder', (WidgetTester tester) async { const String data = '* Item 1\n* Item 2\n1) Item 3\n2) Item 4'; - Widget builder(int index, BulletStyle style) => Text( + Widget builder(int index, BulletStyle style, _) => Text( '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'}'); await tester.pumpWidget( From 8bc971a75b8c53feb1bc3a522e55c27d4edfa694 Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Mon, 25 Mar 2024 17:04:11 +0900 Subject: [PATCH 3/6] Chore update CustomBulletListDemo --- .../example/lib/demos/custom_bullet_list_demo.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart index 20147579c40c..522a76dc7e5d 100644 --- a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart +++ b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart @@ -70,10 +70,13 @@ class CustomBulletListDemo extends StatelessWidget child: Markdown( data: _markdownData, bulletBuilder: (int index, BulletStyle style, int nestLevel) => - switch (style) { - BulletStyle.unorderedList => const Text('・'), - BulletStyle.orderedList => Text('${index + 1}-$nestLevel.'), - }, + FittedBox( + fit: BoxFit.scaleDown, + child: switch (style) { + BulletStyle.unorderedList => const Text('・'), + BulletStyle.orderedList => Text('$nestLevel-${index + 1}.'), + }, + ), ), ), ); From 5f7493d0cff60357e6e8c9723ad1195b14e7994b Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Mon, 25 Mar 2024 23:29:05 +0900 Subject: [PATCH 4/6] Bump version and update CHANGELOG --- packages/flutter_markdown/CHANGELOG.md | 4 ++++ packages/flutter_markdown/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index f3ed8654f361..68d0e53720bf 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.23 + +* Adds the `nestLevel` parameter at `bulletBuilder` on `Markdown` and `MarkdownBody`. + ## 0.6.22 * Introduces a new `MarkdownElementBuilder.isBlockElement()` method to specify if custom element diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index c077bb64f93e..42106f1d537a 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.6.22 +version: 0.6.23 environment: sdk: ^3.3.0 From b7f14a58ed99de52054647a434edeb5c1fff0c3e Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Sat, 30 Mar 2024 15:28:01 +0900 Subject: [PATCH 5/6] Refactor bulletBuilder parameter in MarkdownWidget --- .../lib/demos/custom_bullet_list_demo.dart | 8 +++--- .../flutter_markdown/lib/src/builder.dart | 10 +++++--- packages/flutter_markdown/lib/src/widget.dart | 25 ++++++++++++++++--- packages/flutter_markdown/test/list_test.dart | 12 ++++----- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart index 522a76dc7e5d..e04a29ef1432 100644 --- a/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart +++ b/packages/flutter_markdown/example/lib/demos/custom_bullet_list_demo.dart @@ -69,12 +69,12 @@ class CustomBulletListDemo extends StatelessWidget body: SafeArea( child: Markdown( data: _markdownData, - bulletBuilder: (int index, BulletStyle style, int nestLevel) => - FittedBox( + bulletBuilder: (MarkdownBulletParameters parameters) => FittedBox( fit: BoxFit.scaleDown, - child: switch (style) { + child: switch (parameters.style) { BulletStyle.unorderedList => const Text('・'), - BulletStyle.orderedList => Text('$nestLevel-${index + 1}.'), + BulletStyle.orderedList => + Text('${parameters.nestLevel}-${parameters.index + 1}.'), }, ), ), diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index b9e65f9dd3ee..4a0a090cb7f3 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -612,9 +612,13 @@ class MarkdownBuilder implements md.NodeVisitor { return Padding( padding: styleSheet.listBulletPadding!, child: bulletBuilder!( - index, - isUnordered ? BulletStyle.unorderedList : BulletStyle.orderedList, - _listIndents.length - 1, + MarkdownBulletParameters( + index: index, + style: isUnordered + ? BulletStyle.unorderedList + : BulletStyle.orderedList, + nestLevel: _listIndents.length - 1, + ), ), ); } diff --git a/packages/flutter_markdown/lib/src/widget.dart b/packages/flutter_markdown/lib/src/widget.dart index 2c500190ed73..be7f9d7047c3 100644 --- a/packages/flutter_markdown/lib/src/widget.dart +++ b/packages/flutter_markdown/lib/src/widget.dart @@ -47,11 +47,30 @@ typedef MarkdownCheckboxBuilder = Widget Function(bool value); /// /// Used by [MarkdownWidget.bulletBuilder] typedef MarkdownBulletBuilder = Widget Function( - int index, - BulletStyle style, - int nestLevel, + MarkdownBulletParameters parameters, ); +/// An parameters of [MarkdownBulletBuilder]. +/// +/// Used by [MarkdownWidget.bulletBuilder] +class MarkdownBulletParameters { + /// Creates a new instance of [MarkdownBulletParameters]. + const MarkdownBulletParameters({ + required this.index, + required this.style, + required this.nestLevel, + }); + + /// The index of the bullet on that nesting level. + final int index; + + /// The style of the bullet. + final BulletStyle style; + + /// The nest level of the bullet. + final int nestLevel; +} + /// Enumeration sent to the user when calling [MarkdownBulletBuilder] /// /// Use this to differentiate the bullet styling when building your own. diff --git a/packages/flutter_markdown/test/list_test.dart b/packages/flutter_markdown/test/list_test.dart index 5213520b428b..59574e42c27a 100644 --- a/packages/flutter_markdown/test/list_test.dart +++ b/packages/flutter_markdown/test/list_test.dart @@ -98,8 +98,8 @@ void defineTests() { testWidgets('custom bullet builder', (WidgetTester tester) async { const String data = '* Item 1\n * Item 2\n * Item 3\n * Item 4\n* Item 5'; - Widget builder(int index, BulletStyle style, int nestLevel) => Text( - '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'} $nestLevel', + Widget builder(MarkdownBulletParameters parameters) => Text( + '${parameters.index} ${parameters.style == BulletStyle.orderedList ? 'ordered' : 'unordered'} ${parameters.nestLevel}', ); await tester.pumpWidget( @@ -168,8 +168,8 @@ void defineTests() { testWidgets('custom bullet builder', (WidgetTester tester) async { const String data = '1. Item 1\n 1. Item 2\n 1. Item 3\n 1. Item 4\n1. Item 5'; - Widget builder(int index, BulletStyle style, int nestLevel) => Text( - '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'} $nestLevel', + Widget builder(MarkdownBulletParameters parameters) => Text( + '${parameters.index} ${parameters.style == BulletStyle.orderedList ? 'ordered' : 'unordered'} ${parameters.nestLevel}', ); await tester.pumpWidget( @@ -219,8 +219,8 @@ void defineTests() { testWidgets('custom bullet builder', (WidgetTester tester) async { const String data = '* Item 1\n* Item 2\n1) Item 3\n2) Item 4'; - Widget builder(int index, BulletStyle style, _) => Text( - '$index ${style == BulletStyle.orderedList ? 'ordered' : 'unordered'}'); + Widget builder(MarkdownBulletParameters parameters) => Text( + '${parameters.index} ${parameters.style == BulletStyle.orderedList ? 'ordered' : 'unordered'}'); await tester.pumpWidget( boilerplate( From f9b64e026204d4757ee0f918cf398bf9cd112eb9 Mon Sep 17 00:00:00 2001 From: Kurogoma4D Date: Sat, 30 Mar 2024 15:53:06 +0900 Subject: [PATCH 6/6] Bump version and update CHANGELOG --- packages/flutter_markdown/CHANGELOG.md | 6 ++++-- packages/flutter_markdown/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index 68d0e53720bf..084f94a27bdc 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,6 +1,8 @@ -## 0.6.23 +## 0.7.0 -* Adds the `nestLevel` parameter at `bulletBuilder` on `Markdown` and `MarkdownBody`. +* **BREAKING CHANGES**: + * Replaces parameters at `bulletBuilder` with `MarkdownBulletParameters`. + * Introduces a new parameter `nestLevel` that exposes the bullet item's nesting level. ## 0.6.22 diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index 42106f1d537a..b5e2c9456223 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.6.23 +version: 0.7.0 environment: sdk: ^3.3.0