1
+ import 'package:collection/collection.dart' ;
1
2
import 'package:ensemble/framework/action.dart' ;
2
3
import 'package:ensemble/framework/data_context.dart' ;
3
4
import 'package:ensemble/framework/error_handling.dart' ;
@@ -85,6 +86,14 @@ class ShowBottomSheetAction extends EnsembleAction {
85
86
min: 0 ,
86
87
max: 1 );
87
88
89
+ bool isSnap (scopeManager) =>
90
+ Utils .optionalBool (
91
+ eval (payload["scrollOptions" ]? ["snap" ], scopeManager)) ??
92
+ false ;
93
+
94
+ List <double >? additionalSnaps (scopeManager) => Utils .getList <double >(
95
+ eval (payload["scrollOptions" ]? ["additionalViewportSnaps" ], scopeManager));
96
+
88
97
@override
89
98
Future <dynamic > execute (BuildContext context, ScopeManager scopeManager) {
90
99
if (body != null ) {
@@ -140,6 +149,12 @@ class ShowBottomSheetAction extends EnsembleAction {
140
149
initialViewport = (minViewport + maxViewport) / 2.0 ;
141
150
}
142
151
152
+ bool useSnap = isSnap (scopeManager);
153
+ List <double >? snaps = additionalSnaps (scopeManager)
154
+ ? .where ((item) => item > minViewport && item < maxViewport)
155
+ .toList ();
156
+ snaps? .sort ();
157
+
143
158
// On platforms with a mouse (Web/desktop), there is no min/maxViewport due to platform consistency,
144
159
// so the height will be fixed to initialViewport, and content will just scroll within it.
145
160
// https://docs.flutter.dev/release/breaking-changes/default-scroll-behavior-drag
@@ -148,6 +163,8 @@ class ShowBottomSheetAction extends EnsembleAction {
148
163
minChildSize: minViewport,
149
164
maxChildSize: maxViewport,
150
165
initialChildSize: initialViewport,
166
+ snap: useSnap,
167
+ snapSizes: useSnap ? snaps : null ,
151
168
builder: (context, scrollController) =>
152
169
buildRootContainer (scopeManager, context,
153
170
child: SingleChildScrollView (
0 commit comments