import 'package:flutter/material.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; /// GlassPanel - 實心背景面板 /// /// Material Design 3 風格的實心背景容器 /// 用於卡片、彈窗、底部抽屜等需要清晰背景的容器 /// /// 示例: /// ```dart /// GlassPanel( /// child: Text('內容'), /// ) /// ``` class GlassPanel extends StatelessWidget { /// 子組件 final Widget child; /// 背景色,默認使用 surfaceContainer final Color? backgroundColor; /// 邊框色 final Color? borderColor; /// 圓角,默認特大圓角 final BorderRadius? borderRadius; /// 內邊距 final EdgeInsetsGeometry? padding; /// 外邊距 final EdgeInsetsGeometry? margin; /// 寬度 final double? width; /// 高度 final double? height; /// 是否顯示邊框 final bool showBorder; const GlassPanel({ super.key, required this.child, this.backgroundColor, this.borderColor, this.borderRadius, this.padding, this.margin, this.width, this.height, this.showBorder = true, }); @override Widget build(BuildContext context) { final bgColor = backgroundColor ?? context.appColors.surfaceCard; final brColor = borderColor ?? context.appColors.ghostBorder; final br = borderRadius ?? BorderRadius.circular(AppRadius.xl); Widget content = Container( width: width, height: height, padding: padding ?? EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: bgColor, borderRadius: br, border: showBorder ? Border.all( color: brColor, width: 1, ) : null, ), child: child, ); if (margin != null) { content = Padding( padding: margin!, child: content, ); } return content; } } /// GlassCard - 帶實心背景的卡片 /// /// 用於列表項、信息展示等場景 /// 預設了常用配置,簡化使用 class GlassCard extends StatelessWidget { /// 子組件 final Widget child; /// 點擊回調 final VoidCallback? onTap; /// 長按回調 final VoidCallback? onLongPress; /// 內邊距 final EdgeInsetsGeometry? padding; /// 外邊距 final EdgeInsetsGeometry? margin; /// 圓角 final BorderRadius? borderRadius; /// 是否顯示霓虹光效 final bool showNeonGlow; /// 霓虹光效顏色 final Color? neonGlowColor; const GlassCard({ super.key, required this.child, this.onTap, this.onLongPress, this.padding, this.margin, this.borderRadius, this.showNeonGlow = false, this.neonGlowColor, }); @override Widget build(BuildContext context) { final br = borderRadius ?? BorderRadius.circular(AppRadius.xl); final glowColor = neonGlowColor ?? context.colors.primary.withValues(alpha: context.appColors.glowOpacity); Widget card = GlassPanel( padding: padding ?? EdgeInsets.all(AppSpacing.md), margin: margin, borderRadius: br, child: child, ); if (showNeonGlow) { card = Container( decoration: BoxDecoration( borderRadius: br, boxShadow: [ BoxShadow( color: glowColor, blurRadius: 15, spreadRadius: 0, ), ], ), child: card, ); } if (onTap != null || onLongPress != null) { return GestureDetector( onTap: onTap, onLongPress: onLongPress, child: card, ); } return card; } } /// GlassBottomSheet - 實心背景底部抽屜 /// /// 用於彈出的底部面板 class GlassBottomSheet extends StatelessWidget { /// 子組件 final Widget child; /// 標題 final String? title; /// 是否顯示關閉按鈕 final bool showCloseButton; /// 內邊距 final EdgeInsetsGeometry? padding; const GlassBottomSheet({ super.key, required this.child, this.title, this.showCloseButton = true, this.padding, }); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: context.appColors.surfaceCard, borderRadius: const BorderRadius.vertical( top: Radius.circular(AppRadius.xxl), ), border: Border.all( color: context.appColors.ghostBorder, ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 頂部拖動條 Container( margin: const EdgeInsets.only(top: 12, bottom: 8), width: 40, height: 4, decoration: BoxDecoration( color: context.colors.outlineVariant.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(2), ), ), // 標題欄 if (title != null || showCloseButton) Padding( padding: EdgeInsets.fromLTRB( AppSpacing.lg, AppSpacing.sm, AppSpacing.sm, AppSpacing.md, ), child: Row( children: [ if (title != null) Expanded( child: Text( title!, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: context.colors.onSurface, ), ), ), if (showCloseButton) GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( padding: EdgeInsets.all(AppSpacing.sm), decoration: BoxDecoration( color: context.colors.outlineVariant .withOpacity(0.2), shape: BoxShape.circle, ), child: Icon( Icons.close, size: 18, color: context.colors.onSurfaceVariant, ), ), ), ], ), ), // 內容 Padding( padding: padding ?? EdgeInsets.fromLTRB( AppSpacing.lg, 0, AppSpacing.lg, AppSpacing.xl, ), child: child, ), ], ), ); } /// 顯示底部抽屜 static Future show({ required BuildContext context, required Widget Function(BuildContext) builder, bool isScrollControlled = false, bool isDismissible = true, bool enableDrag = true, }) { return showModalBottomSheet( context: context, isScrollControlled: isScrollControlled, isDismissible: isDismissible, enableDrag: enableDrag, backgroundColor: Colors.transparent, builder: builder, ); } }