PavelPZ / riverpod_navigator

Simple but powerfull Flutter navigation with riverpod and Navigator 2.0
MIT License
27 stars 3 forks source link

Better Nested Navigation #26

Open TimWhiting opened 1 year ago

TimWhiting commented 1 year ago

Specifically, I'm interested in eventually having an interface where the nested navigators are configured via a riverpod family rather than using nested provider scopes. (This would solve some of the problems encountered on #20 I think). We could still provide a way to get a navigator without the family arguments as follows:

final familyNavigatorProvider = Provider.family((ref, args) => throw UnimplementedError());
final familyArgsProvider = Provider((ref) => throw UnimplementedError());
final navigatorProvider = Provider((ref) => 
      ref.watch(familyNavigatorProvider(ref.watch(familyArgsProvider))), 
      dependencies: [familyArgsProvider, familyNavigatorProvider]);

Then in the nested provider scope you just override the familyArgsProvider.

This allows you to make some behavior nested, while still having most of the navigator stuff global.

For example deep links and the TypePath should ideally be global, however, the logic for navigating within the tabs should be scoped. Sometimes you'd like actions from outside the tab to cause a change within the tab, or reflect the current tab (especially on Desktop / web), which is why making a family provider makes the most sense which allows some access to nested navigator states from outside the RiverpodScope that contains the particular nested navigator. So a more refined sort of design might look like:

final globalNavigatorProvider = Provider((ref) => someDefaultImplementation);
final nestedNavigatorProvider = Provider.family((ref, args) => 
    ref.read(globalNavigatorProvider).nestedState(args));
final familyArgsProvider = Provider((ref) => throw UnimplementedError());
final navigatorProvider = Provider((ref) => 
           ref.watch(nestedNavigatorProvider(ref.watch(familyArgsProvider))), 
           dependencies: [familyArgsProvider, nestedNavigatorProvider]);