Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce SliverWoltModalSheetPage and WoltModalSheetPage classes to construct modal sheet pages #95

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 89 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,59 @@ Here is an example that shows all the modal sheet elements in use:

![Modal sheet elements in use](https://github.com/woltapp/wolt_modal_sheet/blob/main/doc/bottom_sheet_example.jpeg?raw=true)

## Usage of WoltModalSheet Pages

The WoltModalSheet library provides two primary classes for constructing
modal sheet pages: `SliverWoltModalSheetPage` and `WoltModalSheetPage`.
Understanding the use cases and functionalities of these classes is key to
creating performant and easy to construct modal sheets.

### SliverWoltModalSheetPage

`SliverWoltModalSheetPage` is designed for complex and dynamic content
layouts within a modal sheet. It leverages the power of Flutter's Sliver
widgets to provide flexible and efficient scrolling behaviors.

```dart
SliverWoltModalSheetPage(
mainContentSlivers: [
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
// Your list items
}),
),
// Other sliver widgets...
],
// Additional page elements like pageTitle, topBarTitle, etc.
)
```

### WoltModalSheetPage
WoltModalSheetPage provides a simpler alternative for pages that primarily
consist of a single widget or a straightforward layout. It automatically
wraps the child widget in a SliverToBoxAdapter, making it suitable for use
in sliver-based scrollable layouts.

Key Features:
* Simplicity: Ideal for single-widget content or basic layouts.
* No Sliver Overhead: Automatically handles the wrapping of non-sliver
widgets into slivers.
* Ease of Use: Simplifies the process of creating modal sheet pages without
needing to deal with slivers directly.

```dart
WoltModalSheetPage(
child: MyCustomContentWidget(),
pageTitle: Text('My Page Title'),
// Other properties...
)
```

### Choosing Between the Two
* Use `SliverWoltModalSheetPage` when your modal sheet requires complex scrolling behaviors or needs to display a list of items.
* Choose WoltModalSheetPage for simpler content layouts or when working with
a single widget.

## Getting started

To use this plugin, add wolt_modal_sheet as a dependency in your pubspec.yaml
Expand All @@ -201,11 +254,12 @@ using [WoltModalSheetThemeData](./lib/src/theme/wolt_modal_sheet_theme_data.dart
extension.

```dart
@override
Widget build(BuildContext context) {
final pageIndexNotifier = ValueNotifier(0);

WoltModalSheetPage page1(BuildContext modalSheetContext, TextTheme textTheme) {
return WoltModalSheetPage.withSingleChild(
SliverWoltModalSheetPage page1(BuildContext modalSheetContext, TextTheme textTheme) {
return WoltModalSheetPage(
hasSabGradient: false,
stickyActionBar: Padding(
padding: const EdgeInsets.all(_pagePadding),
Expand Down Expand Up @@ -253,25 +307,10 @@ Pagination involves a sequence of screens the user navigates sequentially. We ch
);
}

WoltModalSheetPage page2(BuildContext modalSheetContext, TextTheme textTheme) {
return WoltModalSheetPage.withCustomSliverList(
stickyActionBar: Padding(
padding:
const EdgeInsets.fromLTRB(_pagePadding, _pagePadding / 4, _pagePadding, _pagePadding),
child: ElevatedButton(
onPressed: () {
Navigator.of(modalSheetContext).pop();
pageIndexNotifier.value = 0;
},
child: const SizedBox(
height: _buttonHeight,
width: double.infinity,
child: Center(child: Text('Close')),
),
),
),
SliverWoltModalSheetPage page2(BuildContext modalSheetContext, TextTheme textTheme) {
return SliverWoltModalSheetPage(
pageTitle: Padding(
padding: const EdgeInsets.symmetric(horizontal: _pagePadding),
padding: const EdgeInsets.all(_pagePadding),
child: Text(
'Material Colors',
style: textTheme.headlineMedium!.copyWith(fontWeight: FontWeight.bold),
Expand All @@ -296,12 +335,36 @@ Pagination involves a sequence of screens the user navigates sequentially. We ch
pageIndexNotifier.value = 0;
},
),
sliverList: SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => ColorTile(color: allMaterialColors[index]),
childCount: allMaterialColors.length,
mainContentSlivers: [
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 2.0,
),
delegate: SliverChildBuilderDelegate(
(_, index) => ColorTile(color: materialColorsInGrid[index]),
childCount: materialColorsInGrid.length,
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => ColorTile(color: materialColorsInSliverList[index]),
childCount: materialColorsInSliverList.length,
),
),
...materialColorsInSpinner.map((e) => Shifter(child: ColorTile(color: e))).toList(),
SliverPadding(
padding: const EdgeInsets.all(_pagePadding),
sliver: SliverToBoxAdapter(
child: TextButton(
onPressed: Navigator.of(modalSheetContext).pop,
child: const Text('Close'),
),
),
),
],
);
}

Expand Down Expand Up @@ -396,7 +459,7 @@ Pagination involves a sequence of screens the user navigates sequentially. We ch
The code snippet above produces the following:
</br>
</br>
![Example app](https://github.com/woltapp/wolt_modal_sheet/blob/main/doc/example_app_with_theme_extensions.gif?raw=true)
![Example app](https://github.com/woltapp/wolt_modal_sheet/blob/main/doc/wms_demo.gif?raw=true)

### Playground app with imperative navigation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class AddWaterDescriptionModalPage {
required VoidCallback onNextPage,
required VoidCallback onClosed,
}) {
return WoltModalSheetPage.withSingleChild(
return WoltModalSheetPage(
heroImage: const Image(
image: AssetImage('lib/assets/images/add_water_description.png'),
fit: BoxFit.cover,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class WaterSettingsModalPage {
final buttonEnabledListener = ValueNotifier(false);
const pageTitle = 'Water settings';

return WoltModalSheetPage.withSingleChild(
return WoltModalSheetPage(
stickyActionBar: ValueListenableBuilder<bool>(
valueListenable: buttonEnabledListener,
builder: (_, isEnabled, __) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class GrindOrRejectModalPage {
required VoidCallback onStartGrinding,
required VoidCallback onClosed,
}) {
return WoltModalSheetPage.withSingleChild(
return WoltModalSheetPage(
stickyActionBar: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Column(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RejectOrderModalPage {
}) {
final buttonEnabledListener = ValueNotifier(false);

return WoltModalSheetPage.withSingleChild(
return WoltModalSheetPage(
stickyActionBar: ValueListenableBuilder<bool>(
valueListenable: buttonEnabledListener,
builder: (_, isEnabled, __) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';
class OfferRecommendationModalPage {
OfferRecommendationModalPage._();

static WoltModalSheetPage build({
static SliverWoltModalSheetPage build({
required VoidCallback onCoffeeOrderServed,
required VoidCallback onBackButtonPressed,
required VoidCallback onClosed,
Expand All @@ -18,7 +18,7 @@ class OfferRecommendationModalPage {
final tileCount = allRecommendations.length + 1;
final Set<ExtraRecommendation> selectedRecommendations = {};

return WoltModalSheetPage.withCustomSliverList(
return SliverWoltModalSheetPage(
stickyActionBar: ValueListenableBuilder<int>(
valueListenable: selectedItemCountListener,
builder: (_, count, __) {
Expand All @@ -45,42 +45,45 @@ class OfferRecommendationModalPage {
trailingNavBarWidget: WoltModalSheetCloseButton(onClosed: onClosed),
leadingNavBarWidget:
WoltModalSheetBackButton(onBackPressed: onBackButtonPressed),
sliverList: SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == 0) {
return const Padding(
padding: EdgeInsets.all(16.0),
child: ModalSheetContentText(
'Please select any extras the customer would be interested in purchasing',
),
);
} else {
final recommendation = allRecommendations[index - 1];
return Padding(
padding: EdgeInsets.fromLTRB(
16,
16,
16,
index == tileCount - 1 ? WoltElevatedButton.height * 2 : 0,
),
child: ExtraRecommendationTile(
recommendation: recommendation,
onPressed: (isSelected) {
isSelected
? selectedRecommendations.add(recommendation)
: selectedRecommendations.remove(recommendation);
selectedItemCountListener.value =
selectedRecommendations.length;
},
isSelected: selectedRecommendations.contains(recommendation),
),
);
}
},
childCount: tileCount,
mainContentSlivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) {
if (index == 0) {
return const Padding(
padding: EdgeInsets.all(16.0),
child: ModalSheetContentText(
'Please select any extras the customer would be interested in purchasing',
),
);
} else {
final recommendation = allRecommendations[index - 1];
return Padding(
padding: EdgeInsets.fromLTRB(
16,
16,
16,
index == tileCount - 1 ? WoltElevatedButton.height * 2 : 0,
),
child: ExtraRecommendationTile(
recommendation: recommendation,
onPressed: (isSelected) {
isSelected
? selectedRecommendations.add(recommendation)
: selectedRecommendations.remove(recommendation);
selectedItemCountListener.value =
selectedRecommendations.length;
},
isSelected:
selectedRecommendations.contains(recommendation),
),
);
}
},
childCount: tileCount,
),
),
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ServeOrOfferModalPage {
required VoidCallback onNextPage,
required VoidCallback onClosed,
}) {
return WoltModalSheetPage.withSingleChild(
return WoltModalSheetPage(
heroImage: const Image(
image: AssetImage('lib/assets/images/coffee_is_ready.png'),
fit: BoxFit.cover,
Expand Down
Binary file removed doc/example_app_with_theme_extensions.gif
Binary file not shown.
Binary file added doc/wms_demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
Loading