Skip to main content

AsBottomSheet

A modal bottom sheet component that slides up from the bottom of the screen for contextual actions and content.

Import

import 'package:alphasow_ui/alphasow_ui.dart';

Basic Usage

AsBottomSheet.show(
context: context,
builder: (context) => Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Bottom Sheet Content'),
SizedBox(height: 16),
AsButton(
onPressed: () => Navigator.pop(context),
child: Text('Close'),
),
],
),
),
)

Action Bottom Sheet

void _showActionSheet() {
AsBottomSheet.show(
context: context,
builder: (context) => AsBottomSheet(
title: 'Choose Action',
actions: [
AsBottomSheetAction(
icon: Icons.share,
title: 'Share',
onPressed: () {
Navigator.pop(context);
_shareContent();
},
),
AsBottomSheetAction(
icon: Icons.edit,
title: 'Edit',
onPressed: () {
Navigator.pop(context);
_editContent();
},
),
AsBottomSheetAction(
icon: Icons.delete,
title: 'Delete',
isDestructive: true,
onPressed: () {
Navigator.pop(context);
_deleteContent();
},
),
],
),
);
}

Scrollable Bottom Sheet

AsBottomSheet.show(
context: context,
isScrollControlled: true,
builder: (context) => DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
color: Theme.of(context).scaffoldBackgroundColor,
),
child: ListView(
controller: scrollController,
children: [
// Handle bar
Container(
width: 40,
height: 4,
margin: EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: Colors.grey,
),
),
// Content
...List.generate(20, (index) => ListTile(
title: Text('Item $index'),
)),
],
),
),
),
)
void _showFormBottomSheet() {
AsBottomSheet.show(
context: context,
isScrollControlled: true,
builder: (context) => Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Add New Item',
style: Theme.of(context).textTheme.headlineSmall,
),
SizedBox(height: 16),
AsTextField(
labelText: 'Name',
onChanged: (value) {},
),
SizedBox(height: 16),
AsTextField(
labelText: 'Description',
maxLines: 3,
onChanged: (value) {},
),
SizedBox(height: 16),
Row(
children: [
Expanded(
child: AsButton(
style: AsButtonStyle.secondary,
onPressed: () => Navigator.pop(context),
child: Text('Cancel'),
),
),
SizedBox(width: 16),
Expanded(
child: AsButton(
onPressed: () {
Navigator.pop(context);
_addItem();
},
child: Text('Add'),
),
),
],
),
],
),
),
),
);
}

API Reference

AsBottomSheet Properties

PropertyTypeDefaultDescription
titleString?nullBottom sheet title
actionsList<AsBottomSheetAction>?nullList of action items
childWidget?nullCustom child widget
backgroundColorColor?nullBackground color
borderRadiusBorderRadius?nullBorder radius

AsBottomSheet.show Parameters

ParameterTypeDefaultDescription
contextBuildContextrequiredBuild context
builderWidgetBuilderrequiredBuilder function
isScrollControlledboolfalseWhether sheet can be scrolled
isDismissiblebooltrueWhether sheet can be dismissed
enableDragbooltrueWhether sheet can be dragged
backgroundColorColor?nullBackground color
elevationdouble?nullShadow elevation
shapeShapeBorder?nullCustom shape

AsBottomSheetAction Properties

PropertyTypeDefaultDescription
iconIconDatarequiredAction icon
titleStringrequiredAction title
onPressedVoidCallbackrequiredAction callback
isDestructiveboolfalseWhether action is destructive

Examples

Settings Bottom Sheet

void _showSettingsSheet() {
AsBottomSheet.show(
context: context,
builder: (context) => AsBottomSheet(
title: 'Settings',
actions: [
AsBottomSheetAction(
icon: Icons.account_circle,
title: 'Account',
onPressed: () {
Navigator.pop(context);
_openAccount();
},
),
AsBottomSheetAction(
icon: Icons.notifications,
title: 'Notifications',
onPressed: () {
Navigator.pop(context);
_openNotifications();
},
),
AsBottomSheetAction(
icon: Icons.privacy_tip,
title: 'Privacy',
onPressed: () {
Navigator.pop(context);
_openPrivacy();
},
),
AsBottomSheetAction(
icon: Icons.help,
title: 'Help',
onPressed: () {
Navigator.pop(context);
_openHelp();
},
),
],
),
);
}

Photo Options Sheet

void _showPhotoOptions() {
AsBottomSheet.show(
context: context,
builder: (context) => AsBottomSheet(
title: 'Select Photo',
actions: [
AsBottomSheetAction(
icon: Icons.camera_alt,
title: 'Take Photo',
onPressed: () {
Navigator.pop(context);
_takePhoto();
},
),
AsBottomSheetAction(
icon: Icons.photo_library,
title: 'Choose from Library',
onPressed: () {
Navigator.pop(context);
_chooseFromLibrary();
},
),
AsBottomSheetAction(
icon: Icons.delete,
title: 'Remove Photo',
isDestructive: true,
onPressed: () {
Navigator.pop(context);
_removePhoto();
},
),
],
),
);
}

Filter Bottom Sheet

class FilterBottomSheet extends StatefulWidget {
@override
_FilterBottomSheetState createState() => _FilterBottomSheetState();
}

class _FilterBottomSheetState extends State<FilterBottomSheet> {
String _selectedCategory = 'All';
double _priceRange = 100;
bool _inStock = false;

@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Filters',
style: Theme.of(context).textTheme.headlineSmall,
),
SizedBox(height: 16),

// Category filter
Text('Category'),
DropdownButton<String>(
value: _selectedCategory,
items: ['All', 'Electronics', 'Clothing', 'Books']
.map((e) => DropdownMenuItem(value: e, child: Text(e)))
.toList(),
onChanged: (value) {
setState(() => _selectedCategory = value!);
},
),

SizedBox(height: 16),

// Price range
Text('Max Price: \$${_priceRange.round()}'),
Slider(
value: _priceRange,
max: 500,
divisions: 10,
onChanged: (value) {
setState(() => _priceRange = value);
},
),

// In stock filter
AsCheckbox(
value: _inStock,
label: 'In Stock Only',
onChanged: (value) {
setState(() => _inStock = value ?? false);
},
),

SizedBox(height: 16),

// Actions
Row(
children: [
Expanded(
child: AsButton(
style: AsButtonStyle.secondary,
onPressed: () {
setState(() {
_selectedCategory = 'All';
_priceRange = 100;
_inStock = false;
});
},
child: Text('Reset'),
),
),
SizedBox(width: 16),
Expanded(
child: AsButton(
onPressed: () {
Navigator.pop(context, {
'category': _selectedCategory,
'price': _priceRange,
'inStock': _inStock,
});
},
child: Text('Apply'),
),
),
],
),
],
),
);
}
}

Platform Differences

Material (Android/Web)

  • Uses showModalBottomSheet with Material styling
  • Material Design animations
  • Material elevation and shadows

Cupertino (iOS/macOS)

  • Uses CupertinoActionSheet for action sheets
  • iOS-style animations and transitions
  • Native iOS appearance

Best Practices

  1. Use for contextual actions - Bottom sheets work best for actions related to current content
  2. Keep it simple - Don't overload with too many options
  3. Handle keyboard - Use isScrollControlled: true for forms
  4. Provide handle - Add visual drag handle for scrollable sheets
  5. Consider alternatives - Use dialogs for critical decisions

See Also