CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-navigation--bottom-tabs

Bottom tab navigator following iOS design guidelines for React Navigation

Pending
Overview
Eval results
Files

animations-transitions.mddocs/

Animation and Transitions

Built-in animation presets and custom transition configurations for smooth tab switching experiences with full control over timing, easing, and visual effects.

Capabilities

Scene Style Interpolators

Pre-built interpolation functions for common tab transition animations.

/**
 * Scene style interpolators for tab transitions
 */
const SceneStyleInterpolators: {
  /**
   * Simple cross-fade animation between tabs
   */
  forFade: BottomTabSceneStyleInterpolator;
  
  /**
   * Animation where screens slightly shift to left/right during transitions
   */
  forShift: BottomTabSceneStyleInterpolator;
};

/**
 * Function type for scene style interpolation
 */
type BottomTabSceneStyleInterpolator = (
  props: BottomTabSceneInterpolationProps
) => BottomTabSceneInterpolatedStyle;

interface BottomTabSceneInterpolationProps {
  current: {
    /**
     * Animated value for the current screen:
     * - -1 if the index is lower than active tab
     * - 0 if they're active  
     * - 1 if the index is higher than active tab
     */
    progress: Animated.Value;
  };
}

interface BottomTabSceneInterpolatedStyle {
  /**
   * Interpolated style for the view containing screen content
   */
  sceneStyle: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}

Usage Examples:

import { SceneStyleInterpolators } from "@react-navigation/bottom-tabs";

<Tab.Screen
  name="FadeScreen"
  component={FadeScreen}
  options={{
    animation: 'fade',
    sceneStyleInterpolator: SceneStyleInterpolators.forFade,
  }}
/>

<Tab.Screen
  name="ShiftScreen"
  component={ShiftScreen}
  options={{
    animation: 'shift',
    sceneStyleInterpolator: SceneStyleInterpolators.forShift,
  }}
/>

Transition Presets

Complete animation presets combining timing specifications with style interpolators.

/**
 * Pre-configured transition presets for tab animations
 */
const TransitionPresets: {
  /**
   * Fade transition with timing configuration
   */
  FadeTransition: BottomTabTransitionPreset;
  
  /**
   * Shift transition with timing configuration
   */
  ShiftTransition: BottomTabTransitionPreset;
};

interface BottomTabTransitionPreset {
  /**
   * Whether transition animations should be enabled when switching tabs
   */
  animationEnabled?: boolean;
  
  /**
   * Function which specifies interpolated styles for bottom-tab scenes
   */
  sceneStyleInterpolator?: BottomTabSceneStyleInterpolator;
  
  /**
   * Object which specifies the animation type (timing or spring) and options
   */
  transitionSpec?: TransitionSpec;
}

Usage Examples:

import { TransitionPresets } from "@react-navigation/bottom-tabs";

<Tab.Navigator
  screenOptions={{
    ...TransitionPresets.FadeTransition,
  }}
>
  {/* All screens will use fade transition */}
</Tab.Navigator>

<Tab.Screen
  name="SpecialScreen"
  component={SpecialScreen}
  options={{
    ...TransitionPresets.ShiftTransition,
    // Override specific properties
    animationEnabled: true,
  }}
/>

Transition Specifications

Timing and spring animation configurations for precise control over transition behavior.

/**
 * Animation timing specifications
 */
const TransitionSpecs: {
  /**
   * Timing spec for fade animations (150ms linear easing)
   */
  FadeSpec: TransitionSpec;
  
  /**
   * Timing spec for shift animations (150ms ease-in-out)
   */
  ShiftSpec: TransitionSpec;
};

type TransitionSpec = 
  | {
      animation: 'timing';
      config: Omit<
        Animated.TimingAnimationConfig,
        'toValue' | keyof Animated.AnimationConfig
      >;
    }
  | {
      animation: 'spring';
      config: Omit<
        Animated.SpringAnimationConfig,
        'toValue' | keyof Animated.AnimationConfig
      >;
    };

Usage Examples:

import { TransitionSpecs } from "@react-navigation/bottom-tabs";

<Tab.Screen
  name="TimedScreen"
  component={TimedScreen}
  options={{
    transitionSpec: TransitionSpecs.FadeSpec,
    animation: 'fade',
  }}
/>

// Custom timing specification
<Tab.Screen
  name="CustomTiming"
  component={CustomScreen}
  options={{
    transitionSpec: {
      animation: 'timing',
      config: {
        duration: 300,
        easing: Easing.bezier(0.4, 0, 0.2, 1),
      },
    },
  }}
/>

// Spring animation specification
<Tab.Screen
  name="SpringScreen"
  component={SpringScreen}
  options={{
    transitionSpec: {
      animation: 'spring',
      config: {
        stiffness: 1000,
        damping: 500,
        mass: 3,
        overshootClamping: true,
        restDisplacementThreshold: 0.01,
        restSpeedThreshold: 0.01,
      },
    },
  }}
/>

Custom Scene Interpolators

Create custom animation effects by implementing your own scene style interpolators.

/**
 * Custom scene style interpolator implementation
 */
type CustomSceneStyleInterpolator = (
  props: BottomTabSceneInterpolationProps
) => BottomTabSceneInterpolatedStyle;

Usage Examples:

// Custom scale and rotate interpolator
const scaleRotateInterpolator = ({ current }) => ({
  sceneStyle: {
    opacity: current.progress.interpolate({
      inputRange: [-1, 0, 1],
      outputRange: [0, 1, 0],
    }),
    transform: [
      {
        scale: current.progress.interpolate({
          inputRange: [-1, 0, 1],
          outputRange: [0.85, 1, 0.85],
        }),
      },
      {
        rotateY: current.progress.interpolate({
          inputRange: [-1, 0, 1],
          outputRange: ['-45deg', '0deg', '45deg'],
        }),
      },
    ],
  },
});

// Custom slide and blur effect
const slideBlurInterpolator = ({ current }) => ({
  sceneStyle: {
    opacity: current.progress.interpolate({
      inputRange: [-1, -0.5, 0, 0.5, 1],
      outputRange: [0, 0.5, 1, 0.5, 0],
    }),
    transform: [
      {
        translateX: current.progress.interpolate({
          inputRange: [-1, 0, 1],
          outputRange: [-200, 0, 200],
        }),
      },
      {
        scale: current.progress.interpolate({
          inputRange: [-1, -0.2, 0, 0.2, 1],
          outputRange: [0.8, 0.95, 1, 0.95, 0.8],
        }),
      },
    ],
  },
});

<Tab.Screen
  name="CustomAnimated"
  component={CustomScreen}
  options={{
    sceneStyleInterpolator: scaleRotateInterpolator,
    transitionSpec: {
      animation: 'spring',
      config: {
        stiffness: 100,
        damping: 15,
      },
    },
  }}
/>

Animation Names

Built-in animation names for common transition effects.

/**
 * Built-in animation names for tab transitions
 */
type TabAnimationName = 'none' | 'fade' | 'shift';

Usage Examples:

<Tab.Navigator
  screenOptions={{
    animation: 'fade', // Apply fade animation to all screens
  }}
>
  <Tab.Screen name="Home" component={HomeScreen} />
  <Tab.Screen 
    name="Special" 
    component={SpecialScreen}
    options={{
      animation: 'shift', // Override with shift animation
    }}
  />
  <Tab.Screen 
    name="Static" 
    component={StaticScreen}
    options={{
      animation: 'none', // No animation for this screen
    }}
  />
</Tab.Navigator>

Keyboard Animation Configuration

Configure tab bar visibility animations when the keyboard appears or disappears.

/**
 * Animation configuration for tab bar visibility changes
 */
interface TabBarVisibilityAnimationConfig {
  show?: TabBarVisibilityAnimation;
  hide?: TabBarVisibilityAnimation;
}

type TabBarVisibilityAnimation = 
  | TimingKeyboardAnimationConfig 
  | SpringKeyboardAnimationConfig;

interface TimingKeyboardAnimationConfig {
  animation: 'timing';
  config?: Omit<
    Partial<Animated.TimingAnimationConfig>,
    'toValue' | 'useNativeDriver'
  >;
}

interface SpringKeyboardAnimationConfig {
  animation: 'spring';
  config?: Omit<
    Partial<Animated.SpringAnimationConfig>,
    'toValue' | 'useNativeDriver'
  >;
}

Usage Examples:

<Tab.Navigator
  screenOptions={{
    tabBarHideOnKeyboard: true,
    tabBarVisibilityAnimationConfig: {
      show: {
        animation: 'spring',
        config: {
          damping: 15,
          stiffness: 150,
          mass: 1,
        },
      },
      hide: {
        animation: 'timing',
        config: {
          duration: 200,
          easing: Easing.out(Easing.cubic),
        },
      },
    },
  }}
>
  {/* screens */}
</Tab.Navigator>

Performance Optimization

Optimize animations for better performance and smoother transitions.

/**
 * Animation configuration options for performance optimization
 */
interface AnimationPerformanceOptions {
  /**
   * Whether to use native driver for animations (automatically determined by platform)
   */
  useNativeDriver?: boolean;
  
  /**
   * Whether to enable GPU acceleration for transforms
   */
  enableGPUAcceleration?: boolean;
}

Usage Examples:

// Optimized custom interpolator
const optimizedInterpolator = ({ current }) => ({
  sceneStyle: {
    // Use transforms instead of changing layout properties
    transform: [
      {
        translateX: current.progress.interpolate({
          inputRange: [-1, 0, 1],
          outputRange: [-50, 0, 50],
        }),
      },
    ],
    // Avoid changing opacity if not necessary for better performance
    opacity: current.progress.interpolate({
      inputRange: [-1, -0.01, 0, 0.01, 1],
      outputRange: [0, 0, 1, 0, 0],
    }),
  },
});

// Performance-optimized timing config
const performantTransitionSpec = {
  animation: 'timing',
  config: {
    duration: 150,
    easing: Easing.out(Easing.cubic),
    // These properties are automatically handled by React Navigation
    useNativeDriver: true,
  },
};

Animation State Management

Monitor and control animation states programmatically.

/**
 * Animation event handlers
 */
interface AnimationEventHandlers {
  /**
   * Called when transition animation starts
   */
  onTransitionStart?: () => void;
  
  /**
   * Called when transition animation ends
   */
  onTransitionEnd?: () => void;
}

Usage Examples:

function AnimatedScreen({ navigation }) {
  React.useEffect(() => {
    const startListener = navigation.addListener('transitionStart', () => {
      console.log('Animation started');
      // Pause expensive operations during animation
      pauseBackgroundTasks();
    });
    
    const endListener = navigation.addListener('transitionEnd', () => {
      console.log('Animation ended');
      // Resume operations after animation
      resumeBackgroundTasks();
    });
    
    return () => {
      startListener();
      endListener();
    };
  }, [navigation]);
  
  return <View>{/* screen content */}</View>;
}

Combining Animation Features

Complete example combining multiple animation features for a rich user experience.

const advancedAnimationConfig = {
  animation: 'fade',
  sceneStyleInterpolator: ({ current }) => ({
    sceneStyle: {
      opacity: current.progress.interpolate({
        inputRange: [-1, 0, 1],
        outputRange: [0, 1, 0],
      }),
      transform: [
        {
          scale: current.progress.interpolate({
            inputRange: [-1, -0.5, 0, 0.5, 1],
            outputRange: [0.9, 0.95, 1, 0.95, 0.9],
          }),
        },
        {
          translateY: current.progress.interpolate({
            inputRange: [-1, 0, 1],
            outputRange: [50, 0, -50],
          }),
        },
      ],
    },
  }),
  transitionSpec: {
    animation: 'spring',
    config: {
      stiffness: 300,
      damping: 25,
      mass: 1,
    },
  },
};

<Tab.Screen
  name="AdvancedAnimated"
  component={AdvancedScreen}
  options={advancedAnimationConfig}
/>

Install with Tessl CLI

npx tessl i tessl/npm-react-navigation--bottom-tabs

docs

animations-transitions.md

index.md

navigation-routing.md

navigator-creation.md

screen-configuration.md

tab-bar-customization.md

utilities-hooks.md

tile.json