React Native prevent text from growing container width - css

How can I prevent the text from making its container grow in width and instead wrap to keep the width of the container? Note that I don`t want the container to have a fixed width, the width of the container is determined by its other children.
For example, the following code
class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={[styles.bubble2, {}]}>
<View
style={{ width: 100, height: 100, backgroundColor: "#ff0000" }}
/>
<Text
style={{
fontSize: 18,
flexWrap: "wrap",
backgroundColor: "#00ff00"
}}
>
Some random text goes here
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#fff",
paddingTop: 20,
alignItems: "center",
justifyContent: "center"
},
bubble2: {
backgroundColor: "orange",
paddingHorizontal: 20,
alignItems: "center",
justifyContent: "center"
}
});
renders this. Note how the text makes the container width larger to fit
and what I am trying to achieve is this without setting the width of the outer container

Related

How to align between two items inline left and right using flex in react native

Here's what I'm trying to achieve:
I want to align the 2 messages text label next to bargraph with background color green. The bargraph has dynamic width which renders coming from the backend and when size grows, the 2 messages label should also adjust and is always next to bargraph.
And here's what I have done sofar. It seems like that 2 messages won't show up next to bargraph with green background.
component code:
<View style={[styles.container]}>
<View style={[styles.barGraph, styles.greenDeep]}>
<View style={{ flex: 6 }}>
<Text style={styles.textLeft}>agree</Text>
</View>
<View style={{ flex: 6}}>
<Text style={styles.textRight}>3 (60 %)</Text>
</View>
</View>
<View>
<Text>2 messages</Text>
</View>
</View>
css:
container: {
flex: 1,
flexDirection: "column",
alignContent: "space-between",
},
textLeft: {
fontSize: 12,
color: 'white',
textAlign: 'left'
},
textRight: {
fontSize: 12,
color: 'white',
textAlign: 'right'
},
barGraph: {
flexDirection: 'row',
marginBottom: theme.SIZES.BASE,
width: width - theme.SIZES.BASE * 10,
padding: 10,
borderRadius: 5
},
greenDeep: {
backgroundColor: '#36d79a'
},
How would it be possible with react native's flex property?
For live editing, visit snack here live editor
To achive this:
First you have to set your flexDirection of container class to column. Set maxWidth at other container classes, and create a new class for your message with justifyContent: 'center' attribute.
container: {
flex: 1,
flexDirection: "row", /*it was column*/
alignContent: "space-between",
}
surveyDetailsContainer: {
/* some code */
maxWidth: 500,
},
container: {
/* some code */
maxWidth: 500,
},
/* some other classes*/
barGraph: {
/* some code */
maxWidth: 400,
},
/*created a new class, included the minWidth and added 3 more new attributes*/
message: {
minWidth: 5,
maxWidth: 80,
justifyContent: 'center',
marginLeft: 5,
}
And then put the new message class into:
<View style={[styles.message]}>
<Text>2 messages</Text>
</View>
Here is the whole code: https://snack.expo.dev/UwP7GVLzX
You can play around more with maxWidth, minWidth to make it responsive.

React Native - Align text in centre

import React from 'react'
import { View, StyleSheet, Image, Text } from 'react-native'
function RecentlyJoinedProfileCard({title, image}) {
return (
<View style={styles.container}>
<View>
<Image style={styles.image} source={{uri: image}} />
<Text styles={styles.name}>{title}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
paddingBottom:55
},
image: {
width:100,
height:100,
borderRadius: 75,
marginHorizontal:10,
marginVertical:10
},
name: {
fontSize: 15,
fontWeight: "bold",
alignSelf: 'center'
}
})
export default RecentlyJoinedProfileCard
This gives me the following:
The text is not aligning in the center of each image:
I've tried alignSelf: 'center' style in the text
I've also tried applying the following to the container
justifyContent: 'center',
alignItems: 'center',
Any idea on how to centre the name so its aligned in the centre rather than to the left.
Try this ->
<View style={{alignItems:'center'}}>
<Image style={styles.image} source={{uri: image}} />
<Text styles={styles.name}>{title}</Text>
</View>
Why are you nesting View inside View?
Okay for your style to be applied on the child elements you need to give the style to the nested View and use alignItems instead of alignSelf
E.g
<View style={styles.subContainer}>
<Image style={styles.image} source={{uri: image}} />
<Text styles={styles.name}>{title}</Text>
</View>
const styles = StyleSheet.create({
...
subContainer: {
justifyContent: 'center',
alignItems: 'center'
}
})
Just add alignItems && justifyContent "center" to parent View to align your items in center
just update your styles code like this:
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center'
paddingBottom:55
},
})
Change the alignSelf to textAlign: 'center'
name: {
//...
textAlign: 'center'
}

Flexbox: How to make children the same width as the parent?

In my React Native app, I'm having trouble with making the children the same width as the parent. Please see image below:
I want the black and the green View to take the whole screen width, therefore get rid of the white background caused by the parent.
How can I achieve this? For example, I tried to apply width: 100% to the children, doesn't work. Several solutions like this, this and this don't work here.
Here is the code:
<View style={styles.containerWholePage}>
<View>
<View style={styles.upper}></View>
<View style={styles.lower}></View>
</View>
</View>
const styles = StyleSheet.create({
containerWholePage: {
alignItems: 'center',
},
lower: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'green',
flex: 6,
width: '100%', // doesn't work
},
upper: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'black',
flex: 3,
width: '100%', // doesn't work
},
});
Do you have an idea what I'm doing wrong?
This work for me as you want.
<View style={styles.containerWholePage}>
{/* <View> */}
<View style={styles.upper}></View>
<View style={styles.lower}></View>
{/* </View> */}
</View>
const styles = StyleSheet.create({
containerWholePage: {
alignItems: 'center',
flex:1,
},
lower: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'green',
// height:100,
flex: 6,
width: '100%', // doesn't work
},
upper: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'black',
flex: 3,
//height:200,
width: '100%', // doesn't work
},
});

React Native vertical text alignment when using explicit height

I want to vertically center my text inside a view with an explicit height.
Center text vertically in react-native did not fully answer my question because they don't use explicit height.
When I use
<View style={styles.rightContainer}>
<Text style={styles.label2}>
Centered
</Text>
</View>
rightContainer: {
marginRight: 10,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
label2: {
height: 40,
backgroundColor: 'green',
textAlignVertical: 'center',
},
If I take away the explicit height,
label2: {
backgroundColor: 'green',
textAlignVertical: 'center',
},
it works.
I need to set the explicit height because I will convert this View to a tappable button.
How do I make this work?
What am I misunderstanding about react-native layout?
It's because the 'textAlignVertical' property is Android-only. Check the documentation on Text.
You could add an extra container wrapping the text:
export default class FlexDirectionBasics extends Component {
render() {
return (
<View style={styles.rightContainer}>
<View style={styles.labelContainer}>
<Text style={styles.label}>Centered</Text>
</View>
</View>
);
}
}
const styles = {
rightContainer: {
marginRight: 10,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
labelContainer: {
height: 40,
backgroundColor: 'green',
alignItems: 'center',
justifyContent: 'center',
},
label2: {},
};

Long text pushing other elements off screen with react native

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:
However, when the blue text gets long, it pushes the date off of the right side of the screen like this:
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>
Remove flex: 1 from dateContainer and add flexWrap: 'wrap' to textContainer.
textContainer: {
flex: 1,
flexWrap: 'wrap'
},
dateContainer: {
justifyContent: 'center',
alignItems: 'flex-end'
},
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.
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
}
The solution to this is adding flexGrow: 0 to the element that is pushing others away.
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.

Resources