15

I'm trying to build a layout in React-Native using Flexbox and I'm having trouble when the text is long. I want the layout to look like this:

Desired Layout

However, when the blue text gets long, it pushes the date off of the right side of the screen like this:

enter image description here

I'm intentionally making the text stay on 1 line. What I want is for the blue text to expand as much as possible without making the text shrink. I'm new to RN and my work with CSS is very limited so I don't have much experience doing things like this. Here is my stylesheet code:

const styles = StyleSheet.create({
  textContainer: {
    flex: 1
  },
  separator: {
    height: 1,
    backgroundColor: '#dddddd'
  },
  title: {
    fontSize: 25,
    fontWeight: 'bold',
    color: '#48BBEC'
  },
  subtitle: {
    fontSize: 20,
    color: '#656565'
  },
  dateContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'flex-end'
  },
  rowContainer: {
    flexDirection: 'row',
    padding: 10
  }
});

And, finally, my layout code:

<TouchableHighlight
    underlayColor='#dddddd'>
      <View style={styles.rowContainer}>
          <View  cstyle={styles.textContainer}>
            <Text numberOfLines={1} style={styles.title}>{rowData.name}</Text>
            <Text style={styles.subtitle}>{rowData.teacher}</Text>
          </View>
          <View style={styles.dateContainer}>
            <Text style={styles.subtitle}>{result}</Text>
          </View>
        <View style={styles.separator}/>
      </View>
    </TouchableHighlight>
beyerss
  • 1,302
  • 3
  • 21
  • 38
  • Just a suggestion - try giving the dateContainer a min-width value? – sol Jul 03 '17 at 13:08
  • I tried that but then the blue text goes under the date text – beyerss Jul 03 '17 at 13:10
  • @beyerss not sure I understand whats the required functionality, what should happen when the text is too long? – Jony-Y Jul 03 '17 at 13:16
  • How about trying with max-width for "textContainer" class? – Vinay Gayakwad Jul 03 '17 at 13:18
  • I want the blue text to just truncate (show a "..." on the end of the string). – beyerss Jul 03 '17 at 13:18
  • I don't *think* I can use a maxWidth because the max width would be dependent on the screen size. If there is a way to set that size dynamically, that would work. – beyerss Jul 03 '17 at 13:21
  • Not sure in Flexbox, but as per my CSS knowledge you can do it by giving value in percentage for maxWidth. – Vinay Gayakwad Jul 03 '17 at 13:25
  • 1
    If I do percentages, that would leave, potentially, way too much space for the date. For example, a tablet would have much more white space than a phone. So far this is the best solution but I would expect to have a better way to do this so that the title can grow all the way up to the date text. – beyerss Jul 03 '17 at 13:29
  • https://stackoverflow.com/q/36247140/3597276 – Michael Benjamin Jul 03 '17 at 14:48
  • @Michael_B Suggestion does not seem to work in React Native – Grav Dec 08 '17 at 22:17

6 Answers6

5

Remove flex: 1 from dateContainer and add flexWrap: 'wrap' to textContainer.

textContainer: {
  flex: 1,
  flexWrap: 'wrap'
},
dateContainer: {
  justifyContent: 'center',
  alignItems: 'flex-end'
},
Devendra
  • 119
  • 1
  • 5
2

You'll have to set a width on the text component you wish to truncate (even if it's 100% of it's container which is the flexbox child I imagine), and also set numberOfLines prop to 1 (or however many lines you want to allow). See docs here on ellipsize mode and number of lines.

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

Code example of what I explain above:

<View style={{display: 'flex', flexDirection: 'row', overflow: 'hidden'}}>
    <View>
      <Text
        numberOfLines={1}
        style={{width: '100%'}}>Text here that I want to truncate</Text>
      <Text
        numberOfLines={1}
        style={{width:'100%'}}>Another line of text</Text>
    </View>
    <View style={{width: 120}}>
        <Text>01/01/2017</Text>
    </View>
</View>

If you're still having issues, it's possible you'll need to also use overflow: hidden in your text component style.

Kelley Rose
  • 122
  • 2
  • 5
  • 1
    I cannot get this to work, I have tried both with and without `overflow: hidden` in the text components. – Grav Dec 08 '17 at 22:17
2

To solve your problem, remove the flex: 1 from the dateContainer and it won't go off the screen.

dateContainer: {
  //flex: 1, line removed
  justifyContent: 'center',
  alignItems: 'flex-end'
},

Add the flex: 1 to your rowContainer as follows:

rowContainer: {
   flex: 1, //Line added
   flexDirection: 'row',
   padding: 10
}
Isaac Sekamatte
  • 5,500
  • 1
  • 34
  • 40
1

On your textContainer style replace the flex: 1 with flexShrink: 1

Inbal Tish
  • 257
  • 3
  • 5
0

The solution to this is adding flexGrow: 0 to the element that is pushing others away.

Bradley Flood
  • 10,233
  • 3
  • 46
  • 43
-1

I ended up solving this by measuring the parent view's width (with the onLayout callback) and then setting the width of the text's parent to the remainder.

This means having some state in the component, but it could be turned in to a general component with a left-side dynamic-sized component and a right-side static component.

Grav
  • 1,714
  • 14
  • 27