@uiw/react-native
Version:
UIW for React Native
83 lines (82 loc) • 2.84 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';
import { useTheme } from '@shopify/restyle';
const TooltipContainer = ({ content, children }) => {
return content ? <Tooltip title={content}>{children}</Tooltip> : <React.Fragment>{children}</React.Fragment>;
};
export default (props) => {
const theme = useTheme();
const styles = createStyles({
textColor: theme.colors.primary_text || '#ccc',
});
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({});
function createStyles({ textColor }) {
return StyleSheet.create({
container: {
backgroundColor: 'transparent',
textAlign: 'left',
},
centered: {
textAlign: 'center',
},
uppercase: {
textTransform: 'uppercase',
},
highlight: {
color: textColor,
fontSize: 14,
},
notHighlight: {
color: undefined,
},
});
}