From ae8ec2ebb6ab58432af627f3cd7a91a9b89bb43a Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 15 Nov 2023 10:17:41 -0800 Subject: [PATCH] 0.12.1 fixes (#2083) * Dismiss drawers on page change * Fixed routing regression Fix #2082 * ViewControl * Bottom sheet to use control state Fix #2075 * AnimatedTransitionPage * Remove old animated pages * Flet version bumped to 0.12.1 * Added `BottomSheet. is_scroll_controlled` property Allows expanding bottom sheet on the entire screen. Close #2087 * Fixed: close currently opened AlertDialog before opening a new one Fix #1670 * Added `BottomSheet.maintain_bottom_view_insets_padding` property Close #2010 --- CHANGELOG.md | 12 ++ client/pubspec.lock | 2 +- package/CHANGELOG.md | 12 ++ package/lib/src/controls/alert_dialog.dart | 5 + package/lib/src/controls/bottom_sheet.dart | 79 ++++---- package/lib/src/controls/page.dart | 170 ++++++++++-------- .../src/widgets/animated_transition_page.dart | 73 ++++++++ .../lib/src/widgets/fade_transition_page.dart | 53 ------ .../lib/src/widgets/no_animation_page.dart | 48 ----- package/pubspec.yaml | 2 +- .../flet-core/src/flet_core/bottom_sheet.py | 26 ++- 11 files changed, 273 insertions(+), 209 deletions(-) create mode 100644 package/lib/src/widgets/animated_transition_page.dart delete mode 100644 package/lib/src/widgets/fade_transition_page.dart delete mode 100644 package/lib/src/widgets/no_animation_page.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index dbe4c22a3..1bfc0f410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Flet changelog +# 0.12.1 + +* Ability to expand `ButtomSheet` to the top of the screen with `BottomSheet.is_scroll_controlled` property ([#2087](https://github.com/flet-dev/flet/issues/2087)). +* `BottomSheet.maintain_bottom_view_insets_padding` to avoid obstructing controls with on-screen keyboard ([#2010](https://github.com/flet-dev/flet/issues/2010)). +* Fixed: `NavigationDrawer` disappears when you move the window and is not opening again ([#2062](https://github.com/flet-dev/flet/issues/2062)). +* Fixed: alert dialog doesn't close ([#2011](https://github.com/flet-dev/flet/issues/2011)). +* Fixed: Resizing app's window with an opened BottomSheet triggers new addition to Overlay ([#2075](https://github.com/flet-dev/flet/issues/2075)). +* Fixed: on_window_event isnt handled after page navigation ([#2081](https://github.com/flet-dev/flet/issues/2081)). +* Fixed: Routing is not working in 0.12.0 ([#2082](https://github.com/flet-dev/flet/issues/2082)). +* Fixed: routing regression. +* Fixed: Multiple dialogs (AlertDialog) will create a ghost dialog ([#1670](https://github.com/flet-dev/flet/issues/1670)). + # 0.12.0 * `NavigationDrawer` control ([docs](https://flet.dev/docs/controls/navigationdrawer)). diff --git a/client/pubspec.lock b/client/pubspec.lock index c07093d24..c6f568fe8 100644 --- a/client/pubspec.lock +++ b/client/pubspec.lock @@ -183,7 +183,7 @@ packages: path: "../package" relative: true source: path - version: "0.12.0" + version: "0.12.1" flutter: dependency: "direct main" description: flutter diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index 4332e37d8..b2df5e791 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -1,3 +1,15 @@ +# 0.12.1 + +* Ability to expand `ButtomSheet` to the top of the screen with `BottomSheet.is_scroll_controlled` property ([#2087](https://github.com/flet-dev/flet/issues/2087)). +* `BottomSheet.maintain_bottom_view_insets_padding` to avoid obstructing controls with on-screen keyboard ([#2010](https://github.com/flet-dev/flet/issues/2010)). +* Fixed: `NavigationDrawer` disappears when you move the window and is not opening again ([#2062](https://github.com/flet-dev/flet/issues/2062)). +* Fixed: alert dialog doesn't close ([#2011](https://github.com/flet-dev/flet/issues/2011)). +* Fixed: Resizing app's window with an opened BottomSheet triggers new addition to Overlay ([#2075](https://github.com/flet-dev/flet/issues/2075)). +* Fixed: on_window_event isnt handled after page navigation ([#2081](https://github.com/flet-dev/flet/issues/2081)). +* Fixed: Routing is not working in 0.12.0 ([#2082](https://github.com/flet-dev/flet/issues/2082)). +* Fixed: routing regression. +* Fixed: Multiple dialogs (AlertDialog) will create a ghost dialog ([#1670](https://github.com/flet-dev/flet/issues/1670)). + # 0.12.0 * `NavigationDrawer` control ([docs](https://flet.dev/docs/controls/navigationdrawer)). diff --git a/package/lib/src/controls/alert_dialog.dart b/package/lib/src/controls/alert_dialog.dart index 4fdea6940..cf4ea26bb 100644 --- a/package/lib/src/controls/alert_dialog.dart +++ b/package/lib/src/controls/alert_dialog.dart @@ -94,6 +94,11 @@ class _AlertDialogControlState extends State { return dialog; } + // close previous dialog + if (ModalRoute.of(context)?.isCurrent != true) { + Navigator.pop(context); + } + widget.control.state["open"] = open; WidgetsBinding.instance.addPostFrameCallback((_) { diff --git a/package/lib/src/controls/bottom_sheet.dart b/package/lib/src/controls/bottom_sheet.dart index 6f04e351c..db8d059af 100644 --- a/package/lib/src/controls/bottom_sheet.dart +++ b/package/lib/src/controls/bottom_sheet.dart @@ -30,29 +30,25 @@ class BottomSheetControl extends StatefulWidget { } class _BottomSheetControlState extends State { - bool _open = false; - - Widget _createBottomSheet() { - bool disabled = widget.control.isDisabled || widget.parentDisabled; - var contentCtrls = widget.children.where((c) => c.name == "content"); - - if (contentCtrls.isEmpty) { - return const ErrorControl("BottomSheet does not have a content."); - } - - return createControl(widget.control, contentCtrls.first.id, disabled); - } - @override Widget build(BuildContext context) { debugPrint("BottomSheet build: ${widget.control.id}"); + var server = FletAppServices.of(context).server; + + bool lastOpen = widget.control.state["open"] ?? false; + bool disabled = widget.control.isDisabled || widget.parentDisabled; + var open = widget.control.attrBool("open", false)!; //var modal = widget.control.attrBool("modal", true)!; var dismissible = widget.control.attrBool("dismissible", true)!; var enableDrag = widget.control.attrBool("enableDrag", false)!; var showDragHandle = widget.control.attrBool("showDragHandle", false)!; var useSafeArea = widget.control.attrBool("useSafeArea", true)!; + var isScrollControlled = + widget.control.attrBool("isScrollControlled", false)!; + var maintainBottomViewInsetsPadding = + widget.control.attrBool("maintainBottomViewInsetsPadding", true)!; void resetOpenState() { List> props = [ @@ -60,47 +56,68 @@ class _BottomSheetControlState extends State { ]; widget.dispatch( UpdateControlPropsAction(UpdateControlPropsPayload(props: props))); - FletAppServices.of(context).server.updateControlProps(props: props); + server.updateControlProps(props: props); } - if (!open && _open) { - _open = false; - resetOpenState(); - Navigator.pop(context); - } else if (open && !_open) { - var bottomSheet = _createBottomSheet(); - if (bottomSheet is ErrorControl) { - return bottomSheet; - } - - _open = open; + if (open && !lastOpen) { + widget.control.state["open"] = open; WidgetsBinding.instance.addPostFrameCallback((_) { showModalBottomSheet( context: context, builder: (context) { - return bottomSheet; + var contentCtrls = + widget.children.where((c) => c.name == "content"); + + if (contentCtrls.isEmpty) { + return const ErrorControl( + "BottomSheet does not have a content."); + } + + var content = createControl( + widget.control, contentCtrls.first.id, disabled); + + if (content is ErrorControl) { + return content; + } + + if (maintainBottomViewInsetsPadding) { + var bottomPadding = + MediaQuery.of(context).viewInsets.bottom; + debugPrint("bottomPadding: $bottomPadding"); + content = Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom), + child: content, + ); + } + + return content; }, isDismissible: dismissible, + isScrollControlled: isScrollControlled, enableDrag: enableDrag, showDragHandle: showDragHandle, useSafeArea: useSafeArea) .then((value) { - debugPrint("BottomSheet dismissed: $_open"); - bool shouldDismiss = _open; - _open = false; + lastOpen = widget.control.state["open"] ?? false; + debugPrint("BottomSheet dismissed: $lastOpen"); + bool shouldDismiss = lastOpen; + widget.control.state["open"] = false; if (shouldDismiss) { resetOpenState(); - FletAppServices.of(context).server.sendPageEvent( + server.sendPageEvent( eventTarget: widget.control.id, eventName: "dismiss", eventData: ""); } }); }); + } else if (open != lastOpen && lastOpen) { + Navigator.pop(context); } - return widget.nextChild ?? const SizedBox.shrink(); + return const SizedBox.shrink(); } } diff --git a/package/lib/src/controls/page.dart b/package/lib/src/controls/page.dart index 7d5beb5b8..09861adbf 100644 --- a/package/lib/src/controls/page.dart +++ b/package/lib/src/controls/page.dart @@ -28,9 +28,8 @@ import '../utils/edge_insets.dart'; import '../utils/images.dart'; import '../utils/theme.dart'; import '../utils/user_fonts.dart'; -import '../widgets/fade_transition_page.dart'; +import '../widgets/animated_transition_page.dart'; import '../widgets/loading_page.dart'; -import '../widgets/no_animation_page.dart'; import '../widgets/page_media.dart'; import '../widgets/window_media.dart'; import 'app_bar.dart'; @@ -92,8 +91,6 @@ class _PageControlState extends State { late final RouteParser _routeParser; String? _prevViewRoutes; bool _keyboardHandlerSubscribed = false; - bool? _drawerOpened; - bool? _endDrawerOpened; @override void initState() { @@ -484,7 +481,8 @@ class _PageControlState extends State { List> pages = []; if (routesView.views.isEmpty) { - pages.add(FadeTransitionPage( + pages.add(AnimatedTransitionPage( + fadeTransition: true, child: hideLoadingPage ? const Scaffold( body: PageMedia(), @@ -528,19 +526,26 @@ class _PageControlState extends State { String viewRoutes = routesView.views .map((v) => v.attrString("route") ?? v.id) .join(); + pages = routesView.views.map((view) { var key = ValueKey(view.attrString("route") ?? view.id); - var child = _buildViewWidget(routesView.page, view.id, - overlayWidgets(view.id), loadingPage); + var child = ViewControl( + parent: routesView.page, + viewId: view.id, + overlayWidgets: overlayWidgets(view.id), + loadingPage: loadingPage, + dispatch: widget.dispatch); + + //debugPrint("ROUTES: $_prevViewRoutes $viewRoutes"); + return _prevViewRoutes == null - ? FadeTransitionPage(key: key, child: child) - : _prevViewRoutes == viewRoutes - ? NoAnimationPage(key: key, child: child) - : MaterialPage( - key: key, - child: child, - fullscreenDialog: - view.attrBool("fullscreenDialog", false)!); + ? AnimatedTransitionPage( + key: key, child: child, fadeTransition: true) + : AnimatedTransitionPage( + key: key, + child: child, + fullscreenDialog: + view.attrBool("fullscreenDialog", false)!); }).toList(); _prevViewRoutes = viewRoutes; @@ -569,16 +574,39 @@ class _PageControlState extends State { return nextChild; }); } +} - Widget _buildViewWidget(Control parent, String viewId, - List overlayWidgets, Widget? loadingPage) { +class ViewControl extends StatefulWidget { + final Control parent; + final String viewId; + final List overlayWidgets; + final Widget? loadingPage; + final dynamic dispatch; + + const ViewControl( + {super.key, + required this.parent, + required this.viewId, + required this.overlayWidgets, + required this.loadingPage, + required this.dispatch}); + + @override + State createState() => _ViewControlState(); +} + +class _ViewControlState extends State { + final scaffoldKey = GlobalKey(); + + @override + Widget build(BuildContext context) { return StoreConnector( distinct: true, converter: (store) { - return ControlViewModel.fromStore(store, viewId); + return ControlViewModel.fromStore(store, widget.viewId); }, ignoreChange: (state) { - return state.controls[viewId] == null; + return state.controls[widget.viewId] == null; }, // onWillChange: (prev, next) { // debugPrint("View StoreConnector.onWillChange(): $prev, $next"); @@ -642,7 +670,7 @@ class _PageControlState extends State { List childIds = [appBar?.id, drawer?.id, endDrawer?.id].whereNotNull().toList(); - final textDirection = parent.attrBool("rtl", false)! + final textDirection = widget.parent.attrBool("rtl", false)! ? TextDirection.rtl : TextDirection.ltr; @@ -660,7 +688,7 @@ class _PageControlState extends State { return false; }, builder: (context, childrenViews) { - debugPrint("Route view StoreConnector build: $viewId"); + debugPrint("Route view StoreConnector build: ${widget.viewId}"); var appBarView = childrenViews.controlViews.firstWhereOrNull( (v) => v.control.id == (appBar?.id ?? "")); @@ -686,49 +714,67 @@ class _PageControlState extends State { ScrollNotificationControl(control: control, child: child); } - GlobalKey? scaffoldKey = - FletAppServices.of(context).globalKeys["_scaffold"] - as GlobalKey?; - if (scaffoldKey == null) { - scaffoldKey = GlobalKey(); - FletAppServices.of(context).globalKeys["_scaffold"] = - scaffoldKey; + final bool? drawerOpened = widget.parent.state["drawerOpened"]; + final bool? endDrawerOpened = + widget.parent.state["endDrawerOpened"]; + + void dismissDrawer(String id) { + List> props = [ + {"i": id, "open": "false"} + ]; + widget.dispatch(UpdateControlPropsAction( + UpdateControlPropsPayload(props: props))); + FletAppServices.of(context) + .server + .updateControlProps(props: props); + FletAppServices.of(context).server.sendPageEvent( + eventTarget: id, eventName: "dismiss", eventData: ""); } WidgetsBinding.instance.addPostFrameCallback((_) { if (drawerView != null) { + if (scaffoldKey.currentState?.isDrawerOpen == false && + drawerOpened == true) { + widget.parent.state["drawerOpened"] = false; + dismissDrawer(drawerView.control.id); + } if (drawerView.control.attrBool("open", false)! && - _drawerOpened != true) { - if (scaffoldKey?.currentState?.isEndDrawerOpen == true) { - scaffoldKey?.currentState?.closeEndDrawer(); + drawerOpened != true) { + if (scaffoldKey.currentState?.isEndDrawerOpen == true) { + scaffoldKey.currentState?.closeEndDrawer(); } Future.delayed(const Duration(milliseconds: 1)) .then((value) { - scaffoldKey?.currentState?.openDrawer(); - _drawerOpened = true; + scaffoldKey.currentState?.openDrawer(); + widget.parent.state["drawerOpened"] = true; }); } else if (!drawerView.control.attrBool("open", false)! && - _drawerOpened == true) { - scaffoldKey?.currentState?.closeDrawer(); - _drawerOpened = false; + drawerOpened == true) { + scaffoldKey.currentState?.closeDrawer(); + widget.parent.state["drawerOpened"] = false; } } if (endDrawerView != null) { + if (scaffoldKey.currentState?.isEndDrawerOpen == false && + endDrawerOpened == true) { + widget.parent.state["endDrawerOpened"] = false; + dismissDrawer(endDrawerView.control.id); + } if (endDrawerView.control.attrBool("open", false)! && - _endDrawerOpened != true) { - if (scaffoldKey?.currentState?.isDrawerOpen == true) { - scaffoldKey?.currentState?.closeDrawer(); + endDrawerOpened != true) { + if (scaffoldKey.currentState?.isDrawerOpen == true) { + scaffoldKey.currentState?.closeDrawer(); } Future.delayed(const Duration(milliseconds: 1)) .then((value) { - scaffoldKey?.currentState?.openEndDrawer(); - _endDrawerOpened = true; + scaffoldKey.currentState?.openEndDrawer(); + widget.parent.state["endDrawerOpened"] = true; }); } else if (!endDrawerView.control .attrBool("open", false)! && - _endDrawerOpened == true) { - scaffoldKey?.currentState?.closeEndDrawer(); - _endDrawerOpened = false; + endDrawerOpened == true) { + scaffoldKey.currentState?.closeEndDrawer(); + widget.parent.state["endDrawerOpened"] = false; } } }); @@ -756,19 +802,8 @@ class _PageControlState extends State { : null, onDrawerChanged: (opened) { if (drawerView != null && !opened) { - _drawerOpened = false; - List> props = [ - {"i": drawerView.control.id, "open": "false"} - ]; - widget.dispatch(UpdateControlPropsAction( - UpdateControlPropsPayload(props: props))); - FletAppServices.of(context) - .server - .updateControlProps(props: props); - FletAppServices.of(context).server.sendPageEvent( - eventTarget: drawerView.control.id, - eventName: "dismiss", - eventData: ""); + widget.parent.state["drawerOpened"] = false; + dismissDrawer(drawerView.control.id); } }, endDrawer: endDrawerView != null @@ -781,19 +816,8 @@ class _PageControlState extends State { : null, onEndDrawerChanged: (opened) { if (endDrawerView != null && !opened) { - _endDrawerOpened = false; - List> props = [ - {"i": endDrawerView.control.id, "open": "false"} - ]; - widget.dispatch(UpdateControlPropsAction( - UpdateControlPropsPayload(props: props))); - FletAppServices.of(context) - .server - .updateControlProps(props: props); - FletAppServices.of(context).server.sendPageEvent( - eventTarget: endDrawerView.control.id, - eventName: "dismiss", - eventData: ""); + widget.parent.state["endDrawerOpened"] = false; + dismissDrawer(endDrawerView.control.id); } }, body: Stack(children: [ @@ -802,7 +826,7 @@ class _PageControlState extends State { padding: parseEdgeInsets(control, "padding") ?? const EdgeInsets.all(10), child: child)), - ...overlayWidgets + ...widget.overlayWidgets ]), bottomNavigationBar: navBar != null ? createControl(control, navBar.id, control.isDisabled) @@ -814,9 +838,9 @@ class _PageControlState extends State { return Directionality( textDirection: textDirection, - child: loadingPage != null + child: widget.loadingPage != null ? Stack( - children: [scaffold, loadingPage], + children: [scaffold, widget.loadingPage!], ) : scaffold); }); diff --git a/package/lib/src/widgets/animated_transition_page.dart b/package/lib/src/widgets/animated_transition_page.dart new file mode 100644 index 000000000..04347b8ba --- /dev/null +++ b/package/lib/src/widgets/animated_transition_page.dart @@ -0,0 +1,73 @@ +// Copyright 2021, the Flutter project authors. Please see the AUTHORS file +// for details. 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'; + +class AnimatedTransitionPage extends Page { + final bool fadeTransition; + final Widget child; + final Duration duration; + final bool fullscreenDialog; + + const AnimatedTransitionPage({ + LocalKey? key, + required this.child, + this.fadeTransition = false, + this.fullscreenDialog = false, + this.duration = const Duration(milliseconds: 300), + }) : super(key: key); + + @override + Route createRoute(BuildContext context) => + PageBasedAnimatedTransitionRoute(this, fullscreenDialog); +} + +class PageBasedAnimatedTransitionRoute extends PageRoute { + final AnimatedTransitionPage _page; + + PageBasedAnimatedTransitionRoute(this._page, bool fullscreenDialog) + : super(settings: _page, fullscreenDialog: fullscreenDialog); + + @override + Color? get barrierColor => null; + + @override + String? get barrierLabel => null; + + @override + Duration get transitionDuration => _page.duration; + + @override + bool get maintainState => true; + + @override + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + final Widget child = (settings as AnimatedTransitionPage).child; + + if (_page.fadeTransition) { + // initial page + var curveTween = CurveTween(curve: Curves.easeIn); + return FadeTransition( + opacity: animation.drive(curveTween), + child: (settings as AnimatedTransitionPage).child, + ); + } else { + // use standard animation + return Semantics( + scopesRoute: true, + explicitChildNodes: true, + child: child, + ); + } + } + + @override + Widget buildTransitions(BuildContext context, Animation animation, + Animation secondaryAnimation, Widget child) => + _page.fadeTransition + ? child + : Theme.of(context).pageTransitionsTheme.buildTransitions( + this, context, animation, secondaryAnimation, child); +} diff --git a/package/lib/src/widgets/fade_transition_page.dart b/package/lib/src/widgets/fade_transition_page.dart deleted file mode 100644 index 52df8d04c..000000000 --- a/package/lib/src/widgets/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. 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'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - LocalKey? key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }) : super(key: key); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/package/lib/src/widgets/no_animation_page.dart b/package/lib/src/widgets/no_animation_page.dart deleted file mode 100644 index fe0361cd3..000000000 --- a/package/lib/src/widgets/no_animation_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. 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'; - -class NoAnimationPage extends Page { - final Widget child; - final Duration duration; - - const NoAnimationPage({ - LocalKey? key, - required this.child, - this.duration = const Duration(milliseconds: 0), - }) : super(key: key); - - @override - Route createRoute(BuildContext context) => NoAnimationPageRoute(this); -} - -class NoAnimationPageRoute extends PageRoute { - final NoAnimationPage _page; - - NoAnimationPageRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoAnimationPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/package/pubspec.yaml b/package/pubspec.yaml index d8e7248d1..8a71caf67 100644 --- a/package/pubspec.yaml +++ b/package/pubspec.yaml @@ -2,7 +2,7 @@ name: flet description: Write entire Flutter app in Python or add server-driven UI experience into existing Flutter app. homepage: https://flet.dev repository: https://github.com/flet-dev/flet -version: 0.12.0 +version: 0.12.1 # This package supports all platforms listed below. platforms: diff --git a/sdk/python/packages/flet-core/src/flet_core/bottom_sheet.py b/sdk/python/packages/flet-core/src/flet_core/bottom_sheet.py index 77cd97259..73f438ecc 100644 --- a/sdk/python/packages/flet-core/src/flet_core/bottom_sheet.py +++ b/sdk/python/packages/flet-core/src/flet_core/bottom_sheet.py @@ -64,6 +64,8 @@ def __init__( enable_drag: Optional[bool] = None, show_drag_handle: Optional[bool] = None, use_safe_area: Optional[bool] = None, + is_scroll_controlled: Optional[bool] = None, + maintain_bottom_view_insets_padding: Optional[bool] = None, on_dismiss=None, ): Control.__init__( @@ -74,16 +76,16 @@ def __init__( data=data, ) - self.__title: Optional[Control] = None self.__content: Optional[Control] = None - self.__actions: List[Control] = [] self.open = open self.dismissible = dismissible self.enable_drag = enable_drag self.show_drag_handle = show_drag_handle self.use_safe_area = use_safe_area + self.is_scroll_controlled = is_scroll_controlled self.content = content + self.maintain_bottom_view_insets_padding = maintain_bottom_view_insets_padding self.on_dismiss = on_dismiss def _get_control_name(self): @@ -141,6 +143,26 @@ def use_safe_area(self) -> Optional[bool]: def use_safe_area(self, value: Optional[bool]): self._set_attr("useSafeArea", value) + # is_scroll_controlled + @property + def is_scroll_controlled(self) -> Optional[bool]: + return self._get_attr("isScrollControlled", data_type="bool", def_value=False) + + @is_scroll_controlled.setter + def is_scroll_controlled(self, value: Optional[bool]): + self._set_attr("isScrollControlled", value) + + # maintain_bottom_view_insets_padding + @property + def maintain_bottom_view_insets_padding(self) -> Optional[bool]: + return self._get_attr( + "maintainBottomViewInsetsPadding", data_type="bool", def_value=True + ) + + @maintain_bottom_view_insets_padding.setter + def maintain_bottom_view_insets_padding(self, value: Optional[bool]): + self._set_attr("maintainBottomViewInsetsPadding", value) + # content @property def content(self):