diff --git a/README.md b/README.md
index c72fbe0..94b2c5a 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,9 @@
Fully controllable, high performance pager component w/ gesture support for React Native
-
-
+
+
+
# Installation
@@ -26,14 +27,14 @@ There are additional steps to setting these up:
_These examples were inspired by the docs of the awesome [react-native-snap-carousel library](https://github.com/archriss/react-native-snap-carousel)_
-
-
-
+
+
+
-
-
-
+
+
+
### Basic Pager
@@ -162,7 +163,7 @@ function Buttons({ activeIndex, onChange }) {
## Pager
```typescript
-import { Pager } from 'react-native-pager-component'
+import { Pager } from '@crowdlinker/react-native-pager'
Props
--------
@@ -191,6 +192,43 @@ clampDrag: {
}
```
+## Pagination
+
+```typescript
+import { Pagination } from '@crowdlinker/react-native-pager'
+
+Props
+--------
+children: React.ReactNode;
+animatedIndex: Animated.Value;
+pageInterpolation: iPageInterpolation;
+style?: ViewStyle;
+```
+
+## Slider
+
+```typescript
+import { Slider } from '@crowdlinker/react-native-pager'
+
+Props
+--------
+numberOfScreens: number;
+animatedIndex: Animated.Value;
+style: ViewStyle;
+```
+
+## Progress
+
+```typescript
+import { Progress } from '@crowdlinker/react-native-pager'
+
+Props
+--------
+numberOfScreens: number;
+animatedIndex: Animated.Value;
+style: ViewStyle;
+```
+
## Tabs and Stack
Tab and Stack configurations are pretty straightforward to get setup:
@@ -367,6 +405,7 @@ const swipeCards = {
// you can pass a function as a transformer -- offset in this case will represent
// the distance a screen is from the active screen
// e.g -1 means 1 to the left, 4 means 4 to the right
+ // this will move cards downwards as they get further away from the activeIndex
translateY: (offset: Animated.Value) =>
Animated.multiply(offset, 10),
},
@@ -380,7 +419,7 @@ const swipeCards = {
},
],
- // any Animated[fn] can be used in these functions
+ // any Animated function can be used in these
zIndex: offset => floor(divide(offset, -1)),
};
@@ -388,3 +427,75 @@ const swipeCards = {
...
;
```
+
+## Pagination
+
+
+
+
+
+There's a few components to display the current active tab. These require an `animatedIndex` prop that you can pass into the active pager component and share with these components:
+
+```javascript
+
+const animatedIndex = new Value(0)
+
+function MyPager({ children }) {
+
+
+ {children}
+
+
+ // e.g: render this somewhere
+
+}
+```
+
+There are three right now: ``, `` and ``. The API for these might change as it would be nice to have less opinionated and configurable components here.
+
+```javascript
+// e.g emphasize active circle
+const circleInterpolation = {
+ transform: [
+ {
+ scale: {
+ inputRange: [-2, -1, 0, 1, 2],
+ outputRange: [0.5, 0.5, 0.8, 0.5, 0.5],
+ },
+ },
+ ],
+};
+
+// e.g - position circles vertically
+
+
+
+
+;
+```
+
+```javascript
+
+```
+
+```javascript
+
+```
diff --git a/docs/assets/paginated-tabs.gif b/docs/assets/paginated-tabs.gif
new file mode 100644
index 0000000..e40e328
Binary files /dev/null and b/docs/assets/paginated-tabs.gif differ
diff --git a/example/App.tsx b/example/App.tsx
index 61ea086..66522de 100644
--- a/example/App.tsx
+++ b/example/App.tsx
@@ -70,10 +70,7 @@ const App = () => {
return (
-
- {children}
-
-
+ {children}
);
diff --git a/example/tabs-stack.tsx b/example/tabs-stack.tsx
index 31ddc59..db28106 100644
--- a/example/tabs-stack.tsx
+++ b/example/tabs-stack.tsx
@@ -1,6 +1,17 @@
import React, {useState} from 'react';
-import {StyleSheet, TouchableOpacity, View, Text} from 'react-native';
-import {Pager, Pagination, Slider} from '@crowdlinker/react-native-pager';
+import {
+ StyleSheet,
+ TouchableOpacity,
+ View,
+ Text,
+ ViewStyle,
+} from 'react-native';
+import {
+ Pager,
+ Pagination,
+ Slider,
+ Progress,
+} from '@crowdlinker/react-native-pager';
import Animated from 'react-native-reanimated';
const {Value, multiply} = Animated;
@@ -63,7 +74,36 @@ function Stack({children}) {
);
}
-const animatedIndex = new Value(0);
+const circleInterpolation = {
+ transform: [
+ {
+ scale: {
+ inputRange: [-2, -1, 0, 1, 2],
+ outputRange: [0.5, 0.5, 0.8, 0.5, 0.5],
+ },
+ },
+ ],
+};
+
+function Circles({children, onChange}) {
+ return (
+
+ {React.Children.map(children, (_, i) => (
+
+ ))}
+
+ );
+}
+
+const circlesContainer: ViewStyle = {
+ height: 20,
+ width: '70%',
+ alignSelf: 'center',
+ transform: [{translateY: -30}],
+};
function Circle({i, onPress}) {
return (
@@ -86,80 +126,67 @@ function Circle({i, onPress}) {
);
}
-const circleInterpolation = {
- transform: [
- {
- scale: {
- inputRange: [-2, -1, 0, 1, 2],
- outputRange: [0.5, 0.5, 0.8, 0.5, 0.5],
- },
- },
- ],
-};
+function Tabbar({children, onChange, activeIndex}) {
+ return (
+
+ {React.Children.map(children, (c, i) => (
+ onChange(i)}
+ style={{
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ }}>
+
+ {i}
+
+
+ ))}
+
+ );
+}
-function Tabs({
- children,
- activeIndex: parentActiveIndex,
- onChange: parentOnChange,
- ...rest
-}) {
- const [_activeIndex, _onChange] = useState(0);
+const animatedIndex = new Value(0);
- const activeIndex =
- parentActiveIndex !== undefined ? parentActiveIndex : _activeIndex;
- const onChange = parentActiveIndex !== undefined ? parentOnChange : _onChange;
+function Tabs({children}) {
+ const [activeIndex, onChange] = useState(0);
+ const activeColor = colors[activeIndex % colors.length];
return (
-
+
+ onChange={onChange}>
{children}
-
+
+ {children}
+
+
+
+
);
}
diff --git a/src/pager.tsx b/src/pager.tsx
index 717f064..98c8b63 100644
--- a/src/pager.tsx
+++ b/src/pager.tsx
@@ -84,8 +84,6 @@ const {
abs,
lessThan,
ceil,
- interpolate,
- concat,
// @ts-ignore
debug,
} = Animated;
diff --git a/src/pagination.tsx b/src/pagination.tsx
index 80b8b1a..25e24c5 100644
--- a/src/pagination.tsx
+++ b/src/pagination.tsx
@@ -4,11 +4,11 @@ import { ViewStyle, LayoutChangeEvent } from 'react-native';
import { iPageInterpolation } from './pager';
import { memoize, mapConfigToStyle } from './util';
-const { sub, Value, divide, multiply } = Animated;
+const { sub, Value, divide, multiply, add } = Animated;
interface iPagination {
children: React.ReactNode;
- animatedIndex: Animated.Node;
+ animatedIndex: Animated.Value;
pageInterpolation: iPageInterpolation;
style?: ViewStyle;
}
@@ -48,7 +48,7 @@ function Pagination({
interface iPaginationItem {
children: React.ReactNode;
- animatedIndex: Animated.Node;
+ animatedIndex: Animated.Value;
pageInterpolation: iPageInterpolation;
index: number;
style?: ViewStyle;
@@ -73,10 +73,15 @@ function PaginationItem({
interface iSlider {
numberOfScreens: number;
- animatedIndex: Animated.Node;
+ animatedIndex: Animated.Value;
style: ViewStyle;
}
+const DEFAULT_SLIDER_STYLE = {
+ height: 2,
+ backgroundColor: 'aquamarine',
+};
+
function Slider({ numberOfScreens, animatedIndex, style }: iSlider) {
const width = memoize(new Value(0));
@@ -93,6 +98,35 @@ function Slider({ numberOfScreens, animatedIndex, style }: iSlider) {
style={{
width: sliderWidth,
transform: [{ translateX: translation }],
+ ...DEFAULT_SLIDER_STYLE,
+ ...style,
+ }}
+ />
+
+ );
+}
+
+function Progress({ numberOfScreens, animatedIndex, style }: iSlider) {
+ const width = memoize(new Value(0));
+
+ function handleLayout({ nativeEvent: { layout } }: LayoutChangeEvent) {
+ width.setValue(layout.width as any);
+ }
+
+ const sliderWidth = divide(
+ width,
+ numberOfScreens,
+ divide(1, add(animatedIndex, 1))
+ );
+
+ return (
+
+
@@ -100,4 +134,4 @@ function Slider({ numberOfScreens, animatedIndex, style }: iSlider) {
);
}
-export { Pagination, Slider };
+export { Pagination, Slider, Progress };