How to set Background Image in Nextjs? - next.js

I'm using Nextjs and Material-Ui in my project, setting background image is not working as it did in other projects with react. It's my first time using Nextjs.
I've tried importing Image from "next/image" and using the
<Image height={} width={} />
but it's not working like background! I'd appreciate if you have any information about setting background in Nextjs with MUI.

Short answer: In fact, the path to the image is a relative path, and
the goal is to get the absolute path of the image.
To import the image as a background Image in NextJS page can be applied by various methods, but in this case, importing as an image file maybe is more suitable.
import myImage from "../public/imageName.png";
After the code is compiled the myImage will have an object that is considered the details of an image such as "src", "height", "width", and "blurDataURL".
Here is an example of what the object looks like.
{
"src": "/_next/static/media/imageName.7f7cc385.png",
"height": 7730,
"width": 7730,
"blurDataURL": "/_next/image?url=%2F_next%2Fstatic%2Fmedia%myImage.7f7cc385.png&w=8&q=70"
}
Finally, this can have a direct access to the image's absolute path via the src property of myImage object. By using the src property of the myImage, the following code demonstrates how to display an image located in the public folder by MUI Box Component.
<Box
height={789}
width={1440}
sx={{
background: `url(${myImage.src}) center / cover`,
}}
/>

jsx:
<div className={classes.pageContainer}>
//your code here
</div>
css class:
pageContainer: {
width: '100%',
height: '100vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
backgroundImage: 'url(IMAGEROUTE/IMAGENAME.svg)',
},

Related

How to give path/url for background image in tailwind?

I'm using Tailwind in my React Project. I want to add a background image in a div but it shows the following error:
Module not found: Error: Can't resolve '../../icons/blog-hero-1.png' in 'C:\Users\DELL\frontend-development\aidhumanity-practice-2\src'
I'm adding tailwind class
bg-[url('../../icons/blog-hero-1.png')]
for adding background image and url is relative to the current file and also it's working when added normal image through:
import Hero from "../../icons/blog-hero-1.png"
<div>
<img src={Hero} className="h-full rounded-3xl"></img>
</div>
Can anyone guide how to give the correct url?
Note: I've added a codesandbox example here as well for better demonstration in which I've tried to import background image in "Homepage.js" but it's not working.
https://codesandbox.io/s/background-image-wl9104?file=/src/components/Homepage.js
Well you can achieve the same result with the below approach as well:
In your tailwind.config.js file:
module.exports = {
theme: {
extend: {
backgroundImage: {
'hero': "url('../../icons/blog-hero-1.png')"
}
},
},
plugins: [],
}
You can simply mention bg-hero in you class to implement.

Why is my CSS not applied on child in React App (Next.js) using MUI styled

In my flex component I want to apply a marginRight between the child elements. The CSS is effective in development during hot reloading, but does not get applied when rendered with SSR although the page source contains the style.
const LineStyled = styled(FlexBox)(({theme}) => ({
width: '100%',
'& > *': {
display: 'block',
marginRight: theme.spacing(1)
}
}));
// Rendered style from page source.
<style data-emotion="css" data-s="">.css-x816gr>*{display:block;margin-right:8px;}</style>
// Rendered HTML from page source.
<div class="MuiBox-root css-x816gr"><p>...</p></div>
Upon first render the FlexBox contains a skeleton, and once data is loaded the children are rendered. Can this cause issues with styling and rerender?
Using Next.js 13 appdir with SSR.

How to style a map container with CSS using ReactJS

My map is implemented using MapLibre GL, but this issue also happens with Google Maps API or Mapbox GL.
I have the following ReactJS component:
import React, { useRef, useEffect } from "react";
import maplibregl from "maplibre-gl";
import map_style from "./style/style.json";
export default function Map() {
const mapContainer = useRef(null);
const map = useRef(null);
useEffect(() => {
if (map.current) return; //stops map from intializing more than once
map.current = new maplibregl.Map({
container: mapContainer.current,
style: map_style,
center: [12, 26],
});
});
return (
<div
ref={mapContainer}
className="my-map"
style={{ height: 500, width: 500 }}
/>
);
}
The above code renders the map, but I do not want a fixed height and width. I need to apply different styles depending on parent DOM elements, screen sizes, etc.
Problem is, right now if I assign a width and height in my CSS file, it's not being applied to the map. On the other hand, if I remove or change the syntax of style={{ height: 500, width: 500 }} in my ReactJS component, the map fails to display.
How can I style with CSS in this scenario?
The map library needs to read the container dimensions to compute the inner view.
As long as you provide explicit size, possibly through className, you should be fine.
Most mapping libraries also offer some API to request a re-read of the container dimensions, so that the view can be adjusted when the container is revealed or changes size (possibly for responsiveness). In the case of MapLibre GL JS, see resize() map method:
Resizes the map according to the dimensions of its container element.
Checks if the map container size changed and updates the map if it has changed. This method must be called after the map's container is resized programmatically or when the map is shown after being initially hidden with CSS.
A solution to get the map to render according to the parent div styling is to change the following code:
style={{ height: 500, width: 500 }}
to:
style={{ height: null, width: null }}
Now the map renders according to CSS styling for its related div.

What is the use of '& .MuiTextField-root' in { makeStyles } of Material UI?

I am making a project in React JS through some resources using Material-UI. I was creating in Form.js file for my app, and there was some styling given to that as shown below ---
import useStyles from './styles';
const classes = useStyles();
<form autoCapitalize='off' noValidate className={`${classes.root} ${classes.form}`} onSubmit={handleSubmit}> ```
In styles.js --
export default makeStyles((theme) => ({
root: {
'& .MuiTextField-root': {
margin: theme.spacing(1),
},
},
form: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'center',
}
}));
Now I am not able to understand the use of
'& .MuiTextField-root': {
margin: theme.spacing(1),
}
Can anyone please help me with this like what is the use of '& .MuiTextField-root' ??
When I try to simply use the
margin: theme.spacing(1),
its not giving margin from top and bottom, but its giving very less margin
from left and right. But using the Former one gives equal and more margin
from each side to all the textfields and Buttons in the . Why is it so?? Any help will be appreciated. Thanks!
Attaching the Screenshot ---FORM Image with '& .MuiTextField-root'
FORM Image WithOut '& .MuiTextField-root', just using root: {margin: theme.spacing(1)} only
If you know SCSS then this is the convention to select the child selector to write class for. As you are using it in a form. So the text fields are the child of the form. That's why you have to access/write it like this.
The following code actually mean, any child containing the class name MuiTextField-root will have the margin css rules in it. Doc
'& .MuiTextField-root': {
margin: theme.spacing(1),
}
& .MuiTextField-root would mean any children of current element with that class
You can use the browser dev tools to identify the slot for the component you want to override. It can save you a lot of time. The styles injected into the DOM by MUI rely on class names that follow a simple pattern: [hash]-Mui[Component name]-[name of the slot].
⚠️ These class names can't be used as CSS selectors because they are unstable, however, MUI applies global class names using a consistent convention: Mui[Component name]-[name of the slot].
If you would like to override the styles of the components using classes, you can use the className prop available on each component. For overriding the styles of the different parts inside the component, you can use the global classes available for each slot, as described in the previous section.

Override React AgGrid styling settings using createStyles and withStyles

I'm aware that it's possible to override Ag Grid properties by editing the CSS itself, however I'm wondering if it's possible to use the functionalities built into react to do this instead. I'm relatively new to the two frameworks, so apologies if there's something I'm not understanding.
Ultimately, what I want to do is something like this:
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
agHeaderCellLabel: {
agHeaderCellText: {
writingMode: 'vertical-lr',
marginTop: '100px',
},
},
})
export default styles
GridComponent.tsx
-----------------
import styles from './styles'
...
return (
<Paper className={classes.root}>
<div
id="myGrid"
style={{
height: '100%',
width: '100%',
}}
className={`ag-theme-material ${classes.agHeaderCellLabel}`}
>
<AgGridReact
// listening for events
onGridReady={onGridReady}
onRowSelected={onRowSelected}
onCellClicked={onCellClicked}
onModelUpdated={calculateRowCount}
// Data
columnDefs={cDef}
defaultColDef={defaultColumnFormat}
suppressRowClickSelection={true}
groupSelectsChildren={true}
debug={true}
rowSelection="multiple"
// rowGroupPanelShow={this.state.rowGroupPanelShow}
enableRangeSelection={true}
pagination={true}
rowData={rows}
/>
</div>
</Paper>
)
...
export withStyles(styles)(GridComponent)
In this example I'm just trying to get the header text to be displayed vertically.
I've inherited this project, and I've noticed that all of the styling has been done in this method, as there are no custom css files lying around, so I'm trying to stick with that convention of a styles file alongside the component.
Is this possible, and if so,
I ran into this same situation, and came up with the following solution. Although not necessarily ideal, it allows you to continue with the desired convention.
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
//Apply changes to agGrid material HeaderRoot
myClassAppliedToGrid: {
'& .ag-header[ref="headerRoot"]':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
//OR
//Apply Changes to agGrid material header row
myClassAppliedToGrid: {
'& .ag-header-row':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
})
export default styles
The key idea is using the & SASS syntax to "reach into" agGrid and make more specific CSS classes so you can override them. (see https://css-tricks.com/the-sass-ampersand/ for more info)
The key pieces of info are:
.parent {
& .child {}
}
turns into
.parent .child {}
and
.some-class {
&.another-class {}
}
turns into
.some-class.another-class { }
Using this sytanx, you should be able to create CSS classes that you can apply to your grid, columns, rows, etc that will properly override the material ag-grid theme.
Here is another example, but this class gets applied to a cell using agGrid cellStyleRules when a row is dragged over it, rather than applying the class to the grid as a whole. This way it only effects cells that have a row drag occuring over them:
rowDraggedOverCellsTopEdge: {
'&.ag-cell': {
borderTopColor: theme.palette.gray[50],
borderTopWidth: 8,
backgroundColor: fade(theme.palette.gray[50], 0.3)
}
},
Finally, one thing I did not do but would reccommend investigating is looking into agGrid's theme overriding, especially if you are on version 23+
https://www.ag-grid.com/javascript-grid-themes-provided/#customising-themes
It might be a good idea to get your base overrides to the theme done this way if you expect a consistent look and feel of your grids throughout the application.
Cheers!

Resources