yana 0.1.0 yana: ^0.1.0 copied to clipboard
Yet Another Navigation Approach
YANA - Yet Another Navigation Approach #
YANA provides a convenient way to use declarative state-driven testable navigation. It is Navigator 2.0 without rough edges.
Declarative #
The declarative approach separates navigation from UI and business logic. No more Navigator.push
and Navigator.pop
in surprising places.
TreeNavNode buildNavigation(state) => firstOf<AppState>(
when: always,
pages: [
_loginFlow(),
_authedFlow(),
],
)(state);
_loginFlow() => anyOf<AppState>(
when: hasNoUser,
pages: [
materialPage(
when: always,
name: ScreenKeys.authorization,
builder: (_) => const LoginScreen(),
onPopPage: () => false,
)
],
);
_authedFlow() => anyOf<AppState>(
when: hasUser,
pages: [
materialPage(
when: always,
name: ScreenKeys.books,
builder: (_) => const BooksScreen(),
onPopPage: () => false,
),
materialPage(
when: hasSelectedBook,
name: ScreenKeys.bookDetails,
builder: (_) => const BookDetailsScreen(),
onPopPage: () => false,
),
],
);
State-driven #
Always predictable screens based on your state. Thanks to Navigator 2.0!
class AppRouterDelegate {
TreeNavNode _navNode;
StreamSubscription<AppState> _storeSubscription;
AppRouterDelegate(store) {
_storeSubscription = store.onChange.listen((event) {
_navNode = buildNavigation(store);
notifyListeners();
});
}
@override
Widget build(BuildContext context) {
final node = _navNode;
final pages = [...node.pages];
return Navigator(
key: navigatorKey,
pages: pages,
onPopPage: (route, result) {
if (node.onPopPage!(route, result)) {
return route.didPop(result);
}
return false;
},
);
}
}
Testable #
Simple unit tests guarantee that each state is translated to the expected navigation configuration. Check tests in demos for details.
var pages = buildNavigation(state).pages;
expect(pages, hasLength(1));
expect(pages[0].name, equals(ScreenKeys.authorization));
state.loggedIn = true;
pages = buildNavigation(state).pages;
expect(pages, hasLength(1));
expect(pages[0].name, equals(ScreenKeys.books));
Getting Started #
- Add
yana
package to yourpubspec.yaml
- Define
buildNavigation
function - Create your
AppRouterDelegate
that triggersbuildNavigation
for required state changes - Done!
Check examples with redux and provider state management.
Advanced #
How to customize a presentation of a page? #
Check implementation popUpDialog
for inspiration.
Status #
- Production-ready. The library has been used in multiple applications since 2019.
- You can expect breaking changes before the package reaches 1.0.0 based on community feedback.