diff --git a/frontend/app_flowy/packages/appflowy_editor/CHANGELOG.md b/frontend/app_flowy/packages/appflowy_editor/CHANGELOG.md
index 88a977e250..bac617937b 100644
--- a/frontend/app_flowy/packages/appflowy_editor/CHANGELOG.md
+++ b/frontend/app_flowy/packages/appflowy_editor/CHANGELOG.md
@@ -1 +1,5 @@
+## 0.0.2
+Minor Updates to Documentation.
+
## 0.0.1
+Initial Version of the library.
\ No newline at end of file
diff --git a/frontend/app_flowy/packages/appflowy_editor/README.md b/frontend/app_flowy/packages/appflowy_editor/README.md
index 4961f036c4..8e239b6004 100644
--- a/frontend/app_flowy/packages/appflowy_editor/README.md
+++ b/frontend/app_flowy/packages/appflowy_editor/README.md
@@ -15,6 +15,10 @@ and the Flutter guide for
A highly customizable rich-text editor for Flutter
+
+ Discord •
+ Twitter
+
diff --git a/frontend/app_flowy/packages/appflowy_editor/documentation/images/example.png b/frontend/app_flowy/packages/appflowy_editor/documentation/images/example.png
index 1b1d439dbf..9bd16610dc 100644
Binary files a/frontend/app_flowy/packages/appflowy_editor/documentation/images/example.png and b/frontend/app_flowy/packages/appflowy_editor/documentation/images/example.png differ
diff --git a/frontend/app_flowy/packages/appflowy_editor/example/lib/main.dart b/frontend/app_flowy/packages/appflowy_editor/example/lib/main.dart
index 8b00d936ee..e1192580c5 100644
--- a/frontend/app_flowy/packages/appflowy_editor/example/lib/main.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/example/lib/main.dart
@@ -81,41 +81,6 @@ class _MyHomePageState extends State
{
return Container();
}
- Widget _buildExpandableFab() {
- return ExpandableFab(
- distance: 112.0,
- children: [
- ActionButton(
- onPressed: () {
- if (page == 0) return;
- setState(() {
- page = 0;
- });
- },
- icon: const Icon(Icons.note_add),
- ),
- ActionButton(
- icon: const Icon(Icons.document_scanner),
- onPressed: () {
- if (page == 1) return;
- setState(() {
- page = 1;
- });
- },
- ),
- ActionButton(
- onPressed: () {
- if (page == 2) return;
- setState(() {
- page = 2;
- });
- },
- icon: const Icon(Icons.text_fields),
- ),
- ],
- );
- }
-
Widget _buildAppFlowyEditorWithEmptyDocument() {
final editorState = EditorState.empty();
final editor = AppFlowyEditor(
@@ -176,4 +141,39 @@ class _MyHomePageState extends State {
),
);
}
+
+ Widget _buildExpandableFab() {
+ return ExpandableFab(
+ distance: 112.0,
+ children: [
+ ActionButton(
+ onPressed: () {
+ if (page == 0) return;
+ setState(() {
+ page = 0;
+ });
+ },
+ icon: const Icon(Icons.note_add),
+ ),
+ ActionButton(
+ icon: const Icon(Icons.document_scanner),
+ onPressed: () {
+ if (page == 1) return;
+ setState(() {
+ page = 1;
+ });
+ },
+ ),
+ ActionButton(
+ onPressed: () {
+ if (page == 2) return;
+ setState(() {
+ page = 2;
+ });
+ },
+ icon: const Icon(Icons.text_fields),
+ ),
+ ],
+ );
+ }
}
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/flowy_svg.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/flowy_svg.dart
index cb60addaff..96ae89a4d5 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/flowy_svg.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/infra/flowy_svg.dart
@@ -5,18 +5,23 @@ class FlowySvg extends StatelessWidget {
const FlowySvg({
Key? key,
this.name,
- this.size = const Size(20, 20),
+ this.width,
+ this.height,
this.color,
this.number,
this.padding,
}) : super(key: key);
final String? name;
- final Size size;
+ final double? width;
+ final double? height;
final Color? color;
final int? number;
final EdgeInsets? padding;
+ final _defaultWidth = 20.0;
+ final _defaultHeight = 20.0;
+
@override
Widget build(BuildContext context) {
return Padding(
@@ -27,22 +32,21 @@ class FlowySvg extends StatelessWidget {
Widget _buildSvg() {
if (name != null) {
- return SizedBox.fromSize(
- size: size,
- child: SvgPicture.asset(
- 'assets/images/$name.svg',
- color: color,
- package: 'appflowy_editor',
- fit: BoxFit.fill,
- ),
+ return SvgPicture.asset(
+ 'assets/images/$name.svg',
+ color: color,
+ fit: BoxFit.fill,
+ height: height,
+ width: width,
+ package: 'appflowy_editor',
);
} else if (number != null) {
final numberText =
'$number. ';
return SvgPicture.string(
numberText,
- width: size.width,
- height: size.width,
+ width: width ?? _defaultWidth,
+ height: height ?? _defaultHeight,
);
}
return Container();
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/bulleted_list_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/bulleted_list_text.dart
index 74ee29ed44..267a5acc66 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/bulleted_list_text.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/bulleted_list_text.dart
@@ -47,7 +47,7 @@ class _BulletedListTextNodeWidgetState extends State
final iconKey = GlobalKey();
final _richTextKey = GlobalKey(debugLabel: 'bulleted_list_text');
- final _iconSize = 20.0;
+ final _iconWidth = 20.0;
final _iconRightPadding = 5.0;
@override
@@ -67,7 +67,8 @@ class _BulletedListTextNodeWidgetState extends State
children: [
FlowySvg(
key: iconKey,
- size: Size.square(_iconSize),
+ width: _iconWidth,
+ height: _iconWidth,
padding:
EdgeInsets.only(top: topPadding, right: _iconRightPadding),
name: 'point',
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/checkbox_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/checkbox_text.dart
index 646bd4d408..1607d6f649 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/checkbox_text.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/checkbox_text.dart
@@ -45,7 +45,7 @@ class _CheckboxNodeWidgetState extends State
final iconKey = GlobalKey();
final _richTextKey = GlobalKey(debugLabel: 'checkbox_text');
- final _iconSize = 20.0;
+ final _iconWidth = 20.0;
final _iconRightPadding = 5.0;
@override
@@ -74,7 +74,8 @@ class _CheckboxNodeWidgetState extends State
GestureDetector(
key: iconKey,
child: FlowySvg(
- size: Size.square(_iconSize),
+ width: _iconWidth,
+ height: _iconWidth,
padding: EdgeInsets.only(
top: topPadding,
right: _iconRightPadding,
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/number_list_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/number_list_text.dart
index 836da9b69e..de3b0b55b6 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/number_list_text.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/number_list_text.dart
@@ -47,7 +47,7 @@ class _NumberListTextNodeWidgetState extends State
final iconKey = GlobalKey();
final _richTextKey = GlobalKey(debugLabel: 'number_list_text');
- final _iconSize = 20.0;
+ final _iconWidth = 20.0;
final _iconRightPadding = 5.0;
@override
@@ -66,7 +66,8 @@ class _NumberListTextNodeWidgetState extends State
children: [
FlowySvg(
key: iconKey,
- size: Size.square(_iconSize),
+ width: _iconWidth,
+ height: _iconWidth,
padding:
EdgeInsets.only(top: topPadding, right: _iconRightPadding),
number: widget.textNode.attributes.number,
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/quoted_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/quoted_text.dart
index aa43be053a..0389dfa50f 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/quoted_text.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/quoted_text.dart
@@ -46,7 +46,7 @@ class _QuotedTextNodeWidgetState extends State
final iconKey = GlobalKey();
final _richTextKey = GlobalKey(debugLabel: 'quoted_text');
- final _iconSize = 20.0;
+ final _iconWidth = 20.0;
final _iconRightPadding = 5.0;
@override
@@ -60,25 +60,27 @@ class _QuotedTextNodeWidgetState extends State
width: defaultMaxTextNodeWidth,
child: Padding(
padding: EdgeInsets.only(bottom: defaultLinePadding),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- FlowySvg(
- key: iconKey,
- size: Size(_iconSize, _quoteHeight),
- padding:
- EdgeInsets.only(top: topPadding, right: _iconRightPadding),
- name: 'quote',
- ),
- Expanded(
- child: FlowyRichText(
- key: _richTextKey,
- placeholderText: 'Quote',
- textNode: widget.textNode,
- editorState: widget.editorState,
+ child: IntrinsicHeight(
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ FlowySvg(
+ key: iconKey,
+ width: _iconWidth,
+ padding: EdgeInsets.only(
+ top: topPadding, right: _iconRightPadding),
+ name: 'quote',
),
- ),
- ],
+ Expanded(
+ child: FlowyRichText(
+ key: _richTextKey,
+ placeholderText: 'Quote',
+ textNode: widget.textNode,
+ editorState: widget.editorState,
+ ),
+ ),
+ ],
+ ),
),
));
}
@@ -86,6 +88,6 @@ class _QuotedTextNodeWidgetState extends State
double get _quoteHeight {
final lines =
widget.textNode.toRawString().characters.where((c) => c == '\n').length;
- return (lines + 1) * _iconSize;
+ return (lines + 1) * _iconWidth;
}
}
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/toolbar_widget.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/toolbar_widget.dart
index dfc5c5c971..4c2b621795 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/toolbar_widget.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/toolbar_widget.dart
@@ -141,7 +141,7 @@ class _ToolbarWidgetState extends State with ToolbarMixin {
Size(toolbarHeight - (width != null ? 20 : 0), toolbarHeight),
child: Center(
child: FlowySvg(
- size: Size(width ?? 20, 20),
+ width: width ?? 20,
name: 'toolbar/$name',
),
),
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart
index e6f474668a..ecaf3325e4 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart
@@ -120,8 +120,9 @@ AppFlowyKeyEventHandler arrowKeysHandler = (editorState, event) {
editorState.updateCursorSelection(Selection.collapsed(leftPosition));
}
} else {
- editorState
- .updateCursorSelection(currentSelection.collapse(atStart: true));
+ editorState.updateCursorSelection(
+ currentSelection.collapse(atStart: currentSelection.isBackward),
+ );
}
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
@@ -131,7 +132,9 @@ AppFlowyKeyEventHandler arrowKeysHandler = (editorState, event) {
editorState.updateCursorSelection(Selection.collapsed(rightPosition));
}
} else {
- editorState.updateCursorSelection(currentSelection.collapse());
+ editorState.updateCursorSelection(
+ currentSelection.collapse(atStart: !currentSelection.isBackward),
+ );
}
return KeyEventResult.handled;
} else if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/slash_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/slash_handler.dart
index a13d203450..cbb345a370 100644
--- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/slash_handler.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/slash_handler.dart
@@ -448,5 +448,6 @@ class PopupListItem {
Widget _popupListIcon(String name) => FlowySvg(
name: 'popup_list/$name',
color: Colors.black,
- size: const Size.square(18.0),
+ width: 18.0,
+ height: 18.0,
);
diff --git a/frontend/app_flowy/packages/appflowy_editor/pubspec.yaml b/frontend/app_flowy/packages/appflowy_editor/pubspec.yaml
index 56820bf316..9a7318659f 100644
--- a/frontend/app_flowy/packages/appflowy_editor/pubspec.yaml
+++ b/frontend/app_flowy/packages/appflowy_editor/pubspec.yaml
@@ -1,6 +1,6 @@
name: appflowy_editor
-description: An easily extensible, test-covered rich text editing component for Flutter.
-version: 0.0.1
+description: A highly customizable rich-text editor for Flutter
+version: 0.0.2
homepage: https://github.com/AppFlowy-IO/AppFlowy
environment:
diff --git a/frontend/app_flowy/packages/appflowy_editor/test/infra/test_raw_key_event.dart b/frontend/app_flowy/packages/appflowy_editor/test/infra/test_raw_key_event.dart
index f54528064c..150a3e2d00 100644
--- a/frontend/app_flowy/packages/appflowy_editor/test/infra/test_raw_key_event.dart
+++ b/frontend/app_flowy/packages/appflowy_editor/test/infra/test_raw_key_event.dart
@@ -88,6 +88,12 @@ extension on LogicalKeyboardKey {
if (this == LogicalKeyboardKey.delete) {
return PhysicalKeyboardKey.delete;
}
+ if (this == LogicalKeyboardKey.arrowRight) {
+ return PhysicalKeyboardKey.arrowRight;
+ }
+ if (this == LogicalKeyboardKey.arrowLeft) {
+ return PhysicalKeyboardKey.arrowLeft;
+ }
if (this == LogicalKeyboardKey.pageDown) {
return PhysicalKeyboardKey.pageDown;
}
diff --git a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/arrow_keys_handler_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/arrow_keys_handler_test.dart
new file mode 100644
index 0000000000..e4631b56ad
--- /dev/null
+++ b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/arrow_keys_handler_test.dart
@@ -0,0 +1,84 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import '../../infra/test_editor.dart';
+
+void main() async {
+ setUpAll(() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+ });
+
+ group('arrow_keys_handler.dart', () {
+ testWidgets('Presses arrow right key, move the cursor from left to right',
+ (tester) async {
+ const text = 'Welcome to Appflowy 😁';
+ final editor = tester.editor
+ ..insertTextNode(text)
+ ..insertTextNode(text);
+ await editor.startTesting();
+
+ await editor.updateSelection(
+ Selection.single(path: [0], startOffset: 0),
+ );
+
+ final textNode = editor.nodeAtPath([0]) as TextNode;
+ for (var i = 0; i < text.length; i++) {
+ await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
+
+ if (i == text.length - 1) {
+ // Wrap to next node if the cursor is at the end of the current node.
+ expect(
+ editor.documentSelection,
+ Selection.single(
+ path: [1],
+ startOffset: 0,
+ ),
+ );
+ } else {
+ expect(
+ editor.documentSelection,
+ Selection.single(
+ path: [0],
+ startOffset: textNode.delta.nextRunePosition(i),
+ ),
+ );
+ }
+ }
+ });
+ });
+
+ testWidgets(
+ 'Presses arrow left/right key since selection is not collapsed and backward',
+ (tester) async {
+ await _testPressArrowKeyInNotCollapsedSelection(tester, true);
+ });
+
+ testWidgets(
+ 'Presses arrow left/right key since selection is not collapsed and forward',
+ (tester) async {
+ await _testPressArrowKeyInNotCollapsedSelection(tester, false);
+ });
+}
+
+Future _testPressArrowKeyInNotCollapsedSelection(
+ WidgetTester tester, bool isBackward) async {
+ const text = 'Welcome to Appflowy 😁';
+ final editor = tester.editor
+ ..insertTextNode(text)
+ ..insertTextNode(text);
+ await editor.startTesting();
+
+ final start = Position(path: [0], offset: 5);
+ final end = Position(path: [1], offset: 10);
+ final selection = Selection(
+ start: isBackward ? start : end,
+ end: isBackward ? end : start,
+ );
+ await editor.updateSelection(selection);
+ await editor.pressLogicKey(LogicalKeyboardKey.arrowLeft);
+ expect(editor.documentSelection?.start, start);
+
+ await editor.updateSelection(selection);
+ await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
+ expect(editor.documentSelection?.end, end);
+}