grabber_sheet 1.2.1
grabber_sheet: ^1.2.1 copied to clipboard
Stop fighting gesture conflicts. A production-ready bottom sheet with a persistent grabber that just works.
GrabberSheet #
Stop fighting gesture conflicts. A production-ready bottom sheet with a persistent grabber that just works.
🚀 Installation #
flutter pub add grabber_sheet
⚡ Usage (3 Lines of Code) #
Wrap your list, connect the controller. Done.
GrabberSheet(
snap: true,
builder: (context, controller) {
return ListView.builder(
controller: controller, // <--- Key Step: Connect this!
itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
);
},
)
💡 Why GrabberSheet? #
You've probably faced it: DraggableScrollableSheet gesture conflicts.
The list scrolls when you want to drag the sheet. The header disappears. It feels "janky."
GrabberSheet solves these pain points instantly.
| Pain Point | DraggableScrollableSheet | GrabberSheet |
|---|---|---|
| Gesture Conflicts | ⚠️ Scrolls when you want to Drag | ✅ Zero Conflict (Perfectly separated) |
| Header / Grabber | ❌ Build it yourself (Hard) | ✅ Built-in & Persistent |
| Snapping | ⚠️ Complex math required | ✅ One Parameter (snap: true) |
| Dev Experience | 🔥 Frustrating | 🍰 Plug & Play |
🎨 Advanced Customization #
1. Smart Snapping #
Enable snap: true for a polished feel. It handles both slow drags (closest point) and fast flings (momentum) automatically.
GrabberSheet(
snap: true,
minChildSize: 0.2,
maxChildSize: 1.0,
snapSizes: const [0.5], // Add intermediate snap points
// ...
)
2. Custom Grabber Styling #
Match your app's design system effortlessly.
GrabberSheet(
grabberStyle: GrabberStyle(
width: 60,
height: 6,
color: Colors.grey.shade300,
radius: const Radius.circular(12),
),
// ...
)
You can also hide the grabber completely (showGrabber: false).
3. Fixed Header (Non-Scrollable Area) #
Need a title or close button that always stays visible? Use the bottom property.
GrabberSheet(
bottom: Row(
children: [
Text('Locations', style: TextStyle(fontSize: 18)),
Spacer(),
CloseButton(),
],
),
// ...
)
4. Programmatic Control #
Open, close, or snap to specific sizes using GrabberSheetController.
final controller = GrabberSheetController();
// ...
controller.maximize(); // Go to maxChildSize
controller.minimize(); // Go to minChildSize
controller.animateTo(0.5); // Go to 50%
5. Desktop & Web Support #
By default, the grabber is hidden on desktop/web (standard UI pattern). Force it visible if needed:
GrabberSheet(
showGrabberOnNonMobile: true,
// ...
)
📘 Properties #
| Property | Description | Default |
|---|---|---|
builder |
(Required) Builds content. Must use the provided ScrollController. |
- |
snap |
Enable auto-snapping behavior. | false |
initialChildSize |
Starting height fraction (0.0 - 1.0). | 0.5 |
minChildSize |
Minimum collapsed height. | 0.25 |
maxChildSize |
Maximum expanded height. | 1.0 |
snapSizes |
List of intermediate snap points (e.g. [0.5, 0.8]). |
null |
showGrabber |
Toggle the grabber handle visibility. | true |
grabberStyle |
Customize width, height, color, radius, margin. | Default Style |
bottom |
Widget to display below grabber (Title, Buttons, etc.). | null |
controller |
Control sheet position programmatically. | null |
onSizeChanged |
Callback for size changes during drag/animation. | null |
onSnap |
Callback when snapping completes. | null |
🤝 Contribution #
Found a bug or have a feature request? Please visit the GitHub repository.