import * as React from 'react'; import { LayoutChangeEvent, StyleProp, StyleSheet, View, ViewStyle, } from 'react-native'; import { Pager } from './Pager'; import { SceneView } from './SceneView'; import { TabBar } from './TabBar'; import type { Layout, NavigationState, PagerProps, Route, SceneRendererProps, } from './types'; export type Props = PagerProps & { onIndexChange: (index: number) => void; navigationState: NavigationState; renderScene: (props: SceneRendererProps & { route: T }) => React.ReactNode; renderLazyPlaceholder?: (props: { route: T }) => React.ReactNode; renderTabBar?: ( props: SceneRendererProps & { navigationState: NavigationState } ) => React.ReactNode; tabBarPosition?: 'top' | 'bottom'; initialLayout?: Partial; lazy?: ((props: { route: T }) => boolean) | boolean; lazyPreloadDistance?: number; sceneContainerStyle?: StyleProp; pagerStyle?: StyleProp; style?: StyleProp; }; export function TabView({ onIndexChange, navigationState, renderScene, initialLayout, keyboardDismissMode = 'auto', lazy = false, lazyPreloadDistance = 0, onSwipeStart, onSwipeEnd, renderLazyPlaceholder = () => null, renderTabBar = (props) => , sceneContainerStyle, pagerStyle, style, swipeEnabled = true, tabBarPosition = 'top', animationEnabled = true, overScrollMode, }: Props) { const [layout, setLayout] = React.useState({ width: 0, height: 0, ...initialLayout, }); const jumpToIndex = (index: number) => { if (index !== navigationState.index) { onIndexChange(index); } }; const handleLayout = (e: LayoutChangeEvent) => { const { height, width } = e.nativeEvent.layout; setLayout((prevLayout) => { if (prevLayout.width === width && prevLayout.height === height) { return prevLayout; } return { height, width }; }); }; return ( {({ position, render, addEnterListener, jumpTo }) => { // All of the props here must not change between re-renders // This is crucial to optimizing the routes with PureComponent const sceneRendererProps = { position, layout, jumpTo, }; return ( {tabBarPosition === 'top' && renderTabBar({ ...sceneRendererProps, navigationState, })} {render( navigationState.routes.map((route, i) => { return ( {({ loading }) => loading ? renderLazyPlaceholder({ route }) : renderScene({ ...sceneRendererProps, route, }) } ); }) )} {tabBarPosition === 'bottom' && renderTabBar({ ...sceneRendererProps, navigationState, })} ); }} ); } const styles = StyleSheet.create({ pager: { flex: 1, overflow: 'hidden', }, });