@fountain-ui/lab 2.0.0-beta.17 → 2.0.0-beta.20

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 (52) hide show
  1. package/build/commonjs/Carousel/Carousel.js +6 -13
  2. package/build/commonjs/Carousel/Carousel.js.map +1 -1
  3. package/build/commonjs/Carousel/components/ScrollViewGesture.js +4 -3
  4. package/build/commonjs/Carousel/components/ScrollViewGesture.js.map +1 -1
  5. package/build/commonjs/Carousel/hooks/index.js +3 -3
  6. package/build/commonjs/Carousel/hooks/index.js.map +1 -1
  7. package/build/commonjs/Carousel/hooks/useIndexController.js +14 -13
  8. package/build/commonjs/Carousel/hooks/useIndexController.js.map +1 -1
  9. package/build/commonjs/Carousel/hooks/{usePagingAnimation.js → usePagingAnimator.js} +44 -22
  10. package/build/commonjs/Carousel/hooks/usePagingAnimator.js.map +1 -0
  11. package/build/commonjs/Carousel/types.js +1 -1
  12. package/build/commonjs/Carousel/types.js.map +1 -1
  13. package/build/commonjs/ViewPager/ChildrenMemoizedPage.js +1 -1
  14. package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +1 -1
  15. package/build/commonjs/ViewPager/ViewPagerNative.js +4 -3
  16. package/build/commonjs/ViewPager/ViewPagerNative.js.map +1 -1
  17. package/build/commonjs/ViewPager/ViewPagerWeb.js +4 -3
  18. package/build/commonjs/ViewPager/ViewPagerWeb.js.map +1 -1
  19. package/build/module/Carousel/Carousel.js +8 -12
  20. package/build/module/Carousel/Carousel.js.map +1 -1
  21. package/build/module/Carousel/components/ScrollViewGesture.js +4 -3
  22. package/build/module/Carousel/components/ScrollViewGesture.js.map +1 -1
  23. package/build/module/Carousel/hooks/index.js +1 -1
  24. package/build/module/Carousel/hooks/index.js.map +1 -1
  25. package/build/module/Carousel/hooks/useIndexController.js +14 -13
  26. package/build/module/Carousel/hooks/useIndexController.js.map +1 -1
  27. package/build/module/Carousel/hooks/{usePagingAnimation.js → usePagingAnimator.js} +43 -22
  28. package/build/module/Carousel/hooks/usePagingAnimator.js.map +1 -0
  29. package/build/module/Carousel/types.js +1 -1
  30. package/build/module/Carousel/types.js.map +1 -1
  31. package/build/module/ViewPager/ChildrenMemoizedPage.js +1 -1
  32. package/build/module/ViewPager/ChildrenMemoizedPage.js.map +1 -1
  33. package/build/module/ViewPager/ViewPagerNative.js +5 -4
  34. package/build/module/ViewPager/ViewPagerNative.js.map +1 -1
  35. package/build/module/ViewPager/ViewPagerWeb.js +5 -4
  36. package/build/module/ViewPager/ViewPagerWeb.js.map +1 -1
  37. package/build/typescript/Carousel/components/ScrollViewGesture.d.ts +1 -1
  38. package/build/typescript/Carousel/hooks/index.d.ts +1 -1
  39. package/build/typescript/Carousel/hooks/{usePagingAnimation.d.ts → usePagingAnimator.d.ts} +6 -5
  40. package/build/typescript/Carousel/types.d.ts +8 -4
  41. package/package.json +2 -2
  42. package/src/Carousel/Carousel.tsx +7 -12
  43. package/src/Carousel/components/ScrollViewGesture.tsx +8 -4
  44. package/src/Carousel/hooks/index.ts +1 -1
  45. package/src/Carousel/hooks/useIndexController.tsx +12 -20
  46. package/src/Carousel/hooks/{usePagingAnimation.ts → usePagingAnimator.ts} +48 -29
  47. package/src/Carousel/types.ts +9 -4
  48. package/src/ViewPager/ChildrenMemoizedPage.tsx +1 -1
  49. package/src/ViewPager/ViewPagerNative.tsx +4 -2
  50. package/src/ViewPager/ViewPagerWeb.tsx +4 -2
  51. package/build/commonjs/Carousel/hooks/usePagingAnimation.js.map +0 -1
  52. package/build/module/Carousel/hooks/usePagingAnimation.js.map +0 -1
@@ -4,8 +4,8 @@ import type { AutoplayController, StartPagingAnimation } from '../types';
4
4
  export interface ScrollViewGestureProps {
5
5
  autoplayController: AutoplayController;
6
6
  children: ReactNode;
7
+ gestureTranslationX: Animated.Value;
7
8
  interruptAnimation: () => void;
8
- translateX: Animated.Value;
9
9
  scrollEnabled: boolean;
10
10
  startPagingAnimation: StartPagingAnimation;
11
11
  }
@@ -1,5 +1,5 @@
1
1
  export { default as useAutoplayController } from './useAutoplayController';
2
2
  export { default as useIndexController } from './useIndexController';
3
3
  export { default as useLoopedData } from './useLoopedData';
4
- export { default as usePagingAnimation } from './usePagingAnimation';
4
+ export { default as usePagingAnimator } from './usePagingAnimator';
5
5
  export { default as useItemVisibilityStore } from './useItemVisibilityStore';
@@ -1,16 +1,17 @@
1
1
  import { Animated } from 'react-native';
2
2
  import type { CreateScrollAnimation, IndexController, StartPagingAnimation } from '../types';
3
- export interface PagingAnimationParameters {
3
+ export interface PagingAnimatorConfig {
4
4
  createScrollAnimation: CreateScrollAnimation;
5
5
  itemWidth: number;
6
6
  indexController: IndexController;
7
+ initialIndex: number;
7
8
  loop: boolean;
8
9
  numberOfData: number;
9
- offsetX: Animated.Value;
10
- translateX: Animated.Value;
11
10
  }
12
- export interface UsePagingAnimation {
11
+ export interface PagingAnimator {
12
+ gestureTranslationX: Animated.Value;
13
+ globalInterpolation: Animated.AnimatedInterpolation;
13
14
  interruptAnimation: () => void;
14
15
  startPagingAnimation: StartPagingAnimation;
15
16
  }
16
- export default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation;
17
+ export default function usePagingAnimator(config: PagingAnimatorConfig): PagingAnimator;
@@ -2,8 +2,8 @@ import type { ReactElement } from 'react';
2
2
  import type { Animated, ViewProps } from 'react-native';
3
3
  declare const directions: readonly ["next", "prev", "stay"];
4
4
  export declare type PagingDirection = (typeof directions)[number];
5
- declare const animationStates: readonly ["started", "finished", "interrupted"];
6
- export declare type AnimationState = (typeof animationStates)[number];
5
+ declare const scrollStates: readonly ["idle", "dragging", "interrupted"];
6
+ export declare type ScrollState = (typeof scrollStates)[number];
7
7
  export declare type ItemHeight = number | 'auto';
8
8
  export interface RenderItem<T> {
9
9
  (info: {
@@ -27,15 +27,19 @@ export interface OnIndexChange {
27
27
  export interface OnPositionChange {
28
28
  (position: number): void;
29
29
  }
30
+ export interface ScrollStateChangeEvent {
31
+ offset: number;
32
+ state: ScrollState;
33
+ }
30
34
  export interface IndexController {
31
35
  getCurrentIndex: GetCurrentIndex;
32
36
  lastIndex: number;
33
- notifyAnimationState: (state: AnimationState) => void;
34
- notifyOffsetHasChanged: (offset: number) => void;
37
+ notifyScrollStateHasChanged: (event: ScrollStateChangeEvent) => void;
35
38
  }
36
39
  export declare type PagingAnimationType = 'directional' | 'index';
37
40
  export interface BasePagingAnimationConfig {
38
41
  animated?: boolean;
42
+ lastGestureTranslationX?: number;
39
43
  }
40
44
  export interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {
41
45
  direction: PagingDirection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.17",
3
+ "version": "2.0.0-beta.20",
4
4
  "private": false,
5
5
  "author": "Fountain-UI Team",
6
6
  "description": "Incubator for Fountain-UI React components.",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "973591c61fab2561cea9f30d03e802a24817b5f8"
73
+ "gitHead": "e97185cf56e1f51817e29a7d1b7e43bcf8ef0342"
74
74
  }
@@ -1,5 +1,4 @@
1
- import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef } from 'react';
2
- import { Animated } from 'react-native';
1
+ import React, { forwardRef, memo, useImperativeHandle, useMemo } from 'react';
3
2
  import ViewabilityTrackerView from '../ViewabilityTrackerView';
4
3
  import type CarouselProps from './CarouselProps';
5
4
  import type { CarouselInstance } from './types';
@@ -8,7 +7,7 @@ import {
8
7
  useIndexController,
9
8
  useItemVisibilityStore,
10
9
  useLoopedData,
11
- usePagingAnimation,
10
+ usePagingAnimator,
12
11
  } from './hooks';
13
12
  import { createDefaultItemStyle, createDefaultScrollAnimation } from './animation';
14
13
  import { InternalContext, RootView, ScrollViewGesture } from './components';
@@ -34,11 +33,6 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
34
33
 
35
34
  const data = useLoopedData(originalData, loop);
36
35
 
37
- const initialTx = itemWidth * initialIndex;
38
- const offsetX = useRef(new Animated.Value(initialTx)).current;
39
- const translateX = useRef(new Animated.Value(0)).current;
40
- const globalInterpolation = Animated.add(offsetX, translateX);
41
-
42
36
  const [itemVisibilityStore, onPositionChange] = useItemVisibilityStore({
43
37
  initialIndex,
44
38
  numberOfData: data.length,
@@ -57,16 +51,17 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
57
51
  const { getCurrentIndex } = indexController;
58
52
 
59
53
  const {
54
+ gestureTranslationX,
55
+ globalInterpolation,
60
56
  interruptAnimation,
61
57
  startPagingAnimation,
62
- } = usePagingAnimation({
58
+ } = usePagingAnimator({
63
59
  createScrollAnimation,
64
60
  itemWidth,
65
61
  indexController,
62
+ initialIndex,
66
63
  loop,
67
64
  numberOfData: data.length,
68
- offsetX,
69
- translateX,
70
65
  });
71
66
 
72
67
  const autoplayController = useAutoplayController({
@@ -119,8 +114,8 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
119
114
  >
120
115
  <ScrollViewGesture
121
116
  autoplayController={autoplayController}
117
+ gestureTranslationX={gestureTranslationX}
122
118
  interruptAnimation={interruptAnimation}
123
- translateX={translateX}
124
119
  scrollEnabled={scrollEnabled}
125
120
  startPagingAnimation={startPagingAnimation}
126
121
  >
@@ -8,8 +8,8 @@ import type { AutoplayController, PagingDirection, StartPagingAnimation } from '
8
8
  export interface ScrollViewGestureProps {
9
9
  autoplayController: AutoplayController;
10
10
  children: ReactNode;
11
+ gestureTranslationX: Animated.Value,
11
12
  interruptAnimation: () => void;
12
- translateX: Animated.Value,
13
13
  scrollEnabled: boolean;
14
14
  startPagingAnimation: StartPagingAnimation;
15
15
  }
@@ -40,7 +40,7 @@ export default function ScrollViewGesture(props: ScrollViewGestureProps) {
40
40
  autoplayController,
41
41
  children,
42
42
  interruptAnimation,
43
- translateX,
43
+ gestureTranslationX,
44
44
  scrollEnabled,
45
45
  startPagingAnimation,
46
46
  } = props;
@@ -54,7 +54,7 @@ export default function ScrollViewGesture(props: ScrollViewGestureProps) {
54
54
  }, [interruptAnimation, pauseAutoplay]);
55
55
 
56
56
  const handleGestureEvent = useCallback(Animated.event(
57
- [{ nativeEvent: { translationX: translateX } }],
57
+ [{ nativeEvent: { translationX: gestureTranslationX } }],
58
58
  { useNativeDriver: true },
59
59
  ), []);
60
60
 
@@ -68,7 +68,11 @@ export default function ScrollViewGesture(props: ScrollViewGestureProps) {
68
68
 
69
69
  startPagingAnimation(
70
70
  'directional',
71
- { direction: direction, isOriginatedFromGesture: true },
71
+ {
72
+ direction: direction,
73
+ isOriginatedFromGesture: true,
74
+ lastGestureTranslationX: translationX,
75
+ },
72
76
  );
73
77
 
74
78
  resumeAutoplay();
@@ -1,5 +1,5 @@
1
1
  export { default as useAutoplayController } from './useAutoplayController';
2
2
  export { default as useIndexController } from './useIndexController';
3
3
  export { default as useLoopedData } from './useLoopedData';
4
- export { default as usePagingAnimation } from './usePagingAnimation';
4
+ export { default as usePagingAnimator } from './usePagingAnimator';
5
5
  export { default as useItemVisibilityStore } from './useItemVisibilityStore';
@@ -1,7 +1,7 @@
1
1
  import { useCallback } from 'react';
2
2
  import { useImperativeState } from '@fountain-ui/core';
3
3
  import { mod } from '@fountain-ui/utils';
4
- import type { AnimationState, IndexController } from '../types';
4
+ import type { IndexController, ScrollStateChangeEvent } from '../types';
5
5
 
6
6
  export interface UseIndexControllerParameters {
7
7
  initialIndex: number;
@@ -25,41 +25,33 @@ export default function useIndexController(params: UseIndexControllerParameters)
25
25
  const currentIndex = useImperativeState(initialIndex);
26
26
  const currentPosition = useImperativeState(initialIndex);
27
27
 
28
- const notifyAnimationState = useCallback((state: AnimationState) => {
29
- if (state === 'finished' || state === 'interrupted') {
28
+ const notifyScrollStateHasChanged = useCallback(({ offset, state }: ScrollStateChangeEvent) => {
29
+ const normalized = -Math.round(offset / itemWidth);
30
+ const index = Math.floor(mod(normalized, numberOfOriginalData));
31
+ const position = Math.floor(mod(normalized, numberOfData));
32
+
33
+ if (state === 'idle' || state === 'interrupted') {
30
34
  if (currentIndex.hasChanged()) {
31
35
  onIndexChange?.(currentIndex.get());
32
36
  }
33
-
34
37
  if (currentPosition.hasChanged()) {
35
38
  onPositionChange?.(currentPosition.get());
36
39
  }
37
40
  }
38
- }, [
39
- onIndexChange,
40
- onPositionChange,
41
- ]);
42
-
43
- const notifyOffsetHasChanged = useCallback((offset: number) => {
44
- const roundedOffset = Math.round(offset / itemWidth) * itemWidth;
45
-
46
- // To prevent floating point problem, make sure index is integer type.
47
- const nextIndex = Math.floor(mod((-roundedOffset / itemWidth), numberOfOriginalData));
48
- currentIndex.set(nextIndex);
49
41
 
50
- // To prevent floating point problem, make sure index is integer type.
51
- const nextPosition = Math.floor(mod((-roundedOffset / itemWidth), numberOfData));
52
- currentPosition.set(nextPosition);
42
+ currentIndex.set(index);
43
+ currentPosition.set(position);
53
44
  }, [
54
45
  itemWidth,
55
46
  numberOfData,
56
47
  numberOfOriginalData,
48
+ onIndexChange,
49
+ onPositionChange,
57
50
  ]);
58
51
 
59
52
  return {
60
53
  getCurrentIndex: currentIndex.get,
61
54
  lastIndex: numberOfOriginalData - 1,
62
- notifyAnimationState,
63
- notifyOffsetHasChanged,
55
+ notifyScrollStateHasChanged,
64
56
  };
65
57
  };
@@ -1,4 +1,4 @@
1
- import { useCallback, useRef } from 'react';
1
+ import { useCallback, useMemo, useRef } from 'react';
2
2
  import { Animated } from 'react-native';
3
3
  import type {
4
4
  CreateScrollAnimation,
@@ -11,17 +11,18 @@ import type {
11
11
  StartPagingAnimation,
12
12
  } from '../types';
13
13
 
14
- export interface PagingAnimationParameters {
14
+ export interface PagingAnimatorConfig {
15
15
  createScrollAnimation: CreateScrollAnimation;
16
16
  itemWidth: number;
17
17
  indexController: IndexController;
18
+ initialIndex: number;
18
19
  loop: boolean;
19
20
  numberOfData: number;
20
- offsetX: Animated.Value;
21
- translateX: Animated.Value;
22
21
  }
23
22
 
24
- export interface UsePagingAnimation {
23
+ export interface PagingAnimator {
24
+ gestureTranslationX: Animated.Value;
25
+ globalInterpolation: Animated.AnimatedInterpolation;
25
26
  interruptAnimation: () => void;
26
27
  startPagingAnimation: StartPagingAnimation;
27
28
  }
@@ -54,24 +55,34 @@ function toValueCompensator(itemWidth: number) {
54
55
  };
55
56
  }
56
57
 
57
- export default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {
58
+ export default function usePagingAnimator(config: PagingAnimatorConfig): PagingAnimator {
58
59
  const {
59
60
  createScrollAnimation,
60
61
  itemWidth,
61
62
  indexController,
63
+ initialIndex,
62
64
  loop,
63
65
  numberOfData,
64
- offsetX,
65
- translateX,
66
- } = params;
66
+ } = config;
67
67
 
68
68
  const {
69
69
  getCurrentIndex,
70
70
  lastIndex,
71
- notifyAnimationState,
72
- notifyOffsetHasChanged,
71
+ notifyScrollStateHasChanged,
73
72
  } = indexController;
74
73
 
74
+ const initialOffsetX = itemWidth * initialIndex;
75
+ const accumulativeOffsetX = useRef(new Animated.Value(initialOffsetX)).current;
76
+ const animationOffsetX = useRef(new Animated.Value(0)).current;
77
+ const gestureTranslationX = useRef(new Animated.Value(0)).current;
78
+
79
+ const globalInterpolation = useMemo(() => {
80
+ return Animated.add(
81
+ Animated.add(accumulativeOffsetX, animationOffsetX),
82
+ gestureTranslationX,
83
+ );
84
+ }, []);
85
+
75
86
  const toValueRef = useRef<number>(0);
76
87
  const currentOffsetRef = useRef<number>(0);
77
88
 
@@ -95,14 +106,12 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
95
106
  const nextOffset = ensureOffsetBoundary(newOffset);
96
107
 
97
108
  currentOffsetRef.current = nextOffset;
98
- offsetX.setValue(nextOffset);
109
+ accumulativeOffsetX.setValue(nextOffset);
99
110
 
100
111
  toValueRef.current = 0;
101
- translateX.setValue(0);
112
+ animationOffsetX.setValue(0);
102
113
  }, [
103
114
  ensureOffsetBoundary,
104
- offsetX,
105
- translateX,
106
115
  ]);
107
116
 
108
117
  const interruptAnimation = useCallback(() => {
@@ -110,22 +119,22 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
110
119
  return;
111
120
  }
112
121
 
113
- translateX.stopAnimation(lastValue => {
122
+ animationOffsetX.stopAnimation(lastValue => {
114
123
  isAnimatingRef.current = false;
115
124
 
116
125
  const prevOffset = currentOffsetRef.current;
117
126
  const totalOffset = prevOffset + lastValue;
118
127
 
119
- notifyOffsetHasChanged(totalOffset);
120
- notifyAnimationState('interrupted');
121
-
122
128
  requireNewOffset(totalOffset);
129
+
130
+ notifyScrollStateHasChanged({ offset: totalOffset, state: 'interrupted' });
123
131
  });
124
- }, [requireNewOffset, translateX]);
132
+ }, [
133
+ notifyScrollStateHasChanged,
134
+ requireNewOffset,
135
+ ]);
125
136
 
126
137
  const finalizeAnimation = useCallback(() => {
127
- notifyAnimationState('finished');
128
-
129
138
  isAnimatingRef.current = false;
130
139
 
131
140
  const prevOffset = currentOffsetRef.current;
@@ -133,8 +142,10 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
133
142
  const totalOffset = prevOffset + toValue;
134
143
 
135
144
  requireNewOffset(totalOffset);
145
+
146
+ notifyScrollStateHasChanged({ offset: totalOffset, state: 'idle' });
136
147
  }, [
137
- notifyAnimationState,
148
+ notifyScrollStateHasChanged,
138
149
  requireNewOffset,
139
150
  ]);
140
151
 
@@ -202,18 +213,25 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
202
213
  toValueRef.current = toValue;
203
214
  isAnimatingRef.current = true;
204
215
 
205
- notifyOffsetHasChanged(currentOffsetRef.current + toValue);
216
+ notifyScrollStateHasChanged({
217
+ offset: currentOffsetRef.current + toValue,
218
+ state: 'dragging',
219
+ });
220
+
221
+ const lastGestureTranslationX: number = configWithDefaults.lastGestureTranslationX ?? 0;
222
+ if (Number.isFinite(lastGestureTranslationX)) {
223
+ animationOffsetX.setValue(lastGestureTranslationX);
224
+ gestureTranslationX.setValue(0);
225
+ }
206
226
 
207
227
  if (configWithDefaults.animated) {
208
- const animation = createScrollAnimation(translateX, toValue);
228
+ const animation = createScrollAnimation(animationOffsetX, toValue);
209
229
 
210
230
  animation.start(({ finished }) => {
211
231
  if (finished) {
212
232
  finalizeAnimation();
213
233
  }
214
234
  });
215
-
216
- notifyAnimationState('started');
217
235
  } else {
218
236
  finalizeAnimation();
219
237
  }
@@ -224,11 +242,12 @@ export default function usePagingAnimation(params: PagingAnimationParameters): U
224
242
  itemWidth,
225
243
  lastIndex,
226
244
  loop,
227
- notifyAnimationState,
228
- notifyOffsetHasChanged,
245
+ notifyScrollStateHasChanged,
229
246
  ]);
230
247
 
231
248
  return {
249
+ gestureTranslationX,
250
+ globalInterpolation,
232
251
  interruptAnimation,
233
252
  startPagingAnimation,
234
253
  };
@@ -5,9 +5,9 @@ const directions = ['next', 'prev', 'stay'] as const;
5
5
 
6
6
  export type PagingDirection = (typeof directions)[number];
7
7
 
8
- const animationStates = ['started', 'finished', 'interrupted'] as const;
8
+ const scrollStates = ['idle', 'dragging', 'interrupted'] as const;
9
9
 
10
- export type AnimationState = (typeof animationStates)[number];
10
+ export type ScrollState = (typeof scrollStates)[number];
11
11
 
12
12
  export type ItemHeight = number | 'auto';
13
13
 
@@ -35,17 +35,22 @@ export interface OnPositionChange {
35
35
  (position: number): void;
36
36
  }
37
37
 
38
+ export interface ScrollStateChangeEvent {
39
+ offset: number;
40
+ state: ScrollState;
41
+ }
42
+
38
43
  export interface IndexController {
39
44
  getCurrentIndex: GetCurrentIndex;
40
45
  lastIndex: number;
41
- notifyAnimationState: (state: AnimationState) => void;
42
- notifyOffsetHasChanged: (offset: number) => void;
46
+ notifyScrollStateHasChanged: (event: ScrollStateChangeEvent) => void;
43
47
  }
44
48
 
45
49
  export type PagingAnimationType = 'directional' | 'index';
46
50
 
47
51
  export interface BasePagingAnimationConfig {
48
52
  animated?: boolean;
53
+ lastGestureTranslationX?: number;
49
54
  }
50
55
 
51
56
  export interface DirectionalPagingAnimationConfig extends BasePagingAnimationConfig {
@@ -109,5 +109,5 @@ export default memo(Page, (prevProps, nextProps) => {
109
109
  return false;
110
110
  }
111
111
 
112
- return prevProps.index !== nextProps.index;
112
+ return prevProps.index === nextProps.index;
113
113
  });
@@ -1,4 +1,4 @@
1
- import React, { Children, forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
1
+ import React, { Children, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
2
2
  import type { ViewPagerOnPageSelectedEvent } from 'react-native-pager-view';
3
3
  import RNViewPager from 'react-native-pager-view';
4
4
  import { useSyncAnimatedValue } from '@fountain-ui/core';
@@ -117,10 +117,12 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
117
117
 
118
118
  const pageStore = usePageStore(sharedPage);
119
119
 
120
+ const contextValue = useMemo(() => ({ pageStore }), [pageStore]);
121
+
120
122
  const PageComponent = pageComponent;
121
123
 
122
124
  return (
123
- <InternalContext.Provider value={{ pageStore }}>
125
+ <InternalContext.Provider value={contextValue}>
124
126
  <RNViewPager
125
127
  ref={pagerRef}
126
128
  initialPage={sharedPage.initialValue}
@@ -1,4 +1,4 @@
1
- import React, { Children, forwardRef, useCallback, useImperativeHandle } from 'react';
1
+ import React, { Children, forwardRef, useCallback, useImperativeHandle, useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { StyleSheet, useSyncAnimatedValue } from '@fountain-ui/core';
4
4
  import type ViewPagerProps from './ViewPagerProps';
@@ -42,10 +42,12 @@ const ViewPager = forwardRef<ViewPagerInstance, ViewPagerProps>(function ViewPag
42
42
 
43
43
  const pageStore = usePageStore(sharedPage);
44
44
 
45
+ const contextValue = useMemo(() => ({ pageStore }), [pageStore]);
46
+
45
47
  const PageComponent = pageComponent;
46
48
 
47
49
  return (
48
- <InternalContext.Provider value={{ pageStore }}>
50
+ <InternalContext.Provider value={contextValue}>
49
51
  <View style={[styles.root, style]}>
50
52
  {Children.map(children, (child, index) => (
51
53
  <PageComponent
@@ -1 +0,0 @@
1
- {"version":3,"names":["directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyAnimationState","notifyOffsetHasChanged","toValueRef","useRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","useCallback","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyAnimationState,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (!isAnimatingRef.current) {\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n notifyAnimationState('interrupted');\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n notifyAnimationState('finished');\n\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [\n notifyAnimationState,\n requireNewOffset,\n ]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n\n notifyAnimationState('started');\n } else {\n finalizeAnimation();\n }\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyAnimationState,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":";;;;;;;AAAA;;AA4BA,SAASA,gBAAT,CAA0BC,SAA1B,EAA6C;EACzC,OAAO,UAAUC,SAAV,EAA8C;IACjD,QAAQA,SAAR;MACI,KAAK,MAAL;QACI,OAAO,CAACD,SAAR;;MACJ,KAAK,MAAL;QACI,OAAOA,SAAP;;MACJ,KAAK,MAAL;QACI,OAAO,CAAP;IANR;EAQH,CATD;AAUH;;AAED,SAASE,kBAAT,CAA4BF,SAA5B,EAA+C;EAC3C,OAAO,UAAUG,OAAV,EAA2BC,aAA3B,EAA0D;IAC7D,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAL,CAASH,aAAa,GAAGJ,SAAzB,CAAlB;IAEA,MAAMQ,eAAe,GAAGF,IAAI,CAACC,GAAL,CAASP,SAAS,GAAG,CAArB,CAAxB;IACA,MAAMS,gBAAgB,GAAGJ,SAAS,GAAGG,eAAZ,GACnBH,SAAS,GAAGL,SADO,GAEnBK,SAFN;IAIA,MAAMJ,SAAS,GAAGG,aAAa,GAAG,CAAhB,GAAoB,CAAC,CAArB,GAAyB,CAA3C;IAEA,OAAOD,OAAO,GAAIF,SAAS,GAAGQ,gBAA9B;EACH,CAXD;AAYH;;AAEc,SAASC,kBAAT,CAA4BC,MAA5B,EAAmF;EAC9F,MAAM;IACFC,qBADE;IAEFZ,SAFE;IAGFa,eAHE;IAIFC,IAJE;IAKFC,YALE;IAMFC,OANE;IAOFC;EAPE,IAQFN,MARJ;EAUA,MAAM;IACFO,eADE;IAEFC,SAFE;IAGFC,oBAHE;IAIFC;EAJE,IAKFR,eALJ;EAOA,MAAMS,UAAU,GAAG,IAAAC,aAAA,EAAe,CAAf,CAAnB;EACA,MAAMC,gBAAgB,GAAG,IAAAD,aAAA,EAAe,CAAf,CAAzB;EAEA,MAAME,cAAc,GAAG,IAAAF,aAAA,EAAgB,KAAhB,CAAvB;EAEA,MAAMG,QAAQ,GAAGpB,IAAI,CAACC,GAAL,CAASQ,YAAY,GAAGf,SAAxB,CAAjB;EAEA,MAAM2B,oBAAgD,GAAG,IAAAC,kBAAA,EAAaC,MAAD,IAAoB;IACrF,IAAIf,IAAJ,EAAU;MACN,MAAMgB,YAAY,GAAGxB,IAAI,CAACC,GAAL,CAASsB,MAAT,KAAqBH,QAAQ,GAAG1B,SAArD;;MACA,IAAI8B,YAAJ,EAAkB;QACd,MAAMC,YAAY,GAAGF,MAAM,GAAG,CAAT,GAAa,CAAb,GAAiB,CAAC,CAAvC;QACA,OAAOA,MAAM,GAAI,CAACE,YAAD,GAAgBL,QAAjC;MACH;IACJ;;IAED,OAAOG,MAAM,GAAGH,QAAhB;EACH,CAVwD,EAUtD,CAAC1B,SAAD,EAAYc,IAAZ,EAAkBY,QAAlB,CAVsD,CAAzD;EAYA,MAAMM,gBAAgB,GAAG,IAAAJ,kBAAA,EAAaK,SAAD,IAAuB;IACxD,MAAMC,UAAU,GAAGP,oBAAoB,CAACM,SAAD,CAAvC;IAEAT,gBAAgB,CAACW,OAAjB,GAA2BD,UAA3B;IACAlB,OAAO,CAACoB,QAAR,CAAiBF,UAAjB;IAEAZ,UAAU,CAACa,OAAX,GAAqB,CAArB;IACAlB,UAAU,CAACmB,QAAX,CAAoB,CAApB;EACH,CARwB,EAQtB,CACCT,oBADD,EAECX,OAFD,EAGCC,UAHD,CARsB,CAAzB;EAcA,MAAMoB,kBAAkB,GAAG,IAAAT,kBAAA,EAAY,MAAM;IACzC,IAAI,CAACH,cAAc,CAACU,OAApB,EAA6B;MACzB;IACH;;IAEDlB,UAAU,CAACqB,aAAX,CAAyBC,SAAS,IAAI;MAClCd,cAAc,CAACU,OAAf,GAAyB,KAAzB;MAEA,MAAMK,UAAU,GAAGhB,gBAAgB,CAACW,OAApC;MACA,MAAMM,WAAW,GAAGD,UAAU,GAAGD,SAAjC;MAEAlB,sBAAsB,CAACoB,WAAD,CAAtB;MACArB,oBAAoB,CAAC,aAAD,CAApB;MAEAY,gBAAgB,CAACS,WAAD,CAAhB;IACH,CAVD;EAWH,CAhB0B,EAgBxB,CAACT,gBAAD,EAAmBf,UAAnB,CAhBwB,CAA3B;EAkBA,MAAMyB,iBAAiB,GAAG,IAAAd,kBAAA,EAAY,MAAM;IACxCR,oBAAoB,CAAC,UAAD,CAApB;IAEAK,cAAc,CAACU,OAAf,GAAyB,KAAzB;IAEA,MAAMK,UAAU,GAAGhB,gBAAgB,CAACW,OAApC;IACA,MAAMhC,OAAO,GAAGmB,UAAU,CAACa,OAA3B;IACA,MAAMM,WAAW,GAAGD,UAAU,GAAGrC,OAAjC;IAEA6B,gBAAgB,CAACS,WAAD,CAAhB;EACH,CAVyB,EAUvB,CACCrB,oBADD,EAECY,gBAFD,CAVuB,CAA1B;EAeA,MAAMW,oBAAoB,GAAG,IAAAf,kBAAA,EAAY,CAACgB,IAAD,EAA4BC,MAA5B,KAA8D;IACnG,IAAIpB,cAAc,CAACU,OAAnB,EAA4B;MACxB;IACH;;IAED,MAAMW,kBAAyC,GAAG;MAC9CC,QAAQ,EAAE,IADoC;MAE9C,GAAGF;IAF2C,CAAlD;IAKA,MAAMG,YAAY,GAAG9B,eAAe,EAApC;IAEA,MAAM+B,4CAA4C,GAAGlD,gBAAgB,CAACC,SAAD,CAArE;IACA,MAAMkD,iBAAiB,GAAGhD,kBAAkB,CAACF,SAAD,CAA5C;;IAEA,MAAMmD,yCAAyC,GAAIC,OAAD,IAAuD;MACrG,MAAM;QAAEnD,SAAF;QAAaoD;MAAb,IAAyCD,OAA/C;;MAEA,IAAIJ,YAAY,KAAK,CAAjB,IAAsB/C,SAAS,KAAK,MAAxC,EAAgD;QAC5C,OAAOoD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB,CAAC9B,SAAD,GAAanB,SAFnB,CAD4C,CAGd;MACjC,CAJD,MAIO,IAAIgD,YAAY,KAAK7B,SAAjB,IAA8BlB,SAAS,KAAK,MAAhD,EAAwD;QAC3D,OAAOoD,uBAAuB,GACxBJ,4CAA4C,CAAC,MAAD,CADpB,GAExB9B,SAAS,GAAGnB,SAFlB,CAD2D,CAG9B;MAChC;;MACD,OAAOiD,4CAA4C,CAAChD,SAAD,CAAnD;IACH,CAbD;;IAeA,MAAMqD,2BAA2B,GAAIF,OAAD,IAAuD;MACvF,MAAMG,mBAAqD,GAAG;QAC1DF,uBAAuB,EAAE,KADiC;QAE1D,GAAGD;MAFuD,CAA9D;MAKA,OAAOtC,IAAI,GACLmC,4CAA4C,CAACM,mBAAmB,CAACtD,SAArB,CADvC,GAELkD,yCAAyC,CAACI,mBAAD,CAF/C;IAGH,CATD;;IAWA,MAAMC,qBAAqB,GAAG,QAAmD;MAAA,IAAlD;QAAEC;MAAF,CAAkD;;MAC7E,IAAIA,KAAK,GAAG,CAAR,IAAaA,KAAK,GAAGtC,SAArB,IAAkCsC,KAAK,KAAKT,YAAhD,EAA8D;QAC1D;QACA,OAAO,CAAP;MACH;;MAED,MAAMU,QAAQ,GAAGpD,IAAI,CAACC,GAAL,CAASyC,YAAY,GAAGS,KAAxB,IAAiCzD,SAAlD;MACA,MAAMC,SAAS,GAAGwD,KAAK,GAAGT,YAAR,GAAuB,CAAC,CAAxB,GAA4B,CAA9C;MAEA,OAAOU,QAAQ,GAAGzD,SAAlB;IACH,CAVD;;IAYA,MAAM0D,aAAa,GAAGf,IAAI,KAAK,aAAT,CAClB;IADkB,EAEhBU,2BAA2B,CAACR,kBAAD,CAFX,CAGlB;IAHkB,EAIhBU,qBAAqB,CAACV,kBAAD,CAJ3B;IAMA,MAAM3C,OAAO,GAAG+C,iBAAiB,CAACS,aAAD,EAAgBnC,gBAAgB,CAACW,OAAjC,CAAjC;IAEAb,UAAU,CAACa,OAAX,GAAqBhC,OAArB;IACAsB,cAAc,CAACU,OAAf,GAAyB,IAAzB;IAEAd,sBAAsB,CAACG,gBAAgB,CAACW,OAAjB,GAA2BhC,OAA5B,CAAtB;;IAEA,IAAI2C,kBAAkB,CAACC,QAAvB,EAAiC;MAC7B,MAAMa,SAAS,GAAGhD,qBAAqB,CAACK,UAAD,EAAad,OAAb,CAAvC;MAEAyD,SAAS,CAACC,KAAV,CAAgB,SAAkB;QAAA,IAAjB;UAAEC;QAAF,CAAiB;;QAC9B,IAAIA,QAAJ,EAAc;UACVpB,iBAAiB;QACpB;MACJ,CAJD;MAMAtB,oBAAoB,CAAC,SAAD,CAApB;IACH,CAVD,MAUO;MACHsB,iBAAiB;IACpB;EACJ,CA/E4B,EA+E1B,CACC9B,qBADD,EAECM,eAFD,EAGCwB,iBAHD,EAIC1C,SAJD,EAKCmB,SALD,EAMCL,IAND,EAOCM,oBAPD,EAQCC,sBARD,CA/E0B,CAA7B;EA0FA,OAAO;IACHgB,kBADG;IAEHM;EAFG,CAAP;AAIH;;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"names":["useCallback","useRef","directionToValue","itemWidth","direction","toValueCompensator","toValue","currentOffset","remainder","Math","abs","halfOfItemWidth","compensateVector","usePagingAnimation","params","createScrollAnimation","indexController","loop","numberOfData","offsetX","translateX","getCurrentIndex","lastIndex","notifyAnimationState","notifyOffsetHasChanged","toValueRef","currentOffsetRef","isAnimatingRef","maxWidth","ensureOffsetBoundary","offset","isCloseToEnd","signOfOffset","requireNewOffset","newOffset","nextOffset","current","setValue","interruptAnimation","stopAnimation","lastValue","prevOffset","totalOffset","finalizeAnimation","startPagingAnimation","type","config","configWithDefaults","animated","currentIndex","getValueByDirectionOnAllAdjacentItemsVisible","compensateToValue","getValueByDirectionalPagingOnLoopDisabled","_config","isOriginatedFromGesture","getValueByDirectionalPaging","_configWithDefaults","getValueByIndexPaging","index","distance","wantedToValue","animation","start","finished"],"sources":["usePagingAnimation.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport type {\n CreateScrollAnimation,\n DirectionalPagingAnimationConfig,\n IndexController,\n IndexPagingAnimationConfig,\n PagingAnimationConfig,\n PagingAnimationType,\n PagingDirection,\n StartPagingAnimation,\n} from '../types';\n\nexport interface PagingAnimationParameters {\n createScrollAnimation: CreateScrollAnimation;\n itemWidth: number;\n indexController: IndexController;\n loop: boolean;\n numberOfData: number;\n offsetX: Animated.Value;\n translateX: Animated.Value;\n}\n\nexport interface UsePagingAnimation {\n interruptAnimation: () => void;\n startPagingAnimation: StartPagingAnimation;\n}\n\nfunction directionToValue(itemWidth: number) {\n return function (direction: PagingDirection): number {\n switch (direction) {\n case 'next':\n return -itemWidth;\n case 'prev':\n return itemWidth;\n case 'stay':\n return 0;\n }\n };\n}\n\nfunction toValueCompensator(itemWidth: number) {\n return function (toValue: number, currentOffset: number): number {\n const remainder = Math.abs(currentOffset % itemWidth);\n\n const halfOfItemWidth = Math.abs(itemWidth / 2);\n const compensateVector = remainder > halfOfItemWidth\n ? remainder - itemWidth\n : remainder;\n\n const direction = currentOffset > 0 ? -1 : 1;\n\n return toValue + (direction * compensateVector);\n };\n}\n\nexport default function usePagingAnimation(params: PagingAnimationParameters): UsePagingAnimation {\n const {\n createScrollAnimation,\n itemWidth,\n indexController,\n loop,\n numberOfData,\n offsetX,\n translateX,\n } = params;\n\n const {\n getCurrentIndex,\n lastIndex,\n notifyAnimationState,\n notifyOffsetHasChanged,\n } = indexController;\n\n const toValueRef = useRef<number>(0);\n const currentOffsetRef = useRef<number>(0);\n\n const isAnimatingRef = useRef<boolean>(false);\n\n const maxWidth = Math.abs(numberOfData * itemWidth);\n\n const ensureOffsetBoundary: (offset: number) => number = useCallback((offset: number) => {\n if (loop) {\n const isCloseToEnd = Math.abs(offset) >= (maxWidth - itemWidth);\n if (isCloseToEnd) {\n const signOfOffset = offset > 0 ? 1 : -1;\n return offset + (-signOfOffset * maxWidth);\n }\n }\n\n return offset % maxWidth;\n }, [itemWidth, loop, maxWidth]);\n\n const requireNewOffset = useCallback((newOffset: number) => {\n const nextOffset = ensureOffsetBoundary(newOffset);\n\n currentOffsetRef.current = nextOffset;\n offsetX.setValue(nextOffset);\n\n toValueRef.current = 0;\n translateX.setValue(0);\n }, [\n ensureOffsetBoundary,\n offsetX,\n translateX,\n ]);\n\n const interruptAnimation = useCallback(() => {\n if (!isAnimatingRef.current) {\n return;\n }\n\n translateX.stopAnimation(lastValue => {\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const totalOffset = prevOffset + lastValue;\n\n notifyOffsetHasChanged(totalOffset);\n notifyAnimationState('interrupted');\n\n requireNewOffset(totalOffset);\n });\n }, [requireNewOffset, translateX]);\n\n const finalizeAnimation = useCallback(() => {\n notifyAnimationState('finished');\n\n isAnimatingRef.current = false;\n\n const prevOffset = currentOffsetRef.current;\n const toValue = toValueRef.current;\n const totalOffset = prevOffset + toValue;\n\n requireNewOffset(totalOffset);\n }, [\n notifyAnimationState,\n requireNewOffset,\n ]);\n\n const startPagingAnimation = useCallback((type: PagingAnimationType, config: PagingAnimationConfig) => {\n if (isAnimatingRef.current) {\n return;\n }\n\n const configWithDefaults: PagingAnimationConfig = {\n animated: true,\n ...config,\n };\n\n const currentIndex = getCurrentIndex();\n\n const getValueByDirectionOnAllAdjacentItemsVisible = directionToValue(itemWidth);\n const compensateToValue = toValueCompensator(itemWidth);\n\n const getValueByDirectionalPagingOnLoopDisabled = (_config: DirectionalPagingAnimationConfig): number => {\n const { direction, isOriginatedFromGesture } = _config;\n\n if (currentIndex === 0 && direction === 'prev') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : -lastIndex * itemWidth; // last position\n } else if (currentIndex === lastIndex && direction === 'next') {\n return isOriginatedFromGesture\n ? getValueByDirectionOnAllAdjacentItemsVisible('stay')\n : lastIndex * itemWidth; // first position\n }\n return getValueByDirectionOnAllAdjacentItemsVisible(direction);\n };\n\n const getValueByDirectionalPaging = (_config: DirectionalPagingAnimationConfig): number => {\n const _configWithDefaults: DirectionalPagingAnimationConfig = {\n isOriginatedFromGesture: false,\n ..._config,\n };\n\n return loop\n ? getValueByDirectionOnAllAdjacentItemsVisible(_configWithDefaults.direction)\n : getValueByDirectionalPagingOnLoopDisabled(_configWithDefaults);\n };\n\n const getValueByIndexPaging = ({ index }: IndexPagingAnimationConfig): number => {\n if (index < 0 || index > lastIndex || index === currentIndex) {\n // no animation if index is invalid or equals to current index\n return 0;\n }\n\n const distance = Math.abs(currentIndex - index) * itemWidth;\n const direction = index > currentIndex ? -1 : 1;\n\n return distance * direction;\n };\n\n const wantedToValue = type === 'directional'\n // @ts-ignore\n ? getValueByDirectionalPaging(configWithDefaults)\n // @ts-ignore\n : getValueByIndexPaging(configWithDefaults);\n\n const toValue = compensateToValue(wantedToValue, currentOffsetRef.current);\n\n toValueRef.current = toValue;\n isAnimatingRef.current = true;\n\n notifyOffsetHasChanged(currentOffsetRef.current + toValue);\n\n if (configWithDefaults.animated) {\n const animation = createScrollAnimation(translateX, toValue);\n\n animation.start(({ finished }) => {\n if (finished) {\n finalizeAnimation();\n }\n });\n\n notifyAnimationState('started');\n } else {\n finalizeAnimation();\n }\n }, [\n createScrollAnimation,\n getCurrentIndex,\n finalizeAnimation,\n itemWidth,\n lastIndex,\n loop,\n notifyAnimationState,\n notifyOffsetHasChanged,\n ]);\n\n return {\n interruptAnimation,\n startPagingAnimation,\n };\n};\n"],"mappings":"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"}