React native text component using number of lines
This works for me :)
import React, { useState } from 'react'
import { Text } from 'rect-native'
export function MoreLessText({ children, numberOfLines }) {
const [isTruncatedText, setIsTruncatedText] = useState(false)
const [showMore, setShowMore] = useState(true)
return isTruncatedText ? (
<>
<Text numberOfLines={showMore ? numberOfLines : 0}>{children}</Text>
<Text onPress={() => setShowMore(!showMore)}">
{showMore ? 'Read More' : 'Less'}
</Text>
</>
) : (
<Text
onTextLayout={(event) => {
const { lines } = event.nativeEvent
setIsTruncatedText(lines?.length > numberOfLines)
}}
>
{children}
</Text>
)
}
You can use numberOfLines
as a props for <Text />
component. Its depend on the width of your component then calculate the length of the text. This prop is commonly used with ellipsizeMode
.
Example:
<Text numberOfLines={2} ellipsizeMode='tail'>
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</Text>
This is now possible with the onTextLayout
event that includes an array of lines
being rendered out. Simply looking at the length you can determine if you are at the limit. There's other details in the lines
array like actual height and width of every line which can be further used to determine if the text is being truncated.
const NUM_OF_LINES = 5;
const SOME_LONG_TEXT_BLOCK = 'Fill in some long text yourself ...';
return (<Text
numberOfLines={NUM_OF_LINES}
onTextLayout={({ nativeEvent: { lines } }) =>
setState({ showMoreButton: lines.length === NUM_OF_LINES })
}
>
{SOME_LONG_TEXT_BLOCK}
</Text>;