Skip to content

Advanced Router Navigation library for Flutter

License

Notifications You must be signed in to change notification settings

buzzware/pelican

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pelican - Navigation Router for Flutter

The Pelican is a large bird that navigates around Australia and South East Asia https://en.wikipedia.org/wiki/Australian_pelican

640px-Pelecanus_conspicillatus_-Australia_-8

By Geoff Penaluna - originally posted to Flickr as Pelican, CC BY 2.0, https://commons.wikimedia.org/w/index.php?curid=8442187

Why another Flutter router ?

I have spent a lot of time with routing in other app development environments, like Rails, Ember and Xamarin and researched Flutter packages and the Navigator 2.0 API. None of the available options met my core requirements, being :

  • async everything
  • expressive route table of segments mapped to pages, and full path redirects
  • no code generation
  • parameters and options per segment. Parameters affect routing, options do not.
  • two-way serialization between the page stack and the route (like Rails and Ember.js)
  • defined segments, dynamically constructed route (of segments)
  • no heirarchy in the definition of segments means segments/pages can be dynamically constructed in any order within a route/stack
  • full-route (any string) redirects with arbitrary logic. Redirect to any path, and redirect again ad infinitum
  • match and handle deep links with a redirect handler
  • symbolic routes - for example you can call router.goto("/post_login_triage") and then define async triage logic for that path to determine what path or page to redirect to next
  • path redirects can return a new path, pass to the next match, or cancel routing
  • path redirects can be matched as an exact string or a RegExp
  • segment redirects ("aliases") - future feature
  • ability to goto any route, and intelligently create or destroy pages as required
  • a stack of pages, not a history of routes. Back = pop(), or you can goto any route you've stored.
  • uses Navigator 2.0 as it was intended

I make no claim of the completeness or quality of this repository, but I use it in production, and develop it as required by the application. Some intended features may not be properly implemented yet.

The Less mature DotNet version (used with Avalonia) https://github.com/buzzware/PelicanDotNet

Acknowledgements

Documentation

See example app https://github.com/buzzware/pelican/tree/main/example

Segment Paths

  • A segment path looks like

<page>[;(param[=value])*][+](option[=value])*

Examples

Book;id=1+color=red

Books

Books+search=hardy

  • A route path begins with a /, followed by zero or more segments, separated by /'s

For example :

/Home/Books+search=hardy

"search" is an option that allows values to be passed without affecting routing

/Home/Books+search=hardy/Settings

/Home/Books+search=hardy/Book;id=1

"id" is a parameter that can affect routing

/Home/Books+search=hardy/Book;id=1/Settings

The "Settings" page can be shown anywhere on the stack, and even multiple times - we don't need to define routes for all possible stack routes

RouteTable

This specifies :

  • a builder for each segment. The segment definition string optionally defines parameters and options and their order. The builder uses the passed context object (_) for context information and performing actions
  • a handler for each redirect. The entire route path is matched against the provided redirects by path or RegExp, and then a handler returns the action that should be taken.
PelicanRouter router = PelicanRouter(
  RouteTable(
    {
      'books': (_) async {
        return _.page(
          BooksListScreen(
            books: books,
            onTapped: (book) {
              router.push("book;id=${book.id}");
            }
          )
        );
      },
      'book;id+color;size': (_) async {
        var book = books.firstWhere((b) => b.id==_.segment!.params['id']);
        return _.page(BookDetailsScreen(book: book));
      }
    },
    redirects: [
      PageRedirect('/', (_) async => _.to('/books')),
      PageRedirect.fromPattern(RegExp('http'), (_) async => ... ),  // handle deep links
    ]
  ),
);

Navigation

Examples :

router.push("book;id=${book.id}")

router.pop()

router.goto('/login')

About

Advanced Router Navigation library for Flutter

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published