import 'package:flutter/material.dart'; import 'package:lucide_icons/lucide_icons.dart'; /// Contextual help icon that shows a bottom sheet with help content /// /// Usage: /// ```dart /// ContextualHelpIcon( /// title: 'レベルと称号について', /// content: 'レベルの上げ方の説明...', /// ) /// ``` class ContextualHelpIcon extends StatelessWidget { final String title; final String? content; final Widget? customContent; // For complex help (tables, images) const ContextualHelpIcon({ super.key, required this.title, this.content, this.customContent, }) : assert(content != null || customContent != null, 'Either content or customContent must be provided'); @override Widget build(BuildContext context) { return IconButton( icon: Icon( LucideIcons.helpCircle, size: 18, color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.6), ), tooltip: 'ヘルプを表示', onPressed: () => _showHelpSheet(context), padding: EdgeInsets.zero, constraints: const BoxConstraints( minWidth: 32, minHeight: 32, ), ); } void _showHelpSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), builder: (context) => DraggableScrollableSheet( initialChildSize: 0.6, minChildSize: 0.4, maxChildSize: 0.9, expand: false, builder: (context, scrollController) => _HelpSheetContent( title: title, content: content, customContent: customContent, scrollController: scrollController, ), ), ); } } class _HelpSheetContent extends StatelessWidget { final String title; final String? content; final Widget? customContent; final ScrollController scrollController; const _HelpSheetContent({ required this.title, this.content, this.customContent, required this.scrollController, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(24), child: ListView( controller: scrollController, children: [ // Drag handle Center( child: Container( width: 40, height: 4, margin: const EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(2), ), ), ), // Title Row( children: [ Icon( LucideIcons.helpCircle, color: Theme.of(context).colorScheme.primary, ), const SizedBox(width: 12), Expanded( child: Text( title, style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 16), const Divider(), const SizedBox(height: 16), // Content if (customContent != null) customContent! else if (content != null) Text( content!, style: Theme.of(context).textTheme.bodyLarge?.copyWith( height: 1.6, ), ), const SizedBox(height: 24), // Close button FilledButton.tonal( onPressed: () => Navigator.pop(context), child: const Text('閉じる'), ), ], ), ); } }