Files
daily_mobileapp_customer/lib/widgets/slider_button.dart
2026-05-26 18:01:57 +05:30

139 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:nearledaily/constants/color_constants.dart';
class SliderCheckoutButton extends StatefulWidget {
final Future<void> Function() onConfirmed;
const SliderCheckoutButton({super.key, required this.onConfirmed});
@override
State<SliderCheckoutButton> createState() => _SliderCheckoutButtonState();
}
class _SliderCheckoutButtonState extends State<SliderCheckoutButton> {
double _dragPosition = 0;
bool _isLoading = false;
final double _thumbSize = 52;
final double _trackHeight = 56;
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
final trackWidth = constraints.maxWidth;
final maxDrag = trackWidth - _thumbSize - 8;
final progress = _dragPosition / maxDrag;
return Container(
height: _trackHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
gradient: LinearGradient(
colors: [
ColorConstants.primaryColor,
ColorConstants.primaryColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Stack(
alignment: Alignment.centerLeft,
children: [
// ── CENTER LABEL ──────────────────────────────
Center(
child: _isLoading
? Row(
mainAxisSize: MainAxisSize.min,
children: const [
SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
),
SizedBox(width: 10),
Text(
'Please wait...',
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w600,
letterSpacing: 0.4,
),
),
],
)
: Opacity(
opacity: (1 - progress * 2).clamp(0.0, 1.0),
child: const Text(
'Slide to Checkout',
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w600,
letterSpacing: 0.5,
),
),
),
),
// ── THUMB (hidden while loading) ──────────────
if (!_isLoading)
Positioned(
left: 4 + _dragPosition,
child: GestureDetector(
onHorizontalDragUpdate: (details) {
setState(() {
_dragPosition =
(_dragPosition + details.delta.dx).clamp(0.0, maxDrag);
});
},
onHorizontalDragEnd: (_) async {
if (_dragPosition >= maxDrag * 0.85) {
setState(() {
_dragPosition = 0;
_isLoading = true;
});
try {
await widget.onConfirmed();
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
} else {
setState(() => _dragPosition = 0);
}
},
child: Container(
width: _thumbSize,
height: _thumbSize,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: Icon(
Icons.arrow_forward_ios_rounded,
color: Theme.of(context).primaryColor,
size: 22,
),
),
),
),
],
),
);
});
}
}