Skip to content

Commit d08ebfd

Browse files
[go_router_builder] Generate initialLocation with StatefulShellBranchConfig (flutter#4880)
Add the possibility to generate `initialLocation` with `StatefulShellBranchConfig` before: ```dart class MyRoute extends StatefulShellBranchData { const MyRoute(); } ``` after: ```dart class MyRoute extends StatefulShellBranchData { const MyRoute(); static const String $initialLocation = '/my-route'; } ``` *List which issues are fixed by this PR. You must list at least one issue.* [issues/130786](flutter#130786 (comment))
1 parent 59febcd commit d08ebfd

8 files changed

+442
-2
lines changed

packages/go_router_builder/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.3.3
2+
3+
* Adds `initialLocation` for `StatefulShellBranchConfig`
4+
15
## 2.3.2
26

37
* Supports the latest `package:analyzer`.
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:go_router/go_router.dart';
9+
10+
part 'stateful_shell_route_initial_location_example.g.dart';
11+
12+
void main() => runApp(App());
13+
14+
class App extends StatelessWidget {
15+
App({super.key});
16+
17+
@override
18+
Widget build(BuildContext context) => MaterialApp.router(
19+
routerConfig: _router,
20+
);
21+
22+
final GoRouter _router = GoRouter(
23+
routes: $appRoutes,
24+
initialLocation: '/home',
25+
);
26+
}
27+
28+
class HomeScreen extends StatelessWidget {
29+
const HomeScreen({super.key});
30+
31+
@override
32+
Widget build(BuildContext context) => Scaffold(
33+
appBar: AppBar(title: const Text('foo')),
34+
);
35+
}
36+
37+
@TypedStatefulShellRoute<MainShellRouteData>(
38+
branches: <TypedStatefulShellBranch<StatefulShellBranchData>>[
39+
TypedStatefulShellBranch<HomeShellBranchData>(
40+
routes: <TypedRoute<RouteData>>[
41+
TypedGoRoute<HomeRouteData>(
42+
path: '/home',
43+
),
44+
],
45+
),
46+
TypedStatefulShellBranch<NotificationsShellBranchData>(
47+
routes: <TypedRoute<RouteData>>[
48+
TypedGoRoute<NotificationsRouteData>(
49+
path: '/notifications/:section',
50+
),
51+
],
52+
),
53+
TypedStatefulShellBranch<OrdersShellBranchData>(
54+
routes: <TypedRoute<RouteData>>[
55+
TypedGoRoute<OrdersRouteData>(
56+
path: '/orders',
57+
),
58+
],
59+
),
60+
],
61+
)
62+
class MainShellRouteData extends StatefulShellRouteData {
63+
const MainShellRouteData();
64+
65+
@override
66+
Widget builder(
67+
BuildContext context,
68+
GoRouterState state,
69+
StatefulNavigationShell navigationShell,
70+
) {
71+
return MainPageView(
72+
navigationShell: navigationShell,
73+
);
74+
}
75+
}
76+
77+
class HomeShellBranchData extends StatefulShellBranchData {
78+
const HomeShellBranchData();
79+
}
80+
81+
class NotificationsShellBranchData extends StatefulShellBranchData {
82+
const NotificationsShellBranchData();
83+
84+
static String $initialLocation = '/notifications/old';
85+
}
86+
87+
class OrdersShellBranchData extends StatefulShellBranchData {
88+
const OrdersShellBranchData();
89+
}
90+
91+
class HomeRouteData extends GoRouteData {
92+
const HomeRouteData();
93+
94+
@override
95+
Widget build(BuildContext context, GoRouterState state) {
96+
return const HomePageView(label: 'Home page');
97+
}
98+
}
99+
100+
enum NotificationsPageSection {
101+
latest,
102+
old,
103+
archive,
104+
}
105+
106+
class NotificationsRouteData extends GoRouteData {
107+
const NotificationsRouteData({
108+
required this.section,
109+
});
110+
111+
final NotificationsPageSection section;
112+
113+
@override
114+
Widget build(BuildContext context, GoRouterState state) {
115+
return NotificationsPageView(
116+
section: section,
117+
);
118+
}
119+
}
120+
121+
class OrdersRouteData extends GoRouteData {
122+
const OrdersRouteData();
123+
124+
@override
125+
Widget build(BuildContext context, GoRouterState state) {
126+
return const OrdersPageView(label: 'Orders page');
127+
}
128+
}
129+
130+
class MainPageView extends StatelessWidget {
131+
const MainPageView({
132+
required this.navigationShell,
133+
super.key,
134+
});
135+
136+
final StatefulNavigationShell navigationShell;
137+
138+
@override
139+
Widget build(BuildContext context) {
140+
return Scaffold(
141+
appBar: AppBar(),
142+
body: navigationShell,
143+
bottomNavigationBar: BottomNavigationBar(
144+
items: const <BottomNavigationBarItem>[
145+
BottomNavigationBarItem(
146+
icon: Icon(Icons.home),
147+
label: 'Home',
148+
),
149+
BottomNavigationBarItem(
150+
icon: Icon(Icons.favorite),
151+
label: 'Notifications',
152+
),
153+
BottomNavigationBarItem(
154+
icon: Icon(Icons.list),
155+
label: 'Orders',
156+
),
157+
],
158+
currentIndex: navigationShell.currentIndex,
159+
onTap: (int index) => _onTap(context, index),
160+
),
161+
);
162+
}
163+
164+
void _onTap(BuildContext context, int index) {
165+
navigationShell.goBranch(
166+
index,
167+
initialLocation: index == navigationShell.currentIndex,
168+
);
169+
}
170+
}
171+
172+
class HomePageView extends StatelessWidget {
173+
const HomePageView({
174+
required this.label,
175+
super.key,
176+
});
177+
178+
final String label;
179+
180+
@override
181+
Widget build(BuildContext context) {
182+
return Center(
183+
child: Text(label),
184+
);
185+
}
186+
}
187+
188+
class NotificationsPageView extends StatelessWidget {
189+
const NotificationsPageView({
190+
super.key,
191+
required this.section,
192+
});
193+
194+
final NotificationsPageSection section;
195+
196+
@override
197+
Widget build(BuildContext context) {
198+
return DefaultTabController(
199+
length: 3,
200+
initialIndex: NotificationsPageSection.values.indexOf(section),
201+
child: const Column(
202+
children: <Widget>[
203+
TabBar(
204+
tabs: <Tab>[
205+
Tab(
206+
child: Text(
207+
'Latest',
208+
style: TextStyle(color: Colors.black87),
209+
),
210+
),
211+
Tab(
212+
child: Text(
213+
'Old',
214+
style: TextStyle(color: Colors.black87),
215+
),
216+
),
217+
Tab(
218+
child: Text(
219+
'Archive',
220+
style: TextStyle(color: Colors.black87),
221+
),
222+
),
223+
],
224+
),
225+
Expanded(
226+
child: TabBarView(
227+
children: <Widget>[
228+
NotificationsSubPageView(
229+
label: 'Latest notifications',
230+
),
231+
NotificationsSubPageView(
232+
label: 'Old notifications',
233+
),
234+
NotificationsSubPageView(
235+
label: 'Archived notifications',
236+
),
237+
],
238+
),
239+
),
240+
],
241+
),
242+
);
243+
}
244+
}
245+
246+
class NotificationsSubPageView extends StatelessWidget {
247+
const NotificationsSubPageView({
248+
required this.label,
249+
super.key,
250+
});
251+
252+
final String label;
253+
254+
@override
255+
Widget build(BuildContext context) {
256+
return Center(
257+
child: Text(label),
258+
);
259+
}
260+
}
261+
262+
class OrdersPageView extends StatelessWidget {
263+
const OrdersPageView({
264+
required this.label,
265+
super.key,
266+
});
267+
268+
final String label;
269+
270+
@override
271+
Widget build(BuildContext context) {
272+
return Center(
273+
child: Text(label),
274+
);
275+
}
276+
}

0 commit comments

Comments
 (0)