From 967400e5964af80f4cfc7e3b0ee88a4cd3ed51d6 Mon Sep 17 00:00:00 2001 From: Deion Graham-Long Date: Thu, 29 Feb 2024 19:16:13 -0700 Subject: [PATCH 1/2] fix: next item function overscolling with overscrollEnabled is false --- src/components/Carousel.tsx | 10 +++++++++- src/hooks/useCarouselController.tsx | 15 ++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index 4d279970..febdd03c 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -19,6 +19,7 @@ import { computedRealIndexWithAutoFillData } from "../utils/computed-with-auto-f const Carousel = React.forwardRef>( (_props, ref) => { + const [containerWidth, setContainerWidth] = React.useState(0); const props = useInitProps(_props); const { @@ -87,6 +88,8 @@ const Carousel = React.forwardRef>( duration: scrollAnimationDuration, onScrollEnd: () => runOnJS(_onScrollEnd)(), onScrollStart: () => !!onScrollStart && runOnJS(onScrollStart)(), + containerWidth, + overscrollEnabled: props.overscrollEnabled, }); const { next, prev, scrollTo, getSharedIndex, getCurrentIndex } @@ -155,7 +158,12 @@ const Carousel = React.forwardRef>( const layoutConfig = useLayoutConfig({ ...props, size }); return ( - + { + const { width } = event.nativeEvent.layout; + setContainerWidth(width); + }} + > void onScrollEnd?: () => void + containerWidth: number + overscrollEnabled?: boolean } export interface ICarouselController { @@ -50,6 +52,8 @@ export function useCarouselController(options: IOpts): ICarouselController { duration, autoFillData, fixedDirection, + containerWidth, + overscrollEnabled, } = options; const dataInfo = React.useMemo( @@ -177,15 +181,16 @@ export function useCarouselController(options: IOpts): ICarouselController { const nextPage = currentFixedPage() + count; index.value = nextPage; + let value = -nextPage * size; + if (!loop && !overscrollEnabled) { + value = Math.max(value, -(dataLength * size - containerWidth)); + } if (animated) { - handlerOffset.value = scrollWithTiming( - -nextPage * size, - onFinished, - ) as any; + handlerOffset.value = scrollWithTiming(value, onFinished) as any; } else { - handlerOffset.value = -nextPage * size; + handlerOffset.value = value; onFinished?.(); } }, From 47738d654b4e898bbac0ad1080c3a996f143775a Mon Sep 17 00:00:00 2001 From: Deion Graham-Long Date: Thu, 29 Feb 2024 20:27:08 -0700 Subject: [PATCH 2/2] fix: overscroll & not being able to go to previous item --- src/hooks/useCarouselController.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hooks/useCarouselController.tsx b/src/hooks/useCarouselController.tsx index 02057271..3e9b6d03 100644 --- a/src/hooks/useCarouselController.tsx +++ b/src/hooks/useCarouselController.tsx @@ -210,21 +210,31 @@ export function useCarouselController(options: IOpts): ICarouselController { const prev = React.useCallback( (opts: TCarouselActionOptions = {}) => { const { count = 1, animated = true, onFinished } = opts; - if (!canSliding() || (!loop && index.value <= 0)) return; + /* Checking handlerOffset.value === 0 because if going to the next item doesn't + clear the first element (can happen if overscrollEnabled = false), then we wouldn't + be allowed to go to the previous item + */ + if (!canSliding() || (!loop && index.value <= 0 && handlerOffset.value === 0)) return; onScrollStart?.(); const prevPage = currentFixedPage() - count; index.value = prevPage; + let value = -prevPage * size; + // Avoid overscrolling the first item + if(!loop && value > 0){ + value = 0 + } + if (animated) { handlerOffset.value = scrollWithTiming( - -prevPage * size, + value, onFinished, ); } else { - handlerOffset.value = -prevPage * size; + handlerOffset.value = value; onFinished?.(); } },