Bottom sheets are surfaces containing supplementary content, anchored to the bottom of the screen. They can provide users with quick access to contextual information, actions, or settings without interrupting their current workflow.
Looking for a ready-to-use solution? We recommend @gorhom/bottom-sheet.
The BottomSheet component accepts props such as isOpen
- a shared value indicating whether the bottom sheet is open or closed, toggleSheet
- a function to toggle the visibility of the bottom sheet, and an optional duration
for animation.
function BottomSheet({ isOpen, toggleSheet, duration = 500, children }) {
const { colorScheme } = useColorScheme();
const height = useSharedValue(0);
const progress = useDerivedValue(() =>
withTiming(isOpen.value ? 0 : 1, { duration })
);
const sheetStyle = useAnimatedStyle(() => ({
transform: [{ translateY: progress.value * 2 * height.value }],
}));
const backgroundColorSheetStyle = {
backgroundColor: colorScheme === 'light' ? '#f8f9ff' : '#272B3C',
};
const backdropStyle = useAnimatedStyle(() => ({
opacity: 1 - progress.value,
zIndex: isOpen.value
? 1
: withDelay(duration, withTiming(-1, { duration: 0 })),
}));
return (
<>
<Animated.View style={[sheetStyles.backdrop, backdropStyle]}>
<TouchableOpacity style={styles.flex} onPress={toggleSheet} />
</Animated.View>
<Animated.View
onLayout={(e) => {
height.value = e.nativeEvent.layout.height;
}}
The height
shared value is used to track the height of the bottom sheet, while the progress
derived value interpolates between 0 and 1 based on the state of isOpen
, controlling the animation of the bottom sheet.
function BottomSheet({ isOpen, toggleSheet, duration = 500, children }) {
const { colorScheme } = useColorScheme();
const height = useSharedValue(0);
const progress = useDerivedValue(() =>
The useAnimatedStyle
hook helps in creating animated styles based on shared values. These styles are then applied to BottomSheet to make it visually dynamic by adding backdrop and translating bottom sheet to the top.
);
const sheetStyle = useAnimatedStyle(() => ({
transform: [{ translateY: progress.value * 2 * height.value }],
}));
const backgroundColorSheetStyle = {
backgroundColor: colorScheme === 'light' ? '#f8f9ff' : '#272B3C',
};