diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/exit_editing_mode_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/exit_editing_mode_handler.dart new file mode 100644 index 0000000000..2ffe0f3b96 --- /dev/null +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/exit_editing_mode_handler.dart @@ -0,0 +1,7 @@ +import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; +import 'package:flutter/material.dart'; + +ShortcutEventHandler exitEditingModeEventHandler = (editorState, event) { + editorState.service.selectionService.clearSelection(); + return KeyEventResult.handled; +}; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart index 15cbb42517..22d318a658 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart @@ -4,6 +4,7 @@ import 'package:appflowy_editor/src/service/internal_key_event_handlers/arrow_ke import 'package:appflowy_editor/src/service/internal_key_event_handlers/backspace_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/copy_paste_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/enter_without_shift_in_text_node_handler.dart'; +import 'package:appflowy_editor/src/service/internal_key_event_handlers/exit_editing_mode_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/page_up_down_handler.dart'; import 'package:appflowy_editor/src/service/internal_key_event_handlers/redo_undo_handler.dart'; @@ -276,6 +277,11 @@ List builtInShortcutEvents = [ command: 'shift+parenthesis right', handler: markdownLinkOrImageHandler, ), + ShortcutEvent( + key: 'Exit editing mode', + command: 'escape', + handler: exitEditingModeEventHandler, + ), // https://github.com/flutter/flutter/issues/104944 // Workaround: Using space editing on the web platform often results in errors, // so adding a shortcut event to handle the space input instead of using the diff --git a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/exit_editing_mode_handler_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/exit_editing_mode_handler_test.dart new file mode 100644 index 0000000000..6ee51e4da6 --- /dev/null +++ b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/exit_editing_mode_handler_test.dart @@ -0,0 +1,50 @@ +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('exit_editing_mode_handler.dart', () { + testWidgets('Exit editing mode', (tester) async { + const text = 'Welcome to Appflowy 😁'; + const lines = 3; + final editor = tester.editor; + for (var i = 0; i < lines; i++) { + editor.insertTextNode(text); + } + await editor.startTesting(); + + // collaspsed selection + await _testSelection(editor, Selection.single(path: [1], startOffset: 0)); + + // single selection + await _testSelection( + editor, + Selection.single(path: [1], startOffset: 0, endOffset: text.length), + ); + + // mutliple selection + await _testSelection( + editor, + Selection( + start: Position(path: [0], offset: 0), + end: Position(path: [2], offset: text.length), + ), + ); + }); + + // Future _testSelection() + }); +} + +Future _testSelection( + EditorWidgetTester editor, Selection selection) async { + await editor.updateSelection(selection); + expect(editor.documentSelection, selection); + await editor.pressLogicKey(LogicalKeyboardKey.escape); + expect(editor.documentSelection, null); +}