mirror of
https://github.com/flutter/packages.git
synced 2025-07-04 17:49:50 +08:00
[go_router_builder] Adds support for enhanced enums. (#2395)
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
## 1.0.12
|
||||||
|
|
||||||
|
* Adds support for enhanced enums. [#105876](https://github.com/flutter/flutter/issues/105876).
|
||||||
|
|
||||||
## 1.0.11
|
## 1.0.11
|
||||||
|
|
||||||
* Replaces mentions of the deprecated `GoRouteData.buildPage` with `GoRouteData.buildPageWithState`.
|
* Replaces mentions of the deprecated `GoRouteData.buildPage` with `GoRouteData.buildPageWithState`.
|
||||||
|
@ -11,150 +11,353 @@ import 'shared/data.dart';
|
|||||||
|
|
||||||
part 'all_types.g.dart';
|
part 'all_types.g.dart';
|
||||||
|
|
||||||
@TypedGoRoute<AllTypesRoute>(
|
@TypedGoRoute<AllTypesBaseRoute>(path: '/', routes: <TypedGoRoute<GoRouteData>>[
|
||||||
path: '/:requiredBigIntField/:requiredBoolField/:requiredDateTimeField'
|
TypedGoRoute<BigIntRoute>(path: 'big-int-route/:requiredBigIntField'),
|
||||||
'/:requiredDoubleField/:requiredEnumField/:requiredIntField'
|
TypedGoRoute<BoolRoute>(path: 'bool-route/:requiredBoolField'),
|
||||||
'/:requiredNumField/:requiredStringField/:requiredUriField',
|
TypedGoRoute<DateTimeRoute>(path: 'date-time-route/:requiredDateTimeField'),
|
||||||
)
|
TypedGoRoute<DoubleRoute>(path: 'double-route/:requiredDoubleField'),
|
||||||
|
TypedGoRoute<IntRoute>(path: 'int-route/:requiredIntField'),
|
||||||
|
TypedGoRoute<NumRoute>(path: 'num-route/:requiredNumField'),
|
||||||
|
TypedGoRoute<DoubleRoute>(path: 'double-route/:requiredDoubleField'),
|
||||||
|
TypedGoRoute<EnumRoute>(path: 'enum-route/:requiredEnumField'),
|
||||||
|
TypedGoRoute<EnhancedEnumRoute>(
|
||||||
|
path: 'enhanced-enum-route/:requiredEnumField'),
|
||||||
|
TypedGoRoute<StringRoute>(path: 'string-route/:requiredStringField'),
|
||||||
|
TypedGoRoute<UriRoute>(path: 'uri-route/:requiredUriField'),
|
||||||
|
])
|
||||||
@immutable
|
@immutable
|
||||||
class AllTypesRoute extends GoRouteData {
|
class AllTypesBaseRoute extends GoRouteData {
|
||||||
const AllTypesRoute({
|
const AllTypesBaseRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => const BasePage<void>(
|
||||||
|
dataTitle: 'Root',
|
||||||
|
param: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class BigIntRoute extends GoRouteData {
|
||||||
|
BigIntRoute({
|
||||||
required this.requiredBigIntField,
|
required this.requiredBigIntField,
|
||||||
required this.requiredBoolField,
|
|
||||||
required this.requiredDateTimeField,
|
|
||||||
required this.requiredDoubleField,
|
|
||||||
required this.requiredEnumField,
|
|
||||||
required this.requiredIntField,
|
|
||||||
required this.requiredNumField,
|
|
||||||
required this.requiredStringField,
|
|
||||||
required this.requiredUriField,
|
|
||||||
this.bigIntField,
|
this.bigIntField,
|
||||||
this.boolField,
|
|
||||||
this.dateTimeField,
|
|
||||||
this.doubleField,
|
|
||||||
this.enumField,
|
|
||||||
this.intField,
|
|
||||||
this.numField,
|
|
||||||
this.stringField,
|
|
||||||
this.uriField,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final BigInt requiredBigIntField;
|
final BigInt requiredBigIntField;
|
||||||
final bool requiredBoolField;
|
|
||||||
final DateTime requiredDateTimeField;
|
|
||||||
final double requiredDoubleField;
|
|
||||||
final PersonDetails requiredEnumField;
|
|
||||||
final int requiredIntField;
|
|
||||||
final num requiredNumField;
|
|
||||||
final String requiredStringField;
|
|
||||||
final Uri requiredUriField;
|
|
||||||
|
|
||||||
final BigInt? bigIntField;
|
final BigInt? bigIntField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<BigInt>(
|
||||||
|
dataTitle: 'BigIntRoute',
|
||||||
|
param: requiredBigIntField,
|
||||||
|
queryParam: bigIntField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('BigIntRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoolRoute extends GoRouteData {
|
||||||
|
BoolRoute({
|
||||||
|
required this.requiredBoolField,
|
||||||
|
this.boolField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool requiredBoolField;
|
||||||
final bool? boolField;
|
final bool? boolField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<bool>(
|
||||||
|
dataTitle: 'BoolRoute',
|
||||||
|
param: requiredBoolField,
|
||||||
|
queryParam: boolField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('BoolRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DateTimeRoute extends GoRouteData {
|
||||||
|
DateTimeRoute({
|
||||||
|
required this.requiredDateTimeField,
|
||||||
|
this.dateTimeField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final DateTime requiredDateTimeField;
|
||||||
final DateTime? dateTimeField;
|
final DateTime? dateTimeField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<DateTime>(
|
||||||
|
dataTitle: 'DateTimeRoute',
|
||||||
|
param: requiredDateTimeField,
|
||||||
|
queryParam: dateTimeField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('DateTimeRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DoubleRoute extends GoRouteData {
|
||||||
|
DoubleRoute({
|
||||||
|
required this.requiredDoubleField,
|
||||||
|
this.doubleField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final double requiredDoubleField;
|
||||||
final double? doubleField;
|
final double? doubleField;
|
||||||
final PersonDetails? enumField;
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<double>(
|
||||||
|
dataTitle: 'DoubleRoute',
|
||||||
|
param: requiredDoubleField,
|
||||||
|
queryParam: doubleField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('DoubleRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntRoute extends GoRouteData {
|
||||||
|
IntRoute({
|
||||||
|
required this.requiredIntField,
|
||||||
|
this.intField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final int requiredIntField;
|
||||||
final int? intField;
|
final int? intField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<int>(
|
||||||
|
dataTitle: 'IntRoute',
|
||||||
|
param: requiredIntField,
|
||||||
|
queryParam: intField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('IntRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NumRoute extends GoRouteData {
|
||||||
|
NumRoute({
|
||||||
|
required this.requiredNumField,
|
||||||
|
this.numField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final num requiredNumField;
|
||||||
final num? numField;
|
final num? numField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<num>(
|
||||||
|
dataTitle: 'NumRoute',
|
||||||
|
param: requiredNumField,
|
||||||
|
queryParam: numField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('NumRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnumRoute extends GoRouteData {
|
||||||
|
EnumRoute({
|
||||||
|
required this.requiredEnumField,
|
||||||
|
this.enumField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final PersonDetails requiredEnumField;
|
||||||
|
final PersonDetails? enumField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<PersonDetails>(
|
||||||
|
dataTitle: 'EnumRoute',
|
||||||
|
param: requiredEnumField,
|
||||||
|
queryParam: enumField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('EnumRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnhancedEnumRoute extends GoRouteData {
|
||||||
|
EnhancedEnumRoute({
|
||||||
|
required this.requiredEnumField,
|
||||||
|
this.enumField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final SportDetails requiredEnumField;
|
||||||
|
final SportDetails? enumField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<SportDetails>(
|
||||||
|
dataTitle: 'EnhancedEnumRoute',
|
||||||
|
param: requiredEnumField,
|
||||||
|
queryParam: enumField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('EnhancedEnumRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringRoute extends GoRouteData {
|
||||||
|
StringRoute({
|
||||||
|
required this.requiredStringField,
|
||||||
|
this.stringField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String requiredStringField;
|
||||||
final String? stringField;
|
final String? stringField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<String>(
|
||||||
|
dataTitle: 'StringRoute',
|
||||||
|
param: requiredStringField,
|
||||||
|
queryParam: stringField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('StringRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UriRoute extends GoRouteData {
|
||||||
|
UriRoute({
|
||||||
|
required this.requiredUriField,
|
||||||
|
this.uriField,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Uri requiredUriField;
|
||||||
final Uri? uriField;
|
final Uri? uriField;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => BasePage<Uri>(
|
||||||
|
dataTitle: 'UriRoute',
|
||||||
|
param: requiredUriField,
|
||||||
|
queryParam: uriField,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget drawerTile(BuildContext context) => ListTile(
|
||||||
|
title: const Text('UriRoute'),
|
||||||
|
onTap: () => go(context),
|
||||||
|
selected: GoRouter.of(context).location == location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class BasePage<T> extends StatelessWidget {
|
||||||
|
const BasePage({
|
||||||
|
required this.dataTitle,
|
||||||
|
required this.param,
|
||||||
|
this.queryParam,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String dataTitle;
|
||||||
|
final T param;
|
||||||
|
final T? queryParam;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Scaffold(
|
Widget build(BuildContext context) => Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Go router typed routes'),
|
||||||
|
),
|
||||||
|
drawer: Drawer(
|
||||||
|
child: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
BigIntRoute(
|
||||||
|
requiredBigIntField: BigInt.two,
|
||||||
|
bigIntField: BigInt.zero,
|
||||||
|
).drawerTile(context),
|
||||||
|
BoolRoute(
|
||||||
|
requiredBoolField: true,
|
||||||
|
boolField: false,
|
||||||
|
).drawerTile(context),
|
||||||
|
DateTimeRoute(
|
||||||
|
requiredDateTimeField: DateTime(1970),
|
||||||
|
dateTimeField: DateTime(0),
|
||||||
|
).drawerTile(context),
|
||||||
|
DoubleRoute(
|
||||||
|
requiredDoubleField: 3.14,
|
||||||
|
doubleField: -3.14,
|
||||||
|
).drawerTile(context),
|
||||||
|
IntRoute(
|
||||||
|
requiredIntField: 42,
|
||||||
|
intField: -42,
|
||||||
|
).drawerTile(context),
|
||||||
|
NumRoute(
|
||||||
|
requiredNumField: 2.71828,
|
||||||
|
numField: -2.71828,
|
||||||
|
).drawerTile(context),
|
||||||
|
StringRoute(
|
||||||
|
requiredStringField: r'$!/#bob%%20',
|
||||||
|
stringField: r'$!/#bob%%20',
|
||||||
|
).drawerTile(context),
|
||||||
|
EnumRoute(
|
||||||
|
requiredEnumField: PersonDetails.favoriteSport,
|
||||||
|
enumField: PersonDetails.favoriteFood,
|
||||||
|
).drawerTile(context),
|
||||||
|
EnhancedEnumRoute(
|
||||||
|
requiredEnumField: SportDetails.football,
|
||||||
|
enumField: SportDetails.volleyball,
|
||||||
|
).drawerTile(context),
|
||||||
|
UriRoute(
|
||||||
|
requiredUriField: Uri.parse('https://dart.dev'),
|
||||||
|
uriField: Uri.parse('https://dart.dev'),
|
||||||
|
).drawerTile(context),
|
||||||
|
],
|
||||||
|
)),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const Text('built!'),
|
const Text('Built!'),
|
||||||
SelectableText(location),
|
Text(dataTitle),
|
||||||
|
Text('Param: $param'),
|
||||||
|
Text('Query param: $queryParam'),
|
||||||
|
SelectableText(GoRouter.of(context).location),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hashAll(_items);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (other is AllTypesRoute) {
|
|
||||||
final List<Object?> mine = _items;
|
|
||||||
final List<Object?> theirs = other._items;
|
|
||||||
for (int i = 0; i < mine.length; i++) {
|
|
||||||
if (mine[i] != theirs[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Object?> get _items => <Object?>[
|
|
||||||
requiredBigIntField,
|
|
||||||
requiredBoolField,
|
|
||||||
requiredDateTimeField,
|
|
||||||
requiredDoubleField,
|
|
||||||
requiredEnumField,
|
|
||||||
requiredIntField,
|
|
||||||
requiredNumField,
|
|
||||||
requiredStringField,
|
|
||||||
requiredUriField,
|
|
||||||
bigIntField,
|
|
||||||
boolField,
|
|
||||||
dateTimeField,
|
|
||||||
doubleField,
|
|
||||||
enumField,
|
|
||||||
intField,
|
|
||||||
numField,
|
|
||||||
stringField,
|
|
||||||
uriField,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() => runApp(AllTypesApp());
|
void main() => runApp(AllTypesApp());
|
||||||
|
|
||||||
class AllTypesApp extends StatelessWidget {
|
class AllTypesApp extends StatelessWidget {
|
||||||
AllTypesApp({Key? key}) : super(key: key);
|
AllTypesApp({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => MaterialApp.router(
|
Widget build(BuildContext context) => MaterialApp.router(
|
||||||
routeInformationParser: _router.routeInformationParser,
|
routeInformationParser: _router.routeInformationParser,
|
||||||
routerDelegate: _router.routerDelegate,
|
routerDelegate: _router.routerDelegate,
|
||||||
|
routeInformationProvider: _router.routeInformationProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
late final GoRouter _router = GoRouter(
|
late final GoRouter _router = GoRouter(
|
||||||
debugLogDiagnostics: true,
|
debugLogDiagnostics: true,
|
||||||
routes: $appRoutes,
|
routes: $appRoutes,
|
||||||
|
initialLocation: const AllTypesBaseRoute().location,
|
||||||
// redirect to the login page if the user is not logged in
|
|
||||||
redirect: (GoRouterState state) {
|
|
||||||
if (state.location == '/') {
|
|
||||||
final String location = AllTypesRoute(
|
|
||||||
requiredBigIntField: BigInt.two,
|
|
||||||
requiredBoolField: true,
|
|
||||||
requiredDateTimeField: DateTime.now(),
|
|
||||||
requiredDoubleField: 3.14,
|
|
||||||
requiredEnumField: PersonDetails.favoriteSport,
|
|
||||||
requiredIntField: -42,
|
|
||||||
requiredNumField: 3.15,
|
|
||||||
requiredStringField: r'$!/#bob%%20',
|
|
||||||
requiredUriField: Uri.parse('https://dart.dev'),
|
|
||||||
bigIntField: BigInt.zero,
|
|
||||||
boolField: false,
|
|
||||||
dateTimeField: DateTime(0),
|
|
||||||
doubleField: 3.14,
|
|
||||||
enumField: PersonDetails.favoriteSport,
|
|
||||||
intField: -42,
|
|
||||||
numField: 3.15,
|
|
||||||
stringField: r'$!/#bob%%20',
|
|
||||||
uriField: Uri.parse('https://dart.dev'),
|
|
||||||
).location;
|
|
||||||
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no need to redirect at all
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,57 +9,256 @@ part of 'all_types.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
List<GoRoute> get $appRoutes => [
|
List<GoRoute> get $appRoutes => [
|
||||||
$allTypesRoute,
|
$allTypesBaseRoute,
|
||||||
];
|
];
|
||||||
|
|
||||||
GoRoute get $allTypesRoute => GoRouteData.$route(
|
GoRoute get $allTypesBaseRoute => GoRouteData.$route(
|
||||||
path:
|
path: '/',
|
||||||
'/:requiredBigIntField/:requiredBoolField/:requiredDateTimeField/:requiredDoubleField/:requiredEnumField/:requiredIntField/:requiredNumField/:requiredStringField/:requiredUriField',
|
factory: $AllTypesBaseRouteExtension._fromState,
|
||||||
factory: $AllTypesRouteExtension._fromState,
|
routes: [
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'big-int-route/:requiredBigIntField',
|
||||||
|
factory: $BigIntRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'bool-route/:requiredBoolField',
|
||||||
|
factory: $BoolRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'date-time-route/:requiredDateTimeField',
|
||||||
|
factory: $DateTimeRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'double-route/:requiredDoubleField',
|
||||||
|
factory: $DoubleRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'int-route/:requiredIntField',
|
||||||
|
factory: $IntRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'num-route/:requiredNumField',
|
||||||
|
factory: $NumRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'double-route/:requiredDoubleField',
|
||||||
|
factory: $DoubleRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'enum-route/:requiredEnumField',
|
||||||
|
factory: $EnumRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'enhanced-enum-route/:requiredEnumField',
|
||||||
|
factory: $EnhancedEnumRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'string-route/:requiredStringField',
|
||||||
|
factory: $StringRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'uri-route/:requiredUriField',
|
||||||
|
factory: $UriRouteExtension._fromState,
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
extension $AllTypesRouteExtension on AllTypesRoute {
|
extension $AllTypesBaseRouteExtension on AllTypesBaseRoute {
|
||||||
static AllTypesRoute _fromState(GoRouterState state) => AllTypesRoute(
|
static AllTypesBaseRoute _fromState(GoRouterState state) =>
|
||||||
|
const AllTypesBaseRoute();
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/',
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $BigIntRouteExtension on BigIntRoute {
|
||||||
|
static BigIntRoute _fromState(GoRouterState state) => BigIntRoute(
|
||||||
requiredBigIntField: BigInt.parse(state.params['requiredBigIntField']!),
|
requiredBigIntField: BigInt.parse(state.params['requiredBigIntField']!),
|
||||||
requiredBoolField: _$boolConverter(state.params['requiredBoolField']!),
|
|
||||||
requiredDateTimeField:
|
|
||||||
DateTime.parse(state.params['requiredDateTimeField']!),
|
|
||||||
requiredDoubleField: double.parse(state.params['requiredDoubleField']!),
|
|
||||||
requiredEnumField: _$PersonDetailsEnumMap
|
|
||||||
._$fromName(state.params['requiredEnumField']!),
|
|
||||||
requiredIntField: int.parse(state.params['requiredIntField']!),
|
|
||||||
requiredNumField: num.parse(state.params['requiredNumField']!),
|
|
||||||
requiredStringField: state.params['requiredStringField']!,
|
|
||||||
requiredUriField: Uri.parse(state.params['requiredUriField']!),
|
|
||||||
bigIntField:
|
bigIntField:
|
||||||
_$convertMapValue('big-int-field', state.queryParams, BigInt.parse),
|
_$convertMapValue('big-int-field', state.queryParams, BigInt.parse),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/big-int-route/${Uri.encodeComponent(requiredBigIntField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (bigIntField != null) 'big-int-field': bigIntField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $BoolRouteExtension on BoolRoute {
|
||||||
|
static BoolRoute _fromState(GoRouterState state) => BoolRoute(
|
||||||
|
requiredBoolField: _$boolConverter(state.params['requiredBoolField']!),
|
||||||
boolField:
|
boolField:
|
||||||
_$convertMapValue('bool-field', state.queryParams, _$boolConverter),
|
_$convertMapValue('bool-field', state.queryParams, _$boolConverter),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/bool-route/${Uri.encodeComponent(requiredBoolField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (boolField != null) 'bool-field': boolField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $DateTimeRouteExtension on DateTimeRoute {
|
||||||
|
static DateTimeRoute _fromState(GoRouterState state) => DateTimeRoute(
|
||||||
|
requiredDateTimeField:
|
||||||
|
DateTime.parse(state.params['requiredDateTimeField']!),
|
||||||
dateTimeField: _$convertMapValue(
|
dateTimeField: _$convertMapValue(
|
||||||
'date-time-field', state.queryParams, DateTime.parse),
|
'date-time-field', state.queryParams, DateTime.parse),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/date-time-route/${Uri.encodeComponent(requiredDateTimeField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (dateTimeField != null)
|
||||||
|
'date-time-field': dateTimeField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $DoubleRouteExtension on DoubleRoute {
|
||||||
|
static DoubleRoute _fromState(GoRouterState state) => DoubleRoute(
|
||||||
|
requiredDoubleField: double.parse(state.params['requiredDoubleField']!),
|
||||||
doubleField:
|
doubleField:
|
||||||
_$convertMapValue('double-field', state.queryParams, double.parse),
|
_$convertMapValue('double-field', state.queryParams, double.parse),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/double-route/${Uri.encodeComponent(requiredDoubleField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (doubleField != null) 'double-field': doubleField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $IntRouteExtension on IntRoute {
|
||||||
|
static IntRoute _fromState(GoRouterState state) => IntRoute(
|
||||||
|
requiredIntField: int.parse(state.params['requiredIntField']!),
|
||||||
|
intField: _$convertMapValue('int-field', state.queryParams, int.parse),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/int-route/${Uri.encodeComponent(requiredIntField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (intField != null) 'int-field': intField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $NumRouteExtension on NumRoute {
|
||||||
|
static NumRoute _fromState(GoRouterState state) => NumRoute(
|
||||||
|
requiredNumField: num.parse(state.params['requiredNumField']!),
|
||||||
|
numField: _$convertMapValue('num-field', state.queryParams, num.parse),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/num-route/${Uri.encodeComponent(requiredNumField.toString())}',
|
||||||
|
queryParams: {
|
||||||
|
if (numField != null) 'num-field': numField!.toString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $EnumRouteExtension on EnumRoute {
|
||||||
|
static EnumRoute _fromState(GoRouterState state) => EnumRoute(
|
||||||
|
requiredEnumField: _$PersonDetailsEnumMap
|
||||||
|
._$fromName(state.params['requiredEnumField']!),
|
||||||
enumField: _$convertMapValue(
|
enumField: _$convertMapValue(
|
||||||
'enum-field', state.queryParams, _$PersonDetailsEnumMap._$fromName),
|
'enum-field', state.queryParams, _$PersonDetailsEnumMap._$fromName),
|
||||||
intField: _$convertMapValue('int-field', state.queryParams, int.parse),
|
);
|
||||||
numField: _$convertMapValue('num-field', state.queryParams, num.parse),
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/enum-route/${Uri.encodeComponent(_$PersonDetailsEnumMap[requiredEnumField]!)}',
|
||||||
|
queryParams: {
|
||||||
|
if (enumField != null)
|
||||||
|
'enum-field': _$PersonDetailsEnumMap[enumField!]!,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $EnhancedEnumRouteExtension on EnhancedEnumRoute {
|
||||||
|
static EnhancedEnumRoute _fromState(GoRouterState state) => EnhancedEnumRoute(
|
||||||
|
requiredEnumField: _$SportDetailsEnumMap
|
||||||
|
._$fromName(state.params['requiredEnumField']!),
|
||||||
|
enumField: _$convertMapValue(
|
||||||
|
'enum-field', state.queryParams, _$SportDetailsEnumMap._$fromName),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/enhanced-enum-route/${Uri.encodeComponent(_$SportDetailsEnumMap[requiredEnumField]!)}',
|
||||||
|
queryParams: {
|
||||||
|
if (enumField != null)
|
||||||
|
'enum-field': _$SportDetailsEnumMap[enumField!]!,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $StringRouteExtension on StringRoute {
|
||||||
|
static StringRoute _fromState(GoRouterState state) => StringRoute(
|
||||||
|
requiredStringField: state.params['requiredStringField']!,
|
||||||
stringField: state.queryParams['string-field'],
|
stringField: state.queryParams['string-field'],
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/string-route/${Uri.encodeComponent(requiredStringField)}',
|
||||||
|
queryParams: {
|
||||||
|
if (stringField != null) 'string-field': stringField!,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension $UriRouteExtension on UriRoute {
|
||||||
|
static UriRoute _fromState(GoRouterState state) => UriRoute(
|
||||||
|
requiredUriField: Uri.parse(state.params['requiredUriField']!),
|
||||||
uriField: _$convertMapValue('uri-field', state.queryParams, Uri.parse),
|
uriField: _$convertMapValue('uri-field', state.queryParams, Uri.parse),
|
||||||
);
|
);
|
||||||
|
|
||||||
String get location => GoRouteData.$location(
|
String get location => GoRouteData.$location(
|
||||||
'/${Uri.encodeComponent(requiredBigIntField.toString())}/${Uri.encodeComponent(requiredBoolField.toString())}/${Uri.encodeComponent(requiredDateTimeField.toString())}/${Uri.encodeComponent(requiredDoubleField.toString())}/${Uri.encodeComponent(_$PersonDetailsEnumMap[requiredEnumField]!)}/${Uri.encodeComponent(requiredIntField.toString())}/${Uri.encodeComponent(requiredNumField.toString())}/${Uri.encodeComponent(requiredStringField)}/${Uri.encodeComponent(requiredUriField.toString())}',
|
'/uri-route/${Uri.encodeComponent(requiredUriField.toString())}',
|
||||||
queryParams: {
|
queryParams: {
|
||||||
if (bigIntField != null) 'big-int-field': bigIntField!.toString(),
|
|
||||||
if (boolField != null) 'bool-field': boolField!.toString(),
|
|
||||||
if (dateTimeField != null)
|
|
||||||
'date-time-field': dateTimeField!.toString(),
|
|
||||||
if (doubleField != null) 'double-field': doubleField!.toString(),
|
|
||||||
if (enumField != null)
|
|
||||||
'enum-field': _$PersonDetailsEnumMap[enumField!]!,
|
|
||||||
if (intField != null) 'int-field': intField!.toString(),
|
|
||||||
if (numField != null) 'num-field': numField!.toString(),
|
|
||||||
if (stringField != null) 'string-field': stringField!,
|
|
||||||
if (uriField != null) 'uri-field': uriField!.toString(),
|
if (uriField != null) 'uri-field': uriField!.toString(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -75,6 +274,13 @@ const _$PersonDetailsEnumMap = {
|
|||||||
PersonDetails.favoriteSport: 'favorite-sport',
|
PersonDetails.favoriteSport: 'favorite-sport',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _$SportDetailsEnumMap = {
|
||||||
|
SportDetails.volleyball: 'volleyball',
|
||||||
|
SportDetails.football: 'football',
|
||||||
|
SportDetails.tennis: 'tennis',
|
||||||
|
SportDetails.hockey: 'hockey',
|
||||||
|
};
|
||||||
|
|
||||||
T? _$convertMapValue<T>(
|
T? _$convertMapValue<T>(
|
||||||
String key,
|
String key,
|
||||||
Map<String, String> map,
|
Map<String, String> map,
|
||||||
|
@ -15,7 +15,7 @@ part 'main.g.dart';
|
|||||||
void main() => runApp(App());
|
void main() => runApp(App());
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
App({Key? key}) : super(key: key);
|
App({super.key});
|
||||||
|
|
||||||
final LoginInfo loginInfo = LoginInfo();
|
final LoginInfo loginInfo = LoginInfo();
|
||||||
static const String title = 'GoRouter Example: Named Routes';
|
static const String title = 'GoRouter Example: Named Routes';
|
||||||
@ -148,7 +148,7 @@ class PersonDetailsRoute extends GoRouteData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
const HomeScreen({Key? key}) : super(key: key);
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -184,7 +184,7 @@ class HomeScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FamilyScreen extends StatelessWidget {
|
class FamilyScreen extends StatelessWidget {
|
||||||
const FamilyScreen({required this.family, Key? key}) : super(key: key);
|
const FamilyScreen({required this.family, super.key});
|
||||||
final Family family;
|
final Family family;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -203,8 +203,7 @@ class FamilyScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PersonScreen extends StatelessWidget {
|
class PersonScreen extends StatelessWidget {
|
||||||
const PersonScreen({required this.family, required this.person, Key? key})
|
const PersonScreen({required this.family, required this.person, super.key});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final Family family;
|
final Family family;
|
||||||
final Person person;
|
final Person person;
|
||||||
@ -250,8 +249,8 @@ class PersonDetailsPage extends StatelessWidget {
|
|||||||
required this.person,
|
required this.person,
|
||||||
required this.detailsKey,
|
required this.detailsKey,
|
||||||
this.extra,
|
this.extra,
|
||||||
Key? key,
|
super.key,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final Family family;
|
final Family family;
|
||||||
final Person person;
|
final Person person;
|
||||||
@ -278,7 +277,7 @@ class PersonDetailsPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LoginScreen extends StatelessWidget {
|
class LoginScreen extends StatelessWidget {
|
||||||
const LoginScreen({this.from, Key? key}) : super(key: key);
|
const LoginScreen({this.from, super.key});
|
||||||
final String? from;
|
final String? from;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -14,6 +14,46 @@ enum PersonDetails {
|
|||||||
favoriteSport,
|
favoriteSport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SportDetails {
|
||||||
|
volleyball(
|
||||||
|
imageUrl: '/sportdetails/url/volleyball.jpg',
|
||||||
|
playerPerTeam: 6,
|
||||||
|
accessory: null,
|
||||||
|
hasNet: true,
|
||||||
|
),
|
||||||
|
football(
|
||||||
|
imageUrl: '/sportdetails/url/Football.jpg',
|
||||||
|
playerPerTeam: 11,
|
||||||
|
accessory: null,
|
||||||
|
hasNet: true,
|
||||||
|
),
|
||||||
|
tennis(
|
||||||
|
imageUrl: '/sportdetails/url/tennis.jpg',
|
||||||
|
playerPerTeam: 2,
|
||||||
|
accessory: 'Rackets',
|
||||||
|
hasNet: true,
|
||||||
|
),
|
||||||
|
hockey(
|
||||||
|
imageUrl: '/sportdetails/url/hockey.jpg',
|
||||||
|
playerPerTeam: 6,
|
||||||
|
accessory: 'Hockey sticks',
|
||||||
|
hasNet: true,
|
||||||
|
),
|
||||||
|
;
|
||||||
|
|
||||||
|
const SportDetails({
|
||||||
|
required this.accessory,
|
||||||
|
required this.hasNet,
|
||||||
|
required this.imageUrl,
|
||||||
|
required this.playerPerTeam,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String imageUrl;
|
||||||
|
final int playerPerTeam;
|
||||||
|
final String? accessory;
|
||||||
|
final bool hasNet;
|
||||||
|
}
|
||||||
|
|
||||||
/// sample Person class
|
/// sample Person class
|
||||||
class Person {
|
class Person {
|
||||||
Person({
|
Person({
|
||||||
|
@ -14,7 +14,7 @@ part 'simple_example.g.dart';
|
|||||||
void main() => runApp(App());
|
void main() => runApp(App());
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
App({Key? key}) : super(key: key);
|
App({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => MaterialApp.router(
|
Widget build(BuildContext context) => MaterialApp.router(
|
||||||
@ -50,7 +50,7 @@ class FamilyRoute extends GoRouteData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
const HomeScreen({Key? key}) : super(key: key);
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Scaffold(
|
Widget build(BuildContext context) => Scaffold(
|
||||||
@ -68,7 +68,7 @@ class HomeScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FamilyScreen extends StatelessWidget {
|
class FamilyScreen extends StatelessWidget {
|
||||||
const FamilyScreen({required this.family, Key? key}) : super(key: key);
|
const FamilyScreen({required this.family, super.key});
|
||||||
final Family family;
|
final Family family;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -3,7 +3,7 @@ description: go_router_builder examples
|
|||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.14.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
114
packages/go_router_builder/example/test/all_types_test.dart
Normal file
114
packages/go_router_builder/example/test/all_types_test.dart
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:go_router_builder_example/all_types.dart';
|
||||||
|
import 'package:go_router_builder_example/shared/data.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('Test typed route navigation', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(AllTypesApp());
|
||||||
|
|
||||||
|
final ScaffoldState scaffoldState =
|
||||||
|
tester.firstState(find.byType(Scaffold));
|
||||||
|
|
||||||
|
BigIntRoute(
|
||||||
|
requiredBigIntField: BigInt.from(4),
|
||||||
|
bigIntField: BigInt.from(8),
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BigIntRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: 4'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: 8'), findsOneWidget);
|
||||||
|
|
||||||
|
BoolRoute(
|
||||||
|
requiredBoolField: false,
|
||||||
|
boolField: true,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('BoolRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: false'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: true'), findsOneWidget);
|
||||||
|
|
||||||
|
final DateTime param = DateTime.now();
|
||||||
|
final DateTime query = DateTime(2017, 9, 7, 17, 30);
|
||||||
|
DateTimeRoute(
|
||||||
|
requiredDateTimeField: param,
|
||||||
|
dateTimeField: query,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('DateTimeRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: $param'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: $query'), findsOneWidget);
|
||||||
|
|
||||||
|
DoubleRoute(
|
||||||
|
requiredDoubleField: 3.14,
|
||||||
|
doubleField: -3.14,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('DoubleRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: 3.14'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: -3.14'), findsOneWidget);
|
||||||
|
|
||||||
|
IntRoute(
|
||||||
|
requiredIntField: 65,
|
||||||
|
intField: -65,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('IntRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: 65'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: -65'), findsOneWidget);
|
||||||
|
|
||||||
|
NumRoute(
|
||||||
|
requiredNumField: 987.32,
|
||||||
|
numField: -987.32,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('NumRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: 987.32'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: -987.32'), findsOneWidget);
|
||||||
|
|
||||||
|
StringRoute(
|
||||||
|
requiredStringField: r'Tytire tu patulae recubans sub tegmine fagi.',
|
||||||
|
stringField: r'Tytire tu patulae recubans sub tegmine fagi.',
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('StringRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: Tytire tu patulae recubans sub tegmine fagi.'),
|
||||||
|
findsOneWidget);
|
||||||
|
expect(
|
||||||
|
find.text('Query param: Tytire tu patulae recubans sub tegmine fagi.'),
|
||||||
|
findsOneWidget);
|
||||||
|
|
||||||
|
EnumRoute(
|
||||||
|
requiredEnumField: PersonDetails.favoriteFood,
|
||||||
|
enumField: PersonDetails.favoriteSport,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('EnumRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: PersonDetails.favoriteFood'), findsOneWidget);
|
||||||
|
expect(
|
||||||
|
find.text('Query param: PersonDetails.favoriteSport'), findsOneWidget);
|
||||||
|
|
||||||
|
EnhancedEnumRoute(
|
||||||
|
requiredEnumField: SportDetails.football,
|
||||||
|
enumField: SportDetails.hockey,
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('EnhancedEnumRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: SportDetails.football'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: SportDetails.hockey'), findsOneWidget);
|
||||||
|
|
||||||
|
UriRoute(
|
||||||
|
requiredUriField: Uri.parse('https://dart.dev'),
|
||||||
|
uriField: Uri.parse('https://dart.dev'),
|
||||||
|
).go(scaffoldState.context);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('UriRoute'), findsOneWidget);
|
||||||
|
expect(find.text('Param: https://dart.dev'), findsOneWidget);
|
||||||
|
expect(find.text('Query param: https://dart.dev'), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
@ -368,7 +368,7 @@ String _enumMapConst(InterfaceType type) {
|
|||||||
final StringBuffer buffer = StringBuffer('const ${enumMapName(type)} = {');
|
final StringBuffer buffer = StringBuffer('const ${enumMapName(type)} = {');
|
||||||
|
|
||||||
for (final FieldElement enumField in type.element2.fields
|
for (final FieldElement enumField in type.element2.fields
|
||||||
.where((FieldElement element) => !element.isSynthetic)) {
|
.where((FieldElement element) => element.isEnumConstant)) {
|
||||||
buffer.writeln(
|
buffer.writeln(
|
||||||
'$enumName.${enumField.name}: ${escapeDartString(enumField.name.kebab)},',
|
'$enumName.${enumField.name}: ${escapeDartString(enumField.name.kebab)},',
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ name: go_router_builder
|
|||||||
description: >-
|
description: >-
|
||||||
A builder that supports generated strongly-typed route helpers for
|
A builder that supports generated strongly-typed route helpers for
|
||||||
package:go_router
|
package:go_router
|
||||||
version: 1.0.11
|
version: 1.0.12
|
||||||
repository: https://github.com/flutter/packages/tree/main/packages/go_router_builder
|
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
|
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22
|
||||||
|
|
||||||
|
@ -31,4 +31,5 @@ const Set<String> _expectedAnnotatedTests = <String>{
|
|||||||
'NullableRequiredParam',
|
'NullableRequiredParam',
|
||||||
'UnsupportedType',
|
'UnsupportedType',
|
||||||
'theAnswer',
|
'theAnswer',
|
||||||
|
'EnumParam',
|
||||||
};
|
};
|
||||||
|
@ -70,3 +70,49 @@ class MissingPathParam extends GoRouteData {
|
|||||||
MissingPathParam({required this.id});
|
MissingPathParam({required this.id});
|
||||||
final String id;
|
final String id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ShouldGenerate(r'''
|
||||||
|
GoRoute get $enumParam => GoRouteData.$route(
|
||||||
|
path: '/:y',
|
||||||
|
factory: $EnumParamExtension._fromState,
|
||||||
|
);
|
||||||
|
|
||||||
|
extension $EnumParamExtension on EnumParam {
|
||||||
|
static EnumParam _fromState(GoRouterState state) => EnumParam(
|
||||||
|
y: _$EnumTestEnumMap._$fromName(state.params['y']!),
|
||||||
|
);
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/${Uri.encodeComponent(_$EnumTestEnumMap[y]!)}',
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location, extra: this);
|
||||||
|
|
||||||
|
void push(BuildContext context) => context.push(location, extra: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _$EnumTestEnumMap = {
|
||||||
|
EnumTest.a: 'a',
|
||||||
|
EnumTest.b: 'b',
|
||||||
|
EnumTest.c: 'c',
|
||||||
|
};
|
||||||
|
|
||||||
|
extension<T extends Enum> on Map<T, String> {
|
||||||
|
T _$fromName(String value) =>
|
||||||
|
entries.singleWhere((element) => element.value == value).key;
|
||||||
|
}
|
||||||
|
''')
|
||||||
|
@TypedGoRoute<EnumParam>(path: '/:y')
|
||||||
|
class EnumParam extends GoRouteData {
|
||||||
|
EnumParam({required this.y});
|
||||||
|
final EnumTest y;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EnumTest {
|
||||||
|
a(1),
|
||||||
|
b(3),
|
||||||
|
c(5);
|
||||||
|
|
||||||
|
const EnumTest(this.x);
|
||||||
|
final int x;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user