Skip to content

Commit 35ebe55

Browse files
author
Petr Konecny
committed
chore: updated docs
1 parent b95a7be commit 35ebe55

File tree

1 file changed

+154
-37
lines changed

1 file changed

+154
-37
lines changed

README.md

Lines changed: 154 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,42 @@ 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+
;<HeroCarousel.AnimatedView
171+
entering={FadeIn.duration(400)}
172+
exiting={FadeOut.duration(300)}
173+
style={styles.animatedContent}
174+
>
175+
<Text>This animates when the slide becomes active</Text>
176+
</HeroCarousel.AnimatedView>
177+
```
178+
179+
**Props:**
180+
181+
| Prop | Type | Default | Description |
182+
| ------------------------- | -------------------------------------- | -------- | -------------------------------------------------------- |
183+
| `children` | `React.ReactNode` | Required | Content to animate |
184+
| `entering` | `AnimatedProps<ViewProps>['entering']` | - | Entering animation (from react-native-reanimated) |
185+
| `exiting` | `AnimatedProps<ViewProps>['exiting']` | - | Exiting animation (from react-native-reanimated) |
186+
| `layout` | `AnimatedProps<ViewProps>['layout']` | - | Layout animation (from react-native-reanimated) |
187+
| `enteringThreshold` | `number` | `0.99` | Threshold (0-1) when entering animation should trigger |
188+
| `exitingThreshold` | `number` | `0.01` | Threshold (0-1) when exiting animation should trigger |
189+
| `keepVisibleAfterExiting` | `boolean` | `false` | Keep component visible after exiting animation completes |
190+
| `style` | `AnimatedProps<ViewProps>['style']` | - | Additional styles |
191+
145192
### Hooks
146193

147194
#### `useCarouselContext()`
@@ -161,12 +208,12 @@ const { scrollValue, timeoutValue, slideWidth, userInteracted, setUserInteracted
161208
- `userInteracted`: Boolean indicating if user has interacted with carousel
162209
- `setUserInteracted`: Function to update interaction state
163210

164-
#### `useHeroCarouselSlideIndex()`
211+
#### `useAutoCarouselSlideIndex()`
165212

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

168215
```tsx
169-
const { index, total, runAutoScroll, goToPage } = useHeroCarouselSlideIndex()
216+
const { index, total, runAutoScroll, goToPage } = useAutoCarouselSlideIndex()
170217
```
171218

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

217264
### 📱 Available Examples
218265

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) |
266+
| Example | Description | Source Code |
267+
| ---------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
268+
| **Basic Carousel** | Simple auto-scrolling image carousel | [`BasicExample.tsx`](./example/examples/BasicExample.tsx) |
269+
| **Animated Carousel** | Custom animations with scale, rotation, and opacity | [`AnimatedExample.tsx`](./example/examples/AnimatedExample.tsx) |
270+
| **Video Carousel** | Video playback with play/pause controls | [`VideoCarouselExample.tsx`](./example/examples/VideoCarouselExample.tsx) |
271+
| **Timer Pagination** | Visual progress indicators with custom intervals | [`TimerPaginationExample.tsx`](./example/examples/TimerPaginationExample.tsx) |
272+
| **Entering Animation** | Advanced slide entrance animations using `HeroCarousel.AnimatedView` | [`EnteringAnimationExample.tsx`](./example/examples/EnteringAnimationExample.tsx) |
273+
| **Offset Example** | Custom slide positioning and spacing | [`OffsetExample.tsx`](./example/examples/OffsetExample.tsx) |
227274

228275
### 🎯 Key Example Features
229276

230277
- **Image Carousels** with smooth transitions and auto-scrolling
231278
- **Video Integration** with `expo-video` and playback controls
232279
- **Custom Animations** using `interpolateInsideCarousel` utility
280+
- **Entering/Exiting Animations** using `HeroCarousel.AnimatedView` component
233281
- **Timer-based Pagination** with visual progress bars
234282
- **Gesture Handling** with swipe navigation and user interaction detection
235283
- **Performance Optimization** with image preloading and memoization
284+
- **Compound Pattern** - All examples use `HeroCarousel.Provider` for configuration
236285

237286
### 📍 Pagination Examples
238287

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

254303
### Configuration Examples
255304

256-
Different carousel configurations using the context provider:
305+
Different carousel configurations using the compound pattern:
257306

258307
```tsx
259308
// Basic auto-scrolling carousel
260-
<CarouselContextProvider interval={3000}>
309+
<HeroCarousel.Provider interval={3000}>
261310
<HeroCarousel>{slides}</HeroCarousel>
262-
</CarouselContextProvider>
311+
</HeroCarousel.Provider>
263312

264313
// Video carousel without auto-scroll
265-
<CarouselContextProvider disableAutoScroll>
314+
<HeroCarousel.Provider disableAutoScroll>
266315
<HeroCarousel>{videoSlides}</HeroCarousel>
267-
</CarouselContextProvider>
316+
</HeroCarousel.Provider>
268317

269318
// Carousel with custom intervals per slide
270-
<CarouselContextProvider interval={(index) => (index + 1) * 2000}>
319+
<HeroCarousel.Provider interval={(index) => (index + 1) * 2000}>
271320
<HeroCarousel>{slides}</HeroCarousel>
272-
</CarouselContextProvider>
321+
</HeroCarousel.Provider>
273322

274323
// Carousel starting from specific slide
275-
<CarouselContextProvider initialIndex={2} disableInfiniteScroll>
324+
<HeroCarousel.Provider initialIndex={2} disableInfiniteScroll>
276325
<HeroCarousel>{slides}</HeroCarousel>
277-
</CarouselContextProvider>
326+
</HeroCarousel.Provider>
278327

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

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

290388
Control the carousel programmatically using the context:
291389

292390
```tsx
293391
const CarouselWithControls = () => {
294392
const { scrollValue, goToPage } = useCarouselContext()
295-
const { runAutoScroll } = useHeroCarouselSlideIndex()
393+
const { runAutoScroll } = useAutoCarouselSlideIndex()
296394

297395
const goToNext = () => {
298396
runAutoScroll(0) // Immediate transition
@@ -303,7 +401,7 @@ const CarouselWithControls = () => {
303401
}
304402

305403
return (
306-
<CarouselContextProvider disableAutoScroll>
404+
<HeroCarousel.Provider disableAutoScroll>
307405
<View>
308406
<HeroCarousel>{/* Your slides */}</HeroCarousel>
309407

@@ -312,7 +410,7 @@ const CarouselWithControls = () => {
312410
<Button title="Next" onPress={goToNext} />
313411
</View>
314412
</View>
315-
</CarouselContextProvider>
413+
</HeroCarousel.Provider>
316414
)
317415
}
318416
```
@@ -338,23 +436,42 @@ useEffect(() => {
338436

339437
## Architecture
340438

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

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

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

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

351468
## Troubleshooting
352469

353470
### Common Issues
354471

355472
**Carousel not auto-scrolling:**
356473

357-
- Ensure `CarouselContextProvider` wraps your carousel
474+
- Ensure `HeroCarousel.Provider` wraps your carousel
358475
- Check if `disableAutoScroll` is set to `false`
359476
- Verify React Native Reanimated is properly installed
360477

0 commit comments

Comments
 (0)