Overview
A headless bottom sheet engine for React Native — Gesture Handler for the pans, Reanimated for the motion, keyboard-controller for the keyboard, teleport for the portal.
@delacour/react-native-bottom-sheet moves a sheet and nothing else. Every radius, colour and
inset is a style you pass in: there is no className, no token and no theme. The skinned
BottomSheet in @delacour/react-native-ui is this engine
with the theme attached, and it is the one to reach for when you want a sheet that already matches
the rest of the library.
import { BottomSheet } from "@delacour/react-native-bottom-sheet";
import { Text, View } from "react-native";
<BottomSheet snapPoints={["40%", "85%"]} dynamicSizing={false}>
<BottomSheet.Trigger style={styles.button}>
<Text style={styles.buttonLabel}>Open</Text>
</BottomSheet.Trigger>
<BottomSheet.Portal>
<BottomSheet.Overlay style={styles.overlay} />
<BottomSheet.Container>
<BottomSheet.Background style={styles.background} />
<BottomSheet.Handle style={styles.handle}>
<View style={styles.pill} />
</BottomSheet.Handle>
<BottomSheet.Content style={styles.content}>
<BottomSheet.Title style={styles.title}>Two snap points</BottomSheet.Title>
<BottomSheet.Description style={styles.description}>
Drag the handle up for the second. Drag past the first to close.
</BottomSheet.Description>
<BottomSheet.Close style={styles.close}>
<Text style={styles.closeLabel}>Close</Text>
</BottomSheet.Close>
</BottomSheet.Content>
</BottomSheet.Container>
</BottomSheet.Portal>
</BottomSheet>;A sheet is a root and the parts you place inside it. The root owns the state — where the sheet is, which snap points it may rest at, whose keyboard it is lifting for — and publishes it through a context; a part reads that context and renders one thing. Composition lays the parts out and names every prop.
What it does
Snap points
Pixels, percentages, and the content's own height. Where the sheet may rest.
Gestures
Two pans, a rubber band, a velocity snap, and a haptic on every crossing.
Keyboard
Four behaviours, three scopes, and a footer that lands on the keyboard's edge.
Footer
Inline or sticky. The safe-area band, counted once and collapsed with the keyboard.
Scrollables
A list as the body, and the rule for which of the two a finger moves.
Where it draws
Portal and host
Modal by default, inline on request, and a host for a native modal screen.
Detached
A floating card with margins, four rounded corners, and a rigid close.
Reference
Steps
A typed machine, a body that follows it, and a height that glides between steps.
Animation
A spring or a timing. Platform defaults, reduce motion, and what the callbacks hear.
Core
Every number the sheet computes, as pure functions with no native module in the graph.
What is not here
A className. A colour token. A GestureHandlerRootView, a SafeAreaProvider or a
KeyboardProvider — your app has all three already, and a nested KeyboardProvider is a second,
disagreeing keyboard. A BottomSheetModal component: a modal sheet is a sheet whose portal
teleports, and that is the default. The reasoning behind each is in the package's own
AGENTS.md.