import 'package:flutter/material.dart'; import '../../theme/app_theme.dart'; class ExpandableCard extends StatefulWidget { final Widget header; final Widget child; final bool initiallyExpanded; final Color? backgroundColor; final Color? borderColor; const ExpandableCard({ super.key, required this.header, required this.child, this.initiallyExpanded = false, this.backgroundColor, this.borderColor, }); @override State createState() => _ExpandableCardState(); } class _ExpandableCardState extends State with SingleTickerProviderStateMixin { late bool _expanded; late AnimationController _controller; late Animation _rotation; @override void initState() { super.initState(); _expanded = widget.initiallyExpanded; _controller = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, value: _expanded ? 1.0 : 0.0, ); _rotation = Tween(begin: 0, end: 0.25).animate( CurvedAnimation(parent: _controller, curve: Curves.easeInOut), ); } @override void dispose() { _controller.dispose(); super.dispose(); } void _toggle() { setState(() { _expanded = !_expanded; if (_expanded) { _controller.forward(); } else { _controller.reverse(); } }); } @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: widget.backgroundColor ?? AppColors.surface, borderRadius: BorderRadius.circular(8), border: Border.all( color: widget.borderColor ?? AppColors.surfaceBorder, width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ InkWell( onTap: _toggle, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), child: Row( children: [ RotationTransition( turns: _rotation, child: const Icon( Icons.chevron_right, size: 18, color: AppColors.textSecondary, ), ), const SizedBox(width: 8), Expanded(child: widget.header), ], ), ), ), ClipRect( child: AnimatedCrossFade( firstChild: const SizedBox.shrink(), secondChild: Padding( padding: const EdgeInsets.fromLTRB(12, 0, 12, 12), child: widget.child, ), crossFadeState: _expanded ? CrossFadeState.showSecond : CrossFadeState.showFirst, duration: const Duration(milliseconds: 200), ), ), ], ), ); } }