react-native-reanimated-carousel 4.0.0-alpha.5 → 4.0.0-alpha.6
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/lib/commonjs/{layouts → components}/BaseLayout.js +4 -2
- package/lib/commonjs/components/BaseLayout.js.map +1 -0
- package/lib/commonjs/components/Carousel.js +4 -3
- package/lib/commonjs/components/Carousel.js.map +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js +34 -30
- package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
- package/lib/commonjs/hooks/useLayoutConfig.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +9 -6
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.test.js +53 -0
- package/lib/commonjs/hooks/useOffsetX.test.js.map +1 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js +84 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/commonjs/hooks/usePanGestureProxy.test.js +397 -0
- package/lib/commonjs/hooks/usePanGestureProxy.test.js.map +1 -0
- package/lib/commonjs/hooks/useUpdateGestureConfig.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +17 -6
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.test.js +162 -0
- package/lib/commonjs/hooks/useVisibleRanges.test.js.map +1 -0
- package/lib/module/{layouts → components}/BaseLayout.js +4 -2
- package/lib/module/components/BaseLayout.js.map +1 -0
- package/lib/module/components/Carousel.js +3 -2
- package/lib/module/components/Carousel.js.map +1 -1
- package/lib/module/components/ScrollViewGesture.js +36 -31
- package/lib/module/components/ScrollViewGesture.js.map +1 -1
- package/lib/module/hooks/useLayoutConfig.js.map +1 -1
- package/lib/module/hooks/useOffsetX.js +9 -6
- package/lib/module/hooks/useOffsetX.js.map +1 -1
- package/lib/module/hooks/useOffsetX.test.js +48 -0
- package/lib/module/hooks/useOffsetX.test.js.map +1 -0
- package/lib/module/hooks/usePanGestureProxy.js +71 -0
- package/lib/module/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/module/hooks/usePanGestureProxy.test.js +383 -0
- package/lib/module/hooks/usePanGestureProxy.test.js.map +1 -0
- package/lib/module/hooks/useUpdateGestureConfig.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +17 -6
- package/lib/module/hooks/useVisibleRanges.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.test.js +157 -0
- package/lib/module/hooks/useVisibleRanges.test.js.map +1 -0
- package/lib/typescript/hooks/useLayoutConfig.d.ts +1 -1
- package/lib/typescript/hooks/useOffsetX.test.d.ts +1 -0
- package/lib/typescript/hooks/usePanGestureProxy.d.ts +9 -0
- package/lib/typescript/hooks/usePanGestureProxy.test.d.ts +1 -0
- package/lib/typescript/hooks/useUpdateGestureConfig.d.ts +3 -2
- package/lib/typescript/hooks/useVisibleRanges.d.ts +1 -0
- package/lib/typescript/hooks/useVisibleRanges.test.d.ts +1 -0
- package/lib/typescript/types.d.ts +5 -0
- package/package.json +2 -1
- package/src/{layouts → components}/BaseLayout.tsx +10 -8
- package/src/components/Carousel.tsx +2 -1
- package/src/components/ScrollViewGesture.tsx +48 -43
- package/src/hooks/useLayoutConfig.ts +1 -1
- package/src/hooks/useOffsetX.test.ts +54 -0
- package/src/hooks/useOffsetX.ts +33 -31
- package/src/hooks/usePanGestureProxy.test.tsx +377 -0
- package/src/hooks/usePanGestureProxy.ts +110 -0
- package/src/hooks/useUpdateGestureConfig.ts +4 -2
- package/src/hooks/useVisibleRanges.test.tsx +179 -0
- package/src/hooks/useVisibleRanges.tsx +23 -7
- package/src/types.ts +5 -0
- package/lib/commonjs/layouts/BaseLayout.js.map +0 -1
- package/lib/commonjs/layouts/ParallaxLayout.js +0 -84
- package/lib/commonjs/layouts/ParallaxLayout.js.map +0 -1
- package/lib/module/layouts/BaseLayout.js.map +0 -1
- package/lib/module/layouts/ParallaxLayout.js +0 -61
- package/lib/module/layouts/ParallaxLayout.js.map +0 -1
- package/lib/typescript/layouts/ParallaxLayout.d.ts +0 -13
- package/src/layouts/ParallaxLayout.tsx +0 -141
- /package/lib/typescript/{layouts → components}/BaseLayout.d.ts +0 -0
|
@@ -4,16 +4,27 @@ export function useVisibleRanges(options) {
|
|
|
4
4
|
total = 0,
|
|
5
5
|
viewSize,
|
|
6
6
|
translation,
|
|
7
|
-
windowSize: _windowSize = 0
|
|
7
|
+
windowSize: _windowSize = 0,
|
|
8
|
+
loop
|
|
8
9
|
} = options;
|
|
9
10
|
const windowSize = total <= _windowSize ? total : _windowSize;
|
|
10
11
|
const ranges = useDerivedValue(() => {
|
|
11
12
|
const positiveCount = Math.round(windowSize / 2);
|
|
12
13
|
const negativeCount = windowSize - positiveCount;
|
|
13
|
-
let
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
let currentIndex = Math.round(-translation.value / viewSize);
|
|
15
|
+
currentIndex = currentIndex < 0 ? currentIndex % total + total : currentIndex;
|
|
16
|
+
|
|
17
|
+
if (!loop) {
|
|
18
|
+
// Adjusting negative range if the carousel is not loopable.
|
|
19
|
+
// So, It will be only displayed the positive items.
|
|
20
|
+
return {
|
|
21
|
+
negativeRange: [0 + currentIndex - (windowSize - 1), 0 + currentIndex],
|
|
22
|
+
positiveRange: [0 + currentIndex, windowSize - 1 + currentIndex]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const negativeRange = [(currentIndex - negativeCount + total) % total, (currentIndex - 1 + total) % total];
|
|
27
|
+
const positiveRange = [(currentIndex + total) % total, (currentIndex + positiveCount + total) % total];
|
|
17
28
|
|
|
18
29
|
if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {
|
|
19
30
|
negativeRange[1] = total - 1;
|
|
@@ -29,7 +40,7 @@ export function useVisibleRanges(options) {
|
|
|
29
40
|
negativeRange,
|
|
30
41
|
positiveRange
|
|
31
42
|
};
|
|
32
|
-
}, [total, windowSize, translation]);
|
|
43
|
+
}, [loop, total, windowSize, translation]);
|
|
33
44
|
return ranges;
|
|
34
45
|
}
|
|
35
46
|
//# sourceMappingURL=useVisibleRanges.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useVisibleRanges.tsx"],"names":["useDerivedValue","useVisibleRanges","options","total","viewSize","translation","windowSize","_windowSize","ranges","positiveCount","Math","round","negativeCount","
|
|
1
|
+
{"version":3,"sources":["useVisibleRanges.tsx"],"names":["useDerivedValue","useVisibleRanges","options","total","viewSize","translation","windowSize","_windowSize","loop","ranges","positiveCount","Math","round","negativeCount","currentIndex","value","negativeRange","positiveRange"],"mappings":"AACA,SAASA,eAAT,QAAgC,yBAAhC;AAOA,OAAO,SAASC,gBAAT,CAA0BC,OAA1B,EAMY;AACjB,QAAM;AACJC,IAAAA,KAAK,GAAG,CADJ;AAEJC,IAAAA,QAFI;AAGJC,IAAAA,WAHI;AAIJC,IAAAA,UAAU,EAAEC,WAAW,GAAG,CAJtB;AAKJC,IAAAA;AALI,MAMFN,OANJ;AAQA,QAAMI,UAAU,GAAGH,KAAK,IAAII,WAAT,GAAuBJ,KAAvB,GAA+BI,WAAlD;AAEA,QAAME,MAAM,GAAGT,eAAe,CAAC,MAAM;AACnC,UAAMU,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWN,UAAU,GAAG,CAAxB,CAAtB;AACA,UAAMO,aAAa,GAAGP,UAAU,GAAGI,aAAnC;AAEA,QAAII,YAAY,GAAGH,IAAI,CAACC,KAAL,CAAW,CAACP,WAAW,CAACU,KAAb,GAAqBX,QAAhC,CAAnB;AACAU,IAAAA,YAAY,GAAGA,YAAY,GAAG,CAAf,GAAoBA,YAAY,GAAGX,KAAhB,GAAyBA,KAA5C,GAAoDW,YAAnE;;AAEA,QAAI,CAACN,IAAL,EAAW;AACT;AACA;AACA,aAAO;AACLQ,QAAAA,aAAa,EAAE,CAAC,IAAIF,YAAJ,IAAoBR,UAAU,GAAG,CAAjC,CAAD,EAAsC,IAAIQ,YAA1C,CADV;AAELG,QAAAA,aAAa,EAAE,CAAC,IAAIH,YAAL,EAAmBR,UAAU,GAAG,CAAb,GAAiBQ,YAApC;AAFV,OAAP;AAID;;AAED,UAAME,aAAa,GAAG,CACpB,CAACF,YAAY,GAAGD,aAAf,GAA+BV,KAAhC,IAAyCA,KADrB,EAEpB,CAACW,YAAY,GAAG,CAAf,GAAmBX,KAApB,IAA6BA,KAFT,CAAtB;AAKA,UAAMc,aAAa,GAAG,CACpB,CAACH,YAAY,GAAGX,KAAhB,IAAyBA,KADL,EAEpB,CAACW,YAAY,GAAGJ,aAAf,GAA+BP,KAAhC,IAAyCA,KAFrB,CAAtB;;AAKA,QAAIa,aAAa,CAAC,CAAD,CAAb,GAAmBb,KAAnB,IAA4Ba,aAAa,CAAC,CAAD,CAAb,GAAmBA,aAAa,CAAC,CAAD,CAAhE,EAAqE;AACnEA,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmBb,KAAK,GAAG,CAA3B;AACAc,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmB,CAAnB;AACD;;AACD,QAAIA,aAAa,CAAC,CAAD,CAAb,GAAmBA,aAAa,CAAC,CAAD,CAApC,EAAyC;AACvCD,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmBb,KAAK,GAAG,CAA3B;AACAc,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmB,CAAnB;AACD;;AAED,WAAO;AAAED,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,KAAP;AACD,GApC6B,EAoC3B,CAACT,IAAD,EAAOL,KAAP,EAAcG,UAAd,EAA0BD,WAA1B,CApC2B,CAA9B;AAsCA,SAAOI,MAAP;AACD","sourcesContent":["import type Animated from \"react-native-reanimated\";\nimport { useDerivedValue } from \"react-native-reanimated\";\n\nexport type IVisibleRanges = Animated.SharedValue<{\n negativeRange: number[]\n positiveRange: number[]\n}>;\n\nexport function useVisibleRanges(options: {\n total: number\n viewSize: number\n windowSize?: number\n translation: Animated.SharedValue<number>\n loop?: boolean\n}): IVisibleRanges {\n const {\n total = 0,\n viewSize,\n translation,\n windowSize: _windowSize = 0,\n loop,\n } = options;\n\n const windowSize = total <= _windowSize ? total : _windowSize;\n\n const ranges = useDerivedValue(() => {\n const positiveCount = Math.round(windowSize / 2);\n const negativeCount = windowSize - positiveCount;\n\n let currentIndex = Math.round(-translation.value / viewSize);\n currentIndex = currentIndex < 0 ? (currentIndex % total) + total : currentIndex;\n\n if (!loop) {\n // Adjusting negative range if the carousel is not loopable.\n // So, It will be only displayed the positive items.\n return {\n negativeRange: [0 + currentIndex - (windowSize - 1), 0 + currentIndex],\n positiveRange: [0 + currentIndex, windowSize - 1 + currentIndex],\n };\n }\n\n const negativeRange = [\n (currentIndex - negativeCount + total) % total,\n (currentIndex - 1 + total) % total,\n ];\n\n const positiveRange = [\n (currentIndex + total) % total,\n (currentIndex + positiveCount + total) % total,\n ];\n\n if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {\n negativeRange[1] = total - 1;\n positiveRange[0] = 0;\n }\n if (positiveRange[0] > positiveRange[1]) {\n negativeRange[1] = total - 1;\n positiveRange[0] = 0;\n }\n\n return { negativeRange, positiveRange };\n }, [loop, total, windowSize, translation]);\n\n return ranges;\n}\n"]}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { useSharedValue } from "react-native-reanimated";
|
|
2
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
3
|
+
import { useVisibleRanges } from "./useVisibleRanges";
|
|
4
|
+
const viewSize = 393;
|
|
5
|
+
describe("useVisibleRanges", () => {
|
|
6
|
+
it("should only display the front of the list when loop is false", async () => {
|
|
7
|
+
const hook = renderHook(() => {
|
|
8
|
+
const translation = useSharedValue(-0);
|
|
9
|
+
const range = useVisibleRanges({
|
|
10
|
+
total: 10,
|
|
11
|
+
translation,
|
|
12
|
+
viewSize,
|
|
13
|
+
windowSize: 4,
|
|
14
|
+
loop: false
|
|
15
|
+
});
|
|
16
|
+
return range;
|
|
17
|
+
});
|
|
18
|
+
const expected = hook.result.current.value;
|
|
19
|
+
expect(expected).toMatchInlineSnapshot(`
|
|
20
|
+
{
|
|
21
|
+
"negativeRange": [
|
|
22
|
+
-3,
|
|
23
|
+
0,
|
|
24
|
+
],
|
|
25
|
+
"positiveRange": [
|
|
26
|
+
0,
|
|
27
|
+
3,
|
|
28
|
+
],
|
|
29
|
+
}
|
|
30
|
+
`);
|
|
31
|
+
});
|
|
32
|
+
it("should display the rear of the list and the front of the list when loop is true", async () => {
|
|
33
|
+
const hook = renderHook(() => {
|
|
34
|
+
const translation = useSharedValue(-0);
|
|
35
|
+
const range = useVisibleRanges({
|
|
36
|
+
total: 10,
|
|
37
|
+
translation,
|
|
38
|
+
viewSize,
|
|
39
|
+
windowSize: 4,
|
|
40
|
+
loop: true
|
|
41
|
+
});
|
|
42
|
+
return range;
|
|
43
|
+
});
|
|
44
|
+
const expected = hook.result.current.value;
|
|
45
|
+
expect(expected).toMatchInlineSnapshot(`
|
|
46
|
+
{
|
|
47
|
+
"negativeRange": [
|
|
48
|
+
8,
|
|
49
|
+
9,
|
|
50
|
+
],
|
|
51
|
+
"positiveRange": [
|
|
52
|
+
0,
|
|
53
|
+
2,
|
|
54
|
+
],
|
|
55
|
+
}
|
|
56
|
+
`);
|
|
57
|
+
});
|
|
58
|
+
it("should shows the increased range of the list when the loop is false and swiped the carousel.", async () => {
|
|
59
|
+
const slide0hook = renderHook(() => {
|
|
60
|
+
const translation = useSharedValue(-0 * viewSize);
|
|
61
|
+
const range = useVisibleRanges({
|
|
62
|
+
total: 10,
|
|
63
|
+
translation,
|
|
64
|
+
viewSize,
|
|
65
|
+
windowSize: 4,
|
|
66
|
+
loop: false
|
|
67
|
+
});
|
|
68
|
+
return range;
|
|
69
|
+
}).result.current.value;
|
|
70
|
+
const slide1hook = renderHook(() => {
|
|
71
|
+
const translation = useSharedValue(-1 * viewSize);
|
|
72
|
+
const range = useVisibleRanges({
|
|
73
|
+
total: 10,
|
|
74
|
+
translation,
|
|
75
|
+
viewSize,
|
|
76
|
+
windowSize: 4,
|
|
77
|
+
loop: false
|
|
78
|
+
});
|
|
79
|
+
return range;
|
|
80
|
+
}).result.current.value;
|
|
81
|
+
const slide2hook = renderHook(() => {
|
|
82
|
+
const translation = useSharedValue(-2 * viewSize);
|
|
83
|
+
const range = useVisibleRanges({
|
|
84
|
+
total: 10,
|
|
85
|
+
translation,
|
|
86
|
+
viewSize,
|
|
87
|
+
windowSize: 4,
|
|
88
|
+
loop: false
|
|
89
|
+
});
|
|
90
|
+
return range;
|
|
91
|
+
}).result.current.value;
|
|
92
|
+
const slide3hook = renderHook(() => {
|
|
93
|
+
const translation = useSharedValue(-3 * viewSize);
|
|
94
|
+
const range = useVisibleRanges({
|
|
95
|
+
total: 10,
|
|
96
|
+
translation,
|
|
97
|
+
viewSize,
|
|
98
|
+
windowSize: 4,
|
|
99
|
+
loop: false
|
|
100
|
+
});
|
|
101
|
+
return range;
|
|
102
|
+
}).result.current.value; // [0,3] Display the 0,1,2,3 items.
|
|
103
|
+
|
|
104
|
+
expect(slide0hook).toMatchInlineSnapshot(`
|
|
105
|
+
{
|
|
106
|
+
"negativeRange": [
|
|
107
|
+
-3,
|
|
108
|
+
0,
|
|
109
|
+
],
|
|
110
|
+
"positiveRange": [
|
|
111
|
+
0,
|
|
112
|
+
3,
|
|
113
|
+
],
|
|
114
|
+
}
|
|
115
|
+
`); // [1,4] Display the 1,2,3,4 items.
|
|
116
|
+
|
|
117
|
+
expect(slide1hook).toMatchInlineSnapshot(`
|
|
118
|
+
{
|
|
119
|
+
"negativeRange": [
|
|
120
|
+
-2,
|
|
121
|
+
1,
|
|
122
|
+
],
|
|
123
|
+
"positiveRange": [
|
|
124
|
+
1,
|
|
125
|
+
4,
|
|
126
|
+
],
|
|
127
|
+
}
|
|
128
|
+
`); // [2,5] Display the 2,3,4,5 items.
|
|
129
|
+
|
|
130
|
+
expect(slide2hook).toMatchInlineSnapshot(`
|
|
131
|
+
{
|
|
132
|
+
"negativeRange": [
|
|
133
|
+
-1,
|
|
134
|
+
2,
|
|
135
|
+
],
|
|
136
|
+
"positiveRange": [
|
|
137
|
+
2,
|
|
138
|
+
5,
|
|
139
|
+
],
|
|
140
|
+
}
|
|
141
|
+
`); // [3.6] Display the 3,4,5,6 items.
|
|
142
|
+
|
|
143
|
+
expect(slide3hook).toMatchInlineSnapshot(`
|
|
144
|
+
{
|
|
145
|
+
"negativeRange": [
|
|
146
|
+
0,
|
|
147
|
+
3,
|
|
148
|
+
],
|
|
149
|
+
"positiveRange": [
|
|
150
|
+
3,
|
|
151
|
+
6,
|
|
152
|
+
],
|
|
153
|
+
}
|
|
154
|
+
`);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=useVisibleRanges.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["useVisibleRanges.test.tsx"],"names":["useSharedValue","renderHook","useVisibleRanges","viewSize","describe","it","hook","translation","range","total","windowSize","loop","expected","result","current","value","expect","toMatchInlineSnapshot","slide0hook","slide1hook","slide2hook","slide3hook"],"mappings":"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","sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { renderHook } from \"@testing-library/react-hooks\";\n\nimport { useVisibleRanges } from \"./useVisibleRanges\";\n\nconst viewSize = 393;\n\ndescribe(\"useVisibleRanges\", () => {\n it(\"should only display the front of the list when loop is false\", async () => {\n const hook = renderHook(() => {\n const translation = useSharedValue(-0);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: false,\n });\n\n return range;\n });\n\n const expected = hook.result.current.value;\n\n expect(expected).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n -3,\n 0,\n ],\n \"positiveRange\": [\n 0,\n 3,\n ],\n }\n `);\n });\n\n it(\"should display the rear of the list and the front of the list when loop is true\", async () => {\n const hook = renderHook(() => {\n const translation = useSharedValue(-0);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: true,\n });\n\n return range;\n });\n\n const expected = hook.result.current.value;\n\n expect(expected).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n 8,\n 9,\n ],\n \"positiveRange\": [\n 0,\n 2,\n ],\n }\n `);\n });\n\n it(\"should shows the increased range of the list when the loop is false and swiped the carousel.\", async () => {\n const slide0hook = renderHook(() => {\n const translation = useSharedValue(-0 * viewSize);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: false,\n });\n\n return range;\n }).result.current.value;\n\n const slide1hook = renderHook(() => {\n const translation = useSharedValue(-1 * viewSize);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: false,\n });\n\n return range;\n }).result.current.value;\n\n const slide2hook = renderHook(() => {\n const translation = useSharedValue(-2 * viewSize);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: false,\n });\n\n return range;\n }).result.current.value;\n\n const slide3hook = renderHook(() => {\n const translation = useSharedValue(-3 * viewSize);\n const range = useVisibleRanges({\n total: 10,\n translation,\n viewSize,\n windowSize: 4,\n loop: false,\n });\n\n return range;\n }).result.current.value;\n\n // [0,3] Display the 0,1,2,3 items.\n expect(slide0hook).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n -3,\n 0,\n ],\n \"positiveRange\": [\n 0,\n 3,\n ],\n }\n `);\n\n // [1,4] Display the 1,2,3,4 items.\n expect(slide1hook).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n -2,\n 1,\n ],\n \"positiveRange\": [\n 1,\n 4,\n ],\n }\n `);\n\n // [2,5] Display the 2,3,4,5 items.\n expect(slide2hook).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n -1,\n 2,\n ],\n \"positiveRange\": [\n 2,\n 5,\n ],\n }\n `);\n\n // [3.6] Display the 3,4,5,6 items.\n expect(slide3hook).toMatchInlineSnapshot(`\n {\n \"negativeRange\": [\n 0,\n 3,\n ],\n \"positiveRange\": [\n 3,\n 6,\n ],\n }\n `);\n });\n});\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TInitializeCarouselProps } from "./useInitProps";
|
|
2
|
-
import type { TAnimationStyle } from "../
|
|
2
|
+
import type { TAnimationStyle } from "../components/BaseLayout";
|
|
3
3
|
declare type TLayoutConfigOpts<T> = TInitializeCarouselProps<T> & {
|
|
4
4
|
size: number;
|
|
5
5
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GestureStateChangeEvent, GestureUpdateEvent, PanGesture, PanGestureHandlerEventPayload } from "react-native-gesture-handler";
|
|
2
|
+
import type { GestureConfig } from "./useUpdateGestureConfig";
|
|
3
|
+
export declare const usePanGestureProxy: (customization: {
|
|
4
|
+
onConfigurePanGesture?: ((gesture: PanGesture) => void) | undefined;
|
|
5
|
+
onGestureBegin: (event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
|
6
|
+
onGestureUpdate: (event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => void;
|
|
7
|
+
onGestureEnd: (event: GestureStateChangeEvent<PanGestureHandlerEventPayload>, success: boolean) => void;
|
|
8
|
+
options?: GestureConfig | undefined;
|
|
9
|
+
}) => import("react-native-gesture-handler/lib/typescript/handlers/gestures/panGesture").PanGesture;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PanGesture } from "react-native-gesture-handler";
|
|
2
|
-
export
|
|
2
|
+
export interface GestureConfig {
|
|
3
3
|
enabled?: boolean;
|
|
4
|
-
}
|
|
4
|
+
}
|
|
5
|
+
export declare const useUpdateGestureConfig: (gesture: PanGesture, config: GestureConfig) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -141,6 +141,11 @@ export declare type TCarouselProps<T = any> = {
|
|
|
141
141
|
* props.vertical = false => maxScrollDistancePerSwipeX
|
|
142
142
|
* */
|
|
143
143
|
maxScrollDistancePerSwipe?: number;
|
|
144
|
+
/**
|
|
145
|
+
* @experimental This API will be changed in the future.
|
|
146
|
+
* If positive, the carousel will scroll to the positive direction and vice versa.
|
|
147
|
+
* */
|
|
148
|
+
fixedDirection?: "positive" | "negative";
|
|
144
149
|
/**
|
|
145
150
|
* Custom carousel config.
|
|
146
151
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-reanimated-carousel",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.6",
|
|
4
4
|
"description": "Simple carousel component.fully implemented using Reanimated 2.Infinitely scrolling, very smooth.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"del-cli": "^5.0.0",
|
|
64
64
|
"eslint": "^8.26.0",
|
|
65
65
|
"eslint-config-prettier": "^7.0.0",
|
|
66
|
+
"eslint-plugin-jest": "^27.6.0",
|
|
66
67
|
"eslint-plugin-prettier": "^3.1.3",
|
|
67
68
|
"gifify": "^2.4.3",
|
|
68
69
|
"husky": "^4.2.5",
|
|
@@ -8,13 +8,13 @@ import Animated, {
|
|
|
8
8
|
useDerivedValue,
|
|
9
9
|
} from "react-native-reanimated";
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import { LazyView } from "./LazyView";
|
|
12
12
|
|
|
13
|
-
import { LazyView } from "../components/LazyView";
|
|
14
13
|
import { useCheckMounted } from "../hooks/useCheckMounted";
|
|
15
14
|
import type { IOpts } from "../hooks/useOffsetX";
|
|
16
15
|
import { useOffsetX } from "../hooks/useOffsetX";
|
|
17
16
|
import type { IVisibleRanges } from "../hooks/useVisibleRanges";
|
|
17
|
+
import type { ILayoutConfig } from "../layouts/stack";
|
|
18
18
|
import { CTX } from "../store";
|
|
19
19
|
|
|
20
20
|
export type TAnimationStyle = (value: number) => AnimatedStyleProp<ViewStyle>;
|
|
@@ -30,7 +30,7 @@ export const BaseLayout: React.FC<{
|
|
|
30
30
|
}> = (props) => {
|
|
31
31
|
const mounted = useCheckMounted();
|
|
32
32
|
const { handlerOffset, index, children, visibleRanges, animationStyle }
|
|
33
|
-
|
|
33
|
+
= props;
|
|
34
34
|
|
|
35
35
|
const context = React.useContext(CTX);
|
|
36
36
|
const {
|
|
@@ -73,17 +73,19 @@ export const BaseLayout: React.FC<{
|
|
|
73
73
|
const x = useOffsetX(offsetXConfig, visibleRanges);
|
|
74
74
|
const animationValue = useDerivedValue(() => x.value / size, [x, size]);
|
|
75
75
|
const animatedStyle = useAnimatedStyle(
|
|
76
|
-
() =>
|
|
76
|
+
() => {
|
|
77
|
+
return animationStyle(x.value / size);
|
|
78
|
+
},
|
|
77
79
|
[animationStyle],
|
|
78
80
|
);
|
|
79
81
|
|
|
80
82
|
const updateView = React.useCallback(
|
|
81
83
|
(negativeRange: number[], positiveRange: number[]) => {
|
|
82
84
|
mounted.current
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
&& setShouldUpdate(
|
|
86
|
+
(index >= negativeRange[0] && index <= negativeRange[1])
|
|
87
|
+
|| (index >= positiveRange[0] && index <= positiveRange[1]),
|
|
88
|
+
);
|
|
87
89
|
},
|
|
88
90
|
[index, mounted],
|
|
89
91
|
);
|
|
@@ -3,6 +3,7 @@ import { StyleSheet } from "react-native";
|
|
|
3
3
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
4
4
|
import { runOnJS, useDerivedValue } from "react-native-reanimated";
|
|
5
5
|
|
|
6
|
+
import { BaseLayout } from "./BaseLayout";
|
|
6
7
|
import { ScrollViewGesture } from "./ScrollViewGesture";
|
|
7
8
|
|
|
8
9
|
import { useAutoPlay } from "../hooks/useAutoPlay";
|
|
@@ -13,7 +14,6 @@ import { useLayoutConfig } from "../hooks/useLayoutConfig";
|
|
|
13
14
|
import { useOnProgressChange } from "../hooks/useOnProgressChange";
|
|
14
15
|
import { usePropsErrorBoundary } from "../hooks/usePropsErrorBoundary";
|
|
15
16
|
import { useVisibleRanges } from "../hooks/useVisibleRanges";
|
|
16
|
-
import { BaseLayout } from "../layouts/BaseLayout";
|
|
17
17
|
import { CTX } from "../store";
|
|
18
18
|
import type { ICarouselInstance, TCarouselProps } from "../types";
|
|
19
19
|
import { computedRealIndexWithAutoFillData } from "../utils/computed-with-auto-fill-data";
|
|
@@ -158,6 +158,7 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
|
|
|
158
158
|
viewSize: size,
|
|
159
159
|
translation: handlerOffset,
|
|
160
160
|
windowSize,
|
|
161
|
+
loop,
|
|
161
162
|
});
|
|
162
163
|
|
|
163
164
|
const layoutConfig = useLayoutConfig({ ...props, size });
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { PropsWithChildren } from "react";
|
|
2
|
-
import React, { useCallback
|
|
2
|
+
import React, { useCallback } from "react";
|
|
3
3
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
4
4
|
import type { GestureStateChangeEvent, PanGestureHandlerEventPayload } from "react-native-gesture-handler";
|
|
5
|
-
import {
|
|
6
|
-
Gesture,
|
|
7
|
-
GestureDetector,
|
|
8
|
-
} from "react-native-gesture-handler";
|
|
5
|
+
import { GestureDetector } from "react-native-gesture-handler";
|
|
9
6
|
import Animated, {
|
|
10
7
|
cancelAnimation,
|
|
11
8
|
measure,
|
|
@@ -18,7 +15,7 @@ import Animated, {
|
|
|
18
15
|
} from "react-native-reanimated";
|
|
19
16
|
|
|
20
17
|
import { Easing } from "../constants";
|
|
21
|
-
import {
|
|
18
|
+
import { usePanGestureProxy } from "../hooks/usePanGestureProxy";
|
|
22
19
|
import { CTX } from "../store";
|
|
23
20
|
import type { WithTimingAnimation } from "../types";
|
|
24
21
|
import { dealWithAnimation } from "../utils/deal-with-animation";
|
|
@@ -42,13 +39,14 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
42
39
|
vertical,
|
|
43
40
|
pagingEnabled,
|
|
44
41
|
snapEnabled,
|
|
45
|
-
loop
|
|
42
|
+
loop,
|
|
46
43
|
scrollAnimationDuration,
|
|
47
44
|
withAnimation,
|
|
48
45
|
enabled,
|
|
49
46
|
dataLength,
|
|
50
47
|
overscrollEnabled,
|
|
51
48
|
maxScrollDistancePerSwipe,
|
|
49
|
+
fixedDirection,
|
|
52
50
|
},
|
|
53
51
|
} = React.useContext(CTX);
|
|
54
52
|
|
|
@@ -78,7 +76,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
78
76
|
const getLimit = React.useCallback(() => {
|
|
79
77
|
"worklet";
|
|
80
78
|
|
|
81
|
-
if (!
|
|
79
|
+
if (!loop && !overscrollEnabled) {
|
|
82
80
|
const { width: containerWidth = 0 } = measure(containerRef);
|
|
83
81
|
|
|
84
82
|
// If the item's total width is less than the container's width, then there is no need to scroll.
|
|
@@ -90,7 +88,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
return dataLength * size;
|
|
93
|
-
}, [
|
|
91
|
+
}, [loop, size, dataLength, overscrollEnabled]);
|
|
94
92
|
|
|
95
93
|
const withSpring = React.useCallback(
|
|
96
94
|
(toValue: number, onFinished?: () => void) => {
|
|
@@ -141,7 +139,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
141
139
|
const computed = offset < 0 ? Math.ceil : Math.floor;
|
|
142
140
|
const page = computed(-translation.value / size);
|
|
143
141
|
|
|
144
|
-
if (
|
|
142
|
+
if (loop) {
|
|
145
143
|
const finalPage = page + offset;
|
|
146
144
|
finalTranslation = withSpring(withProcessTranslation(-finalPage * size), onFinished);
|
|
147
145
|
}
|
|
@@ -161,7 +159,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
161
159
|
translation.value = finalTranslation;
|
|
162
160
|
|
|
163
161
|
function withProcessTranslation(translation: number) {
|
|
164
|
-
if (!
|
|
162
|
+
if (!loop && !overscrollEnabled) {
|
|
165
163
|
const limit = getLimit();
|
|
166
164
|
const sign = Math.sign(translation);
|
|
167
165
|
return sign * Math.max(0, Math.min(limit, Math.abs(translation)));
|
|
@@ -174,7 +172,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
174
172
|
withSpring,
|
|
175
173
|
size,
|
|
176
174
|
maxPage,
|
|
177
|
-
|
|
175
|
+
loop,
|
|
178
176
|
snapEnabled,
|
|
179
177
|
translation,
|
|
180
178
|
pagingEnabled,
|
|
@@ -215,7 +213,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
215
213
|
activeDecay();
|
|
216
214
|
return;
|
|
217
215
|
}
|
|
218
|
-
if (!
|
|
216
|
+
if (!loop) {
|
|
219
217
|
translation.value = withSpring(0);
|
|
220
218
|
return;
|
|
221
219
|
}
|
|
@@ -226,7 +224,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
226
224
|
activeDecay();
|
|
227
225
|
return;
|
|
228
226
|
}
|
|
229
|
-
if (!
|
|
227
|
+
if (!loop)
|
|
230
228
|
translation.value = withSpring(-((maxPage - 1) * size));
|
|
231
229
|
}
|
|
232
230
|
}, [
|
|
@@ -235,7 +233,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
235
233
|
maxPage,
|
|
236
234
|
size,
|
|
237
235
|
scrollEndTranslation.value,
|
|
238
|
-
|
|
236
|
+
loop,
|
|
239
237
|
activeDecay,
|
|
240
238
|
withSpring,
|
|
241
239
|
]);
|
|
@@ -252,7 +250,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
252
250
|
function withProcessTranslation(translation: number) {
|
|
253
251
|
"worklet";
|
|
254
252
|
|
|
255
|
-
if (!
|
|
253
|
+
if (!loop && !overscrollEnabled) {
|
|
256
254
|
const limit = getLimit();
|
|
257
255
|
const sign = Math.sign(translation);
|
|
258
256
|
return sign * Math.max(0, Math.min(limit, Math.abs(translation)));
|
|
@@ -261,7 +259,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
261
259
|
return translation;
|
|
262
260
|
}
|
|
263
261
|
|
|
264
|
-
const onGestureBegin = useCallback(() => {
|
|
262
|
+
const onGestureBegin = useCallback((_: PanGestureHandlerEventPayload) => {
|
|
265
263
|
"worklet";
|
|
266
264
|
|
|
267
265
|
touching.value = true;
|
|
@@ -269,7 +267,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
269
267
|
onScrollBegin && runOnJS(onScrollBegin)();
|
|
270
268
|
|
|
271
269
|
max.value = (maxPage - 1) * size;
|
|
272
|
-
if (!
|
|
270
|
+
if (!loop && !overscrollEnabled)
|
|
273
271
|
max.value = getLimit();
|
|
274
272
|
|
|
275
273
|
panOffset.value = translation.value;
|
|
@@ -277,7 +275,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
277
275
|
max,
|
|
278
276
|
size,
|
|
279
277
|
maxPage,
|
|
280
|
-
|
|
278
|
+
loop,
|
|
281
279
|
touching,
|
|
282
280
|
panOffset,
|
|
283
281
|
validStart,
|
|
@@ -296,10 +294,18 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
296
294
|
}
|
|
297
295
|
touching.value = true;
|
|
298
296
|
const { translationX, translationY } = e;
|
|
299
|
-
|
|
297
|
+
|
|
298
|
+
let panTranslation = isHorizontal.value
|
|
300
299
|
? translationX
|
|
301
300
|
: translationY;
|
|
302
|
-
|
|
301
|
+
|
|
302
|
+
if (fixedDirection === "negative")
|
|
303
|
+
panTranslation = -Math.abs(panTranslation);
|
|
304
|
+
|
|
305
|
+
else if (fixedDirection === "positive")
|
|
306
|
+
panTranslation = +Math.abs(panTranslation);
|
|
307
|
+
|
|
308
|
+
if (!loop) {
|
|
303
309
|
if ((translation.value > 0 || translation.value < -max.value)) {
|
|
304
310
|
const boundary = translation.value > 0 ? 0 : -max.value;
|
|
305
311
|
const fixed = boundary - panOffset.value;
|
|
@@ -315,24 +321,34 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
315
321
|
isHorizontal,
|
|
316
322
|
max,
|
|
317
323
|
panOffset,
|
|
318
|
-
|
|
324
|
+
loop,
|
|
319
325
|
overscrollEnabled,
|
|
326
|
+
fixedDirection,
|
|
320
327
|
translation,
|
|
321
328
|
validStart,
|
|
322
329
|
touching,
|
|
323
330
|
]);
|
|
324
331
|
|
|
325
|
-
const
|
|
332
|
+
const onGestureEnd = useCallback((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>, _success: boolean) => {
|
|
326
333
|
"worklet";
|
|
327
334
|
|
|
328
335
|
const { velocityX, velocityY, translationX, translationY } = e;
|
|
329
336
|
scrollEndVelocity.value = isHorizontal.value
|
|
330
337
|
? velocityX
|
|
331
338
|
: velocityY;
|
|
332
|
-
|
|
339
|
+
|
|
340
|
+
let panTranslation = isHorizontal.value
|
|
333
341
|
? translationX
|
|
334
342
|
: translationY;
|
|
335
343
|
|
|
344
|
+
if (fixedDirection === "negative")
|
|
345
|
+
panTranslation = -Math.abs(panTranslation);
|
|
346
|
+
|
|
347
|
+
else if (fixedDirection === "positive")
|
|
348
|
+
panTranslation = +Math.abs(panTranslation);
|
|
349
|
+
|
|
350
|
+
scrollEndTranslation.value = panTranslation;
|
|
351
|
+
|
|
336
352
|
const totalTranslation = scrollEndVelocity.value + scrollEndTranslation.value;
|
|
337
353
|
|
|
338
354
|
if (maxScrollDistancePerSwipeIsSet && Math.abs(totalTranslation) > maxScrollDistancePerSwipe) {
|
|
@@ -343,17 +359,18 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
343
359
|
endWithSpring(onScrollEnd);
|
|
344
360
|
}
|
|
345
361
|
|
|
346
|
-
if (!
|
|
362
|
+
if (!loop)
|
|
347
363
|
touching.value = false;
|
|
348
364
|
}, [
|
|
349
365
|
size,
|
|
350
|
-
|
|
366
|
+
loop,
|
|
351
367
|
touching,
|
|
352
368
|
panOffset,
|
|
353
369
|
translation,
|
|
354
370
|
isHorizontal,
|
|
355
371
|
scrollEndVelocity,
|
|
356
372
|
scrollEndTranslation,
|
|
373
|
+
fixedDirection,
|
|
357
374
|
maxScrollDistancePerSwipeIsSet,
|
|
358
375
|
maxScrollDistancePerSwipe,
|
|
359
376
|
endWithSpring,
|
|
@@ -361,25 +378,13 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
361
378
|
onScrollEnd,
|
|
362
379
|
]);
|
|
363
380
|
|
|
364
|
-
const gesture =
|
|
365
|
-
|
|
366
|
-
.onBegin(onGestureBegin)
|
|
367
|
-
.onUpdate(onGestureUpdate)
|
|
368
|
-
.onEnd(onGestureFinish);
|
|
369
|
-
|
|
370
|
-
if (onConfigurePanGesture)
|
|
371
|
-
onConfigurePanGesture(gesture);
|
|
372
|
-
|
|
373
|
-
return gesture;
|
|
374
|
-
},
|
|
375
|
-
[
|
|
381
|
+
const gesture = usePanGestureProxy({
|
|
382
|
+
onConfigurePanGesture,
|
|
376
383
|
onGestureBegin,
|
|
377
384
|
onGestureUpdate,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
useUpdateGestureConfig(gesture, { enabled });
|
|
385
|
+
onGestureEnd,
|
|
386
|
+
options: { enabled },
|
|
387
|
+
});
|
|
383
388
|
|
|
384
389
|
return (
|
|
385
390
|
<GestureDetector gesture={gesture}>
|
|
@@ -2,8 +2,8 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import type { TInitializeCarouselProps } from "./useInitProps";
|
|
4
4
|
|
|
5
|
+
import type { TAnimationStyle } from "../components/BaseLayout";
|
|
5
6
|
import { Layouts } from "../layouts";
|
|
6
|
-
import type { TAnimationStyle } from "../layouts/BaseLayout";
|
|
7
7
|
|
|
8
8
|
type TLayoutConfigOpts<T> = TInitializeCarouselProps<T> & { size: number };
|
|
9
9
|
|