diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/tab_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/tab_handler.dart index 3b3091bbb2..1b079e03c5 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/tab_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/tab_handler.dart @@ -14,7 +14,8 @@ ShortcutEventHandler tabHandler = (editorState, event) { final textNode = textNodes.first; final previous = textNode.previous; - if (textNode.subtype != BuiltInAttributeKey.bulletedList) { + if (textNode.subtype != BuiltInAttributeKey.bulletedList && + textNode.subtype != BuiltInAttributeKey.checkbox) { final transaction = editorState.transaction ..insertText(textNode, selection.end.offset, ' ' * 4); editorState.apply(transaction); @@ -22,7 +23,8 @@ ShortcutEventHandler tabHandler = (editorState, event) { } if (previous == null || - previous.subtype != BuiltInAttributeKey.bulletedList) { + (previous.subtype != BuiltInAttributeKey.bulletedList && + previous.subtype != BuiltInAttributeKey.checkbox)) { return KeyEventResult.ignored; } diff --git a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/tab_handler_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/tab_handler_test.dart index 641282c55f..4b88960c38 100644 --- a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/tab_handler_test.dart +++ b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/tab_handler_test.dart @@ -152,4 +152,121 @@ void main() async { ); }); }); + + testWidgets('press tab in checkbox/todo list', (tester) async { + const text = 'Welcome to Appflowy 😁'; + final editor = tester.editor + ..insertTextNode( + text, + attributes: { + BuiltInAttributeKey.subtype: BuiltInAttributeKey.checkbox, + BuiltInAttributeKey.checkbox: false, + }, + ) + ..insertTextNode( + text, + attributes: { + BuiltInAttributeKey.subtype: BuiltInAttributeKey.checkbox, + BuiltInAttributeKey.checkbox: false, + }, + ) + ..insertTextNode( + text, + attributes: { + BuiltInAttributeKey.subtype: BuiltInAttributeKey.checkbox, + BuiltInAttributeKey.checkbox: false, + }, + ); + await editor.startTesting(); + var document = editor.document; + + var selection = Selection.single(path: [0], startOffset: 0); + await editor.updateSelection(selection); + await editor.pressLogicKey(LogicalKeyboardKey.tab); + + // nothing happens + expect( + editor.documentSelection, + Selection.single(path: [0], startOffset: 0), + ); + expect(editor.document.toJson(), document.toJson()); + + // Before + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // After + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + + selection = Selection.single(path: [1], startOffset: 0); + await editor.updateSelection(selection); + + await editor.pressLogicKey(LogicalKeyboardKey.tab); + + expect( + editor.documentSelection, + Selection.single(path: [0, 0], startOffset: 0), + ); + expect(editor.nodeAtPath([0])!.subtype, BuiltInAttributeKey.checkbox); + expect(editor.nodeAtPath([1])!.subtype, BuiltInAttributeKey.checkbox); + expect(editor.nodeAtPath([2]), null); + expect(editor.nodeAtPath([0, 0])!.subtype, BuiltInAttributeKey.checkbox); + + selection = Selection.single(path: [1], startOffset: 0); + await editor.updateSelection(selection); + await editor.pressLogicKey(LogicalKeyboardKey.tab); + + expect( + editor.documentSelection, + Selection.single(path: [0, 1], startOffset: 0), + ); + expect(editor.nodeAtPath([0])!.subtype, BuiltInAttributeKey.checkbox); + expect(editor.nodeAtPath([1]), null); + expect(editor.nodeAtPath([2]), null); + expect(editor.nodeAtPath([0, 0])!.subtype, BuiltInAttributeKey.checkbox); + expect(editor.nodeAtPath([0, 1])!.subtype, BuiltInAttributeKey.checkbox); + + // Before + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // After + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + // [] Welcome to Appflowy 😁 + document = editor.document; + selection = Selection.single(path: [0, 0], startOffset: 0); + await editor.updateSelection(selection); + await editor.pressLogicKey(LogicalKeyboardKey.tab); + + expect( + editor.documentSelection, + Selection.single(path: [0, 0], startOffset: 0), + ); + expect(editor.document.toJson(), document.toJson()); + + selection = Selection.single(path: [0, 1], startOffset: 0); + await editor.updateSelection(selection); + await editor.pressLogicKey(LogicalKeyboardKey.tab); + + expect( + editor.documentSelection, + Selection.single(path: [0, 0, 0], startOffset: 0), + ); + expect( + editor.nodeAtPath([0])!.subtype, + BuiltInAttributeKey.checkbox, + ); + expect( + editor.nodeAtPath([0, 0])!.subtype, + BuiltInAttributeKey.checkbox, + ); + expect(editor.nodeAtPath([0, 1]), null); + expect( + editor.nodeAtPath([0, 0, 0])!.subtype, + BuiltInAttributeKey.checkbox, + ); + }); }