feat: Convert _MenuItemTile to StatefulWidget for hover effect support
This commit is contained in:
@@ -124,7 +124,7 @@ IconData _iconForCodePoint(int? codePoint) {
|
|||||||
return Icons.folder_outlined;
|
return Icons.folder_outlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MenuItemTile extends StatelessWidget {
|
class _MenuItemTile extends StatefulWidget {
|
||||||
const _MenuItemTile({
|
const _MenuItemTile({
|
||||||
required this.icon,
|
required this.icon,
|
||||||
required this.label,
|
required this.label,
|
||||||
@@ -143,39 +143,52 @@ class _MenuItemTile extends StatelessWidget {
|
|||||||
final Color? textColor;
|
final Color? textColor;
|
||||||
final Widget? trailing;
|
final Widget? trailing;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_MenuItemTile> createState() => _MenuItemTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MenuItemTileState extends State<_MenuItemTile> {
|
||||||
|
bool _hovering = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Color backgroundColor = selected
|
final bool active = widget.selected || _hovering;
|
||||||
|
final Color backgroundColor = active
|
||||||
? Colors.white.withValues(alpha: 0.10)
|
? Colors.white.withValues(alpha: 0.10)
|
||||||
: Colors.transparent;
|
: Colors.transparent;
|
||||||
final Color foregroundColor = selected ? Colors.white : Colors.white70;
|
final Color foregroundColor = active ? Colors.white : Colors.white70;
|
||||||
|
|
||||||
return AnimatedContainer(
|
return MouseRegion(
|
||||||
|
onEnter: (_) {
|
||||||
|
setState(() => _hovering = true);
|
||||||
|
},
|
||||||
|
onExit: (_) {
|
||||||
|
setState(() => _hovering = false);
|
||||||
|
},
|
||||||
|
child: AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 180),
|
duration: const Duration(milliseconds: 180),
|
||||||
curve: Curves.easeOutCubic,
|
curve: Curves.easeOutCubic,
|
||||||
margin: EdgeInsets.only(
|
margin: const EdgeInsets.only(
|
||||||
right: 8,
|
right: 8,
|
||||||
top: 2,
|
top: 2,
|
||||||
bottom: 2,
|
bottom: 2,
|
||||||
),
|
),
|
||||||
child: Material(
|
child: Material(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
borderRadius: selected
|
borderRadius: const BorderRadius.only(
|
||||||
? const BorderRadius.only(
|
|
||||||
topRight: Radius.circular(999),
|
topRight: Radius.circular(999),
|
||||||
bottomRight: Radius.circular(999),
|
bottomRight: Radius.circular(999),
|
||||||
)
|
),
|
||||||
: BorderRadius.circular(12),
|
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: Icon(icon, color: iconColor ?? foregroundColor),
|
leading: Icon(widget.icon, color: widget.iconColor ?? foregroundColor),
|
||||||
trailing: trailing,
|
trailing: widget.trailing,
|
||||||
title: Text(
|
title: Text(
|
||||||
label,
|
widget.label,
|
||||||
style: TextStyle(color: textColor ?? foregroundColor, fontSize: 14),
|
style: TextStyle(color: widget.textColor ?? foregroundColor, fontSize: 14),
|
||||||
|
),
|
||||||
|
onTap: widget.onTap,
|
||||||
),
|
),
|
||||||
onTap: onTap,
|
|
||||||
hoverColor: Colors.white.withValues(alpha: 0.1),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user