Skip to content

Commit

Permalink
PaneItems "body" attribute not longer required. Related with bdlukaa#…
Browse files Browse the repository at this point in the history
  • Loading branch information
henry2man committed Nov 4, 2022
1 parent ecbdbd5 commit d21a1ac
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 15 deletions.
6 changes: 3 additions & 3 deletions lib/src/controls/navigation/navigation_view/pane_items.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class PaneItem extends NavigationPaneItem {
/// Creates a pane item.
PaneItem({
required this.icon,
required this.body,
this.body,
this.title,
this.trailing,
this.infoBadge,
Expand Down Expand Up @@ -66,7 +66,7 @@ class PaneItem extends NavigationPaneItem {
final Widget? trailing;

/// The body of the view attached to this tab
final Widget body;
final Widget? body;

/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;
Expand Down Expand Up @@ -538,7 +538,7 @@ class PaneItemExpander extends PaneItem {
PaneItemExpander({
required super.icon,
required this.items,
required super.body,
super.body,
super.title,
super.infoBadge,
super.trailing = kDefaultTrailing,
Expand Down
55 changes: 43 additions & 12 deletions lib/src/controls/navigation/navigation_view/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const double _kDefaultAppBarHeight = 50.0;
/// rearrange, open, or close new tabs.
class NavigationView extends StatefulWidget {
/// Creates a navigation view.
const NavigationView({
NavigationView({
Key? key,
this.appBar,
this.pane,
Expand All @@ -45,12 +45,41 @@ class NavigationView extends StatefulWidget {
this.transitionBuilder,
this.paneBodyBuilder,
}) : assert(
(pane != null && content == null) ||
(pane == null && content != null),
'Either pane or content must be provided',
(content == null &&
_checkAllPaneItemHasBodies(pane?.items) &&
(pane?.footerItems == null ||
_checkAllPaneItemHasBodies(pane?.footerItems))) ||
(content != null &&
(pane?.items == null ||
_checkAllPaneItemHasNotBodies(pane?.items)) &&
(pane?.footerItems == null ||
_checkAllPaneItemHasNotBodies(pane?.footerItems))),
'Either content or PaneItems with bodies must be provided',
),
super(key: key);

static bool _checkAllPaneItemHasBodies(List<NavigationPaneItem>? items) {
var allPaneItemHaveBodies = items != null &&
(items.whereType<PaneItem>().every((element) {
return element.body != null;
})) &&
(items.whereType<PaneItemExpander>().every((element) {
return _checkAllPaneItemHasBodies(element.items);
}));
return allPaneItemHaveBodies;
}

static bool _checkAllPaneItemHasNotBodies(List<NavigationPaneItem>? items) {
var allPaneItemHasNotBodies = items != null &&
((items.whereType<PaneItem>().every((element) {
return element.body == null;
}))) &&
(items.whereType<PaneItemExpander>().every((element) {
return _checkAllPaneItemHasNotBodies(element.items);
}));
return allPaneItemHasNotBodies;
}

/// The app bar of the app.
final NavigationAppBar? appBar;

Expand Down Expand Up @@ -156,6 +185,7 @@ class NavigationViewState extends State<NavigationView> {
///
/// Always false if the current display mode is not minimal.
bool get minimalPaneOpen => _minimalPaneOpen;

set minimalPaneOpen(bool open) {
if (displayMode == PaneDisplayMode.minimal) {
setState(() => _minimalPaneOpen = open);
Expand Down Expand Up @@ -365,12 +395,14 @@ class NavigationViewState extends State<NavigationView> {
final body = _NavigationBody(
itemKey: ValueKey(pane.selected ?? -1),
transitionBuilder: widget.transitionBuilder,
child: paneBodyBuilder != null
? paneBodyBuilder(
pane.selected != null ? pane.selectedItem.body : null)
: (pane.selected != null
? pane.selectedItem.body
: const SizedBox.shrink()),
child: widget.content != null
? widget.content!
: (paneBodyBuilder != null
? paneBodyBuilder(
pane.selected != null ? pane.selectedItem.body! : null)
: (pane.selected != null
? pane.selectedItem.body!
: const SizedBox.shrink())),
);
if (pane.customPane != null) {
paneResult = Builder(builder: (context) {
Expand Down Expand Up @@ -440,7 +472,6 @@ class NavigationViewState extends State<NavigationView> {
]);
break;
case PaneDisplayMode.compact:

// Ensure the overlay state is correct
_compactOverlayOpen = PageStorage.of(context)?.readState(
context,
Expand Down Expand Up @@ -674,7 +705,7 @@ class NavigationViewState extends State<NavigationView> {
Expanded(child: widget.content!),
]);
} else {
throw 'Either pane or content must be provided';
throw 'Either content or PaneItems with bodies must be provided';
}
return Mica(
backgroundColor: theme.backgroundColor,
Expand Down
184 changes: 184 additions & 0 deletions test/navigation_view_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,188 @@ void main() {
);
},
);

testWidgets(
'Either content or PaneItems with bodies - case "content", no items',
(WidgetTester tester) async {
await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
content: const Text("ContentWidget"),
),
),
),
);

expect(find.text('ContentWidget'), findsOneWidget);
});

testWidgets(
'Either content or PaneItems with bodies - case "content", items with no bodies',
(WidgetTester tester) async {
await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
content: const Text("ContentWidget"),
pane: NavigationPane(selected: 0, items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1"),
),
PaneItemExpander(
icon: const Icon(FluentIcons.add),
title: const Text("Expander 1"),
items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1-1"),
),
])
]),
),
),
),
);

expect(find.text('ContentWidget'), findsOneWidget);
expect(find.text('Item1-1'), findsNothing);
expect(find.text('Item1-1'), findsNothing);
});

testWidgets(
'Either content or PaneItems with bodies - case "content", items with bodies',
(WidgetTester tester) async {
expect(
() async => await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
content: const Text("ContentWidget"),
pane: NavigationPane(selected: 0, items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1"),
body: const Text("Body Item1"),
),
PaneItemExpander(
icon: const Icon(FluentIcons.add),
title: const Text("Expander 1"),
body: const Text("Body Expander 1"),
items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1-1"),
body: const Text("Body Item1-1"),
),
])
]),
),
),
),
),
throwsAssertionError);
});

testWidgets(
'Either content or PaneItems with bodies - case without "content", items without bodies',
(WidgetTester tester) async {
expect(
() async => await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
pane: NavigationPane(selected: 0, items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1"),
),
PaneItemExpander(
icon: const Icon(FluentIcons.add),
title: const Text("Expander 1"),
body: const Text("Body Expander 1"),
items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1-1"),
),
])
]),
),
),
),
),
throwsAssertionError);
});

testWidgets(
'Either content or PaneItems with bodies - case without "content", items with bodies',
(WidgetTester tester) async {
await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
pane: NavigationPane(selected: 0, items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1"),
body: const Text("Body Item1"),
),
PaneItemExpander(
icon: const Icon(FluentIcons.add),
title: const Text("Expander 1"),
body: const Text("Body Expander 1"),
items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1-1"),
body: const Text("Body Item1-1"),
),
])
]),
),
),
),
);

expect(find.text('Body Item1'), findsOneWidget);
expect(find.text('Body Expander 1'), findsNothing);
expect(find.text('Body Item1-1'), findsNothing);
});

testWidgets(
'Either content or PaneItems with bodies - case without "content", items with bodies, expander selected',
(WidgetTester tester) async {
await tester.pumpWidget(
FluentApp(
home: FluentApp(
home: NavigationView(
pane: NavigationPane(selected: 1, items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1"),
body: const Text("Body Item1"),
),
PaneItemExpander(
icon: const Icon(FluentIcons.add),
title: const Text("Expander 1"),
body: const Text("Body Expander 1"),
items: [
PaneItem(
icon: const Icon(FluentIcons.add),
title: const Text("Item1-1"),
body: const Text("Body Item1-1"),
),
])
]),
),
),
),
);

expect(find.text('Body Item1'), findsNothing);
expect(find.text('Body Expander 1'), findsOneWidget);
expect(find.text('Body Item1-1'), findsNothing);
});
}

0 comments on commit d21a1ac

Please # to comment.