CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-pager-view

React Native wrapper for Android and iOS ViewPager

Pending
Overview
Eval results
Files

use-pager-view.mddocs/

State Management Hook

React hook for managing PagerView state, animations, and programmatic control with React Native Reanimated integration. Provides a comprehensive interface for building interactive pager experiences with smooth animations.

Capabilities

usePagerView Hook

Main hook providing stateful management of PagerView with animation support and programmatic controls.

/**
 * Hook for managing PagerView state, animations, and programmatic control
 * @param params - Configuration object with pagesAmount
 * @returns Complete interface for PagerView management
 */
function usePagerView(params?: UsePagerViewParams): UsePagerViewProps;

interface UsePagerViewParams {
  /** Initial number of pages to create. Default: 0 */
  pagesAmount: number;
}

interface UsePagerViewProps {
  /** Ref object for the PagerView component */
  ref: React.MutableRefObject<PagerView | null>;
  
  /** Current active page index */
  activePage: number;
  
  /** Whether page transitions are animated */
  isAnimated: boolean;
  
  /** Array of page indices */
  pages: number[];
  
  /** Current scroll state */
  scrollState: 'idle' | 'dragging' | 'settling';
  
  /** Whether scrolling is enabled */
  scrollEnabled: boolean;
  
  /** Current scroll progress with position and offset */
  progress: { position: number; offset: number };
  
  /** Whether overdrag is enabled */
  overdragEnabled: boolean;
  
  /** Navigate to specific page (respects animation setting) */
  setPage: (page: number) => void;
  
  /** Add a new page to the end */
  addPage: () => void;
  
  /** Remove the last page */
  removePage: () => void;
  
  /** Toggle scroll enabled state */
  toggleScroll: () => void;
  
  /** Toggle animation enabled state */
  toggleAnimation: () => void;
  
  /** Toggle overdrag enabled state */
  toggleOverdrag: () => void;
  
  /** Set progress state manually */
  setProgress: React.Dispatch<React.SetStateAction<{ position: number; offset: number }>>;
  
  /** Animated event handler for page scroll */
  onPageScroll: Animated.Event<PagerViewOnPageScrollEventData>;
  
  /** Animated event handler for page selection */
  onPageSelected: Animated.Event<PagerViewOnPageSelectedEventData>;
  
  /** Scroll state change handler */
  onPageScrollStateChanged: (e: PageScrollStateChangedNativeEvent) => void;
  
  /** Animated version of PagerView component */
  AnimatedPagerView: React.ComponentType<PagerViewProps>;
  
  /** Reference to PagerView component class */
  PagerView: typeof PagerView;
}

Basic Usage Example:

import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { usePagerView } from 'react-native-pager-view';

export default function BasicHookExample() {
  const {
    ref,
    activePage,
    pages,
    setPage,
    addPage,
    removePage,
    PagerView,
  } = usePagerView({ pagesAmount: 3 });

  return (
    <View style={styles.container}>
      <View style={styles.controls}>
        <Text>Active Page: {activePage}</Text>
        <View style={styles.buttonRow}>
          <Button title="Previous" onPress={() => setPage(Math.max(0, activePage - 1))} />
          <Button title="Next" onPress={() => setPage(Math.min(pages.length - 1, activePage + 1))} />
        </View>
        <View style={styles.buttonRow}>
          <Button title="Add Page" onPress={addPage} />
          <Button title="Remove Page" onPress={removePage} />
        </View>
      </View>
      
      <PagerView ref={ref} style={styles.pagerView} initialPage={0}>
        {pages.map((pageIndex) => (
          <View style={styles.page} key={pageIndex}>
            <Text style={styles.text}>Page {pageIndex + 1}</Text>
          </View>
        ))}
      </PagerView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  controls: { padding: 20, backgroundColor: '#f0f0f0' },
  buttonRow: { 
    flexDirection: 'row', 
    justifyContent: 'space-around', 
    marginVertical: 10 
  },
  pagerView: { flex: 1 },
  page: { 
    justifyContent: 'center', 
    alignItems: 'center',
    backgroundColor: '#e0e0e0',
  },
  text: { fontSize: 24, fontWeight: 'bold' },
});

Animation Integration

Advanced animation features with React Native Reanimated integration for smooth, native-feeling transitions.

/** Animated version of PagerView with Reanimated support */
const AnimatedPagerView: React.ComponentType<PagerViewProps>;

/** Animated event handler for scroll events */
const onPageScroll: Animated.Event<{
  nativeEvent: {
    offset: Animated.Value;
    position: Animated.Value;
  };
}>;

/** Animated event handler for page selection events */
const onPageSelected: Animated.Event<{
  nativeEvent: {
    position: Animated.Value;
  };
}>;

Animation Usage Example:

import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
import Animated, { 
  useAnimatedStyle, 
  interpolate, 
  Extrapolate 
} from 'react-native-reanimated';
import { usePagerView } from 'react-native-pager-view';

const { width } = Dimensions.get('window');

export default function AnimatedExample() {
  const {
    ref,
    pages,
    progress,
    onPageScroll,
    onPageSelected,
    AnimatedPagerView,
  } = usePagerView({ pagesAmount: 4 });

  // Animated style for page indicator
  const indicatorStyle = useAnimatedStyle(() => {
    const translateX = interpolate(
      progress.position + progress.offset,
      [0, pages.length - 1],
      [0, (pages.length - 1) * 30],
      Extrapolate.CLAMP
    );
    
    return {
      transform: [{ translateX }],
    };
  });

  return (
    <View style={styles.container}>
      {/* Page indicator */}
      <View style={styles.indicatorContainer}>
        {pages.map((_, index) => (
          <View key={index} style={styles.dot} />
        ))}
        <Animated.View style={[styles.activeDot, indicatorStyle]} />
      </View>
      
      <AnimatedPagerView
        ref={ref}
        style={styles.pagerView}
        initialPage={0}
        onPageScroll={onPageScroll}
        onPageSelected={onPageSelected}
      >
        {pages.map((pageIndex) => (
          <AnimatedPage key={pageIndex} pageIndex={pageIndex} progress={progress} />
        ))}
      </AnimatedPagerView>
    </View>
  );
}

function AnimatedPage({ pageIndex, progress }: { pageIndex: number; progress: any }) {
  const animatedStyle = useAnimatedStyle(() => {
    const scale = interpolate(
      Math.abs(progress.position - pageIndex) + progress.offset,
      [0, 1],
      [1, 0.8],
      Extrapolate.CLAMP
    );
    
    const opacity = interpolate(
      Math.abs(progress.position - pageIndex) + progress.offset,
      [0, 1],
      [1, 0.5],
      Extrapolate.CLAMP
    );
    
    return {
      transform: [{ scale }],
      opacity,
    };
  });

  return (
    <Animated.View style={[styles.page, animatedStyle]}>
      <Text style={styles.text}>Animated Page {pageIndex + 1}</Text>
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  indicatorContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
    paddingVertical: 20,
    position: 'relative',
  },
  dot: {
    width: 20,
    height: 20,
    borderRadius: 10,
    backgroundColor: '#ddd',
    marginHorizontal: 5,
  },
  activeDot: {
    position: 'absolute',
    width: 20,
    height: 20,
    borderRadius: 10,
    backgroundColor: '#007AFF',
  },
  pagerView: { flex: 1 },
  page: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f9f9f9',
    margin: 20,
    borderRadius: 10,
  },
  text: { fontSize: 24, fontWeight: 'bold' },
});

State Management

Comprehensive state management features for dynamic page control and configuration.

/** State management methods */
interface StateManagement {
  /** Current active page index */
  activePage: number;
  
  /** Array of page indices */
  pages: number[];
  
  /** Whether page transitions are animated */
  isAnimated: boolean;
  
  /** Whether scrolling is enabled */
  scrollEnabled: boolean;
  
  /** Whether overdrag is enabled */
  overdragEnabled: boolean;
  
  /** Current scroll state */
  scrollState: 'idle' | 'dragging' | 'settling';
  
  /** Current scroll progress */
  progress: { position: number; offset: number };
}

/** State control methods */
interface StateControls {
  /** Navigate to specific page (respects animation setting) */
  setPage: (page: number) => void;
  
  /** Add a new page to the end */
  addPage: () => void;
  
  /** Remove the last page (minimum 1 page) */
  removePage: () => void;
  
  /** Toggle scroll enabled state */
  toggleScroll: () => void;
  
  /** Toggle animation enabled state */
  toggleAnimation: () => void;
  
  /** Toggle overdrag enabled state */
  toggleOverdrag: () => void;
}

State Management Example:

import React from 'react';
import { View, Text, Button, Switch, StyleSheet } from 'react-native';
import { usePagerView } from 'react-native-pager-view';

export default function StateManagementExample() {
  const {
    ref,
    activePage,
    pages,
    scrollState,
    scrollEnabled,
    isAnimated,
    overdragEnabled,
    progress,
    setPage,
    addPage,
    removePage,
    toggleScroll,
    toggleAnimation,
    toggleOverdrag,
    onPageScrollStateChanged,
    PagerView,
  } = usePagerView({ pagesAmount: 3 });

  return (
    <View style={styles.container}>
      <View style={styles.controls}>
        <Text style={styles.info}>
          Active: {activePage} | Pages: {pages.length} | State: {scrollState}
        </Text>
        <Text style={styles.info}>
          Progress: {progress.position.toFixed(1)} + {progress.offset.toFixed(2)}
        </Text>
        
        <View style={styles.switchRow}>
          <Text>Scroll Enabled:</Text>
          <Switch value={scrollEnabled} onValueChange={toggleScroll} />
        </View>
        
        <View style={styles.switchRow}>
          <Text>Animated:</Text>
          <Switch value={isAnimated} onValueChange={toggleAnimation} />
        </View>
        
        <View style={styles.switchRow}>
          <Text>Overdrag:</Text>
          <Switch value={overdragEnabled} onValueChange={toggleOverdrag} />
        </View>
        
        <View style={styles.buttonRow}>
          <Button title="Add Page" onPress={addPage} />
          <Button title="Remove Page" onPress={removePage} />
        </View>
        
        <View style={styles.buttonRow}>
          {pages.map((pageIndex) => (
            <Button
              key={pageIndex}
              title={`Page ${pageIndex + 1}`}
              onPress={() => setPage(pageIndex)}
            />
          ))}
        </View>
      </View>
      
      <PagerView
        ref={ref}
        style={styles.pagerView}
        initialPage={0}
        scrollEnabled={scrollEnabled}
        overdrag={overdragEnabled}
        onPageScrollStateChanged={onPageScrollStateChanged}
      >
        {pages.map((pageIndex) => (
          <View 
            style={[
              styles.page, 
              { backgroundColor: pageIndex % 2 === 0 ? '#e3f2fd' : '#f3e5f5' }
            ]} 
            key={pageIndex}
          >
            <Text style={styles.text}>Page {pageIndex + 1}</Text>
            <Text style={styles.subtext}>
              {isAnimated ? 'Animated Navigation' : 'Instant Navigation'}
            </Text>
          </View>
        ))}
      </PagerView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  controls: { padding: 16, backgroundColor: '#f5f5f5' },
  info: { textAlign: 'center', marginBottom: 8, fontSize: 14 },
  switchRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginVertical: 8,
  },
  buttonRow: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginVertical: 10,
  },
  pagerView: { flex: 1 },
  page: {
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  text: { fontSize: 24, fontWeight: 'bold', marginBottom: 8 },
  subtext: { fontSize: 16, color: '#666' },
});

Install with Tessl CLI

npx tessl i tessl/npm-react-native-pager-view

docs

index.md

pager-view.md

use-pager-view.md

tile.json