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

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 (148) 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 +25 -46
  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/ScrollViewGesture.js +51 -33
  9. package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
  10. package/lib/commonjs/components/rnr-demo.test.js +45 -0
  11. package/lib/commonjs/components/rnr-demo.test.js.map +1 -0
  12. package/lib/commonjs/hooks/useCarouselController.js +12 -11
  13. package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
  14. package/lib/commonjs/hooks/useCommonVariables.js +38 -12
  15. package/lib/commonjs/hooks/useCommonVariables.js.map +1 -1
  16. package/lib/commonjs/hooks/useCommonVariables.test.js +38 -0
  17. package/lib/commonjs/hooks/useCommonVariables.test.js.map +1 -0
  18. package/lib/commonjs/hooks/useLayoutConfig.js.map +1 -1
  19. package/lib/commonjs/hooks/useOffsetX.js +9 -6
  20. package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
  21. package/lib/commonjs/hooks/useOffsetX.test.js +53 -0
  22. package/lib/commonjs/hooks/useOffsetX.test.js.map +1 -0
  23. package/lib/commonjs/hooks/usePanGestureProxy.js +84 -0
  24. package/lib/commonjs/hooks/usePanGestureProxy.js.map +1 -0
  25. package/lib/commonjs/hooks/usePanGestureProxy.test.js +397 -0
  26. package/lib/commonjs/hooks/usePanGestureProxy.test.js.map +1 -0
  27. package/lib/commonjs/hooks/useUpdateGestureConfig.js.map +1 -1
  28. package/lib/commonjs/hooks/useVisibleRanges.js +48 -19
  29. package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
  30. package/lib/commonjs/hooks/useVisibleRanges.test.js +162 -0
  31. package/lib/commonjs/hooks/useVisibleRanges.test.js.map +1 -0
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/utils/{computeNewIndexWhenDataChanges.js → compute-offset-if-data-changed.js} +3 -3
  34. package/lib/commonjs/utils/compute-offset-if-data-changed.js.map +1 -0
  35. package/lib/commonjs/utils/compute-offset-if-data-changed.test.js +30 -0
  36. package/lib/commonjs/utils/compute-offset-if-data-changed.test.js.map +1 -0
  37. package/lib/commonjs/utils/compute-offset-if-size-changed.js +18 -0
  38. package/lib/commonjs/utils/compute-offset-if-size-changed.js.map +1 -0
  39. package/lib/commonjs/utils/compute-offset-if-size-changed.test.js +72 -0
  40. package/lib/commonjs/utils/compute-offset-if-size-changed.test.js.map +1 -0
  41. package/lib/commonjs/utils/handleroffset-direction.js +5 -5
  42. package/lib/commonjs/utils/handleroffset-direction.js.map +1 -1
  43. package/lib/commonjs/utils/handleroffset-direction.test.js +46 -0
  44. package/lib/commonjs/utils/handleroffset-direction.test.js.map +1 -0
  45. package/lib/commonjs/utils/index.test.js +6 -6
  46. package/lib/commonjs/utils/index.test.js.map +1 -1
  47. package/lib/module/{layouts → components}/BaseLayout.js +6 -16
  48. package/lib/module/components/BaseLayout.js.map +1 -0
  49. package/lib/module/components/Carousel.js +24 -42
  50. package/lib/module/components/Carousel.js.map +1 -1
  51. package/lib/module/components/ItemRenderer.js +62 -0
  52. package/lib/module/components/ItemRenderer.js.map +1 -0
  53. package/lib/module/components/ScrollViewGesture.js +53 -34
  54. package/lib/module/components/ScrollViewGesture.js.map +1 -1
  55. package/lib/module/components/rnr-demo.test.js +33 -0
  56. package/lib/module/components/rnr-demo.test.js.map +1 -0
  57. package/lib/module/hooks/useCarouselController.js +12 -11
  58. package/lib/module/hooks/useCarouselController.js.map +1 -1
  59. package/lib/module/hooks/useCommonVariables.js +38 -8
  60. package/lib/module/hooks/useCommonVariables.js.map +1 -1
  61. package/lib/module/hooks/useCommonVariables.test.js +34 -0
  62. package/lib/module/hooks/useCommonVariables.test.js.map +1 -0
  63. package/lib/module/hooks/useLayoutConfig.js.map +1 -1
  64. package/lib/module/hooks/useOffsetX.js +9 -6
  65. package/lib/module/hooks/useOffsetX.js.map +1 -1
  66. package/lib/module/hooks/useOffsetX.test.js +48 -0
  67. package/lib/module/hooks/useOffsetX.test.js.map +1 -0
  68. package/lib/module/hooks/usePanGestureProxy.js +71 -0
  69. package/lib/module/hooks/usePanGestureProxy.js.map +1 -0
  70. package/lib/module/hooks/usePanGestureProxy.test.js +383 -0
  71. package/lib/module/hooks/usePanGestureProxy.test.js.map +1 -0
  72. package/lib/module/hooks/useUpdateGestureConfig.js.map +1 -1
  73. package/lib/module/hooks/useVisibleRanges.js +47 -19
  74. package/lib/module/hooks/useVisibleRanges.js.map +1 -1
  75. package/lib/module/hooks/useVisibleRanges.test.js +157 -0
  76. package/lib/module/hooks/useVisibleRanges.test.js.map +1 -0
  77. package/lib/module/index.js.map +1 -1
  78. package/lib/module/utils/{computeNewIndexWhenDataChanges.js → compute-offset-if-data-changed.js} +2 -2
  79. package/lib/module/utils/compute-offset-if-data-changed.js.map +1 -0
  80. package/lib/module/utils/compute-offset-if-data-changed.test.js +27 -0
  81. package/lib/module/utils/compute-offset-if-data-changed.test.js.map +1 -0
  82. package/lib/module/utils/compute-offset-if-size-changed.js +11 -0
  83. package/lib/module/utils/compute-offset-if-size-changed.js.map +1 -0
  84. package/lib/module/utils/compute-offset-if-size-changed.test.js +69 -0
  85. package/lib/module/utils/compute-offset-if-size-changed.test.js.map +1 -0
  86. package/lib/module/utils/handleroffset-direction.js +5 -5
  87. package/lib/module/utils/handleroffset-direction.js.map +1 -1
  88. package/lib/module/utils/handleroffset-direction.test.js +41 -0
  89. package/lib/module/utils/handleroffset-direction.test.js.map +1 -0
  90. package/lib/module/utils/index.test.js +6 -6
  91. package/lib/module/utils/index.test.js.map +1 -1
  92. package/lib/typescript/components/ItemRenderer.d.ts +22 -0
  93. package/lib/typescript/components/ScrollViewGesture.d.ts +1 -1
  94. package/lib/typescript/components/rnr-demo.test.d.ts +1 -0
  95. package/lib/typescript/hooks/useCarouselController.d.ts +3 -2
  96. package/lib/typescript/hooks/useCommonVariables.test.d.ts +1 -0
  97. package/lib/typescript/hooks/useLayoutConfig.d.ts +1 -1
  98. package/lib/typescript/hooks/useOffsetX.test.d.ts +1 -0
  99. package/lib/typescript/hooks/usePanGestureProxy.d.ts +9 -0
  100. package/lib/typescript/hooks/usePanGestureProxy.test.d.ts +1 -0
  101. package/lib/typescript/hooks/useUpdateGestureConfig.d.ts +3 -2
  102. package/lib/typescript/hooks/useVisibleRanges.d.ts +8 -4
  103. package/lib/typescript/hooks/useVisibleRanges.test.d.ts +1 -0
  104. package/lib/typescript/index.d.ts +1 -0
  105. package/lib/typescript/types.d.ts +13 -4
  106. package/lib/typescript/utils/{computeNewIndexWhenDataChanges.d.ts → compute-offset-if-data-changed.d.ts} +1 -1
  107. package/lib/typescript/utils/compute-offset-if-data-changed.test.d.ts +1 -0
  108. package/lib/typescript/utils/compute-offset-if-size-changed.d.ts +5 -0
  109. package/lib/typescript/utils/compute-offset-if-size-changed.test.d.ts +1 -0
  110. package/lib/typescript/utils/handleroffset-direction.d.ts +2 -1
  111. package/lib/typescript/utils/handleroffset-direction.test.d.ts +1 -0
  112. package/package.json +16 -59
  113. package/src/{layouts → components}/BaseLayout.tsx +7 -35
  114. package/src/components/Carousel.tsx +24 -58
  115. package/src/components/ItemRenderer.tsx +105 -0
  116. package/src/components/ScrollViewGesture.tsx +74 -49
  117. package/src/components/rnr-demo.test.tsx +43 -0
  118. package/src/hooks/useCarouselController.tsx +24 -21
  119. package/src/hooks/useCommonVariables.test.tsx +41 -0
  120. package/src/hooks/useCommonVariables.ts +35 -10
  121. package/src/hooks/useLayoutConfig.ts +1 -1
  122. package/src/hooks/useOffsetX.test.ts +54 -0
  123. package/src/hooks/useOffsetX.ts +33 -31
  124. package/src/hooks/usePanGestureProxy.test.tsx +376 -0
  125. package/src/hooks/usePanGestureProxy.ts +110 -0
  126. package/src/hooks/useUpdateGestureConfig.ts +4 -2
  127. package/src/hooks/useVisibleRanges.test.tsx +179 -0
  128. package/src/hooks/useVisibleRanges.tsx +72 -24
  129. package/src/index.tsx +2 -0
  130. package/src/types.ts +13 -4
  131. package/src/utils/compute-offset-if-data-changed.test.ts +30 -0
  132. package/src/utils/{computeNewIndexWhenDataChanges.ts → compute-offset-if-data-changed.ts} +1 -1
  133. package/src/utils/compute-offset-if-size-changed.test.ts +78 -0
  134. package/src/utils/compute-offset-if-size-changed.ts +11 -0
  135. package/src/utils/handleroffset-direction.test.ts +52 -0
  136. package/src/utils/handleroffset-direction.ts +12 -9
  137. package/src/utils/index.test.ts +6 -6
  138. package/lib/commonjs/layouts/BaseLayout.js.map +0 -1
  139. package/lib/commonjs/layouts/ParallaxLayout.js +0 -84
  140. package/lib/commonjs/layouts/ParallaxLayout.js.map +0 -1
  141. package/lib/commonjs/utils/computeNewIndexWhenDataChanges.js.map +0 -1
  142. package/lib/module/layouts/BaseLayout.js.map +0 -1
  143. package/lib/module/layouts/ParallaxLayout.js +0 -61
  144. package/lib/module/layouts/ParallaxLayout.js.map +0 -1
  145. package/lib/module/utils/computeNewIndexWhenDataChanges.js.map +0 -1
  146. package/lib/typescript/layouts/ParallaxLayout.d.ts +0 -13
  147. package/src/layouts/ParallaxLayout.tsx +0 -141
  148. /package/lib/typescript/{layouts → components}/BaseLayout.d.ts +0 -0
@@ -137,10 +137,19 @@ export declare type TCarouselProps<T = any> = {
137
137
  testID?: string;
138
138
  /**
139
139
  * Maximum offset value for once scroll.
140
- * props.vertical = true => maxScrollDistancePerSwipeY
141
- * props.vertical = false => maxScrollDistancePerSwipeX
140
+ * Carousel cannot scroll over than this value.
142
141
  * */
143
142
  maxScrollDistancePerSwipe?: number;
143
+ /**
144
+ * Minimum offset value for once scroll.
145
+ * If the translation value is less than this value, the carousel will not scroll.
146
+ * */
147
+ minScrollDistancePerSwipe?: number;
148
+ /**
149
+ * @experimental This API will be changed in the future.
150
+ * If positive, the carousel will scroll to the positive direction and vice versa.
151
+ * */
152
+ fixedDirection?: "positive" | "negative";
144
153
  /**
145
154
  * Custom carousel config.
146
155
  */
@@ -159,9 +168,9 @@ export declare type TCarouselProps<T = any> = {
159
168
  */
160
169
  onSnapToItem?: (index: number) => void;
161
170
  /**
162
- * On scroll begin
171
+ * On scroll start
163
172
  */
164
- onScrollBegin?: () => void;
173
+ onScrollStart?: () => void;
165
174
  /**
166
175
  * On scroll end
167
176
  */
@@ -1,5 +1,5 @@
1
1
  export declare function omitZero(a: number, b: number): number;
2
- export declare function computeNewIndexWhenDataChanges(params: {
2
+ export declare function computeOffsetIfDataChanged(params: {
3
3
  direction: number;
4
4
  handlerOffset: number;
5
5
  size: number;
@@ -0,0 +1,5 @@
1
+ export declare function computeOffsetIfSizeChanged(params: {
2
+ handlerOffset: number;
3
+ prevSize: number;
4
+ size: number;
5
+ }): number;
@@ -1,2 +1,3 @@
1
1
  import type { SharedValue } from "react-native-reanimated";
2
- export declare function handlerOffsetDirection(handlerOffset: SharedValue<number>): -1 | 1;
2
+ import type { TCarouselProps } from "../types";
3
+ export declare function handlerOffsetDirection(handlerOffset: SharedValue<number>, fixedDirection?: TCarouselProps["fixedDirection"]): -1 | 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-reanimated-carousel",
3
- "version": "4.0.0-alpha.1",
3
+ "version": "4.0.0-alpha.10",
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",
@@ -14,24 +14,13 @@
14
14
  "scripts": {
15
15
  "gif": "node scripts/makegif.js ./scripts/gif-works-directory",
16
16
  "test": "jest run src/**/*",
17
- "test:dev": "jest dev src/**/*",
17
+ "test:dev": "jest dev src/**/* --watch",
18
18
  "typescript": "tsc --noEmit",
19
19
  "lint": "eslint 'src/**/*.{js,ts,tsx}'",
20
20
  "lint:fix": "eslint 'src/**/*.{js,ts,tsx}' --fix",
21
21
  "dev": "watch 'yarn prepare' ./src",
22
22
  "prepare": "bob build",
23
- "release": "yarn prepare && dotenv release-it --no-git.requireUpstream",
24
- "preRelease": "yarn prepare && dotenv release-it --no-git.requireUpstream --preRelease=beta",
25
- "ios": "yarn --cwd exampleExpo ios",
26
- "ios:pretty": "yarn --cwd exampleExpo ios:pretty",
27
- "web": "yarn --cwd exampleExpo web",
28
- "web:pretty": "yarn --cwd exampleExpo web:pretty",
29
- "android": "yarn --cwd exampleExpo android",
30
- "android:pretty": "yarn --cwd exampleExpo android:pretty",
31
- "pods": "cd exampleExpo && pod-install --quiet",
32
- "bootstrap": "yarn && yarn pods",
33
- "deploy": "cd exampleExpo && yarn deploy",
34
- "publish": "yarn run prepare && changeset publish",
23
+ "clean": "del-cli lib",
35
24
  "version": "changeset version"
36
25
  },
37
26
  "keywords": [
@@ -39,7 +28,10 @@
39
28
  "ios",
40
29
  "android"
41
30
  ],
42
- "repository": "https://github.com/dohooo/react-native-reanimated-carousel",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/dohooo/react-native-reanimated-carousel.git"
34
+ },
43
35
  "author": "Doho <zhaodonghao586@outlook.com> (https://github.com/dohooo)",
44
36
  "license": "MIT",
45
37
  "bugs": {
@@ -50,24 +42,28 @@
50
42
  "registry": "https://registry.npmjs.org/"
51
43
  },
52
44
  "devDependencies": {
45
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
46
+ "@babel/plugin-proposal-private-methods": "^7.18.6",
53
47
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
54
48
  "@changesets/changelog-github": "^0.5.0",
55
49
  "@changesets/cli": "latest",
56
50
  "@commitlint/config-conventional": "^11.0.0",
57
51
  "@dohooo/eslint-config": "^0.0.7",
58
52
  "@react-native-community/eslint-config": "^2.0.0",
59
- "@release-it/conventional-changelog": "^2.0.0",
53
+ "@testing-library/jest-native": "^4.0.4",
54
+ "@testing-library/react-hooks": "^8.0.0",
55
+ "@testing-library/react-native": "^7.1.0",
60
56
  "@types/jest": "^29.2.5",
61
57
  "@types/react": "^18.2.15",
62
58
  "@types/react-native": "^0.66.16",
63
- "@types/react-native-snap-carousel": "^3.8.5",
64
- "babel-plugin-inline-dotenv": "^1.6.0",
59
+ "@types/react-test-renderer": "^18.0.7",
65
60
  "babel-plugin-module-resolver": "^4.1.0",
66
61
  "commitlint": "^11.0.0",
67
62
  "cz-conventional-changelog": "^3.3.0",
68
- "dotenv-cli": "^5.1.0",
63
+ "del-cli": "^5.0.0",
69
64
  "eslint": "^8.26.0",
70
65
  "eslint-config-prettier": "^7.0.0",
66
+ "eslint-plugin-jest": "^27.6.0",
71
67
  "eslint-plugin-prettier": "^3.1.3",
72
68
  "gifify": "^2.4.3",
73
69
  "husky": "^4.2.5",
@@ -80,7 +76,7 @@
80
76
  "react-native-builder-bob": "^0.18.1",
81
77
  "react-native-gesture-handler": "~2.12.0",
82
78
  "react-native-reanimated": "~3.3.0",
83
- "release-it": "^14.2.2",
79
+ "react-test-renderer": "^18.2.0",
84
80
  "sponsorkit": "^0.1.3",
85
81
  "typescript": "^4.0.8",
86
82
  "watch": "^1.0.2"
@@ -101,14 +97,6 @@
101
97
  "optional": true
102
98
  }
103
99
  },
104
- "jest": {
105
- "preset": "react-native",
106
- "modulePathIgnorePatterns": [
107
- "<rootDir>/exampleExpo/node_modules",
108
- "<rootDir>/exampleBare/node_modules",
109
- "<rootDir>/lib/"
110
- ]
111
- },
112
100
  "husky": {
113
101
  "hooks": {
114
102
  "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
@@ -120,37 +108,6 @@
120
108
  "@commitlint/config-conventional"
121
109
  ]
122
110
  },
123
- "release-it": {
124
- "git": {
125
- "commitMessage": "chore: release ${version}",
126
- "tagName": "v${version}"
127
- },
128
- "npm": {
129
- "publish": true
130
- },
131
- "github": {
132
- "release": true
133
- },
134
- "plugins": {
135
- "@release-it/conventional-changelog": {
136
- "preset": {
137
- "name": "angular",
138
- "types": [
139
- {
140
- "type": "feat",
141
- "section": "Features"
142
- },
143
- {
144
- "type": "fix",
145
- "section": "Bug Fixes"
146
- },
147
- {}
148
- ]
149
- },
150
- "infile": "CHANGELOG.md"
151
- }
152
- }
153
- },
154
111
  "react-native-builder-bob": {
155
112
  "source": "src",
156
113
  "output": "lib",
@@ -2,19 +2,14 @@ import React from "react";
2
2
  import type { ViewStyle } from "react-native";
3
3
  import type { AnimatedStyleProp } from "react-native-reanimated";
4
4
  import Animated, {
5
- runOnJS,
6
- useAnimatedReaction,
7
5
  useAnimatedStyle,
8
6
  useDerivedValue,
9
7
  } from "react-native-reanimated";
10
8
 
11
- import type { ILayoutConfig } from "./stack";
12
-
13
- import { LazyView } from "../components/LazyView";
14
- import { useCheckMounted } from "../hooks/useCheckMounted";
15
9
  import type { IOpts } from "../hooks/useOffsetX";
16
10
  import { useOffsetX } from "../hooks/useOffsetX";
17
11
  import type { IVisibleRanges } from "../hooks/useVisibleRanges";
12
+ import type { ILayoutConfig } from "../layouts/stack";
18
13
  import { CTX } from "../store";
19
14
 
20
15
  export type TAnimationStyle = (value: number) => AnimatedStyleProp<ViewStyle>;
@@ -28,9 +23,8 @@ export const BaseLayout: React.FC<{
28
23
  animationValue: Animated.SharedValue<number>
29
24
  }) => React.ReactElement
30
25
  }> = (props) => {
31
- const mounted = useCheckMounted();
32
26
  const { handlerOffset, index, children, visibleRanges, animationStyle }
33
- = props;
27
+ = props;
34
28
 
35
29
  const context = React.useContext(CTX);
36
30
  const {
@@ -46,7 +40,7 @@ export const BaseLayout: React.FC<{
46
40
  },
47
41
  } = context;
48
42
  const size = vertical ? height : width;
49
- const [shouldUpdate, setShouldUpdate] = React.useState(false);
43
+
50
44
  let offsetXConfig: IOpts = {
51
45
  handlerOffset,
52
46
  index,
@@ -73,30 +67,10 @@ export const BaseLayout: React.FC<{
73
67
  const x = useOffsetX(offsetXConfig, visibleRanges);
74
68
  const animationValue = useDerivedValue(() => x.value / size, [x, size]);
75
69
  const animatedStyle = useAnimatedStyle(
76
- () => animationStyle(x.value / size),
77
- [animationStyle],
78
- );
79
-
80
- const updateView = React.useCallback(
81
- (negativeRange: number[], positiveRange: number[]) => {
82
- mounted.current
83
- && setShouldUpdate(
84
- (index >= negativeRange[0] && index <= negativeRange[1])
85
- || (index >= positiveRange[0] && index <= positiveRange[1]),
86
- );
87
- },
88
- [index, mounted],
89
- );
90
-
91
- useAnimatedReaction(
92
- () => visibleRanges.value,
93
70
  () => {
94
- runOnJS(updateView)(
95
- visibleRanges.value.negativeRange,
96
- visibleRanges.value.positiveRange,
97
- );
71
+ return animationStyle(x.value / size);
98
72
  },
99
- [visibleRanges.value],
73
+ [animationStyle],
100
74
  );
101
75
 
102
76
  return (
@@ -114,11 +88,9 @@ export const BaseLayout: React.FC<{
114
88
  * e.g.
115
89
  * The testID of first item will be changed to __CAROUSEL_ITEM_0_READY__ from __CAROUSEL_ITEM_0_NOT_READY__ when the item is ready.
116
90
  * */
117
- testID={`__CAROUSEL_ITEM_${index}_${shouldUpdate ? "READY" : "NOT_READY"}__`}
91
+ testID={`__CAROUSEL_ITEM_${index}__`}
118
92
  >
119
- <LazyView shouldUpdate={shouldUpdate}>
120
- {children({ animationValue })}
121
- </LazyView>
93
+ {children({ animationValue })}
122
94
  </Animated.View>
123
95
  );
124
96
  };
@@ -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 { ItemRenderer } from "./ItemRenderer";
6
7
  import { ScrollViewGesture } from "./ScrollViewGesture";
7
8
 
8
9
  import { useAutoPlay } from "../hooks/useAutoPlay";
@@ -12,8 +13,6 @@ import { useInitProps } from "../hooks/useInitProps";
12
13
  import { useLayoutConfig } from "../hooks/useLayoutConfig";
13
14
  import { useOnProgressChange } from "../hooks/useOnProgressChange";
14
15
  import { usePropsErrorBoundary } from "../hooks/usePropsErrorBoundary";
15
- import { useVisibleRanges } from "../hooks/useVisibleRanges";
16
- import { BaseLayout } from "../layouts/BaseLayout";
17
16
  import { CTX } from "../store";
18
17
  import type { ICarouselInstance, TCarouselProps } from "../types";
19
18
  import { computedRealIndexWithAutoFillData } from "../utils/computed-with-auto-fill-data";
@@ -30,8 +29,6 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
30
29
  data,
31
30
  // Length of fill data
32
31
  dataLength,
33
- // Raw data that has not been processed
34
- rawData,
35
32
  // Length of raw data
36
33
  rawDataLength,
37
34
  mode,
@@ -45,10 +42,11 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
45
42
  autoPlayInterval,
46
43
  scrollAnimationDuration,
47
44
  withAnimation,
45
+ fixedDirection,
48
46
  renderItem,
49
47
  onScrollEnd,
50
48
  onSnapToItem,
51
- onScrollBegin,
49
+ onScrollStart,
52
50
  onProgressChange,
53
51
  customAnimation,
54
52
  defaultIndex,
@@ -85,9 +83,10 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
85
83
  handlerOffset,
86
84
  withAnimation,
87
85
  defaultIndex,
88
- onScrollEnd: () => runOnJS(_onScrollEnd)(),
89
- onScrollBegin: () => !!onScrollBegin && runOnJS(onScrollBegin)(),
86
+ fixedDirection,
90
87
  duration: scrollAnimationDuration,
88
+ onScrollEnd: () => runOnJS(_onScrollEnd)(),
89
+ onScrollStart: () => !!onScrollStart && runOnJS(onScrollStart)(),
91
90
  });
92
91
 
93
92
  const { next, prev, scrollTo, getSharedIndex, getCurrentIndex }
@@ -124,10 +123,10 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
124
123
  onScrollEnd,
125
124
  ]);
126
125
 
127
- const scrollViewGestureOnScrollBegin = React.useCallback(() => {
126
+ const scrollViewGestureOnScrollStart = React.useCallback(() => {
128
127
  pauseAutoPlay();
129
- onScrollBegin?.();
130
- }, [onScrollBegin, pauseAutoPlay]);
128
+ onScrollStart?.();
129
+ }, [onScrollStart, pauseAutoPlay]);
131
130
 
132
131
  const scrollViewGestureOnScrollEnd = React.useCallback(() => {
133
132
  startAutoPlay();
@@ -153,54 +152,8 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
153
152
  [getCurrentIndex, next, prev, scrollTo],
154
153
  );
155
154
 
156
- const visibleRanges = useVisibleRanges({
157
- total: dataLength,
158
- viewSize: size,
159
- translation: handlerOffset,
160
- windowSize,
161
- });
162
-
163
155
  const layoutConfig = useLayoutConfig({ ...props, size });
164
156
 
165
- const renderLayout = React.useCallback(
166
- (item: any, i: number) => {
167
- const realIndex = computedRealIndexWithAutoFillData({
168
- index: i,
169
- dataLength: rawDataLength,
170
- loop,
171
- autoFillData,
172
- });
173
-
174
- return (
175
- <BaseLayout
176
- key={i}
177
- index={i}
178
- handlerOffset={offsetX}
179
- visibleRanges={visibleRanges}
180
- animationStyle={customAnimation || layoutConfig}
181
- >
182
- {({ animationValue }) =>
183
- renderItem({
184
- item,
185
- index: realIndex,
186
- animationValue,
187
- })
188
- }
189
- </BaseLayout>
190
- );
191
- },
192
- [
193
- loop,
194
- rawData,
195
- offsetX,
196
- visibleRanges,
197
- autoFillData,
198
- renderItem,
199
- layoutConfig,
200
- customAnimation,
201
- ],
202
- );
203
-
204
157
  return (
205
158
  <GestureHandlerRootView>
206
159
  <CTX.Provider value={{ props, common: commonVariables }}>
@@ -220,12 +173,25 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
220
173
  : styles.itemsHorizontal,
221
174
  ]}
222
175
  testID={testID}
223
- onScrollBegin={scrollViewGestureOnScrollBegin}
176
+ onScrollStart={scrollViewGestureOnScrollStart}
224
177
  onScrollEnd={scrollViewGestureOnScrollEnd}
225
178
  onTouchBegin={scrollViewGestureOnTouchBegin}
226
179
  onTouchEnd={scrollViewGestureOnTouchEnd}
227
180
  >
228
- {data.map(renderLayout)}
181
+ <ItemRenderer
182
+ data={data}
183
+ dataLength={dataLength}
184
+ rawDataLength={rawDataLength}
185
+ loop={loop}
186
+ size={size}
187
+ windowSize={windowSize}
188
+ autoFillData={autoFillData}
189
+ offsetX={offsetX}
190
+ handlerOffset={handlerOffset}
191
+ layoutConfig={layoutConfig}
192
+ renderItem={renderItem}
193
+ customAnimation={customAnimation}
194
+ />
229
195
  </ScrollViewGesture>
230
196
  </CTX.Provider>
231
197
  </GestureHandlerRootView>
@@ -0,0 +1,105 @@
1
+ import React from "react";
2
+ import type { FC } from "react";
3
+ import type { ViewStyle } from "react-native";
4
+ import type Animated from "react-native-reanimated";
5
+ import { useAnimatedReaction, type AnimatedStyleProp, runOnJS } from "react-native-reanimated";
6
+
7
+ import type { TAnimationStyle } from "./BaseLayout";
8
+ import { BaseLayout } from "./BaseLayout";
9
+
10
+ import type { VisibleRanges } from "../hooks/useVisibleRanges";
11
+ import { useVisibleRanges } from "../hooks/useVisibleRanges";
12
+ import type { CarouselRenderItem } from "../types";
13
+ import { computedRealIndexWithAutoFillData } from "../utils/computed-with-auto-fill-data";
14
+
15
+ interface Props {
16
+ data: any[]
17
+ dataLength: number
18
+ rawDataLength: number
19
+ loop: boolean
20
+ size: number
21
+ windowSize?: number
22
+ autoFillData: boolean
23
+ offsetX: Animated.SharedValue<number>
24
+ handlerOffset: Animated.SharedValue<number>
25
+ layoutConfig: TAnimationStyle
26
+ renderItem: CarouselRenderItem<any>
27
+ customAnimation?: ((value: number) => AnimatedStyleProp<ViewStyle>)
28
+ }
29
+
30
+ export const ItemRenderer: FC<Props> = (props) => {
31
+ const {
32
+ data,
33
+ size,
34
+ windowSize,
35
+ handlerOffset,
36
+ offsetX,
37
+ dataLength,
38
+ rawDataLength,
39
+ loop,
40
+ autoFillData,
41
+ layoutConfig,
42
+ renderItem,
43
+ customAnimation,
44
+ } = props;
45
+
46
+ const visibleRanges = useVisibleRanges({
47
+ total: dataLength,
48
+ viewSize: size,
49
+ translation: handlerOffset,
50
+ windowSize,
51
+ loop,
52
+ });
53
+
54
+ const [displayedItems, setDisplayedItems] = React.useState<VisibleRanges>(null!);
55
+
56
+ useAnimatedReaction(
57
+ () => visibleRanges.value,
58
+ ranges => runOnJS(setDisplayedItems)(ranges),
59
+ [visibleRanges],
60
+ );
61
+
62
+ if (!displayedItems)
63
+ return null;
64
+
65
+ return (
66
+ <>
67
+ {
68
+ data.map((item, index) => {
69
+ const realIndex = computedRealIndexWithAutoFillData({
70
+ index,
71
+ dataLength: rawDataLength,
72
+ loop,
73
+ autoFillData,
74
+ });
75
+
76
+ const { negativeRange, positiveRange } = displayedItems;
77
+
78
+ const shouldRender = (index >= negativeRange[0] && index <= negativeRange[1])
79
+ || (index >= positiveRange[0] && index <= positiveRange[1]);
80
+
81
+ if (!shouldRender)
82
+ return null;
83
+
84
+ return (
85
+ <BaseLayout
86
+ key={index}
87
+ index={index}
88
+ handlerOffset={offsetX}
89
+ visibleRanges={visibleRanges}
90
+ animationStyle={customAnimation || layoutConfig}
91
+ >
92
+ {({ animationValue }) =>
93
+ renderItem({
94
+ item,
95
+ index: realIndex,
96
+ animationValue,
97
+ })
98
+ }
99
+ </BaseLayout>
100
+ );
101
+ })
102
+ }
103
+ </>
104
+ );
105
+ };