[go_router] CustomTransitionPage: Make barrierDismissible work (#3026)
* make barrierDismissible work
* add example
* update version
* Update packages/go_router/CHANGELOG.md
Co-authored-by: chunhtai <47866232+chunhtai@users.noreply.github.com>
* pass state.pageKey to Page.key
* update version to 6.0.3
---------
Co-authored-by: chunhtai <47866232+chunhtai@users.noreply.github.com>
diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md
index 2371421..fc741b3 100644
--- a/packages/go_router/CHANGELOG.md
+++ b/packages/go_router/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 6.0.3
+
+- Makes `CustomTransitionPage.barrierDismissible` work
+
## 6.0.2
- Fixes missing result on pop in go_router extension.
diff --git a/packages/go_router/example/lib/transition_animations.dart b/packages/go_router/example/lib/transition_animations.dart
index 74dc79e..0082cb5 100644
--- a/packages/go_router/example/lib/transition_animations.dart
+++ b/packages/go_router/example/lib/transition_animations.dart
@@ -44,6 +44,20 @@
);
},
),
+ GoRoute(
+ path: 'dismissible-details',
+ pageBuilder: (BuildContext context, GoRouterState state) {
+ return CustomTransitionPage<void>(
+ key: state.pageKey,
+ child: const DismissibleDetails(),
+ barrierDismissible: true,
+ barrierColor: Colors.black38,
+ opaque: false,
+ transitionDuration: Duration.zero,
+ transitionsBuilder: (_, __, ___, Widget child) => child,
+ );
+ },
+ ),
],
),
],
@@ -79,6 +93,11 @@
onPressed: () => context.go('/details'),
child: const Text('Go to the Details screen'),
),
+ const SizedBox(height: 48),
+ ElevatedButton(
+ onPressed: () => context.go('/dismissible-details'),
+ child: const Text('Go to the Dismissible Details screen'),
+ ),
],
),
),
@@ -109,3 +128,17 @@
);
}
}
+
+/// The dismissible details screen
+class DismissibleDetails extends StatelessWidget {
+ /// Constructs a [DismissibleDetails]
+ const DismissibleDetails({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return const Padding(
+ padding: EdgeInsets.all(48),
+ child: ColoredBox(color: Colors.red),
+ );
+ }
+}
diff --git a/packages/go_router/lib/src/pages/custom_transition_page.dart b/packages/go_router/lib/src/pages/custom_transition_page.dart
index 431df30..38bde2c 100644
--- a/packages/go_router/lib/src/pages/custom_transition_page.dart
+++ b/packages/go_router/lib/src/pages/custom_transition_page.dart
@@ -107,6 +107,9 @@
CustomTransitionPage<T> get _page => settings as CustomTransitionPage<T>;
@override
+ bool get barrierDismissible => _page.barrierDismissible;
+
+ @override
Color? get barrierColor => _page.barrierColor;
@override
diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml
index ade738b..e29a5f0 100644
--- a/packages/go_router/pubspec.yaml
+++ b/packages/go_router/pubspec.yaml
@@ -1,7 +1,7 @@
name: go_router
description: A declarative router for Flutter based on Navigation 2 supporting
deep linking, data-driven routes and more
-version: 6.0.2
+version: 6.0.3
repository: https://github.com/flutter/packages/tree/main/packages/go_router
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22
diff --git a/packages/go_router/test/custom_transition_page_test.dart b/packages/go_router/test/custom_transition_page_test.dart
index 50fe625..b93fd21 100644
--- a/packages/go_router/test/custom_transition_page_test.dart
+++ b/packages/go_router/test/custom_transition_page_test.dart
@@ -84,6 +84,39 @@
homeScreenPositionInTheMiddleOfRemoval,
);
});
+
+ testWidgets('Dismiss a screen by tapping a modal barrier',
+ (WidgetTester tester) async {
+ const ValueKey<String> homeKey = ValueKey<String>('home');
+ const ValueKey<String> dismissibleModalKey =
+ ValueKey<String>('dismissibleModal');
+
+ final GoRouter router = GoRouter(
+ routes: <GoRoute>[
+ GoRoute(
+ path: '/',
+ builder: (_, __) => const HomeScreen(key: homeKey),
+ ),
+ GoRoute(
+ path: '/dismissible-modal',
+ pageBuilder: (_, GoRouterState state) => CustomTransitionPage<void>(
+ key: state.pageKey,
+ barrierDismissible: true,
+ transitionsBuilder: (_, __, ___, Widget child) => child,
+ child: const DismissibleModal(key: dismissibleModalKey),
+ ),
+ ),
+ ],
+ );
+ await tester.pumpWidget(MaterialApp.router(routerConfig: router));
+ expect(find.byKey(homeKey), findsOneWidget);
+ router.push('/dismissible-modal');
+ await tester.pumpAndSettle();
+ expect(find.byKey(dismissibleModalKey), findsOneWidget);
+ await tester.tapAt(const Offset(50, 50));
+ await tester.pumpAndSettle();
+ expect(find.byKey(homeKey), findsOneWidget);
+ });
}
class HomeScreen extends StatelessWidget {
@@ -111,3 +144,16 @@
);
}
}
+
+class DismissibleModal extends StatelessWidget {
+ const DismissibleModal({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const SizedBox(
+ width: 200,
+ height: 200,
+ child: Center(child: Text('Dismissible Modal')),
+ );
+ }
+}