diff --git a/packages/flutter_adaptive_scaffold/CHANGELOG.md b/packages/flutter_adaptive_scaffold/CHANGELOG.md index 83d3716b01e..6f01cc38d40 100644 --- a/packages/flutter_adaptive_scaffold/CHANGELOG.md +++ b/packages/flutter_adaptive_scaffold/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.6 + +* Add new sample for using AdaptiveScaffold with GoRouter. + ## 0.2.5 * Fix breakpoint not being active in certain cases like foldables. diff --git a/packages/flutter_adaptive_scaffold/example/README.md b/packages/flutter_adaptive_scaffold/example/README.md index 035288f0155..a0ab2f7aad5 100644 --- a/packages/flutter_adaptive_scaffold/example/README.md +++ b/packages/flutter_adaptive_scaffold/example/README.md @@ -1,4 +1,5 @@ # Examples + There are several examples listed in this directory: You can run the following commands in the example directory to see the appropriate demos: @@ -7,3 +8,5 @@ You can run the following commands in the example directory to see the appropria `flutter run lib/adaptive_layout_demo.dart` to see a simple usage of AdaptiveLayout. `flutter run lib/adaptive_scaffold_demo.dart` to see a simple usage of AdaptiveScaffold. + +`flutter run lib/go_router_demo.dart` to see usage of AdaptiveScaffold with GoRouter and some advanced scenarios like auth handling and branches. diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart new file mode 100644 index 00000000000..5918197d376 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo.dart @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'go_router_demo/app_router.dart'; + +void main() { + runApp(const MyApp()); +} + +/// The main application widget for this example. +class MyApp extends StatelessWidget { + /// Creates a const main application widget. + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + restorationScopeId: 'demo', + routerConfig: AppRouter.router, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.blue, + dynamicSchemeVariant: DynamicSchemeVariant.vibrant, + primary: Colors.blue, + ), + useMaterial3: true, + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart new file mode 100644 index 00000000000..ddb36662370 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/app_router.dart @@ -0,0 +1,197 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages/pages.dart'; +import 'scaffold_shell.dart'; + +/// The root navigator key for the main router of the app. +final GlobalKey rootNavigatorKey = + GlobalKey(debugLabel: 'root'); + +final GlobalKey _homeNavigatorKey = + GlobalKey(debugLabel: 'home'); +final GlobalKey _counterNavigatorKey = + GlobalKey(debugLabel: 'counter'); +final GlobalKey _moreNavigatorKey = + GlobalKey(debugLabel: 'more'); + +/// The [AppRouter] maintains the main route configuration for the app. +/// +/// Routes that are `fullScreenDialogs` should also set `_rootNavigatorKey` as +/// the `parentNavigatorKey` to ensure that the dialog is displayed correctly. +class AppRouter { + /// The authentication status of the user. + static ValueNotifier authenticatedNotifier = ValueNotifier(false); + + /// The router with the routes of pages that should be displayed. + static final GoRouter router = GoRouter( + navigatorKey: rootNavigatorKey, + debugLogDiagnostics: true, + errorPageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: NavigationErrorPage()); + }, + redirect: (BuildContext context, GoRouterState state) { + if (state.uri.path == '/') { + return HomePage.path; + } + return null; + }, + refreshListenable: authenticatedNotifier, + routes: [ + _unauthenticatedRoutes, + _authenticatedRoutes, + ..._openRoutes, + ], + ); + + static final GoRoute _unauthenticatedRoutes = GoRoute( + name: LoginPage.name, + path: LoginPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: LoginPage()); + }, + redirect: (BuildContext context, GoRouterState state) { + if (authenticatedNotifier.value) { + return HomePage.path; + } + return null; + }, + routes: [ + GoRoute( + name: ForgotPasswordPage.name, + path: ForgotPasswordPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: ForgotPasswordPage(), + ); + }, + ), + ], + ); + + static final StatefulShellRoute _authenticatedRoutes = + StatefulShellRoute.indexedStack( + parentNavigatorKey: rootNavigatorKey, + builder: ( + BuildContext context, + GoRouterState state, + StatefulNavigationShell navigationShell, + ) { + return ScaffoldShell(navigationShell: navigationShell); + }, + redirect: (BuildContext context, GoRouterState state) { + if (!authenticatedNotifier.value) { + return LoginPage.path; + } + return null; + }, + branches: [ + StatefulShellBranch( + navigatorKey: _homeNavigatorKey, + routes: [ + GoRoute( + name: HomePage.name, + path: HomePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage( + child: HomePage(), + ); + }, + routes: [ + GoRoute( + name: DetailOverviewPage.name, + path: DetailOverviewPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: DetailOverviewPage(), + ); + }, + routes: [ + GoRoute( + name: DetailPage.name, + path: DetailPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return MaterialPage( + child: DetailPage( + itemName: state.uri.queryParameters['itemName']!), + ); + }, + ), + ]), + GoRoute( + name: DetailModalPage.name, + path: DetailModalPage.path, + parentNavigatorKey: rootNavigatorKey, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + fullscreenDialog: true, + child: DetailModalPage(), + ); + }, + ), + ], + ), + ], + ), + StatefulShellBranch( + navigatorKey: _counterNavigatorKey, + routes: [ + GoRoute( + name: CounterPage.name, + path: CounterPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage(child: CounterPage()); + }, + ), + ], + ), + StatefulShellBranch( + navigatorKey: _moreNavigatorKey, + routes: [ + GoRoute( + name: MorePage.name, + path: MorePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const NoTransitionPage( + key: ValueKey(MorePage.name), + child: MorePage(), + ); + }, + routes: [ + GoRoute( + path: ProfilePage.path, + name: ProfilePage.name, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: ProfilePage()); + }, + ), + GoRoute( + name: SettingsPage.name, + path: SettingsPage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage(child: SettingsPage()); + }, + ), + ], + ), + ], + ), + ], + ); + + static final List _openRoutes = [ + GoRoute( + name: LanguagePage.name, + path: LanguagePage.path, + pageBuilder: (BuildContext context, GoRouterState state) { + return const MaterialPage( + child: LanguagePage(), + ); + }, + ), + ]; +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart new file mode 100644 index 00000000000..59b5400a145 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/counter_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The counter page. +class CounterPage extends StatelessWidget { + /// Construct the counter page. + const CounterPage({super.key}); + + /// The path for the counter page. + static const String path = '/counter'; + + /// The name for the counter page. + static const String name = 'Counter'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Counter Page'), + ), + body: const Center( + child: Text('Counter Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart new file mode 100644 index 00000000000..6ce2d75a64b --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_modal_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The detail modal page. +class DetailModalPage extends StatelessWidget { + /// Construct the detail modal page. + const DetailModalPage({super.key}); + + /// The path for the detail modal page. + static const String path = 'detail-modal'; + + /// The name for the detail modal page. + static const String name = 'DetailModal'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Modal Page'), + ), + body: const Center( + child: Text('Detail modal Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart new file mode 100644 index 00000000000..941338e4f12 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_overview_page.dart @@ -0,0 +1,43 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'detail_page.dart'; + +/// The detail overview page. +class DetailOverviewPage extends StatelessWidget { + /// Construct the detail overview page. + const DetailOverviewPage({super.key}); + + /// The path for the detail page. + static const String path = 'detail-overview'; + + /// The name for the detail page. + static const String name = 'DetailOverview'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Overview Page'), + ), + body: ListView.builder( + itemCount: 10, + itemBuilder: (BuildContext context, int index) { + return ListTile( + title: Text('Item $index'), + onTap: () { + context.goNamed( + DetailPage.name, + queryParameters: {'itemName': '$index'}, + ); + }, + ); + }, + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart new file mode 100644 index 00000000000..0abc77f0ee6 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/detail_page.dart @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The detail page. +class DetailPage extends StatelessWidget { + /// Construct the detail page. + const DetailPage({super.key, required this.itemName}); + + /// The path for the detail page. + static const String path = 'detail'; + + /// The name for the detail page. + static const String name = 'Detail'; + + /// The item name for the detail page. + final String itemName; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Detail Page'), + ), + body: Center( + child: Text('Detail Page: $itemName'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart new file mode 100644 index 00000000000..a680f5c55b2 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/forgot_password_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The forgot password page. +class ForgotPasswordPage extends StatelessWidget { + /// Construct the forgot password page. + const ForgotPasswordPage({super.key}); + + /// The path for the forgot password page. + static const String path = 'forgot_password'; + + /// The name for the forgot password page. + static const String name = 'ForgotPassword'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Forgot Password'), + ), + body: const Center( + child: Text('ForgotPassword Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart new file mode 100644 index 00000000000..05dbbad56f6 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/home_page.dart @@ -0,0 +1,50 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages.dart'; + +/// The home page. +class HomePage extends StatelessWidget { + /// Construct the home page. + const HomePage({super.key}); + + /// The path for the home page. + static const String path = '/home'; + + /// The name for the home page. + static const String name = 'Home'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Home Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => { + context.goNamed(DetailOverviewPage.name), + }, + child: const Text('Detail page'), + ), + const SizedBox(height: kMaterialMediumAndUpMargin), + ElevatedButton( + onPressed: () => { + context.goNamed(DetailModalPage.name), + }, + child: const Text('Detail modal page'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart new file mode 100644 index 00000000000..ee160726199 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/language_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The language page. +class LanguagePage extends StatelessWidget { + /// Construct the language page. + const LanguagePage({super.key}); + + /// The path for the language page. + static const String path = '/language'; + + /// The name for the language page. + static const String name = 'Language'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Language'), + ), + body: const Center( + child: Text('Language Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart new file mode 100644 index 00000000000..32084550c61 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/login_page.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import '../app_router.dart'; + +/// The login page. +class LoginPage extends StatelessWidget { + /// Construct the login page. + const LoginPage({super.key}); + + /// The path for the login page. + static const String path = '/login'; + + /// The name for the login page. + static const String name = 'Login'; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Login Page'), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () => { + AppRouter.authenticatedNotifier.value = true, + }, + child: const Text('Login'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart new file mode 100644 index 00000000000..3eca08c7f2a --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/more_page.dart @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages.dart'; + +/// The more page. +class MorePage extends StatelessWidget { + /// Construct the more page. + const MorePage({super.key}); + + /// The path for the more page. + static const String path = '/more'; + + /// The name for the more page. + static const String name = 'More'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('More Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => context.goNamed(ProfilePage.name), + child: const Text('Profile'), + ), + const SizedBox(height: kMaterialMediumAndUpMargin), + ElevatedButton( + onPressed: () => context.goNamed(SettingsPage.name), + child: const Text('Settings'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart new file mode 100644 index 00000000000..c50a61e6ac9 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/navigation_error_page.dart @@ -0,0 +1,26 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The error page for navigation errors. +class NavigationErrorPage extends StatelessWidget { + /// Creates a new instance of the [NavigationErrorPage]. + const NavigationErrorPage({super.key}); + + /// The path for the error page. + static const String path = '/error'; + + /// The name for the error page. + static const String name = 'Error'; + + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Center( + child: Text('Error Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart new file mode 100644 index 00000000000..e7d498f9652 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/pages.dart @@ -0,0 +1,16 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export 'counter_page.dart'; +export 'detail_modal_page.dart'; +export 'detail_overview_page.dart'; +export 'detail_page.dart'; +export 'forgot_password_page.dart'; +export 'home_page.dart'; +export 'language_page.dart'; +export 'login_page.dart'; +export 'more_page.dart'; +export 'navigation_error_page.dart'; +export 'profile_page.dart'; +export 'settings_page.dart'; diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart new file mode 100644 index 00000000000..a5d2ee69e69 --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/profile_page.dart @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import '../app_router.dart'; + +/// The profile page. +class ProfilePage extends StatelessWidget { + /// Construct the profile page. + const ProfilePage({super.key}); + + /// The path for the profile page. + static const String path = 'profile'; + + /// The name for the profile page. + static const String name = 'Profile'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Profile Page'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => { + AppRouter.authenticatedNotifier.value = false, + }, + child: const Text('Sign Out'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart new file mode 100644 index 00000000000..8357e3cdebd --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/pages/settings_page.dart @@ -0,0 +1,29 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// The settings page. +class SettingsPage extends StatelessWidget { + /// Construct the settings page. + const SettingsPage({super.key}); + + /// The path for the settings page. + static const String path = 'settings'; + + /// The name for the settings page. + static const String name = 'Settings'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Settings Page'), + ), + body: const Center( + child: Text('Settings Page'), + ), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart new file mode 100644 index 00000000000..aa070a82c4a --- /dev/null +++ b/packages/flutter_adaptive_scaffold/example/lib/go_router_demo/scaffold_shell.dart @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +import 'pages/pages.dart'; + +/// The [ScaffoldShell] is a [StatelessWidget] that uses the [AdaptiveScaffold] +/// to create a shell for the application. +class ScaffoldShell extends StatelessWidget { + /// Create a new instance of [AppScaffoldShell] + const ScaffoldShell({ + required this.navigationShell, + super.key, + }); + + /// The navigation shell to use with the navigation. + final StatefulNavigationShell navigationShell; + + @override + Widget build(BuildContext context) { + return AdaptiveScaffold( + useDrawer: false, + body: (BuildContext context) => navigationShell, + selectedIndex: navigationShell.currentIndex, + onSelectedIndexChange: (int index) { + navigationShell.goBranch( + index, + initialLocation: index == navigationShell.currentIndex, + ); + }, + destinations: navigationShell.route.branches.map( + (StatefulShellBranch e) { + return switch (e.defaultRoute?.name) { + HomePage.name => const NavigationDestination( + icon: Icon(Icons.home), label: 'Home'), + CounterPage.name => const NavigationDestination( + icon: Icon(Icons.add), label: 'Counter'), + MorePage.name => const NavigationDestination( + icon: Icon(Icons.account_circle), label: 'More'), + _ => throw UnimplementedError( + 'The route ${e.defaultRoute?.name} is not implemented.', + ), + }; + }, + ).toList(), + ); + } +} diff --git a/packages/flutter_adaptive_scaffold/example/pubspec.yaml b/packages/flutter_adaptive_scaffold/example/pubspec.yaml index f73ddc3ccbc..3f82e2ca20e 100644 --- a/packages/flutter_adaptive_scaffold/example/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/example/pubspec.yaml @@ -12,9 +12,10 @@ dependencies: sdk: flutter flutter_adaptive_scaffold: path: .. + go_router: ^14.2.7 dev_dependencies: - build_runner: ^2.1.10 + build_runner: ^2.4.12 flutter_test: sdk: flutter diff --git a/packages/flutter_adaptive_scaffold/pubspec.yaml b/packages/flutter_adaptive_scaffold/pubspec.yaml index 64979c63aa5..6c9eab68f69 100644 --- a/packages/flutter_adaptive_scaffold/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_adaptive_scaffold description: Widgets to easily build adaptive layouts, including navigation elements. -version: 0.2.5 +version: 0.2.6 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22 repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold