Code
// FlockUI Component: Bottom Sheet (Default)
// Description: A draggable modal bottom sheet with a handle bar, title, description, and action buttons.
// Category: Overlays
// External Dependencies: none
//
// This is a template component. When creating new components, follow this structure:
// 1. Add header comments describing your component
// 2. The class must extend `StatefulWidget` — you can name it anything you like
// 3. If using external packages, list them in the header comments above
// 4. Keep the entire component in a single .dart file
import 'package:flutter/material.dart';
class BottomSheetDemo extends StatefulWidget {
const BottomSheetDemo({super.key});
@override
State<BottomSheetDemo> createState() => _BottomSheetDemoState();
}
class _BottomSheetDemoState extends State<BottomSheetDemo> {
void _showBottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (context) {
return Padding(
padding: const EdgeInsets.fromLTRB(24, 12, 24, 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Handle bar
Container(
width: 40,
height: 4,
margin: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(2),
),
),
// Icon
Container(
width: 64,
height: 64,
decoration: BoxDecoration(
color: const Color(0xFF4F46E5).withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(16),
),
child: const Icon(
Icons.share_outlined,
size: 32,
color: Color(0xFF4F46E5),
),
),
const SizedBox(height: 20),
// Title
const Text(
'Share this content',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w700,
color: Color(0xFF1F2937),
),
),
const SizedBox(height: 8),
// Description
const Text(
'Choose how you\'d like to share this content with others.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
color: Color(0xFF6B7280),
height: 1.4,
),
),
const SizedBox(height: 24),
// Share options row
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildShareOption(Icons.chat_bubble_outline, 'Messages'),
_buildShareOption(Icons.email_outlined, 'Email'),
_buildShareOption(Icons.link, 'Copy Link'),
_buildShareOption(Icons.more_horiz, 'More'),
],
),
const SizedBox(height: 28),
// Action buttons
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF4F46E5),
foregroundColor: Colors.white,
elevation: 0,
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text(
'Share',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
),
),
const SizedBox(height: 10),
// Cancel button
SizedBox(
width: double.infinity,
child: TextButton(
onPressed: () => Navigator.pop(context),
style: TextButton.styleFrom(
foregroundColor: const Color(0xFF6B7280),
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text(
'Cancel',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
);
},
);
}
Widget _buildShareOption(IconData icon, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 52,
height: 52,
decoration: BoxDecoration(
color: const Color(0xFFF3F4F6),
borderRadius: BorderRadius.circular(14),
),
child: Icon(icon, size: 24, color: const Color(0xFF4B5563)),
),
const SizedBox(height: 6),
Text(
label,
style: const TextStyle(
fontSize: 12,
color: Color(0xFF6B7280),
fontWeight: FontWeight.w500,
),
),
],
);
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: SizedBox(
width: 260,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Preview label
Text(
'Tap the button to see the bottom sheet',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 16),
// Trigger button
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: _showBottomSheet,
icon: const Icon(Icons.share_outlined, size: 18),
label: const Text('Open Share Sheet'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF4F46E5),
foregroundColor: Colors.white,
elevation: 0,
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
),
],
),
),
);
}
}
Preview