grabber_sheet 1.2.1 copy "grabber_sheet: ^1.2.1" to clipboard
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.

pub.dev Test codecov license

한국어 문서 (Korean Docs)


🚀 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
  // ...
)

snap gif

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%
Example of GrabberSheet with FAB control

5. Desktop & Web Support #

By default, the grabber is hidden on desktop/web (standard UI pattern). Force it visible if needed:

GrabberSheet(
  showGrabberOnNonMobile: true,
  // ...
)

grabber_sheet_web


📘 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.

4
likes
160
points
599
downloads

Publisher

unverified uploader

Weekly Downloads

Stop fighting gesture conflicts. A production-ready bottom sheet with a persistent grabber that just works.

Homepage
Repository (GitHub)
View/report issues

Topics

#bottom-sheet #draggable-sheet #grabber #ui-ux #scrolling

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on grabber_sheet