diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index e7346b2a7379..f1cc4dd90969 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.1.0 + +- Adds `GoRouter.maybeOf` to get the closest `GoRouter` from the context, if there is any. + ## 6.0.10 - Adds helpers for go_router_builder for ShellRoute support diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 73a86c645de6..b2a48e2d447e 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -301,6 +301,13 @@ class GoRouter extends ChangeNotifier implements RouterConfig { return inherited!.goRouter; } + /// The current GoRouter in the widget tree, if any. + static GoRouter? maybeOf(BuildContext context) { + final InheritedGoRouter? inherited = + context.dependOnInheritedWidgetOfExactType(); + return inherited?.goRouter; + } + @override void dispose() { _routeInformationProvider.dispose(); diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 0fbec8080dfc..fcf13313f83c 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: 6.0.10 +version: 6.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/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 4a3a61627f9e..84a3768484e6 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -3275,6 +3275,68 @@ void main() { }); }); }); + + group('of', () { + testWidgets( + 'It should return the go router instance of the widget tree', + (WidgetTester tester) async { + const Key key = Key('key'); + final List routes = [ + GoRoute( + path: '/', + builder: (_, __) => const SizedBox(key: key), + ), + ]; + + final GoRouter router = await createRouter(routes, tester); + final Element context = tester.element(find.byKey(key)); + final GoRouter foundRouter = GoRouter.of(context); + expect(foundRouter, router); + }, + ); + + testWidgets( + 'It should throw if there is no go router in the widget tree', + (WidgetTester tester) async { + const Key key = Key('key'); + await tester.pumpWidget(const SizedBox(key: key)); + + final Element context = tester.element(find.byKey(key)); + expect(() => GoRouter.of(context), throwsA(anything)); + }, + ); + }); + + group('maybeOf', () { + testWidgets( + 'It should return the go router instance of the widget tree', + (WidgetTester tester) async { + const Key key = Key('key'); + final List routes = [ + GoRoute( + path: '/', + builder: (_, __) => const SizedBox(key: key), + ), + ]; + + final GoRouter router = await createRouter(routes, tester); + final Element context = tester.element(find.byKey(key)); + final GoRouter? foundRouter = GoRouter.maybeOf(context); + expect(foundRouter, router); + }, + ); + + testWidgets( + 'It should return null if there is no go router in the widget tree', + (WidgetTester tester) async { + const Key key = Key('key'); + await tester.pumpWidget(const SizedBox(key: key)); + + final Element context = tester.element(find.byKey(key)); + expect(GoRouter.maybeOf(context), isNull); + }, + ); + }); } /// This allows a value of type T or T? to be treated as a value of type T?.