React Native Bottom Sheet
repository·master·Indexed 27 days ago
https://github.com/gorhom/react-native-bottom-sheetA performant, interactive bottom sheet library for React Native (v5.2.14) supporting dynamic sizing, modal presentations, and smooth gesture interactions. Compatible with Expo, React Native Web, and Reanimated v1, v2, and v3. It integrates with scrolling components like FlashList, FlatList, SectionList, and ScrollView, and provides specialized components such as BottomSheetModal, BottomSheetBackdrop, and BottomSheetHandle.
What's inside @gorhom/bottom-sheet
- React Native Bottom Sheet is a performant, interactive bottom sheet component for React Native with fully configurable options. It supports smooth gesture interactions, snapping animations, and seamless keyboard handling for both iOS and Android.
Use BottomSheetFlashList
masterThe
BottomSheetFlashListis a pre-integrated component that combines Shopify's FlashList withBottomSheetgestures.Note: This component is deprecated. It is recommended to use the
useBottomSheetScrollableCreatorhook instead for a simpler approach to creating scrollable components within a bottom sheet.Key Features of React Native Bottom Sheet
masterThe library provides several advanced features:
- Platform Support: Works with React Native Web and is compatible with Expo.
- Sizing & Scrolling: Supports Dynamic Sizing and integrates with
FlashList,FlatList,SectionList,ScrollView, andViewfor scrolling interactions. - Modal Support: Includes a
Bottom Sheet Modalfor modal presentation views. - Interactions: Smooth gesture interactions, snapping animations, and support for
pull to refreshon scrollables. - Integrations: Supports
React Navigationintegration. - Compatibility: Compatible with
Reanimatedv1, v2, and v3. - Development: Written in
TypeScriptwith accessibility support.
Migrate to BottomSheet v5
masterIn v5, dynamic sizing is enabled by default, which may change the height of your bottom sheets. To maintain previous behavior during migration, you can disable it using theenableDynamicSizingprop. You can also limit the height of dynamic content usingmaxDynamicContentSize.Choose the correct version based on Reanimated
masterThe library is maintained in different branches depending on the version of
Reanimatedyou are using. It is highly recommended to use v5 for the most stability and latest features.- v5 (Recommended): Written with
Reanimated v3andGesture Handler v2. - v4 (Not maintained): Written with
Reanimated v2. - v2 (Not maintained): Written with
Reanimated v1and compatible withReanimated v2.
- v5 (Recommended): Written with
Implement Pull to Refresh in Bottom Sheet
masterPull to refresh is enabled by default and is activated when the bottom sheet reaches its top snap point. To implement it, provide the
refreshingandonRefreshprops to any supported Scrollable component (such asBottomSheetFlatList,BottomSheetScrollView, orBottomSheetSectionList).Note: The
refreshControlprop is currently not supported.import React, { useCallback, useMemo } from "react"; import { StyleSheet, View, Text } from "react-native"; import BottomSheet, { BottomSheetFlatList } from "@gorhom/bottom-sheet"; const App = () => { const data = useMemo( () => Array(50) .fill(0) .map((_, index) => `index-${index}`), [] ); const snapPoints = useMemo(() => ["25%", "50%"], []); const handleRefresh = useCallback(() => { console.log("handleRefresh"); }, []); const renderItem = useCallback( ({ item }) => ( <View style={styles.itemContainer}> <Text>{item}</Text> </View> ), [] ); return ( <View style={styles.container}> <BottomSheet snapPoints={snapPoints}> <BottomSheetFlatList data={data} keyExtractor={(i) => i} renderItem={renderItem} contentContainerStyle={styles.contentContainer} refreshing={false} onRefresh={handleRefresh} /> </BottomSheet> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, contentContainer: { backgroundColor: "white", }, itemContainer: { padding: 6, margin: 6, backgroundColor: "#eee", }, }); export default App;Use Scrollable components with Bottom Sheet
masterTo ensure smooth panning interactions and proper synchronization between scrolling and bottom sheet movement, use the pre-integrated 'Scrollable' components instead of standard React Native scrollable components. These components are specifically designed to work with the bottom sheet container's internal functionalities.
Available Scrollable components:
BottomSheetFlatListBottomSheetSectionListBottomSheetScrollViewBottomSheetVirtualizedListBottomSheetView
Add shadow to the Bottom Sheet
masterTo add a shadow to the
BottomSheetcomponent, pass astyleprop containing shadow styling configuration.Note that shadow rendering behavior differs between iOS and Android due to platform-specific drawing implementations. For complex shadow designs, you can use tools like the React Native Shadow Generator to generate the necessary style objects.
Handle keyboard appearance with BottomSheetTextInput
masterTo ensure the Bottom Sheet reacts correctly to keyboard appearance on both iOS and Android, use the pre-integrated
BottomSheetTextInputcomponent instead of the standard React NativeTextInput. This component communicates internally with the Bottom Sheet to manage layout adjustments when the keyboard opens.If you need to use a custom
TextInputcomponent, you must manually implement thehandleOnFocusandhandleOnBlurlogic from theBottomSheetTextInputsource code to maintain compatibility.import React, { useMemo } from "react"; import { View, StyleSheet } from "react-native"; import BottomSheet, { BottomSheetTextInput } from "@gorhom/bottom-sheet"; const App = () => { const snapPoints = useMemo(() => ["25%"], []); return ( <View style={styles.container}> <BottomSheet snapPoints={snapPoints}> <View style={styles.contentContainer}> <BottomSheetTextInput value="Awesome 🎉" style={styles.textInput} /> </View> </BottomSheet> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 24, backgroundColor: "grey", }, textInput: { alignSelf: "stretch", marginHorizontal: 12, marginBottom: 12, padding: 12, borderRadius: 12, backgroundColor: "grey", color: "white", textAlign: "center", }, contentContainer: { flex: 1, alignItems: "center", }, }); export default App;Access Bottom Sheet Modal methods via ref
masterTo use the specific methods of
BottomSheetModal, you must create a reference usinguseRef<BottomSheetModal>(null)and pass it to therefprop of theBottomSheetModalcomponent. This allows you to callpresent()anddismiss()programmatically.import React, { useRef } from 'react'; import { Button, BottomSheetModal } from '@gorhom/bottom-sheet'; const App = () => { const bottomSheetModalRef = useRef<BottomSheetModal>(null); const handlePresentPress = () => bottomSheetModalRef.current?.present(); return ( <> <Button title="Present Sheet" onPress={handlePresentPress} /> <BottomSheetModal ref={bottomSheetModalRef}> {/* Modal Content */} </BottomSheetModal> </> ); };Create a custom footer using BottomSheetFooter
masterTo implement a custom footer that stays positioned at the bottom of the
BottomSheetand reacts to keyboard appearance, wrap your component with theBottomSheetFootercomponent.Your custom footer component will receive an
animatedFooterPositionprop, which is a calculated animated position. To ensure your component can receive this prop, extend theBottomSheetFooterPropsinterface.Key Props for
BottomSheetFooter:animatedFooterPosition: The calculated animated position for the footer.bottomInset: A value (typically fromuseSafeAreaInsets) to avoid bottom notches or safe area obstructions.
import { BottomSheetFooter, BottomSheetFooterProps } from '@gorhom/bottom-sheet'; interface CustomFooterProps extends BottomSheetFooterProps {} const CustomFooter = ({ animatedFooterPosition }: CustomFooterProps) => { return ( <BottomSheetFooter bottomInset={bottomSafeArea} animatedFooterPosition={animatedFooterPosition} > {/* Your footer content here */} </BottomSheetFooter> ); };Deploy the website
masterYou can deploy the website using different methods depending on your hosting setup.
Using SSH: Set the
USE_SSHenvironment variable totrue.Using GitHub Pages (Non-SSH): Provide your GitHub username via the
GIT_USERenvironment variable. This will build the site and push it to thegh-pagesbranch.