diff --git a/CHANGELOG.md b/CHANGELOG.md index d565ad0..85b98f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.2 + +* **Feat (Platform Adaptive Transitions)**: + * Preserved explicit non-default route transitions (e.g., `fade`, `scale`, `none`) in `Browser.defaultAdaptiveTransition`, ensuring custom route transitions are honored without needing custom adaptive callbacks. + * Optimized default adaptive transition for Web and Desktop (Windows, Linux) to use `RouteTransition.only_hero`, preventing lateral slide transitions on wide viewport displays while preserving Hero animations. +* **Test**: Added unit and integration tests verifying platform-specific default adaptive transition behavior and custom route transition preservation across all platforms. + ## 0.3.1 * **Fix (Transitions & Pop Visibility)**: Prevented underlying screen from disappearing or flashing black during push and pop route transitions by eliminating destructive secondary opacity fading in `Scale`, `FadeScale`, and `SharedAxis` widgets. diff --git a/README.md b/README.md index c49b596..33dee4c 100644 --- a/README.md +++ b/README.md @@ -387,7 +387,7 @@ Configure global platform-adaptive transition rules using built-in `Browser.defa Browser( routes: routes, defaultRoute: routes.first, - adaptiveTransition: Browser.defaultAdaptiveTransition, // iOS: slide_cupertino, Android: shared_axis_x, Web/Desktop: fade_scale + adaptiveTransition: Browser.defaultAdaptiveTransition, // iOS/macOS: slide_cupertino, Android/Fuchsia: shared_axis_x, Web/Desktop: only_hero adaptiveTrace: (name) { // All routes under /modal/ open as popups automatically if (name?.startsWith('/modal/') ?? false) { diff --git a/lib/browser.dart b/lib/browser.dart index bc55e90..5bb89e2 100644 --- a/lib/browser.dart +++ b/lib/browser.dart @@ -134,12 +134,16 @@ class Browser extends StatelessWidget { RouteObserver>(); /// Default platform-adaptive route transition strategy: - /// - Web / Desktop (Windows, Linux): `RouteTransition.fade_scale` for a snappy SPA feel. + /// - If the route specifies a non-default transition (e.g., `fade`, `scale`, `none`), it is preserved. + /// - Web / Desktop (Windows, Linux): `RouteTransition.only_hero` to avoid jarring side-slides. /// - iOS / macOS: `RouteTransition.slide_cupertino` for native parallax slide and edge shadow. /// - Android / Fuchsia: `RouteTransition.shared_axis_x` for Material 3 directional motion. static RouteTransition defaultAdaptiveTransition(BrowserRoute route) { + if (route.routeTransition != RouteTransition.slide_right) { + return route.routeTransition; + } if (kIsWeb) { - return RouteTransition.fade_scale; + return RouteTransition.only_hero; } return switch (defaultTargetPlatform) { TargetPlatform.iOS || @@ -147,7 +151,7 @@ class Browser extends StatelessWidget { TargetPlatform.android || TargetPlatform.fuchsia => RouteTransition.shared_axis_x, TargetPlatform.windows || - TargetPlatform.linux => RouteTransition.fade_scale, + TargetPlatform.linux => RouteTransition.only_hero, }; } diff --git a/pubspec.yaml b/pubspec.yaml index 4a23bb4..3be405d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: browser_router description: An advanced navigation system for Flutter that enables typed routes, custom transitions, and robust overlay management. -version: 0.3.1 +version: 0.3.2 repository: https://github.com/coolosos/browser_router homepage: https://github.com/coolosos/browser_router issue_tracker: https://github.com/coolosos/browser_router/issues diff --git a/test/modern_route_transitions_integration_test.dart b/test/modern_route_transitions_integration_test.dart index 040c49c..aa7ec3f 100644 --- a/test/modern_route_transitions_integration_test.dart +++ b/test/modern_route_transitions_integration_test.dart @@ -7,47 +7,89 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('Browser.defaultAdaptiveTransition Tests', () { - test('returns platform-appropriate transitions', () { - const sampleRoute = BrowserRoute(path: '/test', page: SizedBox()); + test( + 'returns platform-appropriate transitions for default slide_right route', + () { + const sampleRoute = BrowserRoute(path: '/test', page: SizedBox()); + + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.slide_cupertino), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.iOS; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.slide_cupertino), - ); + debugDefaultTargetPlatformOverride = TargetPlatform.macOS; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.slide_cupertino), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.macOS; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.slide_cupertino), - ); + debugDefaultTargetPlatformOverride = TargetPlatform.android; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.shared_axis_x), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.android; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.shared_axis_x), - ); + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.shared_axis_x), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.shared_axis_x), - ); + debugDefaultTargetPlatformOverride = TargetPlatform.windows; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.only_hero), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.windows; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.fade_scale), - ); + debugDefaultTargetPlatformOverride = TargetPlatform.linux; + expect( + Browser.defaultAdaptiveTransition(sampleRoute), + equals(RouteTransition.only_hero), + ); - debugDefaultTargetPlatformOverride = TargetPlatform.linux; - expect( - Browser.defaultAdaptiveTransition(sampleRoute), - equals(RouteTransition.fade_scale), - ); + debugDefaultTargetPlatformOverride = null; + }, + ); - debugDefaultTargetPlatformOverride = null; - }); + test( + 'preserves explicit non-default route transitions across all platforms', + () { + const explicitFadeRoute = BrowserRoute( + path: '/fade', + page: SizedBox(), + routeTransition: RouteTransition.fade, + ); + const explicitScaleRoute = BrowserRoute( + path: '/scale', + page: SizedBox(), + routeTransition: RouteTransition.scale, + ); + const explicitNoneRoute = BrowserRoute( + path: '/none', + page: SizedBox(), + routeTransition: RouteTransition.none, + ); + + for (final platform in TargetPlatform.values) { + debugDefaultTargetPlatformOverride = platform; + expect( + Browser.defaultAdaptiveTransition(explicitFadeRoute), + equals(RouteTransition.fade), + ); + expect( + Browser.defaultAdaptiveTransition(explicitScaleRoute), + equals(RouteTransition.scale), + ); + expect( + Browser.defaultAdaptiveTransition(explicitNoneRoute), + equals(RouteTransition.none), + ); + } + + debugDefaultTargetPlatformOverride = null; + }, + ); }); group('Modern Transitions Integration in BrowserPageRoute', () {