import { ScrollView, View, Dimensions, Text, TouchableOpacity, Animated, TextStyle, StyleProp, ViewStyle, NativeSyntheticEvent, NativeScrollEvent } from 'react-native'; import React, { ReactNode, useEffect, useRef, useState } from 'react'; interface SwiperCumCarouselProps { renderTitle?: string, titleStyle?: TextStyle, indexStyle?: TextStyle, buttonLeftText?: string, buttonRightText?: string, buttonLeftStyle?: StyleProp, buttonRightStyle?: StyleProp, renderNextButtonOnly?: boolean, pagingNavigation?: boolean, autoPlay?: boolean, autoPlayDuration?: number, buttonStyle?: StyleProp | TextStyle, buttonGroupStyle?: StyleProp, w?: number, loop?: boolean, animate?: "faded" | null, items?: number, buttonTextStyle?: TextStyle, showsIndex?: boolean, children: [ReactNode, ReactNode, ...ReactNode[]], showsScrollBar?: boolean, showsPagination?: boolean, showsButtons?: boolean, style?: StyleProp, pagingEnabled?: boolean, disablePrevButton?: boolean, disableNextButton?: boolean, } interface FadeAnimatedComponentProps { item: ReactNode, selected?: boolean, index?: number, ScreenWidth?: number, style?: StyleProp } const FadeAnimatedComponent = ({ item, selected, index, ScreenWidth, style }: FadeAnimatedComponentProps) => { const fadeAnim = useRef(new Animated.Value(0)).current; const fadeIn = () => { Animated.timing(fadeAnim, { toValue: 1, duration: 1000, useNativeDriver: true }).start(); }; const fadeOut = () => { Animated.timing(fadeAnim, { toValue: 0, duration: 1000, useNativeDriver: true }).start(); }; useEffect(() => { if (selected) { fadeIn(); } else if (!selected) fadeOut(); }, [selected]); return ( {item} ); }; const SwiperCumCarousel = (props: SwiperCumCarouselProps) => { const { renderTitle, titleStyle, indexStyle, buttonLeftText, buttonRightText, buttonLeftStyle, buttonRightStyle, renderNextButtonOnly, pagingNavigation, autoPlay, autoPlayDuration, buttonStyle, buttonGroupStyle, w, loop, animate, items, buttonTextStyle, showsIndex, children, showsScrollBar, showsPagination, showsButtons, style, pagingEnabled = true, disablePrevButton, disableNextButton } = props; const ScreenWidth = w ? w : Dimensions.get('window').width; const size = Math.ceil(children.length / (items ? items : 1)); const scroll = React.useRef(null); const [currentIndex, setIndex] = useState(1); const debounce = (func: () => void, timeout = 50) => { let timer: ReturnType; return (...args: any[]) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args as any); }, timeout); }; }; const f1 = () => { if (currentIndex < size) { scroll.current?.scrollTo({ x: currentIndex * ScreenWidth, animated: animate !== 'faded' }); } else if (currentIndex === size) { scroll.current?.scrollTo({ x: 0, animated: animate !== 'faded' }); } }; const autoPlayFunc = debounce(f1, autoPlayDuration || 2000); useEffect(() => { if (autoPlay) { autoPlayFunc(); } }, [currentIndex, autoPlay, autoPlayFunc]); const ScrollEvent = (event: NativeSyntheticEvent) => { const px = event && event.nativeEvent && event.nativeEvent.contentOffset; setIndex(Math.round(px.x / ScreenWidth + 1)); }; const clickHandler = (num: number) => { currentIndex >= 1 && currentIndex <= size ? num == 1 && currentIndex < size ? scroll.current?.scrollTo({ x: currentIndex * ScreenWidth, animated: animate == 'faded' ? false : true }) : num == -1 && currentIndex > 1 ? scroll.current?.scrollTo({ x: ScreenWidth * (currentIndex - 2), animated: animate == 'faded' ? false : true }) : null : null; loop ? num == 1 && currentIndex == size ? scroll.current?.scrollTo({ x: 0, animated: animate == 'faded' ? false : true }) : num == -1 && currentIndex == 1 ? scroll.current?.scrollTo({ x: (size - 1) * ScreenWidth, animated: animate == 'faded' ? false : true }) : null : null; }; const paginationScroll = (index: number) => { console.log(index); console.log(currentIndex); // pagingNavigation && scroll.current?.scrollTo({ x: index * ScreenWidth, animated: true }); }; return ( {renderTitle && ( {' '} {renderTitle} {' '} )} { showsIndex && ( {currentIndex} / {size} ) } { children.map((item, i) => { return animate == 'faded' ? ( ) : ( {item} ); })} {showsPagination && ( {new Array(size).fill("").map((_, index) => { return ( paginationScroll(index) } style={{ width: 10, height: 10, borderRadius: 5, backgroundColor: '#030104' }} /> ); })} )} { showsButtons && ( {!renderNextButtonOnly ? ( clickHandler(-1)} style={[{ alignSelf: 'center', backgroundColor: 'red', padding: 15, borderRadius: 10, opacity: !loop && (disablePrevButton || currentIndex == 1) ? 0.4 : 1, }, buttonStyle, buttonLeftStyle ]} activeOpacity={0.6} > {buttonLeftText ? buttonLeftText : 'BACK'} ) : null} clickHandler(+1)} style={[{ alignSelf: 'center', backgroundColor: 'red', padding: 15, borderRadius: 10, opacity: !loop && (disableNextButton || currentIndex == size) ? 0.4 : 1, }, buttonStyle, buttonRightStyle]} activeOpacity={0.6} disabled={ !loop && (disableNextButton || currentIndex == size) ? true : false } > {buttonRightText ? buttonRightText : 'NEXT'} )} ); }; export default SwiperCumCarousel;