β¨ Context-Based Configuration - All carousel settings are configured through the context provider for a clean, centralized API.
β¨ Auto-scrolling with customizable intervals
π Infinite scrolling with seamless transitions
π¬ Video support with play/pause controls
β±οΈ Timer-based pagination with visual progress indicators
π― Advanced animations using React Native Reanimated
π± Gesture-friendly with swipe navigation
π¨ Highly customizable with interpolation utilities
β‘ Performance optimized with worklet functions
npm install @strv/react-native-hero-carousel
# or
yarn add @strv/react-native-hero-carousel
# or
yarn add @strv/react-native-hero-carousel
This library requires the following peer dependencies:
npm install react-native-reanimated react-native-gesture-handler
Make sure to follow the React Native Reanimated installation guide for your platform.
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'
import { HeroCarousel, CarouselContextProvider } from '@strv/react-native-hero-carousel'
const slides = [
{ id: 1, title: 'Slide 1', color: '#FF6B6B' },
{ id: 2, title: 'Slide 2', color: '#4ECDC4' },
{ id: 3, title: 'Slide 3', color: '#45B7D1' },
{ id: 4, title: 'Slide 4', color: '#96CEB4' },
]
const Slide = ({ title, color }: { title: string; color: string }) => (
<View style={[styles.slide, { backgroundColor: color }]}>
<Text style={styles.title}>{title}</Text>
</View>
)
export default function BasicCarousel() {
return (
<CarouselContextProvider interval={4000} disableAutoScroll={false} initialIndex={0}>
<View style={styles.container}>
<HeroCarousel>
{slides.map((slide) => (
<Slide key={slide.id} title={slide.title} color={slide.color} />
))}
</HeroCarousel>
</View>
</CarouselContextProvider>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
slide: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
})
The context provider that must wrap your carousel components. All carousel configuration is passed here.
<CarouselContextProvider
initialIndex={0} // Initial slide index (default: 0)
slideWidth={screenWidth} // Width of each slide (default: screen width)
interval={3000} // Auto-scroll interval in ms
disableAutoScroll={false} // Disable auto-scrolling
disableInfiniteScroll={false} // Disable infinite scrolling
autoScrollAnimation={(to, duration) => withTiming(to, { duration })} // Custom animation
>
{children}
</CarouselContextProvider>
Props:
Prop | Type | Default | Description |
---|---|---|---|
initialIndex |
number |
0 |
Initial slide index to start from |
slideWidth |
number |
screen width | Width of each slide in pixels |
interval |
number | ((index: number) => number) |
3000 |
Auto-scroll interval in milliseconds, or function returning interval for each slide |
disableAutoScroll |
boolean |
false |
Disable automatic scrolling |
disableInfiniteScroll |
boolean |
false |
Disable infinite scrolling (shows first/last slide boundaries) |
autoScrollAnimation |
(to: number, duration: number) => number |
withTiming |
Custom animation function for auto-scroll transitions |
children |
React.ReactNode |
Required | Carousel content (should contain HeroCarousel component) |
The main carousel component that renders slides. Takes no configuration props - all configuration is handled by the context.
<HeroCarousel>
{slides.map((slide) => (
<YourSlideComponent key={slide.id} {...slide} />
))}
</HeroCarousel>
Props:
Prop | Type | Description |
---|---|---|
children |
React.ReactNode[] |
Array of slide components |
Access the carousel's shared state and controls.
const { scrollValue, timeoutValue, slideWidth, userInteracted, setUserInteracted } =
useCarouselContext()
Returns:
scrollValue
: Animated value representing current scroll positiontimeoutValue
: Animated value for timer progress (0-1)slideWidth
: Width of slidesuserInteracted
: Boolean indicating if user has interacted with carouselsetUserInteracted
: Function to update interaction state
Get the current slide information and auto-scroll controls.
const { index, total, runAutoScroll, goToPage } = useHeroCarouselSlideIndex()
Returns:
index
: Current slide indextotal
: Total number of slidesrunAutoScroll
: Function to manually trigger auto-scroll with custom intervalgoToPage
: Function to programmatically navigate to a specific slide from another slide
Advanced interpolation utility for creating custom slide animations.
import { interpolateInsideCarousel } from '@strv/react-native-hero-carousel'
const animatedStyle = useAnimatedStyle(() => {
const progress = interpolateInsideCarousel(scrollValue.value, slideIndex, total, {
valueBefore: 0, // Value for slides before current
thisValue: 1, // Value for current slide
valueAfter: 0, // Value for slides after current
offset: 0.2, // Animation offset (optional)
})
return {
opacity: progress,
transform: [{ scale: progress }],
}
})
We provide a comprehensive example app showcasing all the carousel features. You can run the examples locally or view the source code:
cd example
yarn install
yarn start
Then scan the QR code with Expo Go or run on simulator. See the example app README for detailed setup instructions.
Example | Description | Source Code |
---|---|---|
Basic Carousel | Simple auto-scrolling image carousel | BasicExample.tsx |
Animated Carousel | Custom animations with scale, rotation, and opacity | AnimatedExample.tsx |
Video Carousel | Video playback with play/pause controls | VideoCarouselExample.tsx |
Timer Pagination | Visual progress indicators with custom intervals | TimerPaginationExample.tsx |
Entering Animation | Advanced slide entrance animations | EnteringAnimationExample.tsx |
Offset Example | Custom slide positioning and spacing | OffsetExample.tsx |
- Image Carousels with smooth transitions and auto-scrolling
- Video Integration with
expo-video
and playback controls - Custom Animations using
interpolateInsideCarousel
utility - Timer-based Pagination with visual progress bars
- Gesture Handling with swipe navigation and user interaction detection
- Performance Optimization with image preloading and memoization
The library includes several pagination components and examples:
- Basic Pagination - Simple dot indicators showing current slide (
Pagination.tsx
) - Timer Pagination - Animated progress bars with customizable intervals (
TimerPagination.tsx
) - Custom Pagination - Build your own pagination using
useCarouselContext()
hook for access toscrollValue
andtimeoutValue
All pagination components automatically sync with the carousel state and support:
- β Real-time updates as slides change
- β Timer progress visualization with animated fill
- β User interaction detection (pause on touch)
- β Custom styling and animations
Different carousel configurations using the context provider:
// Basic auto-scrolling carousel
<CarouselContextProvider interval={3000}>
<HeroCarousel>{slides}</HeroCarousel>
</CarouselContextProvider>
// Video carousel without auto-scroll
<CarouselContextProvider disableAutoScroll>
<HeroCarousel>{videoSlides}</HeroCarousel>
</CarouselContextProvider>
// Carousel with custom intervals per slide
<CarouselContextProvider interval={(index) => (index + 1) * 2000}>
<HeroCarousel>{slides}</HeroCarousel>
</CarouselContextProvider>
// Carousel starting from specific slide
<CarouselContextProvider initialIndex={2} disableInfiniteScroll>
<HeroCarousel>{slides}</HeroCarousel>
</CarouselContextProvider>
// Custom slide width and animation
<CarouselContextProvider
slideWidth={300}
autoScrollAnimation={(to, duration) => withSpring(to, { damping: 15 })}
>
<HeroCarousel>{slides}</HeroCarousel>
</CarouselContextProvider>
Control the carousel programmatically using the context:
const CarouselWithControls = () => {
const { scrollValue, goToPage } = useCarouselContext()
const { runAutoScroll } = useHeroCarouselSlideIndex()
const goToNext = () => {
runAutoScroll(0) // Immediate transition
}
const goToSlide = (slideIndex: number) => {
goToPage(slideIndex, 500) // Go to slide with 500ms animation
}
return (
<CarouselContextProvider disableAutoScroll>
<View>
<HeroCarousel>{/* Your slides */}</HeroCarousel>
<View style={styles.controls}>
<Button title="Previous" onPress={() => goToSlide(scrollValue.value - 1)} />
<Button title="Next" onPress={goToNext} />
</View>
</View>
</CarouselContextProvider>
)
}
- Image Optimization: Use optimized image formats and appropriate resolutions
- Preloading: Preload images/videos for smoother transitions
- Memoization: Wrap slide components in
React.memo()
when possible - Worklet Functions: Keep animations in worklet functions for 60fps performance
// Good: Memoized slide component
const SlideComponent = React.memo(({ data }) => {
// Your slide content
})
// Good: Preload images
useEffect(() => {
images.forEach((uri) => Image.prefetch(uri))
}, [])
This library uses a context-based architecture where all carousel configuration is passed to the CarouselContextProvider
rather than individual components. This design provides several benefits:
β
Centralized Configuration - All settings in one place
β
Cleaner Component API - Components focus on rendering, not configuration
β
Easier Testing - Mock context for isolated component testing
That allows for components like pagination to not be attached to the carousel component.
Carousel not auto-scrolling:
- Ensure
CarouselContextProvider
wraps your carousel - Check if
disableAutoScroll
is set tofalse
- Verify React Native Reanimated is properly installed
Animations not smooth:
- Make sure animations are running in worklet functions
- Use
runOnUI
for heavy computations - Avoid heavy operations in animation callbacks
Infinite scroll not working:
- Ensure you have at least 2 slides
- Check if slide widths are properly configured
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
MIT License - see the LICENSE file for details.
Built with β€οΈ using:
- React Native Reanimated for animations
- React Native Gesture Handler for gestures
Made by STRV π