or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

animation-configuration.mdbottom-sheet-component.mdcontrol-hooks.mdgesture-event-handling.mdindex.mdmodal-components.mdscrollable-components.mdui-components.md
tile.json

bottom-sheet-component.mddocs/

Bottom Sheet Component

The main bottom sheet component that provides a draggable sheet interface with gesture-driven interactions, configurable snap points, and extensive customization options.

Capabilities

BottomSheet Component

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>
  );
};

Animation Configuration Interface

Interface for configuring bottom sheet animations.

interface BottomSheetAnimationConfigs {
  /** Animation configs created by useBottomSheetSpringConfigs or useBottomSheetTimingConfigs */
  animationConfigs?: WithSpringConfig | WithTimingConfig;
}

Gesture Configuration

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];
};

Constants

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,
}