diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md index 1c7b9366fb1..ee6dde6d601 100644 --- a/packages/go_router_builder/CHANGELOG.md +++ b/packages/go_router_builder/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.1 + +- Updates README.md to use the mixin `with _$RouteName`. + ## 3.0.0 - Route classes now required to use a mixin `with _$RouteName`. diff --git a/packages/go_router_builder/README.md b/packages/go_router_builder/README.md index 6472f56e1d5..91545bda047 100644 --- a/packages/go_router_builder/README.md +++ b/packages/go_router_builder/README.md @@ -341,7 +341,8 @@ The code generator can convert simple types like `int` and `enum` to/from the ```dart enum BookKind { all, popular, recent } -class BooksRoute extends GoRouteData { +@TypedGoRoute(path: '/books') +class BooksRoute extends GoRouteData with _$BooksRoute { BooksRoute({this.kind = BookKind.popular}); final BookKind kind; @@ -370,7 +371,8 @@ method of the base class instead of the `build` method: ```dart -class MyMaterialRouteWithKey extends GoRouteData { +class MyMaterialRouteWithKey extends GoRouteData with _$MyMaterialRouteWithKey { + const MyMaterialRouteWithKey(); static const LocalKey _key = ValueKey('my-route-with-key'); @override MaterialPage buildPage(BuildContext context, GoRouterState state) { @@ -388,7 +390,8 @@ Overriding the `buildPage` method is also useful for custom transitions: ```dart -class FancyRoute extends GoRouteData { +class FancyRoute extends GoRouteData with _$FancyRoute { + const FancyRoute(); @override CustomTransitionPage buildPage( BuildContext context, @@ -421,6 +424,11 @@ Example: final GlobalKey shellNavigatorKey = GlobalKey(); final GlobalKey rootNavigatorKey = GlobalKey(); +@TypedShellRoute( + routes: >[ + TypedGoRoute(path: 'my-go-route'), + ], +) class MyShellRouteData extends ShellRouteData { const MyShellRouteData(); @@ -433,7 +441,7 @@ class MyShellRouteData extends ShellRouteData { } // For GoRoutes: -class MyGoRouteData extends GoRouteData { +class MyGoRouteData extends GoRouteData with _$MyGoRouteData { const MyGoRouteData(); static final GlobalKey $parentNavigatorKey = rootNavigatorKey; diff --git a/packages/go_router_builder/example/lib/readme_excerpts.dart b/packages/go_router_builder/example/lib/readme_excerpts.dart index 73577ef6452..af4cc03843b 100644 --- a/packages/go_router_builder/example/lib/readme_excerpts.dart +++ b/packages/go_router_builder/example/lib/readme_excerpts.dart @@ -307,7 +307,8 @@ class HotdogScreen extends StatelessWidget { // #docregion BookKind enum BookKind { all, popular, recent } -class BooksRoute extends GoRouteData { +@TypedGoRoute(path: '/books') +class BooksRoute extends GoRouteData with _$BooksRoute { BooksRoute({this.kind = BookKind.popular}); final BookKind kind; @@ -332,8 +333,10 @@ class BooksScreen extends StatelessWidget { } } +@TypedGoRoute(path: '/my-material-route-with-key') // #docregion MyMaterialRouteWithKey -class MyMaterialRouteWithKey extends GoRouteData { +class MyMaterialRouteWithKey extends GoRouteData with _$MyMaterialRouteWithKey { + const MyMaterialRouteWithKey(); static const LocalKey _key = ValueKey('my-route-with-key'); @override MaterialPage buildPage(BuildContext context, GoRouterState state) { @@ -373,8 +376,10 @@ class MyShellRoutePage extends StatelessWidget { } } +@TypedGoRoute(path: '/fancy') // #docregion FancyRoute -class FancyRoute extends GoRouteData { +class FancyRoute extends GoRouteData with _$FancyRoute { + const FancyRoute(); @override CustomTransitionPage buildPage( BuildContext context, @@ -395,6 +400,11 @@ class FancyRoute extends GoRouteData { final GlobalKey shellNavigatorKey = GlobalKey(); final GlobalKey rootNavigatorKey = GlobalKey(); +@TypedShellRoute( + routes: >[ + TypedGoRoute(path: 'my-go-route'), + ], +) class MyShellRouteData extends ShellRouteData { const MyShellRouteData(); @@ -407,7 +417,7 @@ class MyShellRouteData extends ShellRouteData { } // For GoRoutes: -class MyGoRouteData extends GoRouteData { +class MyGoRouteData extends GoRouteData with _$MyGoRouteData { const MyGoRouteData(); static final GlobalKey $parentNavigatorKey = rootNavigatorKey; diff --git a/packages/go_router_builder/example/lib/readme_excerpts.g.dart b/packages/go_router_builder/example/lib/readme_excerpts.g.dart index 41148c9230f..6a6ff0c69b6 100644 --- a/packages/go_router_builder/example/lib/readme_excerpts.g.dart +++ b/packages/go_router_builder/example/lib/readme_excerpts.g.dart @@ -14,6 +14,10 @@ List get $appRoutes => [ $myRoute, $personRouteWithExtra, $hotdogRouteWithEverything, + $booksRoute, + $myMaterialRouteWithKey, + $fancyRoute, + $myShellRouteData, ]; RouteBase get $homeRoute => GoRouteData.$route( @@ -228,3 +232,154 @@ bool _$boolConverter(String value) { throw UnsupportedError('Cannot convert "$value" into a bool.'); } } + +RouteBase get $booksRoute => GoRouteData.$route( + path: '/books', + factory: _$BooksRoute._fromState, + ); + +mixin _$BooksRoute on GoRouteData { + static BooksRoute _fromState(GoRouterState state) => BooksRoute( + kind: _$convertMapValue('kind', state.uri.queryParameters, + _$BookKindEnumMap._$fromName) ?? + BookKind.popular, + ); + + BooksRoute get _self => this as BooksRoute; + + @override + String get location => GoRouteData.$location( + '/books', + queryParams: { + if (_self.kind != BookKind.popular) + 'kind': _$BookKindEnumMap[_self.kind], + }, + ); + + @override + void go(BuildContext context) => context.go(location); + + @override + Future push(BuildContext context) => context.push(location); + + @override + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + @override + void replace(BuildContext context) => context.replace(location); +} + +const _$BookKindEnumMap = { + BookKind.all: 'all', + BookKind.popular: 'popular', + BookKind.recent: 'recent', +}; + +T? _$convertMapValue( + String key, + Map map, + T? Function(String) converter, +) { + final value = map[key]; + return value == null ? null : converter(value); +} + +extension on Map { + T? _$fromName(String? value) => + entries.where((element) => element.value == value).firstOrNull?.key; +} + +RouteBase get $myMaterialRouteWithKey => GoRouteData.$route( + path: '/my-material-route-with-key', + factory: _$MyMaterialRouteWithKey._fromState, + ); + +mixin _$MyMaterialRouteWithKey on GoRouteData { + static MyMaterialRouteWithKey _fromState(GoRouterState state) => + const MyMaterialRouteWithKey(); + + @override + String get location => GoRouteData.$location( + '/my-material-route-with-key', + ); + + @override + void go(BuildContext context) => context.go(location); + + @override + Future push(BuildContext context) => context.push(location); + + @override + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + @override + void replace(BuildContext context) => context.replace(location); +} + +RouteBase get $fancyRoute => GoRouteData.$route( + path: '/fancy', + factory: _$FancyRoute._fromState, + ); + +mixin _$FancyRoute on GoRouteData { + static FancyRoute _fromState(GoRouterState state) => const FancyRoute(); + + @override + String get location => GoRouteData.$location( + '/fancy', + ); + + @override + void go(BuildContext context) => context.go(location); + + @override + Future push(BuildContext context) => context.push(location); + + @override + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + @override + void replace(BuildContext context) => context.replace(location); +} + +RouteBase get $myShellRouteData => ShellRouteData.$route( + navigatorKey: MyShellRouteData.$navigatorKey, + factory: $MyShellRouteDataExtension._fromState, + routes: [ + GoRouteData.$route( + path: 'my-go-route', + parentNavigatorKey: MyGoRouteData.$parentNavigatorKey, + factory: _$MyGoRouteData._fromState, + ), + ], + ); + +extension $MyShellRouteDataExtension on MyShellRouteData { + static MyShellRouteData _fromState(GoRouterState state) => + const MyShellRouteData(); +} + +mixin _$MyGoRouteData on GoRouteData { + static MyGoRouteData _fromState(GoRouterState state) => const MyGoRouteData(); + + @override + String get location => GoRouteData.$location( + 'my-go-route', + ); + + @override + void go(BuildContext context) => context.go(location); + + @override + Future push(BuildContext context) => context.push(location); + + @override + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + @override + void replace(BuildContext context) => context.replace(location); +} diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml index aeb819b55dc..d5fe3284e60 100644 --- a/packages/go_router_builder/pubspec.yaml +++ b/packages/go_router_builder/pubspec.yaml @@ -2,7 +2,7 @@ name: go_router_builder description: >- A builder that supports generated strongly-typed route helpers for package:go_router -version: 3.0.0 +version: 3.0.1 repository: https://github.com/flutter/packages/tree/main/packages/go_router_builder issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22