Skip to content

Commit

Permalink
Master detail controller (#358)
Browse files Browse the repository at this point in the history
* test YaruMasterDetailPage controller

* add controller to YaruMasterDetailPage
  • Loading branch information
d-loose committed Nov 3, 2022
1 parent cfb484c commit 766e2c3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
15 changes: 15 additions & 0 deletions lib/src/layouts/yaru_landscape_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class YaruLandscapeLayout extends StatefulWidget {
required this.pageMinWidth,
this.onLeftPaneWidthChange,
this.appBar,
this.controller,
});

/// The total number of pages.
Expand Down Expand Up @@ -55,6 +56,9 @@ class YaruLandscapeLayout extends StatefulWidget {
/// If provided, a second [AppBar] will be created right to it.
final PreferredSizeWidget? appBar;

/// An optional controller that can be used to navigate to a specific index.
final ValueNotifier<int>? controller;

@override
State<YaruLandscapeLayout> createState() => _YaruLandscapeLayoutState();
}
Expand All @@ -77,6 +81,17 @@ class _YaruLandscapeLayoutState extends State<YaruLandscapeLayout> {
super.initState();
_selectedIndex = widget.selectedIndex;
_leftPaneWidth = widget.leftPaneWidth;
widget.controller?.addListener(_controllerCallback);
}

@override
void dispose() {
widget.controller?.removeListener(_controllerCallback);
super.dispose();
}

void _controllerCallback() {
_onTap(widget.controller!.value);
}

void _onTap(int index) {
Expand Down
6 changes: 6 additions & 0 deletions lib/src/layouts/yaru_master_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class YaruMasterDetailPage extends StatefulWidget {
this.appBar,
this.initialIndex,
this.onSelected,
this.controller,
});

/// The total number of pages.
Expand Down Expand Up @@ -96,6 +97,9 @@ class YaruMasterDetailPage extends StatefulWidget {
/// Called when the user selects a page.
final ValueChanged<int?>? onSelected;

/// An optional controller that can be used to navigate to a specific index.
final ValueNotifier<int>? controller;

@override
_YaruMasterDetailPageState createState() => _YaruMasterDetailPageState();
}
Expand Down Expand Up @@ -141,6 +145,7 @@ class _YaruMasterDetailPageState extends State<YaruMasterDetailPage> {
pageBuilder: widget.pageBuilder,
onSelected: _setIndex,
appBar: widget.appBar,
controller: widget.controller,
);
} else {
return YaruLandscapeLayout(
Expand All @@ -155,6 +160,7 @@ class _YaruMasterDetailPageState extends State<YaruMasterDetailPage> {
pageMinWidth: widget.pageMinWidth,
onLeftPaneWidthChange: (panWidth) => _leftPaneWidth = panWidth,
appBar: widget.appBar,
controller: widget.controller,
);
}
},
Expand Down
16 changes: 16 additions & 0 deletions lib/src/layouts/yaru_portrait_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class YaruPortraitLayout extends StatefulWidget {
required this.pageBuilder,
required this.onSelected,
this.appBar,
this.controller,
});

final int length;
Expand All @@ -23,6 +24,9 @@ class YaruPortraitLayout extends StatefulWidget {

final PreferredSizeWidget? appBar;

/// An optional controller that can be used to navigate to a specific index.
final ValueNotifier<int>? controller;

@override
_YaruPortraitLayoutState createState() => _YaruPortraitLayoutState();
}
Expand All @@ -36,9 +40,21 @@ class _YaruPortraitLayoutState extends State<YaruPortraitLayout> {
@override
void initState() {
_selectedIndex = widget.selectedIndex;
widget.controller?.addListener(_controllerCallback);
super.initState();
}

@override
void dispose() {
widget.controller?.removeListener(_controllerCallback);
super.dispose();
}

void _controllerCallback() {
_navigator.popUntil((route) => route.isFirst);
_onTap(widget.controller!.value);
}

void _onTap(int index) {
widget.onSelected(index);
_navigator.push(pageRoute(index));
Expand Down
41 changes: 41 additions & 0 deletions test/pages/yaru_master_detail_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,47 @@ void main() {
variant: goldenVariant,
tags: 'golden',
);

testWidgets(
'controller',
(tester) async {
final variant = goldenVariant.currentValue!;
final controller = ValueNotifier<int>(0);
await tester.pumpScaffold(
YaruMasterDetailPage(
controller: controller,
leftPaneWidth: kYaruMasterDetailBreakpoint / 3,
length: 8,
appBar: AppBar(title: const Text('Master')),
tileBuilder: (context, index, selected) => YaruMasterTile(
leading: const Icon(YaruIcons.menu),
title: Text('Tile $index'),
),
pageBuilder: (context, index) => YaruDetailPage(
appBar: AppBar(
title: Text('Detail title $index'),
),
body: Center(child: Text('Detail body $index')),
),
),
themeMode: variant.themeMode,
size: Size(variant.value!, 480),
);

controller.value = 3;
await tester.pumpAndSettle();
if (variant.label.startsWith('portrait')) {
expect(find.text('Master'), findsNothing);
expect(find.text('Tile 3'), findsNothing);
} else if (variant.label.startsWith('landscape')) {
expect(find.text('Master'), findsOneWidget);
expect(find.text('Tile 3'), findsOneWidget);
}
expect(find.text('Detail title 3'), findsOneWidget);
expect(find.text('Detail body 3'), findsOneWidget);
},
variant: goldenVariant,
);
}

final goldenVariant = ValueVariant({
Expand Down

0 comments on commit 766e2c3

Please sign in to comment.