I'm currently trying to place a text over an image that is covering the entire page in react-pdf renderer. Does anyone know how to do this? Tried checking the issues in their docs and found this thread: https://github.com/diegomura/react-pdf/issues/1905 with no correct answers.
My code:
import { View, Page, Image, StyleSheet, Text } from "#react-pdf/renderer";
const styles = StyleSheet.create({
page: {
flexDirection: "row",
backgroundColor: "#fff",
width: "100%",
orientation: "portrait",
},
view: {
width: "100%",
height: "100%",
padding: 0,
backgroundColor: "white",
},
title: {
margin: 20,
fontSize: 25,
textAlign: "center",
textTransform: "uppercase",
},
});
export const IntroductionPage = () => (
<Page object-fit="fill" style={styles.page} size="A4">
<View style={styles.view}>
<Text style={styles.title}>HELLO WORLD</Text>
<Image src="https://images.unsplash.com/photo-1523047840906-018758c5ffa1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=3026&q=80" />
</View>
</Page>
);
I want to place the text HELLO WORLD over the image but instead it only renders on top and pushes the image down.
The best way that worked for me was using absolute positioning for Text components. Something similar to this
const styles = StyleSheet.create({
text: {
position: "absolute",
left: '0px',
right: '0px',
marginHorizontal: 'auto',
textAlign: "center",
justifyContent: 'center',
}
...
})
<Document >
<Page size="A4" style={styles.body}>
<View >
<Image src={invitation}></Image>
</View>
<Text style={{top:"350px", ...styles.text }} >
{details.groom}
</Text>
<Text style={{top:"450px", ...styles.text }} >
{details.bride}
</Text>
<Text style={{top:"550px",...styles.text,}} >
would love your presence to celebrate our wedding {"\n"}{"\n"}
Friday 30 August 2023 At 6:00 PM{"\n"}
At Sousse Municipality
</Text>
</Page>
</Document>
</PDFViewer>
The result ended up being like this (I ommited some code in this answer for readability but you can find my entire code in here https://codepen.io/daliovic/pen/VwdZwEo?editors=0010)
Related
I have a modal that contains various children components. One of them being a calendar component that is opened after pressing the text "Select Date"
Upon opening the Calendar component renders underneath the other components on the page.
I have tried using position: 'absolute' with a higher zIndex but I still cannot get the Calendar Component to render on top of everything else...how can I accomplish this?
JSX For the components
<View style={styles.container}>
<View style={styles.routineitems}>
<TouchableOpacity >
<Text style={{ }}>Due Date</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>calendarShouldShow(calendarVisible)}>
<Text style={{ }}>Select Date</Text>
</TouchableOpacity>
</View>
<Calendar style={{position: 'absolute',zIndex: 4}}/>
<View style={styles.routineitems}>
<Text>Tags</Text>
<DropDownPicker
placeholder="Tags"
/>
</View>
<View style={styles.routineitems}>
<Text>Notes</Text>
<TextInput
style={styles.input}
onChangeText ={ value => setNotes(value)}
value={notes}
laceholder="Notes"
textAlign={'right'}
/>
</View>
</View>
STYLESHEET
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
width: '100%'
},
routineitems: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: '90%',
marginBottom: '1%',
marginTop: '1%',
alignItems: 'center',
zIndex: 0
},
input: {
height: 40,
width: '30%',
borderRadius: 20,
backgroundColor: 'white',
fontSize: 50,
textAlignVertical:'bottom',
paddingTop: 0,
paddingBottom:0,
textAlign: 'right'
}
});
I'm using libraries: "react-native-svg": "12.1.0" & "react-native-svg-transformer": "0.14.3"
import FooIcon from '../assets/images/icons/fooIcon.svg';
<View style={{ flex: 1, paddingTop: 8 }}>
<FooIcon></FooIcon>
<View style={{ position: 'absolute', top: 35, bottom: 0, left: 14, right: 0 }} >
<Text>foo</Text>
</View>
</View>
How can I have "foo" text centered over the FooIcon. The solution above does not center the text which is important because "foo" text length can change and it has to be in center in every case.
this chunk of code should do the work for you
<View
style={{
justifyContent: 'center',
alignItems: 'center'
}}
>
<SVG /> //your svg image component goes here
<Text
style={{
position: 'absolute'
}}
>
Test
</Text>
</View>
I would recommend not to use an absolute position if the content size can change dynamically. I would build this with just using flex-box:
...
<View style={styles.itemContainer}>
<Text>Foo</Text>
<View style={styles.iconMock} />
</View>
...
const styles = StyleSheet.create({
itemContainer: {
alignItems: "center",
//this has default flex: 0, which means the container will always have the size the children take.
//we then tell it to centre all the children (items) which gives the needed effect.
},
iconMock: {
backgroundColor: "blue",
height: 50,
width: 150,
}
});
Building it this way the text will always be centred:
I've already added <Text></Text> tag after return(, after that the following error resurfaced adjacent tags must be enclosed <></>>
Error message: Text strings must be rendered within a <Text> component. Please request if you need the entire code.
The symbol & represents the error it located at container1:
import React, { Component } from "react";
import { Platform, StyleSheet, Text, View, Button } from "react-native";
import BoxContainer from './components/BoxContainer'
export default class App extends Component {
//Binding the function with class
buttonClickListener = () => {
alert("Clicked On Button !!!");
};
render() {
return (
<>
<Text style={styles.headerText}> </Text>
<View style={styles.page}>
<BoxContainer style={styles.container3}>
<View style={[{ width: 50, height : 60, backgroundColor: "orange" }]}>
<Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View></BoxContainer>
<BoxContainer style={styles.container1}>
<View style={{flexDirection:'row'}}>
<View style={[{ width: "7%", height :200,backgroundColor: "green" }]}>
<Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View>
<View style={[{ width: "92%", height :300, backgroundColor: "red" }]}>
/>
</MapView> <Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View> </View></View></BoxContainer>
<BoxContainer style={styles.container2}>
<View style={{flexDirection:'column'}}>
<View style={[{ width: 400, height :100, margin: 1, backgroundColor: "blue" }]}>
<Button
onPress={this.buttonClickListener}
title="Button One"
color="#00B0FF"
/>
</View>
<View style={[{ width: 400,height :90, margin: 1, backgroundColor: "black" }]}>
<Button
onPress={this.buttonClickListener}
title="Button Two"
color="#EC407A"
/>
</View>
<View style={[{ width: 400,height :80, margin: 1, backgroundColor: "red" }]}>
<Button
onPress={this.buttonClickListener}
title="Button Three"
color="#1DE9B6"
/>
</View></View></BoxContainer></View>
</>
);
}
}
const styles = StyleSheet.create({
page:{flex:1 ,alignItems: "left"},
container1: {&
flex: 7,
map: {position:'absolute'},
flexDirection: 'row',
justifyContent: "left",
alignItems: "left",
backgroundColor: "#F5FCFF"
},
container2: {
flex: 7,
flexDirection: 'column',
justifyContent: "left",
alignItems: "left",
backgroundColor: "#F5FCFF"
},
headerText: {
fontSize: 10,
textAlign: "center",
fontWeight: "bold"
},
});
In React Native, a string must be wrapped inside <Text> string</Text> component. As it needs to be mapped into native component accordingly which doesn't provide flexibility like HTML.
In React, string without <div> or any other component is possible. Since, HTML doesn't give errors on syntax mistake or these type of error.
The code you shared has multiple syntax errors, which makes it hard for me to be sure whether i'm looking at the real issue or not. For example, you close a MapView with </MapView>, but there's no MapView anywhere before that.
As best i can tell, the error is caused by this:
</View> </View>
Since you have a space in the middle of a line of JSX, it's trying to render that space. But in react native, text is only allowed inside a <Text> component.
To avoid these issues in the future, I'd recommend you use a tool such as Prettier or Eslint to format your code. By doing that, this would be split onto two lines, and in so doing any white space is irrelevant, because whitespace at the start and end of lines is ignored. The only way to get this error when formatting your code on two lines would be to do something like the following, which would make the error much more easy to spot:
</View>{" "}
</View>
Check that all your components you used are closed
and You have not declared MapView which will certainly
give an error.
And remove & from container 1.
You declared some extra tags of View and also you add MapView Closing tag but you are not adding starting tag. That's why you are facing this error. I remove that tag and also align you code.
Here is the code
import React, { Component } from "react";
import { Platform, StyleSheet, Text, View, Button } from "react-native";
import BoxContainer from './components/BoxContainer'
export default class App extends Component {
//Binding the function with class
buttonClickListener = () => {
alert("Clicked On Button !!!");
};
render() {
return (
<>
<Text style={styles.headerText}> </Text>
<View style={styles.page}>
<BoxContainer style={styles.container3}>
<View style={[{ width: 50, height : 60, backgroundColor: "orange" }]}>
<Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View>
</BoxContainer>
<BoxContainer style={styles.container1}>
<View style={{flexDirection:'row'}}>
<View style={[{ width: "7%", height :200,backgroundColor: "green" }]}>
<Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View>
<View style={[{ width: "92%", height :300, backgroundColor: "red" }]}>
<Button
onPress={this.buttonClickListener}
title="BUTTON1"
color="#00B0FF"
/>
</View>
</View>
</BoxContainer>
<BoxContainer style={styles.container2}>
<View style={{flexDirection:'column'}}>
<View style={[{ width: 400, height :100, margin: 1, backgroundColor: "blue" }]}>
<Button
onPress={this.buttonClickListener}
title="Button One"
color="#00B0FF"
/>
</View>
<View style={[{ width: 400,height :90, margin: 1, backgroundColor: "black" }]}>
<Button
onPress={this.buttonClickListener}
title="Button Two"
color="#EC407A"
/>
</View>
<View style={[{ width: 400,height :80, margin: 1, backgroundColor: "red" }]}>
<Button
onPress={this.buttonClickListener}
title="Button Three"
color="#1DE9B6"
/>
</View>
</View>
</BoxContainer>
</View>
</>
);
}
}
const styles = StyleSheet.create({
page:{flex:1 ,alignItems: "left"},
container1: {
flex: 7,
map: {position:'absolute'},
flexDirection: 'row',
justifyContent: "left",
alignItems: "left",
backgroundColor: "#F5FCFF"
},
container2: {
flex: 7,
flexDirection: 'column',
justifyContent: "left",
alignItems: "left",
backgroundColor: "#F5FCFF"
},
headerText: {
fontSize: 10,
textAlign: "center",
fontWeight: "bold"
},
});
Making a to-do list type thing to add in my app but when trying to align the 'add todo' button to the bottom right, the button goes anywhere but there.
I'm pretty good with CSS but get pretty messed up when using React CSS/styles. I've played around with different properties, giving a parent a style instead of the child etc.
The class is as follows
class AgendaScreen extends React.Component {
addReminder = () => {
//blank so far :)
};
render() {
return (
<View>
<Text style={styles.titleStyle}>Agenda</Text>
<View style={styles.reminderView}>
<TouchableOpacity style={styles.reminderTouch}>
<Text style={styles.reminderBtn}>+</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
and the styles here
//Agenda screen styles
reminderView: {
flex: 1,
justifyContent: 'flex-end',
},
reminderTouch: {
width: 60,
height: 60,
backgroundColor: 'orange',
borderRadius: 100,
textAlign: 'center',
margin: 20,
},
reminderBtn: {
fontSize: 50,
margin: 10,
alignSelf: 'flex-end',
},
The goal is to align the plus symbol in the middle of the circle and align that circle to the bottom right. With the pasted settings the circle is in the top left and the plus symbol is aligned to the bottom of the circle.
Also, the code posted above wasn't the closest I've gotten as I could easily do it with padding but I'd prefer to use flexbox.
Simply change your style replace with this style and Please add style to your top view
<View style={{flex:1}}>
<Text>Agends</Text>
<View style={styles.reminderView}>
<TouchableOpacity style={styles.reminderTouch}>
<Text style={styles.reminderBtn}>+</Text>
</TouchableOpacity>
</View>
</View>
reminderView: {
flex: 1,
right:0,
margin:5,
bottom:0,
position:'absolute'
},
reminderTouch: {
width: 60,
height: 60,
backgroundColor: 'orange',
borderRadius: 100,
justifyContent:'center',
alignItems:'center',
margin: 20,
},
reminderBtn: {
fontSize: 50,
margin: 5,
alignSelf: 'center',
}
Please check this snack.expo link
Here is how I would do it:
<View style={{
flex: 1,
justifyContent: 'center',
width:'100%',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}}>
<View
style={{
justifyContent:'center',
alignItems:"center",
width:65,
borderRadius:100,
height:65,
position:'absolute',
bottom:15,
right:15,
backgroundColor:"red",
elevation:10
}}
>
<Icon
name="plus"
size={25}
color="white"
/>
</View>
</View>
What it does is that it makes the round button float on the bottom right corner of the screen. Since you are making a todo app, you would want it to float over the todo list when it becomes longer.
https://snack.expo.io/#ammarahmed/rebellious-donuts
problem trying to make fit the image over some text which is like 2/3rd of the screen here's the link of image http://imgur.com/tuJPGqT
layout is designed like
<View style={styles.container} maintainAspectRatio={true} source={logotwo}>
<Container > <Image source={logo} maintainAspectRatio={true} style={styles.logo}>
</Image>
<View >
<Content >
<Text style={styles.boldtext}>SOME TITLE</Text>
<Text style={styles.subtext} adjustsFontSizeToFit={true} numberOfLines={3}>
A str agfdgdfgfdgfsdgsfdggdgfg(some long sentence) nance.</Text>
<View>
<Button style={styles.button}
onPress={() => { this._signIn() } }>
<Text style={{ fontSize: 20, color: '#fff' }}>
LOGIN
</Text>
</Button>
</View>
</Content>
</View>
</Container >
</View>
and style for the same is
container: {
resizeMode: 'cover', height: null,
backgroundColor: '#ffffff',
},
logo: {
width: null,
height: 398,
resizeMode: 'stretch',
},
boldtext: {
textAlign: 'center',
fontSize: 23,
fontWeight: 'bold',
}
,
subtext: {
marginLeft: 10,
marginRight: 10,
opacity: 0.7,
textAlign: 'center',
},
button: {
marginTop: 20,
alignSelf: 'stretch',
height: 70,
fontSize: 50,
}
i tried adjusting the width and height manually but resolution is not matched up with various screens i tested on.
Please suggest some good standard to follow the same for all screens in my app.