Scrollable Content

The core challenge of any bottom sheet: when scrollable content reaches the top and you keep pulling down, the sheet should follow your finger. GlideSheet handles this natively.

How it works

Just put scrollable content (overflow-y: auto) inside the sheet. GlideSheet detects when the scroll container hits the top and seamlessly transitions to sheet drag — no rubber-band bounce, no jerky transitions.

<BottomSheet.Content>
  <BottomSheet.Handle />
  <div className="overflow-y-auto flex-1">
    {/* Long list or content */}
    {items.map(item => (
      <div key={item.id}>{item.name}</div>
    ))}
  </div>
</BottomSheet.Content>

What makes it different

Most bottom sheet libraries struggle with the scroll-to-drag transition. Common problems include:

  • Rubber-band bouncing when pulling down at scroll top
  • The sheet ignoring the gesture entirely
  • A visible "jump" when transitioning from scroll to drag
  • Requiring touchAction: none workarounds

GlideSheet uses pointer events and a scroll-lock mechanism to detect the exact moment scrolling should become dragging. The transition is invisible to the user.

Handle-only drag

If you want to prevent the content area from triggering drag (useful for interactive elements like maps or canvases), set handleOnly on the Root:

<BottomSheet.Root handleOnly>
  {/* Only the Handle triggers drag */}
</BottomSheet.Root>

Opting out specific elements

Add data-glidesheet-no-drag to any element that should not trigger the sheet drag:

{/* This element won't trigger sheet drag */}
<div data-glidesheet-no-drag>
  <canvas />  {/* interactive canvas */}
  <input type="range" />  {/* sliders */}
</div>