Files
eryao/apps/lib/shared/widgets/bottom_nav_bar.dart
T

104 lines
2.7 KiB
Dart

import 'package:flutter/material.dart';
import '../../l10n/app_localizations.dart';
import '../theme/design_tokens.dart';
enum MainTab { home, profile }
class BottomNavBar extends StatelessWidget {
const BottomNavBar({
super.key,
required this.currentTab,
required this.onTabChange,
required this.onLogoTap,
});
final MainTab currentTab;
final ValueChanged<MainTab> onTabChange;
final VoidCallback onLogoTap;
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final colors = Theme.of(context).colorScheme;
return Container(
padding: const EdgeInsets.symmetric(vertical: AppSpacing.sm),
color: colors.surface,
child: SafeArea(
top: false,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_NavItem(
icon: Icons.home,
label: l10n.homeTab,
selected: currentTab == MainTab.home,
onTap: () => onTabChange(MainTab.home),
),
GestureDetector(
onTap: onLogoTap,
child: ClipRRect(
borderRadius: BorderRadius.circular(AppRadius.lg),
child: Image.asset(
'assets/images/logo.png',
width: 56,
height: 56,
fit: BoxFit.cover,
),
),
),
_NavItem(
icon: Icons.person,
label: l10n.profileTab,
selected: currentTab == MainTab.profile,
onTap: () => onTabChange(MainTab.profile),
),
],
),
),
);
}
}
class _NavItem extends StatelessWidget {
const _NavItem({
required this.icon,
required this.label,
required this.selected,
required this.onTap,
});
final IconData icon;
final String label;
final bool selected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
final iconColor = selected ? colors.primary : colors.outline;
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(AppRadius.md),
child: Padding(
padding: const EdgeInsets.all(AppSpacing.sm),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, color: iconColor),
const SizedBox(height: AppSpacing.xs),
Text(
label,
style: Theme.of(
context,
).textTheme.bodySmall?.copyWith(color: iconColor),
),
],
),
),
);
}
}