@uiw/react-native
Version:
UIW for React Native
132 lines • 3.4 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,
children
} = 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;