Skip to main content

Surface

The surface is the sheet’s visible body. surface provides its fill, and surfaceStyle its shape and shadow.

Provide the sheet’s background through the surface prop. The library renders it behind your content and sizes it natively to cover the whole sheet, independently of the content height.

Decoupling the surface this way keeps the sheet covered as the content height changes. When content shrinks, the sheet animates to its new height without the background briefly exposing blank space behind the content.

With per-detent insets, the surface is laid out against the widest card and scaled with the content to fit narrower ones, so an image keeps its aspect ratio and touches the card's edges at every detent.

If your sheet content animates its own height, pass animateContentHeight={false} to update the sheet position immediately when the active 'content' detent changes height.

Give the surface a filling style such as StyleSheet.absoluteFill. It is mounted in a full-size host, so a surface sized only by its own content would collapse and not show.

<BottomSheet // Or `ModalBottomSheet`.
index={index}
onIndexChange={setIndex}
surface={
<View style={[StyleSheet.absoluteFill, { backgroundColor: 'white' }]} />
}
>
<Text>Sheet content</Text>
</BottomSheet>

Shape and shadows​

Use surfaceStyle to round the surface and give it a shadow. The sheet clips both the fill from surface and your content to this shape. surfaceStyle is not applied to the element you pass as surface, which only fills the surface: a radius there would not round your content, and a shadow there would be clipped.

<BottomSheet // Or `ModalBottomSheet`.
index={index}
onIndexChange={setIndex}
surface={
<View style={[StyleSheet.absoluteFill, { backgroundColor: 'white' }]} />
}
surfaceStyle={{
borderTopLeftRadius: 24,
borderTopRightRadius: 24,
borderCurve: 'continuous',
boxShadow: '0 -4 16 rgba(0, 0, 0, 0.2)',
elevation: 16,
}}
>
<Text>Sheet content</Text>
</BottomSheet>

surfaceStyle takes corner radii, borderCurve, and these shadow props. They follow React Native's support on each platform:

PropiOSAndroidWeb
boxShadow (outset only)YesAPI 28 and laterYes
elevationNoYesNo
shadowColorYesTints elevation on API 28+No
shadowOffset, shadowOpacity, shadowRadiusYesNoNo

borderCurve applies on iOS only. To cover older Android versions, set elevation next to boxShadow. Android casts elevation from a light above the screen, so it is faint along a sheet's top edge.

A press in a clipped corner isn't on the card. It reaches whatever shows through the corner, or closes a modal sheet through its scrim.