React Native: Text not wrapping on web - css

on my mobile app, my text is wrapping as I would expect, but not on web.
Here is an example of one of the rows in my table:
<DataTable.Row style={styles.dataTableRow}>
<DataTable.Cell style={styles.dataTableCell}>
<View style={styles.tableRow}>
<View style={styles.tableColumn1}><Text style={styles.tableColumnText}>To register you as a new customer</Text></View>
<View style={styles.tableColumn2}><Text style={styles.tableColumnText}>(a) Identity (b) Contact</Text></View>
<View style={styles.tableColumn3}><Text style={styles.tableColumnText}>Performance of a contract with you</Text></View>
</View>
</DataTable.Cell>
</DataTable.Row>
And my styles:
dataTableRow: {
width: "100%",
},
dataTableCell: {
width: "100%",
},
tableRow: {
flexDirection: "row",
alignItems: "center",
},
tableColumn1: {
backgroundColor: colours.primary,
width: 300,
padding: 5,
},
tableColumn2: {
backgroundColor: colours.zettlePrimary,
width: 300,
padding: 5,
},
tableColumn3: {
backgroundColor: colours.status.rejected,
width: 600,
padding: 5,
},
tableColumnText: {
flexWrap: "wrap",
}
I normally wouldn't have all these elements/styles, but I have had trouble formatting this react-native-paper <DataTable>
I have used colours in this picture below just to highlight what is going on. And Like I mentioned, I have had no issue on mobile.

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.

Image inside a View element is not aligning to the right in React Native

I am implementing a tile in reactnative and I have to make the Image right in the tile just like this
What I want (click here)
and this is what I can implement till now
What I get ()
this is my code
<View style={styles.container} >
<Image
style={styles.image}
source={item.image}
resizeMode="cover"
/>
<View style={styles.overlay} />
<View style={styles.textContainer}>
<Text style={styles.subText}>{item.title}</Text>
<Text style={styles.headingText}>{item.message}</Text>
</View>
</View>
and this is style
const styles = StyleSheet.create({
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end',
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
marginTop: 20
},
image: {
width: COURSE_ITEM_WIDTH,
height: 120,
borderRadius: 10
},
textContainer: {
position: 'absolute',
left: 16,
flex: 1,
},
headingText: {
fontSize: 18,
color: '#ffffff',
marginTop: 5
},
subText: {
fontSize: 14,
color: '#ffffff',
},
timeText: {
fontSize: 15,
color: 'white',
textAlign: 'center',
marginTop: 5
},
overlay: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: '#206c72',
opacity: 0.6,
borderRadius: 10
}
})
Please help me i dont know what i am doing wrong. thanks in advance!
[note: please ignore the content, focus on alignment]
Your image is aligned to the right but there is nothing at the left of it. You should add flexDirection:'row' to the parent container and put an empty View with width : 40px before your image.
You can also remove the alignItems:flex-end and justifyContent:center from the main container
You can add alignSelf property to flex-end for image and image will be on end of the tile.
example 1:
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
alignSelf: "flex-end"
},
for reference i tried a sandbox example check it out here
also noticed you are using alignItems value twice first one is only necessary you can remove 2nd alignItems and position relative value from styles.container then it will align the image to end. you will get the exact result you want
example 2:
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end', // only need this alignItems
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
marginTop: 20
},
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
// no need of alignSelf to flex-end here
},

With flexbox, how can I create this easy app page loginscreen?

I'm trying to learn how to write React Native apps and they're using Flexbox a lot to style their App screens. How can I achieve the following layout using Flexbox?
Here's the code I have so far:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#cde9ff',
alignItems: 'center',
justifyContent: 'center',
borderWidth: 5,
},
header: {
borderWidth: 1,
fontSize: 38,
marginBottom: '50%',
},
form: {
borderWidth: 1,
},
input: {
width: 200,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: 'black',
marginBottom: 10,
backgroundColor: 'white',
color: 'black',
borderRadius: 10,
},
footer: {
borderWidth: 1,
},
});
I was trying to do it with the margins but that's not really working so well for me right now, and I figured it be best to properly learn to utilise Flexbox whenever I can.
Does someone know how to change my Stylesheet CSS to how I can easily create the quick paint image layout I made?
I would do something like this, and use flex-growth to push to footer at the end of the page
For the structure :
function App() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text>Title</Text>
</View>
<View style={styles.form}>
<View style={styles.input}></View>
<View style={styles.input}></View>
<View style={styles.input}></View>
<View style={styles.input}></View>
<View style={styles.input}></View>
<View style={styles.input}></View>
</View>
<View style={styles.footer}>
<Text>Footer</Text>
</View>
</View>
);
}
For the CSS :
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
alignItems: "center",
},
header: {
alignItems: "center",
width: "75%"
},
form: {
alignSelf: "center",
justifyContent: "center",
alignItems: "center",
width: "75%",
flexGrow: 1
},
input: {
width: 200,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: "black",
marginBottom: 10,
backgroundColor: "white",
color: "black",
borderRadius: 10
},
footer: {
alignItems: "center",
width: "50%"
},
});
codesanbox : https://codesandbox.io/embed/green-cloud-ne9yt?fontsize=14&hidenavigation=1&theme=dark
I think that you are looking for something like this:
HTML:
<div class="main-container">
<div class="title">
<h1> Title </h1>
</div>
<div class="form">
form
</div>
<div class="cta">
login
</div>
</div>
CSS:
.main-container{
height: 600px;
display:flex;
flex-direction:column;
justify-content:space-between;
align-items:center
}
.main-container div{
border: 1px solid black;
width: 300px;
padding: 50px
}
You have to add display flex to the parent container of the divs you want to be flexible
You can check Shahriar link: https://flexbox.malven.co/ it explains flex display pretty good
codepen: https://codepen.io/MichaeIMyers/pen/WNEJpLW

Flexbox styling with React Native

Well I thought I was getting the hang of styling. Tested on several different sized phones and it all looked great. Then... I tested on an iPad. Several of my screens ran way off the page. I am using flex: 1 for the container so I don't understand why. Do iPads not respect flex: 1 or something? Or did I just royally mangle the layout code? I thought using the screen dimensions and % to calculate most things would work for responsive design.
Example, sign in screen. Bottom 2 buttons "Login" and "Home" run almost completely off iPad screen. On phone devices seem to display fine.
EDIT: Thank you so much for the answer! I have rewritten the code and it looks fabulous now on the ipad. I hope this code is an improvement, I have added it to the bottom. Now to rewrite ALL the screens facepalm
import React, { useState } from "react";
import {
Dimensions,
Image,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { auth } from '../../src/config'
import AppText from "../components/AppText";
import colors from "../config/colors";
import Constants from "expo-constants";
let width = Dimensions.get('window').width;
function SignIn( { navigation } ){
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [message, setMessage] = useState('');
function emailSignIn(email, password){
email = email.trim();
auth.signInWithEmailAndPassword(email, password)
.then(function(result) {
setMessage('');
}).catch(function(error) {
setMessage('Invalid Email or Password. Sorry :(');
});
}
function updateEmail(email){
setMessage('');
setEmail(email);
}
function updatePassword(password){
setMessage('');
setPassword(password);
}
return (
<View style={styles.container}>
<Image style={styles.image} source={require("../assets/logo.png")} />
<Image style={styles.rainbow} source={require("../assets/rainbow.png")} />
<View style={styles.bottom}>
<View style={styles.inputView}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="E m a i l..."
placeholderTextColor="#003f5c"
onChangeText={(email) => updateEmail(email)}
autoCapitalize = 'none'
/>
</View>
<View style={styles.inputView2}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="P a s s w o r d..."
placeholderTextColor="#003f5c"
secureTextEntry={true}
onChangeText={(password) => updatePassword(password)}
autoCapitalize = 'none'
/>
</View>
<TouchableOpacity onPress={()=> navigation.navigate('ForgotPassword')}>
<Text style={styles.forgot_button}>Forgot Password?</Text>
</TouchableOpacity>
<AppText style={styles.message}>{message}</AppText>
<TouchableOpacity onPress={()=>emailSignIn(email,password)} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>navigation.navigate('StartScreen')} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>HOME</Text>
</TouchableOpacity>
</View>
</View>
);
}
export default SignIn;
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
paddingVertical: "3%",
width: width * 0.8,
marginBottom: 10,
},
appButtonText: {
fontSize: width * 0.04,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
bottom: {
alignItems: "center",
marginTop: width * 0.8,
},
container: {
flex: 1,
backgroundColor: colors.white,
justifyContent: "center",
alignItems: "center",
marginTop: Constants.statusBarHeight,
},
forgot_button: {
height: width * 0.1,
fontWeight: "bold",
},
image: {
width: width* 0.5,
resizeMode: "contain",
position: "absolute",
top: -20,
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
marginBottom: width * 0.05,
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
marginBottom: 0,
},
message: {
color: colors.red,
marginTop: width * 0.05,
marginBottom: 10,
alignSelf: "center",
},
rainbow: {
position: "absolute",
top: "10%",
},
});
New styles:
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
justifyContent: "center",
marginHorizontal: "5%",
height: "25%",
},
appButtonText: {
fontSize: 18,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
container: {
flex: 1,
backgroundColor: colors.white,
marginTop: Constants.statusBarHeight,
},
forgot_button: {
alignSelf: "center",
fontWeight: "bold",
},
image: {
height: 200,
width: 200,
},
imageContainer: {
flex: 2,
justifyContent: "center",
alignItems: "center",
},
inputButtons: {
flex: 1,
justifyContent: "space-around",
marginHorizontal: "10%",
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
height: "25%",
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
height: "25%",
},
message: {
color: colors.red,
alignSelf: "center",
},
rainbow: {
flex: 1,
width: "100%",
height: "100%",
position: "absolute",
},
rainbowImage: {
height: "60%",
position: "absolute",
top: "15%",
},
submitButtons: {
flex: 1,
justifyContent: "space-around",
},
});
You're getting a width from Dimensions at the top level of your file and then basing all of your layout calculations on this later on. This means that whenever this file is first parsed/run, that width will be calculated. That'll work if the device reports its width correctly on the first pass through the code (not guaranteed), but will break if it gets an unusual width during that pass (likely) and will definitely break if the window changes size or rotates.
Instead of basing all of your calculations on that static width, I suggest you look into leveraging Flexbox for dynamic layouts.
For example, at one point in your code, you set a TextInput to 80% of the view by doing width * 0.8. You could do the same thing by just setting the width to 80%:
export default function App() {
return (
<View style={{flex: 1, justifyContent: "center", alignItems: "center"}}>
<TextInput
style={{borderWidth: 1, width: "80%"}}
/>
</View>
);
}
Basically, try to do everything you can to get rid of relying on Dimensions unless you really need it. And, if you do need it, make sure you calculate it at the time you need it based on the current screen and not just at the first run of the app.

How to have one image centered but another image in the top left corner?

I would like to create a header for my React Native app. It would have one primary image centered, and then a back button to the left of it (near the edge of the screen). At the moment, I am able to get them in the same row and have the primary image centered, but cannot figure out how to bring the back arrow image to the far left.
This is my code.
<View style={styles.container}>
<View style={styles.row}>
<Image style={styles.backarrow} source={require('./images/backarrow.png')} />
<Image style={styles.minilogo} source={require('./images/minibear.png')} />
</View>
</View>
And this is the style code.
container: {
flex: 1,
backgroundColor: '#5683C7',
alignItems: 'center',
justifyContent: 'center',
},
minilogo: {
height: 100,
width: 100,
},
backarrow: {
height: 50,
width: 40,
},
row: {
flexDirection: 'row',
margin: 15,
alignItems: 'center',
}
Ideally it would look like this
Any help would be greatly appreciated! Thanks.
using border width you can understand adjust your layout
apply this stylesheet
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#5683C7',
alignItems: 'center',
justifyContent: 'center',
flexDirection:"column"
},
minilogo: {
height: 100,
width: 100,
justifyContent:"flex-end",
flex:7,
},
backarrow: {
height: 50,
width: 40,
justifyContent:"flex-start",
alignSelf:"center",
flex:3,
},
row: {
flexDirection: 'row',
width:"100%",
margin: 1,
resizeMode:"stretch",
// backgroundColor:"green",
// borderWidth:1,
alignItems:"stretch",
}
});

Resources