apptomate_custom_nav_rail 0.0.1
apptomate_custom_nav_rail: ^0.0.1 copied to clipboard
An enhanced and fully customizable navigation rail for Flutter applications, perfect for responsive web and desktop layouts.
example/lib/main.dart
import 'package:apptomate_custom_nav_rail/apptomate_custom_nav_rail.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const CustomNavigationRailWidget(),
);
}
}
class CustomNavigationRailWidget extends StatefulWidget {
const CustomNavigationRailWidget({super.key});
@override
State<CustomNavigationRailWidget> createState() =>
_CustomNavigationRailWidgetState();
}
class _CustomNavigationRailWidgetState extends State<CustomNavigationRailWidget> {
int _selectedIndex = 0;
bool _isExpanded = false;
final List<Widget> _pages = const [
_PageContent(icon: Icons.home_filled, title: 'Home Page'),
_PageContent(icon: Icons.search, title: 'Search Page'),
_PageContent(icon: Icons.person, title: 'Profile Page'),
_PageContent(icon: Icons.settings, title: 'Settings Page'),
_PageContent(icon: Icons.help, title: 'Help Page'),
_PageContent(icon: Icons.logout, title: 'Logout Page'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
CustomNavigationRail(
selectedIndex: _selectedIndex,
onTap: (index) => setState(() => _selectedIndex = index),
items: const [
NavigationRailItem(
icon: Icons.home_outlined,
activeIcon: Icons.home_filled,
label: 'Home',
tooltip: 'Home Page',
),
NavigationRailItem(
icon: Icons.search_outlined,
activeIcon: Icons.search,
label: 'Search',
tooltip: 'Search Page',
),
NavigationRailItem(
icon: Icons.person_outline,
activeIcon: Icons.person,
label: 'Profile',
tooltip: 'Profile Page',
),
],
footerItems: const [
NavigationRailItem(
icon: Icons.settings_outlined,
activeIcon: Icons.settings,
label: 'Settings',
tooltip: 'Settings Page',
),
NavigationRailItem(
icon: Icons.help_outline,
activeIcon: Icons.help,
label: 'Help',
tooltip: 'Help Center',
),
NavigationRailItem(
icon: Icons.logout_outlined,
activeIcon: Icons.logout,
label: 'Logout',
tooltip: 'Sign out',
),
],
backgroundColor: Colors.white,
selectedItemColor: Colors.blue.shade800,
unselectedItemColor: Colors.grey.shade600,
indicatorColor: Colors.blue.shade100,
elevation: 4.0,
iconSize: 28.0,
labelSpacing: 4.0,
useIndicator: true,
isExpanded: _isExpanded,
minWidth: 72,
minExtendedWidth: 200,
selectedLabelStyle: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
unselectedLabelStyle: const TextStyle(
fontSize: 12,
),
header: IconButton(
icon: Icon(
_isExpanded ? Icons.chevron_left : Icons.menu,
color: Colors.blue.shade800,
),
onPressed: () => setState(() => _isExpanded = !_isExpanded),
),
headerPadding: const EdgeInsets.symmetric(vertical: 16),
footerPadding: const EdgeInsets.only(bottom: 16),
),
Expanded(
child: _pages[_selectedIndex],
),
],
),
);
}
}
class _PageContent extends StatelessWidget {
final IconData icon;
final String title;
const _PageContent({
required this.icon,
required this.title,
});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
size: 64,
color: Colors.blue.shade800,
),
const SizedBox(height: 16),
Text(
title,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: Colors.blue.shade800,
fontWeight: FontWeight.bold,
),
),
],
),
);
}
}