import 'package:flutter/material.dart'; import '../../core/theme/app_color_scheme.dart'; import '../../core/theme/app_spacing.dart'; /// 渐变按钮组件 - 支持 CTA 渐变效果 /// /// 设计规则: /// - 渐变方向: 135度 (primary → primary_container) /// - 圆角: xxl (24px / 1.5rem) /// - 无边框 class GradientButton extends StatelessWidget { final String text; final VoidCallback? onPressed; final bool isLoading; final bool isFullWidth; final LinearGradient? gradient; final IconData? icon; final double height; const GradientButton({ super.key, required this.text, this.onPressed, this.isLoading = false, this.isFullWidth = true, this.gradient, this.icon, this.height = 48, }); /// CTA 按钮 - 使用主题渐变 factory GradientButton.cta({ Key? key, required String text, VoidCallback? onPressed, bool isLoading = false, bool isFullWidth = true, IconData? icon, bool isDark = true, }) { return GradientButton( key: key, text: text, onPressed: onPressed, isLoading: isLoading, isFullWidth: isFullWidth, icon: icon, gradient: isDark ? AppColorScheme.darkCtaGradient : AppColorScheme.lightCtaGradient, ); } /// 买入按钮 - 翡翠绿渐变 factory GradientButton.buy({ Key? key, required String text, VoidCallback? onPressed, bool isLoading = false, bool isFullWidth = true, IconData? icon, }) { return GradientButton( key: key, text: text, onPressed: onPressed, isLoading: isLoading, isFullWidth: isFullWidth, icon: icon ?? Icons.arrow_downward_rounded, gradient: AppColorScheme.buyGradient, ); } /// 卖出按钮 - 红色渐变 factory GradientButton.sell({ Key? key, required String text, VoidCallback? onPressed, bool isLoading = false, bool isFullWidth = true, IconData? icon, }) { return GradientButton( key: key, text: text, onPressed: onPressed, isLoading: isLoading, isFullWidth: isFullWidth, icon: icon ?? Icons.arrow_upward_rounded, gradient: AppColorScheme.sellGradient, ); } @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final colorScheme = Theme.of(context).colorScheme; final buttonGradient = gradient ?? (isDark ? AppColorScheme.darkCtaGradient : AppColorScheme.lightCtaGradient); // 主题感知颜色 - 在渐变背景上使用 onPrimary final textColor = colorScheme.onPrimary; return Container( width: isFullWidth ? double.infinity : null, height: height, decoration: BoxDecoration( gradient: buttonGradient, borderRadius: BorderRadius.circular(AppRadius.xxl), ), child: Material( color: Colors.transparent, child: InkWell( onTap: isLoading ? null : onPressed, borderRadius: BorderRadius.circular(AppRadius.xxl), child: Center( child: Row( mainAxisSize: isFullWidth ? MainAxisSize.max : MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ if (isLoading) SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: textColor, ), ) else ...[ if (icon != null) ...[ Icon(icon, size: 18, color: textColor), SizedBox(width: AppSpacing.sm), ], Text( text, style: TextStyle( color: textColor, fontSize: 16, fontWeight: FontWeight.w600, ), ), ], ], ), ), ), ), ); } } /// Ghost 按钮 - 次要操作 /// /// 设计规则: /// - Ghost Border: 15% opacity outline-variant /// - 圆角: xxl (24px) /// - 主色文字 class GhostButton extends StatelessWidget { final String text; final VoidCallback? onPressed; final bool isLoading; final bool isFullWidth; final IconData? icon; const GhostButton({ super.key, required this.text, this.onPressed, this.isLoading = false, this.isFullWidth = true, this.icon, }); @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final textColor = isDark ? AppColorScheme.darkPrimary : AppColorScheme.lightPrimary; final borderColor = isDark ? AppColorScheme.darkOutlineVariant.withValues(alpha: 0.15) : AppColorScheme.lightOutlineVariant.withValues(alpha: 0.3); return Container( width: isFullWidth ? double.infinity : null, height: 48, decoration: BoxDecoration( color: Colors.transparent, border: Border.all(color: borderColor, width: 1), borderRadius: BorderRadius.circular(AppRadius.xxl), ), child: Material( color: Colors.transparent, child: InkWell( onTap: isLoading ? null : onPressed, borderRadius: BorderRadius.circular(AppRadius.xxl), child: Center( child: Row( mainAxisSize: isFullWidth ? MainAxisSize.max : MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ if (isLoading) SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: textColor, ), ) else ...[ if (icon != null) ...[ Icon(icon, size: 18, color: textColor), SizedBox(width: AppSpacing.sm), ], Text( text, style: TextStyle( color: textColor, fontSize: 16, fontWeight: FontWeight.w600, ), ), ], ], ), ), ), ), ); } }