@leonsilicon/react-native-reanimated-carousel 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +652 -0
- package/lib/commonjs/components/Carousel.js +2 -0
- package/lib/commonjs/components/Carousel.js.map +1 -0
- package/lib/commonjs/components/CarouselLayout.js +2 -0
- package/lib/commonjs/components/CarouselLayout.js.map +1 -0
- package/lib/commonjs/components/ItemLayout.js +2 -0
- package/lib/commonjs/components/ItemLayout.js.map +1 -0
- package/lib/commonjs/components/ItemRenderer.js +2 -0
- package/lib/commonjs/components/ItemRenderer.js.map +1 -0
- package/lib/commonjs/components/LazyView.js +2 -0
- package/lib/commonjs/components/LazyView.js.map +1 -0
- package/lib/commonjs/components/Pagination/Basic/PaginationItem.js +2 -0
- package/lib/commonjs/components/Pagination/Basic/PaginationItem.js.map +1 -0
- package/lib/commonjs/components/Pagination/Basic/index.js +2 -0
- package/lib/commonjs/components/Pagination/Basic/index.js.map +1 -0
- package/lib/commonjs/components/Pagination/Custom/PaginationItem.js +2 -0
- package/lib/commonjs/components/Pagination/Custom/PaginationItem.js.map +1 -0
- package/lib/commonjs/components/Pagination/Custom/index.js +2 -0
- package/lib/commonjs/components/Pagination/Custom/index.js.map +1 -0
- package/lib/commonjs/components/Pagination/index.js +2 -0
- package/lib/commonjs/components/Pagination/index.js.map +1 -0
- package/lib/commonjs/components/ScrollViewGesture.js +2 -0
- package/lib/commonjs/components/ScrollViewGesture.js.map +1 -0
- package/lib/commonjs/constants/index.js +2 -0
- package/lib/commonjs/constants/index.js.map +1 -0
- package/lib/commonjs/hooks/useAutoPlay.js +2 -0
- package/lib/commonjs/hooks/useAutoPlay.js.map +1 -0
- package/lib/commonjs/hooks/useCarouselController.js +2 -0
- package/lib/commonjs/hooks/useCarouselController.js.map +1 -0
- package/lib/commonjs/hooks/useCheckMounted.js +2 -0
- package/lib/commonjs/hooks/useCheckMounted.js.map +1 -0
- package/lib/commonjs/hooks/useCommonVariables.js +2 -0
- package/lib/commonjs/hooks/useCommonVariables.js.map +1 -0
- package/lib/commonjs/hooks/useInitProps.js +2 -0
- package/lib/commonjs/hooks/useInitProps.js.map +1 -0
- package/lib/commonjs/hooks/useLayoutConfig.js +2 -0
- package/lib/commonjs/hooks/useLayoutConfig.js.map +1 -0
- package/lib/commonjs/hooks/useOffsetX.js +2 -0
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -0
- package/lib/commonjs/hooks/useOnProgressChange.js +2 -0
- package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js +2 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/commonjs/hooks/usePropsErrorBoundary.js +2 -0
- package/lib/commonjs/hooks/usePropsErrorBoundary.js.map +1 -0
- package/lib/commonjs/hooks/useSizeResolver.js +2 -0
- package/lib/commonjs/hooks/useSizeResolver.js.map +1 -0
- package/lib/commonjs/hooks/useUpdateGestureConfig.js +2 -0
- package/lib/commonjs/hooks/useUpdateGestureConfig.js.map +1 -0
- package/lib/commonjs/hooks/useVisibleRanges.js +2 -0
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -0
- package/lib/commonjs/index.js +2 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/layouts/index.js +2 -0
- package/lib/commonjs/layouts/index.js.map +1 -0
- package/lib/commonjs/layouts/normal.js +2 -0
- package/lib/commonjs/layouts/normal.js.map +1 -0
- package/lib/commonjs/layouts/parallax.js +2 -0
- package/lib/commonjs/layouts/parallax.js.map +1 -0
- package/lib/commonjs/layouts/stack.js +2 -0
- package/lib/commonjs/layouts/stack.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/store/index.js +2 -0
- package/lib/commonjs/store/index.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/compute-gesture-translation.js +2 -0
- package/lib/commonjs/utils/compute-gesture-translation.js.map +1 -0
- package/lib/commonjs/utils/compute-offset-if-data-changed.js +2 -0
- package/lib/commonjs/utils/compute-offset-if-data-changed.js.map +1 -0
- package/lib/commonjs/utils/compute-offset-if-size-changed.js +2 -0
- package/lib/commonjs/utils/compute-offset-if-size-changed.js.map +1 -0
- package/lib/commonjs/utils/compute-offset-if-sizes-changed.js +2 -0
- package/lib/commonjs/utils/compute-offset-if-sizes-changed.js.map +1 -0
- package/lib/commonjs/utils/computed-with-auto-fill-data.js +2 -0
- package/lib/commonjs/utils/computed-with-auto-fill-data.js.map +1 -0
- package/lib/commonjs/utils/deal-with-animation.js +2 -0
- package/lib/commonjs/utils/deal-with-animation.js.map +1 -0
- package/lib/commonjs/utils/handleroffset-direction.js +2 -0
- package/lib/commonjs/utils/handleroffset-direction.js.map +1 -0
- package/lib/commonjs/utils/log.js +2 -0
- package/lib/commonjs/utils/log.js.map +1 -0
- package/lib/commonjs/utils/sanitize-animation-style.js +2 -0
- package/lib/commonjs/utils/sanitize-animation-style.js.map +1 -0
- package/lib/commonjs/utils/size-resolver.js +2 -0
- package/lib/commonjs/utils/size-resolver.js.map +1 -0
- package/lib/module/components/Carousel.js +2 -0
- package/lib/module/components/Carousel.js.map +1 -0
- package/lib/module/components/CarouselLayout.js +2 -0
- package/lib/module/components/CarouselLayout.js.map +1 -0
- package/lib/module/components/ItemLayout.js +2 -0
- package/lib/module/components/ItemLayout.js.map +1 -0
- package/lib/module/components/ItemRenderer.js +2 -0
- package/lib/module/components/ItemRenderer.js.map +1 -0
- package/lib/module/components/LazyView.js +2 -0
- package/lib/module/components/LazyView.js.map +1 -0
- package/lib/module/components/Pagination/Basic/PaginationItem.js +2 -0
- package/lib/module/components/Pagination/Basic/PaginationItem.js.map +1 -0
- package/lib/module/components/Pagination/Basic/index.js +2 -0
- package/lib/module/components/Pagination/Basic/index.js.map +1 -0
- package/lib/module/components/Pagination/Custom/PaginationItem.js +2 -0
- package/lib/module/components/Pagination/Custom/PaginationItem.js.map +1 -0
- package/lib/module/components/Pagination/Custom/index.js +2 -0
- package/lib/module/components/Pagination/Custom/index.js.map +1 -0
- package/lib/module/components/Pagination/index.js +2 -0
- package/lib/module/components/Pagination/index.js.map +1 -0
- package/lib/module/components/ScrollViewGesture.js +2 -0
- package/lib/module/components/ScrollViewGesture.js.map +1 -0
- package/lib/module/constants/index.js +2 -0
- package/lib/module/constants/index.js.map +1 -0
- package/lib/module/hooks/useAutoPlay.js +2 -0
- package/lib/module/hooks/useAutoPlay.js.map +1 -0
- package/lib/module/hooks/useCarouselController.js +2 -0
- package/lib/module/hooks/useCarouselController.js.map +1 -0
- package/lib/module/hooks/useCheckMounted.js +2 -0
- package/lib/module/hooks/useCheckMounted.js.map +1 -0
- package/lib/module/hooks/useCommonVariables.js +2 -0
- package/lib/module/hooks/useCommonVariables.js.map +1 -0
- package/lib/module/hooks/useInitProps.js +2 -0
- package/lib/module/hooks/useInitProps.js.map +1 -0
- package/lib/module/hooks/useLayoutConfig.js +2 -0
- package/lib/module/hooks/useLayoutConfig.js.map +1 -0
- package/lib/module/hooks/useOffsetX.js +2 -0
- package/lib/module/hooks/useOffsetX.js.map +1 -0
- package/lib/module/hooks/useOnProgressChange.js +2 -0
- package/lib/module/hooks/useOnProgressChange.js.map +1 -0
- package/lib/module/hooks/usePanGestureProxy.js +2 -0
- package/lib/module/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/module/hooks/usePropsErrorBoundary.js +2 -0
- package/lib/module/hooks/usePropsErrorBoundary.js.map +1 -0
- package/lib/module/hooks/useSizeResolver.js +2 -0
- package/lib/module/hooks/useSizeResolver.js.map +1 -0
- package/lib/module/hooks/useUpdateGestureConfig.js +2 -0
- package/lib/module/hooks/useUpdateGestureConfig.js.map +1 -0
- package/lib/module/hooks/useVisibleRanges.js +2 -0
- package/lib/module/hooks/useVisibleRanges.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/layouts/index.js +2 -0
- package/lib/module/layouts/index.js.map +1 -0
- package/lib/module/layouts/normal.js +2 -0
- package/lib/module/layouts/normal.js.map +1 -0
- package/lib/module/layouts/parallax.js +2 -0
- package/lib/module/layouts/parallax.js.map +1 -0
- package/lib/module/layouts/stack.js +2 -0
- package/lib/module/layouts/stack.js.map +1 -0
- package/lib/module/store/index.js +2 -0
- package/lib/module/store/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/compute-gesture-translation.js +2 -0
- package/lib/module/utils/compute-gesture-translation.js.map +1 -0
- package/lib/module/utils/compute-offset-if-data-changed.js +2 -0
- package/lib/module/utils/compute-offset-if-data-changed.js.map +1 -0
- package/lib/module/utils/compute-offset-if-size-changed.js +2 -0
- package/lib/module/utils/compute-offset-if-size-changed.js.map +1 -0
- package/lib/module/utils/compute-offset-if-sizes-changed.js +2 -0
- package/lib/module/utils/compute-offset-if-sizes-changed.js.map +1 -0
- package/lib/module/utils/computed-with-auto-fill-data.js +2 -0
- package/lib/module/utils/computed-with-auto-fill-data.js.map +1 -0
- package/lib/module/utils/deal-with-animation.js +2 -0
- package/lib/module/utils/deal-with-animation.js.map +1 -0
- package/lib/module/utils/handleroffset-direction.js +2 -0
- package/lib/module/utils/handleroffset-direction.js.map +1 -0
- package/lib/module/utils/log.js +2 -0
- package/lib/module/utils/log.js.map +1 -0
- package/lib/module/utils/sanitize-animation-style.js +2 -0
- package/lib/module/utils/sanitize-animation-style.js.map +1 -0
- package/lib/module/utils/size-resolver.js +2 -0
- package/lib/module/utils/size-resolver.js.map +1 -0
- package/lib/typescript/components/Carousel.d.ts +8 -0
- package/lib/typescript/components/Carousel.d.ts.map +1 -0
- package/lib/typescript/components/CarouselLayout.d.ts +6 -0
- package/lib/typescript/components/CarouselLayout.d.ts.map +1 -0
- package/lib/typescript/components/ItemLayout.d.ts +15 -0
- package/lib/typescript/components/ItemLayout.d.ts.map +1 -0
- package/lib/typescript/components/ItemRenderer.d.ts +24 -0
- package/lib/typescript/components/ItemRenderer.d.ts.map +1 -0
- package/lib/typescript/components/LazyView.d.ts +8 -0
- package/lib/typescript/components/LazyView.d.ts.map +1 -0
- package/lib/typescript/components/Pagination/Basic/PaginationItem.d.ts +29 -0
- package/lib/typescript/components/Pagination/Basic/PaginationItem.d.ts.map +1 -0
- package/lib/typescript/components/Pagination/Basic/index.d.ts +23 -0
- package/lib/typescript/components/Pagination/Basic/index.d.ts.map +1 -0
- package/lib/typescript/components/Pagination/Custom/PaginationItem.d.ts +35 -0
- package/lib/typescript/components/Pagination/Custom/PaginationItem.d.ts.map +1 -0
- package/lib/typescript/components/Pagination/Custom/index.d.ts +26 -0
- package/lib/typescript/components/Pagination/Custom/index.d.ts.map +1 -0
- package/lib/typescript/components/Pagination/index.d.ts +5 -0
- package/lib/typescript/components/Pagination/index.d.ts.map +1 -0
- package/lib/typescript/components/ScrollViewGesture.d.ts +19 -0
- package/lib/typescript/components/ScrollViewGesture.d.ts.map +1 -0
- package/lib/typescript/constants/index.d.ts +9 -0
- package/lib/typescript/constants/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useAutoPlay.d.ts +12 -0
- package/lib/typescript/hooks/useAutoPlay.d.ts.map +1 -0
- package/lib/typescript/hooks/useCarouselController.d.ts +28 -0
- package/lib/typescript/hooks/useCarouselController.d.ts.map +1 -0
- package/lib/typescript/hooks/useCheckMounted.d.ts +3 -0
- package/lib/typescript/hooks/useCheckMounted.d.ts.map +1 -0
- package/lib/typescript/hooks/useCommonVariables.d.ts +13 -0
- package/lib/typescript/hooks/useCommonVariables.d.ts.map +1 -0
- package/lib/typescript/hooks/useInitProps.d.ts +17 -0
- package/lib/typescript/hooks/useInitProps.d.ts.map +1 -0
- package/lib/typescript/hooks/useLayoutConfig.d.ts +10 -0
- package/lib/typescript/hooks/useLayoutConfig.d.ts.map +1 -0
- package/lib/typescript/hooks/useOffsetX.d.ts +24 -0
- package/lib/typescript/hooks/useOffsetX.d.ts.map +1 -0
- package/lib/typescript/hooks/useOnProgressChange.d.ts +14 -0
- package/lib/typescript/hooks/useOnProgressChange.d.ts.map +1 -0
- package/lib/typescript/hooks/usePanGestureProxy.d.ts +10 -0
- package/lib/typescript/hooks/usePanGestureProxy.d.ts.map +1 -0
- package/lib/typescript/hooks/usePropsErrorBoundary.d.ts +5 -0
- package/lib/typescript/hooks/usePropsErrorBoundary.d.ts.map +1 -0
- package/lib/typescript/hooks/useSizeResolver.d.ts +27 -0
- package/lib/typescript/hooks/useSizeResolver.d.ts.map +1 -0
- package/lib/typescript/hooks/useUpdateGestureConfig.d.ts +6 -0
- package/lib/typescript/hooks/useUpdateGestureConfig.d.ts.map +1 -0
- package/lib/typescript/hooks/useVisibleRanges.d.ts +23 -0
- package/lib/typescript/hooks/useVisibleRanges.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +7 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/layouts/index.d.ts +11 -0
- package/lib/typescript/layouts/index.d.ts.map +1 -0
- package/lib/typescript/layouts/normal.d.ts +16 -0
- package/lib/typescript/layouts/normal.d.ts.map +1 -0
- package/lib/typescript/layouts/parallax.d.ts +50 -0
- package/lib/typescript/layouts/parallax.d.ts.map +1 -0
- package/lib/typescript/layouts/stack.d.ts +38 -0
- package/lib/typescript/layouts/stack.d.ts.map +1 -0
- package/lib/typescript/store/index.d.ts +38 -0
- package/lib/typescript/store/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +326 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils/compute-gesture-translation.d.ts +9 -0
- package/lib/typescript/utils/compute-gesture-translation.d.ts.map +1 -0
- package/lib/typescript/utils/compute-offset-if-data-changed.d.ts +9 -0
- package/lib/typescript/utils/compute-offset-if-data-changed.d.ts.map +1 -0
- package/lib/typescript/utils/compute-offset-if-size-changed.d.ts +6 -0
- package/lib/typescript/utils/compute-offset-if-size-changed.d.ts.map +1 -0
- package/lib/typescript/utils/compute-offset-if-sizes-changed.d.ts +14 -0
- package/lib/typescript/utils/compute-offset-if-sizes-changed.d.ts.map +1 -0
- package/lib/typescript/utils/computed-with-auto-fill-data.d.ts +23 -0
- package/lib/typescript/utils/computed-with-auto-fill-data.d.ts.map +1 -0
- package/lib/typescript/utils/deal-with-animation.d.ts +3 -0
- package/lib/typescript/utils/deal-with-animation.d.ts.map +1 -0
- package/lib/typescript/utils/handleroffset-direction.d.ts +4 -0
- package/lib/typescript/utils/handleroffset-direction.d.ts.map +1 -0
- package/lib/typescript/utils/log.d.ts +7 -0
- package/lib/typescript/utils/log.d.ts.map +1 -0
- package/lib/typescript/utils/sanitize-animation-style.d.ts +3 -0
- package/lib/typescript/utils/sanitize-animation-style.d.ts.map +1 -0
- package/lib/typescript/utils/size-resolver.d.ts +87 -0
- package/lib/typescript/utils/size-resolver.d.ts.map +1 -0
- package/package.json +151 -0
- package/src/components/Carousel.test.tsx +1153 -0
- package/src/components/Carousel.tsx +35 -0
- package/src/components/CarouselLayout.tsx +231 -0
- package/src/components/ItemLayout.tsx +217 -0
- package/src/components/ItemRenderer.tsx +114 -0
- package/src/components/LazyView.test.tsx +61 -0
- package/src/components/LazyView.tsx +14 -0
- package/src/components/Pagination/Basic/PaginationItem.tsx +149 -0
- package/src/components/Pagination/Basic/index.tsx +98 -0
- package/src/components/Pagination/Custom/PaginationItem.tsx +166 -0
- package/src/components/Pagination/Custom/index.tsx +111 -0
- package/src/components/Pagination/Pagination.test.tsx +178 -0
- package/src/components/Pagination/index.tsx +7 -0
- package/src/components/ScrollViewGesture.tsx +577 -0
- package/src/components/rnr-demo.test.tsx +53 -0
- package/src/constants/index.ts +11 -0
- package/src/hooks/useAutoPlay.test.ts +194 -0
- package/src/hooks/useAutoPlay.ts +58 -0
- package/src/hooks/useCarouselController.test.tsx +1158 -0
- package/src/hooks/useCarouselController.tsx +525 -0
- package/src/hooks/useCheckMounted.test.ts +47 -0
- package/src/hooks/useCheckMounted.ts +14 -0
- package/src/hooks/useCommonVariables.test.tsx +384 -0
- package/src/hooks/useCommonVariables.ts +202 -0
- package/src/hooks/useInitProps.test.tsx +134 -0
- package/src/hooks/useInitProps.ts +111 -0
- package/src/hooks/useLayoutConfig.test.tsx +247 -0
- package/src/hooks/useLayoutConfig.ts +30 -0
- package/src/hooks/useOffsetX.test.ts +110 -0
- package/src/hooks/useOffsetX.ts +109 -0
- package/src/hooks/useOnProgressChange.test.tsx +207 -0
- package/src/hooks/useOnProgressChange.ts +105 -0
- package/src/hooks/usePanGestureProxy.test.tsx +368 -0
- package/src/hooks/usePanGestureProxy.ts +144 -0
- package/src/hooks/usePropsErrorBoundary.ts +138 -0
- package/src/hooks/useSizeResolver.test.tsx +112 -0
- package/src/hooks/useSizeResolver.ts +106 -0
- package/src/hooks/useUpdateGestureConfig.test.ts +89 -0
- package/src/hooks/useUpdateGestureConfig.ts +14 -0
- package/src/hooks/useVisibleRanges.test.tsx +366 -0
- package/src/hooks/useVisibleRanges.tsx +123 -0
- package/src/index.tsx +13 -0
- package/src/layouts/index.tsx +12 -0
- package/src/layouts/normal.ts +32 -0
- package/src/layouts/parallax.test.ts +239 -0
- package/src/layouts/parallax.ts +83 -0
- package/src/layouts/stack.test.ts +252 -0
- package/src/layouts/stack.ts +306 -0
- package/src/store/index.test.tsx +314 -0
- package/src/store/index.tsx +66 -0
- package/src/types.ts +348 -0
- package/src/utils/compute-gesture-translation.test.ts +70 -0
- package/src/utils/compute-gesture-translation.ts +29 -0
- package/src/utils/compute-offset-if-data-changed.test.ts +133 -0
- package/src/utils/compute-offset-if-data-changed.ts +44 -0
- package/src/utils/compute-offset-if-size-changed.test.ts +78 -0
- package/src/utils/compute-offset-if-size-changed.ts +14 -0
- package/src/utils/compute-offset-if-sizes-changed.test.ts +74 -0
- package/src/utils/compute-offset-if-sizes-changed.ts +44 -0
- package/src/utils/computed-with-auto-fill-data.test.ts +298 -0
- package/src/utils/computed-with-auto-fill-data.ts +92 -0
- package/src/utils/deal-with-animation.test.ts +181 -0
- package/src/utils/deal-with-animation.ts +17 -0
- package/src/utils/handleroffset-direction.test.ts +124 -0
- package/src/utils/handleroffset-direction.ts +18 -0
- package/src/utils/index.test.ts +90 -0
- package/src/utils/log.test.ts +134 -0
- package/src/utils/log.ts +12 -0
- package/src/utils/sanitize-animation-style.test.ts +40 -0
- package/src/utils/sanitize-animation-style.ts +20 -0
- package/src/utils/size-resolver.test.ts +193 -0
- package/src/utils/size-resolver.ts +216 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { act, renderHook } from "@testing-library/react-hooks";
|
|
2
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
import { SharedValue, useSharedValue } from "react-native-reanimated";
|
|
4
|
+
|
|
5
|
+
import { useCommonVariables } from "./useCommonVariables";
|
|
6
|
+
import type { TInitializeCarouselProps } from "./useInitProps";
|
|
7
|
+
|
|
8
|
+
function createBaseProps(
|
|
9
|
+
overrides: Partial<TInitializeCarouselProps<any>> = {}
|
|
10
|
+
): TInitializeCarouselProps<any> {
|
|
11
|
+
return {
|
|
12
|
+
defaultIndex: 0,
|
|
13
|
+
loop: true,
|
|
14
|
+
scrollAnimationDuration: 500,
|
|
15
|
+
autoFillData: true,
|
|
16
|
+
autoPlayInterval: 2000,
|
|
17
|
+
autoPlay: false,
|
|
18
|
+
data: [0, 1, 2, 3],
|
|
19
|
+
dataLength: 4,
|
|
20
|
+
rawData: [0, 1, 2, 3],
|
|
21
|
+
rawDataLength: 4,
|
|
22
|
+
vertical: false,
|
|
23
|
+
style: { width: 700, height: 350 } as StyleProp<ViewStyle>,
|
|
24
|
+
renderItem: () => null,
|
|
25
|
+
pagingEnabled: true,
|
|
26
|
+
enabled: true,
|
|
27
|
+
overscrollEnabled: true,
|
|
28
|
+
snapEnabled: true,
|
|
29
|
+
testID: "carousel",
|
|
30
|
+
...overrides,
|
|
31
|
+
} as TInitializeCarouselProps<any>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("useCommonVariables", () => {
|
|
35
|
+
it("returns expected values when style provides width", () => {
|
|
36
|
+
const props = createBaseProps();
|
|
37
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
38
|
+
|
|
39
|
+
expect(result.current.size).toBe(700);
|
|
40
|
+
expect(result.current.validLength).toBe(3);
|
|
41
|
+
expect(result.current.handlerOffset.value).toBeCloseTo(0);
|
|
42
|
+
expect(result.current.resolvedSize.value).toBe(700);
|
|
43
|
+
expect(result.current.sizePhase.value).toBe("ready");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("uses style.height as size when vertical", () => {
|
|
47
|
+
const props = createBaseProps({ vertical: true, style: { height: 360 } });
|
|
48
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
49
|
+
|
|
50
|
+
expect(result.current.size).toBe(360);
|
|
51
|
+
expect(result.current.resolvedSize.value).toBe(360);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("initializes handlerOffset when defaultIndex is non-zero", () => {
|
|
55
|
+
const props = createBaseProps({ defaultIndex: 2 });
|
|
56
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
57
|
+
|
|
58
|
+
expect(result.current.handlerOffset.value).toBe(-1400);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("respects custom defaultScrollOffsetValue", () => {
|
|
62
|
+
let shared!: SharedValue<number>;
|
|
63
|
+
const { result } = renderHook(() => {
|
|
64
|
+
shared = useSharedValue(-500);
|
|
65
|
+
const props = createBaseProps({ defaultScrollOffsetValue: shared });
|
|
66
|
+
return useCommonVariables(props);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(result.current.handlerOffset).toBe(shared);
|
|
70
|
+
expect(result.current.handlerOffset.value).toBe(-500);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("sets validLength to 0 when dataLength is 1", () => {
|
|
74
|
+
const props = createBaseProps({ dataLength: 1, data: [0] });
|
|
75
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
76
|
+
|
|
77
|
+
expect(result.current.validLength).toBe(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("sets validLength to -1 when dataLength is 0", () => {
|
|
81
|
+
const props = createBaseProps({ dataLength: 0, data: [] });
|
|
82
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
83
|
+
|
|
84
|
+
expect(result.current.validLength).toBe(-1);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("handles negative defaultIndex", () => {
|
|
88
|
+
const props = createBaseProps({ defaultIndex: -1 });
|
|
89
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
90
|
+
|
|
91
|
+
expect(result.current.handlerOffset.value).toBe(-700);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("keeps size calculation when loop is disabled", () => {
|
|
95
|
+
const props = createBaseProps({ loop: false });
|
|
96
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
97
|
+
|
|
98
|
+
expect(result.current.size).toBe(700);
|
|
99
|
+
expect(result.current.validLength).toBe(3);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("syncs resolvedSize when style width changes", () => {
|
|
103
|
+
const initial = createBaseProps();
|
|
104
|
+
const hook = renderHook(({ p }) => useCommonVariables(p), { initialProps: { p: initial } });
|
|
105
|
+
expect(hook.result.current.resolvedSize.value).toBe(700);
|
|
106
|
+
|
|
107
|
+
const updated = createBaseProps({ style: { width: 800 } });
|
|
108
|
+
act(() => {
|
|
109
|
+
hook.rerender({ p: updated });
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
expect(hook.result.current.resolvedSize.value).toBe(800);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("updates validLength when dataLength changes", () => {
|
|
116
|
+
const hook = renderHook(({ p }) => useCommonVariables(p), {
|
|
117
|
+
initialProps: { p: createBaseProps() },
|
|
118
|
+
});
|
|
119
|
+
expect(hook.result.current.validLength).toBe(3);
|
|
120
|
+
|
|
121
|
+
act(() => {
|
|
122
|
+
hook.rerender({ p: createBaseProps({ dataLength: 6, data: [0, 1, 2, 3, 4, 5] }) });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(hook.result.current.validLength).toBe(5);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("remains pending when style lacks numeric size", () => {
|
|
129
|
+
const props = createBaseProps({ style: { width: "100%" } });
|
|
130
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
131
|
+
|
|
132
|
+
expect(result.current.size).toBe(0);
|
|
133
|
+
expect(result.current.resolvedSize.value).toBeNull();
|
|
134
|
+
expect(result.current.sizePhase.value).toBe("pending");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("keeps handlerOffset at zero when width is 0", () => {
|
|
138
|
+
const props = createBaseProps({ style: { width: 0 } });
|
|
139
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
140
|
+
|
|
141
|
+
expect(result.current.size).toBe(0);
|
|
142
|
+
expect(result.current.handlerOffset.value).toBeCloseTo(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("handles large defaultIndex values", () => {
|
|
146
|
+
const props = createBaseProps({ defaultIndex: 10 });
|
|
147
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
148
|
+
|
|
149
|
+
expect(result.current.handlerOffset.value).toBe(-7000);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("returns zero size when vertical height is 0", () => {
|
|
153
|
+
const props = createBaseProps({ vertical: true, style: { height: 0 } });
|
|
154
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
155
|
+
|
|
156
|
+
expect(result.current.size).toBe(0);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("accepts floating point dimensions", () => {
|
|
160
|
+
const props = createBaseProps({ style: { width: 700.5 } });
|
|
161
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
162
|
+
|
|
163
|
+
expect(result.current.size).toBe(700.5);
|
|
164
|
+
expect(result.current.resolvedSize.value).toBe(700.5);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("stays pending when only height is provided", () => {
|
|
168
|
+
const props = createBaseProps({ style: { height: 200 } });
|
|
169
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
170
|
+
|
|
171
|
+
expect(result.current.size).toBe(0);
|
|
172
|
+
expect(result.current.sizePhase.value).toBe("pending");
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("itemWidth/itemHeight props", () => {
|
|
176
|
+
it("uses itemWidth for horizontal carousel size when provided", () => {
|
|
177
|
+
const props = createBaseProps({
|
|
178
|
+
style: { width: 700, height: 350 },
|
|
179
|
+
itemWidth: 350,
|
|
180
|
+
});
|
|
181
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
182
|
+
|
|
183
|
+
expect(result.current.size).toBe(350);
|
|
184
|
+
expect(result.current.resolvedSize.value).toBe(350);
|
|
185
|
+
expect(result.current.sizePhase.value).toBe("ready");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("uses itemHeight for vertical carousel size when provided", () => {
|
|
189
|
+
const props = createBaseProps({
|
|
190
|
+
vertical: true,
|
|
191
|
+
style: { width: 700, height: 350 },
|
|
192
|
+
itemHeight: 200,
|
|
193
|
+
});
|
|
194
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
195
|
+
|
|
196
|
+
expect(result.current.size).toBe(200);
|
|
197
|
+
expect(result.current.resolvedSize.value).toBe(200);
|
|
198
|
+
expect(result.current.sizePhase.value).toBe("ready");
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("prioritizes itemWidth over style.width for horizontal carousel", () => {
|
|
202
|
+
const props = createBaseProps({
|
|
203
|
+
style: { width: 700 },
|
|
204
|
+
itemWidth: 350,
|
|
205
|
+
});
|
|
206
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
207
|
+
|
|
208
|
+
expect(result.current.size).toBe(350);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("prioritizes itemHeight over style.height for vertical carousel", () => {
|
|
212
|
+
const props = createBaseProps({
|
|
213
|
+
vertical: true,
|
|
214
|
+
style: { height: 400 },
|
|
215
|
+
itemHeight: 200,
|
|
216
|
+
});
|
|
217
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
218
|
+
|
|
219
|
+
expect(result.current.size).toBe(200);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("prioritizes itemWidth over deprecated width prop", () => {
|
|
223
|
+
const props = createBaseProps({
|
|
224
|
+
width: 700,
|
|
225
|
+
itemWidth: 350,
|
|
226
|
+
});
|
|
227
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
228
|
+
|
|
229
|
+
expect(result.current.size).toBe(350);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("prefers style.width over deprecated width prop when itemWidth not provided", () => {
|
|
233
|
+
const props = createBaseProps({
|
|
234
|
+
width: 500,
|
|
235
|
+
});
|
|
236
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
237
|
+
|
|
238
|
+
expect(result.current.size).toBe(700);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it("prefers style.height over deprecated height prop when itemHeight not provided in vertical mode", () => {
|
|
242
|
+
const props = createBaseProps({
|
|
243
|
+
vertical: true,
|
|
244
|
+
height: 400,
|
|
245
|
+
});
|
|
246
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
247
|
+
|
|
248
|
+
expect(result.current.size).toBe(350);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("falls back to deprecated width prop when style.width is not provided", () => {
|
|
252
|
+
const props = createBaseProps({
|
|
253
|
+
style: {},
|
|
254
|
+
width: 500,
|
|
255
|
+
});
|
|
256
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
257
|
+
|
|
258
|
+
expect(result.current.size).toBe(500);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it("falls back to deprecated height prop when style.height is not provided (vertical mode)", () => {
|
|
262
|
+
const props = createBaseProps({
|
|
263
|
+
vertical: true,
|
|
264
|
+
style: {},
|
|
265
|
+
height: 400,
|
|
266
|
+
});
|
|
267
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
268
|
+
|
|
269
|
+
expect(result.current.size).toBe(400);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it("ignores zero or negative itemWidth", () => {
|
|
273
|
+
const props = createBaseProps({
|
|
274
|
+
style: { width: 700 },
|
|
275
|
+
itemWidth: 0,
|
|
276
|
+
});
|
|
277
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
278
|
+
|
|
279
|
+
expect(result.current.size).toBe(700);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("ignores zero or negative itemHeight", () => {
|
|
283
|
+
const props = createBaseProps({
|
|
284
|
+
vertical: true,
|
|
285
|
+
style: { height: 400 },
|
|
286
|
+
itemHeight: -10,
|
|
287
|
+
});
|
|
288
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
289
|
+
|
|
290
|
+
expect(result.current.size).toBe(400);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it("calculates handlerOffset correctly with itemWidth", () => {
|
|
294
|
+
const props = createBaseProps({
|
|
295
|
+
style: { width: 700 },
|
|
296
|
+
itemWidth: 350,
|
|
297
|
+
defaultIndex: 2,
|
|
298
|
+
});
|
|
299
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
300
|
+
|
|
301
|
+
// defaultIndex 2 * itemWidth 350 = -700
|
|
302
|
+
expect(result.current.handlerOffset.value).toBe(-700);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("updates resolvedSize when itemWidth changes", () => {
|
|
306
|
+
const initial = createBaseProps({ style: { width: 700 }, itemWidth: 350 });
|
|
307
|
+
const hook = renderHook(({ p }) => useCommonVariables(p), { initialProps: { p: initial } });
|
|
308
|
+
expect(hook.result.current.size).toBe(350);
|
|
309
|
+
expect(hook.result.current.resolvedSize.value).toBe(350);
|
|
310
|
+
|
|
311
|
+
const updated = createBaseProps({ style: { width: 700 }, itemWidth: 400 });
|
|
312
|
+
act(() => {
|
|
313
|
+
hook.rerender({ p: updated });
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// resolvedSize (SharedValue) updates immediately via useEffect
|
|
317
|
+
expect(hook.result.current.resolvedSize.value).toBe(400);
|
|
318
|
+
// size (state) updates asynchronously via useAnimatedReaction
|
|
319
|
+
// In test environment, this requires waiting for the animated reaction to fire
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe("sizeExplicit flag", () => {
|
|
324
|
+
it("sets sizeExplicit to true when itemWidth is provided for horizontal carousel", () => {
|
|
325
|
+
const props = createBaseProps({
|
|
326
|
+
style: { width: 700 },
|
|
327
|
+
itemWidth: 350,
|
|
328
|
+
});
|
|
329
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
330
|
+
|
|
331
|
+
expect(result.current.sizeExplicit).toBe(true);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("sets sizeExplicit to true when itemHeight is provided for vertical carousel", () => {
|
|
335
|
+
const props = createBaseProps({
|
|
336
|
+
vertical: true,
|
|
337
|
+
style: { height: 400 },
|
|
338
|
+
itemHeight: 200,
|
|
339
|
+
});
|
|
340
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
341
|
+
|
|
342
|
+
expect(result.current.sizeExplicit).toBe(true);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it("sets sizeExplicit to false when only style.width is provided", () => {
|
|
346
|
+
const props = createBaseProps({
|
|
347
|
+
style: { width: 700 },
|
|
348
|
+
});
|
|
349
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
350
|
+
|
|
351
|
+
expect(result.current.sizeExplicit).toBe(false);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it("sets sizeExplicit to false when only deprecated width prop is provided", () => {
|
|
355
|
+
const props = createBaseProps({
|
|
356
|
+
width: 700,
|
|
357
|
+
});
|
|
358
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
359
|
+
|
|
360
|
+
expect(result.current.sizeExplicit).toBe(false);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("sets sizeExplicit to false when itemWidth is zero", () => {
|
|
364
|
+
const props = createBaseProps({
|
|
365
|
+
style: { width: 700 },
|
|
366
|
+
itemWidth: 0,
|
|
367
|
+
});
|
|
368
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
369
|
+
|
|
370
|
+
expect(result.current.sizeExplicit).toBe(false);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it("sets sizeExplicit to false when itemHeight is negative", () => {
|
|
374
|
+
const props = createBaseProps({
|
|
375
|
+
vertical: true,
|
|
376
|
+
style: { height: 400 },
|
|
377
|
+
itemHeight: -10,
|
|
378
|
+
});
|
|
379
|
+
const { result } = renderHook(() => useCommonVariables(props));
|
|
380
|
+
|
|
381
|
+
expect(result.current.sizeExplicit).toBe(false);
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
});
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyleSheet } from "react-native";
|
|
3
|
+
import type { SharedValue } from "react-native-reanimated";
|
|
4
|
+
import { useAnimatedReaction, useSharedValue } from "react-native-reanimated";
|
|
5
|
+
import { scheduleOnRN } from "react-native-worklets";
|
|
6
|
+
|
|
7
|
+
import type { TInitializeCarouselProps } from "./useInitProps";
|
|
8
|
+
|
|
9
|
+
import { computeOffsetIfDataChanged } from "../utils/compute-offset-if-data-changed";
|
|
10
|
+
import { computeOffsetIfSizeChanged } from "../utils/compute-offset-if-size-changed";
|
|
11
|
+
import { handlerOffsetDirection } from "../utils/handleroffset-direction";
|
|
12
|
+
import { buildPrefixSum } from "../utils/size-resolver";
|
|
13
|
+
|
|
14
|
+
export type TCarouselSizePhase = "pending" | "ready" | "updating";
|
|
15
|
+
|
|
16
|
+
export interface ICommonVariables {
|
|
17
|
+
size: number;
|
|
18
|
+
validLength: number;
|
|
19
|
+
handlerOffset: SharedValue<number>;
|
|
20
|
+
resolvedSize: SharedValue<number | null>;
|
|
21
|
+
sizePhase: SharedValue<TCarouselSizePhase>;
|
|
22
|
+
sizeExplicit: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function useCommonVariables(props: TInitializeCarouselProps<any>): ICommonVariables {
|
|
26
|
+
const {
|
|
27
|
+
vertical,
|
|
28
|
+
style,
|
|
29
|
+
dataLength,
|
|
30
|
+
defaultIndex,
|
|
31
|
+
defaultScrollOffsetValue,
|
|
32
|
+
loop,
|
|
33
|
+
width: explicitWidth,
|
|
34
|
+
height: explicitHeight,
|
|
35
|
+
itemWidth: explicitItemWidth,
|
|
36
|
+
itemHeight: explicitItemHeight,
|
|
37
|
+
getItemSize,
|
|
38
|
+
variableSize,
|
|
39
|
+
} = props;
|
|
40
|
+
|
|
41
|
+
// Variable-size default offset: precompute the prefix up to `defaultIndex`
|
|
42
|
+
// so the carousel mounts already scrolled to the right starting position.
|
|
43
|
+
const variableDefaultOffset = React.useMemo(() => {
|
|
44
|
+
if (!variableSize || !getItemSize || dataLength <= 0) return null;
|
|
45
|
+
const built = buildPrefixSum(dataLength, getItemSize);
|
|
46
|
+
const clamped = Math.max(0, Math.min(dataLength - 1, defaultIndex));
|
|
47
|
+
return -built.prefix[clamped];
|
|
48
|
+
}, [variableSize, getItemSize, dataLength, defaultIndex]);
|
|
49
|
+
|
|
50
|
+
const manualSize = React.useMemo(() => {
|
|
51
|
+
const explicitPageSize = vertical ? explicitItemHeight : explicitItemWidth;
|
|
52
|
+
if (typeof explicitPageSize === "number" && explicitPageSize > 0) {
|
|
53
|
+
return explicitPageSize;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { width, height } = StyleSheet.flatten(style) || {};
|
|
57
|
+
const candidate = vertical ? height : width;
|
|
58
|
+
if (typeof candidate === "number" && candidate > 0) {
|
|
59
|
+
return candidate;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// NOTE: `width`/`height` props are deprecated in v5. They are still respected here to
|
|
63
|
+
// maintain backwards compatibility with v4-style usage. Prefer using `style` when both exist.
|
|
64
|
+
const explicitCandidate = vertical ? explicitHeight : explicitWidth;
|
|
65
|
+
if (typeof explicitCandidate === "number" && explicitCandidate > 0) {
|
|
66
|
+
return explicitCandidate;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return null;
|
|
70
|
+
}, [vertical, style, explicitWidth, explicitHeight, explicitItemHeight, explicitItemWidth]);
|
|
71
|
+
|
|
72
|
+
const resolvedSize = useSharedValue<number | null>(manualSize);
|
|
73
|
+
const sizePhase = useSharedValue<TCarouselSizePhase>(
|
|
74
|
+
variableSize ? "ready" : manualSize ? "ready" : "pending"
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Variable mode mounts already-ready: every item's size is known up-front,
|
|
78
|
+
// so we don't wait for an `onLayout` measurement to start positioning.
|
|
79
|
+
const defaultHandlerOffsetValue =
|
|
80
|
+
variableDefaultOffset !== null
|
|
81
|
+
? variableDefaultOffset
|
|
82
|
+
: manualSize
|
|
83
|
+
? -Math.abs(defaultIndex * manualSize)
|
|
84
|
+
: 0;
|
|
85
|
+
const _handlerOffset = useSharedValue<number>(defaultHandlerOffsetValue);
|
|
86
|
+
// Prefer the newer `scrollOffsetValue` name, but keep the legacy prop for compatibility.
|
|
87
|
+
const handlerOffset = props.scrollOffsetValue ?? defaultScrollOffsetValue ?? _handlerOffset;
|
|
88
|
+
const prevDataLength = useSharedValue(dataLength);
|
|
89
|
+
const prevSize = useSharedValue(manualSize ?? 0);
|
|
90
|
+
const sizeExplicit = React.useMemo(() => {
|
|
91
|
+
const explicitPageSize = vertical ? explicitItemHeight : explicitItemWidth;
|
|
92
|
+
return typeof explicitPageSize === "number" && explicitPageSize > 0;
|
|
93
|
+
}, [explicitItemHeight, explicitItemWidth, vertical]);
|
|
94
|
+
|
|
95
|
+
const [size, setSize] = React.useState<number>(manualSize ?? 0);
|
|
96
|
+
|
|
97
|
+
const syncSize = React.useCallback((next: number) => {
|
|
98
|
+
setSize((current) => (current === next ? current : next));
|
|
99
|
+
}, []);
|
|
100
|
+
|
|
101
|
+
useAnimatedReaction(
|
|
102
|
+
() => resolvedSize.value,
|
|
103
|
+
(current, previous) => {
|
|
104
|
+
if (current == null || current <= 0) return;
|
|
105
|
+
if (current !== previous) {
|
|
106
|
+
scheduleOnRN(syncSize, current);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
[syncSize]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
React.useEffect(() => {
|
|
113
|
+
if (manualSize && manualSize > 0) {
|
|
114
|
+
resolvedSize.value = manualSize;
|
|
115
|
+
sizePhase.value = "ready";
|
|
116
|
+
}
|
|
117
|
+
}, [manualSize, resolvedSize, sizePhase]);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* When data changes, we need to compute new index for handlerOffset
|
|
121
|
+
*/
|
|
122
|
+
useAnimatedReaction(
|
|
123
|
+
() => {
|
|
124
|
+
const previousLength = prevDataLength.value;
|
|
125
|
+
const currentLength = dataLength;
|
|
126
|
+
const isLengthChanged = previousLength !== currentLength;
|
|
127
|
+
const shouldComputed = isLengthChanged && loop;
|
|
128
|
+
|
|
129
|
+
if (shouldComputed) prevDataLength.value = dataLength;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
shouldComputed,
|
|
133
|
+
previousLength,
|
|
134
|
+
currentLength,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
({ shouldComputed, previousLength, currentLength }) => {
|
|
138
|
+
if (shouldComputed) {
|
|
139
|
+
// Variable-mode reflow is handled by useSizeResolver rebuilding the
|
|
140
|
+
// prefix table; the size-based handlerOffset adjustment doesn't apply.
|
|
141
|
+
if (variableSize) return;
|
|
142
|
+
|
|
143
|
+
// direction -> 1 | -1
|
|
144
|
+
const direction = handlerOffsetDirection(handlerOffset);
|
|
145
|
+
|
|
146
|
+
const _size = resolvedSize.value ?? 0;
|
|
147
|
+
if (_size <= 0) return;
|
|
148
|
+
|
|
149
|
+
handlerOffset.value = computeOffsetIfDataChanged({
|
|
150
|
+
direction,
|
|
151
|
+
previousLength,
|
|
152
|
+
currentLength,
|
|
153
|
+
size: _size,
|
|
154
|
+
handlerOffset: handlerOffset.value,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
[dataLength, loop, resolvedSize, variableSize]
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* When size changes, we need to compute new index for handlerOffset. This
|
|
163
|
+
* reaction is uniform-mode only — in variable-size mode, item positions come
|
|
164
|
+
* from the resolver's prefix table, not the scalar container size, so an
|
|
165
|
+
* onLayout-driven resize doesn't translate to a handlerOffset adjustment.
|
|
166
|
+
*/
|
|
167
|
+
useAnimatedReaction(
|
|
168
|
+
() => resolvedSize.value,
|
|
169
|
+
(currentSize) => {
|
|
170
|
+
if (variableSize) return;
|
|
171
|
+
if (currentSize == null || currentSize <= 0) return;
|
|
172
|
+
const previousSize = prevSize.value;
|
|
173
|
+
|
|
174
|
+
if (previousSize === currentSize) return;
|
|
175
|
+
|
|
176
|
+
sizePhase.value = previousSize > 0 ? "updating" : sizePhase.value;
|
|
177
|
+
|
|
178
|
+
if (previousSize <= 0) {
|
|
179
|
+
handlerOffset.value = -Math.abs(defaultIndex * currentSize);
|
|
180
|
+
} else {
|
|
181
|
+
handlerOffset.value = computeOffsetIfSizeChanged({
|
|
182
|
+
handlerOffset: handlerOffset.value,
|
|
183
|
+
prevSize: previousSize,
|
|
184
|
+
size: currentSize,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
prevSize.value = currentSize;
|
|
189
|
+
sizePhase.value = "ready";
|
|
190
|
+
},
|
|
191
|
+
[defaultIndex, resolvedSize, sizePhase, variableSize]
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
size,
|
|
196
|
+
validLength: dataLength - 1,
|
|
197
|
+
handlerOffset,
|
|
198
|
+
resolvedSize,
|
|
199
|
+
sizePhase,
|
|
200
|
+
sizeExplicit,
|
|
201
|
+
};
|
|
202
|
+
}
|