Performant Interactive Bottom Sheet For React Native

A performant, interactive, and highly customizable bottom sheet component for React Native.

Features:

  • Modal presentation view
  • Smooth interactions & snapping animations
  • Support FlatList, SectionList, ScrollView & View scrolling interactions
  • Support React Navigation Integration
  • Compatible with Reanimated v1 & v2
  • Compatible with Expo
  • Written in TypeScript

How to use it:

1. Install and import the Bottom Sheet component.

# Yarn
$ yarn add @gorhom/bottom-sheet

# NPM
$ npm i @gorhom/bottom-sheet
import React, { useCallback, useMemo, useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';

2. Create a basic bottom sheet in your app.

const App = () => {
  // hooks
  const bottomSheetRef = useRef<BottomSheet>(null);
  // variables
  const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);
  // callbacks
  const handleSheetChanges = useCallback((index: number) => {
    console.log('handleSheetChanges', index);
  }, []);
  // renders
  return (
    <View style={styles.container}>
      <BottomSheet
        ref={bottomSheetRef}
        initialSnapIndex={1}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}
      >
      </BottomSheet>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
  },
});
export default App;

3. Possible props to config the bottom sheet.

// configuration
/**
 * Initial snap index, you also could provide {`-1`} to initiate bottom sheet in closed state.
 * @type number
 * @default 0
 */
index?: number;
/**
 * Points for the bottom sheet to snap to. It accepts array of number, string or mix.
 * String values should be a percentage.
 * @type Array<string | number>
 * @example
 * snapPoints={[200, 500]}
 * snapPoints={[200, '%50']}
 * snapPoints={[-1, '%100']}
 */
snapPoints: Array<string | number>;
/**
 * Handle height helps to calculate the internal container and sheet layouts,
 * if `handleComponent` is provided, the library internally will calculate its layout,
 * unless `handleHeight` is provided.
 * @type number
 */
handleHeight?: number;
/**
 * Container height helps to calculate the internal sheet layouts,
 * if `containerHeight` not provided, the library internally will calculate it,
 * however this will cause an extra re-rendering.
 * @type number
 */
containerHeight?: number;
/**
 * Top inset value helps to calculate percentage snap points values,
 * usually comes from `@react-navigation/stack` hook `useHeaderHeight` or from `react-native-safe-area-context` hook `useSafeArea`.
 * @type number
 * @default 0
 */
topInset?: number;
/**
 * Enable content panning gesture interaction.
 * @type boolean
 * @default true
 */
enableContentPanningGesture?: boolean;
/**
 * Enable handle panning gesture interaction.
 * @type boolean
 * @default true
 */
enableHandlePanningGesture?: boolean;
/**
 * This will initially mount the sheet closed then when it calculate its layout,
 * it will snap to provided `index`.
 * @type boolean
 * @default false
 */
animateOnMount?: boolean;
// animated nodes
/**
 * Animated value to be used as a callback of the position node internally.
 * @type Animated.Value<number>
 */
animatedPosition?: Animated.Value<number>;
/**
 * Animated value to be used as a callback for the position index node internally.
 * @type Animated.Value<number>
 */
animatedIndex?: Animated.Value<number>;
// callbacks
/**
 * Callback when the sheet position changed.
 * @type (index: number) => void;
 */
onChange?: (index: number) => void;
/**
 * Callback when the sheet about to animate to a new position.
 * @type (fromIndex: number, toIndex: number) => void;
 */
onAnimate?: (fromIndex: number, toIndex: number) => void;
// components
/**
 * Component to be placed as a sheet handle.
 * @see {BottomSheetHandleProps}
 * @type React.FC\<BottomSheetHandleProps\>
 */
handleComponent?: React.FC<BottomSheetHandleProps> | null;
/**
 * Component to be placed as a sheet backdrop.
 * @type React.FC
 * @default null
 */
backdropComponent?: React.FC<any> | null;
/**
 * Component to be placed as a sheet background.
 * @type React.FC\<BottomSheetBackgroundProps\>
 */
backgroundComponent?: React.FC<BottomSheetBackgroundProps> | null;
/**
 * A scrollable node or normal view.
 * @type React.ReactNode[] | React.ReactNode
 */
children: (() => React.ReactNode) | React.ReactNode[] | React.ReactNode;
} & BottomSheetAnimationConfigs;
export interface BottomSheetAnimationConfigs {
/**
 * Snapping animation easing function.
 * @type Animated.EasingFunction
 * @default Easing.out(Easing.exp)
 */
animationEasing?: Animated.EasingFunction;
/**
 * Snapping animation duration.
 * @type number
 * @default 500
 */
animationDuration?: number;
}

Preview:

Performant Interactive Bottom Sheet For React Native

Download Details:

Author: gorhom

Live Demo: View The Demo

Download Link: Download The Source Code

Official Website: https://github.com/gorhom/react-native-bottom-sheet

License: MIT

You Might Be Interested In:

Add Comment