-
Notifications
You must be signed in to change notification settings - Fork 3.6k
go_router should allow setting requestFocus #4636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
0f3bfa0
fd8b12d
e67036a
30eae56
68cd1a6
9b3a098
28fe484
5e58db7
b66dcfc
5576b21
7e10266
46d0169
fac1b21
627d79e
bb50ce6
033a5ff
f863e60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| ## 10.1.0 | ||
|
|
||
| - Supports setting `requestFocus`. | ||
|
|
||
| ## 10.0.0 | ||
|
|
||
| - **BREAKING CHANGE**: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,7 @@ class RouteBuilder { | |
| required this.restorationScopeId, | ||
| required this.observers, | ||
| required this.onPopPageWithRouteMatch, | ||
| this.requestFocus = true, | ||
| }); | ||
|
|
||
| /// Builder function for a go router with Navigator. | ||
|
|
@@ -63,6 +64,12 @@ class RouteBuilder { | |
| /// its history. | ||
| final String? restorationScopeId; | ||
|
|
||
| /// Whether or not the navigator and it's new topmost route should request focus | ||
| /// when the new route is pushed onto the navigator. | ||
| /// | ||
| /// Defaults to true. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe add a link to navigator.requestfocus
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| final bool requestFocus; | ||
|
|
||
| /// NavigatorObserver used to receive notifications when navigating in between routes. | ||
| /// changes. | ||
| final List<NavigatorObserver> observers; | ||
|
|
@@ -137,6 +144,7 @@ class RouteBuilder { | |
| navigatorKey, | ||
| observers: observers, | ||
| restorationScopeId: restorationScopeId, | ||
| requestFocus: requestFocus, | ||
| ), | ||
| ); | ||
| } | ||
|
|
@@ -258,14 +266,18 @@ class RouteBuilder { | |
|
|
||
| // Build the Navigator for this shell route | ||
| Widget buildShellNavigator( | ||
| List<NavigatorObserver>? observers, String? restorationScopeId) { | ||
| List<NavigatorObserver>? observers, | ||
| String? restorationScopeId, { | ||
| bool requestFocus = true, | ||
| }) { | ||
| return _buildNavigator( | ||
| pagePopContext.onPopPage, | ||
| keyToPages[shellNavigatorKey]!, | ||
| shellNavigatorKey, | ||
| observers: observers ?? const <NavigatorObserver>[], | ||
| restorationScopeId: restorationScopeId, | ||
| heroController: heroController, | ||
| requestFocus: requestFocus, | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -298,13 +310,15 @@ class RouteBuilder { | |
| List<NavigatorObserver> observers = const <NavigatorObserver>[], | ||
| String? restorationScopeId, | ||
| HeroController? heroController, | ||
| bool requestFocus = true, | ||
| }) { | ||
| final Widget navigator = Navigator( | ||
| key: navigatorKey, | ||
| restorationScopeId: restorationScopeId, | ||
| pages: pages, | ||
| observers: observers, | ||
| onPopPage: onPopPage, | ||
| requestFocus: requestFocus, | ||
| ); | ||
| if (heroController != null) { | ||
| return HeroControllerScope( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,6 +83,7 @@ class GoRouter implements RouterConfig<RouteMatchList> { | |
| bool debugLogDiagnostics = false, | ||
| GlobalKey<NavigatorState>? navigatorKey, | ||
| String? restorationScopeId, | ||
| bool? requestFocus, | ||
|
||
| }) : backButtonDispatcher = RootBackButtonDispatcher(), | ||
| assert( | ||
| initialExtra == null || initialLocation != null, | ||
|
|
@@ -147,6 +148,7 @@ class GoRouter implements RouterConfig<RouteMatchList> { | |
| ...observers ?? <NavigatorObserver>[], | ||
| ], | ||
| restorationScopeId: restorationScopeId, | ||
| requestFocus: requestFocus, | ||
| // wrap the returned Navigator to enable GoRouter.of(context).go() et al, | ||
| // allowing the caller to wrap the navigator themselves | ||
| builderWithNav: (BuildContext context, Widget child) => | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:flutter/material.dart'; | ||
| import 'package:flutter_test/flutter_test.dart'; | ||
| import 'package:go_router/go_router.dart'; | ||
|
|
||
| void main() { | ||
| testWidgets('GoRouter does not request focus if requestFocus is false', | ||
| (WidgetTester tester) async { | ||
| final GlobalKey innerKey = GlobalKey(); | ||
| final FocusScopeNode focusNode = FocusScopeNode(); | ||
| final GoRouter router = GoRouter( | ||
| initialLocation: '/', | ||
| routes: <GoRoute>[ | ||
| GoRoute( | ||
| path: '/', | ||
| name: 'home', | ||
| builder: (_, __) => const Text('A'), | ||
| ), | ||
| GoRoute( | ||
| path: '/second', | ||
| name: 'second', | ||
| builder: (_, __) => Text('B', key: innerKey), | ||
| ), | ||
| ], | ||
| requestFocus: false, | ||
| ); | ||
|
|
||
| await tester.pumpWidget(Column( | ||
| children: <Widget>[ | ||
| FocusScope(node: focusNode, child: Container()), | ||
| Expanded( | ||
| child: MaterialApp.router( | ||
| routerConfig: router, | ||
| ), | ||
| ), | ||
| ], | ||
| )); | ||
|
|
||
| expect(find.text('A'), findsOneWidget); | ||
| expect(find.text('B', skipOffstage: false), findsNothing); | ||
| expect(focusNode.hasFocus, false); | ||
| focusNode.requestFocus(); | ||
| await tester.pumpAndSettle(); | ||
| expect(focusNode.hasFocus, true); | ||
|
|
||
| router.pushNamed('second'); | ||
| await tester.pumpAndSettle(); | ||
| expect(find.text('A', skipOffstage: false), findsOneWidget); | ||
| expect(find.text('B'), findsOneWidget); | ||
| expect(focusNode.hasFocus, true); | ||
|
|
||
| router.pop(); | ||
| await tester.pumpAndSettle(); | ||
| expect(find.text('A'), findsOneWidget); | ||
| expect(find.text('B', skipOffstage: false), findsNothing); | ||
| expect(focusNode.hasFocus, true); | ||
| }); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.