react-native-reanimated-carousel 5.0.0-beta.6 → 5.0.0-beta.8

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.
Files changed (68) hide show
  1. package/README.md +32 -2
  2. package/lib/commonjs/components/CarouselLayout.js +1 -1
  3. package/lib/commonjs/components/CarouselLayout.js.map +1 -1
  4. package/lib/commonjs/components/ItemRenderer.js +1 -1
  5. package/lib/commonjs/components/ItemRenderer.js.map +1 -1
  6. package/lib/commonjs/components/ScrollViewGesture.js +1 -1
  7. package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
  8. package/lib/commonjs/hooks/useOnProgressChange.js +1 -1
  9. package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -1
  10. package/lib/commonjs/hooks/usePropsErrorBoundary.js +1 -1
  11. package/lib/commonjs/hooks/usePropsErrorBoundary.js.map +1 -1
  12. package/lib/commonjs/hooks/useVisibleRanges.js +1 -1
  13. package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
  14. package/lib/module/components/CarouselLayout.js +1 -1
  15. package/lib/module/components/CarouselLayout.js.map +1 -1
  16. package/lib/module/components/ItemRenderer.js +1 -1
  17. package/lib/module/components/ItemRenderer.js.map +1 -1
  18. package/lib/module/components/ScrollViewGesture.js +1 -1
  19. package/lib/module/components/ScrollViewGesture.js.map +1 -1
  20. package/lib/module/hooks/useOnProgressChange.js +1 -1
  21. package/lib/module/hooks/useOnProgressChange.js.map +1 -1
  22. package/lib/module/hooks/usePropsErrorBoundary.js +1 -1
  23. package/lib/module/hooks/usePropsErrorBoundary.js.map +1 -1
  24. package/lib/module/hooks/useVisibleRanges.js +1 -1
  25. package/lib/module/hooks/useVisibleRanges.js.map +1 -1
  26. package/lib/typescript/components/CarouselLayout.d.ts.map +1 -1
  27. package/lib/typescript/components/ItemRenderer.d.ts +1 -0
  28. package/lib/typescript/components/ItemRenderer.d.ts.map +1 -1
  29. package/lib/typescript/components/ScrollViewGesture.d.ts.map +1 -1
  30. package/lib/typescript/hooks/usePropsErrorBoundary.d.ts.map +1 -1
  31. package/lib/typescript/hooks/useVisibleRanges.d.ts +6 -0
  32. package/lib/typescript/hooks/useVisibleRanges.d.ts.map +1 -1
  33. package/lib/typescript/types.d.ts +1 -1
  34. package/package.json +4 -2
  35. package/src/components/CarouselLayout.tsx +4 -4
  36. package/src/components/ItemRenderer.tsx +11 -6
  37. package/src/components/ScrollViewGesture.tsx +8 -11
  38. package/src/hooks/useOnProgressChange.ts +1 -1
  39. package/src/hooks/usePropsErrorBoundary.ts +4 -3
  40. package/src/hooks/useVisibleRanges.tsx +80 -54
  41. package/src/types.ts +1 -1
  42. package/src/components/Carousel.test.tsx +0 -1215
  43. package/src/components/LazyView.test.tsx +0 -61
  44. package/src/components/Pagination/Pagination.test.tsx +0 -178
  45. package/src/components/rnr-demo.test.tsx +0 -53
  46. package/src/hooks/useAutoPlay.test.ts +0 -194
  47. package/src/hooks/useCarouselController.test.tsx +0 -1158
  48. package/src/hooks/useCheckMounted.test.ts +0 -47
  49. package/src/hooks/useCommonVariables.test.tsx +0 -384
  50. package/src/hooks/useInitProps.test.tsx +0 -134
  51. package/src/hooks/useLayoutConfig.test.tsx +0 -247
  52. package/src/hooks/useOffsetX.test.ts +0 -54
  53. package/src/hooks/useOnProgressChange.test.tsx +0 -207
  54. package/src/hooks/usePanGestureProxy.test.tsx +0 -368
  55. package/src/hooks/useUpdateGestureConfig.test.ts +0 -89
  56. package/src/hooks/useVisibleRanges.test.tsx +0 -347
  57. package/src/layouts/parallax.test.ts +0 -239
  58. package/src/layouts/stack.test.ts +0 -252
  59. package/src/store/index.test.tsx +0 -314
  60. package/src/utils/compute-gesture-translation.test.ts +0 -70
  61. package/src/utils/compute-offset-if-data-changed.test.ts +0 -133
  62. package/src/utils/compute-offset-if-size-changed.test.ts +0 -78
  63. package/src/utils/computed-with-auto-fill-data.test.ts +0 -298
  64. package/src/utils/deal-with-animation.test.ts +0 -181
  65. package/src/utils/handleroffset-direction.test.ts +0 -124
  66. package/src/utils/index.test.ts +0 -90
  67. package/src/utils/log.test.ts +0 -134
  68. package/src/utils/sanitize-animation-style.test.ts +0 -40
@@ -1,347 +0,0 @@
1
- import { useSharedValue } from "react-native-reanimated";
2
-
3
- import { renderHook } from "@testing-library/react-hooks";
4
-
5
- import { useVisibleRanges } from "./useVisibleRanges";
6
-
7
- const viewSize = 393;
8
-
9
- describe("useVisibleRanges", () => {
10
- it("should only display the front of the list when loop is false", async () => {
11
- const hook = renderHook(() => {
12
- const translation = useSharedValue(-0);
13
- const range = useVisibleRanges({
14
- total: 10,
15
- translation,
16
- viewSize,
17
- windowSize: 4,
18
- loop: false,
19
- });
20
-
21
- return range;
22
- });
23
-
24
- const expected = hook.result.current.value;
25
-
26
- expect(expected).toMatchInlineSnapshot(`
27
- {
28
- "negativeRange": [
29
- 0,
30
- 0,
31
- ],
32
- "positiveRange": [
33
- 0,
34
- 3,
35
- ],
36
- }
37
- `);
38
- });
39
-
40
- it("should display the rear of the list and the front of the list when loop is true", async () => {
41
- const hook = renderHook(() => {
42
- const translation = useSharedValue(-0);
43
- const range = useVisibleRanges({
44
- total: 10,
45
- translation,
46
- viewSize,
47
- windowSize: 4,
48
- loop: true,
49
- });
50
-
51
- return range;
52
- });
53
-
54
- const expected = hook.result.current.value;
55
-
56
- expect(expected).toMatchInlineSnapshot(`
57
- {
58
- "negativeRange": [
59
- 8,
60
- 9,
61
- ],
62
- "positiveRange": [
63
- 0,
64
- 2,
65
- ],
66
- }
67
- `);
68
- });
69
-
70
- it.each([
71
- { total: 1, windowSize: 1, currentIndex: 0 },
72
- { total: 2, windowSize: 5, currentIndex: 1 },
73
- { total: 3, windowSize: 3, currentIndex: 2 },
74
- { total: 4, windowSize: 5, currentIndex: 1 },
75
- ])(
76
- "should display every item when windowSize=$windowSize is at least total=$total in loop mode",
77
- ({ total, windowSize, currentIndex }) => {
78
- const ranges = renderHook(() => {
79
- const translation = useSharedValue(-currentIndex * viewSize);
80
- return useVisibleRanges({
81
- total,
82
- translation,
83
- viewSize,
84
- windowSize,
85
- loop: true,
86
- });
87
- }).result.current.value;
88
-
89
- const visibleIndexes = Array.from({ length: total }, (_, index) => index).filter(
90
- (index) =>
91
- (index >= ranges.negativeRange[0] && index <= ranges.negativeRange[1]) ||
92
- (index >= ranges.positiveRange[0] && index <= ranges.positiveRange[1])
93
- );
94
-
95
- expect(visibleIndexes).toEqual(Array.from({ length: total }, (_, index) => index));
96
- }
97
- );
98
-
99
- it("should shows the increased range of the list when the loop is false and swiped the carousel.", async () => {
100
- const slide0hook = renderHook(() => {
101
- const translation = useSharedValue(-0 * viewSize);
102
- const range = useVisibleRanges({
103
- total: 10,
104
- translation,
105
- viewSize,
106
- windowSize: 4,
107
- loop: false,
108
- });
109
-
110
- return range;
111
- }).result.current.value;
112
-
113
- const slide1hook = renderHook(() => {
114
- const translation = useSharedValue(-1 * viewSize);
115
- const range = useVisibleRanges({
116
- total: 10,
117
- translation,
118
- viewSize,
119
- windowSize: 4,
120
- loop: false,
121
- });
122
-
123
- return range;
124
- }).result.current.value;
125
-
126
- const slide2hook = renderHook(() => {
127
- const translation = useSharedValue(-2 * viewSize);
128
- const range = useVisibleRanges({
129
- total: 10,
130
- translation,
131
- viewSize,
132
- windowSize: 4,
133
- loop: false,
134
- });
135
-
136
- return range;
137
- }).result.current.value;
138
-
139
- const slide3hook = renderHook(() => {
140
- const translation = useSharedValue(-3 * viewSize);
141
- const range = useVisibleRanges({
142
- total: 10,
143
- translation,
144
- viewSize,
145
- windowSize: 4,
146
- loop: false,
147
- });
148
-
149
- return range;
150
- }).result.current.value;
151
-
152
- // [0,3] Display the 0,1,2,3 items.
153
- expect(slide0hook).toMatchInlineSnapshot(`
154
- {
155
- "negativeRange": [
156
- 0,
157
- 0,
158
- ],
159
- "positiveRange": [
160
- 0,
161
- 3,
162
- ],
163
- }
164
- `);
165
-
166
- // [1,4] Display the 1,2,3,4 items.
167
- expect(slide1hook).toMatchInlineSnapshot(`
168
- {
169
- "negativeRange": [
170
- 0,
171
- 1,
172
- ],
173
- "positiveRange": [
174
- 1,
175
- 4,
176
- ],
177
- }
178
- `);
179
-
180
- // [2,5] Display the 2,3,4,5 items.
181
- expect(slide2hook).toMatchInlineSnapshot(`
182
- {
183
- "negativeRange": [
184
- 0,
185
- 2,
186
- ],
187
- "positiveRange": [
188
- 2,
189
- 5,
190
- ],
191
- }
192
- `);
193
-
194
- // [3.6] Display the 3,4,5,6 items.
195
- expect(slide3hook).toMatchInlineSnapshot(`
196
- {
197
- "negativeRange": [
198
- 0,
199
- 3,
200
- ],
201
- "positiveRange": [
202
- 3,
203
- 6,
204
- ],
205
- }
206
- `);
207
- });
208
-
209
- it("should clamp ranges on right overdrag in non-loop mode", () => {
210
- const hook = renderHook(() => {
211
- // Simulate overdrag to the right at the first page (positive translation)
212
- const translation = useSharedValue(viewSize * 0.25);
213
- const range = useVisibleRanges({
214
- total: 5,
215
- translation,
216
- viewSize,
217
- windowSize: 3,
218
- loop: false,
219
- });
220
-
221
- return range;
222
- });
223
-
224
- expect(hook.result.current.value).toEqual({
225
- negativeRange: [0, 0],
226
- positiveRange: [0, 2],
227
- });
228
- });
229
-
230
- it("should return empty positive range when total is 0", () => {
231
- const hook = renderHook(() => {
232
- const translation = useSharedValue(0);
233
- const range = useVisibleRanges({
234
- total: 0,
235
- translation,
236
- viewSize,
237
- windowSize: 4,
238
- loop: false,
239
- });
240
- return range;
241
- });
242
-
243
- expect(hook.result.current.value).toEqual({
244
- negativeRange: [0, 0],
245
- positiveRange: [0, -1],
246
- });
247
- });
248
-
249
- describe("viewSize boundary conditions", () => {
250
- it("should return safe defaults when viewSize is NaN", () => {
251
- const hook = renderHook(() => {
252
- const translation = useSharedValue(0);
253
- const range = useVisibleRanges({
254
- total: 6,
255
- translation,
256
- // Invalid runtime value should not break range calculation
257
- viewSize: Number.NaN,
258
- windowSize: 4,
259
- loop: false,
260
- });
261
- return range;
262
- });
263
-
264
- expect(hook.result.current.value).toEqual({
265
- negativeRange: [0, 0],
266
- positiveRange: [0, 3],
267
- });
268
- });
269
-
270
- it("should return safe defaults when viewSize is 0", () => {
271
- const hook = renderHook(() => {
272
- const translation = useSharedValue(0);
273
- const range = useVisibleRanges({
274
- total: 10,
275
- translation,
276
- viewSize: 0,
277
- windowSize: 4,
278
- loop: false,
279
- });
280
- return range;
281
- });
282
-
283
- // Should not crash and return sensible defaults
284
- expect(hook.result.current.value).toEqual({
285
- negativeRange: [0, 0],
286
- positiveRange: [0, 3], // Math.min(10-1, 4-1) = 3
287
- });
288
- });
289
-
290
- it("should return safe defaults when viewSize is negative", () => {
291
- const hook = renderHook(() => {
292
- const translation = useSharedValue(0);
293
- const range = useVisibleRanges({
294
- total: 5,
295
- translation,
296
- viewSize: -100,
297
- windowSize: 3,
298
- loop: true,
299
- });
300
- return range;
301
- });
302
-
303
- expect(hook.result.current.value).toEqual({
304
- negativeRange: [0, 0],
305
- positiveRange: [0, 2], // Math.min(5-1, 3-1) = 2
306
- });
307
- });
308
-
309
- it("should handle small total with viewSize 0", () => {
310
- const hook = renderHook(() => {
311
- const translation = useSharedValue(0);
312
- const range = useVisibleRanges({
313
- total: 2,
314
- translation,
315
- viewSize: 0,
316
- windowSize: 5,
317
- loop: false,
318
- });
319
- return range;
320
- });
321
-
322
- expect(hook.result.current.value).toEqual({
323
- negativeRange: [0, 0],
324
- positiveRange: [0, 1], // Math.min(2-1, 5-1) = 1
325
- });
326
- });
327
-
328
- it("should handle loop mode with viewSize 0", () => {
329
- const hook = renderHook(() => {
330
- const translation = useSharedValue(0);
331
- const range = useVisibleRanges({
332
- total: 6,
333
- translation,
334
- viewSize: 0,
335
- windowSize: 4,
336
- loop: true,
337
- });
338
- return range;
339
- });
340
-
341
- expect(hook.result.current.value).toEqual({
342
- negativeRange: [0, 0],
343
- positiveRange: [0, 3], // Math.min(6-1, 4-1) = 3
344
- });
345
- });
346
- });
347
- });
@@ -1,239 +0,0 @@
1
- import { parallaxLayout } from "./parallax";
2
-
3
- // Mock react-native-reanimated
4
- jest.mock("react-native-reanimated", () => ({
5
- interpolate: jest.fn((value, inputRange, outputRange) => {
6
- // Simple linear interpolation mock for testing
7
- const inputMin = inputRange[0];
8
- const inputMax = inputRange[inputRange.length - 1];
9
- const outputMin = outputRange[0];
10
- const outputMax = outputRange[outputRange.length - 1];
11
-
12
- if (value <= inputMin) return outputMin;
13
- if (value >= inputMax) return outputMax;
14
-
15
- // Linear interpolation
16
- const progress = (value - inputMin) / (inputMax - inputMin);
17
- return outputMin + progress * (outputMax - outputMin);
18
- }),
19
- Extrapolation: {
20
- CLAMP: "clamp",
21
- },
22
- }));
23
-
24
- describe("parallaxLayout", () => {
25
- const baseConfig = {
26
- size: 300,
27
- vertical: false,
28
- };
29
-
30
- it("should create layout function with default config", () => {
31
- const layout = parallaxLayout(baseConfig);
32
- expect(typeof layout).toBe("function");
33
- });
34
-
35
- it("should return transform object for horizontal layout", () => {
36
- const layout = parallaxLayout(baseConfig);
37
- const result = layout(0);
38
-
39
- expect(result).toHaveProperty("transform");
40
- expect(result).toHaveProperty("zIndex");
41
- expect(result.transform).toHaveLength(2);
42
- expect(result.transform[0]).toHaveProperty("translateX");
43
- expect(result.transform[1]).toHaveProperty("scale");
44
- });
45
-
46
- it("should return transform object for vertical layout", () => {
47
- const verticalConfig = { ...baseConfig, vertical: true };
48
- const layout = parallaxLayout(verticalConfig);
49
- const result = layout(0);
50
-
51
- expect(result).toHaveProperty("transform");
52
- expect(result).toHaveProperty("zIndex");
53
- expect(result.transform).toHaveLength(2);
54
- expect(result.transform[0]).toHaveProperty("translateY");
55
- expect(result.transform[1]).toHaveProperty("scale");
56
- });
57
-
58
- it("should handle center position (value = 0)", () => {
59
- const layout = parallaxLayout(baseConfig);
60
- const result = layout(0);
61
-
62
- // At center position, translateX should be 0
63
- expect(result.transform[0].translateX).toBe(0);
64
- // Scale should be a number (parallax logic applied)
65
- expect(typeof result.transform[1].scale).toBe("number");
66
- });
67
-
68
- it("should handle left position (value = -1)", () => {
69
- const layout = parallaxLayout(baseConfig);
70
- const result = layout(-1);
71
-
72
- // At left position, translateX should be -size + parallaxScrollingOffset
73
- expect(result.transform[0].translateX).toBe(-200); // -300 + 100
74
- // Scale should be a number
75
- expect(typeof result.transform[1].scale).toBe("number");
76
- });
77
-
78
- it("should handle right position (value = 1)", () => {
79
- const layout = parallaxLayout(baseConfig);
80
- const result = layout(1);
81
-
82
- // At right position, translateX should be size - parallaxScrollingOffset
83
- expect(result.transform[0].translateX).toBe(200); // 300 - 100
84
- // Scale should be a number
85
- expect(typeof result.transform[1].scale).toBe("number");
86
- });
87
-
88
- it("should handle custom parallaxScrollingOffset", () => {
89
- const modeConfig = { parallaxScrollingOffset: 50 };
90
- const layout = parallaxLayout(baseConfig, modeConfig);
91
-
92
- const leftResult = layout(-1);
93
- const rightResult = layout(1);
94
-
95
- expect(leftResult.transform[0].translateX).toBe(-250); // -300 + 50
96
- expect(rightResult.transform[0].translateX).toBe(250); // 300 - 50
97
- });
98
-
99
- it("should handle custom parallaxScrollingScale", () => {
100
- const modeConfig = { parallaxScrollingScale: 0.9 };
101
- const layout = parallaxLayout(baseConfig, modeConfig);
102
-
103
- const centerResult = layout(0);
104
- const sideResult = layout(-1);
105
-
106
- // Verify the structure and that scale values are calculated
107
- expect(typeof centerResult.transform[1].scale).toBe("number");
108
- expect(typeof sideResult.transform[1].scale).toBe("number");
109
- expect(centerResult.transform[1].scale).toBeGreaterThan(0);
110
- expect(sideResult.transform[1].scale).toBeGreaterThan(0);
111
- });
112
-
113
- it("should handle custom parallaxAdjacentItemScale", () => {
114
- const modeConfig = {
115
- parallaxScrollingScale: 0.9,
116
- parallaxAdjacentItemScale: 0.7,
117
- };
118
- const layout = parallaxLayout(baseConfig, modeConfig);
119
-
120
- const centerResult = layout(0);
121
- const sideResult = layout(-1);
122
-
123
- // Verify the structure and that scale values are calculated
124
- expect(typeof centerResult.transform[1].scale).toBe("number");
125
- expect(typeof sideResult.transform[1].scale).toBe("number");
126
- expect(centerResult.transform[1].scale).toBeGreaterThan(0);
127
- expect(sideResult.transform[1].scale).toBeGreaterThan(0);
128
- });
129
-
130
- it("should handle vertical layout with custom config", () => {
131
- const verticalConfig = { ...baseConfig, vertical: true };
132
- const modeConfig = { parallaxScrollingOffset: 80 };
133
- const layout = parallaxLayout(verticalConfig, modeConfig);
134
-
135
- const leftResult = layout(-1);
136
- const centerResult = layout(0);
137
- const rightResult = layout(1);
138
-
139
- expect(leftResult.transform[0].translateY).toBe(-220); // -300 + 80
140
- expect(centerResult.transform[0].translateY).toBe(0);
141
- expect(rightResult.transform[0].translateY).toBe(220); // 300 - 80
142
- });
143
-
144
- it("should handle edge case values", () => {
145
- const layout = parallaxLayout(baseConfig);
146
-
147
- // Test with values beyond the normal range
148
- const farLeftResult = layout(-2);
149
- const farRightResult = layout(2);
150
-
151
- expect(typeof farLeftResult.transform[0].translateX).toBe("number");
152
- expect(typeof farLeftResult.transform[1].scale).toBe("number");
153
- expect(typeof farRightResult.transform[0].translateX).toBe("number");
154
- expect(typeof farRightResult.transform[1].scale).toBe("number");
155
- });
156
-
157
- it("should handle fractional values", () => {
158
- const layout = parallaxLayout(baseConfig);
159
-
160
- const halfwayResult = layout(0.5);
161
- const quarterResult = layout(-0.25);
162
-
163
- expect(typeof halfwayResult.transform[0].translateX).toBe("number");
164
- expect(typeof halfwayResult.transform[1].scale).toBe("number");
165
- expect(typeof quarterResult.transform[0].translateX).toBe("number");
166
- expect(typeof quarterResult.transform[1].scale).toBe("number");
167
- });
168
-
169
- it("should handle zero size", () => {
170
- const zeroSizeConfig = { ...baseConfig, size: 0 };
171
- const layout = parallaxLayout(zeroSizeConfig);
172
- const result = layout(0);
173
-
174
- expect(result).toHaveProperty("transform");
175
- expect(result).toHaveProperty("zIndex");
176
- });
177
-
178
- it("should handle negative size", () => {
179
- const negativeSizeConfig = { ...baseConfig, size: -100 };
180
- const layout = parallaxLayout(negativeSizeConfig);
181
- const result = layout(0);
182
-
183
- expect(result).toHaveProperty("transform");
184
- expect(result).toHaveProperty("zIndex");
185
- });
186
-
187
- it("should handle all config properties at once", () => {
188
- const fullModeConfig = {
189
- parallaxScrollingOffset: 75,
190
- parallaxScrollingScale: 0.85,
191
- parallaxAdjacentItemScale: 0.6,
192
- };
193
- const layout = parallaxLayout(baseConfig, fullModeConfig);
194
-
195
- const centerResult = layout(0);
196
- const sideResult = layout(-1);
197
-
198
- // Verify the structure and that values are calculated correctly
199
- expect(typeof centerResult.transform[1].scale).toBe("number");
200
- expect(typeof sideResult.transform[1].scale).toBe("number");
201
- expect(sideResult.transform[0].translateX).toBe(-225); // -300 + 75
202
- });
203
-
204
- it("should handle empty mode config", () => {
205
- const layout = parallaxLayout(baseConfig, {});
206
- const result = layout(0);
207
-
208
- // At center (value = 0), scale should be a number (default parallax behavior)
209
- expect(typeof result.transform[1].scale).toBe("number");
210
- expect(result.transform[1].scale).toBeGreaterThan(0);
211
- expect(result.transform[1].scale).toBeLessThanOrEqual(1);
212
- });
213
-
214
- it("should handle undefined mode config", () => {
215
- const layout = parallaxLayout(baseConfig, undefined);
216
- const result = layout(0);
217
-
218
- // At center (value = 0), scale should be a number (default parallax behavior)
219
- expect(typeof result.transform[1].scale).toBe("number");
220
- expect(result.transform[1].scale).toBeGreaterThan(0);
221
- expect(result.transform[1].scale).toBeLessThanOrEqual(1);
222
- });
223
-
224
- it("should maintain consistent zIndex calculation", () => {
225
- const layout = parallaxLayout(baseConfig);
226
-
227
- const leftResult = layout(-1);
228
- const centerResult = layout(0);
229
- const rightResult = layout(1);
230
-
231
- expect(typeof leftResult.zIndex).toBe("number");
232
- expect(typeof centerResult.zIndex).toBe("number");
233
- expect(typeof rightResult.zIndex).toBe("number");
234
-
235
- // Center should have highest zIndex
236
- expect(centerResult.zIndex).toBeGreaterThanOrEqual(leftResult.zIndex);
237
- expect(centerResult.zIndex).toBeGreaterThanOrEqual(rightResult.zIndex);
238
- });
239
- });