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

Expose page list, current page, and getters for isAtLastPage / isAtFirstPage #299

Merged
merged 2 commits into from
Aug 11, 2024
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
1 change: 1 addition & 0 deletions demo_ui_components/lib/demo_ui_components.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export 'src/button/wolt_modal_sheet_back_button.dart';
export 'src/button/wolt_circular_elevated_button.dart';
export 'src/button/wolt_modal_sheet_close_or_next_sab.dart';
export 'src/button/wolt_modal_sheet_close_button.dart';
export 'src/button/wolt_elevated_button.dart';
export 'src/colors/wolt_colors.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:demo_ui_components/demo_ui_components.dart';
import 'package:flutter/material.dart';
import 'package:wolt_modal_sheet/wolt_modal_sheet.dart';

class WoltModalSheetCloseOrNextSab extends StatelessWidget {
const WoltModalSheetCloseOrNextSab({
this.colorName = WoltColorName.blue,
super.key,
});

final WoltColorName colorName;

@override
Widget build(BuildContext context) {
final totalPageCount = WoltModalSheet.of(context).pages.length;
final currentPageIndex = WoltModalSheet.of(context).currentPageIndex;
final bool isAtLastPage = WoltModalSheet.of(context).isAtLastPage;
return WoltElevatedButton(
onPressed: isAtLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
child: Text(isAtLastPage
? "Close"
: "Next (${currentPageIndex + 1}/$totalPageCount)"),
);
}
}
18 changes: 15 additions & 3 deletions lib/src/wolt_modal_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,21 @@ class WoltModalSheet<T> extends StatefulWidget {
class WoltModalSheetState extends State<WoltModalSheet> {
List<SliverWoltModalSheetPage> _pages = [];

/// The list of pages in the modal sheet.
List<SliverWoltModalSheetPage> get pages => _pages;

/// The current page displayed in the modal sheet.
SliverWoltModalSheetPage get currentPage => _pages[_currentPageIndex];

/// The index of the currently displayed page in the in-modal navigation stack.
int get currentPageIndex => _currentPageIndex;

/// Returns true if the current page is the first page in the stack.
bool get isAtFirstPage => _currentPageIndex == 0;

/// Returns true if the current page is the last page in the stack.
bool get isAtLastPage => _currentPageIndex == _pages.length - 1;

final GlobalKey _childKey = GlobalKey(debugLabel: 'Modal sheet child');

static const barrierLayoutId = 'barrierLayoutId';
Expand Down Expand Up @@ -888,9 +903,6 @@ class WoltModalSheetState extends State<WoltModalSheet> {
}
return false;
}

/// The index of the currently displayed page in the in-modal navigation stack.
int get currentPageIndex => _currentPageIndex;
}

class _WoltModalMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
Expand Down
19 changes: 8 additions & 11 deletions playground/lib/home/pages/root_sheet_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,14 @@ class RootSheetPage {
static List<SliverWoltModalSheetPage> _constructAllPagesAfterRootPage(
BuildContext context) =>
[
SheetPageWithForcedMaxHeight.build(
Theme.of(context).brightness,
isLastPage: false,
),
SheetPageWithHeroImage.build(isLastPage: false),
SheetPageWithLazyList.build(isLastPage: false),
SheetPageWithTextField.build(isLastPage: false),
SheetPageWithMinHeight.build(isLastPage: false),
SheetPageWithInAppNavigation.build(isLastPage: false),
SheetPageWithCustomTopBar.build(isLastPage: false),
SheetPageWithNoPageTitleNoTopBar.build(isLastPage: false),
SheetPageWithForcedMaxHeight.build(Theme.of(context).brightness),
SheetPageWithHeroImage.build(),
SheetPageWithLazyList.build(),
SheetPageWithTextField.build(),
SheetPageWithMinHeight.build(),
SheetPageWithInAppNavigation.build(),
SheetPageWithCustomTopBar.build(),
SheetPageWithNoPageTitleNoTopBar.build(),
SheetPageWithUpdatePage.build(context, isLastPage: true),
];

Expand Down
16 changes: 4 additions & 12 deletions playground/lib/home/pages/sheet_page_with_custom_top_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,14 @@ class SheetPageWithCustomTopBar {
static const ModalPageName pageId = ModalPageName.customTopBar;

/// Builds and returns a [WoltModalSheetPage] with custom top bar.
static WoltModalSheetPage build({bool isLastPage = true}) {
static WoltModalSheetPage build() {
return WoltModalSheetPage(
id: pageId,
backgroundColor: WoltColors.blue8,
forceMaxHeight: true,
stickyActionBar: Padding(
padding: const EdgeInsets.all(16.0),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
colorName: WoltColorName.blue,
child: Text(isLastPage ? "Close" : "Next"),
);
}),
stickyActionBar: const Padding(
padding: EdgeInsets.all(16.0),
child: WoltModalSheetCloseOrNextSab(),
),
trailingNavBarWidget: const WoltModalSheetCloseButton(),
isTopBarLayerAlwaysVisible: false,
Expand Down
14 changes: 3 additions & 11 deletions playground/lib/home/pages/sheet_page_with_forced_max_height.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,9 @@ class SheetPageWithForcedMaxHeight {
: WoltColors.green64,
hasSabGradient: false,
forceMaxHeight: true,
stickyActionBar: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
colorName: WoltColorName.green,
child: Text(isLastPage ? "Close" : "Next"),
);
}),
stickyActionBar: const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(colorName: WoltColorName.green),
),
pageTitle: const ModalSheetTitle(
'Page with forced max height and background color'),
Expand Down
15 changes: 4 additions & 11 deletions playground/lib/home/pages/sheet_page_with_hero_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,16 @@ class SheetPageWithHeroImage {

static const ModalPageName pageId = ModalPageName.heroImage;

static WoltModalSheetPage build({bool isLastPage = true}) {
static WoltModalSheetPage build() {
return WoltModalSheetPage(
id: pageId,
heroImage: const Image(
image: AssetImage('lib/assets/images/hero_image.jpg'),
fit: BoxFit.cover,
),
stickyActionBar: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
child: Text(isLastPage ? "Close" : "Next"),
);
}),
stickyActionBar: const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(),
),
pageTitle: const ModalSheetTitle('Page with a hero image'),
leadingNavBarWidget: const WoltModalSheetBackButton(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class SheetPageWithInAppNavigation {

static const ModalPageName pageId = ModalPageName.inAppNavigation;

static WoltModalSheetPage build({bool isLastPage = true}) {
static WoltModalSheetPage build() {
return WoltModalSheetPage(
id: pageId,
leadingNavBarWidget: const WoltModalSheetBackButton(),
Expand Down
19 changes: 5 additions & 14 deletions playground/lib/home/pages/sheet_page_with_lazy_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,16 @@ class SheetPageWithLazyList {

static const ModalPageName pageId = ModalPageName.lazyLoadingList;

static SliverWoltModalSheetPage build({bool isLastPage = true}) {
static SliverWoltModalSheetPage build() {
final colors = allMaterialColors;
const titleText = 'Material Colors';
const heroImageHeight = 200.0;
return SliverWoltModalSheetPage(
id: pageId,
stickyActionBar: isLastPage
? null
: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
child: const Text("Next"),
);
}),
),
stickyActionBar: const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(),
),
topBarTitle: const ModalSheetTopBarTitle(titleText),
heroImageHeight: heroImageHeight,
heroImage: const Stack(
Expand Down
15 changes: 4 additions & 11 deletions playground/lib/home/pages/sheet_page_with_min_height.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,13 @@ class SheetPageWithMinHeight {

static const ModalPageName pageId = ModalPageName.minHeight;

static WoltModalSheetPage build({bool isLastPage = true}) {
static WoltModalSheetPage build() {
return WoltModalSheetPage(
id: pageId,
hasTopBarLayer: false,
stickyActionBar: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
child: Text(isLastPage ? "Close" : "Next"),
);
}),
stickyActionBar: const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(),
),
child: const Padding(
padding: EdgeInsets.only(bottom: 100, top: 16, left: 16, right: 16),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,9 @@ class SheetPageWithNoPageTitleNoTopBar {
id: pageId,
backgroundColor: WoltColors.green8,
forceMaxHeight: true,
stickyActionBar: Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Builder(builder: (context) {
return WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
colorName: WoltColorName.green,
child: Text(isLastPage ? "Close" : "Next"),
);
}),
stickyActionBar: const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(colorName: WoltColorName.green),
),
hasTopBarLayer: false,
child: const Padding(
Expand Down
3 changes: 2 additions & 1 deletion playground/lib/home/pages/sheet_page_with_text_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class SheetPageWithTextField {

static const ModalPageName pageId = ModalPageName.textField;

static WoltModalSheetPage build({bool isLastPage = true}) {
static WoltModalSheetPage build() {
ValueNotifier<bool> isButtonEnabledNotifier = ValueNotifier(false);
final textEditingController = TextEditingController();
textEditingController.addListener(() {
Expand All @@ -19,6 +19,7 @@ class SheetPageWithTextField {
stickyActionBar: ValueListenableBuilder<bool>(
valueListenable: isButtonEnabledNotifier,
builder: (context, isEnabled, __) {
final isLastPage = WoltModalSheet.of(context).isAtLastPage;
return Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltElevatedButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,9 @@ class SheetPageWithUpdatePage {
enableDrag: enableDrag,
hasTopBarLayer: hasTopBarLayer,
stickyActionBar: Builder(builder: (context) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltElevatedButton(
onPressed: isLastPage
? Navigator.of(context).pop
: WoltModalSheet.of(context).showNext,
colorName: WoltColorName.green,
child: Text(isLastPage ? "Close" : "Next"),
),
return const Padding(
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: WoltModalSheetCloseOrNextSab(colorName: WoltColorName.green),
);
}),
isTopBarLayerAlwaysVisible: hasTopBarLayer,
Expand Down
40 changes: 40 additions & 0 deletions test/wolt_modal_sheet_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,45 @@ void main() {
equals(const Size(524.0, 86.0)),
);
});

testWidgets('getters return the correct page, page index and list of pages',
(tester) async {
const page1Id = 'page1';
const page2Id = 'page2';
final page1 =
WoltModalSheetPage(child: const Text('Page 1'), id: page1Id);
final page2 =
WoltModalSheetPage(child: const Text('Page 2'), id: page2Id);

await tester.pumpWidget(buildSheetWithShow(
pageListBuilder: (_) => [page1, page2],
));

await tester.tap(find.text('Open sheet'));
await tester.pumpAndSettle();

final WoltModalSheetState modal =
WoltModalSheet.of(tester.element(find.text('Page 1')));

expect(modal.pages.length, 2);
expect(modal.pages[0].id, page1Id);
expect(modal.pages[1].id, page2Id);
expect(modal.currentPage, page1);
expect(modal.currentPageIndex, 0);
expect(modal.isAtFirstPage, isTrue);
expect(modal.isAtLastPage, isFalse);

// Go to next page
modal.showNext();
await tester.pumpAndSettle();

expect(modal.pages.length, 2);
expect(modal.pages[0].id, page1Id);
expect(modal.pages[1].id, page2Id);
expect(modal.currentPage, page2);
expect(modal.currentPageIndex, 1);
expect(modal.isAtFirstPage, isFalse);
expect(modal.isAtLastPage, isTrue);
});
});
}