Hooks and utilities for creating and customizing animation configurations for bottom sheet movements, providing both spring and timing-based animations with platform-specific defaults.
Utility hook for generating spring animation configurations with proper defaults and type safety.
/**
* Hook for generating spring animation configurations
* Currently a pass-through function that may be enhanced in future versions
* @param configs - Spring animation configuration (excludes velocity)
* @returns Memoized spring configuration object
*/
declare function useBottomSheetSpringConfigs(
configs: Omit<WithSpringConfig, 'velocity'>
): Omit<WithSpringConfig, 'velocity'>;
interface WithSpringConfig {
/** Damping ratio for spring animation */
damping?: number;
/** Stiffness of the spring */
stiffness?: number;
/** Mass of the object being animated */
mass?: number;
/** Initial velocity (managed internally by library) */
velocity?: number;
/** Whether to clamp overshoot */
overshootClamping?: boolean;
/** Threshold for displacement at rest */
restDisplacementThreshold?: number;
/** Threshold for speed at rest */
restSpeedThreshold?: number;
/** Reduce motion accessibility setting */
reduceMotion?: ReduceMotion;
}Usage Examples:
import React, { useMemo } from 'react';
import { View } from 'react-native';
import BottomSheet, {
useBottomSheet,
useBottomSheetSpringConfigs
} from '@gorhom/bottom-sheet';
// Basic spring configuration
const SpringExample = () => {
const springConfigs = useBottomSheetSpringConfigs({
damping: 80,
stiffness: 500,
mass: 1,
overshootClamping: true,
restDisplacementThreshold: 0.1,
restSpeedThreshold: 0.1,
});
const { snapToIndex } = useBottomSheet();
const handleSnapWithSpring = () => {
snapToIndex(1, springConfigs);
};
return (
<View>
<Button title="Snap with Spring" onPress={handleSnapWithSpring} />
</View>
);
};
// Bouncy spring animation
const BouncySpringExample = () => {
const bouncySpring = useBottomSheetSpringConfigs({
damping: 15,
stiffness: 200,
mass: 2,
overshootClamping: false, // Allow overshoot for bounce effect
});
const { expand } = useBottomSheet();
const expandWithBounce = () => {
expand(bouncySpring);
};
return (
<View>
<Button title="Bouncy Expand" onPress={expandWithBounce} />
</View>
);
};
// Stiff, fast spring
const FastSpringExample = () => {
const fastSpring = useBottomSheetSpringConfigs({
damping: 50,
stiffness: 1000,
mass: 0.5,
overshootClamping: true,
});
const { close } = useBottomSheet();
const fastClose = () => {
close(fastSpring);
};
return (
<View>
<Button title="Fast Close" onPress={fastClose} />
</View>
);
};
// Responsive to reduce motion settings
const AccessibleSpringExample = () => {
const accessibleSpring = useBottomSheetSpringConfigs({
damping: 80,
stiffness: 400,
reduceMotion: ReduceMotion.System, // Respects system settings
});
const { snapToIndex } = useBottomSheet();
const accessibleSnap = () => {
snapToIndex(2, accessibleSpring);
};
return (
<View>
<Button title="Accessible Snap" onPress={accessibleSnap} />
</View>
);
};Generates timing animation configurations with sensible defaults for duration and easing functions.
/**
* Hook for generating timing animation configurations
* Provides defaults: duration: 250ms, easing: Easing.out(Easing.exp)
* @param configs - Timing animation configuration
* @returns Memoized timing configuration object
*/
declare function useBottomSheetTimingConfigs(
configs: TimingConfig
): TimingConfig;
interface TimingConfig {
/** Animation duration in milliseconds */
duration?: number;
/** Easing function for animation curve */
easing?: EasingFunction | EasingFunctionFactory;
/** Reduce motion accessibility setting */
reduceMotion?: ReduceMotion;
}Usage Examples:
import React from 'react';
import { View, Button } from 'react-native';
import { Easing } from 'react-native-reanimated';
import BottomSheet, {
useBottomSheet,
useBottomSheetTimingConfigs
} from '@gorhom/bottom-sheet';
// Basic timing configuration
const TimingExample = () => {
const timingConfigs = useBottomSheetTimingConfigs({
duration: 300,
easing: Easing.bezier(0.25, 0.46, 0.45, 0.94),
});
const { snapToIndex } = useBottomSheet();
const handleSnapWithTiming = () => {
snapToIndex(1, timingConfigs);
};
return (
<View>
<Button title="Snap with Timing" onPress={handleSnapWithTiming} />
</View>
);
};
// Fast, snappy animation
const FastTimingExample = () => {
const fastTiming = useBottomSheetTimingConfigs({
duration: 150,
easing: Easing.out(Easing.quad),
});
const { collapse } = useBottomSheet();
const fastCollapse = () => {
collapse(fastTiming);
};
return (
<View>
<Button title="Fast Collapse" onPress={fastCollapse} />
</View>
);
};
// Slow, smooth animation
const SmoothTimingExample = () => {
const smoothTiming = useBottomSheetTimingConfigs({
duration: 600,
easing: Easing.bezier(0.4, 0.0, 0.2, 1.0), // Material Design easing
});
const { expand } = useBottomSheet();
const smoothExpand = () => {
expand(smoothTiming);
};
return (
<View>
<Button title="Smooth Expand" onPress={smoothExpand} />
</View>
);
};
// Custom easing curves
const CustomEasingExample = () => {
const customTiming = useBottomSheetTimingConfigs({
duration: 400,
easing: Easing.inOut(Easing.back(1.5)), // Back easing with custom factor
});
const { snapToPosition } = useBottomSheet();
const customSnap = () => {
snapToPosition('75%', customTiming);
};
return (
<View>
<Button title="Custom Easing Snap" onPress={customSnap} />
</View>
);
};
// Accessibility-aware timing
const AccessibleTimingExample = () => {
const accessibleTiming = useBottomSheetTimingConfigs({
duration: 250,
easing: Easing.out(Easing.exp),
reduceMotion: ReduceMotion.System,
});
const { close } = useBottomSheet();
const accessibleClose = () => {
close(accessibleTiming);
};
return (
<View>
<Button title="Accessible Close" onPress={accessibleClose} />
</View>
);
};The library provides platform-specific default configurations:
/** Platform-specific default animation configurations */
const ANIMATION_CONFIGS = Platform.select<TimingConfig | SpringConfig>({
android: {
duration: 250,
easing: Easing.out(Easing.exp),
},
default: {
damping: 500,
stiffness: 1000,
mass: 3,
overshootClamping: true,
restDisplacementThreshold: 10,
restSpeedThreshold: 10,
},
});
const ANIMATION_EASING: EasingFunction = Easing.out(Easing.exp);
const ANIMATION_DURATION = 250;All animation configurations support accessibility settings:
enum ReduceMotion {
/** Follow system accessibility settings (default) */
System = 'system',
/** Always disable animations */
Always = 'always',
/** Never disable animations */
Never = 'never',
}Usage with Reduce Motion:
// Automatically respect system settings
const respectfulAnimation = useBottomSheetSpringConfigs({
damping: 80,
stiffness: 400,
reduceMotion: ReduceMotion.System, // Default behavior
});
// Force disable animations
const noAnimation = useBottomSheetTimingConfigs({
duration: 0, // Instant
reduceMotion: ReduceMotion.Always,
});
// Force enable animations
const alwaysAnimated = useBottomSheetSpringConfigs({
damping: 50,
stiffness: 300,
reduceMotion: ReduceMotion.Never,
});For rapid interactions like buttons or toggles:
const quickAnimation = useBottomSheetTimingConfigs({
duration: 150,
easing: Easing.out(Easing.quad),
});For content changes or navigation:
const smoothAnimation = useBottomSheetSpringConfigs({
damping: 80,
stiffness: 500,
mass: 1,
});For engaging user interactions:
const playfulAnimation = useBottomSheetSpringConfigs({
damping: 20,
stiffness: 300,
mass: 1.5,
overshootClamping: false,
});For exact positioning requirements:
const preciseAnimation = useBottomSheetSpringConfigs({
damping: 100,
stiffness: 800,
mass: 0.8,
overshootClamping: true,
restDisplacementThreshold: 0.1,
restSpeedThreshold: 0.1,
});Common easing functions available from React Native Reanimated:
// Linear
Easing.linear
// Quadratic
Easing.quad
Easing.in(Easing.quad)
Easing.out(Easing.quad)
Easing.inOut(Easing.quad)
// Cubic
Easing.cubic
Easing.in(Easing.cubic)
Easing.out(Easing.cubic)
Easing.inOut(Easing.cubic)
// Exponential
Easing.exp
Easing.in(Easing.exp)
Easing.out(Easing.exp)
Easing.inOut(Easing.exp)
// Back
Easing.back(overshoot)
Easing.in(Easing.back(1.7))
Easing.out(Easing.back(1.7))
Easing.inOut(Easing.back(1.7))
// Bounce
Easing.bounce
Easing.in(Easing.bounce)
Easing.out(Easing.bounce)
Easing.inOut(Easing.bounce)
// Bezier curves
Easing.bezier(x1, y1, x2, y2)