Skip to content
This repository was archived by the owner on Nov 27, 2022. It is now read-only.

Commit 9a12301

Browse files
feat: add animationEnabled to TabView (#1388)
* feat: add disableChangeTabAnimation to TabView * refactor: change prop name * fix: update dependencies array * feat: add animationEnabled on web * feat: expose the style prop accepted by the Pager component (#1260) * fix: animation when swiping on web * fix: reset pendingIndexRef & remove unncecessary checks Co-authored-by: Szymon Rybczak <[email protected]>
1 parent 20b5062 commit 9a12301

File tree

5 files changed

+53
-26
lines changed

5 files changed

+53
-26
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ String indicating whether the keyboard gets dismissed in response to a drag gest
308308

309309
Boolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing `false` will disable swipe gestures, but the user can still switch tabs by pressing the tab bar.
310310

311+
#### `animationEnabled`
312+
313+
Enables animation when changing tab. By default it's true.
314+
311315
##### `onSwipeStart`
312316

313317
Callback which is called when the swipe gesture starts, i.e. the user touches the screen and moves it.

src/PagerViewAdapter.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default function PagerViewAdapter<T extends Route>({
4141
onSwipeEnd,
4242
children,
4343
style,
44+
animationEnabled,
4445
...rest
4546
}: Props<T>) {
4647
const { index } = navigationState;
@@ -58,23 +59,36 @@ export default function PagerViewAdapter<T extends Route>({
5859
navigationStateRef.current = navigationState;
5960
});
6061

61-
const jumpTo = React.useCallback((key: string) => {
62-
const index = navigationStateRef.current.routes.findIndex(
63-
(route: { key: string }) => route.key === key
64-
);
65-
66-
pagerRef.current?.setPage(index);
67-
}, []);
62+
const jumpTo = React.useCallback(
63+
(key: string) => {
64+
const index = navigationStateRef.current.routes.findIndex(
65+
(route: { key: string }) => route.key === key
66+
);
67+
68+
if (animationEnabled) {
69+
pagerRef.current?.setPage(index);
70+
} else {
71+
pagerRef.current?.setPageWithoutAnimation(index);
72+
position.setValue(index);
73+
}
74+
},
75+
[animationEnabled, position]
76+
);
6877

6978
React.useEffect(() => {
7079
if (keyboardDismissMode === 'auto') {
7180
Keyboard.dismiss();
7281
}
7382

7483
if (indexRef.current !== index) {
75-
pagerRef.current?.setPage(index);
84+
if (animationEnabled) {
85+
pagerRef.current?.setPage(index);
86+
} else {
87+
pagerRef.current?.setPageWithoutAnimation(index);
88+
position.setValue(index);
89+
}
7690
}
77-
}, [keyboardDismissMode, index]);
91+
}, [keyboardDismissMode, index, animationEnabled, position]);
7892

7993
const onPageScrollStateChanged = (
8094
state: PageScrollStateChangedNativeEvent

src/PanResponderAdapter.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export default function PanResponderAdapter<T extends Route>({
5858
onSwipeEnd,
5959
children,
6060
style,
61+
animationEnabled = false,
6162
}: Props<T>) {
6263
const { routes, index } = navigationState;
6364

@@ -76,27 +77,32 @@ export default function PanResponderAdapter<T extends Route>({
7677
const swipeDistanceThreshold = layout.width / 1.75;
7778

7879
const jumpToIndex = React.useCallback(
79-
(index: number) => {
80+
(index: number, animate = animationEnabled) => {
8081
const offset = -index * layoutRef.current.width;
8182

8283
const { timing, ...transitionConfig } = DefaultTransitionSpec;
8384

84-
Animated.parallel([
85-
timing(panX, {
86-
...transitionConfig,
87-
toValue: offset,
88-
useNativeDriver: false,
89-
}),
90-
]).start(({ finished }) => {
91-
if (finished) {
92-
onIndexChangeRef.current(index);
93-
pendingIndexRef.current = undefined;
94-
}
95-
});
96-
97-
pendingIndexRef.current = index;
85+
if (animate) {
86+
Animated.parallel([
87+
timing(panX, {
88+
...transitionConfig,
89+
toValue: offset,
90+
useNativeDriver: false,
91+
}),
92+
]).start(({ finished }) => {
93+
if (finished) {
94+
onIndexChangeRef.current(index);
95+
pendingIndexRef.current = undefined;
96+
}
97+
});
98+
pendingIndexRef.current = index;
99+
} else {
100+
panX.setValue(offset);
101+
onIndexChangeRef.current(index);
102+
pendingIndexRef.current = undefined;
103+
}
98104
},
99-
[panX]
105+
[animationEnabled, panX]
100106
);
101107

102108
React.useEffect(() => {
@@ -230,7 +236,7 @@ export default function PanResponderAdapter<T extends Route>({
230236
nextIndex = currentIndex;
231237
}
232238

233-
jumpToIndex(nextIndex);
239+
jumpToIndex(nextIndex, true);
234240
};
235241

236242
// TODO: use the listeners

src/TabView.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export default function TabView<T extends Route>({
5151
style,
5252
swipeEnabled = true,
5353
tabBarPosition = 'top',
54+
animationEnabled = true,
5455
}: Props<T>) {
5556
const [layout, setLayout] = React.useState({
5657
width: 0,
@@ -86,6 +87,7 @@ export default function TabView<T extends Route>({
8687
onSwipeStart={onSwipeStart}
8788
onSwipeEnd={onSwipeEnd}
8889
onIndexChange={jumpToIndex}
90+
animationEnabled={animationEnabled}
8991
style={pagerStyle}
9092
>
9193
{({ position, render, addEnterListener, jumpTo }) => {

src/types.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export type PagerProps = Omit<
5353
> & {
5454
keyboardDismissMode?: 'none' | 'on-drag' | 'auto';
5555
swipeEnabled?: boolean;
56+
animationEnabled?: boolean;
5657
onSwipeStart?: () => void;
5758
onSwipeEnd?: () => void;
5859
};

0 commit comments

Comments
 (0)