Browse Source

Merge pull request #2068 from squidrye/fix-slash-menu-bug-2030

fix: slash menu responds to multiple key events
Alex Wallen 2 years ago
parent
commit
68fd5ffe67

+ 8 - 1
frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/selection_menu/selection_menu_widget.dart

@@ -324,7 +324,7 @@ class _SelectionMenuWidgetState extends State<SelectionMenuWidget> {
       _deleteLastCharacters();
       return KeyEventResult.handled;
     } else if (event.character != null &&
-        !arrowKeys.contains(event.logicalKey)) {
+        !arrowKeys.contains(event.logicalKey) && event.logicalKey != LogicalKeyboardKey.tab) {
       keyword += event.character!;
       _insertText(event.character!);
       return KeyEventResult.handled;
@@ -339,7 +339,14 @@ class _SelectionMenuWidgetState extends State<SelectionMenuWidget> {
       newSelectedIndex -= 1;
     } else if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
       newSelectedIndex += 1;
+    } else if (event.logicalKey == LogicalKeyboardKey.tab) {
+      newSelectedIndex += widget.maxItemInRow;
+      var currRow = (newSelectedIndex) % widget.maxItemInRow;
+      if (newSelectedIndex >= _showingItems.length) {
+        newSelectedIndex = (currRow + 1) % widget.maxItemInRow;
+      }
     }
+
     if (newSelectedIndex != _selectedIndex) {
       setState(() {
         _selectedIndex = newSelectedIndex.clamp(0, _showingItems.length - 1);

+ 81 - 0
frontend/appflowy_flutter/packages/appflowy_editor/test/render/selection_menu/selection_menu_widget_test.dart

@@ -118,6 +118,79 @@ void main() async {
         findsNothing,
       );
     });
+
+    group('tab and arrow keys move selection in desired direction', () {
+
+      testWidgets('left and right keys move selection in desired direction',
+        (tester) async {
+        final editor = await _prepare(tester);
+
+        var initialSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.arrowRight);
+
+        var newSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(newSelection.item), 5);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.arrowLeft);
+
+        var finalSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
+      });
+
+      testWidgets('up and down keys move selection in desired direction',
+        (tester) async {
+        final editor = await _prepare(tester);
+
+        var initialSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.arrowDown);
+
+        var newSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(newSelection.item), 1);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.arrowUp);
+
+        var finalSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 0);
+      });
+
+      testWidgets('arrow keys and tab move same selection',
+        (tester) async {
+        final editor = await _prepare(tester);
+
+        var initialSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.arrowDown);
+
+        var newSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(newSelection.item), 1);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.tab);
+
+        var finalSelection = getSelectedMenuItem(tester);
+        expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 6);
+      });
+
+      testWidgets('tab moves selection to next row Item on reaching end of current row',
+        (tester) async {
+        final editor = await _prepare(tester);
+
+        final initialSelection = getSelectedMenuItem(tester);
+
+        expect(defaultSelectionMenuItems.indexOf(initialSelection.item), 0);
+
+        await editor.pressLogicKey(LogicalKeyboardKey.tab);
+        await editor.pressLogicKey(LogicalKeyboardKey.tab);
+
+        final finalSelection = getSelectedMenuItem(tester);
+
+        expect(defaultSelectionMenuItems.indexOf(finalSelection.item), 1);
+      });
+    });
   });
 }
 
@@ -178,3 +251,11 @@ Future<void> _testDefaultSelectionMenuItems(
     expect(node?.attributes.check, false);
   }
 }
+
+SelectionMenuItemWidget getSelectedMenuItem(WidgetTester tester) {
+  return tester
+      .state(find.byWidgetPredicate(
+        (widget) => widget is SelectionMenuItemWidget && widget.isSelected,
+  ))
+      .widget as SelectionMenuItemWidget;
+}