petitspas/frontend/lib/widgets/hover_relief_widget.dart

88 lines
3.2 KiB
Dart

import 'package:flutter/material.dart';
class HoverReliefWidget extends StatefulWidget {
final Widget child;
final VoidCallback? onPressed;
final BorderRadius borderRadius;
final double initialElevation;
final double hoverElevation;
final double scaleFactor;
final bool enableHoverEffect; // Pour activer/désactiver l'effet de survol
final Color initialShadowColor; // Nouveau paramètre
final Color hoverShadowColor; // Nouveau paramètre
const HoverReliefWidget({
required this.child,
this.onPressed,
this.borderRadius = const BorderRadius.all(Radius.circular(15.0)),
this.initialElevation = 4.0,
this.hoverElevation = 8.0,
this.scaleFactor = 1.03, // Légèrement réduit par rapport à l'exemple précédent
this.enableHoverEffect = true, // Par défaut, l'effet est activé
this.initialShadowColor = const Color(0x26000000), // Default: Colors.black.withOpacity(0.15)
this.hoverShadowColor = const Color(0x4D000000), // Default: Colors.black.withOpacity(0.3)
super.key,
});
@override
State<HoverReliefWidget> createState() => _HoverReliefWidgetState();
}
class _HoverReliefWidgetState extends State<HoverReliefWidget> {
bool _isHovering = false;
@override
Widget build(BuildContext context) {
final bool canHover = widget.enableHoverEffect && widget.onPressed != null;
final hoverTransform = Matrix4.identity()..scale(widget.scaleFactor);
final transform = _isHovering && canHover ? hoverTransform : Matrix4.identity();
final shadowColor = _isHovering && canHover ? widget.hoverShadowColor : widget.initialShadowColor;
final elevation = _isHovering && canHover ? widget.hoverElevation : widget.initialElevation;
Widget content = AnimatedContainer(
duration: const Duration(milliseconds: 200),
transform: transform,
transformAlignment: Alignment.center,
child: Material(
color: Colors.transparent,
elevation: elevation,
shadowColor: shadowColor,
borderRadius: widget.borderRadius,
clipBehavior: Clip.antiAlias,
child: widget.child,
),
);
if (widget.onPressed == null) {
// Si non cliquable, on retourne juste le contenu avec l'élévation initiale (pas de survol)
// Ajustement: pour toujours avoir un Material de base même si non cliquable et sans hover.
return Material(
color: Colors.transparent,
elevation: widget.initialElevation, // Utilise l'élévation initiale
shadowColor: widget.initialShadowColor, // Appliqué ici pour l'état non cliquable
borderRadius: widget.borderRadius,
clipBehavior: Clip.antiAlias,
child: widget.child,
);
}
return MouseRegion(
onEnter: (_) {
if (widget.enableHoverEffect) setState(() => _isHovering = true);
},
onExit: (_) {
if (widget.enableHoverEffect) setState(() => _isHovering = false);
},
cursor: SystemMouseCursors.click,
child: InkWell(
onTap: widget.onPressed,
borderRadius: widget.borderRadius,
hoverColor: Colors.transparent,
splashColor: Colors.grey.withOpacity(0.2),
highlightColor: Colors.grey.withOpacity(0.1),
child: content,
),
);
}
}