import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; /// A lightweight press-scale wrapper used instead of InkWell for the large /// dashboard tiles. It keeps touch feedback cheap on older devices. class Pressable extends StatefulWidget { const Pressable({ super.key, required this.child, this.onTap, this.onLongPress, this.semanticLabel, this.pressedScale = 0.965, this.borderRadius = BorderRadius.zero, }); final Widget child; final VoidCallback? onTap; final VoidCallback? onLongPress; final String? semanticLabel; final double pressedScale; final BorderRadius borderRadius; @override State createState() => _PressableState(); } class _PressableState extends State { bool _pressed = false; void _setPressed(bool pressed) { if (!mounted || _pressed == pressed) return; setState(() => _pressed = pressed); } @override Widget build(BuildContext context) { final canInteract = widget.onTap != null || widget.onLongPress != null; return Semantics( button: canInteract, label: widget.semanticLabel, child: GestureDetector( behavior: HitTestBehavior.opaque, onTapDown: canInteract ? (_) => _setPressed(true) : null, onTapUp: canInteract ? (_) => _setPressed(false) : null, onTapCancel: canInteract ? () => _setPressed(false) : null, onTap: widget.onTap, onLongPress: widget.onLongPress == null ? null : () { HapticFeedback.mediumImpact(); widget.onLongPress!(); }, child: AnimatedScale( scale: _pressed ? widget.pressedScale : 1, duration: const Duration(milliseconds: 110), curve: Curves.easeOutCubic, child: widget.child, ), ), ); } }