Accessible Bottom Navigation Bar
Component Detail
Description
A persistent five-tab bottom navigation bar built on StatefulShellRoute that preserves tab state across navigation events. Relies exclusively on tap interactions, carries full semantic labels for screen readers, and never requires swipe gestures for any interaction.
accessible-bottom-nav-bar
Summaries
The Accessible Bottom Navigation Bar is the primary wayfinding mechanism for the mobile application, shaping how all users — including those relying on screen readers or Switch Access — move between core product areas. By building accessibility into the navigation layer from the start, the organization avoids costly retrofitting and reduces the risk of failing app store accessibility audits. Preserving tab state across navigation events reduces friction and supports engagement and retention metrics. A reliable, inclusive navigation system is foundational to delivering a competitive, high-quality user experience that serves the broadest possible audience, including users with motor and visual impairments.
This medium-complexity shared component underpins navigation across all five main product areas, making it one of the highest-impact deliverables in terms of dependency surface. It depends on the tab-state-manager, which must be delivered and tested first. QA must verify tab state preservation across all five tabs under interruption scenarios such as incoming calls and app backgrounding, screen reader announcement accuracy on both iOS VoiceOver and Android TalkBack, and the absence of any swipe-dependent interaction path. Any regression here affects all features simultaneously, so post-integration changes require full cross-feature regression coverage and dedicated accessibility QA sign-off before release.
Built on GoRouter's StatefulShellRoute, this component maintains independent navigation stacks per tab, preserving scroll position and sub-route state across tab switches without re-rendering sibling branches. It consumes tab-state-manager for persistent state and exposes setActiveTab(index) and restoreTabState(tabIndex) for programmatic control from deep-link or notification entry points. Semantic labels and roles are applied via Flutter's Semantics widget with a button role and explicit label per tab, satisfying VoiceOver and TalkBack requirements. The announceTabChange(label) method triggers accessibility announcements on each tab transition.
All interactions are tap-driven — no horizontal swipe gesture is used — ensuring Switch Access and motor-impaired users retain full navigation capability across all application areas.
Responsibilities
- Render five labelled navigation tabs with active-state indicators
- Preserve scroll position and sub-route state per tab via StatefulShellRoute
- Expose semantic labels and roles for VoiceOver and TalkBack
- Emit tab-change events without relying on horizontal swipe input
Interfaces
buildBottomNavBar(context, currentIndex)
onTabSelected(index)
getActiveTab()
setActiveTab(index)
preserveTabState(tabIndex, state)
restoreTabState(tabIndex)
announceTabChange(label)