import 'package:flutter/material.dart'; import '../../about/internal/application/TextType.dart'; import '../../utils/Colors.dart'; import '../text/Text.dart'; /// The primary action. One per screen — if a screen appears to need two, one /// of them is secondary. Widget roundedCornerButton( String label, VoidCallback onPressed, { Color? background, Color? foreground, IconData? icon, bool enabled = true, double radius = 14, double verticalPadding = 16, }) { final Color bg = enabled ? (background ?? colorPrimaryDark) : colorGrey; final Color fg = foreground ?? colorWhite; return ElevatedButton( onPressed: enabled ? onPressed : null, style: ElevatedButton.styleFrom( elevation: 0, backgroundColor: bg, disabledBackgroundColor: colorGrey.withValues(alpha: 0.4), padding: EdgeInsets.symmetric(vertical: verticalPadding), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radius), ), ), child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ if (icon != null) ...[ Icon(icon, size: 16, color: fg), const SizedBox(width: 8), ], text(label, 14, TextType.Bold, color: fg), ], ), ); } /// The secondary action — outlined, never filled, so the hierarchy is never /// ambiguous. Widget outlinedActionButton( String label, VoidCallback onPressed, { Color? foreground, IconData? icon, bool enabled = true, double radius = 14, }) { final Color fg = enabled ? (foreground ?? colorPrimaryDark) : colorGrey; return OutlinedButton( onPressed: enabled ? onPressed : null, style: OutlinedButton.styleFrom( side: BorderSide(color: fg.withValues(alpha: 0.35), width: 1), padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(radius), ), ), child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ if (icon != null) ...[ Icon(icon, size: 16, color: fg), const SizedBox(width: 8), ], text(label, 14, TextType.Bold, color: fg), ], ), ); } Widget textButton( String label, VoidCallback onPressed, { Color? color, double textSize = 13, TextType type = TextType.Regular, }) { return TextButton( onPressed: onPressed, child: text(label, textSize, type, color: color ?? colorGrey2), ); } Widget iconButton( Widget icon, VoidCallback onPressed, { bool bordered = false, Color? borderColor, Color? background, double radius = 10, double size = 38, }) { return GestureDetector( onTap: onPressed, child: Container( width: size, height: size, alignment: Alignment.center, decoration: BoxDecoration( color: background ?? Colors.transparent, borderRadius: BorderRadius.circular(radius), border: bordered ? Border.all(color: borderColor ?? colorBorder, width: 1) : null, ), child: icon, ), ); } /// The destructive action — abandoning, which costs the most debt of all and /// so is always visually distinct from completing. Widget destructiveButton( String label, VoidCallback onPressed, { IconData? icon, bool enabled = true, }) { return roundedCornerButton( label, onPressed, background: colorDestructive, foreground: colorWhite, icon: icon, enabled: enabled, ); } /// A segmented selector, used for class, energy, proof type and tone. Widget segmentedSelector({ required List options, required T selected, required String Function(T) label, required void Function(T) onSelected, Color? activeColor, }) { final Color active = activeColor ?? colorPrimaryDark; return Wrap( spacing: 8, runSpacing: 8, children: options.map((option) { final bool isSelected = option == selected; return GestureDetector( onTap: () => onSelected(option), child: Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration( color: isSelected ? active : colorWhite, borderRadius: BorderRadius.circular(10), border: Border.all( color: isSelected ? active : colorBorder, width: 1, ), ), child: text( label(option), 12, isSelected ? TextType.Bold : TextType.Regular, color: isSelected ? colorWhite : colorGrey2, ), ), ); }).toList(), ); }