/// Minimal stand-ins for the FaiEmptyState + ChainErrorBox /// widgets Studio ships. The editor brings its own so the /// package compiles standalone — host-styled variants are /// a future plugin-API extension. library; import 'package:flutter/material.dart'; import 'tokens.dart'; class FaiEmptyState extends StatelessWidget { final IconData icon; final String title; final String? hint; /// Optional action rendered under the hint (e.g. the empty flow /// list's "import example flows" button). final Widget? action; const FaiEmptyState({ super.key, required this.icon, required this.title, this.hint, this.action, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Center( child: Padding( padding: const EdgeInsets.all(FaiSpace.xl), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(icon, size: 40, color: theme.colorScheme.onSurfaceVariant), const SizedBox(height: FaiSpace.md), Text( title, style: theme.textTheme.titleMedium, textAlign: TextAlign.center, ), if (hint != null) ...[ const SizedBox(height: FaiSpace.sm), Text( hint!, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), textAlign: TextAlign.center, ), ], if (action != null) ...[ const SizedBox(height: FaiSpace.md), action!, ], ], ), ), ); } } class ChainErrorBox extends StatelessWidget { final Object? error; final bool isError; final double? maxHeight; const ChainErrorBox({ super.key, required this.error, this.isError = true, this.maxHeight, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final fg = isError ? theme.colorScheme.error : theme.colorScheme.onSurface; return Container( constraints: maxHeight == null ? null : BoxConstraints(maxHeight: maxHeight!), padding: const EdgeInsets.all(FaiSpace.md), decoration: BoxDecoration( color: isError ? theme.colorScheme.errorContainer.withValues(alpha: 0.4) : theme.colorScheme.surfaceContainer, borderRadius: BorderRadius.circular(FaiRadius.sm), border: Border.all( color: isError ? theme.colorScheme.error.withValues(alpha: 0.4) : theme.colorScheme.outlineVariant, ), ), child: SingleChildScrollView( child: SelectableText( error?.toString() ?? '', style: TextStyle(fontFamily: 'monospace', fontSize: 12, color: fg), ), ), ); } }