react-native-tab-view
Version:
Tab view component for React Native
126 lines (125 loc) • 3.72 kB
JavaScript
import * as React from 'react';
import { Animated, Keyboard, Platform, StyleSheet } from 'react-native';
import ViewPager from 'react-native-pager-view';
import useLatestCallback from 'use-latest-callback';
import { useAnimatedValue } from "./useAnimatedValue.js";
import { jsx as _jsx } from "react/jsx-runtime";
const AnimatedViewPager = Animated.createAnimatedComponent(ViewPager);
const useNativeDriver = Platform.OS !== 'web';
export function PagerViewAdapter({
keyboardDismissMode = 'auto',
swipeEnabled = true,
navigationState,
onIndexChange,
onSwipeStart,
onSwipeEnd,
children,
style,
animationEnabled,
...rest
}) {
const {
index
} = navigationState;
const listenersRef = React.useRef([]);
const pagerRef = React.useRef(null);
const indexRef = React.useRef(index);
const navigationStateRef = React.useRef(navigationState);
const position = useAnimatedValue(index);
const offset = useAnimatedValue(0);
React.useEffect(() => {
navigationStateRef.current = navigationState;
});
const jumpTo = useLatestCallback(key => {
const index = navigationStateRef.current.routes.findIndex(route => route.key === key);
if (animationEnabled) {
pagerRef.current?.setPage(index);
} else {
pagerRef.current?.setPageWithoutAnimation(index);
position.setValue(index);
}
onIndexChange(index);
});
React.useEffect(() => {
if (keyboardDismissMode === 'auto') {
Keyboard.dismiss();
}
if (indexRef.current !== index) {
if (animationEnabled) {
pagerRef.current?.setPage(index);
} else {
pagerRef.current?.setPageWithoutAnimation(index);
position.setValue(index);
}
}
}, [keyboardDismissMode, index, animationEnabled, position]);
const onPageScrollStateChanged = state => {
const {
pageScrollState
} = state.nativeEvent;
switch (pageScrollState) {
case 'idle':
onSwipeEnd?.();
return;
case 'dragging':
{
const subscription = offset.addListener(({
value
}) => {
const next = index + (value > 0 ? Math.ceil(value) : Math.floor(value));
if (next !== index) {
listenersRef.current.forEach(listener => listener(next));
}
offset.removeListener(subscription);
});
onSwipeStart?.();
return;
}
}
};
const addEnterListener = useLatestCallback(listener => {
listenersRef.current.push(listener);
return () => {
const index = listenersRef.current.indexOf(listener);
if (index > -1) {
listenersRef.current.splice(index, 1);
}
};
});
const memoizedPosition = React.useMemo(() => Animated.add(position, offset), [offset, position]);
return children({
position: memoizedPosition,
addEnterListener,
jumpTo,
render: children => /*#__PURE__*/_jsx(AnimatedViewPager, {
...rest,
ref: pagerRef,
style: [styles.container, style],
initialPage: index,
keyboardDismissMode: keyboardDismissMode === 'auto' ? 'on-drag' : keyboardDismissMode,
onPageScroll: Animated.event([{
nativeEvent: {
position: position,
offset: offset
}
}], {
useNativeDriver
}),
onPageSelected: e => {
const index = e.nativeEvent.position;
indexRef.current = index;
onIndexChange(index);
},
onPageScrollStateChanged: onPageScrollStateChanged,
scrollEnabled: swipeEnabled,
children: children
})
});
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
//# sourceMappingURL=PagerViewAdapter.js.map
;