ark_navigation 0.1.0-dev.1 copy "ark_navigation: ^0.1.0-dev.1" to clipboard
ark_navigation: ^0.1.0-dev.1 copied to clipboard

Typed modular Flutter navigation with explicit stack operations, deep links, nested scopes, and no code generation.

example/ark_navigation_example.dart

import 'package:ark_navigation/ark_navigation.dart' as ark;
import 'package:flutter/material.dart';

void main() {
  runApp(const ExampleHost());
}

final class HomeDestination extends ark.NavigationDestination<void> {
  const HomeDestination();
}

final class ProductDestination extends ark.NavigationDestination<bool> {
  const ProductDestination({required this.productId});

  final String productId;
}

final class ExampleHost extends StatefulWidget {
  const ExampleHost({super.key});

  @override
  State<ExampleHost> createState() => _ExampleHostState();
}

final class _ExampleHostState extends State<ExampleHost> {
  late final ark.NavigationSession _session = ark.NavigationSession(
    id: const ark.NavigationSessionId('example'),
    graph: _createGraph(),
  );

  @override
  void dispose() {
    _session.dispose();
    super.dispose();
  }

  @override
  Widget build(final BuildContext context) {
    return MaterialApp.router(
      title: 'Ark Navigation example',
      routerConfig: _session.routerConfig,
    );
  }
}

ark.NavigationGraph _createGraph() {
  const ark.NavigationScopeId rootScopeId = ark.NavigationScopeId('root');
  const ark.NavigationModuleId moduleId = ark.NavigationModuleId('catalog');

  return ark.NavigationGraph(
    rootScopeId: rootScopeId,
    scopes: const <ark.NavigationScopeDefinition>[
      ark.NavigationScopeDefinition(
        id: rootScopeId,
        restorationScopeId: 'example-root',
      ),
    ],
    modules: <ark.NavigationModule>[
      ark.NavigationModule(
        id: moduleId,
        routes: <ark.NavigationRouteDefinitionBase>[
          ark.NavigationRouteDefinition<HomeDestination, void>(
            id: const ark.NavigationRouteId('home'),
            pageBuilder: (final context, final destination, final entry) =>
                const HomePage(),
            uriCodec: ark.CallbackNavigationUriCodec<HomeDestination>(
              pattern: '/',
              encoder: (final destination) => Uri(path: '/'),
              decoder: (final match) => const HomeDestination(),
            ),
          ),
          ark.NavigationRouteDefinition<ProductDestination, bool>(
            id: const ark.NavigationRouteId('product'),
            pageBuilder: (final context, final destination, final entry) =>
                ProductPage(productId: destination.productId),
            uriCodec: ark.CallbackNavigationUriCodec<ProductDestination>(
              pattern: '/products/:productId',
              encoder: (final destination) => Uri(
                pathSegments: <String>['products', destination.productId],
              ),
              decoder: (final match) =>
                  ProductDestination(productId: match.path('productId')),
            ),
            stackPlanBuilder: (final destination) =>
                <ark.NavigationTarget<Object?>>[
                  const ark.NavigationTarget<Object?>(
                    destination: HomeDestination(),
                  ),
                  ark.NavigationTarget<Object?>(destination: destination),
                ],
          ),
        ],
      ),
    ],
    mounts: <ark.NavigationMount>[
      ark.NavigationMount(
        id: const ark.NavigationMountId('catalog-root'),
        moduleId: moduleId,
        scopeId: rootScopeId,
      ),
    ],
  );
}

final class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

final class _HomePageState extends State<HomePage> {
  String _message = 'No result yet';

  Future<void> _openProduct() async {
    final ark.NavigationTicket<bool> ticket =
        ark.ArkNavigationBuildContextExtension(context).readNavigation
            .push<bool>(const ProductDestination(productId: 'keyboard-42'));

    final ark.NavigationOperationResult commit = await ticket.committed;
    if (commit is! ark.NavigationCommitted) {
      if (mounted) {
        setState(() => _message = 'Navigation was not committed');
      }
      return;
    }

    final ark.NavigationCompletion<bool> completion = await ticket.completed;
    if (!mounted) {
      return;
    }
    setState(() {
      _message = switch (completion) {
        ark.NavigationPopped<bool>(:final result) => 'Purchased: $result',
        ark.NavigationRemoved<bool>() => 'Product route was replaced',
        ark.NavigationNotCommitted<bool>() => 'Navigation was not committed',
      };
    });
  }

  @override
  Widget build(final BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Catalog')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(_message),
            const SizedBox(height: 16),
            FilledButton(
              onPressed: _openProduct,
              child: const Text('Open product'),
            ),
          ],
        ),
      ),
    );
  }
}

final class ProductPage extends StatelessWidget {
  const ProductPage({required this.productId, super.key});

  final String productId;

  @override
  Widget build(final BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Product $productId')),
      body: Center(
        child: FilledButton(
          onPressed: () => ark.ArkNavigationBuildContextExtension(
            context,
          ).readNavigation.pop(result: true),
          child: const Text('Buy and return a result'),
        ),
      ),
    );
  }
}
0
likes
0
points
70
downloads

Documentation

Documentation

Publisher

verified publisherarktelos.dev

Weekly Downloads

Typed modular Flutter navigation with explicit stack operations, deep links, nested scopes, and no code generation.

Homepage
Repository (GitLab)
View/report issues

Topics

#deep-linking #flutter #navigation #routing

License

unknown (license)

Dependencies

flutter

More

Packages that depend on ark_navigation