diff --git a/packages/komodo_ui/lib/src/defi/withdraw/withdraw_error_display.dart b/packages/komodo_ui/lib/src/defi/withdraw/withdraw_error_display.dart index 35c68f3b..45a990fb 100644 --- a/packages/komodo_ui/lib/src/defi/withdraw/withdraw_error_display.dart +++ b/packages/komodo_ui/lib/src/defi/withdraw/withdraw_error_display.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -class ErrorDisplay extends StatelessWidget { +class ErrorDisplay extends StatefulWidget { const ErrorDisplay({ required this.message, this.icon, @@ -22,19 +22,32 @@ class ErrorDisplay extends StatelessWidget { final String? detailedMessage; final bool showDetails; + @override + State createState() => _ErrorDisplayState(); +} + +class _ErrorDisplayState extends State { + bool showDetailedMessage = false; + + /// Shows the detailed error message if the override is true, or if the user + /// has toggled the detailed message to be shown. + bool get shouldShowDetailedMessage => + widget.detailedMessage != null && + (widget.showDetails || showDetailedMessage); + @override Widget build(BuildContext context) { final theme = Theme.of(context); // Determine color based on whether this is a warning or error final color = - isWarning ? theme.colorScheme.tertiary : theme.colorScheme.error; + widget.isWarning ? theme.colorScheme.tertiary : theme.colorScheme.error; // Determine background and container design final backgroundColor = - isWarning - ? theme.colorScheme.tertiaryContainer.withOpacity(0.7) - : theme.colorScheme.errorContainer.withOpacity(0.7); + widget.isWarning + ? theme.colorScheme.tertiaryContainer.withValues(alpha: 0.7) + : theme.colorScheme.errorContainer.withValues(alpha: 0.7); return Card( elevation: 0, @@ -50,8 +63,8 @@ class ErrorDisplay extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( - icon ?? - (isWarning + widget.icon ?? + (widget.isWarning ? Icons.warning_amber_rounded : Icons.error_outline), color: color, @@ -62,64 +75,94 @@ class ErrorDisplay extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - message, - style: theme.textTheme.titleSmall?.copyWith( - color: - isWarning - ? theme.colorScheme.onTertiaryContainer - : theme.colorScheme.onErrorContainer, - fontWeight: FontWeight.bold, - ), - ), - if (detailedMessage != null && showDetails) ...[ - const SizedBox(height: 8), - Text( - detailedMessage!, - style: theme.textTheme.bodySmall?.copyWith( - color: - isWarning - ? theme.colorScheme.onTertiaryContainer - .withOpacity(0.8) - : theme.colorScheme.onErrorContainer - .withOpacity(0.8), + Row( + children: [ + Expanded( + child: Text( + widget.message, + style: theme.textTheme.titleSmall?.copyWith( + color: + widget.isWarning + ? theme.colorScheme.onTertiaryContainer + : theme.colorScheme.onErrorContainer, + fontWeight: FontWeight.bold, + ), + ), ), - ), - ], + if (widget.detailedMessage != null) + TextButton( + onPressed: () { + // If the widget showDetails override is present, then + // we don't want to toggle the showDetailedMessage state + if (widget.showDetails) { + return; + } + + setState(() { + showDetailedMessage = !showDetailedMessage; + }); + }, + child: Text( + shouldShowDetailedMessage + ? 'Hide Details' + : 'Show Details', + style: TextStyle(color: color), + ), + ), + ], + ), + AnimatedSize( + duration: const Duration(milliseconds: 200), + curve: Curves.easeInOut, + child: + shouldShowDetailedMessage + ? Padding( + padding: const EdgeInsets.only(top: 8), + child: SelectableText( + widget.detailedMessage!, + style: theme.textTheme.bodySmall?.copyWith( + color: + widget.isWarning + ? theme + .colorScheme + .onTertiaryContainer + .withValues(alpha: 0.8) + : theme + .colorScheme + .onErrorContainer + .withValues(alpha: 0.8), + ), + ), + ) + : const SizedBox.shrink(), + ), ], ), ), ], ), - if (child != null) ...[const SizedBox(height: 16), child!], - if (actionLabel != null && onActionPressed != null) ...[ + if (widget.child != null) ...[ + const SizedBox(height: 16), + widget.child!, + ], + ...[ const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - if (detailedMessage != null) - TextButton( - onPressed: () { - // Show detailed error message or toggle visibility - // This would need state management in a StatefulWidget - }, - child: Text( - showDetails ? 'Hide Details' : 'Show Details', - style: TextStyle(color: color), + if (widget.actionLabel != null && + widget.onActionPressed != null) + ElevatedButton( + onPressed: widget.onActionPressed, + style: ElevatedButton.styleFrom( + backgroundColor: color, + foregroundColor: + widget.isWarning + ? theme.colorScheme.onTertiary + : theme.colorScheme.onError, ), + child: Text(widget.actionLabel!), ), - const SizedBox(width: 12), - ElevatedButton( - onPressed: onActionPressed, - style: ElevatedButton.styleFrom( - backgroundColor: color, - foregroundColor: - isWarning - ? theme.colorScheme.onTertiary - : theme.colorScheme.onError, - ), - child: Text(actionLabel!), - ), ], ), ],