The main bottom sheet component that provides a draggable sheet interface with gesture-driven interactions, configurable snap points, and extensive customization options.
Primary bottom sheet component with comprehensive configuration options for gesture handling, animations, keyboard behavior, and styling.
/**
* Main bottom sheet component with draggable interface
* @param props - Configuration props for the bottom sheet
* @returns JSX.Element
*/
export default function BottomSheet(props: BottomSheetProps): JSX.Element;
interface BottomSheetProps extends BottomSheetAnimationConfigs, Partial<BottomSheetGestureProps>, Omit<NullableAccessibilityProps, 'accessibilityHint'> {
//#region configuration
/** Initial snap point index, provide -1 to initiate bottom sheet in closed state (default: 0) */
index?: number;
/** Points for the bottom sheet to snap to. Array of number, string or mix. Required unless enableDynamicSizing is true */
snapPoints?: Array<string | number> | SharedValue<Array<string | number>>;
/** Defines how violently sheet has to be stopped while over dragging (default: 2.5) */
overDragResistanceFactor?: number;
/** Whether the bottom sheet is attached to the bottom or no (default: false) */
detached?: boolean;
/** Enable content panning gesture interaction (default: true) */
enableContentPanningGesture?: boolean;
/** Enable handle panning gesture interaction (default: true) */
enableHandlePanningGesture?: boolean;
/** Enable over drag for the sheet (default: true) */
enableOverDrag?: boolean;
/** Enable pan down gesture to close the sheet (default: false) */
enablePanDownToClose?: boolean;
/** Enable dynamic sizing for content view and scrollable content size (default: true) */
enableDynamicSizing?: boolean;
/** To start the sheet closed and snap to initial index when it's mounted (default: true) */
animateOnMount?: boolean;
/** Override the user reduce motion setting (default: ReduceMotion.System) */
overrideReduceMotion?: ReduceMotion;
//#endregion
//#region layout
/** @deprecated Use containerLayoutState instead */
containerHeight?: number | SharedValue<number>;
/** @deprecated Use containerLayoutState instead */
containerOffset?: SharedValue<Required<Insets>>;
/** Container layout state for calculating container height and offsets */
containerLayoutState?: SharedValue<ContainerLayoutState>;
/** Top inset value for percentage snap points calculations (default: 0) */
topInset?: number;
/** Bottom inset value for percentage snap points calculations (default: 0) */
bottomInset?: number;
/** Max dynamic content size height to limit bottom sheet height */
maxDynamicContentSize?: number;
//#endregion
//#region keyboard
/** Keyboard appearance behavior: 'interactive' | 'extend' | 'fillParent' (default: 'interactive') */
keyboardBehavior?: keyof typeof KEYBOARD_BEHAVIOR;
/** Keyboard blur behavior: 'none' | 'restore' */
keyboardBlurBehavior?: keyof typeof KEYBOARD_BLUR_BEHAVIOR;
/** Enable blurring keyboard when user starts to drag (default: false) */
enableBlurKeyboardOnGesture?: boolean;
/** Android keyboard input mode: 'adjustPan' | 'adjustResize' (default: 'adjustPan') */
android_keyboardInputMode?: keyof typeof KEYBOARD_INPUT_MODE;
//#endregion
//#region styles
/** View style to be applied to the container */
containerStyle?: StyleProp<ViewStyle>;
/** View style to be applied to the sheet container component (can be animated) */
style?: StyleProp<AnimateStyle<ViewStyle>>;
/** View style to be applied to the background component */
backgroundStyle?: StyleProp<ViewStyle>;
/** View style to be applied to the handle component */
handleStyle?: StyleProp<ViewStyle>;
/** View style to be applied to the handle indicator component */
handleIndicatorStyle?: StyleProp<ViewStyle>;
//#endregion
//#region components
/** Component to be placed as a sheet handle */
handleComponent?: React.FC<BottomSheetHandleProps> | null;
/** Component to be placed as a sheet backdrop */
backdropComponent?: React.FC<BottomSheetBackdropProps>;
/** Component to be placed as a background */
backgroundComponent?: React.FC<BottomSheetBackgroundProps> | null;
/** Component to be placed as a footer */
footerComponent?: React.FC<BottomSheetFooterProps>;
/** Child content - scrollable node or normal view */
children: React.ReactNode;
//#endregion
//#region animated nodes
/** Animated value callback for position node */
animatedPosition?: SharedValue<number>;
/** Animated value callback for position index node */
animatedIndex?: SharedValue<number>;
//#endregion
//#region callbacks
/** Callback when sheet position changes to a provided point */
onChange?: (index: number, position: number, type: SNAP_POINT_TYPE) => void;
/** Callback when sheet closes */
onClose?: () => void;
/** Callback when sheet is about to animate to new position */
onAnimate?: (fromIndex: number, toIndex: number, fromPosition: number, toPosition: number) => void;
//#endregion
//#region experimental
/** ⚠️ Experimental: Custom hook for pan gesture events handler */
gestureEventsHandlersHook?: GestureEventsHandlersHookType;
//#endregion
}Usage Examples:
import React, { useRef, useMemo } from 'react';
import { View, Text, Button } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
// Basic bottom sheet
const BasicExample = () => {
const bottomSheetRef = useRef<BottomSheet>(null);
const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);
return (
<View style={{ flex: 1 }}>
<BottomSheet
ref={bottomSheetRef}
index={1}
snapPoints={snapPoints}
>
<View style={{ flex: 1, alignItems: 'center' }}>
<Text>Bottom Sheet Content</Text>
</View>
</BottomSheet>
</View>
);
};
// With custom handle and backdrop
const CustomizedExample = () => {
const bottomSheetRef = useRef<BottomSheet>(null);
const snapPoints = useMemo(() => [150, 300, 500], []);
const renderHandle = () => (
<View style={{ backgroundColor: 'blue', height: 30, borderRadius: 15 }} />
);
const renderBackdrop = (props) => (
<BottomSheetBackdrop
{...props}
disappearsOnIndex={-1}
appearsOnIndex={0}
/>
);
return (
<View style={{ flex: 1 }}>
<BottomSheet
ref={bottomSheetRef}
index={0}
snapPoints={snapPoints}
handleComponent={renderHandle}
backdropComponent={renderBackdrop}
enablePanDownToClose={true}
onChange={(index) => console.log('Sheet moved to index:', index)}
>
<View style={{ flex: 1, padding: 20 }}>
<Text>Custom bottom sheet with handle and backdrop</Text>
</View>
</BottomSheet>
</View>
);
};
// Dynamic sizing
const DynamicExample = () => {
const bottomSheetRef = useRef<BottomSheet>(null);
return (
<View style={{ flex: 1 }}>
<BottomSheet
ref={bottomSheetRef}
enableDynamicSizing
index={0}
>
<View style={{ padding: 20 }}>
<Text>This sheet sizes itself based on content</Text>
<Text>No need to specify snapPoints!</Text>
</View>
</BottomSheet>
</View>
);
};Interface for configuring bottom sheet animations.
interface BottomSheetAnimationConfigs {
/** Animation configs created by useBottomSheetSpringConfigs or useBottomSheetTimingConfigs */
animationConfigs?: WithSpringConfig | WithTimingConfig;
}Configuration interface for customizing pan gesture behavior.
type BottomSheetGestureProps = {
/** Active offset for X axis gesture recognition */
activeOffsetX: Parameters<PanGesture['activeOffsetX']>[0];
/** Active offset for Y axis gesture recognition */
activeOffsetY: Parameters<PanGesture['activeOffsetY']>[0];
/** Fail offset for Y axis gesture recognition */
failOffsetY: Parameters<PanGesture['failOffsetY']>[0];
/** Fail offset for X axis gesture recognition */
failOffsetX: Parameters<PanGesture['failOffsetX']>[0];
/** Simultaneous gesture handlers */
simultaneousHandlers: Parameters<PanGesture['simultaneousWithExternalGesture']>[0];
/** Gesture handlers to wait for */
waitFor: Parameters<PanGesture['requireExternalGestureToFail']>[0];
};const KEYBOARD_BEHAVIOR = {
interactive: 'interactive',
extend: 'extend',
fillParent: 'fillParent',
} as const;
const KEYBOARD_BLUR_BEHAVIOR = {
none: 'none',
restore: 'restore',
} as const;
const KEYBOARD_INPUT_MODE = {
adjustPan: 'adjustPan',
adjustResize: 'adjustResize',
} as const;
enum SNAP_POINT_TYPE {
PROVIDED = 0,
DYNAMIC = 1,
}