x_router 0.3.0 copy "x_router: ^0.3.0" to clipboard
x_router: ^0.3.0 copied to clipboard

A simple and powerful routing lib that simplify having multiple child router.

example/lib/main.dart

import 'package:example/layout/home_layout.dart';
import 'package:example/pages/dashboard_page.dart';
import 'package:example/pages/favorites_page.dart';
import 'package:example/pages/product_details_page.dart';
import 'package:example/pages/products_page.dart';
import 'package:example/pages/sign_in_page.dart';
import 'package:example/services/auth_service.dart';
import 'package:flutter/material.dart';
import 'package:x_router/x_router.dart';

/// This example features a complex
/// app navigation system with child routing and reactive resolvers
///
/// The goal here is not to show the feature
/// not necessarily to have a simple getting started example.

/// all the locations in the app
class RouteLocations {
  // this is the main page which will show the navigation
  static const signIn = '/sign-in';
  // the other pages are displayed inside that page above the nav
  static const app = '/app';
  static const dashboard = '$app/dashboard';
  static const products = '$app/products';
  static const favorites = '$app/favorites';
  static const productDetail = '$app/products/:id';
}

/// the routes for each location
final _routes = [
  // Root router routes
  XRoute(
    path: RouteLocations.signIn,
    builder: (ctx, route) => const SignInPage(),
    titleBuilder: (ctx) => translate(ctx, 'sign in ! (Browser tab title)'),
  ),
  // this page contains a child router
  XRoute(
    path: RouteLocations.app,
    builder: (ctx, route) => const HomeLayout(),
    // those page will be placed inside the home layout page
    children: [
      XRoute(
        path: RouteLocations.dashboard,
        builder: (ctx, route) => const DashboardPage(),
        titleBuilder: (_) => 'dashboard',
      ),
      XRoute(
        path: RouteLocations.favorites,
        builder: (ctx, route) => const FavoritesPage(),
        titleBuilder: (_) => 'My favorites',
      ),
      XRoute(
        path: RouteLocations.products,
        builder: (ctx, route) {
          return const ProductsPage();
        },
        titleBuilder: (_) => 'products',
      ),
      XRoute(
        path: RouteLocations.productDetail,
        builder: (ctx, activatedRoute) =>
            ProductDetailsPage(activatedRoute.pathParams['id']!),
      ),
    ],
  ),
];

// the router instance used throughout the app
final router = XRouter(
  routes: _routes,
  resolvers: [
    // Auth reactive resolver, redirects when unauthenticated / authenticated
    AuthResolver(),
    // redirects app to dashboard
    XRedirectResolver(
      from: RouteLocations.app,
      to: RouteLocations.dashboard,
      matchChildren: false,
    ),
    XRedirectResolver(
      from: RouteLocations.productDetail,
      to: '${RouteLocations.productDetail}/info',
      matchChildren: false,
    ),
    // will redirect to app when a route is not found
    XNotFoundResolver(redirectTo: RouteLocations.app, routes: _routes),
  ],
);

void main() async {
  router.eventStream.listen((event) => print(event));
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: router.informationParser,
      routerDelegate: router.delegate,
      routeInformationProvider: router.informationProvider,
      backButtonDispatcher: router.backButtonDispatcher,
      debugShowCheckedModeBanner: false,
      title: 'XRouter Demo',
      theme: ThemeData.from(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
        ),
        useMaterial3: true,
      ),
    );
  }
}

// fake translate
String translate(BuildContext ctx, String text) => text;

/// goes to login page if we are not signed in.
class AuthResolver with XResolver {
  AuthResolver();

  @override
  Future<XResolverAction> resolve(String target) async {
    final isSignInRoute =
        XRoutePattern(RouteLocations.signIn).match(target, matchChildren: true);
    final authStatus = await AuthService.instance.authStatusStream.first;
    switch (authStatus) {
      case AuthStatus.authenticated:
        if (isSignInRoute) {
          return const Redirect(RouteLocations.app);
        } else {
          return const Next();
        }
      case AuthStatus.unautenticated:
      default:
        if (isSignInRoute) {
          return const Next();
        } else {
          return const Redirect(RouteLocations.signIn);
        }
    }
  }
}
5
likes
140
pub points
0%
popularity

Publisher

unverified uploader

A simple and powerful routing lib that simplify having multiple child router.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter

More

Packages that depend on x_router