Skip to content

Commit 6c0e383

Browse files
author
Petr Konecny
committed
chore: updated docs
1 parent b95a7be commit 6c0e383

File tree

1 file changed

+155
-37
lines changed

1 file changed

+155
-37
lines changed

README.md

Lines changed: 155 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
</div>
88
A highly customizable, performant carousel component for React Native with advanced animations, auto-scrolling capabilities, and infinite scrolling support. Built with React Native Reanimated for smooth, native-level performance.
99

10-
**✨ Context-Based Configuration** - All carousel settings are configured through the context provider for a clean, centralized API.
10+
**✨ Compound Pattern** - Clean, intuitive API with `HeroCarousel.Provider`, `HeroCarousel.Item`, and `HeroCarousel.AnimatedView`
11+
**✨ Context-Based Configuration** - All carousel settings are configured through the provider for a clean, centralized API.
1112

1213
## Features
1314

@@ -45,7 +46,7 @@ Make sure to follow the [React Native Reanimated installation guide](https://doc
4546
```tsx
4647
import React from 'react'
4748
import { View, Text, StyleSheet } from 'react-native'
48-
import { HeroCarousel, CarouselContextProvider } from '@strv/react-native-hero-carousel'
49+
import { HeroCarousel } from '@strv/react-native-hero-carousel'
4950

5051
const slides = [
5152
{ id: 1, title: 'Slide 1', color: '#FF6B6B' },
@@ -62,15 +63,15 @@ const Slide = ({ title, color }: { title: string; color: string }) => (
6263

6364
export default function BasicCarousel() {
6465
return (
65-
<CarouselContextProvider interval={4000} disableAutoScroll={false} initialIndex={0}>
66+
<HeroCarousel.Provider interval={4000} disableAutoScroll={false} initialIndex={0}>
6667
<View style={styles.container}>
6768
<HeroCarousel>
6869
{slides.map((slide) => (
6970
<Slide key={slide.id} title={slide.title} color={slide.color} />
7071
))}
7172
</HeroCarousel>
7273
</View>
73-
</CarouselContextProvider>
74+
</HeroCarousel.Provider>
7475
)
7576
}
7677

@@ -95,12 +96,22 @@ const styles = StyleSheet.create({
9596

9697
### Components
9798

98-
#### `CarouselContextProvider`
99+
The `HeroCarousel` component uses a **compound pattern** that provides a clean, intuitive API:
100+
101+
```tsx
102+
<HeroCarousel.Provider>
103+
<HeroCarousel>
104+
<HeroCarousel.Item>{/* Your slide content */}</HeroCarousel.Item>
105+
</HeroCarousel>
106+
</HeroCarousel.Provider>
107+
```
108+
109+
#### `HeroCarousel.Provider`
99110

100111
The context provider that must wrap your carousel components. **All carousel configuration is passed here.**
101112

102113
```tsx
103-
<CarouselContextProvider
114+
<HeroCarousel.Provider
104115
initialIndex={0} // Initial slide index (default: 0)
105116
slideWidth={screenWidth} // Width of each slide (default: screen width)
106117
interval={3000} // Auto-scroll interval in ms
@@ -109,7 +120,7 @@ The context provider that must wrap your carousel components. **All carousel con
109120
autoScrollAnimation={(to, duration) => withTiming(to, { duration })} // Custom animation
110121
>
111122
{children}
112-
</CarouselContextProvider>
123+
</HeroCarousel.Provider>
113124
```
114125

115126
**Props:**
@@ -126,7 +137,7 @@ The context provider that must wrap your carousel components. **All carousel con
126137

127138
#### `HeroCarousel`
128139

129-
The main carousel component that renders slides. **Takes no configuration props** - all configuration is handled by the context.
140+
The main carousel component that renders slides. **Takes no configuration props** - all configuration is handled by the context provider.
130141

131142
```tsx
132143
<HeroCarousel>
@@ -142,6 +153,43 @@ The main carousel component that renders slides. **Takes no configuration props*
142153
| ---------- | ------------------- | ------------------------- |
143154
| `children` | `React.ReactNode[]` | Array of slide components |
144155

156+
#### `HeroCarousel.Item`
157+
158+
A wrapper component for individual slides. Provides slide context to child components. **Note:** This is automatically used internally when you pass children to `HeroCarousel`, but you can use it directly for more control.
159+
160+
```tsx
161+
<HeroCarousel.Item>{/* Your slide content */}</HeroCarousel.Item>
162+
```
163+
164+
#### `HeroCarousel.AnimatedView`
165+
166+
A specialized animated view component that automatically handles entering/exiting animations based on carousel scroll position. Perfect for creating slide-specific animations.
167+
168+
```tsx
169+
import { FadeIn, FadeOut } from 'react-native-reanimated'
170+
171+
;<HeroCarousel.AnimatedView
172+
entering={FadeIn.duration(400)}
173+
exiting={FadeOut.duration(300)}
174+
style={styles.animatedContent}
175+
>
176+
<Text>This animates when the slide becomes active</Text>
177+
</HeroCarousel.AnimatedView>
178+
```
179+
180+
**Props:**
181+
182+
| Prop | Type | Default | Description |
183+
| ------------------------- | -------------------------------------- | -------- | -------------------------------------------------------- |
184+
| `children` | `React.ReactNode` | Required | Content to animate |
185+
| `entering` | `AnimatedProps<ViewProps>['entering']` | - | Entering animation (from react-native-reanimated) |
186+
| `exiting` | `AnimatedProps<ViewProps>['exiting']` | - | Exiting animation (from react-native-reanimated) |
187+
| `layout` | `AnimatedProps<ViewProps>['layout']` | - | Layout animation (from react-native-reanimated) |
188+
| `enteringThreshold` | `number` | `0.99` | Threshold (0-1) when entering animation should trigger |
189+
| `exitingThreshold` | `number` | `0.01` | Threshold (0-1) when exiting animation should trigger |
190+
| `keepVisibleAfterExiting` | `boolean` | `false` | Keep component visible after exiting animation completes |
191+
| `style` | `AnimatedProps<ViewProps>['style']` | - | Additional styles |
192+
145193
### Hooks
146194

147195
#### `useCarouselContext()`
@@ -161,12 +209,12 @@ const { scrollValue, timeoutValue, slideWidth, userInteracted, setUserInteracted
161209
- `userInteracted`: Boolean indicating if user has interacted with carousel
162210
- `setUserInteracted`: Function to update interaction state
163211

164-
#### `useHeroCarouselSlideIndex()`
212+
#### `useAutoCarouselSlideIndex()`
165213

166-
Get the current slide information and auto-scroll controls.
214+
Get the current slide information and auto-scroll controls. Must be used within a slide component (inside `HeroCarousel`).
167215

168216
```tsx
169-
const { index, total, runAutoScroll, goToPage } = useHeroCarouselSlideIndex()
217+
const { index, total, runAutoScroll, goToPage } = useAutoCarouselSlideIndex()
170218
```
171219

172220
**Returns:**
@@ -216,23 +264,25 @@ Then scan the QR code with Expo Go or run on simulator. See the [example app REA
216264

217265
### 📱 Available Examples
218266

219-
| Example | Description | Source Code |
220-
| ---------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------- |
221-
| **Basic Carousel** | Simple auto-scrolling image carousel | [`BasicExample.tsx`](./example/examples/BasicExample.tsx) |
222-
| **Animated Carousel** | Custom animations with scale, rotation, and opacity | [`AnimatedExample.tsx`](./example/examples/AnimatedExample.tsx) |
223-
| **Video Carousel** | Video playback with play/pause controls | [`VideoCarouselExample.tsx`](./example/examples/VideoCarouselExample.tsx) |
224-
| **Timer Pagination** | Visual progress indicators with custom intervals | [`TimerPaginationExample.tsx`](./example/examples/TimerPaginationExample.tsx) |
225-
| **Entering Animation** | Advanced slide entrance animations | [`EnteringAnimationExample.tsx`](./example/examples/EnteringAnimationExample.tsx) |
226-
| **Offset Example** | Custom slide positioning and spacing | [`OffsetExample.tsx`](./example/examples/OffsetExample.tsx) |
267+
| Example | Description | Source Code |
268+
| ---------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
269+
| **Basic Carousel** | Simple auto-scrolling image carousel | [`BasicExample.tsx`](./example/examples/BasicExample.tsx) |
270+
| **Animated Carousel** | Custom animations with scale, rotation, and opacity | [`AnimatedExample.tsx`](./example/examples/AnimatedExample.tsx) |
271+
| **Video Carousel** | Video playback with play/pause controls | [`VideoCarouselExample.tsx`](./example/examples/VideoCarouselExample.tsx) |
272+
| **Timer Pagination** | Visual progress indicators with custom intervals | [`TimerPaginationExample.tsx`](./example/examples/TimerPaginationExample.tsx) |
273+
| **Entering Animation** | Advanced slide entrance animations using `HeroCarousel.AnimatedView` | [`EnteringAnimationExample.tsx`](./example/examples/EnteringAnimationExample.tsx) |
274+
| **Offset Example** | Custom slide positioning and spacing | [`OffsetExample.tsx`](./example/examples/OffsetExample.tsx) |
227275

228276
### 🎯 Key Example Features
229277

230278
- **Image Carousels** with smooth transitions and auto-scrolling
231279
- **Video Integration** with `expo-video` and playback controls
232280
- **Custom Animations** using `interpolateInsideCarousel` utility
281+
- **Entering/Exiting Animations** using `HeroCarousel.AnimatedView` component
233282
- **Timer-based Pagination** with visual progress bars
234283
- **Gesture Handling** with swipe navigation and user interaction detection
235284
- **Performance Optimization** with image preloading and memoization
285+
- **Compound Pattern** - All examples use `HeroCarousel.Provider` for configuration
236286

237287
### 📍 Pagination Examples
238288

@@ -253,46 +303,95 @@ All pagination components automatically sync with the carousel state and support
253303

254304
### Configuration Examples
255305

256-
Different carousel configurations using the context provider:
306+
Different carousel configurations using the compound pattern:
257307

258308
```tsx
259309
// Basic auto-scrolling carousel
260-
<CarouselContextProvider interval={3000}>
310+
<HeroCarousel.Provider interval={3000}>
261311
<HeroCarousel>{slides}</HeroCarousel>
262-
</CarouselContextProvider>
312+
</HeroCarousel.Provider>
263313

264314
// Video carousel without auto-scroll
265-
<CarouselContextProvider disableAutoScroll>
315+
<HeroCarousel.Provider disableAutoScroll>
266316
<HeroCarousel>{videoSlides}</HeroCarousel>
267-
</CarouselContextProvider>
317+
</HeroCarousel.Provider>
268318

269319
// Carousel with custom intervals per slide
270-
<CarouselContextProvider interval={(index) => (index + 1) * 2000}>
320+
<HeroCarousel.Provider interval={(index) => (index + 1) * 2000}>
271321
<HeroCarousel>{slides}</HeroCarousel>
272-
</CarouselContextProvider>
322+
</HeroCarousel.Provider>
273323

274324
// Carousel starting from specific slide
275-
<CarouselContextProvider initialIndex={2} disableInfiniteScroll>
325+
<HeroCarousel.Provider initialIndex={2} disableInfiniteScroll>
276326
<HeroCarousel>{slides}</HeroCarousel>
277-
</CarouselContextProvider>
327+
</HeroCarousel.Provider>
278328

279329
// Custom slide width and animation
280-
<CarouselContextProvider
330+
<HeroCarousel.Provider
281331
slideWidth={300}
282332
autoScrollAnimation={(to, duration) => withSpring(to, { damping: 15 })}
283333
>
284334
<HeroCarousel>{slides}</HeroCarousel>
285-
</CarouselContextProvider>
335+
</HeroCarousel.Provider>
336+
```
337+
338+
### Using HeroCarousel.AnimatedView
339+
340+
The `HeroCarousel.AnimatedView` component automatically handles entering/exiting animations based on carousel scroll position. Perfect for creating slide-specific animations:
341+
342+
```tsx
343+
import { HeroCarousel } from '@strv/react-native-hero-carousel'
344+
import { FadeIn, FadeOut, SlideInDown } from 'react-native-reanimated'
345+
346+
const Slide = ({ title, image }: { title: string; image: string }) => (
347+
<View style={styles.slide}>
348+
<Image source={{ uri: image }} style={styles.image} />
349+
350+
{/* Content that animates when slide becomes active */}
351+
<HeroCarousel.AnimatedView
352+
entering={FadeIn.duration(400)}
353+
exiting={FadeOut.duration(300)}
354+
style={styles.content}
355+
>
356+
<Text style={styles.title}>{title}</Text>
357+
</HeroCarousel.AnimatedView>
358+
359+
{/* Multiple animated views with different timings */}
360+
<HeroCarousel.AnimatedView
361+
entering={SlideInDown.duration(500).delay(200)}
362+
style={styles.subtitle}
363+
>
364+
<Text>Subtitle with delay</Text>
365+
</HeroCarousel.AnimatedView>
366+
</View>
367+
)
368+
369+
// Usage
370+
<HeroCarousel.Provider>
371+
<HeroCarousel>
372+
{slides.map((slide) => (
373+
<Slide key={slide.id} {...slide} />
374+
))}
375+
</HeroCarousel>
376+
</HeroCarousel.Provider>
286377
```
287378

379+
**Key Features:**
380+
381+
- Automatically triggers entering animation when slide becomes active
382+
- Triggers exiting animation when slide leaves view
383+
- Supports all Reanimated entering/exiting animations
384+
- Configurable thresholds for animation timing
385+
- Can keep content visible after exiting animation
386+
288387
### Programmatic Navigation
289388

290389
Control the carousel programmatically using the context:
291390

292391
```tsx
293392
const CarouselWithControls = () => {
294393
const { scrollValue, goToPage } = useCarouselContext()
295-
const { runAutoScroll } = useHeroCarouselSlideIndex()
394+
const { runAutoScroll } = useAutoCarouselSlideIndex()
296395

297396
const goToNext = () => {
298397
runAutoScroll(0) // Immediate transition
@@ -303,7 +402,7 @@ const CarouselWithControls = () => {
303402
}
304403

305404
return (
306-
<CarouselContextProvider disableAutoScroll>
405+
<HeroCarousel.Provider disableAutoScroll>
307406
<View>
308407
<HeroCarousel>{/* Your slides */}</HeroCarousel>
309408

@@ -312,7 +411,7 @@ const CarouselWithControls = () => {
312411
<Button title="Next" onPress={goToNext} />
313412
</View>
314413
</View>
315-
</CarouselContextProvider>
414+
</HeroCarousel.Provider>
316415
)
317416
}
318417
```
@@ -338,23 +437,42 @@ useEffect(() => {
338437

339438
## Architecture
340439

440+
### Compound Pattern
441+
442+
This library uses a **compound component pattern** that provides a clean, intuitive API:
443+
444+
```tsx
445+
<HeroCarousel.Provider>
446+
<HeroCarousel>
447+
<HeroCarousel.Item>
448+
<HeroCarousel.AnimatedView>{/* Your content */}</HeroCarousel.AnimatedView>
449+
</HeroCarousel.Item>
450+
</HeroCarousel>
451+
</HeroCarousel.Provider>
452+
```
453+
341454
### Context-Based Configuration
342455

343-
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:
456+
All carousel configuration is passed to the `HeroCarousel.Provider` rather than individual components. This design provides several benefits:
344457

345458
**Centralized Configuration** - All settings in one place
346459
**Cleaner Component API** - Components focus on rendering, not configuration
347-
**Easier Testing** - Mock context for isolated component testing
460+
**Easier Testing** - Mock context for isolated component testing
461+
**Flexible Composition** - Components like pagination can be placed anywhere within the provider
462+
463+
The compound pattern allows for:
348464

349-
That allows for components like pagination to not be attached to the carousel component.
465+
- **Intuitive API** - Related components are grouped under `HeroCarousel.*`
466+
- **Better Discoverability** - All carousel-related components are accessible via autocomplete
467+
- **Flexible Usage** - Use `HeroCarousel.Item` and `HeroCarousel.AnimatedView` when needed, or pass children directly to `HeroCarousel`
350468

351469
## Troubleshooting
352470

353471
### Common Issues
354472

355473
**Carousel not auto-scrolling:**
356474

357-
- Ensure `CarouselContextProvider` wraps your carousel
475+
- Ensure `HeroCarousel.Provider` wraps your carousel
358476
- Check if `disableAutoScroll` is set to `false`
359477
- Verify React Native Reanimated is properly installed
360478

0 commit comments

Comments
 (0)