From 985038504348c246fa1dd51561cefeb48116e00f Mon Sep 17 00:00:00 2001 From: Daichi Fujita <68946713+fujidaiti@users.noreply.github.com> Date: Sat, 28 Sep 2024 00:17:07 +0900 Subject: [PATCH 1/5] Bump to v0.10.0 (#254) --- CHANGELOG.md | 11 +++++++++++ pubspec.yaml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e4d495..ac8587d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.10.0 Sep 28, 2024 + +**This version contains breaking changes. +** See the [migration guide](https://github.com/fujidaiti/smooth_sheets/blob/main/migrations/migration-guide-0.10.x.md) for more details. + +- Fix: Touch is ignored issue not fixed for top edge (#212) +- Fix: Closing keyboard slows down snapping animation (#193) +- Fix: Dynamically changing sheet height doesn't respect snapping constraints (#226) +- Fix: Snapping effect doesn't work when closing keyboard on non-fullscreen sheet (#192) +- Fix: Unwanted bouncing when opening or closing the on-screen keyboard on ScrollableSheet (#245) + ## 0.9.4 Aug 31, 2024 - Add `SwipeDismissSensitivity`, a way to customize sensitivity of swipe-to-dismiss action on modal sheet (#222) diff --git a/pubspec.yaml b/pubspec.yaml index 8a5454d..08c9c7e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: smooth_sheets description: Sheet widgets with smooth motion and great flexibility. Also supports nested navigation in both imperative and declarative ways. -version: 0.9.4 +version: 0.10.0 repository: https://github.com/fujidaiti/smooth_sheets screenshots: - description: Practical examples of smooth_sheets. From e654e4868d86d538efaf466b030624145e51a585 Mon Sep 17 00:00:00 2001 From: Daichi Fujita <68946713+fujidaiti@users.noreply.github.com> Date: Sat, 28 Sep 2024 00:55:03 +0900 Subject: [PATCH 2/5] Fix documentation (#255) --- CHANGELOG.md | 3 +- README.md | 247 +++++++++++++++------------------------------------ 2 files changed, 71 insertions(+), 179 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac8587d..7c9358d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,7 @@ ## 0.10.0 Sep 28, 2024 -**This version contains breaking changes. -** See the [migration guide](https://github.com/fujidaiti/smooth_sheets/blob/main/migrations/migration-guide-0.10.x.md) for more details. +**This version contains breaking changes.** See the [migration guide](https://github.com/fujidaiti/smooth_sheets/blob/main/migrations/migration-guide-0.10.x.md) for more details. - Fix: Touch is ignored issue not fixed for top edge (#212) - Fix: Closing keyboard slows down snapping animation (#193) diff --git a/README.md b/README.md index 2176703..4fffd1f 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,16 @@ **smooth_sheets** offers modal and persistent sheet widgets for Flutter apps. The key features are: - **Smooth motion**: The sheets respond to user interaction with smooth, graceful motion. -- **Highly flexible**: Not restricted to a specific design. Both modal and persistent styles are - supp/orted, as well as scrollable and non-scrollable widgets. -- **Supports nested navigation**: A sheet is able to have multiple pages and to navigate between the - pages with motion animation for transitions. -- **Works with imperative & declarative Navigator API**: No special navigation mechanism is - required. The traditional ways such as `Navigator.push` is supported and it works with Navigator - 2.0 packages like go_route as well. +- **Highly flexible**: Not restricted to a specific design. Both modal and persistent styles are supported, as well as scrollable and non-scrollable widgets. +- **Supports nested navigation**: A sheet is able to have multiple pages and to navigate between the pages with motion animation for transitions. +- **Works with imperative & declarative Navigator API**: No special navigation mechanism is required. The traditional ways such as `Navigator.push` is supported and it works with Navigator 2.0 packages like go_route as well. - **iOS flavor**: The modal sheets in the style of iOS 15 are supported.
## For developers using Flutter 3.24+ -If your project uses Flutter 3.24.0 or later, we recommend using the pre-release versions -named `1.0.0-f324.x.x.x`. While you can still use the non-pre-release versions (e.g., `0.9.4`) with -Flutter 3.24+, you may encounter issues related to the `PopScope` widget due to a breaking change in -Flutter 3.24. There are no functional or API differences between the pre-release and non-pre-release -versions, except that the pre-release versions require Flutter 3.24.0 or later. +If your project uses Flutter 3.24.0 or later, we recommend using the pre-release versions named `1.0.0-f324.x.x.x`. While you can still use the non-pre-release versions (e.g., `0.9.4`) with Flutter 3.24+, you may encounter issues related to the `PopScope` widget due to a breaking change in Flutter 3.24. There are no functional or API differences between the pre-release and non-pre-release versions, except that the pre-release versions require Flutter 3.24.0 or later. ```yaml dependencies: @@ -35,31 +27,19 @@ dependencies:
Background -This package previously used the `Route.onPopInvoked` method to invoke `PopScope.onPopInvoked` -callbacks when users performed a swipe-to-dismiss gesture. However, these methods were deprecated in -Flutter 3.24.0 as part of -a [breaking change](https://docs.flutter.dev/release/breaking-changes/popscope-with-result) related -to the `PopScope` widget. The problem is that `ModalRoute.onPopInvoked`, which was an override -of `Route.onPopInvoked` and where `PopScope.onPopInvoked` callbacks were actually invoked, was -removed. As a result, the `PopScope.onPopInvoked` callback is no longer invoked in Flutter 3.24+. -These changes led to issues such as [#233](https://github.com/fujidaiti/smooth_sheets/issues/233). - -The only possible solution was to replace `Route.onPopInvoked` with `Route.onPopInvokedWithResult`, -which was introduced in Flutter 3.24.0. However, migrating to the new API would require increasing -the lower bound of the SDK constraint to 3.24.0. For those using an SDK version lower than 3.24, -this change would be a significant breaking change. Ultimately, we decided to publish different -versions for different SDK constraints to maintain backward compatibility. +This package previously used the `Route.onPopInvoked` method to invoke `PopScope.onPopInvoked` callbacks when users performed a swipe-to-dismiss gesture. However, these methods were deprecated in Flutter 3.24.0 as part of a [breaking change](https://docs.flutter.dev/release/breaking-changes/popscope-with-result) related to the `PopScope` widget. The problem is that `ModalRoute.onPopInvoked`, which was an override of `Route.onPopInvoked` and where `PopScope.onPopInvoked` callbacks were actually invoked, was removed. As a result, the `PopScope.onPopInvoked` callback is no longer invoked in Flutter 3.24+. These changes led to issues such as [#233](https://github.com/fujidaiti/smooth_sheets/issues/233). + +The only possible solution was to replace `Route.onPopInvoked` with `Route.onPopInvokedWithResult`, which was introduced in Flutter 3.24.0. However, migrating to the new API would require increasing the lower bound of the SDK constraint to 3.24.0. For those using an SDK version lower than 3.24, this change would be a significant breaking change. Ultimately, we decided to publish different versions for different SDK constraints to maintain backward compatibility.

## Migration guide -- [0.8.x to 0.9.x](https://github.com/fujidaiti/smooth_sheets/blob/main/docs/migration-guide-0.9.x.md) - 🆕 -- [0.7.x to 0.8.x](https://github.com/fujidaiti/smooth_sheets/blob/main/docs/migration-guide-0.8.x.md) +- [0.9.x to 0.10.x](https://github.com/fujidaiti/smooth_sheets/blob/main/migrations/migration-guide-0.10.x.md) 🆕 +- [0.8.x to 0.9.x](https://github.com/fujidaiti/smooth_sheets/blob/main/migrations/migration-guide-0.9.x.md) -See [here](https://github.com/fujidaiti/smooth_sheets/blob/main/docs/) for older versions. +See [here](https://github.com/fujidaiti/smooth_sheets/tree/main/migrations) for older versions.
@@ -131,11 +111,7 @@ See [here](https://github.com/fujidaiti/smooth_sheets/blob/main/docs/) for older ## Why use this? -There are few packages on pub.dev that supports nested navigation with motion animation for page -transitions. One of the great choices for this usecase -is [wolt_modal_sheet](https://github.com/woltapp/wolt_modal_sheet), which this package is inspired -by. Although smooth_sheet has similar features with wolt_modal_sheet, it does not intended to be a -replacement of that package. Here is some differences between those 2 packages: +There are few packages on pub.dev that supports nested navigation with motion animation for page transitions. One of the great choices for this usecase is [wolt_modal_sheet](https://github.com/woltapp/wolt_modal_sheet), which this package is inspired by. Although smooth_sheet has similar features with wolt_modal_sheet, it does not intended to be a replacement of that package. Here is some differences between those 2 packages: | | wolt_modal_sheet | smooth_sheets | |:----------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------:| @@ -151,27 +127,21 @@ replacement of that package. Here is some differences between those 2 packages: Several resources are available for learning the functionalities of this package. -- Tutorials: - See [example/lib/tutorial/](https://github.com/fujidaiti/smooth_sheets/tree/main/example/lib/tutorial) - to learn the basic usage of the core components. -- Showcases: More practical examples are available - in [example/lib/showcase/](https://github.com/fujidaiti/smooth_sheets/tree/main/example/lib/showcase). +- Tutorials: See [example/lib/tutorial/](https://github.com/fujidaiti/smooth_sheets/tree/main/example/lib/tutorial) to learn the basic usage of the core components. +- Showcases: More practical examples are available in [example/lib/showcase/](https://github.com/fujidaiti/smooth_sheets/tree/main/example/lib/showcase). - Documentation: WORK IN PROGRESS! Please see the source code for a while.
## Ingredients -This section provides descriptions for each core component and links to related resources for -further learning. +This section provides descriptions for each core component and links to related resources for further learning.
### SheetAnchor -SheetAnchor represents the visible height of the sheet. It is used in a variety of situations, for -example, to specify how much area of a sheet is initially visible at first build, or to limit the -range of sheet dragging. +SheetAnchor represents the visible height of the sheet. It is used in a variety of situations, for example, to specify how much area of a sheet is initially visible at first build, or to limit the range of sheet dragging.
@@ -182,15 +152,11 @@ range of sheet dragging. -A sheet that can be dragged. The height will be equal to the content. The behavior of the sheet when -over-dragged or under-dragged is determined by [SheetPhysics](#sheetphysics). Note that this widget -does not work with scrollable widgets. Instead, use [ScrollableSheet](#scrollablesheet) for this -usecase. +A sheet that can be dragged. The height will be equal to the content. The behavior of the sheet when over-dragged or under-dragged is determined by [SheetPhysics](#sheetphysics). Note that this widget does not work with scrollable widgets. Instead, use [ScrollableSheet](#scrollablesheet) for this usecase. See also: -- [draggable_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/draggable_sheet.dart) - for basic usage. +- [draggable_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/draggable_sheet.dart) for basic usage.
@@ -201,14 +167,11 @@ See also: -A sheet that is similar to [DraggableSheet](#draggablesheet), but specifically designed to be -integrated with scrollable widgets. It will begin to be dragged when the content is over-scrolled or -under-scrolled. +A sheet that is similar to [DraggableSheet](#draggablesheet), but specifically designed to be integrated with scrollable widgets. It will begin to be dragged when the content is over-scrolled or under-scrolled. See also: -- [scrollable_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/scrollable_sheet.dart) - for basic usage. +- [scrollable_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/scrollable_sheet.dart) for basic usage.
@@ -219,17 +182,12 @@ See also: -A sheet that is able to have multiple pages and performs graceful motion animation when page -transitions. It supports both of imperative Navigator API such as `Navigator.push`, and declarative -API (Navigator 2.0). +A sheet that is able to have multiple pages and performs graceful motion animation when page transitions. It supports both of imperative Navigator API such as `Navigator.push`, and declarative API (Navigator 2.0). See also: -- [declarative_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/declarative_navigation_sheet.dart), - tutorial of integration with Navigator 2.0 using [go_router](https://pub.dev/packages/go_router) - package. -- [imperative_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/imperative_navigation_sheet.dart), - a tutorial of integration with imperative Navigator API. +- [declarative_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/declarative_navigation_sheet.dart), tutorial of integration with Navigator 2.0 using [go_router](https://pub.dev/packages/go_router) package. +- [imperative_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/imperative_navigation_sheet.dart), a tutorial of integration with imperative Navigator API.
@@ -239,37 +197,22 @@ See also: - - - -A sheet can be displayed as a modal sheet using ModalSheetRoute for imperative navigation, or -ModalSheetPage for declarative navigation. To enable the *swipe-to-dismiss* action, which allows the -user to dismiss the sheet by a swiping-down gesture, set `swipeDismissible` to true. +A sheet can be displayed as a modal sheet using ModalSheetRoute for imperative navigation, or ModalSheetPage for declarative navigation. To enable the *swipe-to-dismiss* action, which allows the user to dismiss the sheet by a swiping-down gesture, set `swipeDismissible` to true.
-Furthermore, [the modal sheets in the style of iOS 15](https://medium.com/surf-dev/bottomsheet-in-ios-15-uisheetpresentationcontroller-and-its-capabilities-5e913661c9f) -are also supported. For imperative navigation, use CupertinoModalSheetRoute, and for declarative -navigation, use CupertinoModalSheetPage, respectively. +Furthermore, [the modal sheets in the style of iOS 15](https://medium.com/surf-dev/bottomsheet-in-ios-15-uisheetpresentationcontroller-and-its-capabilities-5e913661c9f) are also supported. For imperative navigation, use CupertinoModalSheetRoute, and for declarative navigation, use CupertinoModalSheetPage, respectively. See also: -- [SwipeDismissSensitivity](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SwipeDismissSensitivity-class.html), - which can be used to tweak the sensitivity of the swipe-to-dismiss action. -- [declarative_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/declarative_modal_sheet.dart), - a tutorial of integration with declarative navigation - using [go_router](https://pub.dev/packages/go_router) package. -- [imperative_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/imperative_modal_sheet.dart), - a tutorial of integration with imperative Navigator API. -- [cupertino_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/cupertino_modal_sheet.dart), - a tutorial of iOS style modal sheets. -- [ios_style_declarative_modal_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/ios_style_declarative_modal_navigation_sheet.dart), - an example of iOS-style modal NavigationSheet with go_router. -- [showcase/todo_list](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/showcase/todo_list), - which uses SheetDismissible to show a confirmation dialog when the user tries to discard the todo - editing sheet without saving the content. +- [SwipeDismissSensitivity](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SwipeDismissSensitivity-class.html), which can be used to tweak the sensitivity of the swipe-to-dismiss action. +- [declarative_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/declarative_modal_sheet.dart), a tutorial of integration with declarative navigation using [go_router](https://pub.dev/packages/go_router) package. +- [imperative_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/imperative_modal_sheet.dart), a tutorial of integration with imperative Navigator API. +- [cupertino_modal_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/cupertino_modal_sheet.dart), a tutorial of iOS style modal sheets. +- [ios_style_declarative_modal_navigation_sheet.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/ios_style_declarative_modal_navigation_sheet.dart), an example of iOS-style modal NavigationSheet with go_router. +- [showcase/todo_list](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/showcase/todo_list), which uses SheetDismissible to show a confirmation dialog when the user tries to discard the todo editing sheet without saving the content.
@@ -280,26 +223,18 @@ See also: -A physics determines how the sheet will behave when over-dragged or under-dragged, or when the user -stops dragging. There are 3 predefined physics: +A physics determines how the sheet will behave when over-dragged or under-dragged, or when the user stops dragging. There are 3 predefined physics: - ClampingSheetPhysics: Prevents the sheet from reaching beyond the content bounds. -- BouncingSheetPhysics: Allows the sheet to go beyond the content bounds, but then bounce the sheet - back to the edge of those bounds. - Use [BouncingBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/BouncingBehavior-class.html) - and its subclasses to tweak the bouncing behavior. -- SnappingSheetPhysics: Automatically snaps the sheet to a certain extent when the user stops - dragging. +- BouncingSheetPhysics: Allows the sheet to go beyond the content bounds, but then bounce the sheet back to the edge of those bounds. Use [BouncingBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/BouncingBehavior-class.html) and its subclasses to tweak the bouncing behavior. +- SnappingSheetPhysics: Automatically snaps the sheet to a certain extent when the user stops dragging. -These physics can be combined to create more complex behavior (e.g. bouncing behavior + snapping -behavior). +These physics can be combined to create more complex behavior (e.g. bouncing behavior + snapping behavior). See also: -- [sheet_physics.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_physics.dart) - for basic usage. -- [bouncing_behaviors.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/bouncing_behaviors.dart), - which shows how to tweak the bouncing behavior of BouncingSheetPhysics. +- [sheet_physics.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_physics.dart) for basic usage. +- [bouncing_behaviors.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/bouncing_behaviors.dart), which shows how to tweak the bouncing behavior of BouncingSheetPhysics.
@@ -310,13 +245,11 @@ See also: -Like [ScrollController](https://api.flutter.dev/flutter/widgets/ScrollController-class.html) for -scrollable widget, the SheetController can be used to animate or observe the extent of a sheet. +Like [ScrollController](https://api.flutter.dev/flutter/widgets/ScrollController-class.html) for scrollable widget, the SheetController can be used to animate or observe the extent of a sheet. See also: -- [sheet_controller.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_controller.dart) - for basic usage. +- [sheet_controller.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_controller.dart) for basic usage.
@@ -327,20 +260,14 @@ See also: -A special kind of [Scaffold](https://api.flutter.dev/flutter/material/Scaffold-class.html) designed -for use in a sheet. It has slots for an app bar and a bottom bar, similar to Scaffold. However, it -differs in that its height reduces to fit the content widget. +A special kind of [Scaffold](https://api.flutter.dev/flutter/material/Scaffold-class.html) designed for use in a sheet. It has slots for an app bar and a bottom bar, similar to Scaffold. However, it differs in that its height reduces to fit the content widget. See also: -- [SheetContentScaffold](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetContentScaffold-class.html), - the API documentation. -- [BottomBarVisibility](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/BottomBarVisibility-class.html), - which can be used to control the visibility of the bottom bar based on the sheet position. -- [tutorial/sheet_content_scaffold.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_content_scaffold.dart), - which shows the basic usage of SheetContentScaffold. -- [tutorial/bottom_bar_visibility.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/bottom_bar_visibility.dart), - which shows the basic usage of BottomBarVisibility widgets. +- [SheetContentScaffold](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetContentScaffold-class.html), the API documentation. +- [BottomBarVisibility](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/BottomBarVisibility-class.html), which can be used to control the visibility of the bottom bar based on the sheet position. +- [tutorial/sheet_content_scaffold.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_content_scaffold.dart), which shows the basic usage of SheetContentScaffold. +- [tutorial/bottom_bar_visibility.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/bottom_bar_visibility.dart), which shows the basic usage of BottomBarVisibility widgets.
@@ -350,18 +277,11 @@ See also: -SheetDraggable enables its child widget to act as a drag handle for the sheet. Typically, you will -want to use this widget when placing non-scrollable widget(s) in -a [ScrollableSheet](#scrollablesheet), since it only works with scrollable widgets, so you can't -drag the sheet by touching a non-scrollable area. Try removing SheetDraggable and you will see that -the drag handle doesn't work as it should. -Note that SheetDraggable is not needed when using DraggableSheet since it implicitly wraps the child -widget with SheetDraggable. +SheetDraggable enables its child widget to act as a drag handle for the sheet. Typically, you will want to use this widget when placing non-scrollable widget(s) in a [ScrollableSheet](#scrollablesheet), since it only works with scrollable widgets, so you can't drag the sheet by touching a non-scrollable area. Try removing SheetDraggable and you will see that the drag handle doesn't work as it should. Note that SheetDraggable is not needed when using DraggableSheet since it implicitly wraps the child widget with SheetDraggable. See also: -- [sheet_draggable.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_draggable.dart) - for basic usage. +- [sheet_draggable.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_draggable.dart) for basic usage.
@@ -371,51 +291,37 @@ See also: -It is easy to create sheet extent driven animations by using SheetPositionDrivenAnimation, a special -kind of [Animation](https://api.flutter.dev/flutter/animation/Animation-class.html) whose value -changes from 0 to 1 as the sheet extent changes from 'startExtent' to 'endExtent'. +It is easy to create sheet extent driven animations by using SheetPositionDrivenAnimation, a special kind of [Animation](https://api.flutter.dev/flutter/animation/Animation-class.html) whose value changes from 0 to 1 as the sheet extent changes from 'startExtent' to 'endExtent'. See also: -- [sheet_position_driven_animation](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_position_driven_animation.dart) - for basic usage. -- [airbnb_mobile_app.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/showcase/airbnb_mobile_app.dart), - which show how SheetPositionDrivenAnimation can be used to hide the bottom navigation bar and a - FAB when the sheet is dragged down, and to show them when the sheet is dragged up again. +- [sheet_position_driven_animation](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/sheet_position_driven_animation.dart) for basic usage. +- [airbnb_mobile_app.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/showcase/airbnb_mobile_app.dart), which show how SheetPositionDrivenAnimation can be used to hide the bottom navigation bar and a FAB when the sheet is dragged down, and to show them when the sheet is dragged up again.
### SheetNotification -A sheet dispatches -a [SheetNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetNotification-class.html) -when its extent changes. This can be used to observe the extent of a descendant sheet from an -ancestor widget. +A sheet dispatches a [SheetNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetNotification-class.html) when its extent changes. This can be used to observe the extent of a descendant sheet from an ancestor widget. ```dart -NotificationListener -( -onNotification: (notification) { -debugPrint('${notification.metrics}'); -return false; -}, -child: DraggableSheet(...), +NotificationListener( + onNotification: (notification) { + debugPrint('${notification.metrics}'); + return false; + }, + child: DraggableSheet( + ... + ), ), ``` See also: -- [SheetDragUpdateNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetDragUpdateNotification-class.html), - which is dispatched when the sheet is dragged by the user. -- [SheetUpdateNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetUpdateNotification-class.html), - which is dispatched when the sheet extent is updated by other than user interaction such as - animation. -- [SheetOverflowNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetOverflowNotification-class.html), - which is dispatched when the user tries to drag the sheet beyond its draggable bounds but the - sheet has not changed its extent because its [SheetPhysics](#sheetphysics) does not allow it to - be. -- [NotificationListener](https://api.flutter.dev/flutter/widgets/NotificationListener-class.html), - which can be used to listen for the notifications in a subtree. +- [SheetDragUpdateNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetDragUpdateNotification-class.html), which is dispatched when the sheet is dragged by the user. +- [SheetUpdateNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetUpdateNotification-class.html), which is dispatched when the sheet extent is updated by other than user interaction such as animation. +- [SheetOverflowNotification](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetOverflowNotification-class.html), which is dispatched when the user tries to drag the sheet beyond its draggable bounds but the sheet has not changed its extent because its [SheetPhysics](#sheetphysics) does not allow it to be. +- [NotificationListener](https://api.flutter.dev/flutter/widgets/NotificationListener-class.html), which can be used to listen for the notifications in a subtree.
@@ -426,43 +332,31 @@ See also:
-[SheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetKeyboardDismissBehavior-class.html) -determines when the sheet should dismiss the on-screen keyboard. This feature is similar -to [ScrollViewKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/ScrollViewKeyboardDismissBehavior.html) -for scrollable widgets. +[SheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/SheetKeyboardDismissBehavior-class.html) determines when the sheet should dismiss the on-screen keyboard. This feature is similar to [ScrollViewKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/ScrollViewKeyboardDismissBehavior.html) for scrollable widgets. -Although it is easy to create custom behaviors by implementing SheetKeyboardDismissBehavior -interface, there are 3 types of predefined behaviors for convenience. +Although it is easy to create custom behaviors by implementing SheetKeyboardDismissBehavior interface, there are 3 types of predefined behaviors for convenience. -- [DragSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragSheetKeyboardDismissBehavior-class.html), - which always dismisses the on-screen keyboard when the sheet is dragged. -- [DragDownSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragDownSheetKeyboardDismissBehavior-class.html), - which always dismisses the on-screen keyboard only when the sheet is dragged down. -- [DragUpSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragUpSheetKeyboardDismissBehavior-class.html), - which always dismisses the on-screen keyboard only when the sheet is dragged up. +- [DragSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragSheetKeyboardDismissBehavior-class.html), which always dismisses the on-screen keyboard when the sheet is dragged. +- [DragDownSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragDownSheetKeyboardDismissBehavior-class.html), which always dismisses the on-screen keyboard only when the sheet is dragged down. +- [DragUpSheetKeyboardDismissBehavior](https://pub.dev/documentation/smooth_sheets/latest/smooth_sheets/DragUpSheetKeyboardDismissBehavior-class.html), which always dismisses the on-screen keyboard only when the sheet is dragged up. See also: -- [tutorial/keyboard_dismiss_behavior.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/keyboard_dismiss_behavior.dart) - for basic usage. +- [tutorial/keyboard_dismiss_behavior.dart](https://github.com/fujidaiti/smooth_sheets/blob/main/example/lib/tutorial/keyboard_dismiss_behavior.dart) for basic usage.
## Questions -If you have any questions, feel free to ask them -on [the discussions page](https://github.com/fujidaiti/smooth_sheets/discussions). +If you have any questions, feel free to ask them on [the discussions page](https://github.com/fujidaiti/smooth_sheets/discussions).
## Contributing -Contributions are what make the open source community such an amazing place to learn, inspire, and -create. Any contributions you make are **greatly appreciated**. +Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. -If you have a suggestion that would make this better, please fork the repo and create a pull -request. You can also simply open an issue with the tag "enhancement". -Don't forget to give the project a star! Thanks again! +If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again! 1. Fork the Project 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) @@ -480,4 +374,3 @@ Don't forget to give the project a star! Thanks again! - [norelease.dev](https://pub.dev/publishers/norelease.dev/packages)
- From a19ded5fc9ee7c65a1bd951608b3bfd678f64efa Mon Sep 17 00:00:00 2001 From: Daichi Fujita <68946713+fujidaiti@users.noreply.github.com> Date: Sat, 28 Sep 2024 09:51:41 +0900 Subject: [PATCH 3/5] Support Android Studio (#256) ## Description Added .idea/ to version control and added run configurations for better DX in Android Studio. ## Summary (check all that apply) - [ ] Modified / added code - [ ] Modified / added tests - [ ] Modified / added examples - [x] Modified / added others (pubspec.yaml, workflows, etc...) - [ ] Updated README - [ ] Contains breaking changes - [ ] Created / updated migration guide - [ ] Incremented version number - [ ] Updated CHANGELOG --- .gitignore | 74 ++- .idea/.gitignore | 3 + .idea/appInsightsSettings.xml | 6 + .idea/caches/deviceStreaming.xml | 318 +++++++++++ .idea/codeStyles/Project.xml | 117 ++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .../AI_Playlist_Generator.xml | 6 + .idea/runConfigurations/AirBnb.xml | 6 + .../Bottom_Bar_Visibility.xml | 6 + .../Cupertino_Modal_Sheet.xml | 6 + .../Declarative_Modal_Sheet.xml | 6 + .../Declarative_Navigation_Sheet.xml | 6 + .idea/runConfigurations/Draggable_Sheet.xml | 6 + .../Imperative_Modal_Sheet.xml | 6 + .../Imperative_Navigation_Sheet.xml | 6 + .../Keyboard_Dismiss_Behavior.xml | 6 + .../Navigation_Sheet_And_Keyboard.xml | 6 + .idea/runConfigurations/Safari.xml | 6 + .../ScrollableSheet_And_PageView.xml | 6 + .idea/runConfigurations/Scrollable_Sheet.xml | 6 + .../Sheet_Content_Scaffold.xml | 6 + .idea/runConfigurations/Sheet_Controller.xml | 6 + .idea/runConfigurations/Sheet_Draggable.xml | 6 + .idea/runConfigurations/Sheet_Physics.xml | 6 + .../Sheet_Position_Driven_Animation.xml | 6 + .../TextField_With_Multiple_Stops.xml | 6 + .idea/runConfigurations/Todo_List.xml | 6 + .../iOS_Style_Modal_Navigation_Sheet.xml | 6 + .idea/smooth_sheets.iml | 500 ++++++++++++++++++ .idea/vcs.xml | 6 + 32 files changed, 1168 insertions(+), 7 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/appInsightsSettings.xml create mode 100644 .idea/caches/deviceStreaming.xml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations/AI_Playlist_Generator.xml create mode 100644 .idea/runConfigurations/AirBnb.xml create mode 100644 .idea/runConfigurations/Bottom_Bar_Visibility.xml create mode 100644 .idea/runConfigurations/Cupertino_Modal_Sheet.xml create mode 100644 .idea/runConfigurations/Declarative_Modal_Sheet.xml create mode 100644 .idea/runConfigurations/Declarative_Navigation_Sheet.xml create mode 100644 .idea/runConfigurations/Draggable_Sheet.xml create mode 100644 .idea/runConfigurations/Imperative_Modal_Sheet.xml create mode 100644 .idea/runConfigurations/Imperative_Navigation_Sheet.xml create mode 100644 .idea/runConfigurations/Keyboard_Dismiss_Behavior.xml create mode 100644 .idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml create mode 100644 .idea/runConfigurations/Safari.xml create mode 100644 .idea/runConfigurations/ScrollableSheet_And_PageView.xml create mode 100644 .idea/runConfigurations/Scrollable_Sheet.xml create mode 100644 .idea/runConfigurations/Sheet_Content_Scaffold.xml create mode 100644 .idea/runConfigurations/Sheet_Controller.xml create mode 100644 .idea/runConfigurations/Sheet_Draggable.xml create mode 100644 .idea/runConfigurations/Sheet_Physics.xml create mode 100644 .idea/runConfigurations/Sheet_Position_Driven_Animation.xml create mode 100644 .idea/runConfigurations/TextField_With_Multiple_Stops.xml create mode 100644 .idea/runConfigurations/Todo_List.xml create mode 100644 .idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml create mode 100644 .idea/smooth_sheets.iml create mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index 3b67647..bcae468 100644 --- a/.gitignore +++ b/.gitignore @@ -10,12 +10,6 @@ .svn/ migrate_working_dir/ -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - # Flutter/Dart/Pub related /pubspec.lock **/doc/api/ @@ -24,4 +18,70 @@ migrate_working_dir/ build/ # FVM Version Cache -.fvm/ \ No newline at end of file +.fvm/ + +# IntelliJ related +# Source: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml new file mode 100644 index 0000000..6bbe2ae --- /dev/null +++ b/.idea/appInsightsSettings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml new file mode 100644 index 0000000..af74dbf --- /dev/null +++ b/.idea/caches/deviceStreaming.xml @@ -0,0 +1,318 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..4bec4ea --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,117 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5c94cb2 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..04db2f0 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/AI_Playlist_Generator.xml b/.idea/runConfigurations/AI_Playlist_Generator.xml new file mode 100644 index 0000000..4d3ca6d --- /dev/null +++ b/.idea/runConfigurations/AI_Playlist_Generator.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/AirBnb.xml b/.idea/runConfigurations/AirBnb.xml new file mode 100644 index 0000000..92284c6 --- /dev/null +++ b/.idea/runConfigurations/AirBnb.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Bottom_Bar_Visibility.xml b/.idea/runConfigurations/Bottom_Bar_Visibility.xml new file mode 100644 index 0000000..431bf16 --- /dev/null +++ b/.idea/runConfigurations/Bottom_Bar_Visibility.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Cupertino_Modal_Sheet.xml b/.idea/runConfigurations/Cupertino_Modal_Sheet.xml new file mode 100644 index 0000000..629358a --- /dev/null +++ b/.idea/runConfigurations/Cupertino_Modal_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Declarative_Modal_Sheet.xml b/.idea/runConfigurations/Declarative_Modal_Sheet.xml new file mode 100644 index 0000000..cae8763 --- /dev/null +++ b/.idea/runConfigurations/Declarative_Modal_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Declarative_Navigation_Sheet.xml b/.idea/runConfigurations/Declarative_Navigation_Sheet.xml new file mode 100644 index 0000000..4d6284b --- /dev/null +++ b/.idea/runConfigurations/Declarative_Navigation_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Draggable_Sheet.xml b/.idea/runConfigurations/Draggable_Sheet.xml new file mode 100644 index 0000000..c1a3e75 --- /dev/null +++ b/.idea/runConfigurations/Draggable_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Imperative_Modal_Sheet.xml b/.idea/runConfigurations/Imperative_Modal_Sheet.xml new file mode 100644 index 0000000..be01b10 --- /dev/null +++ b/.idea/runConfigurations/Imperative_Modal_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Imperative_Navigation_Sheet.xml b/.idea/runConfigurations/Imperative_Navigation_Sheet.xml new file mode 100644 index 0000000..cd9260f --- /dev/null +++ b/.idea/runConfigurations/Imperative_Navigation_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml b/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml new file mode 100644 index 0000000..2f6cc20 --- /dev/null +++ b/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml b/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml new file mode 100644 index 0000000..1fffb0b --- /dev/null +++ b/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Safari.xml b/.idea/runConfigurations/Safari.xml new file mode 100644 index 0000000..650dbf4 --- /dev/null +++ b/.idea/runConfigurations/Safari.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/ScrollableSheet_And_PageView.xml b/.idea/runConfigurations/ScrollableSheet_And_PageView.xml new file mode 100644 index 0000000..90e0fe7 --- /dev/null +++ b/.idea/runConfigurations/ScrollableSheet_And_PageView.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Scrollable_Sheet.xml b/.idea/runConfigurations/Scrollable_Sheet.xml new file mode 100644 index 0000000..7afc809 --- /dev/null +++ b/.idea/runConfigurations/Scrollable_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Content_Scaffold.xml b/.idea/runConfigurations/Sheet_Content_Scaffold.xml new file mode 100644 index 0000000..323601d --- /dev/null +++ b/.idea/runConfigurations/Sheet_Content_Scaffold.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Controller.xml b/.idea/runConfigurations/Sheet_Controller.xml new file mode 100644 index 0000000..663e47f --- /dev/null +++ b/.idea/runConfigurations/Sheet_Controller.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Draggable.xml b/.idea/runConfigurations/Sheet_Draggable.xml new file mode 100644 index 0000000..f048d5b --- /dev/null +++ b/.idea/runConfigurations/Sheet_Draggable.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Physics.xml b/.idea/runConfigurations/Sheet_Physics.xml new file mode 100644 index 0000000..3889c70 --- /dev/null +++ b/.idea/runConfigurations/Sheet_Physics.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml b/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml new file mode 100644 index 0000000..5ed8ff0 --- /dev/null +++ b/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/TextField_With_Multiple_Stops.xml b/.idea/runConfigurations/TextField_With_Multiple_Stops.xml new file mode 100644 index 0000000..34b131c --- /dev/null +++ b/.idea/runConfigurations/TextField_With_Multiple_Stops.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Todo_List.xml b/.idea/runConfigurations/Todo_List.xml new file mode 100644 index 0000000..a2748f4 --- /dev/null +++ b/.idea/runConfigurations/Todo_List.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml b/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml new file mode 100644 index 0000000..8dcb630 --- /dev/null +++ b/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/smooth_sheets.iml b/.idea/smooth_sheets.iml new file mode 100644 index 0000000..3144690 --- /dev/null +++ b/.idea/smooth_sheets.iml @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 646db6490f4744983969d9bbccbe085249206eb5 Mon Sep 17 00:00:00 2001 From: Daichi Fujita <68946713+fujidaiti@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:47:02 +0900 Subject: [PATCH 4/5] Fix Entrypoint file not found error in Android Studio (#257) Updated all the run configuration files to use absolute paths for the entry point files. --- .idea/runConfigurations/AI_Playlist_Generator.xml | 2 +- .idea/runConfigurations/AirBnb.xml | 2 +- .idea/runConfigurations/Bottom_Bar_Visibility.xml | 2 +- .idea/runConfigurations/Cupertino_Modal_Sheet.xml | 2 +- .idea/runConfigurations/Declarative_Modal_Sheet.xml | 2 +- .idea/runConfigurations/Declarative_Navigation_Sheet.xml | 2 +- .idea/runConfigurations/Draggable_Sheet.xml | 2 +- .idea/runConfigurations/Imperative_Modal_Sheet.xml | 2 +- .idea/runConfigurations/Imperative_Navigation_Sheet.xml | 2 +- .idea/runConfigurations/Keyboard_Dismiss_Behavior.xml | 2 +- .idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml | 2 +- .idea/runConfigurations/Safari.xml | 2 +- .idea/runConfigurations/ScrollableSheet_And_PageView.xml | 2 +- .idea/runConfigurations/Scrollable_Sheet.xml | 2 +- .idea/runConfigurations/Sheet_Content_Scaffold.xml | 2 +- .idea/runConfigurations/Sheet_Controller.xml | 2 +- .idea/runConfigurations/Sheet_Draggable.xml | 2 +- .idea/runConfigurations/Sheet_Physics.xml | 2 +- .idea/runConfigurations/Sheet_Position_Driven_Animation.xml | 2 +- .idea/runConfigurations/TextField_With_Multiple_Stops.xml | 2 +- .idea/runConfigurations/Todo_List.xml | 2 +- .idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.idea/runConfigurations/AI_Playlist_Generator.xml b/.idea/runConfigurations/AI_Playlist_Generator.xml index 4d3ca6d..d66593c 100644 --- a/.idea/runConfigurations/AI_Playlist_Generator.xml +++ b/.idea/runConfigurations/AI_Playlist_Generator.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/AirBnb.xml b/.idea/runConfigurations/AirBnb.xml index 92284c6..b0fc46d 100644 --- a/.idea/runConfigurations/AirBnb.xml +++ b/.idea/runConfigurations/AirBnb.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Bottom_Bar_Visibility.xml b/.idea/runConfigurations/Bottom_Bar_Visibility.xml index 431bf16..6f47469 100644 --- a/.idea/runConfigurations/Bottom_Bar_Visibility.xml +++ b/.idea/runConfigurations/Bottom_Bar_Visibility.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Cupertino_Modal_Sheet.xml b/.idea/runConfigurations/Cupertino_Modal_Sheet.xml index 629358a..868fa85 100644 --- a/.idea/runConfigurations/Cupertino_Modal_Sheet.xml +++ b/.idea/runConfigurations/Cupertino_Modal_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Declarative_Modal_Sheet.xml b/.idea/runConfigurations/Declarative_Modal_Sheet.xml index cae8763..362e4a0 100644 --- a/.idea/runConfigurations/Declarative_Modal_Sheet.xml +++ b/.idea/runConfigurations/Declarative_Modal_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Declarative_Navigation_Sheet.xml b/.idea/runConfigurations/Declarative_Navigation_Sheet.xml index 4d6284b..3a9449a 100644 --- a/.idea/runConfigurations/Declarative_Navigation_Sheet.xml +++ b/.idea/runConfigurations/Declarative_Navigation_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Draggable_Sheet.xml b/.idea/runConfigurations/Draggable_Sheet.xml index c1a3e75..e06b0fd 100644 --- a/.idea/runConfigurations/Draggable_Sheet.xml +++ b/.idea/runConfigurations/Draggable_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Imperative_Modal_Sheet.xml b/.idea/runConfigurations/Imperative_Modal_Sheet.xml index be01b10..7c4c63c 100644 --- a/.idea/runConfigurations/Imperative_Modal_Sheet.xml +++ b/.idea/runConfigurations/Imperative_Modal_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Imperative_Navigation_Sheet.xml b/.idea/runConfigurations/Imperative_Navigation_Sheet.xml index cd9260f..f1b68a0 100644 --- a/.idea/runConfigurations/Imperative_Navigation_Sheet.xml +++ b/.idea/runConfigurations/Imperative_Navigation_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml b/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml index 2f6cc20..5d09cc4 100644 --- a/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml +++ b/.idea/runConfigurations/Keyboard_Dismiss_Behavior.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml b/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml index 1fffb0b..516df85 100644 --- a/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml +++ b/.idea/runConfigurations/Navigation_Sheet_And_Keyboard.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Safari.xml b/.idea/runConfigurations/Safari.xml index 650dbf4..72f737e 100644 --- a/.idea/runConfigurations/Safari.xml +++ b/.idea/runConfigurations/Safari.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/ScrollableSheet_And_PageView.xml b/.idea/runConfigurations/ScrollableSheet_And_PageView.xml index 90e0fe7..ddb51e9 100644 --- a/.idea/runConfigurations/ScrollableSheet_And_PageView.xml +++ b/.idea/runConfigurations/ScrollableSheet_And_PageView.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Scrollable_Sheet.xml b/.idea/runConfigurations/Scrollable_Sheet.xml index 7afc809..8ff54dd 100644 --- a/.idea/runConfigurations/Scrollable_Sheet.xml +++ b/.idea/runConfigurations/Scrollable_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Content_Scaffold.xml b/.idea/runConfigurations/Sheet_Content_Scaffold.xml index 323601d..0cef1ef 100644 --- a/.idea/runConfigurations/Sheet_Content_Scaffold.xml +++ b/.idea/runConfigurations/Sheet_Content_Scaffold.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Controller.xml b/.idea/runConfigurations/Sheet_Controller.xml index 663e47f..ec367de 100644 --- a/.idea/runConfigurations/Sheet_Controller.xml +++ b/.idea/runConfigurations/Sheet_Controller.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Draggable.xml b/.idea/runConfigurations/Sheet_Draggable.xml index f048d5b..689adf6 100644 --- a/.idea/runConfigurations/Sheet_Draggable.xml +++ b/.idea/runConfigurations/Sheet_Draggable.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Physics.xml b/.idea/runConfigurations/Sheet_Physics.xml index 3889c70..528edd5 100644 --- a/.idea/runConfigurations/Sheet_Physics.xml +++ b/.idea/runConfigurations/Sheet_Physics.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml b/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml index 5ed8ff0..ff8ef49 100644 --- a/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml +++ b/.idea/runConfigurations/Sheet_Position_Driven_Animation.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/TextField_With_Multiple_Stops.xml b/.idea/runConfigurations/TextField_With_Multiple_Stops.xml index 34b131c..75822d5 100644 --- a/.idea/runConfigurations/TextField_With_Multiple_Stops.xml +++ b/.idea/runConfigurations/TextField_With_Multiple_Stops.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/Todo_List.xml b/.idea/runConfigurations/Todo_List.xml index a2748f4..40962ca 100644 --- a/.idea/runConfigurations/Todo_List.xml +++ b/.idea/runConfigurations/Todo_List.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml b/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml index 8dcb630..8e489c0 100644 --- a/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml +++ b/.idea/runConfigurations/iOS_Style_Modal_Navigation_Sheet.xml @@ -1,6 +1,6 @@ - \ No newline at end of file From 6900149fe04e393ea5dcad2c325c079643f631d5 Mon Sep 17 00:00:00 2001 From: Daichi Fujita <68946713+fujidaiti@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:26:34 +0900 Subject: [PATCH 5/5] Fix: Modal sheet jerks when swipe to dismiss (#258) ## Related issues (optional) Fixes #250. ## Description This PR modifies `_SwipeDismissibleController` to ensure that the transition animation curve remains linear during the animation triggered by a swipe-to-dismiss gesture. This is crucial to prevent the sheet from jerking when the user swipes it down, as reported in #250. See the comments in the `_handleDragEnd` method for a more detailed explanation. ## Summary (check all that apply) - [x] Modified / added code - [x] Modified / added tests - [ ] Modified / added examples - [x] Modified / added others (pubspec.yaml, workflows, etc...) - [ ] Updated README - [ ] Contains breaking changes - [ ] Created / updated migration guide - [ ] Incremented version number - [ ] Updated CHANGELOG --- example/pubspec.lock | 2 +- lib/src/modal/modal_sheet.dart | 63 +++-- pubspec.yaml | 1 + test/modal/modal_sheet_test.dart | 423 +++++++++++++++++++++++++++---- 4 files changed, 417 insertions(+), 72 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index b8618ad..4b9761c 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -195,7 +195,7 @@ packages: path: ".." relative: true source: path - version: "0.9.4" + version: "0.10.0" source_span: dependency: transitive description: diff --git a/lib/src/modal/modal_sheet.dart b/lib/src/modal/modal_sheet.dart index 56d63c7..42b6ea3 100644 --- a/lib/src/modal/modal_sheet.dart +++ b/lib/src/modal/modal_sheet.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:math'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import '../foundation/sheet_drag.dart'; @@ -150,12 +151,24 @@ class ModalSheetRoute extends PageRoute with ModalSheetRouteMixin { mixin ModalSheetRouteMixin on ModalRoute { bool get swipeDismissible; + Curve get transitionCurve; + SwipeDismissSensitivity get swipeDismissSensitivity; @override bool get opaque => false; + /// The curve used for the transition animation. + /// + /// In the middle of a dismiss gesture drag, + /// this returns [Curves.linear] to match the finger motion. + @nonVirtual + @visibleForTesting + Curve get effectiveCurve => (navigator?.userGestureInProgress ?? false) + ? Curves.linear + : transitionCurve; + /// Lazily initialized in case `swipeDismissible` is set to false. late final _swipeDismissibleController = _SwipeDismissibleController( route: this, @@ -188,13 +201,9 @@ mixin ModalSheetRouteMixin on ModalRoute { Widget child, ) { final transitionTween = Tween(begin: const Offset(0, 1), end: Offset.zero); - // In the middle of a dismiss gesture drag, - // let the transition be linear to match finger motions. - final curve = - navigator!.userGestureInProgress ? Curves.linear : this.transitionCurve; return SlideTransition( position: animation.drive( - transitionTween.chain(CurveTween(curve: curve)), + transitionTween.chain(CurveTween(curve: effectiveCurve)), ), child: child, ); @@ -390,19 +399,43 @@ class _SwipeDismissibleController with SheetGestureProxyMixin { )); } - if (transitionController.isAnimating) { - // Keep the userGestureInProgress in true state so we don't change the - // curve of the page transition mid-flight since the route's transition - // depends on userGestureInProgress. + // Reset the transition animation curve back to the default from linear + // indirectly, by resetting the userGestureInProgress flag. + // It is "indirect" because ModalSheetRouteMixin.effectiveCurve returns + // the linear curve when the userGestureInProgress flag is set to true. + // + // If the transition animation has not settled at either the start or end, + // delay resetting the userGestureInProgress until the animation completes + // to ensure the effectiveCurve remains linear during the animation, + // matching the user's swipe motion. This is important to prevent the sheet + // from jerking when the user swipes it down. + // See https://github.com/fujidaiti/smooth_sheets/issues/250. + // + // Note: We cannot use AnimationController.isAnimating here to determine if + // the transition animation is running, because, in Navigator 2.0, + // the pop animation may not have started at this point even if + // Navigator.pop() is called to pop the modal route. + // + // The following sequence of events illustrates why: + // 1. Calling Navigator.pop() updates the internal page stack, triggering + // a rebuild of the Navigator. Note that the transition animation + // does not start here, so AnimationController.isAnimating returns false. + // 2. The Navigator rebuilds with the new page stack. + // 3. The modal route is removed from the Navigator's subtree. + // 4. Route.didPop() is called, initiating the pop transition animation + // by calling AnimationController.reverse(). + if (transitionController.isCompleted || transitionController.isDismissed) { + _isUserGestureInProgress = false; + } else { late final AnimationStatusListener animationStatusCallback; - animationStatusCallback = (_) { - _isUserGestureInProgress = false; - transitionController.removeStatusListener(animationStatusCallback); + animationStatusCallback = (status) { + if (status == AnimationStatus.completed || + status == AnimationStatus.dismissed) { + _isUserGestureInProgress = false; + transitionController.removeStatusListener(animationStatusCallback); + } }; transitionController.addStatusListener(animationStatusCallback); - } else { - // Otherwise, reset the userGestureInProgress state immediately. - _isUserGestureInProgress = false; } if (invokePop) { diff --git a/pubspec.yaml b/pubspec.yaml index 08c9c7e..85f8e1d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,5 +24,6 @@ dev_dependencies: build_runner: ^2.4.9 flutter_test: sdk: flutter + go_router: ^14.2.3 mockito: ^5.4.4 pedantic_mono: ^1.23.0 diff --git a/test/modal/modal_sheet_test.dart b/test/modal/modal_sheet_test.dart index 5e3fba1..4291064 100644 --- a/test/modal/modal_sheet_test.dart +++ b/test/modal/modal_sheet_test.dart @@ -1,37 +1,94 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:go_router/go_router.dart'; import 'package:smooth_sheets/smooth_sheets.dart'; +class _Boilerplate extends StatelessWidget { + const _Boilerplate({ + required this.modalRoute, + }); + + final ModalSheetRoute modalRoute; + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Builder( + builder: (context) { + return Scaffold( + body: Center( + child: ElevatedButton( + onPressed: () { + Navigator.push(context, modalRoute); + }, + child: const Text('Open modal'), + ), + ), + ); + }, + ), + ); + } +} + +class _BoilerplateWithGoRouter extends StatelessWidget { + const _BoilerplateWithGoRouter({ + required this.modalPage, + this.onExitModal, + }); + + final ModalSheetPage modalPage; + final FutureOr Function()? onExitModal; + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + routerConfig: GoRouter( + routes: [ + GoRoute( + path: '/', + builder: (context, state) { + return Scaffold( + body: Center( + child: ElevatedButton( + onPressed: () => context.go('/modal'), + child: const Text('Open modal'), + ), + ), + ); + }, + routes: [ + GoRoute( + path: 'modal', + pageBuilder: (context, state) => modalPage, + onExit: onExitModal != null + ? (context, state) => onExitModal!() + : null, + ), + ], + ), + ], + ), + ); + } +} + void main() { group('Swipe-to-dismiss action test', () { Widget boilerplate(SwipeDismissSensitivity sensitivity) { - return MaterialApp( - home: Builder( + return _Boilerplate( + modalRoute: ModalSheetRoute( + swipeDismissible: true, + swipeDismissSensitivity: sensitivity, builder: (context) { - return Scaffold( - body: Center( - child: ElevatedButton( - onPressed: () { - Navigator.push( - context, - ModalSheetRoute( - swipeDismissible: true, - swipeDismissSensitivity: sensitivity, - builder: (context) { - return DraggableSheet( - child: Container( - key: const Key('sheet'), - color: Colors.white, - width: double.infinity, - height: 600, - ), - ); - }, - ), - ); - }, - child: const Text('Open modal'), - ), + return DraggableSheet( + child: Container( + key: const Key('sheet'), + color: Colors.white, + width: double.infinity, + height: 600, ), ); }, @@ -155,37 +212,21 @@ void main() { setUp(() { isOnPopInvokedCalled = false; - testWidget = MaterialApp( - home: Builder( + testWidget = _Boilerplate( + modalRoute: ModalSheetRoute( + swipeDismissible: true, builder: (context) { - return Scaffold( - body: Center( - child: ElevatedButton( - onPressed: () { - Navigator.push( - context, - ModalSheetRoute( - swipeDismissible: true, - builder: (context) { - return DraggableSheet( - child: PopScope( - canPop: false, - onPopInvoked: (didPop) { - isOnPopInvokedCalled = true; - }, - child: Container( - key: const Key('sheet'), - color: Colors.white, - width: double.infinity, - height: 200, - ), - ), - ); - }, - ), - ); - }, - child: const Text('Open modal'), + return DraggableSheet( + child: PopScope( + canPop: false, + onPopInvoked: (didPop) { + isOnPopInvokedCalled = true; + }, + child: Container( + key: const Key('sheet'), + color: Colors.white, + width: double.infinity, + height: 200, ), ), ); @@ -222,4 +263,274 @@ void main() { }, ); }); + + // Regression tests for https://github.com/fujidaiti/smooth_sheets/issues/250 + // TODO: Add test cases using Navigator 2.0. + group('Transition animation status and animation curve consistency test', () { + ({ + Widget testWidget, + ModalSheetRoute modalRoute, + ValueGetter popInvoked, + }) boilerplate() { + var popInvoked = false; + final modalRoute = ModalSheetRoute( + swipeDismissible: true, + transitionCurve: Curves.easeInOut, + builder: (context) { + return DraggableSheet( + child: PopScope( + canPop: false, + onPopInvoked: (didPop) async { + if (!didPop) { + popInvoked = true; + Navigator.pop(context); + } + }, + child: Container( + key: const Key('sheet'), + color: Colors.white, + width: double.infinity, + height: 400, + ), + ), + ); + }, + ); + + return ( + testWidget: _Boilerplate(modalRoute: modalRoute), + modalRoute: modalRoute, + popInvoked: () => popInvoked, + ); + } + + testWidgets('Swipe-to-dismissed', (tester) async { + final env = boilerplate(); + await tester.pumpWidget(env.testWidget); + + await tester.tap(find.text('Open modal')); + await tester.pumpAndSettle(); + expect(env.modalRoute.animation!.isCompleted, isTrue); + expect(env.modalRoute.effectiveCurve, Curves.easeInOut); + + // Start dragging. + final gesture = await tester.press(find.byKey(const Key('sheet'))); + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + // End dragging and then a pop animation starts. + await gesture.moveBy(const Offset(0, 100)); + await gesture.up(); + expect(env.popInvoked(), isTrue); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + // Ensure that the pop animation is completed. + await tester.pumpAndSettle(); + expect(env.modalRoute.animation!.isDismissed, isTrue); + expect(env.modalRoute.effectiveCurve, Curves.easeInOut); + }); + + testWidgets('Swipe-to-dismiss canceled', (tester) async { + final env = boilerplate(); + await tester.pumpWidget(env.testWidget); + + await tester.tap(find.text('Open modal')); + await tester.pumpAndSettle(); + expect(env.modalRoute.animation!.isCompleted, isTrue); + expect(env.modalRoute.effectiveCurve, Curves.easeInOut); + + // Start dragging. + final gesture = await tester.press(find.byKey(const Key('sheet'))); + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + // Release the drag, triggering the modal + // to settle back to its original position. + await gesture.up(); + expect(env.popInvoked(), isFalse); + expect(env.modalRoute.animation!.status, AnimationStatus.forward); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute.animation!.isCompleted, isFalse); + expect(env.modalRoute.animation!.isDismissed, isFalse); + expect(env.modalRoute.effectiveCurve, Curves.linear); + + // Ensure that the pop animation is completed. + await tester.pumpAndSettle(); + expect(env.modalRoute.animation!.isCompleted, isTrue); + expect(env.modalRoute.effectiveCurve, Curves.easeInOut); + }); + }); + + // Regression tests for https://github.com/fujidaiti/smooth_sheets/issues/250 + group( + 'Transition animation status and animation curve consistency test ' + 'with Navigator 2.0', + () { + ({ + Widget testWidget, + ValueGetter?> modalRoute, + ValueGetter popInvoked, + }) boilerplate() { + var popInvoked = false; + ModalSheetRouteMixin? modalRoute; + final testWidget = _BoilerplateWithGoRouter( + onExitModal: () { + popInvoked = true; + return true; + }, + modalPage: ModalSheetPage( + swipeDismissible: true, + transitionCurve: Curves.easeInOut, + child: Builder( + builder: (context) { + modalRoute = + ModalRoute.of(context)! as ModalSheetRouteMixin; + + return DraggableSheet( + child: Container( + key: const Key('sheet'), + color: Colors.white, + width: double.infinity, + height: 400, + ), + ); + }, + ), + ), + ); + + return ( + testWidget: testWidget, + modalRoute: () => modalRoute, + popInvoked: () => popInvoked, + ); + } + + testWidgets('Swipe-to-dismissed', (tester) async { + final env = boilerplate(); + await tester.pumpWidget(env.testWidget); + + await tester.tap(find.text('Open modal')); + await tester.pumpAndSettle(); + expect(env.modalRoute()!.animation!.isCompleted, isTrue); + expect(env.modalRoute()!.effectiveCurve, Curves.easeInOut); + + // Start dragging. + final gesture = await tester.press(find.byKey(const Key('sheet'))); + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + // End dragging and then a pop animation starts. + await gesture.moveBy(const Offset(0, 100)); + await gesture.up(); + expect(env.popInvoked(), isTrue); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + // Ensure that the pop animation is completed. + await tester.pumpAndSettle(); + expect(env.modalRoute()!.animation!.isDismissed, isTrue); + expect(env.modalRoute()!.effectiveCurve, Curves.easeInOut); + }); + + testWidgets('Swipe-to-dismiss canceled', (tester) async { + final env = boilerplate(); + await tester.pumpWidget(env.testWidget); + + await tester.tap(find.text('Open modal')); + await tester.pumpAndSettle(); + expect(env.modalRoute()!.animation!.isCompleted, isTrue); + expect(env.modalRoute()!.effectiveCurve, Curves.easeInOut); + + // Start dragging. + final gesture = await tester.press(find.byKey(const Key('sheet'))); + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await gesture.moveBy(const Offset(0, 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + // Release the drag, triggering the modal + // to settle back to its original position. + await gesture.up(); + expect(env.popInvoked(), isFalse); + expect(env.modalRoute()!.animation!.status, AnimationStatus.forward); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + await tester.pump(const Duration(milliseconds: 50)); + expect(env.modalRoute()!.animation!.isCompleted, isFalse); + expect(env.modalRoute()!.animation!.isDismissed, isFalse); + expect(env.modalRoute()!.effectiveCurve, Curves.linear); + + // Ensure that the pop animation is completed. + await tester.pumpAndSettle(); + expect(env.modalRoute()!.animation!.isCompleted, isTrue); + expect(env.modalRoute()!.effectiveCurve, Curves.easeInOut); + }); + }, + ); }