diff --git a/.changeset/hot-berries-ring.md b/.changeset/hot-berries-ring.md new file mode 100644 index 00000000..39c26a95 --- /dev/null +++ b/.changeset/hot-berries-ring.md @@ -0,0 +1,5 @@ +--- +"nuka-carousel": minor +--- + +feat: provide page info on beforeSlide and afterSlide callbacks diff --git a/docs/api/callbacks.mdx b/docs/api/callbacks.mdx index 0e5f9ff4..6b69c6c8 100644 --- a/docs/api/callbacks.mdx +++ b/docs/api/callbacks.mdx @@ -14,10 +14,10 @@ Functions that are invoked when the progression methods (goBack()/goForward()) a ### Details -| Prop Name | Type | Default Value | -| :------------ | :--------- | :------------ | -| `beforeSlide` | () => void | `undefined` | -| `afterSlide` | () => void | `undefined` | +| Prop Name | Type | Default Value | +| :------------ | :--------------------------------------------------------- | :------------ | +| `beforeSlide` | (currentSlideIndex: number, endSlideIndex: number) => void | `undefined` | +| `afterSlide` | (endSlideIndex: number) => void | `undefined` | - `beforeSlide` - Runs a given function before scrolling when a progression method is called. It will also run right before the carousel registers that it has been scrolled on if manually scrolled. - `afterSlide` - Runs a given function after scrolling when a progression method is called or after manually scrolling. @@ -25,13 +25,9 @@ Functions that are invoked when the progression methods (goBack()/goForward()) a ### Example ```tsx - myCustomBeforeFunction()}> - {/* Cards */} - + myCustomBeforeFunction()}>{/* Cards */} ``` ```tsx - myCustomAfterFunction()}> - {/* Cards */} - + myCustomAfterFunction()}>{/* Cards */} ``` diff --git a/packages/nuka/src/Carousel/Carousel.stories.tsx b/packages/nuka/src/Carousel/Carousel.stories.tsx index 6178e914..aeafa2e8 100644 --- a/packages/nuka/src/Carousel/Carousel.stories.tsx +++ b/packages/nuka/src/Carousel/Carousel.stories.tsx @@ -171,8 +171,12 @@ export const GoToPage: Story = { export const BeforeSlide: Story = { args: { - beforeSlide: () => - console.log('Function was called before scroll occurred '), + beforeSlide: (currentSlideIndex, endSlideIndex) => + console.log( + 'Function was called before scroll occurred ', + currentSlideIndex, + endSlideIndex, + ), children: ( <> {[...Array(10)].map((_, index) => ( @@ -185,7 +189,8 @@ export const BeforeSlide: Story = { export const AfterSlide: Story = { args: { - afterSlide: () => console.log('Function was called after scroll occurred '), + afterSlide: (endSlideIndex) => + console.log('Function was called after scroll occurred ', endSlideIndex), children: ( <> {[...Array(10)].map((_, index) => ( diff --git a/packages/nuka/src/Carousel/Carousel.tsx b/packages/nuka/src/Carousel/Carousel.tsx index c12140ac..1477a25b 100644 --- a/packages/nuka/src/Carousel/Carousel.tsx +++ b/packages/nuka/src/Carousel/Carousel.tsx @@ -54,6 +54,7 @@ export const Carousel = forwardRef( const carouselRef = useRef(null); const containerRef = useRef(null); + const previousPageRef = useRef(-1); // -- update page count and scroll offset based on scroll distance const { totalPages, scrollOffset } = useMeasurement({ @@ -103,9 +104,12 @@ export const Carousel = forwardRef( // -- scroll container when page index changes useEffect(() => { if (containerRef.current) { - beforeSlide && beforeSlide(); + const currentSlideIndex = previousPageRef.current; + const endSlideIndex = currentPage; + beforeSlide && beforeSlide(currentSlideIndex, endSlideIndex); containerRef.current.scrollLeft = scrollOffset[currentPage]; - afterSlide && setTimeout(() => afterSlide(), 0); + afterSlide && setTimeout(() => afterSlide(endSlideIndex), 0); + previousPageRef.current = currentPage; } }, [currentPage, scrollOffset, beforeSlide, afterSlide]); diff --git a/packages/nuka/src/types.ts b/packages/nuka/src/types.ts index 09a7a6cd..de94a65a 100644 --- a/packages/nuka/src/types.ts +++ b/packages/nuka/src/types.ts @@ -4,8 +4,8 @@ export type ShowArrowsOption = boolean | 'always' | 'hover'; export type ScrollDistanceType = number | 'slide' | 'screen'; export type CarouselCallbacks = { - beforeSlide?: () => void; - afterSlide?: () => void; + beforeSlide?: (currentSlideIndex: number, endSlideIndex: number) => void; + afterSlide?: (endSlideIndex: number) => void; }; export type CarouselProps = CarouselCallbacks & {