How to have Ellipsis effect on Text
Asked Answered
C

10

306

I'm having a long text in my app and I need to truncate it and add three dots to the end.

How can I do that in React Native Text element?

Thanks

Concertante answered 2/6, 2015 at 10:55 Comment(3)
You've been given the perfect answer. Maybe you should accept it?Pandemic
The fact there is so many up votes , shows there should probably be a component for this or a prop at least.Cana
@Cana there is: <Text> and numberOfLinesWaggoner
D
108

use numberOfLines

<Text numberOfLines={1}>long long long long text<Text>

or if you know/or can compute the max character count per row, JS substring may be used.

<Text>{ ((mytextvar).length > maxlimit) ? 
    (((mytextvar).substring(0,maxlimit-3)) + '...') : 
    mytextvar }
</Text>
Darrendarrey answered 3/6, 2015 at 6:52 Comment(6)
That's not a solution. Text is variable width.Cymbiform
As long as the container of the Text element has a Flex value (I use, 1), the text will be truncated within the container. So @Rahul Chaudhari's answer is the way to do it.Tourneur
numberOfLines={1}Cavill
The link provided is broken and the solution should be to use react-native's built in support for this which is explained in other answers.Cockalorum
Is there any styling for the <Text> for handling the long text? As i am facing that issue for <ListItemText> in material ui and i am not able to find any answer for thatOutwork
I'm having issues with numberOfLines when there is a linebreak. I want there to be an ellipses, but there is not. So it looks like that is all the text, but really, there is a line break and more lines to follow.Sanative
R
775

Use the numberOfLines parameter on a Text component:

<Text numberOfLines={1}>long long long long text<Text>

Will produce:

long long long…

(Assuming you have short width container.)


Use the ellipsizeMode parameter to move the ellipsis to the head or middle. tail is the default value.

<Text numberOfLines={1} ellipsizeMode='head'>long long long long text<Text>

Will produce:

…long long text

NOTE: The Text component should also include style={{ flex: 1 }} when the ellipsis needs to be applied relative to the size of its container. Useful for row layouts, etc.

Rectrix answered 15/3, 2016 at 14:14 Comment(7)
Maybe obvious maybe not, need to specify width on the Text as well.Lajoie
The interesting question is: how do you compute the number of lines? Because I guess nobody ever knows it in advance (since it has no reason to be static).Cullet
Nice answer, but if want the same behavior like css ellipses, need use ellipsizeMode='tail'.Transcendentalistic
@RanYefet you should consider marking this answer as the correct one, it would help others, thanks!Bowe
@Goutham The closest you will get is ellipsizeMode set to middle I think.Prevail
I add my answer too, but this answer is better. thank youIronlike
style={{ flexShrink: 1 }} can be used instead of flex: 1 if you don't want the element to grow in a row layoutCann
D
108

use numberOfLines

<Text numberOfLines={1}>long long long long text<Text>

or if you know/or can compute the max character count per row, JS substring may be used.

<Text>{ ((mytextvar).length > maxlimit) ? 
    (((mytextvar).substring(0,maxlimit-3)) + '...') : 
    mytextvar }
</Text>
Darrendarrey answered 3/6, 2015 at 6:52 Comment(6)
That's not a solution. Text is variable width.Cymbiform
As long as the container of the Text element has a Flex value (I use, 1), the text will be truncated within the container. So @Rahul Chaudhari's answer is the way to do it.Tourneur
numberOfLines={1}Cavill
The link provided is broken and the solution should be to use react-native's built in support for this which is explained in other answers.Cockalorum
Is there any styling for the <Text> for handling the long text? As i am facing that issue for <ListItemText> in material ui and i am not able to find any answer for thatOutwork
I'm having issues with numberOfLines when there is a linebreak. I want there to be an ellipses, but there is not. So it looks like that is all the text, but really, there is a line break and more lines to follow.Sanative
H
88

You can use ellipsizeMode and numberOfLines. e.g

<Text ellipsizeMode='tail' numberOfLines={2}>
  This very long text should be truncated with dots in the beginning.
</Text>

https://facebook.github.io/react-native/docs/text.html

Hectograph answered 30/3, 2017 at 7:4 Comment(2)
As long as the container of the Text element has a Flex value (I use, 1), the text will be truncated within the container.Tourneur
ellipsizeMode='tail' is not needed as 'tail' is default value for ellipsizeMode. Unless you want to show ellipse in beginning of the text, you can use just numberOfLines prop and it should work.Recoup
S
34
<Text ellipsizeMode='tail' numberOfLines={2} style={{width:100}}>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at cursus 
</Text>

Result inside box:


<-- width = 100-->
 -----------------
| Lorem ipsum     |
| dolar sit a...  |
 -----------------
Stratovision answered 22/5, 2020 at 5:6 Comment(0)
I
18
<View 
   style={{
        flexDirection: 'row',
        padding: 10,
    }}
>
  <Text numberOfLines={5} style={{flex:1}}>
       This is a very long text that will overflow on a small device This is a very 
       long text that will overflow on a small deviceThis is a very long text that 
       will overflow on a small deviceThis is a very long text that will overflow 
       on a small device
  </Text>
</View>
Ironlike answered 26/6, 2019 at 12:4 Comment(0)
P
4

To Achieve ellipses for the text use the Text property numberofLines={1} which will automatically truncate the text with an ellipsis you can specify the ellipsizeMode as "head", "middle", "tail" or "clip" By default it is tail

https://reactnative.dev/docs/text#ellipsizemode

Pathless answered 13/9, 2020 at 5:58 Comment(0)
D
2

If you want read more behavior, then you can use the react-native-read-more-text library:

npm i react-native-read-more-text --save

<ReadMore
  numberOfLines={1}
  renderTruncatedFooter={(handlePress) => { return <Text onPress={handlePress} style={{ color: 'grey' }}>show more</Text> }}
  renderRevealedFooter={(handlePress) => { return <Text onPress={handlePress} style={{ color: 'grey' }}>show less</Text> }}
>
  <Text>yourText</Text>
</ReadMore>

Docs: https://github.com/expo/react-native-read-more-text

To hide "read more" when the content is less than numberOfLines, you can use ternary operator:

{
  'yourText'.length > 50
  ?
  <ReadMore
    numberOfLines={1}
    renderTruncatedFooter={(handlePress) => { return <Text onPress={handlePress} style={{ color: 'grey' }}>show more</Text> }}
    renderRevealedFooter={(handlePress) => { return <Text onPress={handlePress} style={{ color: 'grey' }}>show less</Text> }}
  >
    <Text>yourText</Text>
  </ReadMore>
  :
  <Text>yourText</Text>
}
Diploid answered 8/10, 2021 at 14:2 Comment(0)
M
2
<Text numberOfLines={1}>long long long long text<Text>

exchangeTypeText: { width: "85%", overflow: "hidden",

},

Mullet answered 2/11, 2023 at 12:59 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Supposition
E
0

Here is JSX vertion if some one using simple react ,, not knowing react native though

import { useState } from "react";
    
    function ElipseText({ text, size = 500 }) {
      const [showMore, setShowMore] = useState(true)
      const renderText = (text) => {
        let textJSX = text;
        if (showMore) {
          textJSX = text.substring(0, size);
        }
        return (<span className="elipse-text">
          <p className="text01" dangerouslySetInnerHTML={{ __html: textJSX }} />
          &nbsp;&nbsp;
          <a className="btn01" onClick={() => setShowMore(!showMore)}>
            {!showMore && <svg width="1em" height="1em" viewBox="0 0 512 512"><path fill="currentColor" d="M497.333 239.999H80.092l95.995-95.995l-22.627-22.627L18.837 256L153.46 390.623l22.627-22.627l-95.997-95.997h417.243v-32z"></path></svg>}
            {showMore ? "Show More" : "Show Less"}
            {showMore && <svg width="1em" height="1em" viewBox="0 0 15 15"><path fill="currentColor" fillRule="evenodd" d="M9.854 3.146L14.207 7.5l-4.353 4.354l-.708-.708L12.293 8H1V7h11.293L9.146 3.854l.708-.708Z" clipRule="evenodd"></path></svg>}
          </a>
        </span>)
      }
    
      return (
        <>
          {renderText(text)}
        </>
      )
    }
    
    export default ElipseText

SCSS File

.elipse-text {
  .btn01 {
    display: inline-flex;
    color: var(--color-dark);
    align-items: center;
    gap: 0.5rem;
    border-bottom: 1px solid var(--color-dark);
  }

  .text01 {
    display: contents;
  }
}
Eve answered 2/6, 2015 at 10:55 Comment(0)
F
-20

const styles = theme => ({
 contentClass:{
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    display: '-webkit-box',
    WebkitLineClamp:1,
    WebkitBoxOrient:'vertical'
 }   
})
render () {
  return(
    <div className={classes.contentClass}>
      {'content'}
    </div>
  )
}
Fossiliferous answered 2/6, 2015 at 10:55 Comment(1)
the question is more about React Native, where textOverflow is not a valid propOddson

© 2022 - 2024 — McMap. All rights reserved.