ark_navigation 0.1.0-dev.2 copy "ark_navigation: ^0.1.0-dev.2" to clipboard
ark_navigation: ^0.1.0-dev.2 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
160
points
70
downloads

Documentation

Documentation
API reference

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

Apache-2.0 (license)

Dependencies

flutter

More

Packages that depend on ark_navigation