@uiw/react-native
Version:
UIW for React Native
91 lines (90 loc) • 2.34 kB
JavaScript
import React from 'react';
import { Text as RNText, StyleSheet, Animated } from 'react-native';
import _ from 'lodash';
import Tooltip from '../Tooltip';
import { rnTextType, getTextPartsByHighlight, sliceText } from '../utils/rn-text';
const TooltipContainer = ({
content,
children
}) => {
return content ? <Tooltip title={content}>{children}</Tooltip> : <React.Fragment>{children}</React.Fragment>;
};
export default (props => {
const {
type,
color,
center,
uppercase,
animated,
backgroundColor,
style,
children,
label,
highlightText,
highlightTextStyle,
tooltipProps = {
number: 0,
content: ''
},
...others
} = props;
const {
number,
content
} = tooltipProps;
const TextContainer = animated ? Animated.createAnimatedComponent(RNText) : RNText;
/**
* 文本渲染
* @param children
* @returns
*/
const renderText = children => {
// 递归渲染子级的Text
if (!_.isEmpty(highlightText)) {
if (_.isArray(children)) {
return children.map(child => renderText(child));
}
if (_.isString(children)) {
const textParts = getTextPartsByHighlight(children, highlightText);
return textParts.map((text, index) => {
const shouldHighlight = _.lowerCase(text) === _.lowerCase(highlightText);
return <RNText key={index} style={shouldHighlight ? [styles.highlight, highlightTextStyle] : styles.notHighlight}>
{text}
</RNText>;
});
}
}
return children;
};
const textStyle = [{
...rnTextType(type)
}, styles.container, color && {
color
}, backgroundColor && {
backgroundColor
}, center && styles.centered, uppercase && styles.uppercase, style];
return <TooltipContainer content={content}>
<TextContainer {...others} style={textStyle}>
{number ? sliceText(renderText(label || children), number) : renderText(label || children)}
</TextContainer>
</TooltipContainer>;
});
const styles = StyleSheet.create({
container: {
backgroundColor: 'transparent',
textAlign: 'left'
},
centered: {
textAlign: 'center'
},
uppercase: {
textTransform: 'uppercase'
},
highlight: {
color: '#333333',
fontSize: 14
},
notHighlight: {
color: undefined
}
});