Modal bottom sheets that overlay the entire screen with stack management, presentation controls, and provider-based lifecycle management.
Modal version of the bottom sheet that overlays the entire screen and supports data passing and stack behaviors.
/**
* Modal bottom sheet component that overlays the entire screen
* @param props - Modal configuration props extending BottomSheetProps
* @returns JSX.Element
*/
declare const BottomSheetModal: React.ForwardRefExoticComponent<BottomSheetModalProps>;
interface BottomSheetModalProps<T = any> extends Omit<BottomSheetProps, 'containerHeight' | 'onClose'> {
/** Modal identifier for stack management (default: auto-generated) */
name?: string;
/** Stack behavior when mounting: 'push' | 'switch' | 'replace' (default: 'switch') */
stackBehavior?: 'push' | 'switch' | 'replace';
/** Auto-dismiss modal when sheet closes (default: true) */
enableDismissOnClose?: boolean;
/** Custom container component for modal content */
containerComponent?: React.ComponentType<React.PropsWithChildren>;
/** Callback when modal is dismissed */
onDismiss?: () => void;
/** Content with optional data passing support */
children: React.FC<{ data?: T }> | React.ReactNode[] | React.ReactNode;
}Usage Examples:
import React, { useRef } from 'react';
import { View, Text, Button } from 'react-native';
import { BottomSheetModal, BottomSheetModalProvider } from '@gorhom/bottom-sheet';
// Basic modal
const ModalExample = () => {
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
const snapPoints = useMemo(() => ['25%', '50%', '75%'], []);
const handlePresentModal = () => {
bottomSheetModalRef.current?.present();
};
const handleDismissModal = () => {
bottomSheetModalRef.current?.dismiss();
};
return (
<BottomSheetModalProvider>
<View style={{ flex: 1, padding: 24 }}>
<Button title="Present Modal" onPress={handlePresentModal} />
<BottomSheetModal
ref={bottomSheetModalRef}
index={1}
snapPoints={snapPoints}
onDismiss={() => console.log('Modal dismissed')}
>
<View style={{ flex: 1, alignItems: 'center' }}>
<Text>Modal Content</Text>
<Button title="Dismiss" onPress={handleDismissModal} />
</View>
</BottomSheetModal>
</View>
</BottomSheetModalProvider>
);
};
// With data passing
interface UserData {
id: number;
name: string;
email: string;
}
const DataPassingExample = () => {
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
const snapPoints = useMemo(() => ['40%', '75%'], []);
const handlePresentModal = () => {
const userData: UserData = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
};
bottomSheetModalRef.current?.present(userData);
};
return (
<BottomSheetModalProvider>
<View style={{ flex: 1, padding: 24 }}>
<Button title="Show User Details" onPress={handlePresentModal} />
<BottomSheetModal
ref={bottomSheetModalRef}
index={0}
snapPoints={snapPoints}
enableDismissOnClose={true}
>
{({ data }: { data?: UserData }) => (
<View style={{ flex: 1, padding: 20 }}>
<Text>User Details</Text>
{data && (
<>
<Text>ID: {data.id}</Text>
<Text>Name: {data.name}</Text>
<Text>Email: {data.email}</Text>
</>
)}
</View>
)}
</BottomSheetModal>
</View>
</BottomSheetModalProvider>
);
};
// Stack behavior example
const StackBehaviorExample = () => {
const modal1Ref = useRef<BottomSheetModal>(null);
const modal2Ref = useRef<BottomSheetModal>(null);
const snapPoints = useMemo(() => ['50%'], []);
return (
<BottomSheetModalProvider>
<View style={{ flex: 1, padding: 24 }}>
<Button title="Show Modal 1" onPress={() => modal1Ref.current?.present()} />
{/* First modal with push behavior */}
<BottomSheetModal
ref={modal1Ref}
index={0}
snapPoints={snapPoints}
stackBehavior="push"
name="modal1"
>
<View style={{ flex: 1, padding: 20 }}>
<Text>Modal 1</Text>
<Button
title="Show Modal 2 (Replace)"
onPress={() => modal2Ref.current?.present()}
/>
</View>
</BottomSheetModal>
{/* Second modal with replace behavior */}
<BottomSheetModal
ref={modal2Ref}
index={0}
snapPoints={snapPoints}
stackBehavior="replace"
name="modal2"
>
<View style={{ flex: 1, padding: 20 }}>
<Text>Modal 2 (Replaced Modal 1)</Text>
</View>
</BottomSheetModal>
</View>
</BottomSheetModalProvider>
);
};Provider component that manages modal bottom sheets lifecycle and stack behavior. Must wrap components that use BottomSheetModal.
/**
* Provider for managing modal bottom sheets
* @param props - Provider props with children
* @returns JSX.Element
*/
declare const BottomSheetModalProvider: React.FC<BottomSheetModalProviderProps>;
interface BottomSheetModalProviderProps {
/** Child components that may contain BottomSheetModal components */
children?: React.ReactNode;
}Usage Example:
import React from 'react';
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
import App from './App';
// Wrap your app or screen components
const AppWithProvider = () => {
return (
<BottomSheetModalProvider>
<App />
</BottomSheetModalProvider>
);
};
export default AppWithProvider;Interface for imperative modal methods available through refs.
interface BottomSheetModalMethods<T = any> extends BottomSheetMethods {
/** Present the modal to the initial snap point with optional data */
present: (data?: T) => void;
/** Close and unmount the modal */
dismiss: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
}Usage with Ref:
import React, { useRef } from 'react';
import { BottomSheetModal } from '@gorhom/bottom-sheet';
const ComponentWithModalRef = () => {
const modalRef = useRef<BottomSheetModal>(null);
const handleOpenModal = () => {
// Present modal
modalRef.current?.present();
};
const handleCloseModal = () => {
// Dismiss modal with animation
modalRef.current?.dismiss();
};
const handleSnapToIndex = () => {
// Use inherited BottomSheetMethods
modalRef.current?.snapToIndex(1);
};
return (
<BottomSheetModal ref={modalRef} snapPoints={['50%', '90%']}>
{/* Modal content */}
</BottomSheetModal>
);
};Modal stack behaviors control how multiple modals interact:
push: Stack the new modal on top of existing onesswitch: Minimize current modal and show new onereplace: Dismiss current modal and show new one (default)// Example showing different stack behaviors
const handlePresentPushModal = () => {
// Keeps current modal and stacks new one
pushModalRef.current?.present();
};
const handlePresentSwitchModal = () => {
// Minimizes current modal and shows new one
switchModalRef.current?.present();
};
const handlePresentReplaceModal = () => {
// Dismisses current modal and shows new one
replaceModalRef.current?.present();
};The modal system provides context for managing multiple modals:
interface BottomSheetModalContextType {
/** Dismiss a specific modal by key */
dismiss: (key?: string) => boolean;
/** Dismiss all modals */
dismissAll: () => void;
}