@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.
Files changed (64) hide show
  1. package/lib/commonjs/components/Carousel.js +290 -195
  2. package/lib/commonjs/components/Carousel.js.map +1 -1
  3. package/lib/commonjs/components/CarouselContainer.js +17 -31
  4. package/lib/commonjs/components/CarouselContainer.js.map +1 -1
  5. package/lib/commonjs/components/PageItem.js +52 -45
  6. package/lib/commonjs/components/PageItem.js.map +1 -1
  7. package/lib/commonjs/components/PaginationIndicator.js +23 -34
  8. package/lib/commonjs/components/PaginationIndicator.js.map +1 -1
  9. package/lib/commonjs/components/useCarouselContext.js +3 -8
  10. package/lib/commonjs/components/useCarouselContext.js.map +1 -1
  11. package/lib/commonjs/components/useInternalCarouselContext.js +3 -6
  12. package/lib/commonjs/components/useInternalCarouselContext.js.map +1 -1
  13. package/lib/commonjs/index.js +7 -17
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/package.json +1 -0
  16. package/lib/commonjs/types.js +4 -0
  17. package/lib/commonjs/types.js.map +1 -1
  18. package/lib/commonjs/utils.js +24 -18
  19. package/lib/commonjs/utils.js.map +1 -1
  20. package/lib/module/components/Carousel.js +291 -180
  21. package/lib/module/components/Carousel.js.map +1 -1
  22. package/lib/module/components/CarouselContainer.js +18 -23
  23. package/lib/module/components/CarouselContainer.js.map +1 -1
  24. package/lib/module/components/PageItem.js +53 -37
  25. package/lib/module/components/PageItem.js.map +1 -1
  26. package/lib/module/components/PaginationIndicator.js +23 -24
  27. package/lib/module/components/PaginationIndicator.js.map +1 -1
  28. package/lib/module/components/useCarouselContext.js +2 -2
  29. package/lib/module/components/useCarouselContext.js.map +1 -1
  30. package/lib/module/components/useInternalCarouselContext.js +2 -0
  31. package/lib/module/components/useInternalCarouselContext.js.map +1 -1
  32. package/lib/module/index.js +2 -0
  33. package/lib/module/index.js.map +1 -1
  34. package/lib/module/types.js +2 -0
  35. package/lib/module/types.js.map +1 -1
  36. package/lib/module/utils.js +22 -12
  37. package/lib/module/utils.js.map +1 -1
  38. package/lib/typescript/components/Carousel.d.ts +3 -1
  39. package/lib/typescript/components/Carousel.d.ts.map +1 -0
  40. package/lib/typescript/components/CarouselContainer.d.ts +3 -2
  41. package/lib/typescript/components/CarouselContainer.d.ts.map +1 -0
  42. package/lib/typescript/components/PageItem.d.ts +5 -3
  43. package/lib/typescript/components/PageItem.d.ts.map +1 -0
  44. package/lib/typescript/components/PaginationIndicator.d.ts +3 -1
  45. package/lib/typescript/components/PaginationIndicator.d.ts.map +1 -0
  46. package/lib/typescript/components/useCarouselContext.d.ts +1 -1
  47. package/lib/typescript/components/useCarouselContext.d.ts.map +1 -0
  48. package/lib/typescript/components/useInternalCarouselContext.d.ts +1 -1
  49. package/lib/typescript/components/useInternalCarouselContext.d.ts.map +1 -0
  50. package/lib/typescript/index.d.ts +1 -0
  51. package/lib/typescript/index.d.ts.map +1 -0
  52. package/lib/typescript/types.d.ts +17 -15
  53. package/lib/typescript/types.d.ts.map +1 -0
  54. package/lib/typescript/utils.d.ts +4 -1
  55. package/lib/typescript/utils.d.ts.map +1 -0
  56. package/package.json +26 -29
  57. package/src/components/Carousel.tsx +407 -206
  58. package/src/components/CarouselContainer.tsx +4 -4
  59. package/src/components/PageItem.tsx +55 -33
  60. package/src/components/PaginationIndicator.tsx +2 -2
  61. package/src/components/useCarouselContext.ts +0 -1
  62. package/src/components/useInternalCarouselContext.ts +0 -1
  63. package/src/types.ts +9 -7
  64. 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 'src/types';
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>(Component: FC<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: Animated.SharedValue<number>;
22
+ animatedValue: SharedValue<number>;
23
23
  animation?: 'parallax';
24
- freeze: Animated.SharedValue<boolean>;
24
+ freeze: SharedValue<boolean>;
25
25
  itemWidth: number;
26
26
  inactiveOpacity: number;
27
27
  inactiveScale: number;
28
28
  containerStyle: StyleProp<ViewStyle>;
29
- onPress: () => void;
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: ViewStyle['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
- <TouchableOpacity
118
- activeOpacity={0.9}
119
- style={mContainerStyle}
131
+ <Pressable
132
+ style={({ pressed }) => [
133
+ mContainerStyle,
134
+ pressed && { opacity: 0.9 },
135
+ ]}
120
136
  onPress={onPress}
121
137
  >
122
- <Animated.View style={[styles.container, animatedStyle]}>
123
- {renderContent()}
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
- </TouchableOpacity>
147
+ </Pressable>
126
148
  );
127
149
  }
128
150
 
129
- const styles = StyleSheet.create({
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: Animated.SharedValue<number>;
117
+ currentPage: SharedValue<number>;
118
118
  pageNumber: number;
119
119
  configs: IndicatorConfigs;
120
120
  activeIndicatorStyle?: StyleProp<ViewStyle>;
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
1
  import { createContext, useContext } from 'react';
3
2
  import type { CarouselContextType } from '../types';
4
3
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
2
1
  import { createContext, useContext } from 'react';
3
2
  import type { CarouselContextInternalType } from '../types';
4
3
 
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ScrollViewProps, StyleProp, ViewStyle } from 'react-native';
2
- import type Animated from 'react-native-reanimated';
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?: Animated.SharedValue<number>;
20
+ animatedPage?: SharedValue<number>;
21
21
  scrollViewProps?: ScrollViewProps;
22
22
  renderItem: (
23
23
  data: { item: T; index?: number },
24
24
  animatedData?: {
25
- scrollPosition?: Animated.SharedValue<number>;
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: Animated.SharedValue<number>;
45
- totalPage: Animated.SharedValue<number>;
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: Animated.SharedValue<number>;
55
+ animatedValue: SharedValue<number>;
54
56
  offset: number;
55
- freeze: Animated.SharedValue<boolean>;
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
- const nearestPage = offset - offsets[lo] <= offsets[hi] - offset ? lo : hi;
44
- if (Math.abs(offsets[nearestPage] - offset) < delta) {
45
- return nearestPage;
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
+ }