/* eslint-disable @typescript-eslint/no-shadow */ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import React, { useCallback, useEffect, useImperativeHandle, useMemo, useState, } from 'react'; import { Dimensions, I18nManager, Text, TouchableOpacity, View, } from 'react-native'; import { scale } from 'react-native-size-scaling'; import { useDeviceOrientation } from '../../../useDeviceOrientation'; import { getPathDown } from '../../utils/pathDown'; import { getPathUp } from '../../utils/pathUp'; import { CurvedViewExpoComponent } from '../CurvedView/curvedViewExpo'; import type { ICurvedBottomBarRef, NavigatorBottomBarProps } from './model'; import { styles } from './styles'; const { width: maxW } = Dimensions.get('window'); const Tab = createBottomTabNavigator(); const BottomBarComponent = React.forwardRef< ICurvedBottomBarRef, NavigatorBottomBarProps >((props, ref) => { const { type = 'DOWN', circlePosition = 'CENTER', style, width = null, height = 65, circleWidth = 50, bgColor = 'gray', initialRouteName, tabBar, renderCircle, borderTopLeftRight = false, shadowStyle, borderColor = 'gray', borderWidth = 0, } = props; const [itemLeft, setItemLeft] = useState([]); const [itemRight, setItemRight] = useState([]); const [maxWidth, setMaxWidth] = useState(width || maxW); const [isShow, setIsShow] = useState(true); const children = props?.children as any[]; const orientation = useDeviceOrientation(); useImperativeHandle(ref, () => { return { setVisible }; }); const setVisible = (visible: boolean) => { setIsShow(visible); }; useEffect(() => { const { width: w } = Dimensions.get('window'); if (!width) { setMaxWidth(w); } }, [orientation, width]); const _renderButtonCenter = useCallback( (focusedTab: string, navigate: any) => { const getTab = children.filter( (e: any) => e?.props?.position === 'CIRCLE' || e?.props?.position === 'CENTER' )[0]?.props?.name; return renderCircle({ routeName: getTab, selectedTab: focusedTab, navigate: (selectTab: string) => { if (selectTab) { navigate(selectTab); } }, }); }, [children, renderCircle] ); useEffect(() => { const arrLeft: any = children.filter( (item) => item?.props?.position === 'LEFT' ); const arrRight: any = children.filter( (item) => item?.props?.position === 'RIGHT' ); setItemLeft(arrLeft); setItemRight(arrRight); }, [children, initialRouteName]); const getCircleWidth = useMemo(() => { return circleWidth < 50 ? 50 : circleWidth > 60 ? 60 : circleWidth; }, [circleWidth]); const getTabbarHeight = useMemo(() => { return height < 50 ? 50 : height > 90 ? 90 : height; }, [height]); const d = useMemo(() => { return type === 'DOWN' ? getPathDown( maxWidth, getTabbarHeight, getCircleWidth, borderTopLeftRight, !I18nManager.isRTL ? circlePosition : circlePosition === 'LEFT' ? 'RIGHT' : circlePosition === 'RIGHT' ? 'LEFT' : 'CENTER' ) : getPathUp( maxWidth, getTabbarHeight + 30, getCircleWidth, borderTopLeftRight, !I18nManager.isRTL ? circlePosition : circlePosition === 'LEFT' ? 'RIGHT' : circlePosition === 'RIGHT' ? 'LEFT' : 'CENTER' ); }, [ borderTopLeftRight, circlePosition, getCircleWidth, getTabbarHeight, maxWidth, type, ]); const renderItem = ({ color, routeName, navigate }: any) => { return ( navigate(routeName)} > {routeName} ); }; const _renderTabIcon = useCallback( (arr: any[], focusedTab: string, navigation: any) => { return ( {arr.map((item: any, index) => { const routeName: string = item?.props?.name; if (tabBar === undefined) { return renderItem({ routeName, color: focusedTab === routeName ? 'blue' : 'gray', navigate: navigation.navigate, }); } return ( {tabBar({ routeName, selectedTab: focusedTab, navigate: (selectTab: string) => { if (selectTab !== focusedTab) { navigation.navigate({ name: routeName, merge: true, }); } }, })} ); })} ); }, [getTabbarHeight, tabBar] ); const renderPosition = useCallback( (props: any) => { const { state, navigation } = props; const focusedTab = state?.routes[state.index].name; if (circlePosition === 'LEFT') { return ( <> {_renderButtonCenter(focusedTab, navigation.navigate)} {_renderTabIcon( [...itemLeft, ...itemRight], focusedTab, navigation )} ); } if (circlePosition === 'RIGHT') { return ( <> {_renderTabIcon( [...itemLeft, ...itemRight], focusedTab, navigation )} {_renderButtonCenter(focusedTab, navigation.navigate)} ); } return ( <> {_renderTabIcon(itemLeft, focusedTab, navigation)} {_renderButtonCenter(focusedTab, navigation.navigate)} {_renderTabIcon(itemRight, focusedTab, navigation)} ); }, [ _renderButtonCenter, _renderTabIcon, circlePosition, getCircleWidth, itemLeft, itemRight, ] ); const _renderTabContainer = useCallback( (props: any) => { return ( {renderPosition(props)} ); }, [maxWidth, renderPosition, type] ); const MyTabBar = useCallback( (props: any) => { if (!isShow) { return null; } return ( {_renderTabContainer(props)} ); }, [ _renderTabContainer, bgColor, d, getTabbarHeight, isShow, maxWidth, shadowStyle, style, type, borderColor, borderWidth, ] ); const main = useMemo(() => { return ( {children?.map((e: any) => { const Component = e?.props?.component; return ( {(props) => } ); })} ); }, [MyTabBar, children, props]); return main; }); export default BottomBarComponent;