diff --git a/docs/api/autoplay.mdx b/docs/api/autoplay.mdx
index 01286a8b..6680f1c6 100644
--- a/docs/api/autoplay.mdx
+++ b/docs/api/autoplay.mdx
@@ -25,7 +25,7 @@ For accessibility, the carousel will pause when the user is interacting with it.
#### Code
```tsx
-
+
diff --git a/docs/api/index.mdx b/docs/api/index.mdx
index bd77cfb1..fc47765c 100644
--- a/docs/api/index.mdx
+++ b/docs/api/index.mdx
@@ -78,12 +78,12 @@ Feel free to mix React components and HTML elements as children. Nuka Carousel w
:::caution
-Nuka Carousel uses a flex container for its magic
-
-:::
+### Nuka Carousel uses a flex container to hold its contents.
In order for Nuka to measure your slides, they must have a width that can be calculated.
+:::
+
### Images
If you're using images, Nuka will correctly calculate the width and height of the image after it has loaded.
@@ -114,6 +114,12 @@ However, it's recommended to set the width and height of the image in the HTML t
When using HTML block elements, such as `div`, you must set the min width in the HTML.
+:::info
+
+Most of the examples use Tailwind classes for styling
+
+:::
+
```jsx
.demo-slide {
min-width: 300px;
@@ -145,5 +151,5 @@ function CarouselImage() {
-
+;
```
diff --git a/docs/api/initial-page.mdx b/docs/api/initial-page.mdx
new file mode 100644
index 00000000..d678349c
--- /dev/null
+++ b/docs/api/initial-page.mdx
@@ -0,0 +1,31 @@
+---
+sidebar_position: 4
+---
+
+import { Carousel } from 'nuka-carousel';
+
+# Initial Page
+
+The carousel can start on any index within bounds of its length. Anything out of bounds will default back to `0` for its index. This list is `0` indexed.
+
+| Prop Name | Type | Default Value |
+| :------------ | :----- | :------------ |
+| `initialPage` | number | `0` |
+
+### Example
+
+
+
+
+
+
+
+#### Code
+
+```tsx
+
+
+
+
+
+```
diff --git a/docs/v8-upgrade-guide.mdx b/docs/v8-upgrade-guide.mdx
index 06d85214..dac6626c 100644
--- a/docs/v8-upgrade-guide.mdx
+++ b/docs/v8-upgrade-guide.mdx
@@ -45,7 +45,7 @@ The following props were removed becuase they are no longer valid or replaced by
- `pauseOnHover` - Enabled by default. See the autoplay docs.
- `renderTop{direction}Controls`
- `scrollMode` - Defaults to `remainder`.
-- `slideIndex`
+- `slideIndex` - Use initialPage to start on a certain page, use goToPage to change indices on command.
- `slidesToShow` - Now based on media queries and how large the slides are.
- `speed` - Controlled by native browser settings.
- `style` - See the style guide.
diff --git a/packages/nuka/src/Carousel/Carousel.css b/packages/nuka/src/Carousel/Carousel.css
index 0f8cabb6..7c0cb352 100644
--- a/packages/nuka/src/Carousel/Carousel.css
+++ b/packages/nuka/src/Carousel/Carousel.css
@@ -17,10 +17,15 @@
}
.nuka-overflow {
overflow: scroll;
- scroll-behavior: smooth;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
+.nuka-overflow.scroll-smooth {
+ scroll-behavior: smooth;
+}
+.nuka-overflow.scroll-auto {
+ scroll-behavior: auto;
+}
.nuka-overflow::-webkit-scrollbar {
display: none;
}
diff --git a/packages/nuka/src/Carousel/Carousel.stories.tsx b/packages/nuka/src/Carousel/Carousel.stories.tsx
index aeafa2e8..be2b5c62 100644
--- a/packages/nuka/src/Carousel/Carousel.stories.tsx
+++ b/packages/nuka/src/Carousel/Carousel.stories.tsx
@@ -169,6 +169,20 @@ export const GoToPage: Story = {
},
};
+export const InitialPage: Story = {
+ args: {
+ initialPage: 2,
+ scrollDistance: 'slide',
+ children: (
+ <>
+ {[...Array(10)].map((_, index) => (
+
+ ))}
+ >
+ ),
+ },
+};
+
export const BeforeSlide: Story = {
args: {
beforeSlide: (currentSlideIndex, endSlideIndex) =>
diff --git a/packages/nuka/src/Carousel/Carousel.tsx b/packages/nuka/src/Carousel/Carousel.tsx
index db0fbb24..e78981f5 100644
--- a/packages/nuka/src/Carousel/Carousel.tsx
+++ b/packages/nuka/src/Carousel/Carousel.tsx
@@ -59,6 +59,7 @@ export const Carousel = forwardRef(
swiping,
title,
wrapMode,
+ initialPage,
} = options;
const carouselRef = useRef(null);
@@ -75,6 +76,7 @@ export const Carousel = forwardRef(
const { currentPage, goBack, goForward, goToPage } = usePaging({
totalPages,
wrapMode,
+ initialPage,
});
// -- handle touch scroll events
@@ -139,8 +141,12 @@ export const Carousel = forwardRef(
containerRef.current.scrollLeft = scrollOffset[currentPage];
afterSlide && setTimeout(() => afterSlide(endSlideIndex), 0);
previousPageRef.current = currentPage;
+ if (initialPage === undefined || currentPage === initialPage) {
+ containerRef.current.classList.remove('scroll-auto');
+ containerRef.current.classList.add('scroll-smooth');
+ }
}
- }, [currentPage, scrollOffset, beforeSlide, afterSlide]);
+ }, [currentPage, scrollOffset, beforeSlide, afterSlide, initialPage]);
const containerClassName = cls(
'nuka-container',
diff --git a/packages/nuka/src/hooks/use-paging.test.tsx b/packages/nuka/src/hooks/use-paging.test.tsx
index e677f4bd..a8b9d9ec 100644
--- a/packages/nuka/src/hooks/use-paging.test.tsx
+++ b/packages/nuka/src/hooks/use-paging.test.tsx
@@ -94,4 +94,32 @@ describe('usePaging', () => {
});
expect(result.current.currentPage).toBe(0);
});
+
+ it('should start at index 0 if not given an initial page index', () => {
+ const { result } = renderHook(() =>
+ usePaging({ totalPages: 5, wrapMode: 'wrap' }),
+ );
+ expect(result.current.currentPage).toBe(0);
+ });
+
+ it('should start at the given initial page index', () => {
+ const { result } = renderHook(() =>
+ usePaging({ totalPages: 5, wrapMode: 'wrap', initialPage: 2 }),
+ );
+ expect(result.current.currentPage).toBe(2);
+ });
+
+ it('should start at in bound indices if initial page is out of bounds', () => {
+ const { result } = renderHook(() =>
+ usePaging({ totalPages: 5, wrapMode: 'wrap', initialPage: 200 }),
+ );
+ expect(result.current.currentPage).toBe(5);
+ });
+
+ it('should start at 0 indices if initial page is out of bounds', () => {
+ const { result } = renderHook(() =>
+ usePaging({ totalPages: 5, wrapMode: 'wrap', initialPage: -2 }),
+ );
+ expect(result.current.currentPage).toBe(0);
+ });
});
diff --git a/packages/nuka/src/hooks/use-paging.tsx b/packages/nuka/src/hooks/use-paging.tsx
index facb6bf2..0f0b0fe4 100644
--- a/packages/nuka/src/hooks/use-paging.tsx
+++ b/packages/nuka/src/hooks/use-paging.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { CarouselProps } from '../types';
@@ -12,14 +12,22 @@ type UsePagingReturnType = {
type PagingProps = {
totalPages: number;
wrapMode: CarouselProps['wrapMode'];
+ initialPage?: number;
};
export function usePaging({
totalPages,
wrapMode,
+ initialPage,
}: PagingProps): UsePagingReturnType {
const [currentPage, setCurrentPage] = useState(0);
+ useEffect(() => {
+ if (initialPage) {
+ setCurrentPage(Math.max(0, Math.min(initialPage, totalPages)));
+ }
+ }, [initialPage, totalPages]);
+
const goToPage = (idx: number) => {
if (idx < 0 || idx >= totalPages) return;
setCurrentPage(idx);
diff --git a/packages/nuka/src/types.ts b/packages/nuka/src/types.ts
index 4bdc292d..135d8aac 100644
--- a/packages/nuka/src/types.ts
+++ b/packages/nuka/src/types.ts
@@ -25,6 +25,7 @@ export type CarouselProps = CarouselCallbacks & {
swiping?: boolean;
title?: string;
wrapMode?: 'nowrap' | 'wrap';
+ initialPage?: number;
};
export type SlideHandle = {