Scrolling Content
Scrolling content within the sheet works like a regular view — bound the scroll view's height with flex: 1, plug a ScrollView or FlatList in, and point the sheet at it with scrollableRef.
How?
Pass a ref of your scroll view (including ScrollView and FlatList) to the sheet via the scrollableRef prop. Keyboard handling and nested scrolling are then wired for you.
Like any scroll view in React Native, it needs a bounded height to scroll. Pass flex: 1 via the sheet's style prop so the content fills the sheet's visible height per detent — resizing in realtime while dragging:
const App = () => {
const sheet = useRef<TrueSheet>(null)
const scrollableRef = useRef<ScrollView>(null)
return (
<TrueSheet ref={sheet} scrollableRef={scrollableRef} style={{ flex: 1 }} detents={[0.5, 1]}>
<ScrollView ref={scrollableRef}>
<View />
</ScrollView>
</TrueSheet>
)
}
The scroll view doesn't have to be a direct child — wrapping it in a container View works too:
<TrueSheet scrollableRef={scrollableRef} style={{ flex: 1 }} detents={[0.5, 1]}>
<View style={{ flex: 1 }}>
<View>{/* Header content */}</View>
<FlatList ref={scrollableRef} data={data} renderItem={renderItem} />
</View>
</TrueSheet>
On Android, nested scrolling is managed internally — any nestedScrollEnabled prop on your ScrollView or FlatList is ignored. RefreshControl is also fully supported.
The auto detent works with scrolling content too — no flex: 1 needed. The sheet sizes to the scroll view's content height and resizes as content grows or shrinks, while the viewport is automatically bounded to the sheet's visible height.
Bottom Safe-Area Inset
The sheet applies the bottom safe-area inset to your scroll content automatically while the content can scroll — the last item clears the home indicator (iOS) and navigation bar (Android):
- iOS: The scroll view's native
contentInsetAdjustmentBehavioris set toautomaticwhile it's plugged into the sheet — no need to set React Native's iOS-only prop yourself. - Android: The inset is applied as content padding, mirroring iOS's
automaticbehavior — parity React Native's iOS-only prop can't provide. - Web: The content is lifted above the safe area (
env(safe-area-inset-bottom)).
To opt out and manage the padding yourself, set contentInsetAdjustmentBehavior to false in scrollableOptions:
const insets = useSafeAreaInsets()
<TrueSheet
scrollableRef={scrollableRef}
scrollableOptions={{ contentInsetAdjustmentBehavior: false }}
>
<ScrollView ref={scrollableRef} contentContainerStyle={{ paddingBottom: insets.bottom }}>
<View />
</ScrollView>
</TrueSheet>
This only applies while the sheet's insetAdjustment is 'automatic'. If the sheet has a relative footer, the footer absorbs the bottom inset instead — pad your content for the footer's height, not the safe area.
Preventing Scroll-to-Expand
By default, scrolling content to the top edge expands the sheet to the next detent. To disable this (e.g., for YouTube-style comments sheets where only the grabber should expand the sheet), set scrollingExpandsSheet to false:
<TrueSheet
scrollableRef={scrollableRef}
scrollableOptions={{ scrollingExpandsSheet: false }}
detents={[0.5, 1]}
>
<ScrollView ref={scrollableRef}>
<View />
</ScrollView>
</TrueSheet>
On iOS, this uses prefersScrollingExpandsWhenScrolledToEdge. On Android, a custom BottomSheetBehavior selectively blocks scroll-driven expansion while preserving normal scrolling, fling deceleration, and grabber-based dragging.
Scroll Edge Effect
On iOS 26+, you can apply a blur/gradient edge effect on the header and footer when content scrolls behind them. This uses UIScrollEdgeElementContainerInteraction under the hood.
Set topScrollEdgeEffect and/or bottomScrollEdgeEffect in scrollableOptions to enable it:
<TrueSheet
scrollableRef={scrollableRef}
scrollableOptions={{
topScrollEdgeEffect: 'automatic',
bottomScrollEdgeEffect: 'soft',
}}
header={<Header />}
footer={<Footer />}
>
<ScrollView ref={scrollableRef}>
<View />
</ScrollView>
</TrueSheet>
Available values: 'automatic', 'hard', 'soft', or 'hidden' (default). See ScrollEdgeEffect.
This also controls the scroll view's own edge effects (UIScrollEdgeEffect). topScrollEdgeEffect applies to both the header interaction and the scroll view's top edge, and bottomScrollEdgeEffect applies to both the footer interaction and the scroll view's bottom edge.
This feature requires iOS 26 or later. On older versions, these options are ignored.