react-native-reanimated-carousel 2.3.8 → 2.3.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 (59) hide show
  1. package/lib/commonjs/Carousel.js +1 -1
  2. package/lib/commonjs/Carousel.js.map +1 -1
  3. package/lib/commonjs/ScrollViewGesture.js +1 -1
  4. package/lib/commonjs/ScrollViewGesture.js.map +1 -1
  5. package/lib/commonjs/hooks/useAutoPlay.js +1 -1
  6. package/lib/commonjs/hooks/useAutoPlay.js.map +1 -1
  7. package/lib/commonjs/hooks/useCarouselController.js +1 -1
  8. package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
  9. package/lib/commonjs/hooks/useCommonVariables.js +1 -1
  10. package/lib/commonjs/hooks/useCommonVariables.js.map +1 -1
  11. package/lib/commonjs/utils/computedWithAutoFillData.js +1 -1
  12. package/lib/commonjs/utils/computedWithAutoFillData.js.map +1 -1
  13. package/lib/module/Carousel.js +40 -25
  14. package/lib/module/Carousel.js.map +1 -1
  15. package/lib/module/ScrollViewGesture.js +8 -10
  16. package/lib/module/ScrollViewGesture.js.map +1 -1
  17. package/lib/module/hooks/useAutoPlay.js +7 -3
  18. package/lib/module/hooks/useAutoPlay.js.map +1 -1
  19. package/lib/module/hooks/useCarouselController.js +35 -44
  20. package/lib/module/hooks/useCarouselController.js.map +1 -1
  21. package/lib/module/hooks/useCommonVariables.js +2 -3
  22. package/lib/module/hooks/useCommonVariables.js.map +1 -1
  23. package/lib/module/utils/computedWithAutoFillData.js +25 -0
  24. package/lib/module/utils/computedWithAutoFillData.js.map +1 -1
  25. package/lib/typescript/{src/Carousel.d.ts → Carousel.d.ts} +0 -0
  26. package/lib/typescript/{src/LazyView.d.ts → LazyView.d.ts} +0 -0
  27. package/lib/typescript/{src/ScrollViewGesture.d.ts → ScrollViewGesture.d.ts} +0 -0
  28. package/lib/typescript/{src/constants → constants}/index.d.ts +0 -0
  29. package/lib/typescript/{src/hooks → hooks}/useAutoPlay.d.ts +0 -0
  30. package/lib/typescript/{src/hooks → hooks}/useCarouselController.d.ts +4 -10
  31. package/lib/typescript/{src/hooks → hooks}/useCheckMounted.d.ts +0 -0
  32. package/lib/typescript/{src/hooks → hooks}/useCommonVariables.d.ts +0 -0
  33. package/lib/typescript/{src/hooks → hooks}/useInitProps.d.ts +0 -0
  34. package/lib/typescript/{src/hooks → hooks}/useLayoutConfig.d.ts +0 -0
  35. package/lib/typescript/{src/hooks → hooks}/useOffsetX.d.ts +0 -0
  36. package/lib/typescript/{src/hooks → hooks}/useOnProgressChange.d.ts +0 -0
  37. package/lib/typescript/{src/hooks → hooks}/usePropsErrorBoundary.d.ts +0 -0
  38. package/lib/typescript/{src/hooks → hooks}/useVisibleRanges.d.ts +0 -0
  39. package/lib/typescript/{src/index.d.ts → index.d.ts} +0 -0
  40. package/lib/typescript/{src/layouts → layouts}/BaseLayout.d.ts +0 -0
  41. package/lib/typescript/{src/layouts → layouts}/ParallaxLayout.d.ts +0 -0
  42. package/lib/typescript/{src/layouts → layouts}/index.d.ts +0 -0
  43. package/lib/typescript/{src/layouts → layouts}/normal.d.ts +0 -0
  44. package/lib/typescript/{src/layouts → layouts}/parallax.d.ts +0 -0
  45. package/lib/typescript/{src/layouts → layouts}/stack.d.ts +0 -0
  46. package/lib/typescript/{src/store → store}/index.d.ts +0 -0
  47. package/lib/typescript/{src/types.d.ts → types.d.ts} +5 -0
  48. package/lib/typescript/{src/utils → utils}/computedWithAutoFillData.d.ts +4 -0
  49. package/lib/typescript/{src/utils → utils}/dealWithAnimation.d.ts +0 -0
  50. package/lib/typescript/{src/utils → utils}/log.d.ts +0 -0
  51. package/package.json +3 -3
  52. package/src/Carousel.tsx +43 -29
  53. package/src/ScrollViewGesture.tsx +7 -9
  54. package/src/hooks/useAutoPlay.ts +4 -3
  55. package/src/hooks/useCarouselController.tsx +55 -62
  56. package/src/hooks/useCommonVariables.ts +2 -2
  57. package/src/types.ts +4 -0
  58. package/src/utils/computedWithAutoFillData.ts +18 -0
  59. package/lib/typescript/exampleBare/App.d.ts +0 -2
@@ -10,6 +10,31 @@ function isAutoFillData(params) {
10
10
  return !!params.loop && !!params.autoFillData;
11
11
  }
12
12
 
13
+ export function convertToSharedIndex(params) {
14
+ 'worklet';
15
+
16
+ const {
17
+ loop,
18
+ rawDataLength,
19
+ index,
20
+ autoFillData
21
+ } = params;
22
+
23
+ if (isAutoFillData({
24
+ loop,
25
+ autoFillData
26
+ })) {
27
+ switch (rawDataLength) {
28
+ case SINGLE_ITEM:
29
+ return 0;
30
+
31
+ case DOUBLE_ITEM:
32
+ return index % 2;
33
+ }
34
+ }
35
+
36
+ return index;
37
+ }
13
38
  export function computedOffsetXValueWithAutoFillData(params) {
14
39
  'worklet';
15
40
 
@@ -1 +1 @@
1
- {"version":3,"sources":["computedWithAutoFillData.ts"],"names":["DATA_LENGTH","SINGLE_ITEM","DOUBLE_ITEM","isAutoFillData","params","loop","autoFillData","computedOffsetXValueWithAutoFillData","rawDataLength","value","size","computedRealIndexWithAutoFillData","index","dataLength","computedFillDataWithAutoFillData","data"],"mappings":"AAAA,SAASA,WAAT,QAA4B,eAA5B;AAEA,MAAM;AAAEC,EAAAA,WAAF;AAAeC,EAAAA;AAAf,IAA+BF,WAArC;;AAEA,SAASG,cAAT,CAAwBC,MAAxB,EAA0E;AACtE;;AACA,SAAO,CAAC,CAACA,MAAM,CAACC,IAAT,IAAiB,CAAC,CAACD,MAAM,CAACE,YAAjC;AACH;;AAOD,OAAO,SAASC,oCAAT,CACHH,MADG,EAML;AACE;;AAEA,QAAM;AAAEI,IAAAA,aAAF;AAAiBC,IAAAA,KAAjB;AAAwBC,IAAAA,IAAxB;AAA8BL,IAAAA,IAA9B;AAAoCC,IAAAA;AAApC,MAAqDF,MAA3D;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQE,aAAR;AACI,WAAKP,WAAL;AACI,eAAOQ,KAAK,GAAGC,IAAf;;AACJ,WAAKR,WAAL;AACI,eAAOO,KAAK,IAAIC,IAAI,GAAG,CAAX,CAAZ;AAJR;AAMH;;AAED,SAAOD,KAAP;AACH;AAED,OAAO,SAASE,iCAAT,CACHP,MADG,EAKL;AACE,QAAM;AAAEQ,IAAAA,KAAF;AAASC,IAAAA,UAAT;AAAqBR,IAAAA,IAArB;AAA2BC,IAAAA;AAA3B,MAA4CF,MAAlD;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQO,UAAR;AACI,WAAKZ,WAAL;AACI,eAAOW,KAAK,GAAG,CAAf;;AACJ,WAAKV,WAAL;AACI,eAAOU,KAAK,GAAG,CAAf;AAJR;AAMH;;AAED,SAAOA,KAAP;AACH;AAED,OAAO,SAASE,gCAAT,CACHV,MADG,EAKA;AACH,QAAM;AAAEW,IAAAA,IAAF;AAAQV,IAAAA,IAAR;AAAcC,IAAAA,YAAd;AAA4BO,IAAAA;AAA5B,MAA2CT,MAAjD;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQO,UAAR;AACI,WAAKZ,WAAL;AACI,eAAO,CAACc,IAAI,CAAC,CAAD,CAAL,EAAUA,IAAI,CAAC,CAAD,CAAd,EAAmBA,IAAI,CAAC,CAAD,CAAvB,CAAP;;AACJ,WAAKb,WAAL;AACI,eAAO,CAACa,IAAI,CAAC,CAAD,CAAL,EAAUA,IAAI,CAAC,CAAD,CAAd,EAAmBA,IAAI,CAAC,CAAD,CAAvB,EAA4BA,IAAI,CAAC,CAAD,CAAhC,CAAP;AAJR;AAMH;;AAED,SAAOA,IAAP;AACH","sourcesContent":["import { DATA_LENGTH } from 'src/constants';\n\nconst { SINGLE_ITEM, DOUBLE_ITEM } = DATA_LENGTH;\n\nfunction isAutoFillData(params: { autoFillData: boolean; loop: boolean }) {\n 'worklet';\n return !!params.loop && !!params.autoFillData;\n}\n\ntype BaseParams<T extends object = {}> = {\n autoFillData: boolean;\n loop: boolean;\n} & T;\n\nexport function computedOffsetXValueWithAutoFillData(\n params: BaseParams<{\n rawDataLength: number;\n value: number;\n size: number;\n }>\n) {\n 'worklet';\n\n const { rawDataLength, value, size, loop, autoFillData } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (rawDataLength) {\n case SINGLE_ITEM:\n return value % size;\n case DOUBLE_ITEM:\n return value % (size * 2);\n }\n }\n\n return value;\n}\n\nexport function computedRealIndexWithAutoFillData(\n params: BaseParams<{\n index: number;\n dataLength: number;\n }>\n) {\n const { index, dataLength, loop, autoFillData } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (dataLength) {\n case SINGLE_ITEM:\n return index % 1;\n case DOUBLE_ITEM:\n return index % 2;\n }\n }\n\n return index;\n}\n\nexport function computedFillDataWithAutoFillData<T>(\n params: BaseParams<{\n data: T[];\n dataLength: number;\n }>\n): T[] {\n const { data, loop, autoFillData, dataLength } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (dataLength) {\n case SINGLE_ITEM:\n return [data[0], data[0], data[0]];\n case DOUBLE_ITEM:\n return [data[0], data[1], data[0], data[1]];\n }\n }\n\n return data;\n}\n"]}
1
+ {"version":3,"sources":["computedWithAutoFillData.ts"],"names":["DATA_LENGTH","SINGLE_ITEM","DOUBLE_ITEM","isAutoFillData","params","loop","autoFillData","convertToSharedIndex","rawDataLength","index","computedOffsetXValueWithAutoFillData","value","size","computedRealIndexWithAutoFillData","dataLength","computedFillDataWithAutoFillData","data"],"mappings":"AAAA,SAASA,WAAT,QAA4B,eAA5B;AAEA,MAAM;AAAEC,EAAAA,WAAF;AAAeC,EAAAA;AAAf,IAA+BF,WAArC;;AAEA,SAASG,cAAT,CAAwBC,MAAxB,EAA0E;AACtE;;AACA,SAAO,CAAC,CAACA,MAAM,CAACC,IAAT,IAAiB,CAAC,CAACD,MAAM,CAACE,YAAjC;AACH;;AAOD,OAAO,SAASC,oBAAT,CACHH,MADG,EAEL;AACE;;AACA,QAAM;AAAEC,IAAAA,IAAF;AAAQG,IAAAA,aAAR;AAAuBC,IAAAA,KAAvB;AAA8BH,IAAAA;AAA9B,MAA+CF,MAArD;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQE,aAAR;AACI,WAAKP,WAAL;AACI,eAAO,CAAP;;AACJ,WAAKC,WAAL;AACI,eAAOO,KAAK,GAAG,CAAf;AAJR;AAMH;;AAED,SAAOA,KAAP;AACH;AAED,OAAO,SAASC,oCAAT,CACHN,MADG,EAML;AACE;;AAEA,QAAM;AAAEI,IAAAA,aAAF;AAAiBG,IAAAA,KAAjB;AAAwBC,IAAAA,IAAxB;AAA8BP,IAAAA,IAA9B;AAAoCC,IAAAA;AAApC,MAAqDF,MAA3D;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQE,aAAR;AACI,WAAKP,WAAL;AACI,eAAOU,KAAK,GAAGC,IAAf;;AACJ,WAAKV,WAAL;AACI,eAAOS,KAAK,IAAIC,IAAI,GAAG,CAAX,CAAZ;AAJR;AAMH;;AAED,SAAOD,KAAP;AACH;AAED,OAAO,SAASE,iCAAT,CACHT,MADG,EAKL;AACE,QAAM;AAAEK,IAAAA,KAAF;AAASK,IAAAA,UAAT;AAAqBT,IAAAA,IAArB;AAA2BC,IAAAA;AAA3B,MAA4CF,MAAlD;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQQ,UAAR;AACI,WAAKb,WAAL;AACI,eAAOQ,KAAK,GAAG,CAAf;;AACJ,WAAKP,WAAL;AACI,eAAOO,KAAK,GAAG,CAAf;AAJR;AAMH;;AAED,SAAOA,KAAP;AACH;AAED,OAAO,SAASM,gCAAT,CACHX,MADG,EAKA;AACH,QAAM;AAAEY,IAAAA,IAAF;AAAQX,IAAAA,IAAR;AAAcC,IAAAA,YAAd;AAA4BQ,IAAAA;AAA5B,MAA2CV,MAAjD;;AAEA,MAAID,cAAc,CAAC;AAAEE,IAAAA,IAAF;AAAQC,IAAAA;AAAR,GAAD,CAAlB,EAA4C;AACxC,YAAQQ,UAAR;AACI,WAAKb,WAAL;AACI,eAAO,CAACe,IAAI,CAAC,CAAD,CAAL,EAAUA,IAAI,CAAC,CAAD,CAAd,EAAmBA,IAAI,CAAC,CAAD,CAAvB,CAAP;;AACJ,WAAKd,WAAL;AACI,eAAO,CAACc,IAAI,CAAC,CAAD,CAAL,EAAUA,IAAI,CAAC,CAAD,CAAd,EAAmBA,IAAI,CAAC,CAAD,CAAvB,EAA4BA,IAAI,CAAC,CAAD,CAAhC,CAAP;AAJR;AAMH;;AAED,SAAOA,IAAP;AACH","sourcesContent":["import { DATA_LENGTH } from 'src/constants';\n\nconst { SINGLE_ITEM, DOUBLE_ITEM } = DATA_LENGTH;\n\nfunction isAutoFillData(params: { autoFillData: boolean; loop: boolean }) {\n 'worklet';\n return !!params.loop && !!params.autoFillData;\n}\n\ntype BaseParams<T extends object = {}> = {\n autoFillData: boolean;\n loop: boolean;\n} & T;\n\nexport function convertToSharedIndex(\n params: BaseParams<{ index: number; rawDataLength: number }>\n) {\n 'worklet';\n const { loop, rawDataLength, index, autoFillData } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (rawDataLength) {\n case SINGLE_ITEM:\n return 0;\n case DOUBLE_ITEM:\n return index % 2;\n }\n }\n\n return index;\n}\n\nexport function computedOffsetXValueWithAutoFillData(\n params: BaseParams<{\n rawDataLength: number;\n value: number;\n size: number;\n }>\n) {\n 'worklet';\n\n const { rawDataLength, value, size, loop, autoFillData } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (rawDataLength) {\n case SINGLE_ITEM:\n return value % size;\n case DOUBLE_ITEM:\n return value % (size * 2);\n }\n }\n\n return value;\n}\n\nexport function computedRealIndexWithAutoFillData(\n params: BaseParams<{\n index: number;\n dataLength: number;\n }>\n) {\n const { index, dataLength, loop, autoFillData } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (dataLength) {\n case SINGLE_ITEM:\n return index % 1;\n case DOUBLE_ITEM:\n return index % 2;\n }\n }\n\n return index;\n}\n\nexport function computedFillDataWithAutoFillData<T>(\n params: BaseParams<{\n data: T[];\n dataLength: number;\n }>\n): T[] {\n const { data, loop, autoFillData, dataLength } = params;\n\n if (isAutoFillData({ loop, autoFillData })) {\n switch (dataLength) {\n case SINGLE_ITEM:\n return [data[0], data[0], data[0]];\n case DOUBLE_ITEM:\n return [data[0], data[1], data[0], data[1]];\n }\n }\n\n return data;\n}\n"]}
@@ -1,28 +1,22 @@
1
- import React from 'react';
2
1
  import type Animated from 'react-native-reanimated';
3
2
  import type { TCarouselActionOptions, TCarouselProps } from '../types';
4
3
  interface IOpts {
5
4
  loop: boolean;
6
5
  size: number;
6
+ data: TCarouselProps['data'];
7
+ autoFillData: TCarouselProps['autoFillData'];
7
8
  handlerOffsetX: Animated.SharedValue<number>;
8
9
  withAnimation?: TCarouselProps['withAnimation'];
9
- disable?: boolean;
10
10
  duration?: number;
11
- originalLength: number;
12
- length: number;
13
11
  defaultIndex?: number;
14
12
  onScrollBegin?: () => void;
15
13
  onScrollEnd?: () => void;
16
- onChange: (index: number) => void;
17
14
  }
18
15
  export interface ICarouselController {
19
- length: number;
20
- index: Animated.SharedValue<number>;
21
- sharedIndex: React.MutableRefObject<number>;
22
- sharedPreIndex: React.MutableRefObject<number>;
16
+ sharedIndex: Animated.SharedValue<number>;
17
+ sharedPreIndex: Animated.SharedValue<number>;
23
18
  prev: (opts?: TCarouselActionOptions) => void;
24
19
  next: (opts?: TCarouselActionOptions) => void;
25
- computedIndex: () => void;
26
20
  getCurrentIndex: () => number;
27
21
  to: (index: number, animated?: boolean) => void;
28
22
  scrollTo: (opts?: TCarouselActionOptions) => void;
File without changes
File without changes
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import type { ViewStyle } from 'react-native';
2
3
  import type { PanGestureHandlerProps } from 'react-native-gesture-handler';
3
4
  import type { AnimatedStyleProp, WithSpringConfig, WithTimingConfig } from 'react-native-reanimated';
@@ -128,6 +129,10 @@ export declare type TCarouselProps<T = any> = {
128
129
  * Specifies the scrolling animation effect.
129
130
  */
130
131
  withAnimation?: WithAnimation;
132
+ /**
133
+ * Used to locate this view in end-to-end tests.
134
+ */
135
+ testID?: string;
131
136
  /**
132
137
  * Custom carousel config.
133
138
  */
@@ -2,6 +2,10 @@ declare type BaseParams<T extends object = {}> = {
2
2
  autoFillData: boolean;
3
3
  loop: boolean;
4
4
  } & T;
5
+ export declare function convertToSharedIndex(params: BaseParams<{
6
+ index: number;
7
+ rawDataLength: number;
8
+ }>): number;
5
9
  export declare function computedOffsetXValueWithAutoFillData(params: BaseParams<{
6
10
  rawDataLength: number;
7
11
  value: number;
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-reanimated-carousel",
3
- "version": "2.3.8",
3
+ "version": "2.3.11",
4
4
  "description": "Simple carousel component.fully implemented using Reanimated 2.Infinitely scrolling, very smooth.",
5
5
  "main": "lib/commonjs/index",
6
6
  "types": "lib/typescript/index.d.ts",
@@ -26,8 +26,8 @@
26
26
  "lint": "eslint \"src/**/*.{js,ts,tsx}\"",
27
27
  "dev": "yarn watch 'yarn prepare' ./src",
28
28
  "prepare": "bob build",
29
- "release": "release-it --no-git.requireUpstream",
30
- "preRelease": "release-it --no-git.requireUpstream --preRelease=beta",
29
+ "release": "yarn prepare && release-it --no-git.requireUpstream",
30
+ "preRelease": "yarn prepare && release-it --no-git.requireUpstream --preRelease=beta",
31
31
  "ios": "yarn --cwd example ios",
32
32
  "ios:pretty": "yarn --cwd example ios:pretty",
33
33
  "web": "yarn --cwd example web",
package/src/Carousel.tsx CHANGED
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
- import Animated, { runOnJS, useDerivedValue } from 'react-native-reanimated';
2
+ import Animated, {
3
+ runOnJS,
4
+ runOnUI,
5
+ useDerivedValue,
6
+ } from 'react-native-reanimated';
3
7
 
4
8
  import { useCarouselController } from './hooks/useCarouselController';
5
9
  import { useAutoPlay } from './hooks/useAutoPlay';
@@ -22,6 +26,7 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
22
26
  const props = useInitProps(_props);
23
27
 
24
28
  const {
29
+ testID,
25
30
  data,
26
31
  rawData,
27
32
  loop,
@@ -73,28 +78,27 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
73
78
  const carouselController = useCarouselController({
74
79
  loop,
75
80
  size,
81
+ data,
82
+ autoFillData,
76
83
  handlerOffsetX,
77
- length: data.length,
78
- disable: !data.length,
79
84
  withAnimation,
80
- originalLength: data.length,
81
85
  defaultIndex,
82
86
  onScrollEnd: () => runOnJS(_onScrollEnd)(),
83
87
  onScrollBegin: () => !!onScrollBegin && runOnJS(onScrollBegin)(),
84
- onChange: (i) => !!onSnapToItem && runOnJS(onSnapToItem)(i),
85
88
  duration: scrollAnimationDuration,
86
89
  });
87
90
 
88
91
  const {
92
+ sharedIndex,
93
+ sharedPreIndex,
94
+ to,
89
95
  next,
90
96
  prev,
91
- sharedPreIndex,
92
- sharedIndex,
93
- computedIndex,
97
+ scrollTo,
94
98
  getCurrentIndex,
95
99
  } = carouselController;
96
100
 
97
- const { start, pause } = useAutoPlay({
101
+ const { start: startAutoPlay, pause: pauseAutoPlay } = useAutoPlay({
98
102
  autoPlay,
99
103
  autoPlayInterval,
100
104
  autoPlayReverse,
@@ -102,29 +106,44 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
102
106
  });
103
107
 
104
108
  const _onScrollEnd = React.useCallback(() => {
105
- computedIndex();
106
- onScrollEnd?.(sharedPreIndex.current, sharedIndex.current);
107
- }, [sharedPreIndex, sharedIndex, computedIndex, onScrollEnd]);
109
+ 'worklet';
110
+ const _sharedIndex = Math.round(sharedIndex.value);
111
+ const _sharedPreIndex = Math.round(sharedPreIndex.value);
112
+
113
+ if (onSnapToItem) {
114
+ runOnJS(onSnapToItem)(_sharedIndex);
115
+ }
116
+ if (onScrollEnd) {
117
+ runOnJS(onScrollEnd)(_sharedPreIndex, _sharedIndex);
118
+ }
119
+ }, [onSnapToItem, onScrollEnd, sharedIndex, sharedPreIndex]);
108
120
 
109
121
  const scrollViewGestureOnScrollBegin = React.useCallback(() => {
110
- pause();
122
+ pauseAutoPlay();
111
123
  onScrollBegin?.();
112
- }, [onScrollBegin, pause]);
124
+ }, [onScrollBegin, pauseAutoPlay]);
113
125
 
114
126
  const scrollViewGestureOnScrollEnd = React.useCallback(() => {
115
- start();
116
- _onScrollEnd();
117
- }, [_onScrollEnd, start]);
127
+ startAutoPlay();
128
+ /**
129
+ * TODO magic
130
+ */
131
+ runOnUI(_onScrollEnd)();
132
+ }, [_onScrollEnd, startAutoPlay]);
118
133
 
119
- const scrollViewGestureOnTouchBegin = React.useCallback(pause, [pause]);
134
+ const scrollViewGestureOnTouchBegin = React.useCallback(pauseAutoPlay, [
135
+ pauseAutoPlay,
136
+ ]);
120
137
 
121
- const scrollViewGestureOnTouchEnd = React.useCallback(start, [start]);
138
+ const scrollViewGestureOnTouchEnd = React.useCallback(startAutoPlay, [
139
+ startAutoPlay,
140
+ ]);
122
141
 
123
142
  const goToIndex = React.useCallback(
124
143
  (i: number, animated?: boolean) => {
125
- carouselController.to(i, animated);
144
+ to(i, animated);
126
145
  },
127
- [carouselController]
146
+ [to]
128
147
  );
129
148
 
130
149
  React.useImperativeHandle(
@@ -134,15 +153,9 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
134
153
  prev,
135
154
  getCurrentIndex,
136
155
  goToIndex,
137
- scrollTo: carouselController.scrollTo,
156
+ scrollTo,
138
157
  }),
139
- [
140
- getCurrentIndex,
141
- goToIndex,
142
- next,
143
- prev,
144
- carouselController.scrollTo,
145
- ]
158
+ [getCurrentIndex, goToIndex, next, prev, scrollTo]
146
159
  );
147
160
 
148
161
  const visibleRanges = useVisibleRanges({
@@ -201,6 +214,7 @@ const Carousel = React.forwardRef<ICarouselInstance, TCarouselProps<any>>(
201
214
  { width: width || '100%', height: height || '100%' },
202
215
  style,
203
216
  ]}
217
+ testID={testID}
204
218
  >
205
219
  <ScrollViewGesture
206
220
  size={size}
@@ -68,24 +68,22 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
68
68
  const _withSpring = React.useCallback(
69
69
  (toValue: number, onFinished?: () => void) => {
70
70
  'worklet';
71
- const callback = (isFinished: boolean) => {
72
- 'worklet';
73
- if (isFinished) {
74
- onFinished && runOnJS(onFinished)();
75
- }
76
- };
77
-
78
71
  const defaultWithAnimation: WithTimingAnimation = {
79
72
  type: 'timing',
80
73
  config: {
81
- duration: scrollAnimationDuration,
74
+ duration: scrollAnimationDuration + 100,
82
75
  easing: Easing.easeOutQuart,
83
76
  },
84
77
  };
85
78
 
86
79
  return dealWithAnimation(withAnimation ?? defaultWithAnimation)(
87
80
  toValue,
88
- callback
81
+ (isFinished: boolean) => {
82
+ 'worklet';
83
+ if (isFinished) {
84
+ onFinished && runOnJS(onFinished)();
85
+ }
86
+ }
89
87
  );
90
88
  },
91
89
  [scrollAnimationDuration, withAnimation]
@@ -14,6 +14,7 @@ export function useAutoPlay(opts: {
14
14
  carouselController,
15
15
  } = opts;
16
16
 
17
+ const { prev, next } = carouselController;
17
18
  const timer = React.useRef<NodeJS.Timer>();
18
19
  const stopped = React.useRef<boolean>(!autoPlay);
19
20
 
@@ -25,10 +26,10 @@ export function useAutoPlay(opts: {
25
26
  timer.current && clearTimeout(timer.current);
26
27
  timer.current = setTimeout(() => {
27
28
  autoPlayReverse
28
- ? carouselController.prev({ onFinished: play })
29
- : carouselController.next({ onFinished: play });
29
+ ? prev({ onFinished: play })
30
+ : next({ onFinished: play });
30
31
  }, autoPlayInterval);
31
- }, [autoPlayReverse, autoPlayInterval, carouselController]);
32
+ }, [autoPlayReverse, autoPlayInterval, prev, next]);
32
33
 
33
34
  const pause = React.useCallback(() => {
34
35
  if (!autoPlay) {
@@ -1,38 +1,37 @@
1
1
  import React from 'react';
2
2
  import type Animated from 'react-native-reanimated';
3
3
  import { Easing } from '../constants';
4
- import { runOnJS, useSharedValue } from 'react-native-reanimated';
4
+ import {
5
+ runOnJS,
6
+ useDerivedValue,
7
+ useSharedValue,
8
+ } from 'react-native-reanimated';
5
9
  import type {
6
10
  TCarouselActionOptions,
7
11
  TCarouselProps,
8
12
  WithTimingAnimation,
9
13
  } from '../types';
10
14
  import { dealWithAnimation } from '@/utils/dealWithAnimation';
15
+ import { convertToSharedIndex } from '@/utils/computedWithAutoFillData';
11
16
 
12
17
  interface IOpts {
13
18
  loop: boolean;
14
19
  size: number;
20
+ data: TCarouselProps['data'];
21
+ autoFillData: TCarouselProps['autoFillData'];
15
22
  handlerOffsetX: Animated.SharedValue<number>;
16
23
  withAnimation?: TCarouselProps['withAnimation'];
17
- disable?: boolean;
18
24
  duration?: number;
19
- originalLength: number;
20
- length: number;
21
25
  defaultIndex?: number;
22
26
  onScrollBegin?: () => void;
23
27
  onScrollEnd?: () => void;
24
- // the length before fill data
25
- onChange: (index: number) => void;
26
28
  }
27
29
 
28
30
  export interface ICarouselController {
29
- length: number;
30
- index: Animated.SharedValue<number>;
31
- sharedIndex: React.MutableRefObject<number>;
32
- sharedPreIndex: React.MutableRefObject<number>;
31
+ sharedIndex: Animated.SharedValue<number>;
32
+ sharedPreIndex: Animated.SharedValue<number>;
33
33
  prev: (opts?: TCarouselActionOptions) => void;
34
34
  next: (opts?: TCarouselActionOptions) => void;
35
- computedIndex: () => void;
36
35
  getCurrentIndex: () => number;
37
36
  to: (index: number, animated?: boolean) => void;
38
37
  scrollTo: (opts?: TCarouselActionOptions) => void;
@@ -41,70 +40,66 @@ export interface ICarouselController {
41
40
  export function useCarouselController(options: IOpts): ICarouselController {
42
41
  const {
43
42
  size,
43
+ data,
44
44
  loop,
45
45
  handlerOffsetX,
46
46
  withAnimation,
47
- disable = false,
48
- originalLength,
49
- length,
50
- onChange,
51
- duration,
52
47
  defaultIndex = 0,
48
+ duration,
49
+ autoFillData,
53
50
  } = options;
54
51
 
52
+ const dataInfo = React.useMemo(
53
+ () => ({
54
+ length: data.length,
55
+ disable: !data.length,
56
+ originalLength: data.length,
57
+ }),
58
+ [data]
59
+ );
60
+
55
61
  const index = useSharedValue<number>(defaultIndex);
56
62
  // The Index displayed to the user
57
- const sharedIndex = React.useRef<number>(defaultIndex);
58
- const sharedPreIndex = React.useRef<number>(defaultIndex);
63
+ const sharedIndex = useSharedValue<number>(defaultIndex);
64
+ const sharedPreIndex = useSharedValue<number>(defaultIndex);
59
65
 
60
66
  const currentFixedPage = React.useCallback(() => {
61
67
  if (loop) {
62
68
  return -Math.round(handlerOffsetX.value / size);
63
69
  }
64
70
 
65
- const fixed = (handlerOffsetX.value / size) % length;
71
+ const fixed = (handlerOffsetX.value / size) % dataInfo.length;
66
72
  return Math.round(
67
73
  handlerOffsetX.value <= 0
68
74
  ? Math.abs(fixed)
69
- : Math.abs(fixed > 0 ? length - fixed : 0)
75
+ : Math.abs(fixed > 0 ? dataInfo.length - fixed : 0)
70
76
  );
71
- }, [handlerOffsetX, length, size, loop]);
77
+ }, [handlerOffsetX, dataInfo, size, loop]);
72
78
 
73
- const convertToSharedIndex = React.useCallback(
74
- (i: number) => {
75
- if (loop) {
76
- switch (originalLength) {
77
- case 1:
78
- return 0;
79
- case 2:
80
- return i % 2;
81
- }
82
- }
83
- return i;
84
- },
85
- [originalLength, loop]
86
- );
87
-
88
- const computedIndex = React.useCallback(() => {
89
- sharedPreIndex.current = sharedIndex.current;
90
- const toInt = (handlerOffsetX.value / size) % length;
91
- const i =
92
- handlerOffsetX.value <= 0
93
- ? Math.abs(toInt)
94
- : Math.abs(toInt > 0 ? length - toInt : 0);
79
+ useDerivedValue(() => {
80
+ const handlerOffsetXValue = handlerOffsetX.value;
81
+ sharedPreIndex.value = sharedIndex.value;
82
+ const toInt = (handlerOffsetXValue / size) % dataInfo.length;
83
+ const isPositive = handlerOffsetXValue <= 0;
84
+ const i = isPositive
85
+ ? Math.abs(toInt)
86
+ : Math.abs(toInt > 0 ? dataInfo.length - toInt : 0);
95
87
  index.value = i;
96
- const _sharedIndex = convertToSharedIndex(i);
97
- sharedIndex.current = _sharedIndex;
98
- onChange(_sharedIndex);
88
+ sharedIndex.value = convertToSharedIndex({
89
+ loop,
90
+ rawDataLength: dataInfo.originalLength,
91
+ autoFillData: autoFillData!,
92
+ index: i,
93
+ });
99
94
  }, [
100
- length,
101
- handlerOffsetX,
102
95
  sharedPreIndex,
103
- index,
104
- size,
105
96
  sharedIndex,
106
- convertToSharedIndex,
107
- onChange,
97
+ size,
98
+ dataInfo,
99
+ index,
100
+ loop,
101
+ autoFillData,
102
+ handlerOffsetX,
108
103
  ]);
109
104
 
110
105
  const getCurrentIndex = React.useCallback(() => {
@@ -112,8 +107,8 @@ export function useCarouselController(options: IOpts): ICarouselController {
112
107
  }, [index]);
113
108
 
114
109
  const canSliding = React.useCallback(() => {
115
- return !disable;
116
- }, [disable]);
110
+ return !dataInfo.disable;
111
+ }, [dataInfo]);
117
112
 
118
113
  const onScrollEnd = React.useCallback(() => {
119
114
  options.onScrollEnd?.();
@@ -151,7 +146,8 @@ export function useCarouselController(options: IOpts): ICarouselController {
151
146
  (opts: TCarouselActionOptions = {}) => {
152
147
  'worklet';
153
148
  const { count = 1, animated = true, onFinished } = opts;
154
- if (!canSliding() || (!loop && index.value >= length - 1)) return;
149
+ if (!canSliding() || (!loop && index.value >= dataInfo.length - 1))
150
+ return;
155
151
 
156
152
  onScrollBegin?.();
157
153
 
@@ -172,7 +168,7 @@ export function useCarouselController(options: IOpts): ICarouselController {
172
168
  canSliding,
173
169
  loop,
174
170
  index,
175
- length,
171
+ dataInfo,
176
172
  onScrollBegin,
177
173
  handlerOffsetX,
178
174
  size,
@@ -259,15 +255,12 @@ export function useCarouselController(options: IOpts): ICarouselController {
259
255
  );
260
256
 
261
257
  return {
258
+ sharedIndex,
259
+ sharedPreIndex,
260
+ to,
262
261
  next,
263
262
  prev,
264
- to,
265
263
  scrollTo,
266
- index,
267
- length,
268
- sharedIndex,
269
- sharedPreIndex,
270
- computedIndex,
271
264
  getCurrentIndex,
272
265
  };
273
266
  }
@@ -11,7 +11,7 @@ interface ICommonVariables {
11
11
  export function useCommonVariables(
12
12
  props: TInitializeCarouselProps<any>
13
13
  ): ICommonVariables {
14
- const { vertical, height, width, data, defaultIndex, rawData } = props;
14
+ const { vertical, height, width, data, defaultIndex } = props;
15
15
  const size = vertical ? height : width;
16
16
  const validLength = data.length - 1;
17
17
  const defaultHandlerOffsetX = -Math.abs(defaultIndex * size);
@@ -19,7 +19,7 @@ export function useCommonVariables(
19
19
 
20
20
  React.useEffect(() => {
21
21
  handlerOffsetX.value = defaultHandlerOffsetX;
22
- }, [vertical, handlerOffsetX, defaultHandlerOffsetX, rawData]);
22
+ }, [vertical, handlerOffsetX, defaultHandlerOffsetX]);
23
23
 
24
24
  return {
25
25
  size,
package/src/types.ts CHANGED
@@ -144,6 +144,10 @@ export type TCarouselProps<T = any> = {
144
144
  * Specifies the scrolling animation effect.
145
145
  */
146
146
  withAnimation?: WithAnimation;
147
+ /**
148
+ * Used to locate this view in end-to-end tests.
149
+ */
150
+ testID?: string;
147
151
  /**
148
152
  * Custom carousel config.
149
153
  */
@@ -12,6 +12,24 @@ type BaseParams<T extends object = {}> = {
12
12
  loop: boolean;
13
13
  } & T;
14
14
 
15
+ export function convertToSharedIndex(
16
+ params: BaseParams<{ index: number; rawDataLength: number }>
17
+ ) {
18
+ 'worklet';
19
+ const { loop, rawDataLength, index, autoFillData } = params;
20
+
21
+ if (isAutoFillData({ loop, autoFillData })) {
22
+ switch (rawDataLength) {
23
+ case SINGLE_ITEM:
24
+ return 0;
25
+ case DOUBLE_ITEM:
26
+ return index % 2;
27
+ }
28
+ }
29
+
30
+ return index;
31
+ }
32
+
15
33
  export function computedOffsetXValueWithAutoFillData(
16
34
  params: BaseParams<{
17
35
  rawDataLength: number;
@@ -1,2 +0,0 @@
1
- declare const App: () => JSX.Element;
2
- export default App;