Skip to content

Commit 7814fab

Browse files
authored
[go_router] Fix requestFocus propagation to Navigator (#9177)
Fixes [166972](flutter/flutter#166972) ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 1578d70 commit 7814fab

File tree

4 files changed

+88
-26
lines changed

4 files changed

+88
-26
lines changed

packages/go_router/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 15.1.2
2+
3+
- Fixes focus request propagation from `GoRouter` to `Navigator` by properly handling the `requestFocus` parameter.
4+
15
## 15.1.1
26

37
- Adds missing `caseSensitive` to `GoRouteData.$route`.

packages/go_router/lib/src/builder.dart

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -121,24 +121,25 @@ class RouteBuilder {
121121
configuration: configuration,
122122
errorBuilder: errorBuilder,
123123
errorPageBuilder: errorPageBuilder,
124+
requestFocus: requestFocus,
124125
),
125126
);
126127
}
127128
}
128129

129130
class _CustomNavigator extends StatefulWidget {
130-
const _CustomNavigator({
131-
super.key,
132-
required this.navigatorKey,
133-
required this.observers,
134-
required this.navigatorRestorationId,
135-
required this.onPopPageWithRouteMatch,
136-
required this.matchList,
137-
required this.matches,
138-
required this.configuration,
139-
required this.errorBuilder,
140-
required this.errorPageBuilder,
141-
});
131+
const _CustomNavigator(
132+
{super.key,
133+
required this.navigatorKey,
134+
required this.observers,
135+
required this.navigatorRestorationId,
136+
required this.onPopPageWithRouteMatch,
137+
required this.matchList,
138+
required this.matches,
139+
required this.configuration,
140+
required this.errorBuilder,
141+
required this.errorPageBuilder,
142+
required this.requestFocus});
142143

143144
final GlobalKey<NavigatorState> navigatorKey;
144145
final List<NavigatorObserver> observers;
@@ -155,6 +156,7 @@ class _CustomNavigator extends StatefulWidget {
155156
final String? navigatorRestorationId;
156157
final GoRouterWidgetBuilder? errorBuilder;
157158
final GoRouterPageBuilder? errorPageBuilder;
159+
final bool requestFocus;
158160

159161
@override
160162
State<StatefulWidget> createState() => _CustomNavigatorState();
@@ -283,19 +285,19 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
283285
String? restorationScopeId,
284286
) {
285287
return _CustomNavigator(
286-
// The state needs to persist across rebuild.
287-
key: GlobalObjectKey(navigatorKey.hashCode),
288-
navigatorRestorationId: restorationScopeId,
289-
navigatorKey: navigatorKey,
290-
matches: match.matches,
291-
matchList: matchList,
292-
configuration: widget.configuration,
293-
observers: observers ?? const <NavigatorObserver>[],
294-
onPopPageWithRouteMatch: widget.onPopPageWithRouteMatch,
295-
// This is used to recursively build pages under this shell route.
296-
errorBuilder: widget.errorBuilder,
297-
errorPageBuilder: widget.errorPageBuilder,
298-
);
288+
// The state needs to persist across rebuild.
289+
key: GlobalObjectKey(navigatorKey.hashCode),
290+
navigatorRestorationId: restorationScopeId,
291+
navigatorKey: navigatorKey,
292+
matches: match.matches,
293+
matchList: matchList,
294+
configuration: widget.configuration,
295+
observers: observers ?? const <NavigatorObserver>[],
296+
onPopPageWithRouteMatch: widget.onPopPageWithRouteMatch,
297+
// This is used to recursively build pages under this shell route.
298+
errorBuilder: widget.errorBuilder,
299+
errorPageBuilder: widget.errorPageBuilder,
300+
requestFocus: widget.requestFocus);
299301
},
300302
);
301303
final Page<Object?>? page =
@@ -437,6 +439,7 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
437439
controller: _controller!,
438440
child: Navigator(
439441
key: widget.navigatorKey,
442+
requestFocus: widget.requestFocus,
440443
restorationScopeId: widget.navigatorRestorationId,
441444
pages: _pages!,
442445
observers: widget.observers,

packages/go_router/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: go_router
22
description: A declarative router for Flutter based on Navigation 2 supporting
33
deep linking, data-driven routes and more
4-
version: 15.1.1
4+
version: 15.1.2
55
repository: https://github.com/flutter/packages/tree/main/packages/go_router
66
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22
77

packages/go_router/test/builder_test.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,61 @@ void main() {
383383
(shellNavigatorKey.currentWidget as Navigator?)?.restorationScopeId,
384384
'scope1');
385385
});
386+
387+
testWidgets('GoRouter requestFocus defaults to true',
388+
(WidgetTester tester) async {
389+
final GoRouter router = GoRouter(
390+
routes: <RouteBase>[
391+
GoRoute(
392+
path: '/',
393+
builder: (BuildContext context, GoRouterState state) =>
394+
const Scaffold(
395+
body: Center(child: Text('Home')),
396+
),
397+
),
398+
],
399+
);
400+
401+
await tester.pumpWidget(
402+
MaterialApp.router(
403+
routerConfig: router,
404+
),
405+
);
406+
407+
addTearDown(() => router.dispose());
408+
409+
final Navigator navigator =
410+
tester.widget<Navigator>(find.byType(Navigator));
411+
expect(navigator.requestFocus, isTrue);
412+
});
413+
414+
testWidgets('GoRouter requestFocus can be set to false',
415+
(WidgetTester tester) async {
416+
final GoRouter router = GoRouter(
417+
routes: <RouteBase>[
418+
GoRoute(
419+
path: '/',
420+
builder: (BuildContext context, GoRouterState state) =>
421+
const Scaffold(
422+
body: Center(child: Text('Home')),
423+
),
424+
),
425+
],
426+
requestFocus: false,
427+
);
428+
429+
await tester.pumpWidget(
430+
MaterialApp.router(
431+
routerConfig: router,
432+
),
433+
);
434+
435+
addTearDown(() => router.dispose());
436+
437+
final Navigator navigator =
438+
tester.widget<Navigator>(find.byType(Navigator));
439+
expect(navigator.requestFocus, isFalse);
440+
});
386441
});
387442
}
388443

0 commit comments

Comments
 (0)