diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 8767c3d499..cd4e016c07 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 9.1.0 +- Adds the parentNavigatorKey parameter to ShellRouteData and StatefulShellRouteData. - Fixes a typo in docs for `StatefulShellRoute.indexedStack(...)`. - Cleans some typos in the documentation and asserts. diff --git a/packages/go_router/lib/src/route_data.dart b/packages/go_router/lib/src/route_data.dart index 2fedb32420..26a6fc42a9 100644 --- a/packages/go_router/lib/src/route_data.dart +++ b/packages/go_router/lib/src/route_data.dart @@ -156,6 +156,7 @@ abstract class ShellRouteData extends RouteData { static ShellRoute $route({ required T Function(GoRouterState) factory, GlobalKey? navigatorKey, + GlobalKey? parentNavigatorKey, List routes = const [], List? observers, String? restorationScopeId, @@ -189,6 +190,7 @@ abstract class ShellRouteData extends RouteData { return ShellRoute( builder: builder, pageBuilder: pageBuilder, + parentNavigatorKey: parentNavigatorKey, routes: routes, navigatorKey: navigatorKey, observers: observers, @@ -234,6 +236,7 @@ abstract class StatefulShellRouteData extends RouteData { static StatefulShellRoute $route({ required T Function(GoRouterState) factory, required List branches, + GlobalKey? parentNavigatorKey, ShellNavigationContainerBuilder? navigatorContainerBuilder, String? restorationScopeId, }) { @@ -269,6 +272,7 @@ abstract class StatefulShellRouteData extends RouteData { builder: builder, pageBuilder: pageBuilder, navigatorContainerBuilder: navigatorContainerBuilder, + parentNavigatorKey: parentNavigatorKey, restorationScopeId: restorationScopeId, ); } @@ -276,6 +280,7 @@ abstract class StatefulShellRouteData extends RouteData { branches: branches, builder: builder, pageBuilder: pageBuilder, + parentNavigatorKey: parentNavigatorKey, restorationScopeId: restorationScopeId, ); } diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 2730a7a892..24bb28db2b 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,7 +1,7 @@ name: go_router description: A declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more -version: 9.0.3 +version: 9.1.0 repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 diff --git a/packages/go_router/test/route_data_test.dart b/packages/go_router/test/route_data_test.dart index 684c6c3bcb..dc75fecd18 100644 --- a/packages/go_router/test/route_data_test.dart +++ b/packages/go_router/test/route_data_test.dart @@ -30,6 +30,30 @@ class _ShellRouteDataBuilder extends ShellRouteData { ); } +class _ShellRouteDataWithKey extends ShellRouteData { + const _ShellRouteDataWithKey(this.key); + + final Key key; + + @override + Widget builder( + BuildContext context, + GoRouterState state, + Widget navigator, + ) => + SizedBox( + key: key, + child: navigator, + ); +} + +class _GoRouteDataBuildWithKey extends GoRouteData { + const _GoRouteDataBuildWithKey(this.key); + final Key key; + @override + Widget build(BuildContext context, GoRouterState state) => SizedBox(key: key); +} + final GoRoute _goRouteDataBuild = GoRouteData.$route( path: '/build', factory: (GoRouterState state) => const _GoRouteDataBuild(), @@ -211,6 +235,63 @@ void main() { }, ); + testWidgets( + 'It should build the page from the overridden build method', + (WidgetTester tester) async { + final GlobalKey root = GlobalKey(); + final GlobalKey inner = GlobalKey(); + final GoRouter goRouter = GoRouter( + navigatorKey: root, + initialLocation: '/child/test', + routes: [ + ShellRouteData.$route( + factory: (GoRouterState state) => + const _ShellRouteDataWithKey(Key('under-shell')), + routes: [ + GoRouteData.$route( + path: '/child', + factory: (GoRouterState state) => + const _GoRouteDataBuildWithKey(Key('under')), + routes: [ + ShellRouteData.$route( + factory: (GoRouterState state) => + const _ShellRouteDataWithKey(Key('above-shell')), + navigatorKey: inner, + parentNavigatorKey: root, + routes: [ + GoRouteData.$route( + parentNavigatorKey: inner, + path: 'test', + factory: (GoRouterState state) => + const _GoRouteDataBuildWithKey(Key('above')), + ), + ], + ), + ]), + ], + ), + ], + ); + await tester.pumpWidget(MaterialApp.router( + routerConfig: goRouter, + )); + expect(find.byKey(const Key('under-shell')), findsNothing); + expect(find.byKey(const Key('under')), findsNothing); + + expect(find.byKey(const Key('above-shell')), findsOneWidget); + expect(find.byKey(const Key('above')), findsOneWidget); + + goRouter.pop(); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('under-shell')), findsOneWidget); + expect(find.byKey(const Key('under')), findsOneWidget); + + expect(find.byKey(const Key('above-shell')), findsNothing); + expect(find.byKey(const Key('above')), findsNothing); + }, + ); + testWidgets( 'It should build the page from the overridden buildPage method', (WidgetTester tester) async { @@ -257,6 +338,26 @@ void main() { expect(find.byKey(const Key('page-builder')), findsOneWidget); }, ); + + test('Can assign parent navigator key', () { + final GlobalKey key = GlobalKey(); + final StatefulShellRoute route = StatefulShellRouteData.$route( + parentNavigatorKey: key, + factory: (GoRouterState state) => + const _StatefulShellRouteDataPageBuilder(), + branches: [ + StatefulShellBranchData.$branch( + routes: [ + GoRouteData.$route( + path: '/child', + factory: (GoRouterState state) => const _GoRouteDataBuild(), + ), + ], + ), + ], + ); + expect(route.parentNavigatorKey, key); + }); }); testWidgets(