Anshul Kai
Anshul Kai

Reputation: 4088

React-Native: Avoid Text Wrapping

I have the title of a song and its duration showing in one line. The song title needs to show an ellipsis but the duration should never wrap or show ellipsis. I've tried several combinations but fail to make this work right for long titles. The duration either goes off screen when the name shows ellipsis or the duration wraps. I can't hardcode a fixed width on the duration as it can change size.

<View style={{flexDirection: 'row'}}>
    <Text numberOfLines={2} style={{fontSize: 16, textAlign: 'left'}}>{title}</Text>
    <Text style={{flex: 1, fontSize: 13, textAlign: 'right', marginTop: 2}}>{duration}</Text>
</View>

Upvotes: 44

Views: 61915

Answers (3)

Nor.Z
Nor.Z

Reputation: 1349

try <ScrollView horizontal={true}>.
the text will not wrap until you manually linebreak it;
& you can scroll horizontally.

export default function App() {
  return (
    <View>
      <ScrollView horizontal={true}>
        <Text>{`
Lorem ipsum dolor sit amet, 
consectetur adipiscing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 

Ut enim ad minim veniam, 
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 

Excepteur sint occaecat cupidatat non proident, 
sunt in culpa qui officia deserunt mollit anim id est laborum.
`}</Text>
      </ScrollView>
    </View>
  );
}

update

a better design -- contentContainerStyle={{ flexGrow: 1 }} that fixes the buggy <ScrollView> horizonal scrolling --

  • if the <Text> width doesnt overflow the <ScrollView> width, it can still be scrolled - the <Text> jumps from left to right.
  • if the <Text> width does overflow the <ScrollView> width, it can still be scrolled (over-scroll) with a tiny little bit offset from left
export const MonoText: React.FC<TextProps> = (props) => {
  const style = {
    ...({ fontFamily: 'monospace' } as TextStyle),
    ...(props.style as TextStyle),
  };

  return (
    <>
      <ScrollView horizontal={true} contentContainerStyle={{ flexGrow: 1 }}>
        <Text {...props} style={style} />
      </ScrollView>
    </>
  );
};

Upvotes: 0

Durgaprasad Budhwani
Durgaprasad Budhwani

Reputation: 977

Possibly below solution should satify your creteria

 return (
        <View style={{flexDirection: 'row', flex: 1, justifyContent: 'space-around', marginTop: 50}}>
            <Text numberOfLines={2} style={{fontSize: 16, flex: 1}}>{title}</Text>
            <Text style={{fontSize: 13, marginTop: 2}}>{duration}</Text>
        </View>
    );

Please check and let me know if does not work.

Upvotes: 5

Anshul Kai
Anshul Kai

Reputation: 4088

The solution ended up being fairly simple. Not entirely intuitive but here's how to solve this. It appears that the text that needs ellipsis requires flex: 1.

 <View style={{ flexDirection: "row" }}>
<Text numberOfLines={1} style={{ flex: 1, textAlign: "left" }}>
    {title}
</Text>
<Text style={{ textAlign: "right" }}>{duration}</Text>
</View>;

Upvotes: 83

Related Questions