frontendPlayer/lib/presentation/widgets/sidebar_menu_item.dart
2026-04-10 09:55:19 +03:30

126 lines
3.6 KiB
Dart

import 'package:flutter/material.dart';
import '../../core/constants/app_colors.dart';
import '../../core/constants/app_text_styles.dart';
class SidebarMenuItem extends StatefulWidget {
final String title;
final IconData icon;
final bool isSelected;
final VoidCallback onTap;
const SidebarMenuItem({
super.key,
required this.title,
required this.icon,
this.isSelected = false,
required this.onTap,
});
@override
State<SidebarMenuItem> createState() => _SidebarMenuItemState();
}
class _SidebarMenuItemState extends State<SidebarMenuItem>
with SingleTickerProviderStateMixin {
bool _isHovered = false;
late AnimationController _hoverController;
late Animation<double> _scaleAnimation;
late Animation<Color?> _colorAnimation;
@override
void initState() {
super.initState();
_hoverController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);
_scaleAnimation = Tween<double>(begin: 1.0, end: 1.02).animate(
CurvedAnimation(parent: _hoverController, curve: Curves.easeInOut),
);
_colorAnimation =
ColorTween(
begin: Colors.transparent,
end: AppColors.sidebarSelected.withOpacity(0.5),
).animate(
CurvedAnimation(parent: _hoverController, curve: Curves.easeInOut),
);
}
@override
void dispose() {
_hoverController.dispose();
super.dispose();
}
void _onHoverEnter() {
setState(() => _isHovered = true);
_hoverController.forward();
}
void _onHoverExit() {
setState(() => _isHovered = false);
_hoverController.reverse();
}
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => _onHoverEnter(),
onExit: (_) => _onHoverExit(),
child: ScaleTransition(
scale: _scaleAnimation,
child: AnimatedBuilder(
animation: _colorAnimation,
builder: (context, child) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: widget.isSelected
? AppColors.sidebarSelected
: _colorAnimation.value,
borderRadius: BorderRadius.circular(8),
boxShadow: _isHovered || widget.isSelected
? [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 12,
offset: const Offset(0, 4),
),
]
: [],
),
child: ListTile(
onTap: widget.onTap,
leading: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: Icon(
widget.icon,
color: widget.isSelected ? Colors.white : Colors.white70,
size: _isHovered ? 26 : 24,
),
),
title: Text(
widget.title,
style: AppTextStyles.bodyLarge.copyWith(
color: widget.isSelected ? Colors.white : Colors.white70,
fontWeight: widget.isSelected
? FontWeight.bold
: FontWeight.normal,
),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 4,
),
),
);
},
),
),
);
}
}