Free copy-paste Button 002 for Flutter: a ready-to-use button widget with full Dart source code and a live preview. Works on mobile & desktop. No external packages.
Copy the Dart code below into a new file in your Flutter project (for example lib/widgets/button_002.dart) and use the widget anywhere in your widget tree.
import 'package:flutter/material.dart';
class Button002 extends StatefulWidget {
const Button002({
super.key,
this.text = 'H e l l o',
this.onPressed,
this.icon = Icons.front_hand_sharp,
this.iconSize = 18.0,
this.iconColor,
this.iconGap = 8.0,
this.trailingIcon = false,
});
final String text;
final VoidCallback? onPressed;
final IconData? icon;
final double iconSize;
final Color? iconColor;
final double iconGap;
final bool trailingIcon;
@override
State<Button002> createState() => _Button002State();
}
class _Button002State extends State<Button002> {
bool _isHovered = false;
bool _isPressed = false;
void _handleTapDown(TapDownDetails details) {
setState(() {
_isPressed = true;
});
}
void _handleTapUp(TapUpDetails details) {
setState(() {
_isPressed = false;
});
widget.onPressed?.call();
}
void _handleTapCancel() {
if (_isPressed) {
setState(() {
_isPressed = false;
});
}
}
@override
Widget build(BuildContext context) {
final Color textColor = _isPressed
? const Color(0xFF888E99)
: _isHovered
? const Color(0xFFFFFFFF)
: const Color(0xFFD4D8E0);
final List<Color> gradientColors = _isPressed
? const [Color(0xFF131417), Color(0xFF202329)]
: _isHovered
? const [Color(0xFF2A2E35), Color(0xFF1C1E23)]
: const [Color(0xFF25282E), Color(0xFF191B1F)];
final Border border = _isPressed
? Border.all(color: const Color(0x1F000000), width: 0.8)
: _isHovered
? Border.all(color: const Color(0x40FFFFFF), width: 0.8)
: Border.all(color: const Color(0x24FFFFFF), width: 0.8);
final List<BoxShadow> shadows = const [
BoxShadow(color: Color(0xD9000000), offset: Offset(2, 2), blurRadius: 3),
BoxShadow(
color: Color(0x12FFFFFF),
offset: Offset(-1, -1),
blurRadius: 2,
),
];
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) => setState(() => _isHovered = true),
onExit: (_) => setState(() {
_isHovered = false;
_isPressed = false;
}),
child: GestureDetector(
onTapDown: _handleTapDown,
onTapUp: _handleTapUp,
onTapCancel: _handleTapCancel,
child: AnimatedScale(
scale: _isPressed ? 0.985 : (_isHovered ? 1.015 : 1.0),
duration: const Duration(milliseconds: 160),
curve: Curves.easeOutCubic,
child: AnimatedContainer(
duration: const Duration(milliseconds: 160),
curve: Curves.easeOutCubic,
padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 14),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: border,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: gradientColors,
),
boxShadow: shadows,
),
child: widget.icon == null
? Text(
widget.text,
textAlign: TextAlign.center,
style: TextStyle(
color: textColor,
fontSize: 15,
fontWeight: FontWeight.w600,
letterSpacing: 0.6,
),
)
: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (!widget.trailingIcon) ...[
Icon(
widget.icon,
size: widget.iconSize,
color: widget.iconColor ?? textColor,
),
SizedBox(width: widget.iconGap),
],
Flexible(
child: Text(
widget.text,
textAlign: TextAlign.center,
style: TextStyle(
color: textColor,
fontSize: 15,
fontWeight: FontWeight.w600,
letterSpacing: 0.6,
),
),
),
if (widget.trailingIcon) ...[
SizedBox(width: widget.iconGap),
Icon(
widget.icon,
size: widget.iconSize,
color: widget.iconColor ?? textColor,
),
],
],
),
),
),
),
);
}
}