diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d204d..b49406a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [2.0.1] - 2021/07/30 + +* Add support for strikethrough, code, blockquote, separator and images. +* Custom actions supported by the input. + ## [2.0.0] - 2021/04/01 * Migrate to null-safety. diff --git a/README.md b/README.md index 2a5b00c..2f4e7c6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ MarkdownEditableTextInput is a TextField Widget that allow you to convert easily - [x] Support text direction ## Demo -https://user-images.githubusercontent.com/60510869/119675122-65409f00-be5a-11eb-8cc4-c0f8757030ab.mp4 +![](pictures/test_edition.gif) ## Usage The color of the MarkdownTextInput is defined by the color set in your Theme : @@ -30,6 +30,7 @@ The color of the MarkdownTextInput is defined by the color set in your Theme : | String label | "Description" | Display a label in MarkdownTextInput | | TextDirection textDirection | TextDirection.rtl | Change text direction | | int maxLines | 3 | The maximum of lines that can be display in the input | +| List actions | [MarkdownType.bold, MardownType.italic] | Actions the editor will handle | ### Example You can see an example of how to use this package [here](https://github.com/playmoweb/markdown-editable-textinput/tree/master/example) diff --git a/example/lib/main.dart b/example/lib/main.dart index c18e76a..76cc094 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:markdown_editable_textinput/format_markdown.dart'; import 'package:markdown_editable_textinput/markdown_text_input.dart'; void main() => runApp(MyApp()); @@ -42,7 +43,8 @@ class _MyAppState extends State { (String value) => setState(() => description = value), description, label: 'Description', - maxLines: 2, + maxLines: 10, + actions: MarkdownType.values, ), Padding( padding: const EdgeInsets.only(top: 10), diff --git a/example/pubspec.lock b/example/pubspec.lock index ff53e31..f0df0cd 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + expandable: + dependency: transitive + description: + name: expandable + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.1" fake_async: dependency: transitive description: @@ -101,7 +108,7 @@ packages: path: ".." relative: true source: path - version: "2.0.0" + version: "2.0.1" matcher: dependency: transitive description: @@ -186,4 +193,4 @@ packages: version: "2.1.0" sdks: dart: ">=2.12.0 <3.0.0" - flutter: ">=1.10.7" + flutter: ">=2.0.0" diff --git a/lib/format_markdown.dart b/lib/format_markdown.dart index 788aa11..8918313 100644 --- a/lib/format_markdown.dart +++ b/lib/format_markdown.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + /// Use this class for converting String to [ResultMarkdown] class FormatMarkdown { /// Convert [data] part into [ResultMarkdown] from [type]. @@ -84,7 +86,6 @@ class ResultMarkdown { } /// Represent markdown possible type to convert - enum MarkdownType { /// For **bold** text bold, @@ -119,6 +120,61 @@ enum MarkdownType { /// For adding ------ separator, - /// For ![Alt text](https://picsum.photos/500/500) + /// For ![Alt text](link) image, } + +/// Add data to [MarkdownType] enum +extension MarkownTypeExtension on MarkdownType { + /// Get String used in widget's key + String get key { + switch (this) { + case MarkdownType.bold: + return 'bold_button'; + case MarkdownType.italic: + return 'italic_button'; + case MarkdownType.strikethrough: + return 'strikethrough_button'; + case MarkdownType.link: + return 'link_button'; + case MarkdownType.title: + return 'H#_button'; + case MarkdownType.list: + return 'list_button'; + case MarkdownType.code: + return 'code_button'; + case MarkdownType.blockquote: + return 'quote_button'; + case MarkdownType.separator: + return 'separator_button'; + case MarkdownType.image: + return 'image_button'; + } + } + + /// Get Icon String + IconData get icon { + switch (this) { + case MarkdownType.bold: + return Icons.format_bold; + case MarkdownType.italic: + return Icons.format_italic; + case MarkdownType.strikethrough: + return Icons.format_strikethrough; + case MarkdownType.link: + return Icons.link; + case MarkdownType.title: + return Icons.text_fields; + case MarkdownType.list: + return Icons.list; + case MarkdownType.code: + return Icons.code; + case MarkdownType.blockquote: + return Icons.format_quote_rounded; + case MarkdownType.separator: + return Icons.minimize_rounded; + case MarkdownType.image: + return Icons.image_rounded; + } + } +} diff --git a/lib/markdown_text_input.dart b/lib/markdown_text_input.dart index 48db928..a860cc5 100644 --- a/lib/markdown_text_input.dart +++ b/lib/markdown_text_input.dart @@ -11,20 +11,36 @@ class MarkdownTextInput extends StatefulWidget { final String initialValue; /// Validator for the TextFormField - final String Function(String? value)? validators; + final String? Function(String? value)? validators; /// String displayed at hintText in TextFormField - final String label; + final String? label; /// Change the text direction of the input (RTL / LTR) - final TextDirection textDirection; + final TextDirection? textDirection; /// The maximum of lines that can be display in the input - final int maxLines; + final int? maxLines; + + /// List of action the component can handle + final List actions; /// Constructor for [MarkdownTextInput] - MarkdownTextInput(this.onTextChanged, this.initialValue, - {this.label = '', this.validators, this.textDirection = TextDirection.ltr, this.maxLines = 10}); + MarkdownTextInput( + this.onTextChanged, + this.initialValue, { + this.label = '', + this.validators, + this.textDirection = TextDirection.ltr, + this.maxLines = 10, + this.actions = const [ + MarkdownType.bold, + MarkdownType.italic, + MarkdownType.title, + MarkdownType.link, + MarkdownType.list + ], + }); @override _MarkdownTextInputState createState() => _MarkdownTextInputState(); @@ -99,141 +115,60 @@ class _MarkdownTextInputState extends State { borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), child: ListView( scrollDirection: Axis.horizontal, - children: [ - InkWell( - key: const Key('bold_button'), - onTap: () => onTap(MarkdownType.bold), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.format_bold, - ), - ), - ), - InkWell( - key: const Key('italic_button'), - onTap: () => onTap(MarkdownType.italic), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.format_italic, - ), - ), - ), - InkWell( - key: const Key('strikethrough_button'), - onTap: () => onTap(MarkdownType.strikethrough), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.format_strikethrough, - ), - ), - ), - InkWell( - key: const Key('code_button'), - onTap: () => onTap(MarkdownType.code), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.code, - ), - ), - ), - ExpandableNotifier( - child: Expandable( - key: Key('H#_button'), - collapsed: ExpandableButton( - child: const Center( - child: Padding( - padding: EdgeInsets.all(10), - child: Text( - 'H#', - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), - ), - ), - ), - ), - expanded: Container( - color: Colors.white10, - child: Row( - children: [ - for (int i = 1; i <= 6; i++) - InkWell( - key: Key('H${i}_button'), - onTap: () => onTap(MarkdownType.title, titleSize: i), + children: widget.actions.map((type) { + return type == MarkdownType.title + ? ExpandableNotifier( + child: Expandable( + key: Key('H#_button'), + collapsed: ExpandableButton( + child: const Center( child: Padding( - padding: const EdgeInsets.all(10), + padding: EdgeInsets.all(10), child: Text( - 'H$i', - style: TextStyle(fontSize: (18 - i).toDouble(), fontWeight: FontWeight.w700), + 'H#', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), ), ), ), - ExpandableButton( - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.close, - ), + ), + expanded: Container( + color: Colors.white10, + child: Row( + children: [ + for (int i = 1; i <= 6; i++) + InkWell( + key: Key('H${i}_button'), + onTap: () => onTap(MarkdownType.title, titleSize: i), + child: Padding( + padding: const EdgeInsets.all(10), + child: Text( + 'H$i', + style: TextStyle(fontSize: (18 - i).toDouble(), fontWeight: FontWeight.w700), + ), + ), + ), + ExpandableButton( + child: const Padding( + padding: EdgeInsets.all(10), + child: Icon( + Icons.close, + ), + ), + ), + ], ), ), - ], - ), - ), - ), - ), - InkWell( - key: const Key('link_button'), - onTap: () => onTap(MarkdownType.link), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.link, - ), - ), - ), - InkWell( - key: const Key('list_button'), - onTap: () => onTap(MarkdownType.list), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.list, - ), - ), - ), - InkWell( - key: const Key('quote_button'), - onTap: () => onTap(MarkdownType.blockquote), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.format_quote_rounded, - ), - ), - ), - InkWell( - key: const Key('separator_button'), - onTap: () => onTap(MarkdownType.separator), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.minimize_rounded, - ), - ), - ), - InkWell( - key: const Key('image_button'), - onTap: () => onTap(MarkdownType.image), - child: const Padding( - padding: EdgeInsets.all(10), - child: Icon( - Icons.image_rounded, - ), - ), - ), - ], + ), + ) + : InkWell( + key: Key(type.key), + onTap: () => onTap(type), + child: Padding( + padding: EdgeInsets.all(10), + child: Icon(type.icon), + ), + ); + }).toList(), ), ), ) diff --git a/pictures/test_edition.gif b/pictures/test_edition.gif index 5782354..e54c777 100644 Binary files a/pictures/test_edition.gif and b/pictures/test_edition.gif differ diff --git a/pubspec.lock b/pubspec.lock index 6553bca..8a5133b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -50,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + expandable: + dependency: "direct main" + description: + name: expandable + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.1" fake_async: dependency: transitive description: @@ -151,3 +158,4 @@ packages: version: "2.1.0" sdks: dart: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index c2c15e4..403c37a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: markdown_editable_textinput description: A TextField Widget that allow you to convert easily what's in the TextField to Markdown. -version: 2.0.0 +version: 2.0.1 homepage: https://github.com/playmoweb/markdown-editable-textinput repository: https://github.com/playmoweb/markdown-editable-textinput