@@ -11,13 +11,19 @@ import 'package:meta/meta_meta.dart';
11
11
import 'route.dart' ;
12
12
import 'state.dart' ;
13
13
14
+ /// A superclass for each route data
15
+ abstract class RouteData {
16
+ /// Default const constructor
17
+ const RouteData ();
18
+ }
19
+
14
20
/// Baseclass for supporting
15
21
/// [Type-safe routing] (https://pub.dev/documentation/go_router/latest/topics/Type-safe%20routes-topic.html).
16
22
///
17
23
/// Subclasses must override one of [build] , [buildPage] , or
18
24
/// [redirect] .
19
25
/// {@category Type-safe routes}
20
- abstract class GoRouteData {
26
+ abstract class GoRouteData extends RouteData {
21
27
/// Allows subclasses to have `const` constructors.
22
28
///
23
29
/// [GoRouteData] is abstract and cannot be instantiated directly.
@@ -74,7 +80,8 @@ abstract class GoRouteData {
74
80
static GoRoute $route <T extends GoRouteData >({
75
81
required String path,
76
82
required T Function (GoRouterState ) factory ,
77
- List <GoRoute > routes = const < GoRoute > [],
83
+ GlobalKey <NavigatorState >? parentNavigatorKey,
84
+ List <RouteBase > routes = const < RouteBase > [],
78
85
}) {
79
86
T factoryImpl (GoRouterState state) {
80
87
final Object ? extra = state.extra;
@@ -103,6 +110,7 @@ abstract class GoRouteData {
103
110
pageBuilder: pageBuilder,
104
111
redirect: redirect,
105
112
routes: routes,
113
+ parentNavigatorKey: parentNavigatorKey,
106
114
);
107
115
}
108
116
@@ -111,26 +119,138 @@ abstract class GoRouteData {
111
119
static final Expando <GoRouteData > _stateObjectExpando = Expando <GoRouteData >(
112
120
'GoRouteState to GoRouteData expando' ,
113
121
);
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 ;
114
127
}
115
128
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
117
221
@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
120
224
const TypedGoRoute ({
121
225
required this .path,
122
- this .routes = const < TypedGoRoute < GoRouteData >> [],
226
+ this .routes = const < TypedRoute < RouteData >> [],
123
227
});
124
228
125
- /// The path that corresponds to this rout .
229
+ /// The path that corresponds to this route .
126
230
///
127
231
/// See [GoRoute.path] .
232
+ ///
233
+ ///
128
234
final String path;
129
235
130
236
/// Child route definitions.
131
237
///
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;
134
254
}
135
255
136
256
/// Internal class used to signal that the default page behavior should be used.
0 commit comments