react-native-reanimated-carousel 3.1.5 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/README.zh-CN.md +38 -30
- package/lib/commonjs/Carousel.js +1 -1
- package/lib/commonjs/Carousel.js.map +1 -1
- package/lib/commonjs/ScrollViewGesture.js +1 -1
- package/lib/commonjs/ScrollViewGesture.js.map +1 -1
- package/lib/commonjs/hooks/computeNewIndexWhenDataChanges.js +1 -1
- package/lib/commonjs/hooks/computeNewIndexWhenDataChanges.js.map +1 -1
- package/lib/commonjs/hooks/index.test.js +1 -1
- package/lib/commonjs/hooks/index.test.js.map +1 -1
- package/lib/commonjs/hooks/useCarouselController.js +1 -1
- package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
- package/lib/commonjs/hooks/useCommonVariables.js +1 -1
- package/lib/commonjs/hooks/useCommonVariables.js.map +1 -1
- package/lib/commonjs/hooks/useInitProps.js +1 -1
- package/lib/commonjs/hooks/useInitProps.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +1 -1
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
- package/lib/commonjs/layouts/BaseLayout.js +1 -1
- package/lib/commonjs/layouts/BaseLayout.js.map +1 -1
- package/lib/commonjs/layouts/ParallaxLayout.js +1 -1
- package/lib/commonjs/layouts/ParallaxLayout.js.map +1 -1
- package/lib/commonjs/layouts/normal.js +1 -1
- package/lib/commonjs/layouts/normal.js.map +1 -1
- package/lib/commonjs/layouts/parallax.js +1 -1
- package/lib/commonjs/layouts/parallax.js.map +1 -1
- package/lib/commonjs/layouts/stack.js +1 -1
- package/lib/commonjs/layouts/stack.js.map +1 -1
- package/lib/commonjs/utils/computedWithAutoFillData.js +1 -1
- package/lib/commonjs/utils/computedWithAutoFillData.js.map +1 -1
- package/lib/commonjs/utils/dealWithAnimation.js +1 -1
- package/lib/commonjs/utils/dealWithAnimation.js.map +1 -1
- package/lib/commonjs/utils/handlerOffsetDirection.js +1 -1
- package/lib/commonjs/utils/log.js +1 -1
- package/lib/module/ScrollViewGesture.js +79 -37
- package/lib/module/ScrollViewGesture.js.map +1 -1
- package/lib/module/hooks/index.test.js +0 -1
- package/lib/module/hooks/index.test.js.map +1 -1
- package/lib/module/hooks/useInitProps.js +5 -2
- package/lib/module/hooks/useInitProps.js.map +1 -1
- package/lib/module/layouts/BaseLayout.js +7 -0
- package/lib/module/layouts/BaseLayout.js.map +1 -1
- package/lib/module/utils/dealWithAnimation.js +2 -6
- package/lib/module/utils/dealWithAnimation.js.map +1 -1
- package/lib/typescript/types.d.ts +10 -5
- package/package.json +13 -10
- package/src/ScrollViewGesture.tsx +80 -39
- package/src/hooks/index.test.ts +0 -2
- package/src/hooks/useInitProps.ts +5 -2
- package/src/layouts/BaseLayout.tsx +7 -1
- package/src/types.ts +12 -5
- package/src/utils/dealWithAnimation.ts +6 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useInitProps.ts"],"names":["React","computedFillDataWithAutoFillData","useInitProps","props","defaultIndex","data","rawData","loop","
|
|
1
|
+
{"version":3,"sources":["useInitProps.ts"],"names":["React","computedFillDataWithAutoFillData","useInitProps","props","defaultIndex","data","rawData","loop","autoPlayInterval","_autoPlayInterval","scrollAnimationDuration","style","panGestureHandlerProps","autoFillData","enabled","pagingEnabled","overscrollEnabled","snapEnabled","enableSnap","width","_width","height","_height","Math","round","max","useMemo","dataLength","length","rawDataLength","mode","modeConfig","showLength"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AAGA,SAASC,gCAAT,QAAiD,mCAAjD;AAuBA,OAAO,SAASC,YAAT,CACLC,KADK,EAEwB;AAAA;;AAC7B,QAAM;AACJC,IAAAA,YAAY,GAAG,CADX;AAEJC,IAAAA,IAAI,EAAEC,OAAO,GAAG,EAFZ;AAGJC,IAAAA,IAAI,GAAG,IAHH;AAIJC,IAAAA,gBAAgB,EAAEC,iBAAiB,GAAG,IAJlC;AAKJC,IAAAA,uBAAuB,GAAG,GALtB;AAMJC,IAAAA,KAAK,GAAG,EANJ;AAOJC,IAAAA,sBAAsB,GAAG,EAPrB;AAQJC,IAAAA,YAAY,GAAG,IARX;AASJ;AACAC,IAAAA,OAAO,GAAG,IAVN;AAWJC,IAAAA,aAAa,GAAG,IAXZ;AAYJC,IAAAA,iBAAiB,GAAG,IAZhB;AAaJC,IAAAA,WAAW,wBAAGd,KAAK,CAACe,UAAT,iEAAuB,IAb9B;AAcJC,IAAAA,KAAK,EAAEC,MAdH;AAeJC,IAAAA,MAAM,EAAEC;AAfJ,MAgBFnB,KAhBJ;AAkBA,QAAMgB,KAAK,GAAGI,IAAI,CAACC,KAAL,CAAWJ,MAAM,IAAI,CAArB,CAAd;AACA,QAAMC,MAAM,GAAGE,IAAI,CAACC,KAAL,CAAWF,OAAO,IAAI,CAAtB,CAAf;AACA,QAAMd,gBAAgB,GAAGe,IAAI,CAACE,GAAL,CAAShB,iBAAT,EAA4B,CAA5B,CAAzB;AAEA,QAAMJ,IAAI,GAAGL,KAAK,CAAC0B,OAAN,CACX,MAAM;AACJ,WAAOzB,gCAAgC,CAAI;AACzCM,MAAAA,IADyC;AAEzCM,MAAAA,YAFyC;AAGzCR,MAAAA,IAAI,EAAEC,OAHmC;AAIzCqB,MAAAA,UAAU,EAAErB,OAAO,CAACsB;AAJqB,KAAJ,CAAvC;AAMD,GARU,EASX,CAACtB,OAAD,EAAUC,IAAV,EAAgBM,YAAhB,CATW,CAAb;AAYA,QAAMc,UAAU,GAAGtB,IAAI,CAACuB,MAAxB;AACA,QAAMC,aAAa,GAAGvB,OAAO,CAACsB,MAA9B;;AAEA,MAAIzB,KAAK,CAAC2B,IAAN,KAAe,gBAAf,IAAmC3B,KAAK,CAAC2B,IAAN,KAAe,kBAAtD,EAA0E;AAAA;;AACxE,QAAI,CAAC3B,KAAK,CAAC4B,UAAX,EACE5B,KAAK,CAAC4B,UAAN,GAAmB,EAAnB;AAEF5B,IAAAA,KAAK,CAAC4B,UAAN,CAAiBC,UAAjB,iDAA8B7B,KAAK,CAAC4B,UAApC,sDAA8B,kBAAkBC,UAAhD,yEAA8DL,UAAU,GAAG,CAA3E;AACD;;AAED,SAAO,EACL,GAAGxB,KADE;AAELC,IAAAA,YAFK;AAGLS,IAAAA,YAHK;AAIL;AACAR,IAAAA,IALK;AAML;AACAsB,IAAAA,UAPK;AAQL;AACArB,IAAAA,OATK;AAUL;AACAuB,IAAAA,aAXK;AAYLtB,IAAAA,IAZK;AAaLO,IAAAA,OAbK;AAcLN,IAAAA,gBAdK;AAeLE,IAAAA,uBAfK;AAgBLC,IAAAA,KAhBK;AAiBLC,IAAAA,sBAjBK;AAkBLG,IAAAA,aAlBK;AAmBLE,IAAAA,WAnBK;AAoBLD,IAAAA,iBApBK;AAqBLG,IAAAA,KArBK;AAsBLE,IAAAA;AAtBK,GAAP;AAwBD","sourcesContent":["import React from \"react\";\n\nimport type { TCarouselProps } from \"../types\";\nimport { computedFillDataWithAutoFillData } from \"../utils/computedWithAutoFillData\";\n\ntype TGetRequiredProps<P extends keyof TCarouselProps> = Record<\nP,\nRequired<TCarouselProps>[P]\n>;\n\nexport type TInitializeCarouselProps<T> = TCarouselProps<T> &\nTGetRequiredProps<\n| \"defaultIndex\"\n| \"loop\"\n| \"width\"\n| \"height\"\n| \"scrollAnimationDuration\"\n| \"autoPlayInterval\"\n| \"autoFillData\"\n> & {\n // Raw data that has not been processed\n rawData: T[]\n dataLength: number\n rawDataLength: number\n};\n\nexport function useInitProps<T>(\n props: TCarouselProps<T>,\n): TInitializeCarouselProps<T> {\n const {\n defaultIndex = 0,\n data: rawData = [],\n loop = true,\n autoPlayInterval: _autoPlayInterval = 1000,\n scrollAnimationDuration = 500,\n style = {},\n panGestureHandlerProps = {},\n autoFillData = true,\n // switchers\n enabled = true,\n pagingEnabled = true,\n overscrollEnabled = true,\n snapEnabled = props.enableSnap ?? true,\n width: _width,\n height: _height,\n } = props;\n\n const width = Math.round(_width || 0);\n const height = Math.round(_height || 0);\n const autoPlayInterval = Math.max(_autoPlayInterval, 0);\n\n const data = React.useMemo<T[]>(\n () => {\n return computedFillDataWithAutoFillData<T>({\n loop,\n autoFillData,\n data: rawData,\n dataLength: rawData.length,\n });\n },\n [rawData, loop, autoFillData],\n );\n\n const dataLength = data.length;\n const rawDataLength = rawData.length;\n\n if (props.mode === \"vertical-stack\" || props.mode === \"horizontal-stack\") {\n if (!props.modeConfig)\n props.modeConfig = {};\n\n props.modeConfig.showLength = props.modeConfig?.showLength ?? dataLength - 1;\n }\n\n return {\n ...props,\n defaultIndex,\n autoFillData,\n // Fill data with autoFillData\n data,\n // Length of fill data\n dataLength,\n // Raw data that has not been processed\n rawData,\n // Length of raw data\n rawDataLength,\n loop,\n enabled,\n autoPlayInterval,\n scrollAnimationDuration,\n style,\n panGestureHandlerProps,\n pagingEnabled,\n snapEnabled,\n overscrollEnabled,\n width,\n height,\n };\n}\n"]}
|
|
@@ -68,6 +68,13 @@ export const BaseLayout = props => {
|
|
|
68
68
|
height: height || "100%",
|
|
69
69
|
position: "absolute"
|
|
70
70
|
}, animatedStyle]
|
|
71
|
+
/**
|
|
72
|
+
* We use this testID to know when the carousel item is ready to be tested in test.
|
|
73
|
+
* e.g.
|
|
74
|
+
* The testID of first item will be changed to __CAROUSEL_ITEM_0_READY__ from __CAROUSEL_ITEM_0_NOT_READY__ when the item is ready.
|
|
75
|
+
* */
|
|
76
|
+
,
|
|
77
|
+
testID: `__CAROUSEL_ITEM_${index}_${shouldUpdate ? "READY" : "NOT_READY"}__`
|
|
71
78
|
}, /*#__PURE__*/React.createElement(LazyView, {
|
|
72
79
|
shouldUpdate: shouldUpdate
|
|
73
80
|
}, children({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["BaseLayout.tsx"],"names":["React","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useDerivedValue","useCheckMounted","useOffsetX","LazyView","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":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AAGA,OAAOC,QAAP,IACEC,OADF,EAEEC,mBAFF,EAGEC,gBAHF,EAIEC,eAJF,QAKO,yBALP;AASA,SAASC,eAAT,QAAgC,0BAAhC;AAEA,SAASC,UAAT,QAA2B,qBAA3B;AAEA,SAASC,QAAT,QAAyB,aAAzB;AACA,SAASC,GAAT,QAAoB,UAApB;AAIA,OAAO,MAAMC,UAQX,GAAIC,KAAD,IAAW;AACd,QAAMC,OAAO,GAAGN,eAAe,EAA/B;AACA,QAAM;AAAEO,IAAAA,aAAF;AAAiBC,IAAAA,KAAjB;AAAwBC,IAAAA,QAAxB;AAAkCC,IAAAA,aAAlC;AAAiDC,IAAAA;AAAjD,
|
|
1
|
+
{"version":3,"sources":["BaseLayout.tsx"],"names":["React","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useDerivedValue","useCheckMounted","useOffsetX","LazyView","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 { useCheckMounted } from \"../hooks/useCheckMounted\";\nimport type { IOpts } from \"../hooks/useOffsetX\";\nimport { useOffsetX } from \"../hooks/useOffsetX\";\nimport type { IVisibleRanges } from \"../hooks/useVisibleRanges\";\nimport { LazyView } from \"../LazyView\";\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"]}
|
|
@@ -4,14 +4,10 @@ export function dealWithAnimation(withAnimation) {
|
|
|
4
4
|
|
|
5
5
|
switch (withAnimation.type) {
|
|
6
6
|
case "spring":
|
|
7
|
-
return (value, cb) =>
|
|
8
|
-
return withSpring(value, withAnimation.config, isFinished => cb(isFinished));
|
|
9
|
-
};
|
|
7
|
+
return (value, cb) => withSpring(value, withAnimation.config, isFinished => cb(isFinished));
|
|
10
8
|
|
|
11
9
|
case "timing":
|
|
12
|
-
return (value, cb) =>
|
|
13
|
-
return withTiming(value, withAnimation.config, isFinished => cb(isFinished));
|
|
14
|
-
};
|
|
10
|
+
return (value, cb) => withTiming(value, withAnimation.config, isFinished => cb(isFinished));
|
|
15
11
|
}
|
|
16
12
|
}
|
|
17
13
|
//# sourceMappingURL=dealWithAnimation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["dealWithAnimation.ts"],"names":["withSpring","withTiming","dealWithAnimation","withAnimation","type","value","cb","config","isFinished"],"mappings":"AAAA,SAASA,UAAT,EAAqBC,UAArB,QAAuC,yBAAvC;AAIA,OAAO,SAASC,iBAAT,CACLC,aADK,EAEyD;AAC9D;;AACA,UAAQA,aAAa,CAACC,IAAtB;AACE,SAAK,QAAL;AACE,aAAO,CAACC,KAAD,EAAQC,EAAR,
|
|
1
|
+
{"version":3,"sources":["dealWithAnimation.ts"],"names":["withSpring","withTiming","dealWithAnimation","withAnimation","type","value","cb","config","isFinished"],"mappings":"AAAA,SAASA,UAAT,EAAqBC,UAArB,QAAuC,yBAAvC;AAIA,OAAO,SAASC,iBAAT,CACLC,aADK,EAEyD;AAC9D;;AACA,UAAQA,aAAa,CAACC,IAAtB;AACE,SAAK,QAAL;AACE,aAAO,CAACC,KAAD,EAAQC,EAAR,KAAeN,UAAU,CAACK,KAAD,EAAQF,aAAa,CAACI,MAAtB,EAA8BC,UAAU,IACtEF,EAAE,CAACE,UAAD,CAD4B,CAAhC;;AAGF,SAAK,QAAL;AACE,aAAO,CAACH,KAAD,EAAQC,EAAR,KAAeL,UAAU,CAACI,KAAD,EAAQF,aAAa,CAACI,MAAtB,EAA8BC,UAAU,IACtEF,EAAE,CAACE,UAAD,CAD4B,CAAhC;AANJ;AAUD","sourcesContent":["import { withSpring, withTiming } from \"react-native-reanimated\";\n\nimport type { WithAnimation } from \"../types\";\n\nexport function dealWithAnimation(\n withAnimation: WithAnimation,\n): (value: number, cb: (isFinished: boolean) => void) => number {\n \"worklet\";\n switch (withAnimation.type) {\n case \"spring\":\n return (value, cb) => withSpring(value, withAnimation.config, isFinished =>\n cb(isFinished as boolean),\n );\n case \"timing\":\n return (value, cb) => withTiming(value, withAnimation.config, isFinished =>\n cb(isFinished as boolean),\n );\n }\n}\n"]}
|
|
@@ -115,15 +115,14 @@ export declare type TCarouselProps<T = any> = {
|
|
|
115
115
|
/**
|
|
116
116
|
* If enabled, releasing the touch will scroll to the nearest item.
|
|
117
117
|
* valid when pagingEnabled=false
|
|
118
|
-
* @
|
|
118
|
+
* @default true
|
|
119
119
|
*/
|
|
120
|
-
|
|
120
|
+
snapEnabled?: boolean;
|
|
121
121
|
/**
|
|
122
|
-
* If enabled,
|
|
123
|
-
* valid when pagingEnabled=false
|
|
122
|
+
* If enabled, items will scroll to the first placement when scrolling past the edge rather than closing to the last. (previous conditions: loop=false)
|
|
124
123
|
* @default true
|
|
125
124
|
*/
|
|
126
|
-
|
|
125
|
+
overscrollEnabled?: boolean;
|
|
127
126
|
/**
|
|
128
127
|
* If false, Carousel will not respond to any gestures.
|
|
129
128
|
* @default true
|
|
@@ -168,6 +167,12 @@ export declare type TCarouselProps<T = any> = {
|
|
|
168
167
|
* @param absoluteProgress Convert to index (0 1 2 ...)
|
|
169
168
|
*/
|
|
170
169
|
onProgressChange?: (offsetProgress: number, absoluteProgress: number) => void;
|
|
170
|
+
/**
|
|
171
|
+
* If enabled, releasing the touch will scroll to the nearest item.
|
|
172
|
+
* valid when pagingEnabled=false
|
|
173
|
+
* @deprecated please use snapEnabled instead
|
|
174
|
+
*/
|
|
175
|
+
enableSnap?: boolean;
|
|
171
176
|
} & (TParallaxModeProps | TStackModeProps);
|
|
172
177
|
export interface ICarouselInstance {
|
|
173
178
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-reanimated-carousel",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Simple carousel component.fully implemented using Reanimated 2.Infinitely scrolling, very smooth.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"react-native": "src/index.tsx",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"gif": "node scripts/makegif.js ./scripts/gif-works-directory",
|
|
25
|
-
"test": "
|
|
26
|
-
"test:dev": "
|
|
25
|
+
"test": "jest run src/**/*",
|
|
26
|
+
"test:dev": "jest dev src/**/*",
|
|
27
27
|
"typescript": "tsc --noEmit",
|
|
28
|
-
"lint": "eslint
|
|
29
|
-
"lint:fix": "eslint
|
|
28
|
+
"lint": "eslint 'src/**/*.{js,ts,tsx}'",
|
|
29
|
+
"lint:fix": "eslint 'src/**/*.{js,ts,tsx}' --fix",
|
|
30
30
|
"dev": "yarn watch 'yarn prepare' ./src",
|
|
31
31
|
"prepare": "bob build",
|
|
32
32
|
"release": "yarn prepare && dotenv release-it --no-git.requireUpstream",
|
|
@@ -39,7 +39,9 @@
|
|
|
39
39
|
"android:pretty": "yarn --cwd exampleExpo android:pretty",
|
|
40
40
|
"pods": "cd exampleExpo && pod-install --quiet",
|
|
41
41
|
"bootstrap": "yarn && yarn pods",
|
|
42
|
-
"deploy": "cd exampleExpo && yarn deploy"
|
|
42
|
+
"deploy": "cd exampleExpo && yarn deploy",
|
|
43
|
+
"publish": "yarn run prepare && changeset publish",
|
|
44
|
+
"version": "changeset version"
|
|
43
45
|
},
|
|
44
46
|
"keywords": [
|
|
45
47
|
"react-native",
|
|
@@ -58,11 +60,13 @@
|
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
60
62
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
63
|
+
"@changesets/changelog-git": "^0.1.14",
|
|
64
|
+
"@changesets/cli": "^2.26.0",
|
|
61
65
|
"@commitlint/config-conventional": "^11.0.0",
|
|
62
66
|
"@dohooo/eslint-config": "^0.0.7",
|
|
63
67
|
"@react-native-community/eslint-config": "^2.0.0",
|
|
64
68
|
"@release-it/conventional-changelog": "^2.0.0",
|
|
65
|
-
"@types/jest": "^
|
|
69
|
+
"@types/jest": "^29.2.5",
|
|
66
70
|
"@types/react": "~17.0.2",
|
|
67
71
|
"@types/react-native": "^0.66.16",
|
|
68
72
|
"@types/react-native-snap-carousel": "^3.8.5",
|
|
@@ -76,7 +80,7 @@
|
|
|
76
80
|
"eslint-plugin-prettier": "^3.1.3",
|
|
77
81
|
"gifify": "^2.4.3",
|
|
78
82
|
"husky": "^4.2.5",
|
|
79
|
-
"jest": "^
|
|
83
|
+
"jest": "^29.3.1",
|
|
80
84
|
"pod-install": "^0.1.0",
|
|
81
85
|
"prettier": "^2.0.5",
|
|
82
86
|
"react": "16.13.1",
|
|
@@ -86,8 +90,7 @@
|
|
|
86
90
|
"react-native-reanimated": "2.8.0",
|
|
87
91
|
"release-it": "^14.2.2",
|
|
88
92
|
"sponsorkit": "^0.1.3",
|
|
89
|
-
"typescript": "^4.0.8"
|
|
90
|
-
"vitest": "^0.24.3"
|
|
93
|
+
"typescript": "^4.0.8"
|
|
91
94
|
},
|
|
92
95
|
"peerDependencies": {
|
|
93
96
|
"react": ">=16.8.0",
|
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
} from "react-native-gesture-handler";
|
|
7
7
|
import Animated, {
|
|
8
8
|
cancelAnimation,
|
|
9
|
+
measure,
|
|
9
10
|
runOnJS,
|
|
10
11
|
useAnimatedGestureHandler,
|
|
11
12
|
useAnimatedReaction,
|
|
13
|
+
useAnimatedRef,
|
|
12
14
|
useDerivedValue,
|
|
13
15
|
useSharedValue,
|
|
14
16
|
withDecay,
|
|
@@ -49,6 +51,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
49
51
|
withAnimation,
|
|
50
52
|
enabled,
|
|
51
53
|
dataLength,
|
|
54
|
+
overscrollEnabled,
|
|
52
55
|
},
|
|
53
56
|
} = React.useContext(CTX);
|
|
54
57
|
|
|
@@ -68,8 +71,27 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
68
71
|
const touching = useSharedValue(false);
|
|
69
72
|
const scrollEndTranslation = useSharedValue(0);
|
|
70
73
|
const scrollEndVelocity = useSharedValue(0);
|
|
74
|
+
const containerRef = useAnimatedRef<Animated.View>();
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
// Get the limit of the scroll.
|
|
77
|
+
const getLimit = React.useCallback(() => {
|
|
78
|
+
"worklet";
|
|
79
|
+
|
|
80
|
+
if (!infinite && !overscrollEnabled) {
|
|
81
|
+
const { width: containerWidth = 0 } = measure(containerRef);
|
|
82
|
+
|
|
83
|
+
// If the item's total width is less than the container's width, then there is no need to scroll.
|
|
84
|
+
if (dataLength * size < containerWidth)
|
|
85
|
+
return 0;
|
|
86
|
+
|
|
87
|
+
// Disable the "overscroll" effect
|
|
88
|
+
return dataLength * size - containerWidth;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return dataLength * size;
|
|
92
|
+
}, [infinite, size, dataLength, overscrollEnabled]);
|
|
93
|
+
|
|
94
|
+
const withSpring = React.useCallback(
|
|
73
95
|
(toValue: number, onFinished?: () => void) => {
|
|
74
96
|
"worklet";
|
|
75
97
|
const defaultWithAnimation: WithTimingAnimation = {
|
|
@@ -97,34 +119,49 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
97
119
|
"worklet";
|
|
98
120
|
const origin = translation.value;
|
|
99
121
|
const velocity = scrollEndVelocity.value;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
// Default to scroll in the direction of the slide (with deceleration)
|
|
123
|
+
let finalTranslation: number = withDecay({ velocity, deceleration: 0.999 });
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The page size is the same as the item size.
|
|
127
|
+
* If direction is vertical, the page size is the height of the item.
|
|
128
|
+
* If direction is horizontal, the page size is the width of the item.
|
|
129
|
+
*
|
|
130
|
+
* `page size` equals to `size` variable.
|
|
131
|
+
* */
|
|
132
|
+
if (pagingEnabled) {
|
|
133
|
+
// distance with direction
|
|
134
|
+
const offset = -(scrollEndTranslation.value >= 0 ? 1 : -1); // 1 or -1
|
|
135
|
+
const computed = offset < 0 ? Math.ceil : Math.floor;
|
|
136
|
+
const page = computed(-translation.value / size);
|
|
137
|
+
|
|
138
|
+
if (infinite) {
|
|
139
|
+
const finalPage = page + offset;
|
|
140
|
+
finalTranslation = withSpring(withProcessTranslation(-finalPage * size), onFinished);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const finalPage = Math.min(maxPage - 1, Math.max(0, page + offset));
|
|
144
|
+
finalTranslation = withSpring(withProcessTranslation(-finalPage * size), onFinished);
|
|
111
145
|
}
|
|
112
|
-
translation.value = withDecay({
|
|
113
|
-
velocity,
|
|
114
|
-
deceleration: 0.999,
|
|
115
|
-
});
|
|
116
|
-
return;
|
|
117
146
|
}
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
148
|
+
if (!pagingEnabled && snapEnabled) {
|
|
149
|
+
// scroll to the nearest item
|
|
150
|
+
const nextPage = Math.round((origin + velocity * 0.4) / size) * size;
|
|
151
|
+
finalTranslation = withSpring(withProcessTranslation(nextPage), onFinished);
|
|
152
|
+
}
|
|
123
153
|
|
|
124
|
-
|
|
125
|
-
|
|
154
|
+
translation.value = finalTranslation;
|
|
155
|
+
|
|
156
|
+
function withProcessTranslation(translation: number) {
|
|
157
|
+
if (!infinite && !overscrollEnabled) {
|
|
158
|
+
const limit = getLimit();
|
|
159
|
+
const sign = Math.sign(translation);
|
|
160
|
+
return sign * Math.max(0, Math.min(limit, Math.abs(translation)));
|
|
161
|
+
}
|
|
126
162
|
|
|
127
|
-
|
|
163
|
+
return translation;
|
|
164
|
+
}
|
|
128
165
|
},
|
|
129
166
|
[
|
|
130
167
|
translation,
|
|
@@ -133,7 +170,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
133
170
|
size,
|
|
134
171
|
scrollEndTranslation.value,
|
|
135
172
|
infinite,
|
|
136
|
-
|
|
173
|
+
withSpring,
|
|
137
174
|
snapEnabled,
|
|
138
175
|
maxPage,
|
|
139
176
|
],
|
|
@@ -170,7 +207,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
170
207
|
return;
|
|
171
208
|
}
|
|
172
209
|
if (!infinite) {
|
|
173
|
-
translation.value =
|
|
210
|
+
translation.value = withSpring(0);
|
|
174
211
|
return;
|
|
175
212
|
}
|
|
176
213
|
}
|
|
@@ -181,7 +218,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
181
218
|
return;
|
|
182
219
|
}
|
|
183
220
|
if (!infinite)
|
|
184
|
-
translation.value =
|
|
221
|
+
translation.value = withSpring(-((maxPage - 1) * size));
|
|
185
222
|
}
|
|
186
223
|
}, [
|
|
187
224
|
touching.value,
|
|
@@ -191,7 +228,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
191
228
|
scrollEndTranslation.value,
|
|
192
229
|
infinite,
|
|
193
230
|
activeDecay,
|
|
194
|
-
|
|
231
|
+
withSpring,
|
|
195
232
|
]);
|
|
196
233
|
|
|
197
234
|
useAnimatedReaction(
|
|
@@ -212,7 +249,11 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
212
249
|
touching.value = true;
|
|
213
250
|
ctx.validStart = true;
|
|
214
251
|
onScrollBegin && runOnJS(onScrollBegin)();
|
|
252
|
+
|
|
215
253
|
ctx.max = (maxPage - 1) * size;
|
|
254
|
+
if (!infinite && !overscrollEnabled)
|
|
255
|
+
ctx.max = getLimit();
|
|
256
|
+
|
|
216
257
|
ctx.panOffset = translation.value;
|
|
217
258
|
},
|
|
218
259
|
onActive: (e, ctx) => {
|
|
@@ -225,19 +266,18 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
225
266
|
const panTranslation = isHorizontal.value
|
|
226
267
|
? translationX
|
|
227
268
|
: translationY;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
translation.value = boundary + dynamic * 0.5;
|
|
237
|
-
return;
|
|
269
|
+
if (!infinite) {
|
|
270
|
+
if ((translation.value > 0 || translation.value < -ctx.max)) {
|
|
271
|
+
const boundary = translation.value > 0 ? 0 : -ctx.max;
|
|
272
|
+
const fixed = boundary - ctx.panOffset;
|
|
273
|
+
const dynamic = panTranslation - fixed;
|
|
274
|
+
translation.value = boundary + dynamic * 0.5;
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
238
277
|
}
|
|
239
278
|
|
|
240
|
-
|
|
279
|
+
const translationValue = ctx.panOffset + panTranslation;
|
|
280
|
+
translation.value = translationValue;
|
|
241
281
|
},
|
|
242
282
|
onEnd: (e) => {
|
|
243
283
|
const { velocityX, velocityY, translationX, translationY } = e;
|
|
@@ -273,6 +313,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
|
|
|
273
313
|
onGestureEvent={panGestureEventHandler}
|
|
274
314
|
>
|
|
275
315
|
<Animated.View
|
|
316
|
+
ref={containerRef}
|
|
276
317
|
testID={testID}
|
|
277
318
|
style={style}
|
|
278
319
|
onTouchStart={onTouchBegin}
|
package/src/hooks/index.test.ts
CHANGED
|
@@ -31,13 +31,15 @@ export function useInitProps<T>(
|
|
|
31
31
|
defaultIndex = 0,
|
|
32
32
|
data: rawData = [],
|
|
33
33
|
loop = true,
|
|
34
|
-
enabled = true,
|
|
35
34
|
autoPlayInterval: _autoPlayInterval = 1000,
|
|
36
35
|
scrollAnimationDuration = 500,
|
|
37
36
|
style = {},
|
|
38
37
|
panGestureHandlerProps = {},
|
|
39
|
-
pagingEnabled = true,
|
|
40
38
|
autoFillData = true,
|
|
39
|
+
// switchers
|
|
40
|
+
enabled = true,
|
|
41
|
+
pagingEnabled = true,
|
|
42
|
+
overscrollEnabled = true,
|
|
41
43
|
snapEnabled = props.enableSnap ?? true,
|
|
42
44
|
width: _width,
|
|
43
45
|
height: _height,
|
|
@@ -89,6 +91,7 @@ export function useInitProps<T>(
|
|
|
89
91
|
panGestureHandlerProps,
|
|
90
92
|
pagingEnabled,
|
|
91
93
|
snapEnabled,
|
|
94
|
+
overscrollEnabled,
|
|
92
95
|
width,
|
|
93
96
|
height,
|
|
94
97
|
};
|
|
@@ -30,7 +30,7 @@ export const BaseLayout: React.FC<{
|
|
|
30
30
|
}> = (props) => {
|
|
31
31
|
const mounted = useCheckMounted();
|
|
32
32
|
const { handlerOffset, index, children, visibleRanges, animationStyle }
|
|
33
|
-
|
|
33
|
+
= props;
|
|
34
34
|
|
|
35
35
|
const context = React.useContext(CTX);
|
|
36
36
|
const {
|
|
@@ -109,6 +109,12 @@ export const BaseLayout: React.FC<{
|
|
|
109
109
|
},
|
|
110
110
|
animatedStyle,
|
|
111
111
|
]}
|
|
112
|
+
/**
|
|
113
|
+
* We use this testID to know when the carousel item is ready to be tested in test.
|
|
114
|
+
* e.g.
|
|
115
|
+
* 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
|
+
* */
|
|
117
|
+
testID={`__CAROUSEL_ITEM_${index}_${shouldUpdate ? "READY" : "NOT_READY"}__`}
|
|
112
118
|
>
|
|
113
119
|
<LazyView shouldUpdate={shouldUpdate}>
|
|
114
120
|
{children({ animationValue })}
|
package/src/types.ts
CHANGED
|
@@ -132,15 +132,14 @@ export type TCarouselProps<T = any> = {
|
|
|
132
132
|
/**
|
|
133
133
|
* If enabled, releasing the touch will scroll to the nearest item.
|
|
134
134
|
* valid when pagingEnabled=false
|
|
135
|
-
* @
|
|
135
|
+
* @default true
|
|
136
136
|
*/
|
|
137
|
-
|
|
137
|
+
snapEnabled?: boolean
|
|
138
138
|
/**
|
|
139
|
-
* If enabled,
|
|
140
|
-
* valid when pagingEnabled=false
|
|
139
|
+
* If enabled, items will scroll to the first placement when scrolling past the edge rather than closing to the last. (previous conditions: loop=false)
|
|
141
140
|
* @default true
|
|
142
141
|
*/
|
|
143
|
-
|
|
142
|
+
overscrollEnabled?: boolean
|
|
144
143
|
/**
|
|
145
144
|
* If false, Carousel will not respond to any gestures.
|
|
146
145
|
* @default true
|
|
@@ -188,6 +187,14 @@ export type TCarouselProps<T = any> = {
|
|
|
188
187
|
offsetProgress: number,
|
|
189
188
|
absoluteProgress: number
|
|
190
189
|
) => void
|
|
190
|
+
|
|
191
|
+
// ============================== deprecated props ==============================
|
|
192
|
+
/**
|
|
193
|
+
* If enabled, releasing the touch will scroll to the nearest item.
|
|
194
|
+
* valid when pagingEnabled=false
|
|
195
|
+
* @deprecated please use snapEnabled instead
|
|
196
|
+
*/
|
|
197
|
+
enableSnap?: boolean
|
|
191
198
|
} & (TParallaxModeProps | TStackModeProps);
|
|
192
199
|
|
|
193
200
|
export interface ICarouselInstance {
|
|
@@ -8,16 +8,12 @@ export function dealWithAnimation(
|
|
|
8
8
|
"worklet";
|
|
9
9
|
switch (withAnimation.type) {
|
|
10
10
|
case "spring":
|
|
11
|
-
return (value, cb) =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
15
|
-
};
|
|
11
|
+
return (value, cb) => withSpring(value, withAnimation.config, isFinished =>
|
|
12
|
+
cb(isFinished as boolean),
|
|
13
|
+
);
|
|
16
14
|
case "timing":
|
|
17
|
-
return (value, cb) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
);
|
|
21
|
-
};
|
|
15
|
+
return (value, cb) => withTiming(value, withAnimation.config, isFinished =>
|
|
16
|
+
cb(isFinished as boolean),
|
|
17
|
+
);
|
|
22
18
|
}
|
|
23
19
|
}
|