Skip to content

Commit

Permalink
Add FlexibleWoltModalSheetPage for non-scrolling page content
Browse files Browse the repository at this point in the history
  • Loading branch information
ulusoyca committed Jan 26, 2024
1 parent 7b46f43 commit bf188ed
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,41 +43,44 @@ class WoltModalSheetMainContent extends StatelessWidget {
page.trailingNavBarWidget != null
? navBarHeight
: 0.0;
final isFlexiblePage = page is FlexibleWoltModalSheetPage;
final scrollView = CustomScrollView(
shrinkWrap: true,
physics: themeData?.mainContentScrollPhysics ??
defaultThemeData.mainContentScrollPhysics,
controller: scrollController,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index == 0) {
final heroImage = page.heroImage;
return heroImage != null
? WoltModalSheetHeroImage(
topBarHeight: topBarHeight,
heroImage: heroImage,
heroImageHeight: heroImageHeight,
)
// If top bar layer is always visible, the padding is explicitly added to the
// scroll view since top bar will not be integrated to scroll view at all.
// Otherwise, we implicitly create a spacing as a part of the scroll view.
: SizedBox(
height: isTopBarLayerAlwaysVisible ? 0 : topBarHeight);
} else {
final pageTitle = page.pageTitle;
return KeyedSubtree(
key: pageTitleKey,
child: pageTitle ?? const SizedBox.shrink(),
);
}
},
childCount: 2,
if (!isFlexiblePage)
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index == 0) {
final heroImage = page.heroImage;
return heroImage != null
? WoltModalSheetHeroImage(
topBarHeight: topBarHeight,
heroImage: heroImage,
heroImageHeight: heroImageHeight,
)
// If top bar layer is always visible, the padding is explicitly added to the
// scroll view since top bar will not be integrated to scroll view at all.
// Otherwise, we implicitly create a spacing as a part of the scroll view.
: SizedBox(
height:
isTopBarLayerAlwaysVisible ? 0 : topBarHeight);
} else {
final pageTitle = page.pageTitle;
return KeyedSubtree(
key: pageTitleKey,
child: pageTitle ?? const SizedBox.shrink(),
);
}
},
childCount: 2,
),
),
),
...page.mainContentSlivers,
if (page.forceMaxHeight)
if (page.forceMaxHeight && !isFlexiblePage)
const SliverFillRemaining(
hasScrollBody: false,
child: SizedBox.shrink(),
Expand Down
21 changes: 11 additions & 10 deletions lib/src/content/wolt_modal_sheet_animated_switcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,16 @@ class _WoltModalSheetAnimatedSwitcherState
final shouldShowTopBarTitle = hasTopBarLayer && _page.topBar == null;
Widget? navigationToolbarMiddle;
if (shouldShowTopBarTitle) {
navigationToolbarMiddle = isTopBarLayerAlwaysVisible
? Center(child: topBarTitle)
: WoltModalSheetTopBarTitleFlow(
page: _page,
scrollController: _currentPageScrollController,
titleKey: _pageTitleKey,
topBarTitle: topBarTitle,
softKeyboardClosedListenable: _softKeyboardClosedNotifier,
);
navigationToolbarMiddle =
isTopBarLayerAlwaysVisible || _page is FlexibleWoltModalSheetPage
? Center(child: topBarTitle)
: WoltModalSheetTopBarTitleFlow(
page: _page,
scrollController: _currentPageScrollController,
titleKey: _pageTitleKey,
topBarTitle: topBarTitle,
softKeyboardClosedListenable: _softKeyboardClosedNotifier,
);
}
return PaginatingWidgetsGroup(
mainContentAnimatedBuilder: MainContentAnimatedBuilder(
Expand All @@ -368,7 +369,7 @@ class _WoltModalSheetAnimatedSwitcherState
pageTransitionState: WoltModalSheetPageTransitionState.incoming,
controller: animationController,
child: hasTopBarLayer
? (isTopBarLayerAlwaysVisible
? (isTopBarLayerAlwaysVisible || _page is FlexibleWoltModalSheetPage
? WoltModalSheetTopBar(page: _page)
: WoltModalSheetTopBarFlow(
page: _page,
Expand Down
43 changes: 43 additions & 0 deletions lib/src/modal_page/flexible_wolt_modal_sheet_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

/// A [FlexibleWoltModalSheetPage] is a specialized page for the [WoltModalSheet]
/// that is designed to display content which is flexible in height but unlikely
/// to require scrolling.
///
/// This class is designed for content that needs to adapt to the available
/// vertical space within the modal sheet's maximum height, but is unlikely
/// to exceed that height and require scrolling. It is ideal for content that
/// is flexible in height but has fixed (or intrinsic) dimensions and is laid
/// out using the [Flex] layout model of a [Column].
///
/// Warning:
/// - If there is a risk that the content's height might exceed the modal
/// sheet's maximum height, leading to overflow, it is recommended to use
/// [SliverWoltModalSheetPage] or [WoltModalSheetPage] instead. These classes
/// provide scrolling capabilities to handle larger content effectively using slivers.
class FlexibleWoltModalSheetPage extends SliverWoltModalSheetPage {
/// A [Widget] that represents the main content displayed in the page.
/// This is a shortcut for providing a list of Sliver widgets with only one Sliver widget.
final Widget child;

/// Creates a page to be built within [WoltScrollableModalSheet].
FlexibleWoltModalSheetPage({
required this.child,
super.backgroundColor,
super.enableDrag,
super.leadingNavBarWidget,
super.trailingNavBarWidget,
super.hasTopBarLayer = false,
super.topBar,
super.topBarTitle,
super.navBarHeight,
}) : super(
isTopBarLayerAlwaysVisible: hasTopBarLayer,
mainContentSlivers: [
SliverFillViewport(
delegate: SliverChildListDelegate([child]),
),
],
);
}
1 change: 1 addition & 0 deletions lib/wolt_modal_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library wolt_modal_sheet;

export 'src/modal_page/sliver_wolt_modal_sheet_page.dart';
export 'src/modal_page/wolt_modal_sheet_page.dart';
export 'src/modal_page/flexible_wolt_modal_sheet_page.dart';
export 'src/modal_type/wolt_modal_type.dart';
export 'src/theme/wolt_modal_sheet_theme_data.dart';
export 'src/wolt_modal_sheet.dart';
Expand Down
15 changes: 15 additions & 0 deletions playground/lib/home/pages/multi_page_path_name.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:playground/home/pages/root_sheet_page.dart';
import 'package:playground/home/pages/sheet_page_with_custom_top_bar.dart';
import 'package:playground/home/pages/sheet_page_with_dynamic_page_properties.dart';
import 'package:playground/home/pages/sheet_page_with_flexible_sheet_layout.dart';
import 'package:playground/home/pages/sheet_page_with_forced_max_height.dart';
import 'package:playground/home/pages/sheet_page_with_hero_image.dart';
import 'package:playground/home/pages/sheet_page_with_lazy_list.dart';
Expand All @@ -17,6 +18,7 @@ enum MultiPagePathName {
noTitleNoTopBar(pageCount: 2, queryParamName: "noTitleNoTopBar"),
customTopBar(pageCount: 2, queryParamName: "customTopBar"),
dynamicPageProperties(pageCount: 2, queryParamName: "dynamicPageProperties"),
flexibleLayout(pageCount: 2, queryParamName: "flexibleLayout"),
allPagesPath(pageCount: 6, queryParamName: "all");

static const defaultPath = MultiPagePathName.allPagesPath;
Expand Down Expand Up @@ -80,6 +82,16 @@ enum MultiPagePathName {
onBackPressed: goToPreviousPage,
isLastPage: isLastPage,
);
FlexibleWoltModalSheetPage flexibleSheetLayout(
BuildContext context, {
bool isLastPage = true,
}) =>
SheetPageWithFlexibleSheetLayout.build(
nextPagePressed: () => isLastPage ? close(context) : goToNextPage(),
onClosed: () => close(context),
onBackPressed: goToPreviousPage,
isLastPage: isLastPage,
);
WoltModalSheetPage dynamicPageProperties(BuildContext context,
{bool isLastPage = true}) =>
SheetPageWithDynamicPageProperties.build(
Expand Down Expand Up @@ -112,6 +124,8 @@ enum MultiPagePathName {
return (context) => [root(context), customTopBar(context)];
case MultiPagePathName.dynamicPageProperties:
return (context) => [root(context), dynamicPageProperties(context)];
case MultiPagePathName.flexibleLayout:
return (context) => [root(context), flexibleSheetLayout(context)];
case MultiPagePathName.allPagesPath:
return (context) => [
root(context),
Expand All @@ -121,6 +135,7 @@ enum MultiPagePathName {
noTitleNoTopBar(context, isLastPage: false),
customTopBar(context, isLastPage: false),
dynamicPageProperties(context, isLastPage: false),
flexibleSheetLayout(context, isLastPage: false),
forcedMaxHeight(context, isLastPage: true),
];
}
Expand Down
5 changes: 5 additions & 0 deletions playground/lib/home/pages/root_sheet_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ class RootSheetPage {
value: MultiPagePathName.dynamicPageProperties,
isSelected: false,
),
WoltSelectionListItemData(
title: 'WoltFlexibleSheetPage example',
value: MultiPagePathName.flexibleLayout,
isSelected: false,
),
WoltSelectionListItemData(
title: 'All the pages in one flow',
value: MultiPagePathName.allPagesPath,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:demo_ui_components/demo_ui_components.dart';
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

class SheetPageWithFlexibleSheetLayout {
SheetPageWithFlexibleSheetLayout._();

static FlexibleWoltModalSheetPage build({
required VoidCallback nextPagePressed,
required VoidCallback onBackPressed,
required VoidCallback onClosed,
bool isLastPage = true,
}) {
const textStyle = TextStyle(fontSize: 24, fontWeight: FontWeight.bold);
return FlexibleWoltModalSheetPage(
leadingNavBarWidget:
WoltModalSheetBackButton(onBackPressed: onBackPressed),
trailingNavBarWidget: WoltModalSheetCloseButton(onClosed: onClosed),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Flexible(
flex: 2,
child: ColoredBox(
color: Colors.blue,
child: Center(
child: Text('Flex: 2', style: textStyle),
),
),
),
const Flexible(
flex: 3,
child: ColoredBox(
color: Colors.amber,
child: Center(child: Text('Flex: 3', style: textStyle)),
),
),
Flexible(
flex: 1,
child: GestureDetector(
onTap: isLastPage ? onClosed : nextPagePressed,
child: ColoredBox(
color: Colors.green,
child: Center(
child: Text(
"Flex: 1\n Tap here to ${isLastPage ? 'close' : 'go to the next page'}",
style: textStyle,
textAlign: TextAlign.center,
),
),
),
),
),
],
),
);
}
}

0 comments on commit bf188ed

Please sign in to comment.