SectionTabBar.js 3.83 KB
import React from 'react';
import ReactNative from 'react-native';
import PropTypes from 'prop-types';

const {
    StyleSheet,
    Text,
    View,
    Animated,
    TouchableOpacity,
    Dimensions,
    ViewPropTypes
} = ReactNative;

export default class SectionTabBar extends React.Component {
    static propTypes = {
        containerWidth: PropTypes.number,
        goToPage: PropTypes.func,
        activeTab: PropTypes.number,
        tabs: PropTypes.array,
        underlineColor: PropTypes.string,
        underlineHeight: PropTypes.number,
        backgroundColor: PropTypes.string,
        activeTextColor: PropTypes.string,
        inactiveTextColor: PropTypes.string,
        textStyle: Text.propTypes.style,
        tabStyle: ViewPropTypes.style,
    };

    static defaultProps = {
        containerWidth: Dimensions.get('window').width,
        activeTab: 0,
        activeTextColor: 'black',
        inactiveTextColor: '#b0b0b0',
        underlineColor: 'black',
        backgroundColor: 'white',
        underlineHeight: 1.5,
    };

    constructor(props) {
        super(props);

        let activeTab = this.props.activeTab ? this.props.activeTab : 0;
        this.state = {
            activeTab: activeTab,
        };

        this.setAnimationValue = this.setAnimationValue.bind(this);
    }

    componentDidMount() {
        this._listener = this.props.scrollValue.addListener(this.setAnimationValue);
    }

    componentWillUnmount() {
        this.props.scrollValue.removeListener(this._listener);
    }

    setAnimationValue({ value, }) {
        let num = value % 1
        if (num == 0) {
            this.setState({
                activeTab: value,
            });
        }
    }

    renderTabOption(name, page) {
        const isTabActive = this.state.activeTab === page;
        const { activeTextColor, inactiveTextColor, textStyle, } = this.props;
        const textColor = isTabActive ? activeTextColor : inactiveTextColor;
        const fontWeight = isTabActive ? 'bold' : 'normal';

        return (
            <TouchableOpacity
                key={name}
                style={styles.tab}
                onPress={() => {
                    this.props.goToPage(page);
                    this.setState({
                        activeTab: page
                    });
                }}
            >
                <Text style={[{color: textColor, fontWeight, fontSize: 14}, textStyle, ]}>
                    {name}
                </Text>
            </TouchableOpacity>
        );
    }

    render() {
        const containerWidth = this.props.containerWidth;
        const numberOfTabs = this.props.tabs.length;
        const tabUnderlineStyle = {
            position: 'absolute',
            width: containerWidth / numberOfTabs,
            height: this.props.underlineHeight,
            backgroundColor: 'white',
            bottom: 3.5,
            alignItems: 'center',
        };
        const innerLineStyle = {
            width: 100,
            height: this.props.underlineHeight,
            backgroundColor: this.props.underlineColor,
        };

        const left = this.props.scrollValue.interpolate({
            inputRange: [0, 1, ], outputRange: [0,  containerWidth / numberOfTabs, ],
        });

        return (
            <View style={[styles.tabs, {backgroundColor: this.props.backgroundColor, }, this.props.style, ]}>
                {this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))}
                <Animated.View style={[tabUnderlineStyle, {left}]} >
                    <View style={innerLineStyle}/>
                </Animated.View>
            </View>
        );
    }
}

let styles = StyleSheet.create({
    tabs: {
        height: 41,
        flexDirection: 'row',
        justifyContent: 'space-around',
    },
    tab: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
});