@uiw/react-native
Version:
UIW for React Native
122 lines (121 loc) • 3.84 kB
JavaScript
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { View, StyleSheet, Text, TouchableOpacity, Animated } from 'react-native';
import Icon from '../Icon';
function TabsItem(props) {
const { activeColor, icon, index, value, onChange, defaultColor } = props;
const opacity = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (value === index) {
Animated.timing(opacity, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}).start();
}
else {
Animated.timing(opacity, {
toValue: 0,
duration: 500,
useNativeDriver: true,
}).start();
}
}, [value]);
const style = useCallback(() => {
const { style = {} } = props;
const titleBoxStyle = {
width: style.width ?? 100,
};
const titleStyle = {
fontSize: style.titleSize ?? 20,
color: index === value && activeColor ? activeColor : defaultColor,
fontWeight: style.titleFontWeight ?? '600',
};
const iconBoxStyle = {
width: style.width ?? 100,
};
const iconStyle = {
color: index === value && activeColor ? activeColor : defaultColor,
size: style.iconSize ?? 24,
};
const borderColor = {
width: style.borderWidth ?? 40,
borderBottomWidth: style.borderHeight ?? 4,
borderBottomColor: index === value && activeColor ? activeColor : defaultColor,
bottom: 0,
};
return {
titleBoxStyle,
titleStyle,
iconBoxStyle,
iconStyle,
borderColor,
};
}, [value, activeColor]);
const IconDom = useMemo(() => {
const isIconDom = () => {
if (typeof icon === 'string') {
return <Icon name={icon} color={style().iconStyle.color} size={style().iconStyle.size}/>;
}
else {
return <React.Fragment>{icon}</React.Fragment>;
}
};
if (icon) {
return <View style={[styles.iconBox, { ...style().iconBoxStyle }]}>{isIconDom()}</View>;
}
return null;
}, [icon, props.style, value, activeColor]);
const BorderDom = useMemo(() => {
if (value === index) {
return (<View style={styles.bottomView}>
<Animated.View style={[
styles.bottom,
{
...style().borderColor,
opacity,
},
]}/>
</View>);
}
return null;
}, [value]);
return (<View>
<View style={styles.TabsItemContainer}>
<TouchableOpacity onPress={() => (index === 0 || index) && onChange?.(index)}>
<Animated.View style={[styles.titleBox, { ...style().titleBoxStyle }]}>
{IconDom}
<Text style={[styles.title, { ...style().titleStyle }]}>{props.title}</Text>
</Animated.View>
{BorderDom}
</TouchableOpacity>
</View>
</View>);
}
TabsItem.prototype.isclxItem = {};
const styles = StyleSheet.create({
TabsItemContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
iconBox: {
flexDirection: 'row',
justifyContent: 'center',
},
titleBox: {
paddingTop: 10,
paddingBottom: 10,
},
title: {
textAlign: 'center',
},
bottomView: {
flexDirection: 'row',
justifyContent: 'center',
},
bottom: {
position: 'absolute',
borderStyle: 'solid',
},
});
export default TabsItem;