VooNavigation π§
A comprehensive, adaptive navigation package for Flutter that automatically adjusts to different screen sizes and platforms with Material 3 design. Features a modern, production-ready UI inspired by leading SaaS applications like Notion, Linear, and Figma.
β¨ Features
-
π― Fully Adaptive: Automatically switches between navigation types based on screen size
- Bottom Navigation (< 600px)
- Navigation Rail (600-840px)
- Extended Navigation Rail (840-1240px)
- Navigation Drawer (> 1240px)
-
π Collapsible Drawer: Desktop drawer can collapse to a rail with animated toggle
-
π Per-Page Overrides: Customize scaffold elements (FAB, app bar, etc.) on individual pages with
VooPage -
π¨ Theme Presets: Six distinct visual styles - Glassmorphism, Liquid Glass, Blurry, Neomorphism, Material 3, Minimal
-
π€ User Profile Footer: Built-in user profile component with avatar, name, and status
-
π Navigation Sections: Group items into collapsible sections with headers
-
π go_router Integration: Native integration with StatefulNavigationShell
-
π Rich Navigation Items: Badges, dropdowns, custom icons, tooltips
-
β¨ Smooth Animations: AnimatedSwitcher for icon transitions, micro-interactions
-
π Production Ready: Battle-tested UI matching modern SaaS applications
-
π οΈ Extensive Customization: Colors, shapes, elevations, headers, footers
-
βΏ Accessibility: Full semantic labels and focus management
-
π± Platform Agnostic: Works seamlessly across all platforms
π¦ Installation
Add to your pubspec.yaml:
dependencies:
voo_navigation: ^1.0.3
# Or for local development:
# voo_navigation:
# path: packages/ui/voo_navigation
π Quick Start
With go_router (Recommended)
import 'package:go_router/go_router.dart';
import 'package:voo_navigation/voo_navigation.dart';
// 1. Define your router with StatefulShellRoute
final router = GoRouter(
initialLocation: '/home',
routes: [
StatefulShellRoute.indexedStack(
builder: (context, state, navigationShell) {
// Pass the navigation shell to your scaffold
return ScaffoldWithNavigation(
navigationShell: navigationShell,
);
},
branches: [
StatefulShellBranch(
routes: [
GoRoute(
path: '/home',
builder: (context, state) => HomePage(),
routes: [
// Nested routes
GoRoute(
path: 'details',
builder: (context, state) => HomeDetailsPage(),
),
],
),
],
),
StatefulShellBranch(
routes: [
GoRoute(
path: '/profile',
builder: (context, state) => ProfilePage(),
),
],
),
],
),
],
);
// 2. Create your navigation scaffold
class ScaffoldWithNavigation extends StatelessWidget {
final StatefulNavigationShell navigationShell;
const ScaffoldWithNavigation({required this.navigationShell});
@override
Widget build(BuildContext context) {
final items = [
VooNavigationItem(
id: 'home',
label: 'Home',
icon: Icons.home_outlined,
selectedIcon: Icons.home,
badgeCount: 3,
),
VooNavigationItem(
id: 'profile',
label: 'Profile',
icon: Icons.person_outline,
selectedIcon: Icons.person,
),
];
return VooAdaptiveScaffold(
config: VooNavigationConfig(
items: items,
selectedId: items[navigationShell.currentIndex].id,
onNavigationItemSelected: (itemId) {
final index = items.indexWhere((item) => item.id == itemId);
if (index != -1) {
navigationShell.goBranch(index);
}
},
),
body: navigationShell, // Pass the shell as body
);
}
}
// 3. Use with MaterialApp.router
MaterialApp.router(
routerConfig: router,
)
π― Navigation Types
Bottom Navigation (Mobile)
Automatically used on screens < 600px wide. Perfect for mobile devices.
Navigation Rail (Tablet)
Used on screens 600-840px. Ideal for tablets in portrait mode.
Extended Navigation Rail (Small Laptop)
Used on screens 840-1240px. Shows labels alongside icons.
Navigation Drawer (Desktop)
Used on screens > 1240px. Full-featured drawer with sections and headers.
π οΈ Customization
Navigation Items
VooNavigationItem(
id: 'unique_id',
label: 'Display Label',
icon: Icons.icon_outlined,
selectedIcon: Icons.icon, // Optional different icon when selected
// Badges
badgeCount: 5, // Shows "5"
badgeText: 'NEW', // Custom badge text
showDot: true, // Simple notification dot
badgeColor: Colors.red, // Custom badge color
// Navigation
route: '/route', // Route to navigate to
destination: CustomWidget(), // Or custom widget
onTap: () {}, // Custom callback
// Icon Customization
iconColor: Colors.blue, // Custom icon color
selectedIconColor: Colors.green, // Icon color when selected
leadingWidget: CustomWidget(), // Replace icon with custom widget
// Label Customization
labelStyle: TextStyle(...), // Custom label style
selectedLabelStyle: TextStyle(...), // Label style when selected
// Accessibility
tooltip: 'Custom tooltip',
semanticLabel: 'Accessible label for screen readers',
// Additional Widgets
trailingWidget: Icon(Icons.arrow_forward),
// State
isEnabled: true,
isVisible: true,
sortOrder: 0,
key: ValueKey('my_item'),
// Children for sections
children: [...], // Nested items for dropdowns
isExpanded: true, // Start expanded
)
Configuration Options
VooNavigationConfig(
// Core
items: [...],
selectedId: 'current_id',
// Behavior
isAdaptive: true, // Auto-adapt to screen size
forcedNavigationType: NavigationType.rail, // Override adaptive
// Animation
enableAnimations: true,
animationDuration: Duration(milliseconds: 300),
animationCurve: Curves.easeInOut,
// Appearance
railLabelType: NavigationRailLabelType.selected,
useExtendedRail: true,
showNavigationRailDivider: true,
centerAppBarTitle: false,
// Colors (v0.0.5 defaults to modern dark theme)
backgroundColor: Colors.white,
navigationBackgroundColor: Color(0xFF1F2937), // Professional dark gray
selectedItemColor: Theme.of(context).colorScheme.primary,
unselectedItemColor: Colors.white.withValues(alpha: 0.8),
indicatorColor: Colors.primary.withValues(alpha: 0.12),
// Custom Widgets
drawerHeader: CustomHeader(),
drawerFooter: CustomFooter(),
appBarLeading: CustomLeading(),
appBarActions: [...],
floatingActionButton: FAB(),
// Callbacks
onNavigationItemSelected: (itemId) {...},
)
π± Responsive Breakpoints
The package uses Material 3 breakpoints by default:
| Breakpoint | Width | Navigation Type |
|---|---|---|
| Compact | < 600px | Bottom Navigation |
| Medium | 600-840px | Navigation Rail |
| Expanded | 840-1240px | Extended Rail |
| Large | 1240-1440px | Navigation Drawer |
| Extra Large | > 1440px | Navigation Drawer |
You can customize breakpoints:
VooNavigationConfig(
breakpoints: [
VooBreakpoint(
minWidth: 0,
maxWidth: 500,
navigationType: VooNavigationType.bottomNavigation,
columns: 4,
margin: EdgeInsets.all(16),
gutter: 8,
),
// Add more custom breakpoints
],
)
π¨ Theming
The package fully integrates with your app's theme:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
navigationBarTheme: NavigationBarThemeData(...),
navigationRailTheme: NavigationRailThemeData(...),
drawerTheme: DrawerThemeData(...),
),
)
π Badges & Notifications
Show badges on navigation items:
// Count badge
VooNavigationItem(
badgeCount: 10, // Shows "10"
)
// Custom text badge
VooNavigationItem(
badgeText: 'NEW',
badgeColor: Colors.orange,
)
// Simple dot indicator
VooNavigationItem(
showDot: true,
badgeColor: Colors.red,
)
π Sections & Groups
Organize items into sections using VooNavigationItem.section() or the dedicated VooNavigationSection:
// Simple approach using item factory
VooNavigationItem.section(
label: 'Communication',
children: [
VooNavigationItem(id: 'messages', ...),
VooNavigationItem(id: 'email', ...),
],
isExpanded: true,
)
// Semantic approach using VooNavigationSection
VooNavigationSection(
id: 'main_section',
title: 'Main',
icon: Icons.dashboard,
items: [
VooNavigationItem(id: 'home', label: 'Home', icon: Icons.home, route: '/'),
VooNavigationItem(id: 'dashboard', label: 'Dashboard', icon: Icons.dashboard, route: '/dashboard'),
],
isExpanded: true,
isCollapsible: true,
showDividerBefore: false,
showDividerAfter: true,
)
Use sections in config:
VooNavigationConfig(
items: [...], // Direct items
sections: [ // Organized sections
VooNavigationSection(...),
VooNavigationSection(...),
],
)
π Collapsible Drawer
Enable the desktop drawer to collapse into a navigation rail:
VooNavigationConfig(
enableCollapsibleRail: true,
onCollapseChanged: (isCollapsed) {
print('Drawer collapsed: $isCollapsed');
},
// Optional: custom toggle button
collapseToggleBuilder: (isExpanded, onToggle) {
return IconButton(
icon: Icon(isExpanded ? Icons.chevron_left : Icons.chevron_right),
onPressed: onToggle,
);
},
)
π Per-Page Scaffold Overrides (VooPage)
Customize scaffold elements on individual pages without affecting the global config:
// Basic usage - custom FAB position
VooPage(
config: VooPageConfig(
floatingActionButton: FloatingActionButton.extended(
onPressed: () {},
label: Text('Compose'),
icon: Icon(Icons.create),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
),
child: MyPageContent(),
)
// Custom app bar for a specific page
VooPage.withAppBar(
appBar: AppBar(
title: Text('Custom Title'),
backgroundColor: Colors.teal,
actions: [IconButton(icon: Icon(Icons.search), onPressed: () {})],
),
child: MyPageContent(),
)
// Fullscreen page (no app bar)
VooPage.fullscreen(
child: MyImmersiveContent(),
)
// Clean page (no scaffold elements)
VooPage.clean(
child: MyMinimalContent(),
)
// Hide FAB on specific page
VooPage(
config: VooPageConfig(
showFloatingActionButton: false,
),
child: MyPageContent(),
)
Available VooPageConfig Options
VooPageConfig(
// App Bar
appBar: PreferredSizeWidget?,
showAppBar: bool,
// Floating Action Button
floatingActionButton: Widget?,
floatingActionButtonLocation: FloatingActionButtonLocation?,
showFloatingActionButton: bool,
// Scaffold Properties
backgroundColor: Color?,
resizeToAvoidBottomInset: bool?,
extendBody: bool?,
extendBodyBehindAppBar: bool?,
// Additional Elements
bottomSheet: Widget?,
endDrawer: Widget?,
persistentFooterButtons: List<Widget>?,
// Body Styling
bodyPadding: EdgeInsetsGeometry?,
useBodyCard: bool?,
bodyCardElevation: double?,
bodyCardBorderRadius: BorderRadius?,
bodyCardColor: Color?,
// Custom Scaffold (full control)
useCustomScaffold: bool,
scaffoldBuilder: Widget Function(BuildContext, Widget)?,
)
π¨ Theme Presets
Apply distinct visual styles to your navigation components:
// Glassmorphism - frosted glass effect with blur and translucent surfaces
VooNavigationConfig.glassmorphism(
items: navigationItems,
selectedId: selectedId,
)
// Liquid Glass - deep blur with layered effects and edge refraction
VooNavigationConfig.liquidGlass(
items: navigationItems,
selectedId: selectedId,
)
// Blurry - clean frosted blur with minimal styling
VooNavigationConfig.blurry(
items: navigationItems,
selectedId: selectedId,
)
// Neomorphism - soft embossed/debossed effect with dual shadows
VooNavigationConfig.neomorphism(
items: navigationItems,
selectedId: selectedId,
)
// Material 3 Enhanced - polished Material 3 with richer animations
VooNavigationConfig.material3Enhanced(
items: navigationItems,
selectedId: selectedId,
)
// Minimal Modern - clean flat design
VooNavigationConfig.minimalModern(
items: navigationItems,
selectedId: selectedId,
)
Custom Theme
Create your own navigation theme:
VooNavigationConfig(
items: items,
navigationTheme: VooNavigationTheme(
preset: VooNavigationPreset.glassmorphism,
surfaceOpacity: 0.8,
blurSigma: 20,
borderWidth: 1.5,
borderOpacity: 0.2,
indicatorStyle: VooThemeIndicatorStyle.glow,
indicatorGlowBlur: 16,
containerBorderRadius: 28,
animationDuration: Duration(milliseconds: 250),
animationCurve: Curves.easeInOut,
// Liquid Glass specific properties
innerGlowIntensity: 0.6,
edgeHighlightIntensity: 0.8,
secondaryBlurSigma: 8,
tintIntensity: 0.3,
),
)
Theme Preset Characteristics
| Preset | Surface | Shadows | Border | Indicator |
|---|---|---|---|---|
| Glassmorphism | Translucent (75%) with blur | Soft glow | Subtle light border | Glow effect |
| Liquid Glass | Translucent (60%) with deep blur | Multi-layer glow | Light border with edge highlights | Glow effect |
| Blurry | Translucent (55%) with heavy blur | None | Thin subtle border | Glow effect |
| Neomorphism | Opaque | Dual shadows (light + dark) | None | Embossed |
| Material 3 | Opaque | Elevation shadow | None | Pill |
| Minimal | Opaque | None | Thin outline | Line |
π€ User Profile Footer
Show a user profile in the drawer/rail footer:
VooNavigationConfig(
showUserProfile: true,
// Use default profile widget or provide custom one
userProfileWidget: VooUserProfileFooter(
userName: 'John Doe',
userEmail: 'john@example.com',
avatarUrl: 'https://example.com/avatar.jpg',
status: VooUserStatus.online,
onTap: () => print('Profile tapped'),
onSettingsTap: () => print('Settings tapped'),
onLogout: () => print('Logout'),
),
)
π Empty & Loading States
Handle empty and loading states:
VooNavigationConfig(
items: items,
// Show when items list is empty
emptyStateWidget: Center(
child: Text('No navigation items'),
),
// Show while loading
loadingWidget: Center(
child: CircularProgressIndicator(),
),
)
π Animations
All transitions are animated by default (enhanced in v0.0.5):
- Navigation type changes with smooth transitions
- Item selection with AnimatedSwitcher (200ms)
- Badge updates with scale animations
- Drawer/rail expansion with easing curves
- FAB position changes with Material 3 motion
- Icon transitions between selected/unselected states
- Hover effects with subtle opacity changes (5% overlay)
Control animations:
VooNavigationConfig(
enableAnimations: false, // Disable all animations
animationDuration: Duration(milliseconds: 500),
animationCurve: Curves.elasticOut,
)
π± Example App
Check out the example apps for complete demonstrations:
cd packages/ui/voo_navigation/example
# Run the main example
flutter run
# Run the modern dashboard example (v0.0.5)
flutter run lib/modern_dashboard_example.dart
# Run the go_router integration example
flutter run lib/go_router_example.dart
ποΈ Architecture
The package follows clean architecture with Atomic Design Pattern:
lib/
βββ src/
β βββ domain/
β β βββ entities/ # Core business entities
β β βββ navigation_config.dart
β β βββ navigation_item.dart
β β βββ navigation_route.dart # go_router integration (v0.0.4+)
β β βββ navigation_type.dart
β βββ presentation/
β βββ organisms/ # Complex components
β β βββ voo_adaptive_scaffold.dart
β β βββ voo_adaptive_navigation_rail.dart
β β βββ voo_adaptive_navigation_drawer.dart
β βββ molecules/ # Composite components
β βββ atoms/ # Basic components
β βββ utils/ # Animation utilities
π§ͺ Testing
Run tests:
flutter test
π License
This package is part of the VooFlutter ecosystem.
π Version History
- 1.0.3 - New theme presets
- Added Liquid Glass preset - deep blur with layered effects, inner glow, and edge refraction
- Added Blurry preset - clean frosted blur with minimal styling (inspired by BlurryContainer)
- New theme properties:
innerGlowIntensity,edgeHighlightIntensity,secondaryBlurSigma,tintIntensity - Enhanced gradient backgrounds in example app for better blur visibility
- 1.0.2 - Per-page scaffold overrides & theme fixes
- VooPage system for customizing scaffold elements per page
- Theme presets now properly apply to navigation components
- Fixed styled layout for fullscreen pages
- More visually distinct theme presets
- 1.0.1 - Mobile navigation improvements
- Floating bottom navigation redesign
- Responsive compact mode for 5 items
- 1.0.0 - Stable release with polished animations
- Full collapsible drawer-to-rail implementation
- Enhanced animation system (dropdown arrows, badges, indicators)
- Performance optimizations for collapse transitions
- 0.1.1 - Theme preset system with glassmorphism, neomorphism, Material 3 enhanced, and minimal modern styles
- 0.1.0 - App bar builder pattern for dynamic content
- 0.0.7 - Major feature release (sections, collapsible drawer, user profile)
- 0.0.6 - Updated go_router dependency to ^16.2.2
- 0.0.5 - Visual design overhaul, UX improvements, bug fixes
- 0.0.4 - go_router integration, Material You support
- 0.0.3 - Package maintenance
- 0.0.2 - Animation enhancements, badge system refinements
- 0.0.1 - Initial release
See CHANGELOG.md for detailed version history.
π€ Contributing
Contributions are welcome! Please read our contributing guidelines and follow the code style defined in rules.md.
π What's New in v1.0.3
New Theme Presets
Two new visually stunning theme presets for modern glass-like navigation:
-
Liquid Glass: Premium frosted glass with deep blur, layered effects, inner glow, and edge refraction. Creates a high-end, iOS-inspired aesthetic with multiple blur layers and subtle color tinting.
-
Blurry: Clean frosted blur effect with minimal styling. Inspired by BlurryContainer - heavy blur (28 sigma), semi-transparent surface, thin border, no shadows. Perfect for dark mode interfaces.
New Theme Properties
Fine-tune your glass effects with new customization options:
innerGlowIntensity- Controls the intensity of the inner glow effectedgeHighlightIntensity- Controls the brightness of edge highlights/refractionsecondaryBlurSigma- Secondary blur layer for added depthtintIntensity- How much the primary color tints the surface
Enhanced Example App
- Background gradients now properly fill the screen for better blur visibility
- Higher contrast colors in dark mode to showcase blur effects
π Issues
Report issues on the GitHub repository.
Built by VooStack
Need help with Flutter development or custom navigation solutions?
VooStack builds enterprise Flutter applications and developer tools. We're here to help with your next project.