CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-gorhom--bottom-sheet

A performant interactive bottom sheet with fully configurable options for React Native applications.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

animation-configuration.mddocs/

Animation Configuration

Hooks and utilities for creating and customizing animation configurations for bottom sheet movements, providing both spring and timing-based animations with platform-specific defaults.

Capabilities

useBottomSheetSpringConfigs

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

useBottomSheetTimingConfigs

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

Default Animation Configurations

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;

Reduce Motion Support

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

Common Animation Patterns

Quick Actions

For rapid interactions like buttons or toggles:

const quickAnimation = useBottomSheetTimingConfigs({
  duration: 150,
  easing: Easing.out(Easing.quad),
});

Smooth Transitions

For content changes or navigation:

const smoothAnimation = useBottomSheetSpringConfigs({
  damping: 80,
  stiffness: 500,
  mass: 1,
});

Playful Interactions

For engaging user interactions:

const playfulAnimation = useBottomSheetSpringConfigs({
  damping: 20,
  stiffness: 300,
  mass: 1.5,
  overshootClamping: false,
});

Precise Positioning

For exact positioning requirements:

const preciseAnimation = useBottomSheetSpringConfigs({
  damping: 100,
  stiffness: 800,
  mass: 0.8,
  overshootClamping: true,
  restDisplacementThreshold: 0.1,
  restSpeedThreshold: 0.1,
});

Easing Functions

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)

docs

animation-configuration.md

bottom-sheet-component.md

control-hooks.md

gesture-event-handling.md

index.md

modal-components.md

scrollable-components.md

ui-components.md

tile.json