0

I have a list of comma-separated inline touchables like this:

[(<TouchableOpacity><Text>a</Text></TouchableOpacity>),
 (<Text>, </Text>),
 (<TouchableOpacity><Text>b</Text></TouchableOpacity>),
 (<Text>, </Text>),
 (<TouchableOpacity><Text>c</Text></TouchableOpacity>)]

rendering as a comma-separated string of items:

a, b, c

The problem is that sometimes comma gets wrapped to a newline, which looks kinda ugly:

a, b, c
, d

How to combine two "inline" elements so they get wrapped together?

Update. Code:

...

    let items1 = [];
    for (let i = 1; i <= 100; i++) {
        const text = makeid(i % 10 + 1);

        items1.push((<TouchableOpacity><Text style={{fontSize: 18}}>{text}</Text></TouchableOpacity>));
        items1.push((<Text style={{fontSize: 18}}>, </Text>));
    }

    return (<View style={styles.li}>
        {items1}
    </View>);

...

// just generates some random string
function makeid(len) {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < len; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

const styles = StyleSheet.create({
    li: {
        width: "100%",
        flexDirection: "row",
        flexWrap: "wrap",
        marginBottom: 5,
        paddingLeft: 10
    }
});

Result:

enter image description here

Denis Kulagin
  • 8,472
  • 17
  • 60
  • 129
  • Can you add the styles and the code for rendering this array? – Pritish Vaidya Feb 12 '19 at 15:33
  • 1
    Note that Text accept an onPress prop, so if you're adding TouchableOpacity just to get onPress support, then it's quite useless. In that case you can simply remove them and wrap all Text blocks in a parent Text (since Text supports nesting) and I think your problem is solved. – Milore Feb 12 '19 at 15:35
  • 1
    @Milore It works. Surely will use it as a workaround for now, but sadly it also leaves a user without nice animation provided by . I also think your comment deserves to be an answer. It would be nice if you put a short note on how text wrapping works in React Native. – Denis Kulagin Feb 12 '19 at 16:05
  • @PritishVaidya Sure. Updated the post. – Denis Kulagin Feb 12 '19 at 16:09

1 Answers1

2

1. Starting solution

According to the official documentation:

Text supports nesting, styling, and touch handling.

So if you're adding TouchableOpacity just to get onPress support, then it's quite useless. In that case you can simply remove it and wrap all Text blocks in a parent Text and your problem is solved.

As you correctly note, this

leaves a user without nice animation provided by <TouchableOpacity>.

I thought to a better solution and it was not so far :)

2. Other (and better?) solution

Simply wrap your <TouchableOpacity> and related <Text> with comma in a single <View> with flexDirection: 'row' and add it to the array you're going to render.

  render() {
    let items1 = [];
    for (let i = 1; i <= 100; i++) {
      const text = makeid((i % 10) + 1);

      items1.push(
        <View style={{ flexDirection: 'row'}}>
          <TouchableOpacity>
            <Text style={{ fontSize: 18 }}>{text}</Text>
          </TouchableOpacity>
          <Text style={{ fontSize: 18 }}>, </Text>
        </View>
      );
    }
    return (
      <View style={styles.li}>{items1}</View>
    );
  }

This way you're sure comma do not separate from its previous word and you benefit of <TouchableOpacity> animation.

Here you can find a working example. Hope this helps!

Milore
  • 1,672
  • 1
  • 15
  • 20