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

Commit

Permalink
feat: add animationEnabled to TabView (#1388)
Browse files Browse the repository at this point in the history
* 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 <szymon.rybczak@gmail.com>
  • Loading branch information
szymonrybczak committed Sep 30, 2022
1 parent 20b5062 commit 9a12301
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 26 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ String indicating whether the keyboard gets dismissed in response to a drag gest

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.

#### `animationEnabled`

Enables animation when changing tab. By default it's true.

##### `onSwipeStart`

Callback which is called when the swipe gesture starts, i.e. the user touches the screen and moves it.
Expand Down
32 changes: 23 additions & 9 deletions src/PagerViewAdapter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function PagerViewAdapter<T extends Route>({
onSwipeEnd,
children,
style,
animationEnabled,
...rest
}: Props<T>) {
const { index } = navigationState;
Expand All @@ -58,23 +59,36 @@ export default function PagerViewAdapter<T extends Route>({
navigationStateRef.current = navigationState;
});

const jumpTo = React.useCallback((key: string) => {
const index = navigationStateRef.current.routes.findIndex(
(route: { key: string }) => route.key === key
);

pagerRef.current?.setPage(index);
}, []);
const jumpTo = React.useCallback(
(key: string) => {
const index = navigationStateRef.current.routes.findIndex(
(route: { key: string }) => route.key === key
);

if (animationEnabled) {
pagerRef.current?.setPage(index);
} else {
pagerRef.current?.setPageWithoutAnimation(index);
position.setValue(index);
}
},
[animationEnabled, position]
);

React.useEffect(() => {
if (keyboardDismissMode === 'auto') {
Keyboard.dismiss();
}

if (indexRef.current !== index) {
pagerRef.current?.setPage(index);
if (animationEnabled) {
pagerRef.current?.setPage(index);
} else {
pagerRef.current?.setPageWithoutAnimation(index);
position.setValue(index);
}
}
}, [keyboardDismissMode, index]);
}, [keyboardDismissMode, index, animationEnabled, position]);

const onPageScrollStateChanged = (
state: PageScrollStateChangedNativeEvent
Expand Down
40 changes: 23 additions & 17 deletions src/PanResponderAdapter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default function PanResponderAdapter<T extends Route>({
onSwipeEnd,
children,
style,
animationEnabled = false,
}: Props<T>) {
const { routes, index } = navigationState;

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

const jumpToIndex = React.useCallback(
(index: number) => {
(index: number, animate = animationEnabled) => {
const offset = -index * layoutRef.current.width;

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

Animated.parallel([
timing(panX, {
...transitionConfig,
toValue: offset,
useNativeDriver: false,
}),
]).start(({ finished }) => {
if (finished) {
onIndexChangeRef.current(index);
pendingIndexRef.current = undefined;
}
});

pendingIndexRef.current = index;
if (animate) {
Animated.parallel([
timing(panX, {
...transitionConfig,
toValue: offset,
useNativeDriver: false,
}),
]).start(({ finished }) => {
if (finished) {
onIndexChangeRef.current(index);
pendingIndexRef.current = undefined;
}
});
pendingIndexRef.current = index;
} else {
panX.setValue(offset);
onIndexChangeRef.current(index);
pendingIndexRef.current = undefined;
}
},
[panX]
[animationEnabled, panX]
);

React.useEffect(() => {
Expand Down Expand Up @@ -230,7 +236,7 @@ export default function PanResponderAdapter<T extends Route>({
nextIndex = currentIndex;
}

jumpToIndex(nextIndex);
jumpToIndex(nextIndex, true);
};

// TODO: use the listeners
Expand Down
2 changes: 2 additions & 0 deletions src/TabView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default function TabView<T extends Route>({
style,
swipeEnabled = true,
tabBarPosition = 'top',
animationEnabled = true,
}: Props<T>) {
const [layout, setLayout] = React.useState({
width: 0,
Expand Down Expand Up @@ -86,6 +87,7 @@ export default function TabView<T extends Route>({
onSwipeStart={onSwipeStart}
onSwipeEnd={onSwipeEnd}
onIndexChange={jumpToIndex}
animationEnabled={animationEnabled}
style={pagerStyle}
>
{({ position, render, addEnterListener, jumpTo }) => {
Expand Down
1 change: 1 addition & 0 deletions src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export type PagerProps = Omit<
> & {
keyboardDismissMode?: 'none' | 'on-drag' | 'auto';
swipeEnabled?: boolean;
animationEnabled?: boolean;
onSwipeStart?: () => void;
onSwipeEnd?: () => void;
};

0 comments on commit 9a12301

Please sign in to comment.