import 'package:flutter/material.dart'; import '../../../../shared/theme/app_theme.dart'; import '../../../../shared/theme/design_system.dart'; /// TabBar moderne avec animations et design professionnel class ModernTabBar extends StatefulWidget implements PreferredSizeWidget { const ModernTabBar({ super.key, required this.controller, required this.tabs, this.onTap, }); final TabController controller; final List tabs; final ValueChanged? onTap; @override State createState() => _ModernTabBarState(); @override Size get preferredSize => Size.fromHeight(DesignSystem.goldenWidth(60)); } class _ModernTabBarState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _scaleAnimation; @override void initState() { super.initState(); _animationController = AnimationController( duration: DesignSystem.animationFast, vsync: this, ); _scaleAnimation = Tween( begin: 1.0, end: 0.95, ).animate(CurvedAnimation( parent: _animationController, curve: DesignSystem.animationCurve, )); widget.controller.addListener(_onTabChanged); } @override void dispose() { widget.controller.removeListener(_onTabChanged); _animationController.dispose(); super.dispose(); } void _onTabChanged() { if (mounted) { _animationController.forward().then((_) { _animationController.reverse(); }); } } @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.symmetric( horizontal: DesignSystem.spacingLg, vertical: DesignSystem.spacingSm, ), decoration: BoxDecoration( color: AppTheme.surfaceLight, borderRadius: BorderRadius.circular(DesignSystem.radiusLg), boxShadow: DesignSystem.shadowCard, border: Border.all( color: AppTheme.borderColor.withOpacity(0.1), width: 1, ), ), child: ClipRRect( borderRadius: BorderRadius.circular(DesignSystem.radiusLg), child: TabBar( controller: widget.controller, onTap: widget.onTap, indicator: BoxDecoration( gradient: DesignSystem.primaryGradient, borderRadius: BorderRadius.circular(DesignSystem.radiusMd), ), indicatorSize: TabBarIndicatorSize.tab, indicatorPadding: EdgeInsets.all(DesignSystem.spacingXs), labelColor: Colors.white, unselectedLabelColor: AppTheme.textSecondary, labelStyle: DesignSystem.labelLarge.copyWith( fontWeight: FontWeight.w600, ), unselectedLabelStyle: DesignSystem.labelLarge.copyWith( fontWeight: FontWeight.w500, ), dividerColor: Colors.transparent, tabs: widget.tabs.asMap().entries.map((entry) { final index = entry.key; final tab = entry.value; final isSelected = widget.controller.index == index; return AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) { return Transform.scale( scale: isSelected ? _scaleAnimation.value : 1.0, child: _buildTab(tab, isSelected), ); }, ); }).toList(), ), ), ); } Widget _buildTab(ModernTab tab, bool isSelected) { return Container( height: DesignSystem.goldenWidth(50), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedContainer( duration: DesignSystem.animationFast, child: Icon( tab.icon, size: isSelected ? 20 : 18, color: isSelected ? Colors.white : AppTheme.textSecondary, ), ), if (tab.label != null) ...[ SizedBox(width: DesignSystem.spacingXs), AnimatedDefaultTextStyle( duration: DesignSystem.animationFast, style: (isSelected ? DesignSystem.labelLarge : DesignSystem.labelMedium).copyWith( color: isSelected ? Colors.white : AppTheme.textSecondary, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500, ), child: Text(tab.label!), ), ], if (tab.badge != null) ...[ SizedBox(width: DesignSystem.spacingXs), _buildBadge(tab.badge!, isSelected), ], ], ), ); } Widget _buildBadge(String badge, bool isSelected) { return AnimatedContainer( duration: DesignSystem.animationFast, padding: EdgeInsets.symmetric( horizontal: DesignSystem.spacingXs, vertical: 2, ), decoration: BoxDecoration( color: isSelected ? Colors.white.withOpacity(0.2) : AppTheme.primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(DesignSystem.radiusSm), ), child: Text( badge, style: DesignSystem.labelSmall.copyWith( color: isSelected ? Colors.white : AppTheme.primaryColor, fontWeight: FontWeight.w600, fontSize: 10, ), ), ); } } /// Modèle pour un onglet moderne class ModernTab { const ModernTab({ required this.icon, this.label, this.badge, }); final IconData icon; final String? label; final String? badge; } /// Extension pour créer facilement des onglets modernes extension ModernTabExtension on Tab { static ModernTab modern({ required IconData icon, String? label, String? badge, }) { return ModernTab( icon: icon, label: label, badge: badge, ); } }