diff --git a/README.md b/README.md
index a3ad33f..ff151da 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,7 @@ The context provider that must wrap your carousel components. **All carousel con
| `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 |
| `renderWindow` | `number` | all slides | Slides kept mounted on each side of the current one; for long carousels |
+| `centerSlide` | `boolean` | `false` | Centre the current slide when `slideWidth` is narrower, so neighbours peek in |
| `children` | `React.ReactNode` | Required | Carousel content (should contain HeroCarousel component) |
#### `HeroCarousel`
@@ -355,6 +356,18 @@ Different carousel configurations using the compound pattern:
>
{slides}
+
+// Centred slides with the neighbours peeking in on both sides.
+// Put the gap between slides inside each slide (half on each side), so the content stays centred.
+
+
+ {slides.map((slide) => (
+
+
+
+ ))}
+
+
```
### Using HeroCarousel.AnimatedView
diff --git a/src/components/AnimatedPagedView/index.tsx b/src/components/AnimatedPagedView/index.tsx
index ebcf824..bcd9a5e 100644
--- a/src/components/AnimatedPagedView/index.tsx
+++ b/src/components/AnimatedPagedView/index.tsx
@@ -29,7 +29,10 @@ export const AnimatedPagedView = forwardRef {
const translateX = useSharedValue(0)
const context = useSharedValue({ x: 0 })
- const { slideWidth } = useCarouselContext()
+ const { slideWidth, centerSlide } = useCarouselContext()
+ // Starts the row at the carousel's middle, less half a slide. Layout resolves the 50% against the
+ // carousel's own width, so the current slide is centred from the first frame.
+ const centerStyle = centerSlide ? { left: '50%' as const, marginLeft: -slideWidth / 2 } : null
const childrenArray = React.Children.toArray(props.children)
// Worklets must not capture `props`: it holds React elements, which can't be copied to the UI thread.
const { onScroll, onScrollBeginDrag } = props
@@ -70,7 +73,7 @@ export const AnimatedPagedView = forwardRef translateX.value,
@@ -93,8 +96,8 @@ export const AnimatedPagedView = forwardRef
-
-
+
+
{props.children}
diff --git a/src/components/index.ts b/src/components/index.ts
index be36b76..59284a0 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -1 +1 @@
-export { HeroCarousel, HeroCarouselProps } from './HeroCarousel'
+export { HeroCarousel, type HeroCarouselProps } from './HeroCarousel'
diff --git a/src/context/CarouselContext/index.tsx b/src/context/CarouselContext/index.tsx
index 92e95fa..dfd06ba 100644
--- a/src/context/CarouselContext/index.tsx
+++ b/src/context/CarouselContext/index.tsx
@@ -41,6 +41,8 @@ type ContextProps = {
autoScrollAnimation?: (to: number, duration: number) => number
/** Slides kept mounted on each side of the current one. Mounts every slide when omitted. */
renderWindow?: number
+ /** Centres the current slide when `slideWidth` is narrower than the carousel, so its neighbours peek in on both sides. */
+ centerSlide?: boolean
}
export const CarouselContextProvider = ({
@@ -51,6 +53,7 @@ export const CarouselContextProvider = ({
disableAutoScroll = false,
autoScrollAnimation = DEFAULT_ANIMATION,
renderWindow,
+ centerSlide = false,
...rest
}: ContextProps) => {
const userInteracted = useUserInteracted()
@@ -73,6 +76,7 @@ export const CarouselContextProvider = ({
disableAutoScroll,
autoScrollAnimation,
renderWindow,
+ centerSlide,
}),
[
manualScroll,
@@ -83,6 +87,7 @@ export const CarouselContextProvider = ({
disableAutoScroll,
autoScrollAnimation,
renderWindow,
+ centerSlide,
],
)}
>