@r0b0t3d/react-native-carousel 3.4.6 → 3.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/Carousel.js +290 -195
- package/lib/commonjs/components/Carousel.js.map +1 -1
- package/lib/commonjs/components/CarouselContainer.js +17 -31
- package/lib/commonjs/components/CarouselContainer.js.map +1 -1
- package/lib/commonjs/components/PageItem.js +52 -45
- package/lib/commonjs/components/PageItem.js.map +1 -1
- package/lib/commonjs/components/PaginationIndicator.js +23 -34
- package/lib/commonjs/components/PaginationIndicator.js.map +1 -1
- package/lib/commonjs/components/useCarouselContext.js +3 -8
- package/lib/commonjs/components/useCarouselContext.js.map +1 -1
- package/lib/commonjs/components/useInternalCarouselContext.js +3 -6
- package/lib/commonjs/components/useInternalCarouselContext.js.map +1 -1
- package/lib/commonjs/index.js +7 -17
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +4 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils.js +24 -18
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/components/Carousel.js +291 -180
- package/lib/module/components/Carousel.js.map +1 -1
- package/lib/module/components/CarouselContainer.js +18 -23
- package/lib/module/components/CarouselContainer.js.map +1 -1
- package/lib/module/components/PageItem.js +53 -37
- package/lib/module/components/PageItem.js.map +1 -1
- package/lib/module/components/PaginationIndicator.js +23 -24
- package/lib/module/components/PaginationIndicator.js.map +1 -1
- package/lib/module/components/useCarouselContext.js +2 -2
- package/lib/module/components/useCarouselContext.js.map +1 -1
- package/lib/module/components/useInternalCarouselContext.js +2 -0
- package/lib/module/components/useInternalCarouselContext.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils.js +22 -12
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/components/Carousel.d.ts +3 -1
- package/lib/typescript/components/Carousel.d.ts.map +1 -0
- package/lib/typescript/components/CarouselContainer.d.ts +3 -2
- package/lib/typescript/components/CarouselContainer.d.ts.map +1 -0
- package/lib/typescript/components/PageItem.d.ts +5 -3
- package/lib/typescript/components/PageItem.d.ts.map +1 -0
- package/lib/typescript/components/PaginationIndicator.d.ts +3 -1
- package/lib/typescript/components/PaginationIndicator.d.ts.map +1 -0
- package/lib/typescript/components/useCarouselContext.d.ts +1 -1
- package/lib/typescript/components/useCarouselContext.d.ts.map +1 -0
- package/lib/typescript/components/useInternalCarouselContext.d.ts +1 -1
- package/lib/typescript/components/useInternalCarouselContext.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +17 -15
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils.d.ts +4 -1
- package/lib/typescript/utils.d.ts.map +1 -0
- package/package.json +26 -29
- package/src/components/Carousel.tsx +407 -206
- package/src/components/CarouselContainer.tsx +4 -4
- package/src/components/PageItem.tsx +55 -33
- package/src/components/PaginationIndicator.tsx +2 -2
- package/src/components/useCarouselContext.ts +0 -1
- package/src/components/useInternalCarouselContext.ts +0 -1
- package/src/types.ts +9 -7
- package/src/utils.ts +31 -11
|
@@ -6,7 +6,7 @@ import React, {
|
|
|
6
6
|
useRef,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import { useSharedValue } from 'react-native-reanimated';
|
|
9
|
-
import type { CarouselHandles } from '
|
|
9
|
+
import type { CarouselHandles } from '../types';
|
|
10
10
|
import { CarouselContext } from './useCarouselContext';
|
|
11
11
|
import { InternalCarouselContext } from './useInternalCarouselContext';
|
|
12
12
|
|
|
@@ -15,11 +15,11 @@ type Props = {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
function CarouselContainer({ children }: Props) {
|
|
18
|
-
const carouselHandlers = useRef<CarouselHandles>();
|
|
18
|
+
const carouselHandlers = useRef<CarouselHandles>(null);
|
|
19
19
|
const currentPage = useSharedValue(0);
|
|
20
20
|
const totalPage = useSharedValue(0);
|
|
21
21
|
|
|
22
|
-
const setCarouselHandlers = useCallback((handlers) => {
|
|
22
|
+
const setCarouselHandlers = useCallback((handlers: CarouselHandles) => {
|
|
23
23
|
carouselHandlers.current = handlers;
|
|
24
24
|
}, []);
|
|
25
25
|
|
|
@@ -50,7 +50,7 @@ function CarouselContainer({ children }: Props) {
|
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export default function withCarouselContext<T
|
|
53
|
+
export default function withCarouselContext<T extends Record<string, unknown>>(Component: FC<T>) {
|
|
54
54
|
return (props: T) => {
|
|
55
55
|
return (
|
|
56
56
|
<CarouselContainer>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
1
|
import React, { useMemo } from 'react';
|
|
3
2
|
import {
|
|
4
3
|
Image,
|
|
4
|
+
Pressable,
|
|
5
5
|
StyleProp,
|
|
6
6
|
StyleSheet,
|
|
7
|
-
TouchableOpacity,
|
|
8
7
|
ViewStyle,
|
|
9
8
|
} from 'react-native';
|
|
10
9
|
import Animated, {
|
|
11
10
|
interpolate,
|
|
11
|
+
SharedValue,
|
|
12
12
|
useAnimatedStyle,
|
|
13
13
|
useDerivedValue,
|
|
14
14
|
} from 'react-native-reanimated';
|
|
@@ -19,16 +19,50 @@ type Props<TData> = {
|
|
|
19
19
|
index: number;
|
|
20
20
|
offset: number;
|
|
21
21
|
renderItem: CarouselProps['renderItem'];
|
|
22
|
-
animatedValue:
|
|
22
|
+
animatedValue: SharedValue<number>;
|
|
23
23
|
animation?: 'parallax';
|
|
24
|
-
freeze:
|
|
24
|
+
freeze: SharedValue<boolean>;
|
|
25
25
|
itemWidth: number;
|
|
26
26
|
inactiveOpacity: number;
|
|
27
27
|
inactiveScale: number;
|
|
28
28
|
containerStyle: StyleProp<ViewStyle>;
|
|
29
|
-
onPress
|
|
29
|
+
onPress?: () => void;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
// Pull the inline renderContent() into a named component so React
|
|
33
|
+
// preserves its identity across renders and doesn't remount internal
|
|
34
|
+
// state (images, nested components, etc.).
|
|
35
|
+
function PageContent<TData>({
|
|
36
|
+
renderItem,
|
|
37
|
+
item,
|
|
38
|
+
index,
|
|
39
|
+
animatedValue,
|
|
40
|
+
offset,
|
|
41
|
+
}: {
|
|
42
|
+
renderItem: CarouselProps['renderItem'];
|
|
43
|
+
item: TData;
|
|
44
|
+
index: number;
|
|
45
|
+
animatedValue: SharedValue<number>;
|
|
46
|
+
offset: number;
|
|
47
|
+
}) {
|
|
48
|
+
if (renderItem) {
|
|
49
|
+
return renderItem(
|
|
50
|
+
{ item, index },
|
|
51
|
+
{ scrollPosition: animatedValue, offset }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (typeof item === 'object' && (item as any).source) {
|
|
55
|
+
return (
|
|
56
|
+
<Image
|
|
57
|
+
source={(item as any).source}
|
|
58
|
+
style={[STYLES.image, StyleSheet.absoluteFill]}
|
|
59
|
+
resizeMode="cover"
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
export default function PageItem<TData = any>({
|
|
33
67
|
item,
|
|
34
68
|
index,
|
|
@@ -67,7 +101,7 @@ export default function PageItem<TData = any>({
|
|
|
67
101
|
}, []);
|
|
68
102
|
// @ts-ignore
|
|
69
103
|
const animatedStyle = useAnimatedStyle(() => {
|
|
70
|
-
const transform:
|
|
104
|
+
const transform: any = [
|
|
71
105
|
{
|
|
72
106
|
scale: scale.value,
|
|
73
107
|
},
|
|
@@ -83,26 +117,6 @@ export default function PageItem<TData = any>({
|
|
|
83
117
|
};
|
|
84
118
|
}, []);
|
|
85
119
|
|
|
86
|
-
function renderContent() {
|
|
87
|
-
if (renderItem) {
|
|
88
|
-
return renderItem(
|
|
89
|
-
{ item, index },
|
|
90
|
-
{ scrollPosition: animatedValue, offset }
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
if (typeof item === 'object' && (item as any).source) {
|
|
94
|
-
return (
|
|
95
|
-
<Image
|
|
96
|
-
source={(item as any).source}
|
|
97
|
-
style={[styles.image, StyleSheet.absoluteFill]}
|
|
98
|
-
resizeMode="cover"
|
|
99
|
-
/>
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
console.error('You need implement renderItem');
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
120
|
const mContainerStyle: StyleProp<ViewStyle> = useMemo(() => {
|
|
107
121
|
return [
|
|
108
122
|
{
|
|
@@ -114,19 +128,27 @@ export default function PageItem<TData = any>({
|
|
|
114
128
|
}, [itemWidth, containerStyle]);
|
|
115
129
|
|
|
116
130
|
return (
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
<Pressable
|
|
132
|
+
style={({ pressed }) => [
|
|
133
|
+
mContainerStyle,
|
|
134
|
+
pressed && { opacity: 0.9 },
|
|
135
|
+
]}
|
|
120
136
|
onPress={onPress}
|
|
121
137
|
>
|
|
122
|
-
<Animated.View style={[
|
|
123
|
-
|
|
138
|
+
<Animated.View style={[STYLES.container, animatedStyle]}>
|
|
139
|
+
<PageContent
|
|
140
|
+
renderItem={renderItem}
|
|
141
|
+
item={item}
|
|
142
|
+
index={index}
|
|
143
|
+
animatedValue={animatedValue}
|
|
144
|
+
offset={offset}
|
|
145
|
+
/>
|
|
124
146
|
</Animated.View>
|
|
125
|
-
</
|
|
147
|
+
</Pressable>
|
|
126
148
|
);
|
|
127
149
|
}
|
|
128
150
|
|
|
129
|
-
const
|
|
151
|
+
const STYLES = StyleSheet.create({
|
|
130
152
|
container: {
|
|
131
153
|
flex: 1,
|
|
132
154
|
},
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
1
|
import React, { useMemo } from 'react';
|
|
3
2
|
import { View, StyleSheet, ViewStyle, StyleProp } from 'react-native';
|
|
4
3
|
import Animated, {
|
|
5
4
|
useAnimatedStyle,
|
|
6
5
|
useDerivedValue,
|
|
7
6
|
withSpring,
|
|
7
|
+
type SharedValue,
|
|
8
8
|
} from 'react-native-reanimated';
|
|
9
9
|
import type { IndicatorConfigs, PaginationProps } from '../types';
|
|
10
10
|
import { useCarouselContext } from './useCarouselContext';
|
|
@@ -114,7 +114,7 @@ function IndicatorItem({
|
|
|
114
114
|
activeIndicatorStyle,
|
|
115
115
|
indicatorStyle,
|
|
116
116
|
}: {
|
|
117
|
-
currentPage:
|
|
117
|
+
currentPage: SharedValue<number>;
|
|
118
118
|
pageNumber: number;
|
|
119
119
|
configs: IndicatorConfigs;
|
|
120
120
|
activeIndicatorStyle?: StyleProp<ViewStyle>;
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ScrollViewProps, StyleProp, ViewStyle } from 'react-native';
|
|
2
|
-
import type
|
|
2
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
3
3
|
|
|
4
4
|
export type CarouselProps<T = any> = {
|
|
5
5
|
style?: StyleProp<ViewStyle>;
|
|
@@ -17,18 +17,20 @@ export type CarouselProps<T = any> = {
|
|
|
17
17
|
inactiveScale?: number;
|
|
18
18
|
spaceBetween?: number;
|
|
19
19
|
spaceHeadTail?: number;
|
|
20
|
-
animatedPage?:
|
|
20
|
+
animatedPage?: SharedValue<number>;
|
|
21
21
|
scrollViewProps?: ScrollViewProps;
|
|
22
22
|
renderItem: (
|
|
23
23
|
data: { item: T; index?: number },
|
|
24
24
|
animatedData?: {
|
|
25
|
-
scrollPosition?:
|
|
25
|
+
scrollPosition?: SharedValue<number>;
|
|
26
26
|
offset?: number;
|
|
27
27
|
}
|
|
28
28
|
) => React.ReactNode;
|
|
29
29
|
onPageChange?: (index: number) => void;
|
|
30
30
|
keyExtractor?: (item: T, index?: number) => string;
|
|
31
31
|
onItemPress?: (item: T, index?: number) => void;
|
|
32
|
+
disableItemPress?: boolean;
|
|
33
|
+
scrollViewRef?: any;
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
export type CarouselHandles = {
|
|
@@ -41,8 +43,8 @@ export type CarouselContextType = {
|
|
|
41
43
|
goNext(): void;
|
|
42
44
|
goPrev(): void;
|
|
43
45
|
snapToItem(index: number, animated?: boolean): void;
|
|
44
|
-
currentPage:
|
|
45
|
-
totalPage:
|
|
46
|
+
currentPage: SharedValue<number>;
|
|
47
|
+
totalPage: SharedValue<number>;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
export type CarouselContextInternalType = {
|
|
@@ -50,9 +52,9 @@ export type CarouselContextInternalType = {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
export type AnimatorProps = {
|
|
53
|
-
animatedValue:
|
|
55
|
+
animatedValue: SharedValue<number>;
|
|
54
56
|
offset: number;
|
|
55
|
-
freeze:
|
|
57
|
+
freeze: SharedValue<boolean>;
|
|
56
58
|
itemWidth: number;
|
|
57
59
|
};
|
|
58
60
|
|
package/src/utils.ts
CHANGED
|
@@ -23,26 +23,46 @@ export const generateOffsets = ({
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
export const findNearestPage = (
|
|
27
|
-
offset: number,
|
|
28
|
-
offsets: number[],
|
|
29
|
-
delta: number
|
|
30
|
-
) => {
|
|
26
|
+
export const findNearestPage = (offset: number, offsets: number[]): number => {
|
|
31
27
|
'worklet';
|
|
32
|
-
let mid;
|
|
33
28
|
let lo = 0;
|
|
34
29
|
let hi = offsets.length - 1;
|
|
35
30
|
while (hi - lo > 1) {
|
|
36
|
-
mid = Math.floor((lo + hi) / 2);
|
|
31
|
+
const mid = Math.floor((lo + hi) / 2);
|
|
37
32
|
if (offsets[mid] < offset) {
|
|
38
33
|
lo = mid;
|
|
39
34
|
} else {
|
|
40
35
|
hi = mid;
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
return offset - offsets[lo] <= offsets[hi] - offset ? lo : hi;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function getLogicalPage(
|
|
42
|
+
renderIndex: number,
|
|
43
|
+
totalItems: number,
|
|
44
|
+
additionalPagesPerSide: number,
|
|
45
|
+
loop: boolean
|
|
46
|
+
): number {
|
|
47
|
+
'worklet';
|
|
48
|
+
if (!loop) {
|
|
49
|
+
return renderIndex;
|
|
50
|
+
}
|
|
51
|
+
return (renderIndex - additionalPagesPerSide + totalItems) % totalItems;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function getLoopBoundaryTarget(
|
|
55
|
+
renderPage: number,
|
|
56
|
+
totalPages: number,
|
|
57
|
+
additionalPagesPerSide: number
|
|
58
|
+
): number {
|
|
59
|
+
'worklet';
|
|
60
|
+
const totalRenderPages = totalPages + additionalPagesPerSide * 2;
|
|
61
|
+
if (renderPage <= 0) {
|
|
62
|
+
return totalPages;
|
|
63
|
+
}
|
|
64
|
+
if (renderPage >= totalRenderPages - 1) {
|
|
65
|
+
return renderPage - totalPages;
|
|
46
66
|
}
|
|
47
67
|
return -1;
|
|
48
|
-
}
|
|
68
|
+
}
|