Skip to content

React Native component designed to display the current page of a swiper, slideshow, carousel, and more.

License

Notifications You must be signed in to change notification settings

kolking/react-native-page-indicator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

React Native Page Indicator

React Native component designed to display the current page of a swiper, slideshow, carousel, and more. You can choose from three pre-defined design variants and further customize the look and feel according to your specific requirements. All design variants support both horizontal and vertical orientations. This package has no dependencies and utilizes React Native's Animated API with the native driver to achieve seamless and fluid animations.

Horizontal Vertical

Design Variants

Morse Beads Train

Installation

yarn

yarn add react-native-page-indicator

npm

npm install react-native-page-indicator

Basic example

Pass the total number of pages as the count prop and the current page index as the current prop.

import React from 'react';
import { View, StyleSheet } from 'react-native';
import { PageIndicator } from 'react-native-page-indicator';

const MyComponent = ({ pages, current }) => (
  <View style={styles.wrapper}>
    <PageIndicator count={pages} current={current} />
  </View>
);

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default MyComponent;

Advanced example

To create a more engaging experience where the indicator dynamically responds to the scroll position, you can pass the current page index as an Animated.Value rather than a regular number. The easiest approach to obtain the animated value is by dividing the corresponding scroll position by the page width (for horizontal scrolling) or page height (for vertical scrolling).

import React, { useRef } from 'react';
import { Animated, StyleSheet, Text, View, useWindowDimensions } from 'react-native';
import { PageIndicator } from 'react-native-page-indicator';

const pages = ['Page 1', 'Page 2', 'Page 3'];

const App = () => {
  const { width, height } = useWindowDimensions();
  const scrollX = useRef(new Animated.Value(0)).current;
  const animatedCurrent = useRef(Animated.divide(scrollX, width)).current;

  return (
    <View style={styles.root}>
      <Animated.ScrollView
        horizontal={true}
        pagingEnabled={true}
        showsHorizontalScrollIndicator={false}
        onScroll={Animated.event([{ nativeEvent: { contentOffset: { x: scrollX } } }], {
          useNativeDriver: true,
        })}
      >
        {pages.map((page, index) => (
          <View key={index} style={[styles.page, { width, height }]}>
            <Text>{page}</Text>
          </View>
        ))}
      </Animated.ScrollView>
      <View style={styles.pageIndicator}>
        <PageIndicator count={pages.length} current={animatedCurrent} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    flex: 1,
  },
  page: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  pageIndicator: {
    left: 20,
    right: 20,
    bottom: 50,
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

Common Props

Prop Type Default Description
count number The total number of pages (required)
current number | Animated.Value 0 The current page index can be either a number or an animated value obtained from the scroll position
variant 'morse' | 'beads' | 'train' morse Pre-defined design variant
vertical boolean false When true the indicators will be stacked vertically
color string black Color of the indicators
activeColor string Optional color of the active indicator
gap number 6 Distance between the indicators
opacity number 0.5 Opacity of the inactive indicators
borderRadius number size / 2 Border radius of the indicators
duration number 500 Animation duration (has no effect when Animated.Value is provided for the current prop)
easing EasingFunction Easing.out() Animation easing function (has no effect when Animated.Value is provided for the current prop)
style ViewStyle Style object applied to the wrapping view

Morse Variant Props

Prop Type Default Description
size number 6 Size of the inactive indicators and the thickness of the active indicator
dashSize number size * 4 Length of the active indicator, cannot be smaller than size * 2

Train Variant Props

Prop Type Default Description
size number 6 Thickness of the indicators
dashSize number size * 4 Length of the indicators, cannot be smaller then size

Beads Variant Props

Prop Type Default Description
size number 6 Size of the indicators
scale number 1.5 Scaling factor of the active indicator

Feedback

I appreciate your feedback, so please star the repository if you like it. This is the best motivation for me to maintain the package and add new features. If you have any feature requests, found a bug, or have ideas for improvement, feel free to open an issue.

Also, please check out my other React Native components that might be a good fit for your project:

License

Licensed under the MIT license.