Navigation
Three different things, deliberately kept apart: a bar at the top of a screen, tabs that switch the whole app, and tabs that switch content within one screen.
App bar
An App Bar holds up to three things — typically a back icon, a title and one action. With three, the middle one takes the spare width so the title centres.
Placed as the first thing on a screen, it spans the full width and sits flush at the top, outside the screen's padding. Anywhere else it behaves like an ordinary row, which is occasionally what you want.
Bottom navigation
The Tabs panel on the left adds a tab bar for the whole app. Each tab names a screen as its root, and the bar stays mounted while the screen beneath it changes.
A button anywhere can switch tabs too, using the selectTab action — a “go to your profile” button on a home screen, for instance.
Switching returns to the tab's root
Tabs within a screen
The Tabs widget switches content inside one screen — All, Active, Archived over the same list. Each child is a panel, and its Tab label names the tab above it. Two to five panels.
The canvas shows the first panel, because designing a tab means selecting its panel in the layer tree. Switching happens in preview.
Moving between screens
Any tappable element can carry a navigate action, which opens another screen on top of the current one, and back returns from it. That is a stack: it remembers where you came from.
A decision between two destinations is a branch: one boolean — an app value like app.seenOnboarding, a toggle, a mutation flag — and two arms. Whether someone is signed in is not a branch; that is the auth gate's job.
In the exported app every screen is a typed route: ProductRoute(productId: id).push(context), with the path and its parameters checked by the compiler.
selectTab is not a stack — it replaces. Choosing the wrong one is the usual cause of a back arrow appearing where none belongs.
In the exported app
Screens become named routes. Bottom navigation becomes a shell widget holding an IndexedStack and a NavigationBar, and the app opens on it rather than on a route. In-screen tabs become a DefaultTabController with a TabBar and TabBarView.