@boindahood/text-truncate-show-more
Version:
A simple React Native component to truncate long text and toggle between "show more" / "show less".
47 lines (45 loc) • 1.63 kB
JavaScript
import React, { useCallback, useState } from 'react';
import { StyleSheet, Text, View, } from 'react-native';
const TextTruncate = React.memo((props) => {
const { children, style, numberOfLines } = props;
const [textTruncate, setTextTruncate] = useState();
const onTextLayoutClone = useCallback((e) => {
const { lines } = e.nativeEvent;
// dont need to show more
if (!numberOfLines || (lines === null || lines === void 0 ? void 0 : lines.length) <= numberOfLines) {
setTextTruncate(children);
return;
}
// need to show more
let textTruncateWillShow = '';
lines.forEach((line, index) => {
if (index <= numberOfLines - 1) {
textTruncateWillShow += line.text;
}
});
setTextTruncate(textTruncateWillShow === null || textTruncateWillShow === void 0 ? void 0 : textTruncateWillShow.trim());
}, [numberOfLines, children]);
return <>
<Text style={[styles.defaultStyle, style]}>{textTruncate}</Text>
{/* clone raw text, full line */}
<View style={styles.viewClone} pointerEvents='none'>
<Text numberOfLines={numberOfLines ? numberOfLines + 1 : undefined} onTextLayout={onTextLayoutClone} style={[styles.defaultStyle, style]}>
{children}
</Text>
</View>
</>;
});
const styles = StyleSheet.create({
defaultStyle: {
fontSize: 14,
color: 'black',
fontFamily: 'monospace',
},
viewClone: {
position: 'absolute',
top: 0,
left: 0,
opacity: 0,
},
});
export default TextTruncate;