TKK_E32232276/lib/ui_custom/custom_button.dart

236 lines
6.3 KiB
Dart

import 'package:flutter/material.dart';
enum IconPosition {
left,
right,
}
class CustomCard extends StatelessWidget {
final String title;
final String? subtitle;
final Widget? customSubtitle;
// SIZE
final double? width;
final double? height;
// ACTION
final VoidCallback? onTap;
// CARD ALIGNMENT
final AlignmentGeometry alignment;
// STYLE
final Color backgroundColor;
final Color borderColor;
final double borderWidth;
final double borderRadius;
// TEXT STYLE
final TextStyle? titleStyle;
final TextStyle? subtitleStyle;
// TEXT DEFAULT
final TextAlign titleAlign;
final TextAlign subtitleAlign;
final int? titleMaxLines;
final int? subtitleMaxLines;
final TextOverflow? titleOverflow;
final TextOverflow? subtitleOverflow;
// ICON
final IconData? icon;
final Color iconColor;
final double iconSize;
final bool showIcon;
// SPACING
final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry margin;
// SHADOW
final List<BoxShadow>? boxShadow;
final Widget? customIcon;
final IconPosition iconPosition;
final BoxDecoration? iconDecoration;
final Gradient? iconGradient;
final EdgeInsetsGeometry iconPadding;
final double iconContainerSize;
final Gradient? gradient;
const CustomCard({
super.key,
required this.title,
this.subtitle,
this.customSubtitle,
this.width,
this.height,
this.onTap,
this.alignment = Alignment.centerLeft,
this.backgroundColor = const Color(0xFFF1F5F9),
this.borderColor = const Color(0xFFBFDBFE),
this.borderWidth = 1,
this.borderRadius = 16,
this.titleStyle,
this.subtitleStyle,
//TEXT DEFAULT
this.titleAlign = TextAlign.left,
this.subtitleAlign = TextAlign.left,
this.titleMaxLines,
this.subtitleMaxLines,
this.titleOverflow,
this.subtitleOverflow,
this.icon = Icons.chevron_right,
this.iconColor = const Color(0xFF94A3B8),
this.iconSize = 24,
this.showIcon = true,
this.padding = const EdgeInsets.all(16),
this.margin = const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
this.boxShadow,
this.customIcon,
this.iconPosition = IconPosition.right,
this.iconDecoration,
this.iconGradient,
this.iconPadding = const EdgeInsets.all(8),
this.iconContainerSize = 40,
this.gradient,
});
Widget _buildIcon() {
if (!showIcon) return const SizedBox();
Widget iconWidget = customIcon ??
(icon != null
? Icon(
icon,
color: iconColor,
size: iconSize,
)
: const SizedBox());
return Container(
width: iconContainerSize,
height: iconContainerSize,
padding: iconPadding,
decoration: iconDecoration ??
BoxDecoration(
gradient: iconGradient,
borderRadius: BorderRadius.circular(12),
),
child: Center(child: iconWidget),
);
}
@override
Widget build(BuildContext context) {
return Align(
alignment: alignment,
child: InkWell(
borderRadius: BorderRadius.circular(borderRadius),
onTap: onTap,
child: Container(
width: width ?? double.infinity,
height: height,
margin: margin,
padding: padding,
decoration: BoxDecoration(
color: gradient == null ? backgroundColor : null,
gradient: gradient,
borderRadius: BorderRadius.circular(borderRadius),
border: Border.all(
color: borderColor,
width: borderWidth,
),
boxShadow: boxShadow ??
[
BoxShadow(
// ignore: deprecated_member_use
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// ICON
if (iconPosition == IconPosition.left) ...[
_buildIcon(),
const SizedBox(width: 8),
],
// TEXT
Expanded(
child: SingleChildScrollView(
physics: const NeverScrollableScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
// 🔥 ini ikut textAlign
crossAxisAlignment: titleAlign == TextAlign.right
? CrossAxisAlignment.end
: titleAlign == TextAlign.center
? CrossAxisAlignment.center
: CrossAxisAlignment.start,
children: [
Text(
title,
textAlign: titleAlign,
maxLines: titleMaxLines,
overflow: titleOverflow,
style: titleStyle ??
const TextStyle(
fontFamily: 'Inter',
fontSize: 16,
fontWeight: FontWeight.w700,
color: Color(0xFF1E293B),
),
),
if (customSubtitle != null) ...[
const SizedBox(height: 4),
customSubtitle!,
] else if (subtitle != null) ...[
const SizedBox(height: 4),
Text(
subtitle!,
textAlign: subtitleAlign,
maxLines: subtitleMaxLines,
overflow: subtitleOverflow,
style: subtitleStyle ??
const TextStyle(
fontFamily: 'Inter',
fontSize: 14,
color: Color(0xFF64748B),
),
),
],
],
),
),
),
if (iconPosition == IconPosition.right) ...[
const SizedBox(width: 8),
_buildIcon(),
],
],
),
),
),
);
}
}