Skip to content

Commit 5834b4c

Browse files
hawkkillerchunhtaijohnpryan
authored
[go_router]: implemented helpers for ShellRoute (flutter#2730)
* [Feature]: implemented helpers for ShellRoute * [bugfix]: change export * Removed named private constructor for TypedRoute * Update CHANGELOG.md * Update pubspec.yaml * [Feature]: split routes per type * [Feature]: add new exports * Tests, refactor routes * remove line in changelog * Add navigatorKey for each route * Fixed tests * Format * Bump version in pubspec.yaml * Update packages/go_router/lib/src/route_data.dart Co-authored-by: chunhtai <[email protected]> * Update packages/go_router/lib/src/route_data.dart Co-authored-by: chunhtai <[email protected]> * Removed buildPageWithState tests * Bump version in pubspec * Address comments from code review * Export ShellRouteData * Remove unnecessary import --------- Co-authored-by: chunhtai <[email protected]> Co-authored-by: John Ryan <[email protected]>
1 parent af5906b commit 5834b4c

File tree

5 files changed

+262
-59
lines changed

5 files changed

+262
-59
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+
## 6.0.10
2+
3+
- Adds helpers for go_router_builder for ShellRoute support
4+
15
## 6.0.9
26

37
- Fixes deprecation message for `GoRouterState.namedLocation`

packages/go_router/lib/go_router.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export 'src/configuration.dart'
1111
export 'src/misc/extensions.dart';
1212
export 'src/misc/inherited_router.dart';
1313
export 'src/pages/custom_transition_page.dart';
14-
export 'src/route_data.dart' show GoRouteData, TypedGoRoute;
14+
export 'src/route_data.dart'
15+
show GoRouteData, TypedGoRoute, TypedShellRoute, ShellRouteData;
1516
export 'src/router.dart';
1617
export 'src/typedefs.dart'
1718
show GoRouterPageBuilder, GoRouterRedirect, GoRouterWidgetBuilder;

packages/go_router/lib/src/route_data.dart

Lines changed: 129 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ import 'package:meta/meta_meta.dart';
1111
import 'route.dart';
1212
import 'state.dart';
1313

14+
/// A superclass for each route data
15+
abstract class RouteData {
16+
/// Default const constructor
17+
const RouteData();
18+
}
19+
1420
/// Baseclass for supporting
1521
/// [Type-safe routing](https://pub.dev/documentation/go_router/latest/topics/Type-safe%20routes-topic.html).
1622
///
1723
/// Subclasses must override one of [build], [buildPage], or
1824
/// [redirect].
1925
/// {@category Type-safe routes}
20-
abstract class GoRouteData {
26+
abstract class GoRouteData extends RouteData {
2127
/// Allows subclasses to have `const` constructors.
2228
///
2329
/// [GoRouteData] is abstract and cannot be instantiated directly.
@@ -74,7 +80,8 @@ abstract class GoRouteData {
7480
static GoRoute $route<T extends GoRouteData>({
7581
required String path,
7682
required T Function(GoRouterState) factory,
77-
List<GoRoute> routes = const <GoRoute>[],
83+
GlobalKey<NavigatorState>? parentNavigatorKey,
84+
List<RouteBase> routes = const <RouteBase>[],
7885
}) {
7986
T factoryImpl(GoRouterState state) {
8087
final Object? extra = state.extra;
@@ -103,6 +110,7 @@ abstract class GoRouteData {
103110
pageBuilder: pageBuilder,
104111
redirect: redirect,
105112
routes: routes,
113+
parentNavigatorKey: parentNavigatorKey,
106114
);
107115
}
108116

@@ -111,26 +119,138 @@ abstract class GoRouteData {
111119
static final Expando<GoRouteData> _stateObjectExpando = Expando<GoRouteData>(
112120
'GoRouteState to GoRouteData expando',
113121
);
122+
123+
/// [navigatorKey] is used to point to a certain navigator
124+
///
125+
/// It will use the given key to find the right navigator for [GoRoute]
126+
GlobalKey<NavigatorState>? get navigatorKey => null;
114127
}
115128

116-
/// Annotation for types that support typed routing.
129+
/// Base class for supporting
130+
/// [nested navigation](https://pub.dev/packages/go_router#nested-navigation)
131+
abstract class ShellRouteData extends RouteData {
132+
/// Default const constructor
133+
const ShellRouteData();
134+
135+
/// [pageBuilder] is used to build the page
136+
Page<void> pageBuilder(
137+
BuildContext context,
138+
GoRouterState state,
139+
Widget navigator,
140+
) =>
141+
const NoOpPage();
142+
143+
/// [pageBuilder] is used to build the page
144+
Widget builder(
145+
BuildContext context,
146+
GoRouterState state,
147+
Widget navigator,
148+
) =>
149+
throw UnimplementedError(
150+
'One of `builder` or `pageBuilder` must be implemented.',
151+
);
152+
153+
/// A helper function used by generated code.
154+
///
155+
/// Should not be used directly.
156+
static ShellRoute $route<T extends ShellRouteData>({
157+
required T Function(GoRouterState) factory,
158+
GlobalKey<NavigatorState>? navigatorKey,
159+
List<RouteBase> routes = const <RouteBase>[],
160+
}) {
161+
T factoryImpl(GoRouterState state) {
162+
final Object? extra = state.extra;
163+
164+
// If the "extra" value is of type `T` then we know it's the source
165+
// instance of `GoRouteData`, so it doesn't need to be recreated.
166+
if (extra is T) {
167+
return extra;
168+
}
169+
170+
return (_stateObjectExpando[state] ??= factory(state)) as T;
171+
}
172+
173+
Widget builder(
174+
BuildContext context,
175+
GoRouterState state,
176+
Widget navigator,
177+
) =>
178+
factoryImpl(state).builder(
179+
context,
180+
state,
181+
navigator,
182+
);
183+
184+
Page<void> pageBuilder(
185+
BuildContext context,
186+
GoRouterState state,
187+
Widget navigator,
188+
) =>
189+
factoryImpl(state).pageBuilder(
190+
context,
191+
state,
192+
navigator,
193+
);
194+
195+
return ShellRoute(
196+
builder: builder,
197+
pageBuilder: pageBuilder,
198+
routes: routes,
199+
navigatorKey: navigatorKey,
200+
);
201+
}
202+
203+
/// Used to cache [ShellRouteData] that corresponds to a given [GoRouterState]
204+
/// to minimize the number of times it has to be deserialized.
205+
static final Expando<ShellRouteData> _stateObjectExpando =
206+
Expando<ShellRouteData>(
207+
'GoRouteState to ShellRouteData expando',
208+
);
209+
210+
/// It will be used to instantiate [Navigator] with the given key
211+
GlobalKey<NavigatorState>? get navigatorKey => null;
212+
}
213+
214+
/// A superclass for each typed route descendant
215+
class TypedRoute<T extends RouteData> {
216+
/// Default const constructor
217+
const TypedRoute();
218+
}
219+
220+
/// A superclass for each typed go route descendant
117221
@Target(<TargetKind>{TargetKind.library, TargetKind.classType})
118-
class TypedGoRoute<T extends GoRouteData> {
119-
/// Instantiates a new instance of [TypedGoRoute].
222+
class TypedGoRoute<T extends GoRouteData> extends TypedRoute<T> {
223+
/// Default const constructor
120224
const TypedGoRoute({
121225
required this.path,
122-
this.routes = const <TypedGoRoute<GoRouteData>>[],
226+
this.routes = const <TypedRoute<RouteData>>[],
123227
});
124228

125-
/// The path that corresponds to this rout.
229+
/// The path that corresponds to this route.
126230
///
127231
/// See [GoRoute.path].
232+
///
233+
///
128234
final String path;
129235

130236
/// Child route definitions.
131237
///
132-
/// See [GoRoute.routes].
133-
final List<TypedGoRoute<GoRouteData>> routes;
238+
/// See [RouteBase.routes].
239+
final List<TypedRoute<RouteData>> routes;
240+
}
241+
242+
/// A superclass for each typed shell route descendant
243+
@Target(<TargetKind>{TargetKind.library, TargetKind.classType})
244+
class TypedShellRoute<T extends ShellRouteData> extends TypedRoute<T> {
245+
/// Default const constructor
246+
const TypedShellRoute({
247+
this.routes = const <TypedRoute<RouteData>>[],
248+
});
249+
250+
/// Child route definitions.
251+
///
252+
/// See [RouteBase.routes].
253+
final List<TypedRoute<RouteData>> routes;
134254
}
135255

136256
/// Internal class used to signal that the default page behavior should be used.

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: 6.0.9
4+
version: 6.0.10
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

0 commit comments

Comments
 (0)