-
-
Save CS6/bb6f0e9aeec99f4a6e91dbba4e948fdc to your computer and use it in GitHub Desktop.
Pagination component for use with react-native-snap-carousel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { StyleSheet } from 'react-native' | |
import Animated, { | |
Extrapolate, | |
interpolate, | |
useAnimatedStyle | |
} from 'react-native-reanimated' | |
import { colors, metrics } from 'styles'; | |
function clamp(value, lowerBound, upperBound) { | |
'worklet' | |
return Math.min(Math.max(lowerBound, value), upperBound); | |
}; | |
const DEFAULT_SIZE = 15 | |
function AnimatedDot({ | |
index, | |
style, | |
progress, | |
multiplier, | |
scaleDots | |
}) { | |
const animatedStyles = useAnimatedStyle(() => { | |
const opacity = interpolate( | |
clamp(progress.value, 0, 1 - multiplier), | |
[ | |
(index * multiplier) - multiplier, | |
index * multiplier, | |
(index * multiplier) + multiplier | |
], | |
[0.25, 1, 0.25], | |
Extrapolate.CLAMP | |
) | |
return { | |
opacity, | |
transform: [ | |
{ | |
scale: scaleDots | |
? interpolate( | |
opacity, | |
[0.25, 1], | |
[0.5, 1] | |
) | |
: 1 | |
} | |
] | |
} | |
}) | |
return ( | |
<Animated.View | |
key={`onboarding-pagination-dot-${index}`} | |
style={[style, animatedStyles]} | |
/> | |
) | |
} | |
export function Pagination({ | |
progress, | |
numberOfPages, | |
scaleDots = false, | |
dotStyles = {}, | |
containerStyles = {}, | |
size = 'medium' | |
}) { | |
const multiplier = 1 / numberOfPages | |
function returnSize() { | |
switch (size) { | |
case 'small': | |
return { | |
width: DEFAULT_SIZE * 0.6, | |
height: DEFAULT_SIZE * 0.6, | |
} | |
case 'large': | |
return { | |
width: DEFAULT_SIZE * 1.2, | |
height: DEFAULT_SIZE * 1.2, | |
} | |
default: | |
return { | |
width: DEFAULT_SIZE, | |
height: DEFAULT_SIZE, | |
} | |
} | |
} | |
function renderDots() { | |
let dots = [] | |
for (let i = 0; i < numberOfPages; i++) { | |
dots.push( | |
<AnimatedDot | |
key={`pagination-${i}`} | |
index={i} | |
scaleDots={scaleDots} | |
multiplier={multiplier} | |
progress={progress} | |
size={size} | |
style={[ | |
styles.dotStyle, | |
dotStyles, | |
returnSize() | |
]} | |
/> | |
) | |
} | |
return dots | |
} | |
return ( | |
<View style={[ | |
styles.dotContainer, | |
containerStyles, | |
]}> | |
{renderDots()} | |
</View> | |
) | |
} | |
const styles = StyleSheet.create({ | |
dotContainer: { | |
flex: 1, | |
paddingHorizontal: metrics.padding, | |
flexDirection: 'row', | |
alignSelf: 'center' | |
}, | |
dotStyle: { | |
width: DEFAULT_SIZE, | |
height: DEFAULT_SIZE, | |
borderRadius: 50, | |
marginHorizontal: 5, | |
backgroundColor: colors.white, | |
}, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment