diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart index 0461310da9b..76799e474f1 100644 --- a/packages/flutter/lib/src/material/dropdown_menu.dart +++ b/packages/flutter/lib/src/material/dropdown_menu.dart @@ -550,6 +550,9 @@ class _DropdownMenuState extends State> { if (searchText.isEmpty) { return null; } + if (currentHighlight != null && entries[currentHighlight!].label.toLowerCase().contains(searchText)) { + return currentHighlight; + } final int index = entries.indexWhere((DropdownMenuEntry entry) => entry.label.toLowerCase().contains(searchText)); return index != -1 ? index : null; diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart index 48dfaea83b3..c2cb13c50f8 100644 --- a/packages/flutter/test/material/dropdown_menu_test.dart +++ b/packages/flutter/test/material/dropdown_menu_test.dart @@ -764,6 +764,116 @@ void main() { expect(item5material.color, Colors.transparent); // the previous item should not be highlighted. }, variant: TargetPlatformVariant.desktop()); + // Regression test for https://github.com/flutter/flutter/issues/147253. + testWidgets('Down key and up key can navigate on desktop platforms ' + 'when a label text contains another label text', (WidgetTester tester) async { + final ThemeData themeData = ThemeData(); + await tester.pumpWidget(MaterialApp( + theme: themeData, + home: const Scaffold( + body: DropdownMenu( + dropdownMenuEntries: >[ + DropdownMenuEntry( + value: 0, + label: 'ABC' + ), + DropdownMenuEntry( + value: 1, + label: 'AB' + ), + DropdownMenuEntry( + value: 2, + label: 'ABCD' + ), + ], + ), + ), + )); + + await tester.tap(find.byType(DropdownMenu)); + await tester.pump(); + + final Finder button0Material = find.descendant( + of: find.widgetWithText(MenuItemButton, 'ABC').last, + matching: find.byType(Material), + ); + final Finder button1Material = find.descendant( + of: find.widgetWithText(MenuItemButton, 'AB').last, + matching: find.byType(Material), + ); + final Finder button2Material = find.descendant( + of: find.widgetWithText(MenuItemButton, 'ABCD').last, + matching: find.byType(Material), + ); + + // Press down key three times, the highlight should move to the next item each time. + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pumpAndSettle(); + Material item0Material = tester.widget(button0Material); + expect(item0Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pumpAndSettle(); + Material item1Material = tester.widget(button1Material); + expect(item1Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pumpAndSettle(); + final Material item2Material = tester.widget(button2Material); + expect(item2Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + // Press up key two times, the highlight should up each time. + await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp); + await tester.pumpAndSettle(); + item1Material = tester.widget(button1Material); + expect(item1Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp); + await tester.pumpAndSettle(); + item0Material = tester.widget(button0Material); + expect(item0Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + }, variant: TargetPlatformVariant.desktop()); + + // Regression test for https://github.com/flutter/flutter/issues/147253. + testWidgets('Default search prioritises the current highlight on desktop platforms', + (WidgetTester tester) async { + final ThemeData themeData = ThemeData(); + await tester.pumpWidget(MaterialApp( + theme: themeData, + home: Scaffold( + body: DropdownMenu( + dropdownMenuEntries: menuChildren, + ), + ), + )); + + const String itemLabel = 'Item 2'; + // Open the menu + await tester.tap(find.byType(DropdownMenu)); + await tester.pumpAndSettle(); + // Highlight the third item by exact search. + await tester.enterText(find.byType(TextField).first, itemLabel); + await tester.pumpAndSettle(); + Finder button2Material = find.descendant( + of: find.widgetWithText(MenuItemButton, itemLabel).last, + matching: find.byType(Material), + ); + Material item2material = tester.widget(button2Material); + expect(item2material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + + // Search something that matches multiple items. + await tester.enterText(find.byType(TextField).first, 'Item'); + await tester.pumpAndSettle(); + // The third item should still be highlighted. + button2Material = find.descendant( + of: find.widgetWithText(MenuItemButton, itemLabel).last, + matching: find.byType(Material), + ); + item2material = tester.widget(button2Material); + expect(item2material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); + }, variant: TargetPlatformVariant.desktop()); + testWidgets('The text input should match the label of the menu item ' 'while pressing down key on desktop platforms', (WidgetTester tester) async { final ThemeData themeData = ThemeData();