Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ interface SnapCarouselOptions {
readonly axis?: 'x' | 'y';
// Allows you to render pagination during SSR
readonly initialPages?: number[][];
// Control Snap Carousel's automatic refresh (on layout change, scroll, etc.)
readonly autoRefreshCondition ?: () => boolean;
}
```

Expand Down
24 changes: 16 additions & 8 deletions src/use-snap-carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface SnapCarouselResult {
export interface SnapCarouselOptions {
readonly axis?: 'x' | 'y';
readonly initialPages?: number[][];
readonly autoRefreshCondition?: () => boolean;
}

interface SnapCarouselState {
Expand All @@ -24,7 +25,8 @@ interface SnapCarouselState {

export const useSnapCarousel = ({
axis = 'x',
initialPages = []
initialPages = [],
autoRefreshCondition = () => true
}: SnapCarouselOptions = {}): SnapCarouselResult => {
const dimension = axis === 'x' ? 'width' : 'height';
const scrollDimension = axis === 'x' ? 'scrollWidth' : 'scrollHeight';
Expand Down Expand Up @@ -83,7 +85,7 @@ export const useSnapCarousel = ({
);

const refresh = useCallback(() => {
if (!scrollEl) {
if (!scrollEl ) {
return;
}
const items = Array.from(scrollEl.children);
Expand Down Expand Up @@ -113,22 +115,26 @@ export const useSnapCarousel = ({
}, [refreshActivePage, scrollEl, dimension, farSidePos, nearSidePos]);

useIsomorphicLayoutEffect(() => {
refresh();
}, [refresh]);
if(autoRefreshCondition()) {
refresh();
}
}, [refresh, autoRefreshCondition]);

// On resize we need to refresh the state
useEffect(() => {
const handle = () => {
// TODO: Consider debouncing / throttling
refresh();
if(autoRefreshCondition()) {
refresh();
}
};
window.addEventListener('resize', handle);
window.addEventListener('orientationchange', handle);
return () => {
window.removeEventListener('resize', handle);
window.removeEventListener('orientationchange', handle);
};
}, [refresh]);
}, [refresh, autoRefreshCondition]);

// On scroll we only need to refresh the current page as it won't impact `pages`.
useEffect(() => {
Expand All @@ -137,13 +143,15 @@ export const useSnapCarousel = ({
}
const handle = () => {
// TODO: Consider debouncing / throttling
refreshActivePage(pages);
if(autoRefreshCondition) {
refreshActivePage(pages);
}
};
scrollEl.addEventListener('scroll', handle);
return () => {
scrollEl.removeEventListener('scroll', handle);
};
}, [refreshActivePage, pages, scrollEl]);
}, [refreshActivePage, pages, scrollEl, autoRefreshCondition]);

const handleGoTo = (index: number) => {
if (!scrollEl) {
Expand Down