license import React from 'react' ; import { StyleProp , StyleSheet , View , ViewProps , ViewStyle , } from 'react-native' ; import { ChildrenWithProps , Overwrite , LiteralUnion , } from '../../devsupport' ; import { styled , StyledComponentProps , StyleType , } from '../../theme' ; import { BottomNavigationTabElement , BottomNavigationTabProps , } from './bottomNavigationTab.component' ; import { TabIndicator , TabIndicatorElement , } from '../shared/tabIndicator.component' ; type BottomNavigationStyledProps = Overwrite < StyledComponentProps , { appearance ? : LiteralUnion < 'default' | 'noIndicator' > ; } > ; export interface BottomNavigationProps extends ViewProps , BottomNavigationStyledProps { children ? : ChildrenWithProps < BottomNavigationTabProps > ; selectedIndex ? : number ; onSelect ? : ( index : number ) => void ; indicatorStyle ? : StyleProp < ViewStyle > ; } export type BottomNavigationElement = React . ReactElement < BottomNavigationProps > ; extends React . Component property property property property property property overview-example overview-example overview-example overview-example overview-example example @ styled ( 'BottomNavigation' ) export class BottomNavigation extends React . Component < BottomNavigationProps > { static defaultProps : Partial < BottomNavigationProps > = { selectedIndex : 0 , } ; private onTabSelect = ( index ) : void => { this . props . onSelect && this . props . onSelect ( index ) ; } ; private getComponentStyle = ( source ) => { const { indicatorHeight , indicatorBackgroundColor , ... containerParameters } = source ; return { container : containerParameters , indicator : { height : indicatorHeight , backgroundColor : indicatorBackgroundColor , } , } ; } ; private renderIndicatorElement = ( positions , style ) : TabIndicatorElement => { const { indicatorStyle , selectedIndex } = this . props ; return ( < TabIndicator key = { 0 } style = { [ style , styles . indicator , indicatorStyle ] } selectedPosition = { selectedIndex } positions = { positions } / > ) ; } ; private renderTabElement = ( element , index ) : BottomNavigationTabElement => { return React . cloneElement ( element , { key : index , style : [ styles . item , element . props . style ] , selected : index === this . props . selectedIndex , onSelect : ( ) => this . onTabSelect ( index ) , } ) ; } ; private renderTabElements = ( source ) : BottomNavigationTabElement [ ] => { return React . Children . map ( source , this . renderTabElement ) ; } ; private renderComponentChildren = ( style ) : React . ReactNodeArray => { const tabElements = this . renderTabElements ( this . props . children ) ; const hasIndicator = style . indicator . height > 0 ; return [ hasIndicator && this . renderIndicatorElement ( tabElements . length , style . indicator ) , ... tabElements , ] ; } ; public render ( ) { const { eva , style , ... viewProps } = this . props ; const evaStyle = this . getComponentStyle ( eva . style ) ; const [ indicatorElement , ... tabElements ] = this . renderComponentChildren ( evaStyle ) ; return ( < View { ... viewProps } style = { [ evaStyle . container , styles . container , style ] } > { indicatorElement } { tabElements } < /View>); } } const styles = StyleSheet . create ( { container : { flexDirection : 'row' , } , item : { flex : 1 , } , indicator : { position : 'absolute' , } , } ) ;