Giter Site home page Giter Site logo

slovnicki / beamer Goto Github PK

View Code? Open in Web Editor NEW
584.0 9.0 128.0 37.45 MB

A routing package built on top of Router and Navigator's pages API, supporting arbitrary nested navigation, guards and more.

License: MIT License

Dart 97.38% Kotlin 0.04% Swift 0.13% Objective-C 0.01% HTML 2.44%
navigator router flutter-router flutter

beamer's Introduction

beamer's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beamer's Issues

Deep Location problem

If I going deeper in routing, and would like to go back with APP BAR left arrow - the URL doen’t change.
However - I press the back button in browser - URL is changing.

import 'package:flutter/material.dart';
import 'package:beamer/beamer.dart';

// SCREENS
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () => context.beamTo(BooksLocation()),
          child: Text('Go to books location'),
        ),
      ),
    );
  }
}

const List<Map<String, String>> books = [
  {
    'id': '1',
    'title': 'Stranger in a Strange Land',
    'author': 'Robert A. Heinlein',
  },
  {
    'id': '2',
    'title': 'Foundation',
    'author': 'Isaac Asimov',
  },
  {
    'id': '3',
    'title': 'Fahrenheit 451',
    'author': 'Ray Bradbury',
  },
];

class BooksScreen extends StatelessWidget {
  BooksScreen({this.titleQuery = ''});

  final String titleQuery;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Books'),
      ),
      body: ListView(
        children: books
            .where((book) =>
                book['title'].toLowerCase().contains(titleQuery.toLowerCase()))
            .map((book) => ListTile(
                  title: Text(book['title']),
                  subtitle: Text(book['author']),
                  onTap: () => Beamer.of(context).beamTo(
                    BooksLocation.withParameters(
                      path: {'id': book['id']},
                    ),
                  ),
                ))
            .toList(),
      ),
    );
  }
}

class BookDetailsScreen extends StatelessWidget {
  BookDetailsScreen({
    this.book,
  });

  final Map<String, String> book;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(book['title']),
      ),
      body: Column(
        children: [
          Text('Author: ${book['author']}'),
          SizedBox(
            height: 50.0,
          ),
          ElevatedButton(
            child: Text('GO DEEPER -> '),
            onPressed: () {
              Beamer.of(context).beamTo(
                BooksThirdLocation.withParameters(
                  path: {'id': book['id']},
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

class BookThirdScreen extends StatelessWidget {
  BookThirdScreen({
    this.book,
  });

  final Map<String, String> book;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(book['title']),
      ),
      body: Text('Third screen of book nr. ${book['author']}'),
    );
  }
}

// LOCATIONS
class HomeLocation extends BeamLocation {
  @override
  List<Page> get pages => [
        BeamPage(
          key: ValueKey('home'),
          page: HomeScreen(),
        ),
      ];

  @override
  String get pathBlueprint => '/';
}

class BooksLocation extends BeamLocation {
  BooksLocation() : super();

  BooksLocation.withParameters({
    Map<String, String> path,
    Map<String, String> query,
  }) : super.withParameters(path: path, query: query);

  @override
  List<Page> get pages => [
        ...HomeLocation().pages,
        BeamPage(
          key: ValueKey('books-${queryParameters['title'] ?? ''}'),
          page: BooksScreen(
            titleQuery: queryParameters['title'] ?? '',
          ),
        ),
        if (pathParameters.containsKey('id'))
          BeamPage(
            key: ValueKey('book-${pathParameters['id']}'),
            page: BookDetailsScreen(
              book: books
                  .firstWhere((book) => book['id'] == pathParameters['id']),
            ),
          ),
      ];

  @override
  String get pathBlueprint => '/books/:id';
}

class BooksThirdLocation extends BeamLocation {
  BooksThirdLocation() : super();

  BooksThirdLocation.withParameters({
    Map<String, String> path,
    Map<String, String> query,
  }) : super.withParameters(path: path, query: query);

  @override
  List<Page> get pages => [
        ...HomeLocation().pages,
        BeamPage(
          key: ValueKey('books-${queryParameters['title'] ?? ''}'),
          page: BooksScreen(
            titleQuery: queryParameters['title'] ?? '',
          ),
        ),
        if (pathParameters.containsKey('id'))
          BeamPage(
            key: ValueKey('book-${pathParameters['id']}'),
            page: BookDetailsScreen(
              book: books
                  .firstWhere((book) => book['id'] == pathParameters['id']),
            ),
          ),
        if (pathParameters.containsKey('id'))
          BeamPage(
            key: ValueKey('book-deeper-${pathParameters['id']}'),
            page: BookThirdScreen(
              book: books
                  .firstWhere((book) => book['id'] == pathParameters['id']),
            ),
          ),
      ];

  @override
  String get pathBlueprint => '/books/:id/deeper';
}

// APP
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Beamer(
      initialLocation: HomeLocation(),
      beamLocations: [
        HomeLocation(),
        BooksLocation(),
      ],
      notFoundPage: Scaffold(body: Center(child: Text('Not found'))),
      app: MaterialApp(),
    );
  }
}

void main() {
  runApp(MyApp());
}

remove popLocation

There is no need for this. Pop must be normal, removing the page from stack, and any diferent requirement should be implemented manualy using beamTo

matchPages wrong when there's collection-if based on parameters

example

class BooksLocation extends BeamLocation {
  @override
  List<Page> get pages => [
        ...HomeLocation().pages,
        BeamPage(
          key: ValueKey('books-${queryParameters['title'] ?? ''}'),
          page: BooksScreen(),
        ),
        if (pathParameters.containsKey('id'))
          BeamPage(
            key: ValueKey('book-${pathParameters['id']}'),
            page: BookDetailsScreen(
              book: books[int.parse(pathParameters['id'])],
            ),
          ),
      ];

  @override
  String get pathBlueprint => '/books/:id';
}

and then pop from details screen

add `data` to BeamLocation

as there are path and query parameters. This can be anything. Can also be passed to beamBack(withData: ...)

beamBack

Go back to previous BeamLocation. For example, if you beamTo somewhere deep, you don't need to do multiple pops.

Guards

Is there a way to implement router guards in this package?

parser; reset path parameters

so they don't stay if one is at /account/:accountId/address/:addressId and then manually deletes /address/:addressId from browser URL. addressId should be removed from pathParameters

Provide something to BeamLocation

Provide in the sense of InheritedWidget, Provider and friends, but not to the entire Beamer tree nor to just a single BeamPage's child, both of which are naturally supported.

use Streams?

Would this be a performance improvement, to use Streams for communication between beamTo and Router?

DeepLocation

Make a DeepLocation, a stack of 3-4 screens, instead of SecondLocation in example.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.