react-native-infinite-pager

repository·main·Indexed 42 days ago

https://github.com/computerjazz/react-native-infinite-pager

A pager component for React Native that renders pages dynamically and supports infinitely-swipeable horizontal or vertical navigation. Powered by Reanimated 2 and React Native Gesture Handler, it includes built-in animation presets such as SLIDE, CUBE, STACK, and TURN_IN, as well as an imperative API for programmatic page navigation.

Tokens
3.5K
Snippets
11
Records
14
Agent score
52%

What's inside react-native-infinite-pager

  1. Install react-native-infinite-pager

    main

    To use react-native-infinite-pager, you must first ensure that react-native-reanimated and react-native-gesture-handler are installed and configured in your project. Then, install the package using npm or yarn:

    npm install react-native-infinite-pager
    # or
    yarn add react-native-infinite-pager

    Import it into your component as follows:

    import InfinitePager from 'react-native-infinite-pager'
    npm install react-native-infinite-pager
  2. Use the InfinitePager component

    main

    InfinitePager is the main component for creating infinite paginated views in React Native. It supports both horizontal and vertical orientations and provides several animation presets like SLIDE, CUBE, STACK, and TURN_IN. You must provide either a PageComponent or a renderPage prop to define how individual pages are rendered.

    To use it, pass a component that accepts InfinitePagerPageProps or a render function. You can also control the pager imperatively using a ref.

    import React, { useRef } from 'react';
    import InfinitePager, { InfinitePagerImperativeApi, Preset } from 'react-native-infinite-pager';
    
    const MyPage = ({ index, isActive }: any) => (
      <View style={{ flex: 1, backgroundColor: index % 2 === 0 ? 'red' : 'blue' }} />
    );
    
    const App = () => {
      const pagerRef = useRef<InfinitePagerImperativeApi>(null);
    
      return (
        <InfinitePager
          ref={pagerRef}
          preset={Preset.SLIDE}
          PageComponent={MyPage}
          initialIndex={0}
        />
      );
    };
  3. Example: Basic InfinitePager implementation

    main

    This example demonstrates a basic implementation of InfinitePager with 50 items, where each page displays its index and a dynamic background color.

    import React from "react";
    import { Text, View, StyleSheet } from "react-native";
    import InfinitePager from "react-native-infinite-pager";
    
    const NUM_ITEMS = 50;
    
    function getColor(i: number) {
      const multiplier = 255 / (NUM_ITEMS - 1);
      const colorVal = Math.abs(i) * multiplier;
      return `rgb(${colorVal}, ${Math.abs(128 - colorVal)}, ${255 - colorVal})`;
    }
    
    const Page = ({ index }: { index: number }) => {
      return (
        <View
          style=[
            styles.flex,
            {
              alignItems: "center",
              justifyContent: "center",
              backgroundColor: getColor(index),
            },
          ]}
        >
          <Text style={{ color: "white", fontSize: 80 }}>{index}</Text>
        </View>
      );
    };
    
    export default function App() {
      return (
        <View style={styles.flex}>
          <InfinitePager
            PageComponent={Page}
            style={styles.flex}
            pageWrapperStyle={styles.flex}
          />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      flex: { flex: 1 },
    });
  4. Configure InfinitePager props

    main

    The InfinitePager component accepts several props to control its behavior, styling, and rendering.

    Rendering Options:

    • PageComponent: A component used to render each page. It receives PageProps (including index, focusAnim, isActive, pageWidthAnim, and pageAnim).
    • renderPage: A function used to render each page. Note: You must provide either PageComponent or renderPage, but not both.

    Behavioral Props:

    • onPageChange: Callback invoked when the current page changes. Receives the new page index.
    • pageBuffer: Number of pages to render on either side of the active page.
    • vertical: Boolean to set the paging axis to vertical.
    • minIndex / maxIndex: Optional indices to restrict infinite behavior.
    • initialIndex: The index at which the pager starts.
    • gesturesDisabled: Boolean to disable pan gestures.
    • flingVelocity: Sensitivity of the page-turning "fling".
    • animationConfig: Customizes paging animations using WithSpringConfig.

    Styling Props:

    • style: Style for the pager container.
    • pageWrapperStyle: Style for the container wrapping each page.
    • pageInterpolator: Function for custom page animations.
  5. Use the InfinitePager Imperative API

    main

    You can control the pager programmatically using the InfinitePagerImperativeApi. This API allows you to navigate between pages without relying solely on user gestures.

    Methods available:

    • setPage(index: number, options: ImperativeApiOptions): Navigates to a specific page index.
    • incrementPage(options: ImperativeApiOptions): Navigates to the next page.
    • decrementPage(options: ImperativeApiOptions): Navigates to the previous page.

    ImperativeApiOptions supports an animated boolean property to control whether the transition is animated.

    type ImperativeApiOptions = {
      animated?: boolean;
    };
    
    export type InfinitePagerImperativeApi = {
      setPage: (index: number, options: ImperativeApiOptions) => void;
      incrementPage: (options: ImperativeApiOptions) => void;
      decrementPage: (options: ImperativeApiOptions) => void;
    };
  6. Use the InfinitePagerImperativeApi

    main

    You can control the pager programmatically using the InfinitePagerImperativeApi exposed via a ref.

    Methods:

    • setPage(index: number, options?: { animated?: boolean }): Moves to a specific index. If animated is true, it uses the spring animation.
    • incrementPage(options?: { animated?: boolean }): Moves to the next page.
    • decrementPage(options?: { animated?: boolean }): Moves to the previous page.
    • gestureRef: A mutable ref to the underlying GestureType used by the pager.
    const pagerRef = useRef<InfinitePagerImperativeApi>(null);
    
    // Move to page 5 with animation
    pagerRef.current?.setPage(5, { animated: true });
    
    // Go to next page without animation
    pagerRef.current?.incrementPage({ animated: false });
  7. Use built-in page interpolators for transitions

    main

    The library provides several pre-defined interpolation functions to customize how pages transition during scrolling. These functions are designed to be used with react-native-reanimated and return style objects (including transforms and opacity) based on the current focus animation value.

    Each interpolator accepts a PageInterpolatorParams object containing:

    • focusAnim: The shared value representing the focus state.
    • pageWidth: A shared value for the page width.
    • pageHeight: A shared value for the page height.
    • vertical: Boolean indicating if the pager is in vertical mode.
    • pageBuffer (specific to pageInterpolatorStack): The buffer size for stack effects.

    Available interpolators:

    • pageInterpolatorSlide: A standard sliding transition.
    • pageInterpolatorCube: A 3D cube-like rotation effect.
    • pageInterpolatorStack: A stacking effect where pages scale and fade in/out based on a buffer.
    • pageInterpolatorTurnIn: A 3D 'turn-in' effect involving rotation and scaling.

    defaultPageInterpolator is an alias for pageInterpolatorSlide.

  8. Configure InfinitePagerProps

    main

    The InfinitePagerProps object defines the behavior and appearance of the pager:

    • vertical: Boolean. If true, the pager scrolls vertically.
    • PageComponent: A component that receives InfinitePagerPageProps.
    • renderPage: A function that receives InfinitePagerPageProps to render a page.
    • onPageChange: Callback triggered when the page index changes.
    • pageBuffer: Number of pages to render on either side of the active page (defaults to 1).
    • preset: Animation style from the Preset enum (SLIDE, CUBE, STACK, TURN_IN).
    • minIndex / maxIndex: Bounds for the pager index.
    • initialIndex: The starting page index.
    • animationConfig: Partial WithSpringConfig to customize spring animations.
    • gesturesDisabled: Boolean to disable all pager gestures.
    • simultaneousGestures: Array of gestures that should work alongside the pager's pan gesture.
    • width / height: Explicit dimensions for the pager container.
  9. Use Preset animation styles

    main

    The Preset enum allows you to quickly switch between different page transition styles:

    • Preset.SLIDE: Standard sliding transition.
    • Preset.CUBE: A 3D cube-like rotation.
    • Preset.STACK: A stacking effect.
    • Preset.TURN_IN: A turning/flipping effect.
    export enum Preset {
      SLIDE = "slide",
      CUBE = "cube",
      STACK = "stack",
      TURN_IN = "turn-in",
    }
  10. pageInterpolatorSlide

    main

    Provides a standard sliding transition for pages. It calculates translateX or translateY based on the vertical flag and the focusAnim value.

    Returns a useAnimatedStyle object containing a transform array with translateX and translateY.

    import { pageInterpolatorSlide } from 'react-native-infinite-pager';
    
    // Usage within a component
    const animatedStyle = pageInterpolatorSlide({
      focusAnim,
      pageWidth,
      pageHeight,
      vertical,
    });
  11. Define an InfinitePagerPageComponent

    main

    A page component must conform to the InfinitePagerPageComponent type. It receives the following props to allow for custom animations and styling based on the page's state:

    • index: The current index of the page.
    • isActive: Boolean indicating if the page is the currently focused page.
    • focusAnim: A DerivedValue<number> representing the focus position (useful for parallax or scaling).
    • pageWidthAnim: A SharedValue<number> representing the width of the page.
    • pageHeightAnim: A SharedValue<number> representing the height of the page.
    • pageAnim: A SharedValue<number> representing the current page index (as a float).
    type InfinitePagerPageProps = {
      index: number;
      focusAnim: DerivedValue<number>;
      isActive: boolean;
      pageWidthAnim: SharedValue<number>;
      pageHeightAnim: SharedValue<number>;
      pageAnim: SharedValue<number>;
    };
    
    const MyPage: InfinitePagerPageComponent = ({ index, isActive, focusAnim }) => {
      return (
        <Animated.View style={{ opacity: focusAnim.value }}>
          <Text>Page {index}</Text>
        </Animated.View
      );
    };
  12. pageInterpolatorCube

    main

    Provides a 3D cube rotation effect. It uses perspective and calculates complex rotations (rotateX or rotateY) and translations to simulate a cube turning. It also interpolates opacity to fade pages in and out during the transition.

    Note: The rotation ratio varies by platform (Android uses 1.23, others use 2).

    import { pageInterpolatorCube } from 'react-native-infinite-pager';
    
    const animatedStyle = pageInterpolatorCube({
      focusAnim,
      pageWidth,
      pageHeight,
      vertical,
    });