Skip to content

Commit 1d1fe12

Browse files
authored
[go_router_builder] Add ShellRoute support to go_router_builder (flutter#3439)
[go_router_builder] Add ShellRoute support to go_router_builder
1 parent b5ea225 commit 1d1fe12

17 files changed

Lines changed: 730 additions & 57 deletions

packages/go_router_builder/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.2.0
2+
3+
* Adds Support for ShellRoute
4+
15
## 1.1.7
26

37
* Supports default values for `Set`, `List` and `Iterable` route parameters.

packages/go_router_builder/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,44 @@ class FancyRoute extends GoRouteData {
327327
),
328328
}
329329
```
330+
331+
## TypedShellRoute and navigator keys
332+
333+
There may be situations were a child route of a shell needs to be displayed on a
334+
different navigator. This kind of scenarios can be achieved by declaring a
335+
**static** navigator key named:
336+
337+
- `$navigatorKey` for ShellRoutes
338+
- `$parentNavigatorKey` for GoRoutes
339+
340+
Example:
341+
342+
```dart
343+
// For ShellRoutes:
344+
final GlobalKey<NavigatorState> shellNavigatorKey = GlobalKey<NavigatorState>();
345+
346+
class MyShellRouteData extends ShellRouteData {
347+
const MyShellRouteData();
348+
349+
static final GlobalKey<NavigatorState> $navigatorKey = shellNavigatorKey;
350+
351+
@override
352+
Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
353+
// ...
354+
}
355+
}
356+
357+
// For GoRoutes:
358+
class MyGoRouteData extends GoRouteData {
359+
const MyGoRouteData();
360+
361+
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
362+
363+
@override
364+
Widget build(BuildContext context, GoRouterState state) {
365+
// ...
366+
}
367+
}
368+
```
369+
370+
An example is available [here](https://github.com/flutter/packages/blob/main/packages/go_router_builder/example/lib/shell_route_with_keys_example.dart).

packages/go_router_builder/example/lib/all_types.g.dart

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/go_router_builder/example/lib/main.g.dart

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:go_router/go_router.dart';
9+
10+
part 'shell_route_example.g.dart';
11+
12+
void main() => runApp(App());
13+
14+
class App extends StatelessWidget {
15+
App({super.key});
16+
17+
@override
18+
Widget build(BuildContext context) => MaterialApp.router(
19+
routerConfig: _router,
20+
);
21+
22+
final GoRouter _router = GoRouter(
23+
routes: $appRoutes,
24+
initialLocation: '/foo',
25+
);
26+
}
27+
28+
class HomeScreen extends StatelessWidget {
29+
const HomeScreen({super.key});
30+
31+
@override
32+
Widget build(BuildContext context) => Scaffold(
33+
appBar: AppBar(title: const Text('foo')),
34+
);
35+
}
36+
37+
@TypedShellRoute<MyShellRouteData>(
38+
routes: <TypedRoute<RouteData>>[
39+
TypedGoRoute<FooRouteData>(path: '/foo'),
40+
TypedGoRoute<BarRouteData>(path: '/bar'),
41+
],
42+
)
43+
class MyShellRouteData extends ShellRouteData {
44+
const MyShellRouteData();
45+
46+
@override
47+
Widget builder(
48+
BuildContext context,
49+
GoRouterState state,
50+
Widget navigator,
51+
) {
52+
return MyShellRouteScreen(child: navigator);
53+
}
54+
}
55+
56+
class FooRouteData extends GoRouteData {
57+
const FooRouteData();
58+
59+
@override
60+
Widget build(BuildContext context, GoRouterState state) {
61+
return const FooScreen();
62+
}
63+
}
64+
65+
class BarRouteData extends GoRouteData {
66+
const BarRouteData();
67+
68+
@override
69+
Widget build(BuildContext context, GoRouterState state) {
70+
return const BarScreen();
71+
}
72+
}
73+
74+
class MyShellRouteScreen extends StatelessWidget {
75+
const MyShellRouteScreen({required this.child, super.key});
76+
77+
final Widget child;
78+
79+
int getCurrentIndex(BuildContext context) {
80+
final String location = GoRouter.of(context).location;
81+
if (location == '/bar') {
82+
return 1;
83+
}
84+
return 0;
85+
}
86+
87+
@override
88+
Widget build(BuildContext context) {
89+
final int currentIndex = getCurrentIndex(context);
90+
return Scaffold(
91+
body: child,
92+
bottomNavigationBar: BottomNavigationBar(
93+
currentIndex: currentIndex,
94+
items: const <BottomNavigationBarItem>[
95+
BottomNavigationBarItem(
96+
icon: Icon(Icons.home),
97+
label: 'Foo',
98+
),
99+
BottomNavigationBarItem(
100+
icon: Icon(Icons.business),
101+
label: 'Bar',
102+
),
103+
],
104+
onTap: (int index) {
105+
switch (index) {
106+
case 0:
107+
const FooRouteData().go(context);
108+
break;
109+
case 1:
110+
const BarRouteData().go(context);
111+
break;
112+
}
113+
},
114+
),
115+
);
116+
}
117+
}
118+
119+
class FooScreen extends StatelessWidget {
120+
const FooScreen({super.key});
121+
122+
@override
123+
Widget build(BuildContext context) {
124+
return const Text('Foo');
125+
}
126+
}
127+
128+
class BarScreen extends StatelessWidget {
129+
const BarScreen({super.key});
130+
131+
@override
132+
Widget build(BuildContext context) {
133+
return const Text('Bar');
134+
}
135+
}
136+
137+
@TypedGoRoute<LoginRoute>(path: '/login')
138+
class LoginRoute extends GoRouteData {
139+
const LoginRoute();
140+
141+
@override
142+
Widget build(BuildContext context, GoRouterState state) =>
143+
const LoginScreen();
144+
}
145+
146+
class LoginScreen extends StatelessWidget {
147+
const LoginScreen({super.key});
148+
149+
@override
150+
Widget build(BuildContext context) {
151+
return const Text('Login');
152+
}
153+
}

packages/go_router_builder/example/lib/shell_route_example.g.dart

Lines changed: 83 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)