import 'package:flutter/cupertino.dart'; import 'package:hum/core/constants/app_theme.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class BTNSquareBG extends StatelessWidget { final IconData icon; final VoidCallback action; const BTNSquareBG({super.key, required this.icon, required this.action}); @override Widget build(BuildContext context) { return CupertinoButton( color: CupertinoDynamicColor.resolve(colorBarButton, context), borderRadius: BorderRadius.circular(10), padding: EdgeInsets.zero, onPressed: action, child: Icon( size: 18, color: CupertinoDynamicColor.resolve( colorAccentSecondary, // 👈 define as dynamic in your theme context, ), icon, ), ); } } class BTNRoundBG extends StatelessWidget { final IconData icon; final VoidCallback action; const BTNRoundBG({super.key, required this.icon, required this.action}); @override Widget build(BuildContext context) { return CupertinoButton( color: CupertinoDynamicColor.resolve(colorBarButton, context), borderRadius: BorderRadius.circular(16), padding: EdgeInsets.zero, onPressed: action, child: Icon( size: 18, color: CupertinoDynamicColor.resolve( colorAccentSecondary, // 👈 define as dynamic in your theme context, ), icon, ), ); } } class BTNFilled extends StatelessWidget { const BTNFilled({ super.key, this.text = '', this.width = double.infinity, this.color = colorAccentSecondary, required this.action, }); final String text; final double width; final VoidCallback action; final Color color; @override Widget build(BuildContext context) { return SizedBox( width: width, child: CupertinoButton.filled( color: color, borderRadius: BorderRadius.circular(roundLarge), onPressed: action, child: Text(text), ), ); } } class BTNFilledIcon extends StatelessWidget { const BTNFilledIcon({ super.key, this.text = '', this.width = double.infinity, this.color = colorAccentSecondary, this.alignment = MainAxisAlignment.start, required this.icon, required this.action, }); final String text; final double width; final VoidCallback action; final Color color; final IconData icon; final MainAxisAlignment alignment; @override Widget build(BuildContext context) { return SizedBox( width: width, child: CupertinoButton.filled( color: color, borderRadius: BorderRadius.circular(roundLarge), onPressed: action, child: Row( spacing: 14, crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: alignment, children: [PhosphorIcon(icon), Text(text)], ), ), ); } } class BTNComplex extends StatelessWidget { const BTNComplex({ super.key, this.text = 'text', this.label = 'label', this.width = double.infinity, this.color = colorAccentSecondary, this.alignment = MainAxisAlignment.start, this.trailingIcon = CupertinoIcons.right_chevron, this.textColor = CupertinoColors.white, required this.iconLeading, required this.action, }); final String label; final String text; final double width; final VoidCallback action; final Color color; final IconData iconLeading; final IconData trailingIcon; final MainAxisAlignment alignment; final Color textColor; @override Widget build(BuildContext context) { return SizedBox( width: width, child: CupertinoButton.filled( color: color, borderRadius: BorderRadius.circular(roundLarge), onPressed: action, child: Row( spacing: 14, crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: alignment, children: [ Icon(iconLeading), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Opacity(opacity: .6, child: Text(label, style: TextStyle(fontSize: 14))), Text(text, style: TextStyle(color: textColor)), ], ), Spacer(), Opacity(opacity: .4, child: Icon(trailingIcon, size: 18)), ], ), ), ); } } class BTNFilledAnimated extends StatelessWidget { const BTNFilledAnimated({ super.key, this.text = '', this.width = double.infinity, this.color = colorAccentSecondary, this.working = false, required this.action, }); final String text; final double width; final Color color; final bool working; final VoidCallback action; @override Widget build(BuildContext context) { const double spinnerSize = 16; const double gap = 8; const double slotWidth = spinnerSize + gap; // space reserved on both sides return SizedBox( width: width, child: CupertinoButton.filled( color: color, borderRadius: BorderRadius.circular(roundLarge), // Disable tap while working (optional UX) onPressed: working ? null : action, child: Row( mainAxisSize: MainAxisSize.max, children: [ // right slot shows spinner when working, otherwise keeps same width SizedBox( width: slotWidth, child: AnimatedSwitcher( duration: const Duration(milliseconds: 200), transitionBuilder: (child, anim) => FadeTransition(opacity: anim, child: child), child: working ? Align( alignment: Alignment.centerRight, key: const ValueKey('spinner'), child: Padding( padding: const EdgeInsets.only(left: gap), child: CupertinoActivityIndicator(radius: spinnerSize / 2), ), ) : const SizedBox(key: ValueKey('no-spinner')), ), ), // centered label Expanded(child: Center(child: Text(text))), // left spacer to keep text perfectly centered const SizedBox(width: slotWidth), ], ), ), ); } } class BTNText extends StatelessWidget { const BTNText({super.key, this.text = '', required this.action}); final VoidCallback action; final String text; @override Widget build(BuildContext context) { return CupertinoButton(onPressed: action, child: Text(text)); } } // CONTEXT MENU BUTTON class MenuAction { final String label; final IconData? icon; final VoidCallback onPressed; final bool destructive; const MenuAction({ required this.label, required this.onPressed, this.icon, this.destructive = false, }); } class CupertinoMoreButton extends StatelessWidget { final List actions; final double iconSize; final EdgeInsetsGeometry padding; const CupertinoMoreButton({ super.key, required this.actions, this.iconSize = 22, this.padding = EdgeInsets.zero, }); @override Widget build(BuildContext context) { return CupertinoButton( padding: padding, child: Icon(CupertinoIcons.ellipsis_vertical, size: iconSize), onPressed: () => _showMenu(context), ); } void _showMenu(BuildContext context) { showCupertinoModalPopup( context: context, builder: (ctx) => CupertinoActionSheet( actions: actions.map((a) { final text = Text(a.label); final row = a.icon == null ? text : Row( mainAxisAlignment: MainAxisAlignment.center, children: [Icon(a.icon, size: 18), const SizedBox(width: 8), text], ); return CupertinoActionSheetAction( isDestructiveAction: a.destructive, onPressed: () { Navigator.of(ctx).pop(); a.onPressed(); }, child: row, ); }).toList(), cancelButton: CupertinoActionSheetAction( onPressed: () => Navigator.of(ctx).pop(), isDefaultAction: true, child: const Text('Cancel'), ), ), ); } }