react-native-reanimated-carousel 4.0.0-alpha.1 → 4.0.0-alpha.11

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 (173) hide show
  1. package/README.md +2 -3
  2. package/lib/commonjs/{layouts → components}/BaseLayout.js +5 -21
  3. package/lib/commonjs/components/BaseLayout.js.map +1 -0
  4. package/lib/commonjs/components/Carousel.js +28 -48
  5. package/lib/commonjs/components/Carousel.js.map +1 -1
  6. package/lib/commonjs/components/ItemRenderer.js +80 -0
  7. package/lib/commonjs/components/ItemRenderer.js.map +1 -0
  8. package/lib/commonjs/components/Pagination/Basic/PaginationItem.js +81 -0
  9. package/lib/commonjs/components/Pagination/Basic/PaginationItem.js.map +1 -0
  10. package/lib/commonjs/components/Pagination/Basic/index.js +57 -0
  11. package/lib/commonjs/components/Pagination/Basic/index.js.map +1 -0
  12. package/lib/commonjs/components/Pagination/index.js +14 -0
  13. package/lib/commonjs/components/Pagination/index.js.map +1 -0
  14. package/lib/commonjs/components/ScrollViewGesture.js +51 -33
  15. package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
  16. package/lib/commonjs/components/rnr-demo.test.js +45 -0
  17. package/lib/commonjs/components/rnr-demo.test.js.map +1 -0
  18. package/lib/commonjs/hooks/useCarouselController.js +12 -11
  19. package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
  20. package/lib/commonjs/hooks/useCommonVariables.js +38 -12
  21. package/lib/commonjs/hooks/useCommonVariables.js.map +1 -1
  22. package/lib/commonjs/hooks/useCommonVariables.test.js +38 -0
  23. package/lib/commonjs/hooks/useCommonVariables.test.js.map +1 -0
  24. package/lib/commonjs/hooks/useLayoutConfig.js.map +1 -1
  25. package/lib/commonjs/hooks/useOffsetX.js +9 -6
  26. package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
  27. package/lib/commonjs/hooks/useOffsetX.test.js +53 -0
  28. package/lib/commonjs/hooks/useOffsetX.test.js.map +1 -0
  29. package/lib/commonjs/hooks/useOnProgressChange.js +4 -1
  30. package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -1
  31. package/lib/commonjs/hooks/usePanGestureProxy.js +84 -0
  32. package/lib/commonjs/hooks/usePanGestureProxy.js.map +1 -0
  33. package/lib/commonjs/hooks/usePanGestureProxy.test.js +397 -0
  34. package/lib/commonjs/hooks/usePanGestureProxy.test.js.map +1 -0
  35. package/lib/commonjs/hooks/useUpdateGestureConfig.js.map +1 -1
  36. package/lib/commonjs/hooks/useVisibleRanges.js +48 -19
  37. package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
  38. package/lib/commonjs/hooks/useVisibleRanges.test.js +162 -0
  39. package/lib/commonjs/hooks/useVisibleRanges.test.js.map +1 -0
  40. package/lib/commonjs/index.js +8 -0
  41. package/lib/commonjs/index.js.map +1 -1
  42. package/lib/commonjs/utils/{computeNewIndexWhenDataChanges.js → compute-offset-if-data-changed.js} +3 -3
  43. package/lib/commonjs/utils/compute-offset-if-data-changed.js.map +1 -0
  44. package/lib/commonjs/utils/compute-offset-if-data-changed.test.js +30 -0
  45. package/lib/commonjs/utils/compute-offset-if-data-changed.test.js.map +1 -0
  46. package/lib/commonjs/utils/compute-offset-if-size-changed.js +18 -0
  47. package/lib/commonjs/utils/compute-offset-if-size-changed.js.map +1 -0
  48. package/lib/commonjs/utils/compute-offset-if-size-changed.test.js +72 -0
  49. package/lib/commonjs/utils/compute-offset-if-size-changed.test.js.map +1 -0
  50. package/lib/commonjs/utils/handleroffset-direction.js +5 -5
  51. package/lib/commonjs/utils/handleroffset-direction.js.map +1 -1
  52. package/lib/commonjs/utils/handleroffset-direction.test.js +46 -0
  53. package/lib/commonjs/utils/handleroffset-direction.test.js.map +1 -0
  54. package/lib/commonjs/utils/index.test.js +6 -6
  55. package/lib/commonjs/utils/index.test.js.map +1 -1
  56. package/lib/module/{layouts → components}/BaseLayout.js +6 -16
  57. package/lib/module/components/BaseLayout.js.map +1 -0
  58. package/lib/module/components/Carousel.js +27 -44
  59. package/lib/module/components/Carousel.js.map +1 -1
  60. package/lib/module/components/ItemRenderer.js +62 -0
  61. package/lib/module/components/ItemRenderer.js.map +1 -0
  62. package/lib/module/components/Pagination/Basic/PaginationItem.js +63 -0
  63. package/lib/module/components/Pagination/Basic/PaginationItem.js.map +1 -0
  64. package/lib/module/components/Pagination/Basic/index.js +42 -0
  65. package/lib/module/components/Pagination/Basic/index.js.map +1 -0
  66. package/lib/module/components/Pagination/index.js +5 -0
  67. package/lib/module/components/Pagination/index.js.map +1 -0
  68. package/lib/module/components/ScrollViewGesture.js +53 -34
  69. package/lib/module/components/ScrollViewGesture.js.map +1 -1
  70. package/lib/module/components/rnr-demo.test.js +33 -0
  71. package/lib/module/components/rnr-demo.test.js.map +1 -0
  72. package/lib/module/hooks/useCarouselController.js +12 -11
  73. package/lib/module/hooks/useCarouselController.js.map +1 -1
  74. package/lib/module/hooks/useCommonVariables.js +38 -8
  75. package/lib/module/hooks/useCommonVariables.js.map +1 -1
  76. package/lib/module/hooks/useCommonVariables.test.js +34 -0
  77. package/lib/module/hooks/useCommonVariables.test.js.map +1 -0
  78. package/lib/module/hooks/useLayoutConfig.js.map +1 -1
  79. package/lib/module/hooks/useOffsetX.js +9 -6
  80. package/lib/module/hooks/useOffsetX.js.map +1 -1
  81. package/lib/module/hooks/useOffsetX.test.js +48 -0
  82. package/lib/module/hooks/useOffsetX.test.js.map +1 -0
  83. package/lib/module/hooks/useOnProgressChange.js +4 -1
  84. package/lib/module/hooks/useOnProgressChange.js.map +1 -1
  85. package/lib/module/hooks/usePanGestureProxy.js +71 -0
  86. package/lib/module/hooks/usePanGestureProxy.js.map +1 -0
  87. package/lib/module/hooks/usePanGestureProxy.test.js +383 -0
  88. package/lib/module/hooks/usePanGestureProxy.test.js.map +1 -0
  89. package/lib/module/hooks/useUpdateGestureConfig.js.map +1 -1
  90. package/lib/module/hooks/useVisibleRanges.js +47 -19
  91. package/lib/module/hooks/useVisibleRanges.js.map +1 -1
  92. package/lib/module/hooks/useVisibleRanges.test.js +157 -0
  93. package/lib/module/hooks/useVisibleRanges.test.js.map +1 -0
  94. package/lib/module/index.js +1 -0
  95. package/lib/module/index.js.map +1 -1
  96. package/lib/module/utils/{computeNewIndexWhenDataChanges.js → compute-offset-if-data-changed.js} +2 -2
  97. package/lib/module/utils/compute-offset-if-data-changed.js.map +1 -0
  98. package/lib/module/utils/compute-offset-if-data-changed.test.js +27 -0
  99. package/lib/module/utils/compute-offset-if-data-changed.test.js.map +1 -0
  100. package/lib/module/utils/compute-offset-if-size-changed.js +11 -0
  101. package/lib/module/utils/compute-offset-if-size-changed.js.map +1 -0
  102. package/lib/module/utils/compute-offset-if-size-changed.test.js +69 -0
  103. package/lib/module/utils/compute-offset-if-size-changed.test.js.map +1 -0
  104. package/lib/module/utils/handleroffset-direction.js +5 -5
  105. package/lib/module/utils/handleroffset-direction.js.map +1 -1
  106. package/lib/module/utils/handleroffset-direction.test.js +41 -0
  107. package/lib/module/utils/handleroffset-direction.test.js.map +1 -0
  108. package/lib/module/utils/index.test.js +6 -6
  109. package/lib/module/utils/index.test.js.map +1 -1
  110. package/lib/typescript/components/ItemRenderer.d.ts +22 -0
  111. package/lib/typescript/components/Pagination/Basic/PaginationItem.d.ts +17 -0
  112. package/lib/typescript/components/Pagination/Basic/index.d.ts +16 -0
  113. package/lib/typescript/components/Pagination/index.d.ts +3 -0
  114. package/lib/typescript/components/ScrollViewGesture.d.ts +1 -1
  115. package/lib/typescript/components/rnr-demo.test.d.ts +1 -0
  116. package/lib/typescript/hooks/useCarouselController.d.ts +3 -2
  117. package/lib/typescript/hooks/useCommonVariables.test.d.ts +1 -0
  118. package/lib/typescript/hooks/useLayoutConfig.d.ts +1 -1
  119. package/lib/typescript/hooks/useOffsetX.test.d.ts +1 -0
  120. package/lib/typescript/hooks/usePanGestureProxy.d.ts +9 -0
  121. package/lib/typescript/hooks/usePanGestureProxy.test.d.ts +1 -0
  122. package/lib/typescript/hooks/useUpdateGestureConfig.d.ts +3 -2
  123. package/lib/typescript/hooks/useVisibleRanges.d.ts +8 -4
  124. package/lib/typescript/hooks/useVisibleRanges.test.d.ts +1 -0
  125. package/lib/typescript/index.d.ts +2 -0
  126. package/lib/typescript/types.d.ts +27 -16
  127. package/lib/typescript/utils/{computeNewIndexWhenDataChanges.d.ts → compute-offset-if-data-changed.d.ts} +1 -1
  128. package/lib/typescript/utils/compute-offset-if-data-changed.test.d.ts +1 -0
  129. package/lib/typescript/utils/compute-offset-if-size-changed.d.ts +5 -0
  130. package/lib/typescript/utils/compute-offset-if-size-changed.test.d.ts +1 -0
  131. package/lib/typescript/utils/handleroffset-direction.d.ts +2 -1
  132. package/lib/typescript/utils/handleroffset-direction.test.d.ts +1 -0
  133. package/package.json +18 -60
  134. package/src/{layouts → components}/BaseLayout.tsx +7 -35
  135. package/src/components/Carousel.tsx +33 -71
  136. package/src/components/ItemRenderer.tsx +105 -0
  137. package/src/components/Pagination/Basic/PaginationItem.tsx +111 -0
  138. package/src/components/Pagination/Basic/index.tsx +81 -0
  139. package/src/components/Pagination/index.tsx +5 -0
  140. package/src/components/ScrollViewGesture.tsx +74 -49
  141. package/src/components/rnr-demo.test.tsx +43 -0
  142. package/src/hooks/useCarouselController.tsx +24 -21
  143. package/src/hooks/useCommonVariables.test.tsx +41 -0
  144. package/src/hooks/useCommonVariables.ts +35 -10
  145. package/src/hooks/useLayoutConfig.ts +1 -1
  146. package/src/hooks/useOffsetX.test.ts +54 -0
  147. package/src/hooks/useOffsetX.ts +33 -31
  148. package/src/hooks/useOnProgressChange.ts +7 -2
  149. package/src/hooks/usePanGestureProxy.test.tsx +376 -0
  150. package/src/hooks/usePanGestureProxy.ts +110 -0
  151. package/src/hooks/useUpdateGestureConfig.ts +4 -2
  152. package/src/hooks/useVisibleRanges.test.tsx +179 -0
  153. package/src/hooks/useVisibleRanges.tsx +72 -24
  154. package/src/index.tsx +3 -0
  155. package/src/types.ts +28 -17
  156. package/src/utils/compute-offset-if-data-changed.test.ts +30 -0
  157. package/src/utils/{computeNewIndexWhenDataChanges.ts → compute-offset-if-data-changed.ts} +1 -1
  158. package/src/utils/compute-offset-if-size-changed.test.ts +78 -0
  159. package/src/utils/compute-offset-if-size-changed.ts +11 -0
  160. package/src/utils/handleroffset-direction.test.ts +52 -0
  161. package/src/utils/handleroffset-direction.ts +12 -9
  162. package/src/utils/index.test.ts +6 -6
  163. package/lib/commonjs/layouts/BaseLayout.js.map +0 -1
  164. package/lib/commonjs/layouts/ParallaxLayout.js +0 -84
  165. package/lib/commonjs/layouts/ParallaxLayout.js.map +0 -1
  166. package/lib/commonjs/utils/computeNewIndexWhenDataChanges.js.map +0 -1
  167. package/lib/module/layouts/BaseLayout.js.map +0 -1
  168. package/lib/module/layouts/ParallaxLayout.js +0 -61
  169. package/lib/module/layouts/ParallaxLayout.js.map +0 -1
  170. package/lib/module/utils/computeNewIndexWhenDataChanges.js.map +0 -1
  171. package/lib/typescript/layouts/ParallaxLayout.d.ts +0 -13
  172. package/src/layouts/ParallaxLayout.tsx +0 -141
  173. /package/lib/typescript/{layouts → components}/BaseLayout.d.ts +0 -0
@@ -1,49 +1,97 @@
1
+ import { useRef } from "react";
1
2
  import type Animated from "react-native-reanimated";
2
3
  import { useDerivedValue } from "react-native-reanimated";
3
4
 
4
- export type IVisibleRanges = Animated.SharedValue<{
5
- negativeRange: number[]
6
- positiveRange: number[]
7
- }>;
5
+ type Range = [number, number];
6
+
7
+ export interface VisibleRanges {
8
+ negativeRange: Range
9
+ positiveRange: Range
10
+ }
11
+
12
+ export type IVisibleRanges = Animated.SharedValue<VisibleRanges>;
8
13
 
9
14
  export function useVisibleRanges(options: {
10
15
  total: number
11
16
  viewSize: number
12
17
  windowSize?: number
13
18
  translation: Animated.SharedValue<number>
19
+ loop?: boolean
14
20
  }): IVisibleRanges {
15
21
  const {
16
22
  total = 0,
17
23
  viewSize,
18
24
  translation,
19
- windowSize: _windowSize = 0,
25
+ windowSize: _windowSize,
26
+ loop,
20
27
  } = options;
21
28
 
22
- const windowSize = total <= _windowSize ? total : _windowSize;
29
+ const windowSize = _windowSize ?? total;
30
+ const cachedRanges = useRef<VisibleRanges>(null!);
23
31
 
24
32
  const ranges = useDerivedValue(() => {
25
33
  const positiveCount = Math.round(windowSize / 2);
26
34
  const negativeCount = windowSize - positiveCount;
27
- let curIndex = Math.round(-translation.value / viewSize);
28
- curIndex = curIndex < 0 ? (curIndex % total) + total : curIndex;
29
- const negativeRange = [
30
- (curIndex - negativeCount + total) % total,
31
- (curIndex - 1 + total) % total,
32
- ];
33
- const positiveRange = [
34
- (curIndex + total) % total,
35
- (curIndex + positiveCount + total) % total,
36
- ];
37
- if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {
38
- negativeRange[1] = total - 1;
39
- positiveRange[0] = 0;
35
+
36
+ let currentIndex = Math.round(-translation.value / viewSize);
37
+ currentIndex = currentIndex < 0 ? (currentIndex % total) + total : currentIndex;
38
+
39
+ let newRanges: VisibleRanges;
40
+
41
+ if (!loop) {
42
+ // Adjusting negative range if the carousel is not loopable.
43
+ // So, It will be only displayed the positive items.
44
+ newRanges = {
45
+ negativeRange: [0 + currentIndex - (windowSize - 1), 0 + currentIndex],
46
+ positiveRange: [0 + currentIndex, currentIndex + (windowSize - 1)],
47
+ };
40
48
  }
41
- if (positiveRange[0] > positiveRange[1]) {
42
- negativeRange[1] = total - 1;
43
- positiveRange[0] = 0;
49
+ else {
50
+ const negativeRange: Range = [
51
+ (currentIndex - negativeCount + total) % total,
52
+ (currentIndex - 1 + total) % total,
53
+ ];
54
+
55
+ const positiveRange: Range = [
56
+ (currentIndex + total) % total,
57
+ (currentIndex + positiveCount + total) % total,
58
+ ];
59
+
60
+ if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {
61
+ negativeRange[1] = total - 1;
62
+ positiveRange[0] = 0;
63
+ }
64
+ if (positiveRange[0] > positiveRange[1]) {
65
+ negativeRange[1] = total - 1;
66
+ positiveRange[0] = 0;
67
+ }
68
+
69
+ // console.log({ negativeRange, positiveRange ,total,windowSize,a:total <= _windowSize})
70
+ newRanges = { negativeRange, positiveRange };
44
71
  }
45
- return { negativeRange, positiveRange };
46
- }, [total, windowSize, translation]);
72
+
73
+ if (
74
+ isArraysEqual(
75
+ cachedRanges.current?.negativeRange ?? [],
76
+ newRanges.negativeRange,
77
+ )
78
+ && isArraysEqual(
79
+ cachedRanges.current?.positiveRange ?? [],
80
+ newRanges.positiveRange,
81
+ )
82
+ )
83
+ return cachedRanges.current;
84
+
85
+ cachedRanges.current = newRanges;
86
+ return cachedRanges.current;
87
+ }, [loop, total, windowSize, translation]);
47
88
 
48
89
  return ranges;
49
90
  }
91
+
92
+ function isArraysEqual(a: number[], b: number[]): boolean {
93
+ "worklet";
94
+ if (a.length !== b.length) return false;
95
+
96
+ return a.every((value, index) => value === b[index]);
97
+ }
package/src/index.tsx CHANGED
@@ -1,10 +1,13 @@
1
1
  import Carousel from "./components/Carousel";
2
+ export { Pagination } from "./components/Pagination";
3
+
2
4
  export type {
3
5
  TCarouselProps,
4
6
  ICarouselInstance,
5
7
  IComputedDirectionTypes,
6
8
  CarouselRenderItem,
7
9
  } from "./types";
10
+ export type { TAnimationStyle } from "./components/BaseLayout";
8
11
  export type { ILayoutConfig } from "./layouts/stack";
9
12
 
10
13
  export default Carousel;
package/src/types.ts CHANGED
@@ -153,10 +153,19 @@ export type TCarouselProps<T = any> = {
153
153
  testID?: string
154
154
  /**
155
155
  * Maximum offset value for once scroll.
156
- * props.vertical = true => maxScrollDistancePerSwipeY
157
- * props.vertical = false => maxScrollDistancePerSwipeX
156
+ * Carousel cannot scroll over than this value.
158
157
  * */
159
158
  maxScrollDistancePerSwipe?: number
159
+ /**
160
+ * Minimum offset value for once scroll.
161
+ * If the translation value is less than this value, the carousel will not scroll.
162
+ * */
163
+ minScrollDistancePerSwipe?: number
164
+ /**
165
+ * @experimental This API will be changed in the future.
166
+ * If positive, the carousel will scroll to the positive direction and vice versa.
167
+ * */
168
+ fixedDirection?: "positive" | "negative"
160
169
  /**
161
170
  * Custom carousel config.
162
171
  */
@@ -175,9 +184,9 @@ export type TCarouselProps<T = any> = {
175
184
  */
176
185
  onSnapToItem?: (index: number) => void
177
186
  /**
178
- * On scroll begin
187
+ * On scroll start
179
188
  */
180
- onScrollBegin?: () => void
189
+ onScrollStart?: () => void
181
190
  /**
182
191
  * On scroll end
183
192
  */
@@ -186,11 +195,13 @@ export type TCarouselProps<T = any> = {
186
195
  * On progress change
187
196
  * @param offsetProgress Total of offset distance (0 390 780 ...)
188
197
  * @param absoluteProgress Convert to index (0 1 2 ...)
198
+ *
199
+ * If you want to update a shared value automatically, you can use the shared value as a parameter directly.
189
200
  */
190
- onProgressChange?: (
201
+ onProgressChange?: ((
191
202
  offsetProgress: number,
192
203
  absoluteProgress: number
193
- ) => void
204
+ ) => void) | SharedValue<number>
194
205
 
195
206
  // ============================== deprecated props ==============================
196
207
  /**
@@ -203,23 +214,23 @@ export type TCarouselProps<T = any> = {
203
214
 
204
215
  export interface ICarouselInstance {
205
216
  /**
206
- * Scroll to previous item, it takes one optional argument (count),
207
- * which allows you to specify how many items to cross
208
- */
217
+ * Scroll to previous item, it takes one optional argument (count),
218
+ * which allows you to specify how many items to cross
219
+ */
209
220
  prev: (opts?: Omit<TCarouselActionOptions, "index">) => void
210
221
  /**
211
- * Scroll to next item, it takes one optional argument (count),
212
- * which allows you to specify how many items to cross
213
- */
222
+ * Scroll to next item, it takes one optional argument (count),
223
+ * which allows you to specify how many items to cross
224
+ */
214
225
  next: (opts?: Omit<TCarouselActionOptions, "index">) => void
215
226
  /**
216
- * Get current item index
217
- */
227
+ * Get current item index
228
+ */
218
229
  getCurrentIndex: () => number
219
230
  /**
220
- * Use value to scroll to a position where relative to the current position,
221
- * scrollTo(-2) is equivalent to prev(2), scrollTo(2) is equivalent to next(2)
222
- */
231
+ * Use value to scroll to a position where relative to the current position,
232
+ * scrollTo({count: -2}) is equivalent to prev(2), scrollTo({count: 2}) is equivalent to next(2)
233
+ */
223
234
  scrollTo: (opts?: TCarouselActionOptions) => void
224
235
  }
225
236
 
@@ -0,0 +1,30 @@
1
+ import { computeOffsetIfDataChanged } from "./compute-offset-if-data-changed";
2
+
3
+ describe("computeOffsetIfDataChanged", () => {
4
+ const size = 634;
5
+ it("should return the correct values, if index is 0", () => {
6
+ const index = 0;
7
+ const result = computeOffsetIfDataChanged({
8
+ direction: -1,
9
+ previousLength: 4,
10
+ currentLength: 6,
11
+ size,
12
+ handlerOffset: index * size,
13
+ });
14
+
15
+ expect(result).toMatchInlineSnapshot("0");
16
+ });
17
+
18
+ it("should return the correct values, if index is 1", () => {
19
+ const index = 1;
20
+ const result = computeOffsetIfDataChanged({
21
+ direction: -1,
22
+ previousLength: 4,
23
+ currentLength: 6,
24
+ size,
25
+ handlerOffset: index * size,
26
+ });
27
+
28
+ expect(result).toMatchInlineSnapshot("634");
29
+ });
30
+ });
@@ -6,7 +6,7 @@ export function omitZero(a: number, b: number) {
6
6
  return b;
7
7
  }
8
8
 
9
- export function computeNewIndexWhenDataChanges(params: {
9
+ export function computeOffsetIfDataChanged(params: {
10
10
  direction: number
11
11
  handlerOffset: number
12
12
  size: number
@@ -0,0 +1,78 @@
1
+ import { computeOffsetIfSizeChanged } from "./compute-offset-if-size-changed";
2
+
3
+ describe("computeOffsetIfSizeChanged", () => {
4
+ it("[CASE 1] should return the correct values when size does not change", () => {
5
+ const prevIndex = 1;
6
+ const prevSize = 500;
7
+ const size = 500;
8
+ const handlerOffset = prevIndex * size;
9
+ const result = computeOffsetIfSizeChanged({
10
+ prevSize,
11
+ size,
12
+ handlerOffset,
13
+ });
14
+
15
+ const finallyIndex = result / size;
16
+ expect(finallyIndex).toEqual(prevIndex);
17
+ });
18
+
19
+ it("[CASE 2] should return the correct values when size changes from 500 to 400", () => {
20
+ const prevIndex = 1;
21
+ const prevSize = 500;
22
+ const size = 400;
23
+ const handlerOffset = prevIndex * prevSize;
24
+ const result = computeOffsetIfSizeChanged({
25
+ prevSize,
26
+ size,
27
+ handlerOffset,
28
+ });
29
+
30
+ const finallyIndex = result / size;
31
+ expect(finallyIndex).toEqual(prevIndex);
32
+ });
33
+
34
+ it("[CASE 3] should return the correct values when size changes from 500 to 499", () => {
35
+ const prevIndex = 1;
36
+ const prevSize = 500;
37
+ const size = 499;
38
+ const handlerOffset = prevIndex * prevSize;
39
+ const result = computeOffsetIfSizeChanged({
40
+ prevSize,
41
+ size,
42
+ handlerOffset,
43
+ });
44
+
45
+ const finallyIndex = result / size;
46
+ expect(finallyIndex).toEqual(prevIndex);
47
+ });
48
+
49
+ it("[CASE 4] should return the correct values when size changes from 500 to 501", () => {
50
+ const prevIndex = 1;
51
+ const prevSize = 500;
52
+ const size = 501;
53
+ const handlerOffset = prevIndex * prevSize;
54
+ const result = computeOffsetIfSizeChanged({
55
+ prevSize,
56
+ size,
57
+ handlerOffset,
58
+ });
59
+
60
+ const finallyIndex = result / size;
61
+ expect(finallyIndex).toEqual(prevIndex);
62
+ });
63
+
64
+ it("[CASE 5] should return the correct values when size changes from 224 to 524", () => {
65
+ const prevIndex = 1;
66
+ const prevSize = 224;
67
+ const size = 524;
68
+ const handlerOffset = prevIndex * prevSize;
69
+ const result = computeOffsetIfSizeChanged({
70
+ prevSize,
71
+ size,
72
+ handlerOffset,
73
+ });
74
+
75
+ const finallyIndex = result / size;
76
+ expect(finallyIndex).toEqual(prevIndex);
77
+ });
78
+ });
@@ -0,0 +1,11 @@
1
+ export function computeOffsetIfSizeChanged(params: {
2
+ handlerOffset: number
3
+ prevSize: number
4
+ size: number
5
+ }) {
6
+ "worklet";
7
+ const { handlerOffset, prevSize, size } = params;
8
+
9
+ return handlerOffset / prevSize * size;
10
+ }
11
+
@@ -0,0 +1,52 @@
1
+ import { useSharedValue } from "react-native-reanimated";
2
+
3
+ import { renderHook } from "@testing-library/react-hooks";
4
+
5
+ import { handlerOffsetDirection } from "./handleroffset-direction";
6
+
7
+ describe("handlerOffsetDirection", () => {
8
+ it("should return -1 when default value equals to zero", () => {
9
+ const result = renderHook(() => {
10
+ const handlerOffsetAnimVal = useSharedValue(0);
11
+ return handlerOffsetDirection(handlerOffsetAnimVal);
12
+ });
13
+
14
+ expect(result.result.current).toBe(-1);
15
+ });
16
+
17
+ it("should return 1 when default value is greater than zero", () => {
18
+ const result = renderHook(() => {
19
+ const handlerOffsetAnimVal = useSharedValue(1);
20
+ return handlerOffsetDirection(handlerOffsetAnimVal);
21
+ });
22
+
23
+ expect(result.result.current).toBe(1);
24
+ });
25
+
26
+ it("should return -1 when default value is less than zero", () => {
27
+ const result = renderHook(() => {
28
+ const handlerOffsetAnimVal = useSharedValue(-1);
29
+ return handlerOffsetDirection(handlerOffsetAnimVal);
30
+ });
31
+
32
+ expect(result.result.current).toBe(-1);
33
+ });
34
+
35
+ it("should return 1 when default value equals to zero and fixedDirection is negative", () => {
36
+ const result = renderHook(() => {
37
+ const handlerOffsetAnimVal = useSharedValue(-1);
38
+ return handlerOffsetDirection(handlerOffsetAnimVal, "positive");
39
+ });
40
+
41
+ expect(result.result.current).toBe(1);
42
+ });
43
+
44
+ it("should return -1 when default value is greater than zero and fixedDirection is negative", () => {
45
+ const result = renderHook(() => {
46
+ const handlerOffsetAnimVal = useSharedValue(1);
47
+ return handlerOffsetDirection(handlerOffsetAnimVal, "negative");
48
+ });
49
+
50
+ expect(result.result.current).toBe(-1);
51
+ });
52
+ });
@@ -1,15 +1,18 @@
1
1
  import type { SharedValue } from "react-native-reanimated";
2
2
 
3
- export function handlerOffsetDirection(handlerOffset: SharedValue<number>): -1 | 1 {
3
+ import type { TCarouselProps } from "../types";
4
+
5
+ export function handlerOffsetDirection(handlerOffset: SharedValue<number>, fixedDirection?: TCarouselProps["fixedDirection"]): -1 | 1 {
4
6
  "worklet";
5
7
 
6
- const isPositiveZero = Object.is(handlerOffset.value, +0);
7
- const isNegativeZero = Object.is(handlerOffset.value, -0);
8
- const direction = isPositiveZero
9
- ? 1
10
- : isNegativeZero
11
- ? -1
12
- : Math.sign(handlerOffset.value) as -1 | 1;
8
+ if (fixedDirection === "negative")
9
+ return -1;
10
+
11
+ if (fixedDirection === "positive")
12
+ return 1;
13
+
14
+ if (handlerOffset.value === 0)
15
+ return -1;
13
16
 
14
- return direction;
17
+ return Math.sign(handlerOffset.value) as -1 | 1;
15
18
  }
@@ -1,4 +1,4 @@
1
- import { computeNewIndexWhenDataChanges } from "./computeNewIndexWhenDataChanges";
1
+ import { computeOffsetIfDataChanged } from "./compute-offset-if-data-changed";
2
2
 
3
3
  describe("should work as expected", () => {
4
4
  const size = 375;
@@ -24,7 +24,7 @@ describe("should work as expected", () => {
24
24
 
25
25
  it("The direction is negative, And changing length of data set from 4 to 3, the new index will to be 2.", async () => {
26
26
  const currentIndex = 1;
27
- const handlerOffset = computeNewIndexWhenDataChanges(params({
27
+ const handlerOffset = computeOffsetIfDataChanged(params({
28
28
  currentIndex,
29
29
  direction: "negative",
30
30
  previousLength: 4,
@@ -35,7 +35,7 @@ describe("should work as expected", () => {
35
35
  });
36
36
 
37
37
  it("The direction is negative, Changing length of data set from 4 to 3, the index remains original.", async () => {
38
- const handlerOffset = computeNewIndexWhenDataChanges(params({
38
+ const handlerOffset = computeOffsetIfDataChanged(params({
39
39
  currentIndex: 2,
40
40
  direction: "negative",
41
41
  previousLength: 4,
@@ -46,7 +46,7 @@ describe("should work as expected", () => {
46
46
  });
47
47
 
48
48
  it("The direction is positive, Changing length of data set from 4 to 5, the index remains original.", async () => {
49
- const handlerOffset = computeNewIndexWhenDataChanges(params({
49
+ const handlerOffset = computeOffsetIfDataChanged(params({
50
50
  currentIndex: 3,
51
51
  direction: "positive",
52
52
  previousLength: 4,
@@ -57,7 +57,7 @@ describe("should work as expected", () => {
57
57
  });
58
58
 
59
59
  it("The direction is negative, Changing length of data set from 4 to 5, the index remains original.", async () => {
60
- const handlerOffset = computeNewIndexWhenDataChanges(params({
60
+ const handlerOffset = computeOffsetIfDataChanged(params({
61
61
  currentIndex: 3,
62
62
  direction: "negative",
63
63
  previousLength: 4,
@@ -68,7 +68,7 @@ describe("should work as expected", () => {
68
68
  });
69
69
 
70
70
  it("Changing length of data set from 0 to 3, the index remains original.", async () => {
71
- const handlerOffset = computeNewIndexWhenDataChanges(params({
71
+ const handlerOffset = computeOffsetIfDataChanged(params({
72
72
  currentIndex: 0,
73
73
  direction: "positive",
74
74
  previousLength: 0,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["BaseLayout.tsx"],"names":["BaseLayout","props","mounted","handlerOffset","index","children","visibleRanges","animationStyle","context","React","useContext","CTX","loop","dataLength","width","height","vertical","customConfig","mode","modeConfig","size","shouldUpdate","setShouldUpdate","useState","offsetXConfig","snapDirection","showLength","type","viewCount","x","animationValue","value","animatedStyle","updateView","useCallback","negativeRange","positiveRange","current","position"],"mappings":"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","sourcesContent":["import React from \"react\";\nimport type { ViewStyle } from \"react-native\";\nimport type { AnimatedStyleProp } from \"react-native-reanimated\";\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useDerivedValue,\n} from \"react-native-reanimated\";\n\nimport type { ILayoutConfig } from \"./stack\";\n\nimport { LazyView } from \"../components/LazyView\";\nimport { useCheckMounted } from \"../hooks/useCheckMounted\";\nimport type { IOpts } from \"../hooks/useOffsetX\";\nimport { useOffsetX } from \"../hooks/useOffsetX\";\nimport type { IVisibleRanges } from \"../hooks/useVisibleRanges\";\nimport { CTX } from \"../store\";\n\nexport type TAnimationStyle = (value: number) => AnimatedStyleProp<ViewStyle>;\n\nexport const BaseLayout: React.FC<{\n index: number\n handlerOffset: Animated.SharedValue<number>\n visibleRanges: IVisibleRanges\n animationStyle: TAnimationStyle\n children: (ctx: {\n animationValue: Animated.SharedValue<number>\n }) => React.ReactElement\n}> = (props) => {\n const mounted = useCheckMounted();\n const { handlerOffset, index, children, visibleRanges, animationStyle }\n = props;\n\n const context = React.useContext(CTX);\n const {\n props: {\n loop,\n dataLength,\n width,\n height,\n vertical,\n customConfig,\n mode,\n modeConfig,\n },\n } = context;\n const size = vertical ? height : width;\n const [shouldUpdate, setShouldUpdate] = React.useState(false);\n let offsetXConfig: IOpts = {\n handlerOffset,\n index,\n size,\n dataLength,\n loop,\n ...(typeof customConfig === \"function\" ? customConfig() : {}),\n };\n\n if (mode === \"horizontal-stack\") {\n const { snapDirection, showLength } = modeConfig as ILayoutConfig;\n\n offsetXConfig = {\n handlerOffset,\n index,\n size,\n dataLength,\n loop,\n type: snapDirection === \"right\" ? \"negative\" : \"positive\",\n viewCount: showLength,\n };\n }\n\n const x = useOffsetX(offsetXConfig, visibleRanges);\n const animationValue = useDerivedValue(() => x.value / size, [x, size]);\n const animatedStyle = useAnimatedStyle(\n () => animationStyle(x.value / size),\n [animationStyle],\n );\n\n const updateView = React.useCallback(\n (negativeRange: number[], positiveRange: number[]) => {\n mounted.current\n && setShouldUpdate(\n (index >= negativeRange[0] && index <= negativeRange[1])\n || (index >= positiveRange[0] && index <= positiveRange[1]),\n );\n },\n [index, mounted],\n );\n\n useAnimatedReaction(\n () => visibleRanges.value,\n () => {\n runOnJS(updateView)(\n visibleRanges.value.negativeRange,\n visibleRanges.value.positiveRange,\n );\n },\n [visibleRanges.value],\n );\n\n return (\n <Animated.View\n style={[\n {\n width: width || \"100%\",\n height: height || \"100%\",\n position: \"absolute\",\n },\n animatedStyle,\n ]}\n /**\n * We use this testID to know when the carousel item is ready to be tested in test.\n * e.g.\n * The testID of first item will be changed to __CAROUSEL_ITEM_0_READY__ from __CAROUSEL_ITEM_0_NOT_READY__ when the item is ready.\n * */\n testID={`__CAROUSEL_ITEM_${index}_${shouldUpdate ? \"READY\" : \"NOT_READY\"}__`}\n >\n <LazyView shouldUpdate={shouldUpdate}>\n {children({ animationValue })}\n </LazyView>\n </Animated.View>\n );\n};\n"]}
@@ -1,84 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ParallaxLayout = void 0;
7
-
8
- var _react = _interopRequireDefault(require("react"));
9
-
10
- var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
11
-
12
- var _LazyView = require("../components/LazyView");
13
-
14
- var _useOffsetX = require("../hooks/useOffsetX");
15
-
16
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
-
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
-
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
-
22
- const ParallaxLayout = props => {
23
- const {
24
- handlerOffset,
25
- parallaxScrollingOffset = 100,
26
- parallaxScrollingScale = 0.8,
27
- parallaxAdjacentItemScale = parallaxScrollingScale ** 2,
28
- index,
29
- width,
30
- height,
31
- loop,
32
- dataLength,
33
- children,
34
- visibleRanges,
35
- vertical
36
- } = props;
37
-
38
- const [shouldUpdate, setShouldUpdate] = _react.default.useState(false);
39
-
40
- const size = props.vertical ? props.height : props.width;
41
- const x = (0, _useOffsetX.useOffsetX)({
42
- handlerOffset,
43
- index,
44
- size,
45
- dataLength,
46
- loop
47
- }, visibleRanges);
48
- const offsetXStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
49
- const value = x.value / size;
50
- const translate = (0, _reactNativeReanimated.interpolate)(value, [-1, 0, 1], [-size + parallaxScrollingOffset, 0, size - parallaxScrollingOffset], _reactNativeReanimated.Extrapolate.EXTEND);
51
- const zIndex = (0, _reactNativeReanimated.interpolate)(value, [-1, 0, 1], [0, size, 0], _reactNativeReanimated.Extrapolate.CLAMP);
52
- const scale = (0, _reactNativeReanimated.interpolate)(value, [-1, 0, 1], [parallaxAdjacentItemScale, parallaxScrollingScale, parallaxAdjacentItemScale], _reactNativeReanimated.Extrapolate.CLAMP);
53
- return {
54
- transform: [vertical ? {
55
- translateY: translate
56
- } : {
57
- translateX: translate
58
- }, {
59
- scale
60
- }],
61
- zIndex
62
- };
63
- }, [loop, vertical, parallaxScrollingOffset]);
64
-
65
- const updateView = _react.default.useCallback((negativeRange, positiveRange) => {
66
- setShouldUpdate(index >= negativeRange[0] && index <= negativeRange[1] || index >= positiveRange[0] && index <= positiveRange[1]);
67
- }, [index]);
68
-
69
- (0, _reactNativeReanimated.useAnimatedReaction)(() => visibleRanges.value, () => {
70
- (0, _reactNativeReanimated.runOnJS)(updateView)(visibleRanges.value.negativeRange, visibleRanges.value.positiveRange);
71
- }, [visibleRanges.value]);
72
- return /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
73
- style: [{
74
- width: width || "100%",
75
- height: height || "100%",
76
- position: "absolute"
77
- }, offsetXStyle]
78
- }, /*#__PURE__*/_react.default.createElement(_LazyView.LazyView, {
79
- shouldUpdate: shouldUpdate
80
- }, children));
81
- };
82
-
83
- exports.ParallaxLayout = ParallaxLayout;
84
- //# sourceMappingURL=ParallaxLayout.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["ParallaxLayout.tsx"],"names":["ParallaxLayout","props","handlerOffset","parallaxScrollingOffset","parallaxScrollingScale","parallaxAdjacentItemScale","index","width","height","loop","dataLength","children","visibleRanges","vertical","shouldUpdate","setShouldUpdate","React","useState","size","x","offsetXStyle","value","translate","Extrapolate","EXTEND","zIndex","CLAMP","scale","transform","translateY","translateX","updateView","useCallback","negativeRange","positiveRange","position"],"mappings":"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","sourcesContent":["import type { PropsWithChildren } from \"react\";\nimport React from \"react\";\nimport Animated, {\n Extrapolate,\n interpolate,\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n} from \"react-native-reanimated\";\n\nimport type { ILayoutConfig } from \"./parallax\";\n\nimport { LazyView } from \"../components/LazyView\";\nimport { useOffsetX } from \"../hooks/useOffsetX\";\nimport type { IVisibleRanges } from \"../hooks/useVisibleRanges\";\nimport type { IComputedDirectionTypes } from \"../types\";\n\nexport const ParallaxLayout: React.FC<PropsWithChildren<IComputedDirectionTypes<\n{\n loop?: boolean\n handlerOffset: Animated.SharedValue<number>\n index: number\n dataLength: number\n visibleRanges: IVisibleRanges\n} & ILayoutConfig\n>>> = (props) => {\n const {\n handlerOffset,\n parallaxScrollingOffset = 100,\n parallaxScrollingScale = 0.8,\n parallaxAdjacentItemScale = parallaxScrollingScale ** 2,\n index,\n width,\n height,\n loop,\n dataLength,\n children,\n visibleRanges,\n vertical,\n } = props;\n\n const [shouldUpdate, setShouldUpdate] = React.useState(false);\n\n const size = props.vertical ? props.height : props.width;\n\n const x = useOffsetX(\n {\n handlerOffset,\n index,\n size,\n dataLength,\n loop,\n },\n visibleRanges,\n );\n\n const offsetXStyle = useAnimatedStyle(() => {\n const value = x.value / size;\n\n const translate = interpolate(\n value,\n [-1, 0, 1],\n [\n -size + parallaxScrollingOffset,\n 0,\n size - parallaxScrollingOffset,\n ],\n Extrapolate.EXTEND,\n );\n\n const zIndex = interpolate(\n value,\n [-1, 0, 1],\n [0, size, 0],\n Extrapolate.CLAMP,\n );\n\n const scale = interpolate(\n value,\n [-1, 0, 1],\n [\n parallaxAdjacentItemScale,\n parallaxScrollingScale,\n parallaxAdjacentItemScale,\n ],\n Extrapolate.CLAMP,\n );\n\n return {\n transform: [\n vertical\n ? {\n translateY: translate,\n }\n : {\n translateX: translate,\n },\n {\n scale,\n },\n ],\n zIndex,\n };\n }, [loop, vertical, parallaxScrollingOffset]);\n\n const updateView = React.useCallback(\n (negativeRange: number[], positiveRange: number[]) => {\n setShouldUpdate(\n (index >= negativeRange[0] && index <= negativeRange[1])\n || (index >= positiveRange[0] && index <= positiveRange[1]),\n );\n },\n [index],\n );\n\n useAnimatedReaction(\n () => visibleRanges.value,\n () => {\n runOnJS(updateView)(\n visibleRanges.value.negativeRange,\n visibleRanges.value.positiveRange,\n );\n },\n [visibleRanges.value],\n );\n\n return (\n <Animated.View\n style={[\n {\n width: width || \"100%\",\n height: height || \"100%\",\n position: \"absolute\",\n },\n offsetXStyle,\n ]}\n >\n <LazyView shouldUpdate={shouldUpdate}>{children}</LazyView>\n </Animated.View>\n );\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["computeNewIndexWhenDataChanges.ts"],"names":["omitZero","a","b","computeNewIndexWhenDataChanges","params","direction","handlerOffset","_handlerOffset","size","previousLength","currentLength","positionIndex","round","isPositive","Math","abs","parseInt","String","prevOffset","prevIndex","changedLength","changedOffset"],"mappings":";;;;;;;;AAAO,SAASA,QAAT,CAAkBC,CAAlB,EAA6BC,CAA7B,EAAwC;AAC7C;;AACA,MAAID,CAAC,KAAK,CAAV,EACE,OAAO,CAAP;AAEF,SAAOC,CAAP;AACD;;AAEM,SAASC,8BAAT,CAAwCC,MAAxC,EAMJ;AACD;;AACA,QAAM;AAAEC,IAAAA,SAAF;AAAaC,IAAAA,aAAa,EAAEC,cAA5B;AAA4CC,IAAAA,IAA5C;AAAkDC,IAAAA,cAAlD;AAAkEC,IAAAA;AAAlE,MAAoFN,MAA1F;AAEA,MAAIE,aAAa,GAAGC,cAApB;AACA,MAAII,aAAJ;AACA,MAAIC,KAAJ;AAEA,QAAMC,UAAU,GAAGR,SAAS,GAAG,CAA/B;;AAEA,MAAIQ,UAAJ,EAAgB;AACdF,IAAAA,aAAa,GAAIG,IAAI,CAACC,GAAL,CAAST,aAAT,CAAD,GAA4BE,IAA5C;AACAI,IAAAA,KAAK,GAAGI,QAAQ,CAACC,MAAM,CAACjB,QAAQ,CAACS,cAAD,EAAiBE,aAAa,GAAGF,cAAjC,CAAT,CAAP,CAAhB;AACD,GAHD,MAIK;AACHE,IAAAA,aAAa,GAAG,CAACG,IAAI,CAACC,GAAL,CAAST,aAAT,IAA0BE,IAA3B,IAAmCA,IAAnD;AACAI,IAAAA,KAAK,GAAGI,QAAQ,CAACC,MAAM,CAACjB,QAAQ,CAACS,cAAD,EAAiBE,aAAa,GAAGF,cAAjC,CAAT,CAAP,CAAR,GAA6E,CAArF;AACD;;AAED,QAAMS,UAAU,GAAGlB,QAAQ,CAACS,cAAD,EAAiBE,aAAa,GAAGF,cAAjC,CAA3B;AACA,QAAMU,SAAS,GAAGN,UAAU,GAAGK,UAAH,GAAgBT,cAAc,GAAGS,UAAjB,GAA8B,CAA1E;AACA,QAAME,aAAa,GAAGR,KAAK,IAAIF,aAAa,GAAGD,cAApB,CAA3B;AACA,QAAMY,aAAa,GAAGD,aAAa,GAAGZ,IAAtC;;AACA,MAAIW,SAAS,GAAGT,aAAa,GAAG,CAA5B,IAAiCA,aAAa,GAAGD,cAArD,EAAqE;AACnE,QAAII,UAAJ,EACEP,aAAa,GAAG,CAACI,aAAa,GAAG,CAAjB,IAAsBF,IAAtB,GAA6BH,SAA7C,CADF,KAIEC,aAAa,GAAG,CAACI,aAAa,GAAG,CAAjB,IAAsBF,IAAtB,GAA6B,CAAC,CAA9C;AACH,GAND,MAOK;AACHF,IAAAA,aAAa,IAAIe,aAAa,GAAGhB,SAAjC;AACD;;AAED,SAAOC,aAAP;AACD","sourcesContent":["export function omitZero(a: number, b: number) {\n \"worklet\";\n if (a === 0)\n return 0;\n\n return b;\n}\n\nexport function computeNewIndexWhenDataChanges(params: {\n direction: number\n handlerOffset: number\n size: number\n previousLength: number\n currentLength: number\n}) {\n \"worklet\";\n const { direction, handlerOffset: _handlerOffset, size, previousLength, currentLength } = params;\n\n let handlerOffset = _handlerOffset;\n let positionIndex;\n let round;\n\n const isPositive = direction < 0;\n\n if (isPositive) {\n positionIndex = (Math.abs(handlerOffset)) / size;\n round = parseInt(String(omitZero(previousLength, positionIndex / previousLength)));\n }\n else {\n positionIndex = (Math.abs(handlerOffset) - size) / size;\n round = parseInt(String(omitZero(previousLength, positionIndex / previousLength))) + 1;\n }\n\n const prevOffset = omitZero(previousLength, positionIndex % previousLength);\n const prevIndex = isPositive ? prevOffset : previousLength - prevOffset - 1;\n const changedLength = round * (currentLength - previousLength);\n const changedOffset = changedLength * size;\n if (prevIndex > currentLength - 1 && currentLength < previousLength) {\n if (isPositive)\n handlerOffset = (currentLength - 1) * size * direction;\n\n else\n handlerOffset = (currentLength - 1) * size * -1;\n }\n else {\n handlerOffset += changedOffset * direction;\n }\n\n return handlerOffset;\n}\n\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["BaseLayout.tsx"],"names":["React","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useDerivedValue","LazyView","useCheckMounted","useOffsetX","CTX","BaseLayout","props","mounted","handlerOffset","index","children","visibleRanges","animationStyle","context","useContext","loop","dataLength","width","height","vertical","customConfig","mode","modeConfig","size","shouldUpdate","setShouldUpdate","useState","offsetXConfig","snapDirection","showLength","type","viewCount","x","animationValue","value","animatedStyle","updateView","useCallback","negativeRange","positiveRange","current","position"],"mappings":"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","sourcesContent":["import React from \"react\";\nimport type { ViewStyle } from \"react-native\";\nimport type { AnimatedStyleProp } from \"react-native-reanimated\";\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useDerivedValue,\n} from \"react-native-reanimated\";\n\nimport type { ILayoutConfig } from \"./stack\";\n\nimport { LazyView } from \"../components/LazyView\";\nimport { useCheckMounted } from \"../hooks/useCheckMounted\";\nimport type { IOpts } from \"../hooks/useOffsetX\";\nimport { useOffsetX } from \"../hooks/useOffsetX\";\nimport type { IVisibleRanges } from \"../hooks/useVisibleRanges\";\nimport { CTX } from \"../store\";\n\nexport type TAnimationStyle = (value: number) => AnimatedStyleProp<ViewStyle>;\n\nexport const BaseLayout: React.FC<{\n index: number\n handlerOffset: Animated.SharedValue<number>\n visibleRanges: IVisibleRanges\n animationStyle: TAnimationStyle\n children: (ctx: {\n animationValue: Animated.SharedValue<number>\n }) => React.ReactElement\n}> = (props) => {\n const mounted = useCheckMounted();\n const { handlerOffset, index, children, visibleRanges, animationStyle }\n = props;\n\n const context = React.useContext(CTX);\n const {\n props: {\n loop,\n dataLength,\n width,\n height,\n vertical,\n customConfig,\n mode,\n modeConfig,\n },\n } = context;\n const size = vertical ? height : width;\n const [shouldUpdate, setShouldUpdate] = React.useState(false);\n let offsetXConfig: IOpts = {\n handlerOffset,\n index,\n size,\n dataLength,\n loop,\n ...(typeof customConfig === \"function\" ? customConfig() : {}),\n };\n\n if (mode === \"horizontal-stack\") {\n const { snapDirection, showLength } = modeConfig as ILayoutConfig;\n\n offsetXConfig = {\n handlerOffset,\n index,\n size,\n dataLength,\n loop,\n type: snapDirection === \"right\" ? \"negative\" : \"positive\",\n viewCount: showLength,\n };\n }\n\n const x = useOffsetX(offsetXConfig, visibleRanges);\n const animationValue = useDerivedValue(() => x.value / size, [x, size]);\n const animatedStyle = useAnimatedStyle(\n () => animationStyle(x.value / size),\n [animationStyle],\n );\n\n const updateView = React.useCallback(\n (negativeRange: number[], positiveRange: number[]) => {\n mounted.current\n && setShouldUpdate(\n (index >= negativeRange[0] && index <= negativeRange[1])\n || (index >= positiveRange[0] && index <= positiveRange[1]),\n );\n },\n [index, mounted],\n );\n\n useAnimatedReaction(\n () => visibleRanges.value,\n () => {\n runOnJS(updateView)(\n visibleRanges.value.negativeRange,\n visibleRanges.value.positiveRange,\n );\n },\n [visibleRanges.value],\n );\n\n return (\n <Animated.View\n style={[\n {\n width: width || \"100%\",\n height: height || \"100%\",\n position: \"absolute\",\n },\n animatedStyle,\n ]}\n /**\n * We use this testID to know when the carousel item is ready to be tested in test.\n * e.g.\n * The testID of first item will be changed to __CAROUSEL_ITEM_0_READY__ from __CAROUSEL_ITEM_0_NOT_READY__ when the item is ready.\n * */\n testID={`__CAROUSEL_ITEM_${index}_${shouldUpdate ? \"READY\" : \"NOT_READY\"}__`}\n >\n <LazyView shouldUpdate={shouldUpdate}>\n {children({ animationValue })}\n </LazyView>\n </Animated.View>\n );\n};\n"]}