Can't get this layout in react native:centering vertical text - css

this is a follow up question for my problem.
I have this layout and I want to use it as an component which will be more square shaped.
I am struggling trying to create this layout with css in react native.
Can someone help me? I really only need the style for centering the text on the left .
I appreciate your help.
type TeamsProps = {
name: string,
}
const TeamCard = (props: TeamsProps) => {
const [showOptions, setShowOptions] = useState<Boolean>(false)
const toggleOptions = () => {
setShowOptions(!showOptions)
}
return (
<View style={[styles.container, { height: (Dimensions.get("window").width - 3 * 15) / 2 }]}>
<TouchableOpacity onLongPress={toggleOptions} style={styles.card}>
<View style={styles.nameFlag}>
<Text style={styles.name}>{props.name}</Text>
</View>
<View style={styles.member}>
</View>
</TouchableOpacity>
{ showOptions ?
<TouchableOpacity onPress={toggleOptions} style={styles.options}>
<TextInput style={styles.input} value="Team Name"></TextInput>
<View style={styles.buttons}>
<TouchableOpacity style={[styles.button, styles.delete]}>
<Delete style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.confirm]}>
<Check style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
</View>
</TouchableOpacity>
: <></>
}
</View>
)
}
const styles = StyleSheet.create({
container: {
flexBasis: "calc(50% - 7.5px)"
},
card: {
backgroundColor: constants.mainColor,
borderRadius: 15,
shadowOpacity: 0.6,
shadowRadius: 10,
flex: 1,
flexDirection: "row",
alignItems: "center"
},
nameFlag: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "15%",
marginVertical: 15,
borderTopRightRadius: 30,
borderBottomRightRadius: 30,
justifyContent: "center"
},
name: {
position: "absolute",
// TODO: translateX needs to use -50%, translateY needs to use 50% of parent width
transform: [{ rotate: "-90deg" }, { translateX: -33 }, { translateY: 13 }],
transformOrigin: "left",
width: "max-content",
fontFamily: constants.fontFamilyHeader,
fontSize: constants.fontSizeHeader
},
member: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "calc(85% - 30px)",
margin: 15,
borderRadius: 30,
padding: 15,
flex: 1,
flexDirection: "row",
flexWrap: "wrap",
gap: 15,
justifyContent: "space-around",
alignItems: "center"
},
options: {
backgroundColor: constants.shadowColor,
position: "absolute",
top: 0,
left: 0,
zIndex: 100,
width: "100%",
height: "100%",
borderRadius: 15,
padding: 15,
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: 25
},
input: {
backgroundColor: "white",
width: "100%",
borderRadius: 50,
padding: 5,
fontFamily: constants.fontFamilySubheader,
fontSize: constants.fontSizeHeader,
textAlign: "center"
},
buttons: {
flexDirection: "row",
gap: 25
},
button: {
borderRadius: 50,
width: 40,
height: 40
},
delete: {
backgroundColor: constants.alertColor
},
confirm: {
backgroundColor: constants.accentColor
}
})
weird shifting if text gets longer #Hammad Hassan

Try out this code and let me know
type CardProps= {
name: string
}
const Card = (props: CardProps) => {
return (
<View style={styles.container}>
<View style={styles.nameFlag}>
<Text style={styles.name}>{props.name}</Text>
</View>
<View style={styles.main}>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
backgroundColor: constants.mainColor,
flex: 1,
flexDirection: "row"
},
nameFlag: {
backgroundColor: constants.mainColorLight,
height: "95%",
width: "15%",
marginVertical: "5%",
borderTopRightRadius: 50,
borderBottomRightRadius: 50,
justifyContent: "center"
},
name: {
transform: [{ rotate: "-90deg" }, { translateY: -12 }],
fontFamily: constants.fontFamily,
fontSize: constants.fonzSizeHeader,
textAlign: 'center',
marginRight: 'auto',
marginLeft: 'auto',
marginTop: 'auto',
marginBottom: 'auto'
},
main: {
backgroundColor: constants.mainColorLight,
height: "95%",
width: "75%",
margin: "5%",
borderRadius: 50
}
})
export { Card }

Related

React Native translate text with percentage values not working

I have a react native project where I want to orientate a element verticaly and center the text.
Now I want to use percentages so it is centered width wise which would be the height of the parent element. Also the text should wrap it gets to big.
The problem is I can not use percentage because it get always converted to px inside the browser.
Can someone help me out?
I appreciate your help.
The text on the left side should always be centered like it is in this screenshot. It behaves so weird, if the width is changing the text moves around.
type TeamsProps = {
name: string,
}
const TeamCard = (props: TeamsProps) => {
const [showOptions, setShowOptions] = useState<Boolean>(false)
const toggleOptions = () => {
setShowOptions(!showOptions)
}
return (
<View style={[styles.container, { height: (Dimensions.get("window").width - 3 * 15) / 2 }]}>
<TouchableOpacity onLongPress={toggleOptions} style={styles.card}>
<View style={styles.nameFlag}>
<Text style={styles.name}>{props.name}</Text>
</View>
<View style={styles.member}>
</View>
</TouchableOpacity>
{ showOptions ?
<TouchableOpacity onPress={toggleOptions} style={styles.options}>
<TextInput style={styles.input} value="Team Name"></TextInput>
<View style={styles.buttons}>
<TouchableOpacity style={[styles.button, styles.delete]}>
<Delete style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.confirm]}>
<Check style={{ fontSize: 20, color: "white", margin: "auto" }} />
</TouchableOpacity>
</View>
</TouchableOpacity>
: <></>
}
</View>
)
}
const styles = StyleSheet.create({
container: {
flexBasis: "calc(50% - 7.5px)"
},
card: {
backgroundColor: constants.mainColor,
borderRadius: 15,
shadowOpacity: 0.6,
shadowRadius: 10,
flex: 1,
flexDirection: "row",
alignItems: "center"
},
nameFlag: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "15%",
marginVertical: 15,
borderTopRightRadius: 30,
borderBottomRightRadius: 30,
justifyContent: "center"
},
name: {
position: "absolute",
// TODO: translateX needs to use -50%, translateY needs to use 50% of parent width
transform: [{ rotate: "-90deg" }, { translateX: -33 }, { translateY: 13 }],
transformOrigin: "left",
width: "max-content",
fontFamily: constants.fontFamilyHeader,
fontSize: constants.fontSizeHeader
},
member: {
backgroundColor: constants.mainColorLight,
height: "calc(100% - 30px)",
width: "calc(85% - 30px)",
margin: 15,
borderRadius: 30,
padding: 15,
flex: 1,
flexDirection: "row",
flexWrap: "wrap",
gap: 15,
justifyContent: "space-around",
alignItems: "center"
},
options: {
backgroundColor: constants.shadowColor,
position: "absolute",
top: 0,
left: 0,
zIndex: 100,
width: "100%",
height: "100%",
borderRadius: 15,
padding: 15,
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: 25
},
input: {
backgroundColor: "white",
width: "100%",
borderRadius: 50,
padding: 5,
fontFamily: constants.fontFamilySubheader,
fontSize: constants.fontSizeHeader,
textAlign: "center"
},
buttons: {
flexDirection: "row",
gap: 25
},
button: {
borderRadius: 50,
width: 40,
height: 40
},
delete: {
backgroundColor: constants.alertColor
},
confirm: {
backgroundColor: constants.accentColor
}
})
Return to post

Center react native view

I'm creating a component to show the flag and country name. I'll like that view (image + text) centered in the available space.
So if the width of parent is all the screen, there will be space in the left and same in the right. If the parent is only 50% of the screen will be then left space on the sides...
What I've done:
<View style={styles.mainContainer} >
<View >
<TouchableOpacity
disabled={this.props.disablePicker}
onPress={() => this.setState({ modalVisible: true, dataSource: this.props.dataSource })}
activeOpacity={0.7}
>
<View>
<View style={[pickerStyle,{ flexDirection:'row'}]} >
<Image style={{}} source={selectedLabel.image} />
<Text style={}>{selectedLabel.name}</Text>
{dropDownImage ? <Image
style={dropDownImageStyle}
resizeMode="contain"
source={dropDownImage}
/> : null}
</View>
</View>
</TouchableOpacity>
</View>
</View>
const CountryPickerStyles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
itemSeparatorStyle:{
height: 1,
width: "90%",
alignSelf: "center",
backgroundColor: "#D3D3D3"
},
searchBarContainerStyle: {
marginBottom: 10,
flexDirection: "row",
height: 40,
shadowOpacity: 1.0,
shadowRadius: 5,
shadowOffset: {
width: 1,
height: 1
},
backgroundColor: "rgba(255,255,255,1)",
shadowColor: "#d3d3d3",
borderRadius: 10,
elevation: 3,
marginLeft: 10,
marginRight: 10
},
selectLabelTextStyle: {
color: "#000",
fontSize:16,
flexDirection: "row",
marginLeft: 100,
marginRight: 100
},
placeHolderTextStyle: {
color: "#757575",
padding: 10,
textAlign: "left",
width: "99%",
fontStyle: 'italic',
fontSize:12,
flexDirection: "row"
},
dropDownImageStyle: {
marginLeft: 10,
color: "#757575",
width: 10,
height: 10,
alignSelf: "center"
},
listTextViewStyle: {
color: "#000",
alignItems: "center",
justifyContent: "center",
marginLeft: 20,
marginHorizontal: 10,
textAlign: "left"
},
pickerStyle: {
elevation:0,
paddingRight: 10,
paddingLeft: 10,
marginRight: 10,
marginLeft: 10,
width:"90%",
borderWidth:0 ,
flexDirection: "row"
}
});
here's what I got:
https://pasteboard.co/JG5Rx9P.png
and also https://pasteboard.co/JG5Tthie.png

Implement simple modal in React Native breaks my UI

I have the following Signup page:
import React from "react";
import { Input } from "react-native-elements";
import {
StyleSheet,
Text,
View,
TextInput,
Button,
TouchableHighlight,
TouchableOpacity,
Modal,
Image,
Alert,
} from "react-native";
export default class Signup extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>Binders</Text>
<Text style={styles.slogan}>Création de compte</Text>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "user" }}
placeholder="Pseudo"
/>
<Input
// inputStyle={styles.input}
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "envelope" }}
placeholder="Adresse email"
/>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "lock" }}
placeholder="Mot de passe"
secureTextEntry
/>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "lock" }}
placeholder="Mot de passe"
secureTextEntry
/>
<TouchableOpacity style={styles.signup}>
<Text>Inscription</Text>
</TouchableOpacity>
<Text style={styles.already_signed}>Déjà inscris?</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22,
},
modalText: {
marginBottom: 15,
textAlign: "center",
},
already_signed: {
position: "absolute",
left: "5.2%",
top: "88%",
fontSize: 15,
},
title: {
position: "absolute",
left: "5.2%",
top: "12.34%",
fontStyle: "normal",
fontWeight: "bold",
fontSize: 32,
lineHeight: 32,
display: "flex",
alignItems: "center",
color: "#000000",
alignItems: "center",
justifyContent: "center",
},
input: {
top: "40%",
left: "5.2%",
},
slogan: {
position: "absolute",
left: "5.2%",
top: "18.9%",
fontStyle: "normal",
fontWeight: "normal",
fontSize: 17,
lineHeight: 17,
display: "flex",
alignItems: "center",
color: "#000000",
},
inputContainer: {
borderBottomColor: "#F5FCFF",
backgroundColor: "#FFFFFF",
borderRadius: 30,
borderBottomWidth: 1,
width: 250,
height: 45,
marginBottom: 20,
flexDirection: "row",
alignItems: "center",
},
inputs: {
height: 45,
marginLeft: 16,
borderBottomColor: "#FFFFFF",
flex: 1,
},
inputIcon: {
width: 30,
height: 30,
marginLeft: 15,
justifyContent: "center",
},
buttonContainer: {
height: 45,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginBottom: 20,
width: 250,
borderRadius: 30,
},
signupButton: {
backgroundColor: "#FF4DFF",
},
signUpText: {
color: "white",
},
signup: {
position: "absolute",
alignItems: "center",
justifyContent: "center",
top: "70%",
borderRadius: 8,
left: "5.2%",
borderWidth: 3,
borderColor: "#000000",
width: "88%",
height: "8%",
},
});
However, whenever I want to add a Modal in it, all the UI breaks:
import React from "react";
import { Input } from "react-native-elements";
import {
StyleSheet,
Text,
View,
TextInput,
Button,
TouchableHighlight,
TouchableOpacity,
Modal,
Image,
Alert,
} from "react-native";
export default class Signup extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View style={styles.container}>
<Modal>
<Text style={styles.title}>Binders</Text>
<Text style={styles.slogan}>Création de compte</Text>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "user" }}
placeholder="Pseudo"
/>
<Input
// inputStyle={styles.input}
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "envelope" }}
placeholder="Adresse email"
/>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "lock" }}
placeholder="Mot de passe"
secureTextEntry
/>
<Input
containerStyle={styles.input}
leftIcon={{ type: "font-awesome", name: "lock" }}
placeholder="Mot de passe"
secureTextEntry
/>
<TouchableOpacity style={styles.signup}>
<Text>Inscription</Text>
</TouchableOpacity>
<Text style={styles.already_signed}>Déjà inscris?</Text>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22,
},
modalText: {
marginBottom: 15,
textAlign: "center",
},
already_signed: {
position: "absolute",
left: "5.2%",
top: "88%",
fontSize: 15,
},
title: {
position: "absolute",
left: "5.2%",
top: "12.34%",
fontStyle: "normal",
fontWeight: "bold",
fontSize: 32,
lineHeight: 32,
display: "flex",
alignItems: "center",
color: "#000000",
alignItems: "center",
justifyContent: "center",
},
input: {
top: "40%",
left: "5.2%",
},
slogan: {
position: "absolute",
left: "5.2%",
top: "18.9%",
fontStyle: "normal",
fontWeight: "normal",
fontSize: 17,
lineHeight: 17,
display: "flex",
alignItems: "center",
color: "#000000",
},
inputContainer: {
borderBottomColor: "#F5FCFF",
backgroundColor: "#FFFFFF",
borderRadius: 30,
borderBottomWidth: 1,
width: 250,
height: 45,
marginBottom: 20,
flexDirection: "row",
alignItems: "center",
},
inputs: {
height: 45,
marginLeft: 16,
borderBottomColor: "#FFFFFF",
flex: 1,
},
inputIcon: {
width: 30,
height: 30,
marginLeft: 15,
justifyContent: "center",
},
buttonContainer: {
height: 45,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginBottom: 20,
width: 250,
borderRadius: 30,
},
signupButton: {
backgroundColor: "#FF4DFF",
},
signUpText: {
color: "white",
},
signup: {
position: "absolute",
alignItems: "center",
justifyContent: "center",
top: "70%",
borderRadius: 8,
left: "5.2%",
borderWidth: 3,
borderColor: "#000000",
width: "88%",
height: "8%",
},
});
I tried adding a style={styles.container} in the Modal, but then, only half of the screen is used. What is the best way to add a child component without breaking the whole CSS based on styles.container?
try with this...
Place your modal components inside, below maked
render() {
if (!this.state.modalVisible)
return null
return (
<View>
<Modal
animationType="fade"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {this.setModalVisible(false)}}
>
<TouchableOpacity
style={styles.container}
activeOpacity={1}
onPressOut={() => {this.setModalVisible(false)}}
>
<ScrollView
directionalLockEnabled={true}
contentContainerStyle={styles.scrollModal}
>
<TouchableWithoutFeedback>
<View style={styles.modalContainer}>
// Body of your modal content
</View>
</TouchableWithoutFeedback>
</ScrollView>
</TouchableOpacity>
</Modal>
</View>
)
}
// Then on setModalVisible(), you do everything that you need to do when closing or opening the modal.
setModalVisible = (visible) => {
this.setState({
modalVisible: visible,
})
}

How to make a shadow only for the container, not for inside element

I have an app on react-native. I need to make a shadow for the particular View. When i set it the shadow is working only for the inside of a View elements, but i need the shadow only for the border of View, not for the inside elements. Can you tell me please how can i do it?
const styles = StyleSheet.create({
container: {
alignItems: 'center',
height: HP('11.2%'),
justifyContent: 'center',
width: '100%'
},
icon: {
color: '#757575',
position: 'absolute'
},
inputContainer: {
width: '85%'
},
subContainer: {
alignItems: 'center',
borderRadius: HP('6.8%'),
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, 0.24)',
flexDirection: 'row',
height: HP('7.8%'),
width: WP('95%')
},
shadowStyle: {
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3
},
textInput: {
fontFamily: 'Roboto',
fontSize: HP('2.3%'),
height: 48,
maxWidth: '85%',
left: WP('9%')
}
})
const SearchBar = props => {
const { container, icon, inputContainer, subContainer, shadowStyle, textInput } = styles
const { onChangeText, onLeftIconPress, onRightIconPress, value } = props
return (
<View style={[container, shadowStyle]}>
<View style={[shadowStyle, subContainer]}>
<TouchableOpacity onPress={onLeftIconPress}>
<Ionicons style={(icon, { left: WP('5%') })} name="md-funnel" size={HP('3.5%')} />
</TouchableOpacity>
<View style={inputContainer}>
<TextInput
autoCapitalize="words"
onChangeText={onChangeText}
placeholder="Search.."
style={textInput}
value={value}
/>
</View>
<TouchableOpacity onPress={onRightIconPress}>
<Ionicons style={(icon, { right: WP('0.3%') })} name="ios-mic" size={HP('4%')} />
</TouchableOpacity>
</View>
</View>
)
}

iFrame Border Showing in WebView React Native

In attempts to dynamically add youtube videos to my React Native app, I chose to use a combination of WebView and iFrame since the current react-native-youtube component doesn't work for RN 16^. Ultimately, the solution does work, but the iframe border still shows and will not go away (even with css or frameborder = 0), nor can I change it's color with css. Any ideas? Here's my code:
video-preview component (where users can see video, title, etc before tapping):
module.exports = React.createClass({
render: function() {
return (
<TouchableHighlight
style={styles.touchCard}
underlayColor={'transparent'}
onPress={this.props.onPress} >
<View style={styles.card}>
<WebView
style={styles.videoPreview}
automaticallyAdjustContentInsets={true}
scrollEnabled={false}
style={styles.videoPreview}
html={this.props.source}
renderLoading={this.renderLoading}
renderError={this.renderError}
automaticallyAdjustContentInsets={false} />
<View style={[styles.container, this.border('organge')]}>
<View style={[styles.header, this.border('blue')]}>
<Text style={[styles.previewText]}>{this.props.text}</Text>
</View>
<View style={[styles.footer, this.border('white')]}>
<View style={styles.sourceRow}>
<View style={[this.border('white')]}>
<ImageButton
style={[styles.logoBtn, , this.border('red'), styles.row]}
resizeMode={'contain'}
onPress={this.onHeartPress}
source={this.props.src} />
</View>
<View style={[this.border('white')]}>
<Text style={[styles.rowText, {fontWeight: 'bold'}]}>{this.props.entryBrand}</Text>
<Text style={[styles.rowText]}>{this.props.views}</Text>
</View>
</View>
<View style={[styles.heartRow, this.border('black')]}>
<KeywordBox
style={[styles.category, this.border('blue')]}
key={this.props.key}
text={this.props.category}
onPress={this.props.categoryPress}
selected={this.props.selected} />
</View>
</View>
</View>
</View>
</TouchableHighlight>
);
Which looks like this:
And the input iframe html into the webview looks like this:
<iframe style='border: 0;border-width: 0px;' scrolling='no' frameborder='0' width='320' height='300' src='https://www.youtube.com/embed/2B_QP9JGD7Q'></iframe>
Here's my styling:
var styles = StyleSheet.create({
centerText: {
marginBottom:5,
textAlign: 'center',
},
noResultsText: {
marginTop: 70,
marginBottom:0,
color: '#000000',
},
sourceRow: {
justifyContent: 'space-around',
flexDirection: 'row',
},
rowText: {
textAlign: 'left',
color: 'white',
fontSize: 12,
marginLeft: 5,
fontFamily: 'SFCompactText-Medium'
},
detailText: {
fontFamily: 'SFCompactText-Light',
fontSize: 18,
color: 'white',
textAlign: 'left',
marginTop: 2,
marginLeft: 5,
},
touchCard: {
margin: 3,
width: window.width*0.95,
shadowOffset: {width: 2, height: 2},
shadowOpacity: 0.5,
shadowRadius: 3,
alignSelf:'center',
},
card: {
flex: 1,
width: window.width*0.98,
alignSelf:'center',
},
heartText: {
color: 'white',
fontSize: 12,
fontWeight: 'bold',
alignSelf: 'center',
fontFamily: 'SFCompactText-Medium'
},
heartRow: {
flexDirection: 'row',
justifyContent: 'space-around',
alignSelf: 'center',
justifyContent: 'center',
},
logoBtn: {
height: window.width/10,
width: window.width/10,
alignSelf:'center',
},
heartBtn: {
height: (92/97)*(window.width/13),
width: window.width/13,
alignSelf:'center',
},
category: {
fontFamily: 'Bebas Neue',
fontSize: 10,
fontWeight: 'bold'
},
header: {
flex: 1,
justifyContent: 'space-around',
marginTop: window.height/60,
},
footer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
margin: window.height/80,
},
container: {
flex: 1,
backgroundColor: '#1a1a1a',
},
videoPreview: {
flex: 2,
height: window.width*0.85,
width:window.width*0.98,
flexDirection: 'column'
},
previewText: {
fontFamily: 'Bebas Neue',
fontSize: 23,
color: 'white',
textAlign: 'left',
marginTop: 2,
marginLeft: 5,
},
});

Resources