-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[go_router] implemented helpers for StatefulShellRoute #4228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
990c293
4918014
c6bde6d
52ce037
b9c8080
9005a8c
8cf69b6
5963020
0ccc645
b186f35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,7 +140,7 @@ abstract class ShellRouteData extends RouteData { | |
) => | ||
const NoOpPage(); | ||
|
||
/// [pageBuilder] is used to build the page | ||
/// [builder] is used to build the widget | ||
Widget builder( | ||
BuildContext context, | ||
GoRouterState state, | ||
|
@@ -157,16 +157,10 @@ abstract class ShellRouteData extends RouteData { | |
required T Function(GoRouterState) factory, | ||
GlobalKey<NavigatorState>? navigatorKey, | ||
List<RouteBase> routes = const <RouteBase>[], | ||
List<NavigatorObserver>? observers, | ||
String? restorationScopeId, | ||
}) { | ||
T factoryImpl(GoRouterState state) { | ||
final Object? extra = state.extra; | ||
|
||
// If the "extra" value is of type `T` then we know it's the source | ||
// instance of `GoRouteData`, so it doesn't need to be recreated. | ||
if (extra is T) { | ||
return extra; | ||
} | ||
|
||
return (_stateObjectExpando[state] ??= factory(state)) as T; | ||
} | ||
|
||
|
@@ -197,6 +191,8 @@ abstract class ShellRouteData extends RouteData { | |
pageBuilder: pageBuilder, | ||
routes: routes, | ||
navigatorKey: navigatorKey, | ||
observers: observers, | ||
restorationScopeId: restorationScopeId, | ||
); | ||
} | ||
|
||
|
@@ -208,6 +204,116 @@ abstract class ShellRouteData extends RouteData { | |
); | ||
} | ||
|
||
/// Base class for supporting | ||
/// [StatefulShellRoute](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute-class.html) | ||
abstract class StatefulShellRouteData extends RouteData { | ||
/// Default const constructor | ||
const StatefulShellRouteData(); | ||
|
||
/// [pageBuilder] is used to build the page | ||
Page<void> pageBuilder( | ||
BuildContext context, | ||
GoRouterState state, | ||
StatefulNavigationShell navigationShell, | ||
) => | ||
const NoOpPage(); | ||
|
||
/// [builder] is used to build the widget | ||
Widget builder( | ||
BuildContext context, | ||
GoRouterState state, | ||
StatefulNavigationShell navigationShell, | ||
) => | ||
throw UnimplementedError( | ||
'One of `builder` or `pageBuilder` must be implemented.', | ||
); | ||
|
||
/// A helper function used by generated code. | ||
/// | ||
/// Should not be used directly. | ||
static StatefulShellRoute $route<T extends StatefulShellRouteData>({ | ||
hannah-hyj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
required T Function(GoRouterState) factory, | ||
required List<StatefulShellBranch> branches, | ||
ShellNavigationContainerBuilder? navigatorContainerBuilder, | ||
String? restorationScopeId, | ||
}) { | ||
T factoryImpl(GoRouterState state) { | ||
return (_stateObjectExpando[state] ??= factory(state)) as T; | ||
} | ||
|
||
Widget builder( | ||
BuildContext context, | ||
GoRouterState state, | ||
StatefulNavigationShell navigationShell, | ||
) => | ||
factoryImpl(state).builder( | ||
context, | ||
state, | ||
navigationShell, | ||
); | ||
|
||
Page<void> pageBuilder( | ||
BuildContext context, | ||
GoRouterState state, | ||
StatefulNavigationShell navigationShell, | ||
) => | ||
factoryImpl(state).pageBuilder( | ||
context, | ||
state, | ||
navigationShell, | ||
); | ||
|
||
if (navigatorContainerBuilder != null) { | ||
return StatefulShellRoute( | ||
branches: branches, | ||
builder: builder, | ||
pageBuilder: pageBuilder, | ||
navigatorContainerBuilder: navigatorContainerBuilder, | ||
restorationScopeId: restorationScopeId, | ||
); | ||
} | ||
return StatefulShellRoute.indexedStack( | ||
hannah-hyj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
branches: branches, | ||
builder: builder, | ||
pageBuilder: pageBuilder, | ||
restorationScopeId: restorationScopeId, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should also be in line 260, also how would one specify this in TypeStatefulShellRoute? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should also consider adding this to TypedShellRoute There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
); | ||
} | ||
|
||
/// Used to cache [StatefulShellRouteData] that corresponds to a given [GoRouterState] | ||
/// to minimize the number of times it has to be deserialized. | ||
static final Expando<StatefulShellRouteData> _stateObjectExpando = | ||
Expando<StatefulShellRouteData>( | ||
'GoRouteState to StatefulShellRouteData expando', | ||
); | ||
} | ||
|
||
/// Base class for supporting | ||
/// [StatefulShellRoute](https://pub.dev/documentation/go_router/latest/go_router/StatefulShellRoute-class.html) | ||
abstract class StatefulShellBranchData { | ||
/// Default const constructor | ||
const StatefulShellBranchData(); | ||
|
||
/// A helper function used by generated code. | ||
/// | ||
/// Should not be used directly. | ||
static StatefulShellBranch $branch<T extends StatefulShellBranchData>({ | ||
GlobalKey<NavigatorState>? navigatorKey, | ||
List<RouteBase> routes = const <RouteBase>[], | ||
List<NavigatorObserver>? observers, | ||
String? initialLocation, | ||
String? restorationScopeId, | ||
}) { | ||
return StatefulShellBranch( | ||
routes: routes, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how does one specify initialLocation and restorationScopeId? we may also want a way to specify observers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
navigatorKey: navigatorKey, | ||
observers: observers, | ||
initialLocation: initialLocation, | ||
restorationScopeId: restorationScopeId, | ||
); | ||
} | ||
} | ||
|
||
/// A superclass for each typed route descendant | ||
class TypedRoute<T extends RouteData> { | ||
/// Default const constructor | ||
|
@@ -259,6 +365,35 @@ class TypedShellRoute<T extends ShellRouteData> extends TypedRoute<T> { | |
final List<TypedRoute<RouteData>> routes; | ||
} | ||
|
||
/// A superclass for each typed shell route descendant | ||
@Target(<TargetKind>{TargetKind.library, TargetKind.classType}) | ||
class TypedStatefulShellRoute<T extends StatefulShellRouteData> | ||
extends TypedRoute<T> { | ||
/// Default const constructor | ||
const TypedStatefulShellRoute({ | ||
this.branches = const <TypedStatefulShellBranch<StatefulShellBranchData>>[], | ||
}); | ||
|
||
/// Child route definitions. | ||
/// | ||
/// See [RouteBase.routes]. | ||
final List<TypedStatefulShellBranch<StatefulShellBranchData>> branches; | ||
} | ||
|
||
/// A superclass for each typed shell route descendant | ||
@Target(<TargetKind>{TargetKind.library, TargetKind.classType}) | ||
class TypedStatefulShellBranch<T extends StatefulShellBranchData> { | ||
/// Default const constructor | ||
const TypedStatefulShellBranch({ | ||
this.routes = const <TypedRoute<RouteData>>[], | ||
}); | ||
|
||
/// Child route definitions. | ||
/// | ||
/// See [RouteBase.routes]. | ||
final List<TypedRoute<RouteData>> routes; | ||
} | ||
|
||
/// Internal class used to signal that the default page behavior should be used. | ||
@internal | ||
class NoOpPage extends Page<void> { | ||
|
Uh oh!
There was an error while loading. Please reload this page.