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

control-hooks.mddocs/

Control Hooks

Hooks for imperative control of bottom sheets, accessing animated values, and managing modal presentation with comprehensive state management.

Capabilities

useBottomSheet

Primary hook for accessing bottom sheet controls and animated state. Must be used within a BottomSheet component context.

/**
 * Hook for accessing bottom sheet controls and state
 * Must be used within a BottomSheet context
 * @throws Error if used outside BottomSheet context
 * @returns Combined methods and variables for sheet control
 */
declare function useBottomSheet(): BottomSheetMethods & BottomSheetVariables;

interface BottomSheetMethods {
  /** Snap to one of the provided points from snapPoints */
  snapToIndex: (index: number, animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
  /** Snap to a position out of provided snapPoints (pixels or percentage) */
  snapToPosition: (position: number | string, animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
  /** Snap to the maximum provided point from snapPoints */
  expand: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
  /** Snap to the minimum provided point from snapPoints */
  collapse: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
  /** Close the bottom sheet */
  close: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
  /** Force close sheet, preventing interruptions until closed */
  forceClose: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
}

interface BottomSheetVariables {
  /** Current sheet position index */
  animatedIndex: SharedValue<number>;
  /** Current sheet position in pixels */
  animatedPosition: SharedValue<number>;
}

Usage Examples:

import React from 'react';
import { View, Text, Button } from 'react-native';
import BottomSheet, { useBottomSheet } from '@gorhom/bottom-sheet';

// Component inside BottomSheet that uses the hook
const SheetContent = () => {
  const { snapToIndex, expand, collapse, close, animatedIndex, animatedPosition } = useBottomSheet();

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Text>Bottom Sheet Controls</Text>
      
      <Button title="Snap to Index 0" onPress={() => snapToIndex(0)} />
      <Button title="Snap to Index 1" onPress={() => snapToIndex(1)} />
      <Button title="Expand" onPress={() => expand()} />
      <Button title="Collapse" onPress={() => collapse()} />
      <Button title="Close" onPress={() => close()} />
      
      {/* Access animated values for custom animations */}
      <Text>Current Index: {animatedIndex.value}</Text>
      <Text>Current Position: {animatedPosition.value}</Text>
    </View>
  );
};

// Main component with BottomSheet
const MyComponent = () => {
  const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);

  return (
    <View style={{ flex: 1 }}>
      <BottomSheet snapPoints={snapPoints} index={1}>
        <SheetContent />
      </BottomSheet>
    </View>
  );
};

// Using with custom animation configs
const AnimatedControls = () => {
  const { snapToIndex, snapToPosition } = useBottomSheet();

  const snapWithCustomAnimation = () => {
    snapToIndex(2, {
      duration: 500,
      easing: Easing.bezier(0.25, 0.46, 0.45, 0.94),
    });
  };

  const snapToCustomPosition = () => {
    snapToPosition('75%', {
      damping: 15,
      stiffness: 150,
    });
  };

  return (
    <View>
      <Button title="Snap with Timing" onPress={snapWithCustomAnimation} />
      <Button title="Snap to 75%" onPress={snapToCustomPosition} />
    </View>
  );
};

useBottomSheetModal

Hook for controlling bottom sheet modals from within modal components. Must be used within a BottomSheetModalProvider context.

/**
 * Hook for controlling bottom sheet modals
 * Must be used within BottomSheetModalProvider context
 * @throws Error if used outside BottomSheetModalProvider context
 * @returns Modal control methods
 */
declare function useBottomSheetModal(): BottomSheetModalContextType;

interface BottomSheetModalContextType {
  /** Dismiss a specific modal by key, returns success status */
  dismiss: (key?: string) => boolean;
  /** Dismiss all currently presented modals */
  dismissAll: () => void;
}

Usage Examples:

import React from 'react';
import { View, Text, Button } from 'react-native';
import { 
  BottomSheetModal, 
  BottomSheetModalProvider, 
  useBottomSheetModal 
} from '@gorhom/bottom-sheet';

// Component inside modal that uses the hook
const ModalContent = () => {
  const { dismiss, dismissAll } = useBottomSheetModal();

  const handleDismiss = () => {
    const success = dismiss();
    console.log('Dismiss success:', success);
  };

  const handleDismissAll = () => {
    dismissAll();
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Text>Modal Content</Text>
      <Button title="Dismiss This Modal" onPress={handleDismiss} />
      <Button title="Dismiss All Modals" onPress={handleDismissAll} />
    </View>
  );
};

// Component with multiple modals
const MultiModalExample = () => {
  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()} />
        <Button title="Show Modal 2" onPress={() => modal2Ref.current?.present()} />
        
        <BottomSheetModal
          ref={modal1Ref}
          index={0}
          snapPoints={snapPoints}
          name="modal1"
        >
          <ModalContent />
        </BottomSheetModal>

        <BottomSheetModal
          ref={modal2Ref}
          index={0}
          snapPoints={snapPoints}
          name="modal2"
        >
          <ModalContent />
        </BottomSheetModal>
      </View>
    </BottomSheetModalProvider>
  );
};

// Dismiss specific modal by key
const SpecificDismissExample = () => {
  const { dismiss } = useBottomSheetModal();

  const dismissSpecificModal = () => {
    const success = dismiss('modal1'); // Dismiss modal with name 'modal1'
    if (!success) {
      console.log('Modal with key "modal1" not found');
    }
  };

  return (
    <View>
      <Button title="Dismiss Modal 1" onPress={dismissSpecificModal} />
    </View>
  );
};

useBottomSheetInternal

Advanced hook providing access to internal bottom sheet state and methods. Primarily for library components and advanced customization.

/**
 * Hook for accessing internal bottom sheet state
 * @param unsafe - If true, returns null instead of throwing when used outside context
 * @throws Error if used outside context and unsafe is false
 * @returns Internal context with comprehensive state and controls
 */
declare function useBottomSheetInternal(unsafe?: false): BottomSheetInternalContextType;
declare function useBottomSheetInternal(unsafe: true): BottomSheetInternalContextType | null;

interface BottomSheetInternalContextType {
  // Animated States
  animatedDetentsState: SharedValue<DetentsState>;
  animatedAnimationState: SharedValue<AnimationState>;
  animatedSheetState: SharedValue<SHEET_STATE>;
  animatedKeyboardState: SharedValue<KeyboardState>;
  animatedContentGestureState: SharedValue<State>;
  animatedHandleGestureState: SharedValue<State>;
  animatedLayoutState: SharedValue<LayoutState>;
  animatedScrollableState: SharedValue<ScrollableState>;
  animatedScrollableStatus: SharedValue<SCROLLABLE_STATUS>;
  
  // Animated Values
  animatedPosition: SharedValue<number>;
  animatedIndex: SharedValue<number>;
  animatedSheetHeight: SharedValue<number>;
  isInTemporaryPosition: SharedValue<boolean>;
  
  // Methods
  stopAnimation: () => void;
  animateToPosition: (position: number, source: ANIMATION_SOURCE, velocity?: number, configs?: WithTimingConfig | WithSpringConfig) => void;
  setScrollableRef: (ref: ScrollableRef) => void;
  removeScrollableRef: (ref: RefObject<Scrollable>) => void;
  
  // Configuration
  enableContentPanningGesture: boolean;
  enableOverDrag: boolean;
  enablePanDownToClose: boolean;
  enableDynamicSizing: boolean;
  enableBlurKeyboardOnGesture: boolean;
  overDragResistanceFactor: number;
  
  // Refs
  textInputNodesRef: MutableRefObject<Set<number>>;
}

Usage Example:

import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import { useBottomSheetInternal } from '@gorhom/bottom-sheet';

const AdvancedSheetComponent = () => {
  const internal = useBottomSheetInternal();

  // Monitor sheet state changes
  useEffect(() => {
    const unsubscribe = internal.animatedSheetState.addListener((state) => {
      console.log('Sheet state changed:', state);
    });

    return unsubscribe;
  }, [internal.animatedSheetState]);

  // Safe usage with unsafe parameter
  const internalSafe = useBottomSheetInternal(true);
  if (!internalSafe) {
    return <Text>Not inside bottom sheet context</Text>;
  }

  return (
    <View>
      <Text>Advanced Sheet Component</Text>
      {/* Use internal state for advanced features */}
    </View>
  );
};

useBottomSheetModalInternal

Internal hook for modal management, stack behavior, and container layout state.

/**
 * Hook for accessing internal modal state
 * @param unsafe - If true, returns null instead of throwing when used outside context
 * @returns Internal modal context for advanced modal management
 */
declare function useBottomSheetModalInternal(unsafe?: false): BottomSheetModalInternalContextType;
declare function useBottomSheetModalInternal(unsafe: true): BottomSheetModalInternalContextType | null;

interface BottomSheetModalInternalContextType {
  /** Host name for modal identification */
  hostName: string;
  /** Container layout state for positioning */
  containerLayoutState: SharedValue<ContainerLayoutState>;
  /** Mount a modal with stack behavior */
  mountSheet: (key: string, ref: RefObject<BottomSheetModalPrivateMethods>, stackBehavior: BottomSheetModalStackBehavior) => void;
  /** Unmount a modal */
  unmountSheet: (key: string) => void;
  /** Prepare modal for unmounting */
  willUnmountSheet: (key: string) => void;
}

Animation Configuration Types

Types used with animation configuration parameters in control methods:

interface WithSpringConfig {
  damping?: number;
  stiffness?: number;
  mass?: number;
  velocity?: number;
  overshootClamping?: boolean;
  restDisplacementThreshold?: number;
  restSpeedThreshold?: number;
  reduceMotion?: ReduceMotion;
}

interface WithTimingConfig {
  duration?: number;
  easing?: EasingFunction | EasingFunctionFactory;
  reduceMotion?: ReduceMotion;
}

enum ReduceMotion {
  System = 'system',
  Always = 'always',
  Never = 'never',
}

State Enums and Types

enum SHEET_STATE {
  CLOSED = 0,
  OPENED = 1,
  EXTENDED = 2,
  OVER_EXTENDED = 3,
  FILL_PARENT = 4,
}

enum ANIMATION_SOURCE {
  NONE = 0,
  MOUNT = 1,
  GESTURE = 2,
  USER = 3,
  CONTAINER_RESIZE = 4,
  SNAP_POINT_CHANGE = 5,
  KEYBOARD = 6,
}

enum SCROLLABLE_STATUS {
  LOCKED = 0,
  UNLOCKED = 1,
  UNDETERMINED = 2,
}

interface DetentsState {
  detents?: number[];
  dynamicDetentIndex?: number;
  highestDetentPosition?: number;
  closedDetentPosition?: number;
}

interface AnimationState {
  status: ANIMATION_STATUS;
  source: ANIMATION_SOURCE;
  nextIndex?: number;
  nextPosition?: number;
  isForcedClosing?: boolean;
}