petsHero-AI/lib/shared/widgets/bottom_nav_bar.dart
2026-03-09 11:41:49 +08:00

123 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_spacing.dart';
import '../../core/theme/app_typography.dart';
enum NavTab { home, gallery, profile }
/// Bottom navigation bar - matches Pencil bottomNav
class BottomNavBar extends StatelessWidget {
const BottomNavBar({
super.key,
required this.currentTab,
required this.onTabSelected,
});
final NavTab currentTab;
final ValueChanged<NavTab> onTabSelected;
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 56,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.screenPadding,
vertical: 7.5,
),
decoration: BoxDecoration(
color: AppColors.surface,
boxShadow: [
BoxShadow(
color: AppColors.shadowSoft,
blurRadius: 12,
offset: const Offset(0, -4),
),
],
),
child: Row(
children: [
Expanded(
child: _NavTabItem(
icon: LucideIcons.house,
label: 'HOME',
isSelected: currentTab == NavTab.home,
onTap: () => onTabSelected(NavTab.home),
),
),
Expanded(
child: _NavTabItem(
icon: LucideIcons.images,
label: 'GALLERY',
isSelected: currentTab == NavTab.gallery,
onTap: () => onTabSelected(NavTab.gallery),
),
),
Expanded(
child: _NavTabItem(
icon: LucideIcons.user,
label: 'PROFILE',
isSelected: currentTab == NavTab.profile,
onTap: () => onTabSelected(NavTab.profile),
),
),
],
),
),
);
}
}
class _NavTabItem extends StatelessWidget {
const _NavTabItem({
required this.icon,
required this.label,
required this.isSelected,
required this.onTap,
});
final IconData icon;
final String label;
final bool isSelected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: Container(
height: 41,
alignment: Alignment.center,
decoration: BoxDecoration(
color: isSelected ? AppColors.primary : Colors.transparent,
borderRadius: BorderRadius.circular(26),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Icon(
icon,
size: 18,
color: isSelected ? AppColors.surface : AppColors.textMuted,
),
const SizedBox(width: AppSpacing.xs),
Text(
label,
style: (isSelected
? AppTypography.tabLabel
: AppTypography.tabLabelInactive)
.copyWith(
color: isSelected ? AppColors.surface : AppColors.textMuted,
),
),
],
),
),
);
}
}