I have the following layout within a RN View:
The buttons on the left have a dynamic width applied to a surrounding wrapper view - as based on state there could be 1, 2 or 3 buttons. the width is applied by conditional styles. My issue is - whatever i do I cannot get the description box to wrap - the text wrapper takes on the full width of the screen rather than its available remaining width..
Code:
Here is the code structure:
<View
style={[FormStyles.prRowStrip, { width: "100%", flexGrow: 0, flexWrap: 0 }]}
>
<View style={RP_Styles.btnRow}>
<View
style={[
returnHeader_full() && RP_Styles.btnWrap,
returnHeader_two() && RP_Styles.btnWrap_two,
returnHeader_one() && RP_Styles.btnWrap_one
]}
>
<TouchableOpacity
style={[
RP_Styles.smlBtnWrap,
!hasSiteGuide() && HomeStyles.checkedInHide
]}
onPress={() => this.openDocument(this.state.locationSiteGuidePdf)}
>
<Image
style={RP_Styles.homeSegmentImg}
source={require("../images/icons/ico_site_guide.png")}
/>
<Text style={RP_Styles.homeSegmentText}>Guide</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
RP_Styles.smlBtnWrap,
!hasInventoryItems() && HomeStyles.checkedInHide
]}
onPress={toggleELModal}
>
<Image
style={RP_Styles.homeSegmentImg}
source={require("../images/icons/ico_equip_guide.png")}
/>
<Text style={RP_Styles.homeSegmentText}>Equip</Text>
</TouchableOpacity>
<TouchableOpacity style={RP_Styles.smlBtnWrap} onPress={toggleIssueModal}>
<Image
style={RP_Styles.homeSegmentImg}
source={require("../images/icons/ico_issue_b.png")}
/>
<Text style={RP_Styles.homeSegmentText}>Issue</Text>
</TouchableOpacity>
</View>
<View style={RP_Styles.txtBlock}>
<Text style={[RP_Styles.locBlockTxt]}>
Description: Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam
{this.state.currentMarkerName} - {this.state.currentMarkerDescription}
</Text>
</View>
</View>
</View>
Heres the relevant applied styles currently:
const RP_Styles = StyleSheet.create({
txtBlock: {
backgroundColor:'red',
flexDirection: 'column',
},
locBlockTxt: {
fontSize: 15,
color: '#f79431',
textTransform: 'uppercase',
fontWeight: '500',
flexWrap: 'wrap',
},
btnRow: {
paddingTop: 4,
paddingBottom: 10,
paddingHorizontal: 8,
flexDirection: 'row',
},
btnWrap: {
flexDirection: 'row',
width: '180',
},
btnWrap_two: {
flexDirection: 'row',
flexGrow:0,
flexShrink:0,
width:120,
},
btnWrap_one: {
flexDirection: 'row',
flexGrow:0,
flexShrink:0,
width:60,
},
flRow: {
flexDirection: 'row',
paddingHorizontal: 6,
paddingTop: 12,
marginVertical: 6,
},
firstRow: {
marginTop: 10,
},
)}
const Form_Styles = StyleSheet.create({
prRowStrip: {
backgroundColor: 'rgba(0,0,0,0.05)',
marginVertical: 3,
paddingVertical: 4,
paddingHorizontal: 5,
},
}
as you see there a few inline styles where i've tried adding various style classes - but this is where its at at the mo. Any help would be great-fully received!
Related
When generating pdf file in the table. Is it possible to set to enable text wrap, but disable to break words? Beacuse now it wraps words and added hyphen.
I would like whole word give to the new line without wrap word. How to set it up?
This css works:
flexWrap: wrap, // wrap text
Some css properties cannot be applied:
overflowWrap: "break-word", // Object literal may only specify known properties, and 'overflowWrap' does not exist in type 'Style'.
wordBreak: "normal", // Object literal may only specify known properties, and 'wordBreak' does not exist in type 'Style'.
whiteSpace: "wrap", // Object literal may only specify known properties, and 'whiteSpace' does not exist in type 'Style'.
I use reactjs 17.0.2, react-pdf/renderer 3.0.1, types/react-pdf 5.7.2.
Code:
<Page size="A4" orientation="landscape" style={styles.page}>
<View style={styles.tableContainer}>
{/* -- Table Head: -- */}
<View style={styles.head}>
<Text style={{ ...styles.headCol, width: "8%" }}>{"State"}</Text>
<Text style={{ ...styles.headColLast, width: "24%" }}>{"Subject"}</Text> */}
</View>
{/* -- Table Body: -- */}
<View key={index} style={styles.row}>
<Text style={{ ...styles.rowCol, width: "8%" }}>Ok</Text>
<Text style={{ ...styles.rowColLast, width: "24%" }}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</Text>
</View>
</View>
</Page>
// style:
const borderColor = "#90e5fc"
const paddingTopText = 3;
const paddingLeftText = 2;
const paddingRightText = 2;
const paddingBottomText = 2;
const rowHeight = 80;
Styles = {
page: {
fontFamily: "OpenSans",
fontSize: "9px",
lineHeight: 1.3,
flexDirection: "column",
paddingTop: 30,
paddingLeft: 30,
paddingRight: 30
},
tableContainer: {
flexDirection: "row",
flexWrap: "wrap", // nowrap
marginTop: 24,
borderColor: borderColor,
borderWidth: 2
},
head: {
flexDirection: "row",
borderBottomColor: borderColor,
borderBottomWidth: 1,
height: "auto",
textAlign: "left",
fontWeight: "bold",
flexGrow: 1,
margin: 0,
padding: 0
},
headCol: {
borderRightColor: borderColor,
borderRightWidth: 1,
paddingTop: paddingTopText,
paddingLeft: paddingLeftText,
paddingRight: paddingRightText,
paddingBottom: paddingBottomText
},
headColLast: {
paddingTop: paddingTopText,
paddingLeft: paddingLeftText,
paddingRight: paddingRightText,
paddingBottom: paddingBottomText
},
row: {
flexDirection: "row",
borderBottomColor: borderColor,
borderBottomWidth: 1,
height: rowHeight,
margin: 0,
padding: 0
},
rowCol: {
textAlign: "left",
borderRightColor: borderColor,
borderRightWidth: 1,
paddingTop: paddingTopText,
paddingLeft: paddingLeftText,
paddingRight: paddingRightText,
paddingBottom: paddingBottomText
},
rowColLast: {
textAlign: "left",
paddingTop: paddingTopText,
paddingLeft: paddingLeftText,
paddingRight: paddingRightText,
paddingBottom: 0
},
}
The following solution works. It doesn't wrap words and it doesn't add hyphen "-". Maybe somebody it helps.
export const chunkSubstr = (str, size) => {
const numChunks = Math.ceil(str.length / size);
const chunks = new Array(numChunks);
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
chunks[i] = str.substr(o, size);
}
return chunks;
};
Font.registerHyphenationCallback((word) => {
if (word.length > 16) {
return chunkSubstr(word, 14);
} else {
return [word];
}
});
Im trying to get an image to fit within my view but it overshoots the view and covers most of the screen. I have tried other solutions I've found like resizeMode: "contain"/cover but none seem to fix it.
Heres my code:
return (
<View style={styles.container}>
<View style={styles.articlePicture}>
<Image source={require("../../assets/powerplant.jpg")} style={styles.image}></Image>
</View>
<View style={styles.contentContainer}>
<View style={styles.articleSubTitle}>
<Text>Travel</Text>
</View>
<View style={styles.articleTitle}>
<Text style={styles.title}>Lorem ipsum dolor sit amet</Text>
</View>
</View>
</View>
);
And here is my styles:
container: {
height: "100%",
width: "100%",
backgroundColor: "blue",
},
contentContainer: {
width: "100%",
height: "10%",
backgroundColor: "yellow",
},
articlePicture: {
height: "20%",
backgroundColor: "red",
},
articleTitle: {},
title: {
fontWeight: "bold",
},
articleSubTitle: {},
image: {
height: "100%",
flexDirection: "column",
flexWrap: "wrap",
aspectRatio: 1,
resizeMode: "contain",
},
Use CSS object-fit: cover;
I think something like bellow:
...
image: {
height: "100%",
flexDirection: "column",
flexWrap: "wrap",
aspectRatio: 1,
objectFit: "cover",
},
....
I want to create a profile page where rounded image will be on top of two div in 30:70 ratio where top div will be empty and bottom div will contain few items. I have tried few code snippets from web.
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: 'green', justifyContent: 'flex-start', alignItems: 'flex-start' }}>
<View style={{ flexDirection: 'column', justifyContent: "flex-start", alignItems: "flex-start", alignSelf: "flex-start" }}>
{/* <View style={{ flex: 1, flexDirection: 'row', alignItems: 'flex-end', alignSelf: 'flex-start', margin: 1 }}> */}
<View style={{ backgroundColor: 'white', borderRadius: 10, flexDirection: 'column', height: "30%", width: "100%" }}></View>
{/* </View> */}
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'flex-start', alignSelf: 'flex-start', margin: 1 }}>
<View style={{ backgroundColor: 'white', borderRadius: 10, flexDirection: 'column', height: "70%", width: "100%" }}></View>
</View>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center', alignSelf: 'center', position: 'absolute' }}>
<View style={{
backgroundColor: 'blue',
borderRadius: 10, height: 100, width: 100, borderRadius: 100 / 2
}}></View>
</View>
</View>
reference image
Taking as reference the image you share with us... You can have two views and set the profile avatar style to:
{
position: 'absolute',
alignSelf: 'center',
etc..
}
Check a quick demo: https://snack.expo.io/#abranhe/avatar-example
App.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, ImageBackground, Image } from 'react-native';
import { Ionicons, FontAwesome } from '#expo/vector-icons';
import Constants from 'expo-constants';
import { avatar, background } from './data';
export default class App extends Component {
renderRow({ action, icon, fontAwesome = false }) {
return (
<View style={styles.actionRow}>
{fontAwesome
? <FontAwesome name={icon} size={25} />
: <Ionicons name={icon} size={32} />}
<Text style={styles.text}>{action}</Text>
</View>
);
}
render() {
return (
<View style={styles.container}>
<ImageBackground source={background} style={styles.background}>
<Image source={avatar} style={styles.avatar} />
</ImageBackground>
<View style={styles.content}>
{this.renderRow({ action: 'Scanner', icon: 'ios-camera' })}
{this.renderRow({
action: 'Profile',
icon: 'user-circle-o',
fontAwesome: true,
})}
</View>
</View>
);
}
}
You styles:
const styles = StyleSheet.create({
container: {
flex: 1,
},
background: {
width: '100%',
height: 130,
},
content: {
flex: 1,
marginTop: 80,
marginHorizontal: 10,
},
avatar: {
width: 100,
height: 100,
borderRadius: '50%',
borderWidth: 0.7,
borderColor: 'black',
position: 'absolute',
alignSelf: 'center',
marginTop: 80,
},
actionRow: {
width: '100%',
height: '50',
flexDirection: 'row',
alignItems: 'center',
margin: 10,
},
text: {
marginLeft: 15,
fontWeight: '500',
},
});
import React, { Component } from 'react';
import { StyleSheet, Dimensions } from 'react-native';
import {
CheckBox, Container, Content, Text, View, Button,
} from 'native-base';
import Fonts from '../common/Fonts';
const checkAllMargin = Dimensions.get('window').height / 3.14;
const styles = StyleSheet.create({
wrapper: {
justifyContent: 'flex-end',
flexDirection: 'column',
flex: 1,
},
moveButtonContainer: {
flexDirection: 'row',
alignSelf: 'flex-end',
marginTop: checkAllMargin,
},
prevButton: {
justifyContent: 'center',
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
backgroundColor: '#333333',
height: 55,
},
nextButton: {
justifyContent: 'center',
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
backgroundColor: '#4FCBFF',
height: 55,
},
moveButtonText: {
textAlign: 'center',
fontFamily: Fonts.NANUMGOTHICBOLD,
fontSize: 18,
},
termsView: {
flexDirection: 'row',
justifyContent: 'flex-start',
marginTop: 21,
},
checkBox: {
marginLeft: 10,
},
termsText: {
alignSelf: 'center',
marginLeft: 17,
height: 16,
fontFamily: Fonts.NANUMGOTHIC,
fontSize: 11,
},
termsTextEnd: {
fontFamily: Fonts.NANUMGOTHIC,
fontSize: 11,
alignSelf: 'center',
},
requiredText: {
color: '#4FCBFF',
},
choiceText: {
color: '#999999',
},
checkAllView: {
flexDirection: 'row',
alignItems: 'flex-end',
justifyContent: 'flex-end',
marginTop: 35,
},
checkAllText: {
alignSelf: 'flex-end',
marginRight: 42,
},
checkAllBox: {
marginRight: 17,
},
openLinkButton: {
borderColor: '#CCCCCC',
borderRadius: 10,
height: 18,
width: 35,
alignSelf: 'flex-end',
borderWidth: 1,
},
openLinkText: {
fontFamily: Fonts.NANUMGOTHIC,
fontSize: 9,
paddingTop: 3,
paddingLeft: 5,
},
});
class TermsAgreeContainer extends Component {
constructor(props) {
super(props);
this.state = {
agreeTermsOfServices: false,
agreeTermsOfPrivacy: false,
agreeTermsOfCopyright: false,
agreeAll: false,
};
}
checkTermsOfServices = (isCheck) => {
this.setState({
agreeTermsOfServices: isCheck,
});
}
checkTermsOfPrivacy = (isCheck) => {
this.setState({
agreeTermsOfPrivacy: isCheck,
});
}
checkTermsOfCopyright = (isCheck) => {
this.setState({
agreeTermsOfCopyright: isCheck,
});
}
checkAll = (isCheck) => {
this.setState({
agreeTermsOfServices: isCheck,
agreeTermsOfPrivacy: isCheck,
agreeTermsOfCopyright: isCheck,
agreeAll: isCheck,
});
}
render() {
const {
agreeTermsOfServices, agreeTermsOfPrivacy, agreeTermsOfCopyright, agreeAll,
} = this.state;
const {
checkTermsOfServices, checkTermsOfPrivacy, checkTermsOfCopyright, checkAll,
} = this;
return (
<Container>
<Content scrollEnabled={false} contentContainerStyle={styles.wrapper}>
<View style={styles.termsView}>
<CheckBox
checked={agreeTermsOfServices}
onPress={() => checkTermsOfServices(!agreeTermsOfServices)}
style={styles.checkBox}
/>
<Text
style={styles.termsText}
onPress={() => checkTermsOfServices(!agreeTermsOfServices)}
suppressHighlighting
>
TermsOfServices
</Text>
<Text style={[styles.termsTextEnd, styles.requiredText]}> (required)</Text>
<Text style={[styles.openLinkButton, styles.openLinkText]}>Show</Text>
</View>
<View style={styles.termsView}>
<CheckBox
checked={agreeTermsOfPrivacy}
onPress={() => checkTermsOfPrivacy(!agreeTermsOfPrivacy)}
style={styles.checkBox}
/>
<Text
style={styles.termsText}
onPress={() => checkTermsOfPrivacy(!agreeTermsOfPrivacy)}
suppressHighlighting
>
TermsOfPrivacy
</Text>
<Text style={[styles.termsTextEnd, styles.requiredText]}> (required)</Text>
<Text style={[styles.openLinkButton, styles.openLinkText]}>Show</Text>
</View>
<View style={styles.termsView}>
<CheckBox
checked={agreeTermsOfCopyright}
onPress={() => checkTermsOfCopyright(!agreeTermsOfCopyright)}
style={styles.checkBox}
/>
<Text
style={styles.termsText}
onPress={() => checkTermsOfCopyright(!agreeTermsOfCopyright)}
suppressHighlighting
>
TermsOfCopyright
</Text>
<Text style={[styles.termsTextEnd, styles.choiceText]}> (choice)</Text>
<Text style={[styles.openLinkButton, styles.openLinkText]}>Show</Text>
</View>
<View style={styles.checkAllView}>
<CheckBox
checked={agreeAll}
onPress={() => checkAll(!agreeAll)}
style={styles.checkAllBox}
/>
<Text
style={styles.checkAllText}
onPress={() => checkAll(!agreeAll)}
suppressHighlighting
>
Check All
</Text>
</View>
<View style={styles.moveButtonContainer}>
<Button full style={styles.prevButton}>
<Text style={styles.moveButtonText}>back</Text>
</Button>
<Button full style={styles.nextButton}>
<Text style={styles.moveButtonText}>next</Text>
</Button>
</View>
</Content>
</Container>
);
}
}
export default TermsAgreeContainer;
Currently, the position of the Show button is determined by the Text length on the left.
I would like to move it to the right like the photo.
I want the Show button to be margin 30 based on the right.
However, I do not use margin-right if I use Flex-Start.
How can I place the show button on the right side?
One way could be to divide your current terms row in 2 views, assigning the first one a flex property and just a margin to the second one. Simply wrap the first elements in a <View>, like this:
<View style={styles.termsView}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<CheckBox
checked={agreeTermsOfServices}
onPress={() => checkTermsOfServices(!agreeTermsOfServices)}
style={styles.checkBox}
/>
<Text
style={styles.termsText}
onPress={() => checkTermsOfServices(!agreeTermsOfServices)}
suppressHighlighting>
TermsOfServices
</Text>
<Text style={[styles.termsTextEnd, styles.requiredText]}>
(required)
</Text>
</View>
<Text
style={[
styles.openLinkButton,
styles.openLinkText,
{ marginRight: 10 },
]}>
Show
</Text>
</View>
And repeat this structure for each row.
I'm trying to place my image over view that is already on other view but no success...
I had been trying to use position:'absolute' and more other options I had seen but it didn't work for me.
render() {
let locationFlag=Platform.OS === 'ios'?true:false
return (
<View style={styles.container}>
<LinearGradient
colors={[ '#75a4e7','#7d50f6']}
start={{x: .2, y: 1}}
end={{x:.8,y:0}}
locations={locationFlag?[.15,1]:[.18,2.1]}
style={styles.gradient}>
<View style={styles.profilePhotoContainer}>
<TouchableOpacity onPress={this.handleEditProfileImage.bind(this)}>
<Image
style={styles.profileImage}
source={this.state.profilePhoto}
/>
</TouchableOpacity>
</View>
</LinearGradient>
<View style={
[styles.profileBox]}
>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignSelf: 'stretch',
backgroundColor: Colors.LIGHT_GRAY
},
gradient: {
alignSelf: 'stretch',
alignItems: 'center',
flexDirection: 'column',
height: Dimensions.get('window').height * .35,
},
profilePhotoContainer: {
zIndex: 50,
position: 'absolute',
backgroundColor:'blue',
top: Dimensions.get('window').height * .12,
elevation: 4,
},
profileImage: {
zIndex: 5,
width: 100,
height: 100,
borderRadius: 50,
borderWidth: 4,
borderColor: '#FFF',
backgroundColor: 'transparent',
},
profileBox: {
zIndex: 1,
position: 'absolute',
left: Dimensions.get('window').width * .07,
top: Dimensions.get('window').height * .18,
borderRadius: 8,
shadowRadius: 8,
elevation: 3,
shadowOpacity: 0.3,
backgroundColor: 'yellow',
width: Dimensions.get('window').width * .86,
height: Dimensions.get('window').height * .50,
}
In the link you can see what did I do so far and what is the issue:
https://imgur.com/a/kC4ZTUn
I want to achieve this situation:
https://imgur.com/a/KMSRVfZ
Thank you
You should take the View with the profilePhotoContainer style out from the LinearGradient view and then it will work perfectly!
Here is a sample code to achieve similar to the design,
<View style={{flex: 1}}>
<View style={{flex:0.33,backgroundColor:"aqua",justifyContent:"center",alignItems:"center"}}>
<View style={{position:"absolute",backgroundColor:"grey",height:200,width:100,borderRadius:5,left:0.23*width,top:0.25*height}}/> {/*Represents the box where you add user name, profession etc */}
<View style={{backgroundColor:"yellow",height:50,width:50,borderRadius:25}}/> {/*Image tag goes here */}
</View>
</View>
I don't feel the necessity to add position:"absolute" prop for the profilePhotoContainerthe positioning can be controlled by flex principles. You may require only one view with position:"absolute" prop.
Do comment if you require further assistance.
Get some help from this-
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TouchableOpacity
} from 'react-native';
export default class Profile extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.header}></View>
<Image style={styles.avatar} source={{uri: 'https://bootdey.com/img/Content/avatar/avatar6.png'}}/>
<View style={styles.body}>
<View style={styles.bodyContent}>
<Text style={styles.name}>John Doe</Text>
<Text style={styles.info}>UX Designer / Mobile developer</Text>
<Text style={styles.description}>Lorem ipsum dolor sit amet, saepe sapientem eu nam. Qui ne assum electram expetendis, omittam deseruisse consequuntur ius an,</Text>
<TouchableOpacity style={styles.buttonContainer}>
<Text>Opcion 1</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonContainer}>
<Text>Opcion 2</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
header:{
backgroundColor: "#00BFFF",
height:200,
},
avatar: {
width: 130,
height: 130,
borderRadius: 63,
borderWidth: 4,
borderColor: "white",
marginBottom:10,
alignSelf:'center',
position: 'absolute',
marginTop:130
},
name:{
fontSize:22,
color:"#FFFFFF",
fontWeight:'600',
},
body:{
marginTop:40,
},
bodyContent: {
flex: 1,
alignItems: 'center',
padding:30,
},
name:{
fontSize:28,
color: "#696969",
fontWeight: "600"
},
info:{
fontSize:16,
color: "#00BFFF",
marginTop:10
},
description:{
fontSize:16,
color: "#696969",
marginTop:10,
textAlign: 'center'
},
buttonContainer: {
marginTop:10,
height:45,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginBottom:20,
width:250,
borderRadius:30,
backgroundColor: "#00BFFF",
},
});