@@ -2154,6 +2154,102 @@ void main() {
21542154 expect (value, 0.5 );
21552155 }, variant: const TargetPlatformVariant (< TargetPlatform > { TargetPlatform .iOS, TargetPlatform .macOS }));
21562156
2157+ testWidgets ('In directional nav, Slider can be navigated out of by using up and down arrows' , (WidgetTester tester) async {
2158+ const Map <ShortcutActivator , Intent > shortcuts = < ShortcutActivator , Intent > {
2159+ SingleActivator (LogicalKeyboardKey .arrowLeft): DirectionalFocusIntent (TraversalDirection .left),
2160+ SingleActivator (LogicalKeyboardKey .arrowRight): DirectionalFocusIntent (TraversalDirection .right),
2161+ SingleActivator (LogicalKeyboardKey .arrowDown): DirectionalFocusIntent (TraversalDirection .down),
2162+ SingleActivator (LogicalKeyboardKey .arrowUp): DirectionalFocusIntent (TraversalDirection .up),
2163+ };
2164+
2165+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy .alwaysTraditional;
2166+ double topSliderValue = 0.5 ;
2167+ double bottomSliderValue = 0.5 ;
2168+ await tester.pumpWidget (
2169+ MaterialApp (
2170+ home: Shortcuts (
2171+ shortcuts: shortcuts,
2172+ child: Material (
2173+ child: Center (
2174+ child: StatefulBuilder (builder: (BuildContext context, StateSetter setState) {
2175+ return MediaQuery (
2176+ data: const MediaQueryData (navigationMode: NavigationMode .directional),
2177+ child: Column (
2178+ children: < Widget > [
2179+ Slider (
2180+ value: topSliderValue,
2181+ onChanged: (double newValue) {
2182+ setState (() {
2183+ topSliderValue = newValue;
2184+ });
2185+ },
2186+ autofocus: true ,
2187+ ),
2188+ Slider (
2189+ value: bottomSliderValue,
2190+ onChanged: (double newValue) {
2191+ setState (() {
2192+ bottomSliderValue = newValue;
2193+ });
2194+ },
2195+ ),
2196+ ]
2197+ ),
2198+ );
2199+ }),
2200+ ),
2201+ ),
2202+ ),
2203+ ),
2204+ );
2205+ await tester.pumpAndSettle ();
2206+
2207+ // The top slider is auto-focused and can be adjusted with left and right arrow keys.
2208+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2209+ await tester.pumpAndSettle ();
2210+ expect (topSliderValue, 0.55 , reason: 'focused top Slider increased after first arrowRight' );
2211+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by first arrowRight' );
2212+
2213+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2214+ await tester.pumpAndSettle ();
2215+ expect (topSliderValue, 0.5 , reason: 'focused top Slider decreased after first arrowLeft' );
2216+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by first arrowLeft' );
2217+
2218+ // Pressing the down-arrow key moves focus down to the bottom slider
2219+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowDown);
2220+ await tester.pumpAndSettle ();
2221+ expect (topSliderValue, 0.5 , reason: 'arrowDown unfocuses top Slider, does not alter its value' );
2222+ expect (bottomSliderValue, 0.5 , reason: 'arrowDown focuses bottom Slider, does not alter its value' );
2223+
2224+ // The bottom slider is now focused and can be adjusted with left and right arrow keys.
2225+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2226+ await tester.pumpAndSettle ();
2227+ expect (topSliderValue, 0.5 , reason: 'unfocused top Slider unaffected by second arrowRight' );
2228+ expect (bottomSliderValue, 0.55 , reason: 'focused bottom Slider increased by second arrowRight' );
2229+
2230+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2231+ await tester.pumpAndSettle ();
2232+ expect (topSliderValue, 0.5 , reason: 'unfocused top Slider unaffected by second arrowLeft' );
2233+ expect (bottomSliderValue, 0.5 , reason: 'focused bottom Slider decreased by second arrowLeft' );
2234+
2235+ // Pressing the up-arrow key moves focus back up to the top slider
2236+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowUp);
2237+ await tester.pumpAndSettle ();
2238+ expect (topSliderValue, 0.5 , reason: 'arrowUp focuses top Slider, does not alter its value' );
2239+ expect (bottomSliderValue, 0.5 , reason: 'arrowUp unfocuses bottom Slider, does not alter its value' );
2240+
2241+ // The top slider is now focused again and can be adjusted with left and right arrow keys.
2242+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowRight);
2243+ await tester.pumpAndSettle ();
2244+ expect (topSliderValue, 0.55 , reason: 'focused top Slider increased after third arrowRight' );
2245+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by third arrowRight' );
2246+
2247+ await tester.sendKeyEvent (LogicalKeyboardKey .arrowLeft);
2248+ await tester.pumpAndSettle ();
2249+ expect (topSliderValue, 0.5 , reason: 'focused top Slider decreased after third arrowRight' );
2250+ expect (bottomSliderValue, 0.5 , reason: 'unfocused bottom Slider unaffected by third arrowRight' );
2251+ });
2252+
21572253 testWidgets ('Slider gains keyboard focus when it gains semantics focus on Windows' , (WidgetTester tester) async {
21582254 final SemanticsTester semantics = SemanticsTester (tester);
21592255 final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner! ;
0 commit comments