How to fill an entire page with one image in react-pdf? - html

I am trying to make one pdf page as one base64 image using react-pdf in my reactjs web application.
and I have tried everything that I know of for making the image as an A4 size
image and fill the image completely so that one image comes as one entire page in react-pdf
I have tried width:100%, height:100%, object-fill, tried to increase the size.
but so far I am unsuccessful.
Right now the image comes on center and does not make it to all the corners in the page.
import React, { Component } from 'react'
import ReactPDF, { Page, Text, View, Document, StyleSheet , Font, Image,} from '#react-pdf/renderer';
import pic from "../pics/pic.jpeg"
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#fff',
width:"100%",
orientation:"portrait"
},
image: {
width: '100%',
height:"100%",
padding: 10,
backgroundColor: 'white',
},
});
// Create Document Component
export default class ImageToPDF extends Component {
render() {
return (
<Document >
<Page object-fit="fill" style={styles.page} size="A4">
<View object-fit="fill" style={styles.image}>
<Image object-fit="fill" style={{ padding:"0, 0, 0, 0", margin:"33%, 2rem, 2rem, 2rem",
transform: 'rotate(90deg)'}} src={pic} alt="images" />
</View>
</Page>
</Document>
)
}
}
Expected output: One image comes as one page in the pdf using react-pdf.
Actual result: one image comes in the middle of a page using react-pdf and has a lot of margin on all four sides
Thanks a lot for the help. I really appreciate it

A bit late i guess, but maybe someone else can be helped by this.
I think the code below will do the trick.
I've altered a few things:
The view element had padding, i removed it.
applied objectFit to the image element, I would suggest to use "cover" instead of "fill".
Let me know if this helped.
import React, { Component } from 'react'
import ReactPDF, { Page, Text, View, Document, StyleSheet, Font, Image } from '#react-pdf/renderer';
import pic from "../pics/pic.jpeg"
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#fff',
width: '100%',
orientation: 'portrait',
},
view: {
width: '100%',
height: '100%',
padding: 0,
backgroundColor: 'white',
},
image: {
objectFit: 'cover',
},
});
// Create Document Component
export default class ImageToPDF extends Component {
render() {
return (
<Document >
<Page object-fit="fill" style={styles.page} size="A4">
<View style={styles.view}>
<Image style={styles.image} src={pic} alt="images" />
</View>
</Page>
</Document>
);
};
};

Related

elements in react are always at the bottom of the page

I am creating a airline reservation system using mern stack
I did the navbar and all is well but everytime I add a div or an element in general it's outside the page and I have to style it to be at the position I want it
I want the buttons to be in the middle of the page without forcing it using style
EDIT 1: here is my navbar element
import React from "react";
import { Component } from 'react';
import './style.css';
import background from "./background.jpg";
import SideBar from "./sidebar";
export default class Navbar extends Component {
showSettings (event) {
event.preventDefault();
}
render () {
// NOTE: You also need to provide styles, see https://github.com/negomi/react-burger-menu#styling
return (
<div id="App" style = {{ backgroundImage: `url(${background})`, backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
position:"relative",
width: '100vw',
height: '100vh' }}>
<SideBar pageWrapId={"page-wrap"} outerContainerId={"App"} />
</div>
);
}
}
try to change position from relative to absolute

How do I get deck.gl and react-map-gl to display correctly?

Here is a code sandbox example where I am trying to display a map inside of a specific component. But, I am not able to get the deck.gl and react-map-gl divs to live inside their parent. instead, they spill out to the extent of the document body.
The basic layout of the example is:
<Box id='mapcontainer'>
<DeckGL id="deck-gl">
<MapView id="map" >
<StaticMap/>
</MapView>
</DeckGL>
</Box>
It appears that Deck.gl is creating a <div> and a <canvas> element between the <Box id='mapcontainer'> div and the <DeckGL id='deck-gl'> div, and I can not get the div and canvas to live inside of their parent Box.
The id of the <div> and the <canvas> appear to be created from the id passed into the DeckGL component, id="deck-gl-wrapper" and id="deck-gl" respectively. Where "deck-gl" is the id I passed into the <deckGL> component.
That may or may not be the actual problem, but using the elements inspector in devtools that is my best guess right now.
Can anyone help me figure out why deck.gl and react-map-gl components are not living within their parent bounds? Even when I set the parent and/or canvas props in the DeckGL component?
Documentation links:
react-map-gl
deck.gl
A functioning example is included in the codesandbox linked above. I have included many of the things I have tried as comments but no luck so far.
https://codesandbox.io/s/deck-gl-and-mui-react-e3t23?file=/src/App.js
Thank you...
For local quick reference, the app.js file looks something like this.
import Box from "#material-ui/core/Box";
import DeckGL from "#deck.gl/react";
import { MapView } from "#deck.gl/core";
import { LineLayer } from "#deck.gl/layers";
import { StaticMap } from "react-map-gl";
const MAPBOX_ACCESS_TOKEN = <tokenInCodeSandboxIfYouNeedIt>
const INITIAL_VIEW_STATE = {
longitude: -122.41669,
latitude: 37.7853,
zoom: 13,
pitch: 0,
bearing: 0
};
const data = [
{
sourcePosition: [-122.41669, 37.7853],
targetPosition: [-122.41669, 37.781]
}
];
function App() {
return (
<Box
id='mapcontainer'
sx={{
border: 1,
height: 450,
width: "auto",
m: 5
}}
>
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={true}
id="deck-gl"
>
<LineLayer id="line-layer" data={data} />
<MapView
id="map"
controller={false}
>
<StaticMap
mapStyle="mapbox://styles/mapbox/dark-v9"
mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN}
/>
</MapView>
</DeckGL>
</Box>
);
}
export default App;
In order to allow the deck.gl component to take up the available space of the parent component you can add position: 'relative' into the overrides for your Box with an id of mapcontainer.

ReactJS - How To Setup 3 Divs One On-Top Of The Other?

Disclaimer:
I'm new to ReactJS, and web-development as a whole. Did my best to research before, and did not find an answer.
I'm probably missing something simple, but can't figure it out - so sorry if this question's answer is a one liner "How-Did-I-Miss-That' sort of answer.
Feel free to comment/answer with best practices I missed, or things I can improve in this question.
Thanks is advance to anybody that reads this!
My Own Research:
Float 3 Divs - I did not need the z-axis property, as non of my divs are on top of the other.
3 Divs LTR - Talks about 3 divs aligned horizontally, not vertically. The same method did not work for me in the vertical axis.
3 Divs LTR #2 - This talks about flex, so I tried it too. In the right direction, but not enough.
Vertical Align etc - could not make it happen with this solution either.
(5... 1000) A bunch of other first-second-third results in Google search queries like: "ReactJS vertical 3 divs" and the likes.
Actual Question:
Trying to make a basic outline of a mockup web-page, which consists of 3 divs:
Header Div - In The Top, Not Sticky (=when you y axis scroll, it does not appear).
Content Div - In The Middle, Y/X Axis Scrollable.
Bottom Nav Div - In The Bottom, Sticky.
Mockup:
My Current Status:
Can't make my bottom-menu div to appear. it's stuck under the frame.
Can't be sure my bottom-menu div is actually sticky because of the point above.
The contents tab div has no margin from the Header div, which makes the upper end of the text in it - unreadble.
My Code:
Did a lot of back-and-fourth on this, and this is the closest version I have for this simple (yet - not working!) task:
App.jsx
import React from "react";
import BottomMenu from "../BottomMenu/BottomMenu";
import Header from "../Header/Header";
import ContentTab from "../ContentTab/ContentTab";
const App = () => {
return (
<div style = {{display: "flex", flexDirection: "column", overflow: "visible",
direction: "rtl"}}>
<Header/>
<ContentTab />
<BottomMenu />
</div>
);
};
export default App;
Header.jsx
import React from "react";
import { Toolbar, AppBar } from "#material-ui/core";
import Typography from '#material-ui/core/Typography';
const Header = props => {
return (
<div>
<AppBar color="primary" style={{alignItems: 'center'}}>
<Toolbar>
<Typography>
Test
</Typography>
</Toolbar>
</AppBar>
</div>
);
};
export default Header;
ContentTab.jsx
import React from "react";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
const ContentTab = (props) => {
return (
<div style={{height: "80%", width: "100%"}}>
<Paper align="center" elevation={3}>
<Typography paragraph>First</Typography>
<Typography paragraph>TextTab</Typography>
<Typography paragraph>Last</Typography>
</Paper>
</div>
);
};
export default ContentTab;
BottomMenu.jsx
import React from "react";
import BottomNavigation from "#material-ui/core/BottomNavigation";
import BottomNavigationAction from "#material-ui/core/BottomNavigationAction";
import RestoreIcon from "#material-ui/icons/Restore";
import FavoriteIcon from "#material-ui/icons/Favorite";
import LocationOnIcon from "#material-ui/icons/LocationOn";
import { Toolbar, AppBar } from "#material-ui/core";
export default function BottomMenu() {
const [value, setValue] = React.useState(0);
return (
<div style={{
position: "fixed", bottom: "0", width: "100%", height: "10%"}}>
<AppBar
style={{ background: '#FFFFFF', alignItems: "center" }}
>
<Toolbar>
<BottomNavigation
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
>
<BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
<BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
<BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} />
</BottomNavigation>
</Toolbar>
</AppBar>
</div>
);
}
Actually; the issue is that you're using the Material-UI component AppBar. If this were just a regular DIV tag then you could position it the way you want. To use the AppBar component and make it do what you what then this should do the trick:
remove the outer DIV on the BottomMenu component
style the BottomMenu component's appBar with top of auto and bottom of 0 and give it a position property of fixed.
additionally, style the Header component's appBar with position of static.
this:
in BottomMenu:
<AppBar
position="fixed"
style={{
top: "auto",
bottom: "0",
background: "#FFFFFF",
alignItems: "center"
}}
>
in Header:
<AppBar
position="static"
color="primary"
style={{ alignItems: "center" }}
>
Here's a link to the docs that show it doing what you want:
https://material-ui.com/components/app-bar/
and here's a link to a code sandbox with your code.
https://codesandbox.io/s/material-ui-with-bottom-appbar-ugk31
In general, what I've found with Material-UI is that some of their components have positioning logic built into them and you need to use their properties for positioning instead of trying to do it with CSS.

Using Material UI, how to get two images to stack vertically to the right of another larger image?

Suppose I have three images. One is twice the height of the other two and I would like to design a simple grid where the two smaller ones stack vertically to the right of the larger one. The aspect ratios of the photos means they will work in a five-column layout if the larger one takes up 2 rows x 3 columns and the smaller ones take up 1 row x 2 columns. I'm using the Material UI GridList component (https://material-ui.com/api/grid-list/) and following the API documentation. No matter what settings I use, one of the smaller images renders to the right of the larger one, then there is a equal-sized tile of blank space below it, and the third image stacks vertically underneath the larger one to the left.
I suspect this is not React-specific, but some simple HTML or CSS problem I'm not familiar with. I guess I was expecting the component to do this automatically. In the demo (https://material-ui.com/demos/grid-list/) it automatically fills in horizontal space with images, but now that I'm looking, it does not appear do the same for vertical space.
import React, {Component} from "react";
import ReactDOM from 'react-dom';
import GridList from '#material-ui/core/GridList';
import GridListTile from '#material-ui/core/GridListTile';
import GridListTileBar from '#material-ui/core/GridListTileBar';
export class ImageGrid extends React.Component{
constructor(props){
super(props);
}
render() {
const tileData = [
{
img: "ex_1.jpg",
title: 'Image',
author: 'author',
cols: 3,
rows:2,
},
{
img: "ex_3.jpg",
title: 'Image',
author: 'author',
cols: 2,
rows:1,
},
{
img: "ex_2.jpg",
title: 'Image',
author: 'author',
cols: 2,
rows:1,
},
];
const styles = theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
backgroundColor: theme.palette.background.paper,
},
gridList: {
width: 1384,
height: 320,
float:right,
},
});
return (
<div className={styles.root}>
<GridList component='div' cellHeight={150} spacing={8} cols={5} className={styles.gridList}>
{tileData.map(tile => (
<GridListTile component='div' cols={tile.cols} rows={tile.rows} key={tile.img}>
<img src={tile.img} alt={tile.title} />
<GridListTileBar
title={tile.title}
subtitle={tile.author}
/>
</GridListTile>
))}
</GridList>
</div>
);
}
}

HTML element is cut off when exceeding right boundary on screen

I have a website where I use a table to display some data. The issue is that when I view the website on smaller screens, the table is cut off and not all of the content is displayed. You can see below that despite me scrolling all the way to the right, the right most field is only barely visible and cut off by the screen.
I seem to partly be able to fix this by the width css parameter in root but if I set width too high, is just adds unnecessary right margin.
import React from 'react';
import {ListUsersTableRow} from "./listUserTableRow";
import { withStyles } from 'material-ui/styles';
import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table';
import Paper from 'material-ui/Paper';
const styles = theme => ({
root: {
[theme.breakpoints.up('md')]: {
width: `calc(100% - 140px)`,
},
marginTop: theme.spacing.unit * 3,
overflowX: 'auto',
},
table: {
minWidth: 700,
},
});
export const ListUsersTable = (props) => {
const { classes } = props;
return (
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Edit</TableCell>
<TableCell>Full name</TableCell>
<TableCell>Username</TableCell>
<TableCell>Email</TableCell>
<TableCell>Company</TableCell>
<TableCell>Contact Number</TableCell>
<TableCell>Role</TableCell>
<TableCell>Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.users.map(user => <ListUsersTableRow key={user.id} {...user} toggleEdit={props.toggleEdit}/>)}
</TableBody>
</Table>
</Paper>
)
};
export default withStyles(styles)(ListUsersTable);
min-width is causing your table to be at least as wide as 700.
Try something simple like width: 100%;
If width:100%; messes up your side menu, you may want to consider setting the width of the menu to something like 30% instead of, say, 240px. With your menu taking up 30% of the page, and your table taking up the other 70%, things should fit a little better.
Rough guess without working example, though.