import React, { useCallback, useImperativeHandle, useState, useRef, } from "react"; import { LayoutChangeEvent, StyleSheet, View } from "react-native"; import { NavigationState, SceneRendererProps, TabBar, TabView, TabViewProps, } from "react-native-tab-view"; import { HeaderTabContext } from "./context"; import { useSceneInfo } from "./hooks"; import type { CollapsibleHeaderProps, Route, TabViewCustomRenders, } from "./types"; export { TabFlatList, TabScrollView, TabSectionList, TabScrollViewProps, TabFlatListProps, TabSectionListProps, } from "./scrollable-view"; export type HeaderTabViewRef = {}; export type HeaderTabViewProps = Partial> & Pick, "onIndexChange" | "navigationState" | "renderScene"> & CollapsibleHeaderProps; export function createCollapsibleTabsComponent() { return React.forwardRef(CollapsibleHeaderTabView); } function CollapsibleHeaderTabView( { renderTabBar: renderTabBarProp, renderScrollHeader, initTabbarHeight = 44, minHeaderHeight = 0, navigationState, emptyBodyComponent, renderScene, renderSceneHeader: renderSceneHeaderProp, ...restProps }: HeaderTabViewProps, ref?: any ) { const shareAnimatedValue = { value: 0 }; const headerTrans = { value: 0 }; const curIndexValue = { value: 0 }; const isSlidingHeader = { value: false }; const isStartRefreshing = { value: false }; // layout const [tabbarHeight, setTabbarHeight] = useState(initTabbarHeight); const containeRef = useRef(null); useImperativeHandle(ref, () => ({}), []); const tabbarOnLayout = useCallback( ({ nativeEvent: { layout: { height }, }, }: LayoutChangeEvent) => { if (Math.abs(tabbarHeight - height) < 1) return; setTabbarHeight(height); }, [tabbarHeight] ); const renderTabBar = useCallback( ( tabbarProps: SceneRendererProps & { navigationState: NavigationState; } ) => { return renderTabBarProp ? ( renderTabBarProp(tabbarProps) ) : ( ); }, [renderTabBarProp] ); const renderTabView = (e: TabViewCustomRenders) => { return ( ; } ) => e.renderTabBarContainer(renderTabBar(tabbarProps))} renderScene={(props: any) => e.renderSceneHeader(renderScene(props), props) } /> ); }; const renderTabBarContainer = (children: React.ReactElement) => { return ( {children} ); }; const renderSceneHeader = ( children: React.ReactElement, props: SceneRendererProps & { route: T } ) => { return ( {renderSceneHeaderProp?.(props.route)} {children} ); }; // @ts-ignore const { updateSceneInfo } = useSceneInfo(curIndexValue); return ( false, // @ts-ignore curIndexValue, minHeaderHeight, updateSceneInfo, // @ts-ignore isSlidingHeader, // @ts-ignore isStartRefreshing, scrollStickyHeaderHeight: 0, scrollViewPaddingTop: 0, }} > {renderScrollHeader && renderScrollHeader()} {navigationState.routes.length === 0 && emptyBodyComponent ? ( {emptyBodyComponent} ) : ( renderTabView({ renderTabBarContainer: renderTabBarContainer, renderSceneHeader: renderSceneHeader, }) )} ); } const styles = StyleSheet.create({ full: { flex: 1, }, tabbarStyle: { zIndex: 1, }, });