/** * Horizontal image carousel with parallax and dot pagination. * * @example * ( * * * * )} * /> */ import { memo, useCallback, useState, type ReactElement } from 'react'; import { Container } from '@cleartrip/ct-design-container'; import { useStyles } from '@cleartrip/ct-design-style-manager'; import RNACarousel from 'react-native-reanimated-carousel'; import Pagination from './Pagination'; import { PARALLAX_WINDOW_SIZE } from './constants'; import { useEdgePanGesture } from './hooks/useEdgePanGesture'; import { useParallaxSliderCarouselState } from './hooks/useParallaxSliderCarouselState'; import { staticStyles } from './style'; import { IParallaxSliderProps, TParallaxRenderItemInfo } from './type'; const ParallaxSliderInner = ({ data, slideWidth, wrapperHeight, renderItem, startIndex = 0, showDots = true, maxDotsToShow = data.length, styleConfig, customIcon, customIconIndex, onSlide, testID, }: IParallaxSliderProps) => { const [currentIndex, setCurrentIndex] = useState(startIndex); const { activeIndex, touchStartX } = useParallaxSliderCarouselState(startIndex); const maxIndex = data.length - 1; const { root: rootStyles = [] } = styleConfig || {}; const dynamicStyles = useStyles( () => ({ clip: { width: slideWidth, height: wrapperHeight, overflow: 'hidden', }, }), [slideWidth, wrapperHeight], ); const handleSnapToItem = useCallback( (index: number) => { activeIndex.value = index; setCurrentIndex(index); onSlide?.(index); }, [activeIndex, onSlide], ); // animationValue is driven by the carousel (0 = centered, ±1 = mid-swipe to next/prev slide) const handleConfigurePanGesture = useEdgePanGesture({ activeIndex, maxIndex, touchStartX }); const renderCarouselItem = useCallback( (renderInfo: TParallaxRenderItemInfo) => ( {renderItem(renderInfo)} ), [dynamicStyles.clip, renderItem], ); return ( <> ); }; const ParallaxSlider = memo(ParallaxSliderInner) as (props: IParallaxSliderProps) => ReactElement | null; export default ParallaxSlider;