Skip to content

Commit

Permalink
YaruCompactLayout: replace "page item" with indexed builders (#250)
Browse files Browse the repository at this point in the history
Same as #248 but for the compact layout.
  • Loading branch information
jpnurmi committed Oct 7, 2022
1 parent 8c8ea5a commit c2861bf
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 26 deletions.
9 changes: 8 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,20 @@ class _CompactPage extends StatelessWidget {
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;

final pageItems = [configItem] + examplePageItems;

return YaruCompactLayout(
style: width > 1000
? YaruNavigationRailStyle.labelledExtended
: width > 500
? YaruNavigationRailStyle.labelled
: YaruNavigationRailStyle.compact,
pageItems: [configItem] + examplePageItems,
length: pageItems.length,
iconBuilder: (context, index, selected) =>
pageItems[index].iconBuilder(context, selected),
titleBuilder: (context, index, selected) =>
pageItems[index].titleBuilder(context),
pageBuilder: (context, index) => pageItems[index].builder(context),
);
}
}
Expand Down
37 changes: 27 additions & 10 deletions lib/src/pages/layouts/yaru_compact_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,36 @@ import 'package:flutter/material.dart';
import 'package:yaru/yaru.dart';
import '../../../yaru_widgets.dart';

typedef YaruCompactLayoutBuilder = Widget Function(
BuildContext context,
int index,
bool selected,
);

/// A page layout which use a [YaruNavigationRail] on left for page navigation
class YaruCompactLayout extends StatefulWidget {
const YaruCompactLayout({
super.key,
required this.pageItems,
required this.length,
required this.iconBuilder,
required this.titleBuilder,
required this.pageBuilder,
this.style = YaruNavigationRailStyle.compact,
this.initialIndex = 0,
this.onSelected,
});

/// A list of page destinations
final List<YaruPageItem> pageItems;
/// The total number of pages.
final int length;

/// A builder that is called for each page to build its icon.
final YaruCompactLayoutBuilder iconBuilder;

/// A builder that is called for each page to build its title.
final YaruCompactLayoutBuilder titleBuilder;

/// A builder that is called for each page to build its content.
final IndexedWidgetBuilder pageBuilder;

/// Define the navigation rail style, see [YaruNavigationRailStyle]
final YaruNavigationRailStyle style;
Expand Down Expand Up @@ -78,15 +96,14 @@ class _YaruCompactLayoutState extends State<YaruCompactLayout> {
style: widget.style,
selectedIndex: _index,
onDestinationSelected: (index) {
if (widget.pageItems[index].onTap != null) {
widget.pageItems[index].onTap!.call(context);
}
setState(() {
_index = index;
widget.onSelected?.call(index);
});
},
destinations: widget.pageItems,
length: widget.length,
iconBuilder: widget.iconBuilder,
titleBuilder: widget.titleBuilder,
),
),
),
Expand All @@ -107,9 +124,9 @@ class _YaruCompactLayoutState extends State<YaruCompactLayout> {
pages: [
MaterialPage(
key: ValueKey(_index),
child: widget.pageItems.length > _index
? widget.pageItems[_index].builder(context)
: widget.pageItems[0].builder(context),
child: widget.length > _index
? widget.pageBuilder(context, _index)
: widget.pageBuilder(context, 0),
),
],
onPopPage: (route, result) => route.didPop(result),
Expand Down
38 changes: 23 additions & 15 deletions lib/src/pages/layouts/yaru_navigation_rail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,26 @@ const _kSelectedIconAnimationDuration = Duration(milliseconds: 250);
class YaruNavigationRail extends StatelessWidget {
const YaruNavigationRail({
super.key,
required this.destinations,
required this.length,
required this.iconBuilder,
required this.titleBuilder,
required this.selectedIndex,
required this.onDestinationSelected,
this.style = YaruNavigationRailStyle.compact,
}) : assert(destinations.length >= 2),
}) : assert(length >= 2),
assert(
selectedIndex == null ||
(0 <= selectedIndex && selectedIndex < destinations.length),
(0 <= selectedIndex && selectedIndex < length),
);

/// Defines the appearance of the button items that are arrayed within the
/// navigation rail.
///
/// The value must be a list of two or more [YaruPageItem]
/// values.
final List<YaruPageItem> destinations;
/// The total number of pages.
final int length;

/// A builder that is called for each page to build its icon.
final YaruCompactLayoutBuilder iconBuilder;

/// A builder that is called for each page to build its title.
final YaruCompactLayoutBuilder titleBuilder;

/// The index into [destinations] for the current selected
/// [YaruPageItem] or null if no destination is selected.
Expand All @@ -56,11 +60,12 @@ class YaruNavigationRail extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 5),
child: Column(
children: <Widget>[
for (int i = 0; i < destinations.length; i += 1)
for (int i = 0; i < length; i += 1)
_YaruNavigationRailItem(
i,
i == selectedIndex,
destinations[i],
iconBuilder,
titleBuilder,
onDestinationSelected,
style,
)
Expand All @@ -74,14 +79,16 @@ class _YaruNavigationRailItem extends StatefulWidget {
const _YaruNavigationRailItem(
this.index,
this.selected,
this.destination,
this.iconBuilder,
this.titleBuilder,
this.onDestinationSelected,
this.style,
);

final int index;
final bool selected;
final YaruPageItem destination;
final YaruCompactLayoutBuilder iconBuilder;
final YaruCompactLayoutBuilder titleBuilder;
final ValueChanged<int>? onDestinationSelected;
final YaruNavigationRailStyle style;

Expand Down Expand Up @@ -199,8 +206,9 @@ class _YaruNavigationRailItemState extends State<_YaruNavigationRailItem> {
vertical: 2,
horizontal: 10,
),
child: widget.destination.iconBuilder(
child: widget.iconBuilder(
context,
widget.index,
widget.selected,
),
),
Expand All @@ -216,7 +224,7 @@ class _YaruNavigationRailItemState extends State<_YaruNavigationRailItem> {
}

Widget _buildLabel(BuildContext context) {
var label = widget.destination.titleBuilder(context);
var label = widget.titleBuilder(context, widget.index, widget.selected);

if (label is YaruPageItemTitle) {
label = DefaultTextStyle.merge(
Expand Down

0 comments on commit c2861bf

Please sign in to comment.