Problem with 100vh, content larger than my browser window - reactjs

I need to make the content fit in the browser window, without showing the scroll bar, can someone help me?
I'm using Material-UI, follow the model in Sandbox.
screen
https://codesandbox.io/s/material-ui-grid-ylw6v?file=/src/App.js
Thanks for your help!

Try this css:
::-webkit-scrollbar {
display: none;
}

I managed to solve using the code posted on the link below.
https://github.com/mui-org/material-ui/issues/10739#issuecomment-817742141
Below is the code and the link in Sandbox.
import {
AppBar,
Box,
CssBaseline,
Grid,
IconButton,
makeStyles,
Toolbar,
Typography
} from "#material-ui/core";
import MenuIcon from "#material-ui/icons/Menu";
import "./styles.css";
const useStyles = makeStyles((theme) => {
/*
* This function creates a new object similar to `style`, but only keep
* `property` with the value set from `setNewValue`.
*
* For example given the `style`:
*
* const style = {
* minHeight: 56,
* '#media (min-width:0px) and (orientation: landscape)': { minHeight: 48 },
* '#media (min-width:600px)': { minHeight: 64 }
* }
*
* Then overrideExistingStyle(style, 'minHeight', (v) => v + 1) returns:
*
* {
* minHeight: 57,
* '#media (min-width:0px) and (orientation: landscape)': { minHeight: 49 },
* '#media (min-width:600px)': { minHeight: 65 }
* }
*
* We use overrideExistingStyel to dynamically compute the main content
* height. Since MUI AppBar minHeight depends on the screen size, We use
* overrideExistingStyel() to set the minHeight of the main content to (100vh
* - AppBar height).
*/
function overrideExistingStyle(style, property, setNewValue) {
return Object.fromEntries(
Object.entries(style)
.filter(([key, value]) => key === property || typeof value === "object")
.map(([key, value]) =>
typeof value === "object"
? [key, overrideExistingStyle(value, property, setNewValue)]
: [property, setNewValue(value)]
)
);
}
return {
main: {
display: "flex",
background: "#ccc",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px - (${theme.spacing(2)}px * 2))`
)
},
sidebar: {
width: 240,
background: "#F56638",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px)`
)
},
contentHeader: {
display: "flex",
background: "green",
height: theme.spacing(8)
},
box1: {
display: "flex",
background: "yellow",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px - (${theme.spacing(8)}px))`
)
},
box2: {
display: "flex",
background: "cyan",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px - (${theme.spacing(8)}px))`
)
},
box3: {
display: "flex",
background: "orange",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px - (${theme.spacing(8)}px))`
)
},
box4: {
display: "flex",
background: "gray",
...overrideExistingStyle(
theme.mixins.toolbar,
"minHeight",
(value) => `calc(100vh - ${value}px - (${theme.spacing(8)}px))`
)
}
};
});
export default function App() {
const classes = useStyles();
return (
<>
<CssBaseline />
<div className={classes.root}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
News
</Typography>
</Toolbar>
</AppBar>
<div className={classes.main}>
<Box className={classes.sidebar}>
<h3>Sidebar</h3>
</Box>
<Grid container className={classes.content}>
<Grid item xs={12}>
<Box className={classes.contentHeader}>
<h3>Content Header</h3>
</Box>
</Grid>
<Grid item xs={2}>
<Box flex={1} overflow="auto" className={classes.box1}>
<h3>Box 1</h3>
</Box>
</Grid>
<Grid item xs={2}>
<Box flex={1} overflow="auto" className={classes.box2}>
<h3>Box 2</h3>
</Box>
</Grid>
<Grid item xs={2}>
<Box flex={1} overflow="auto" className={classes.box3}>
<h3>Box 3</h3>
</Box>
</Grid>
<Grid item xs={6}>
<Box flex={1} overflow="auto" className={classes.box4}>
<h3>Box 4</h3>
</Box>
</Grid>
</Grid>
</div>
</div>
</>
);
}
https://codesandbox.io/s/material-ui-grid-ajustado-qlmcw?file=/src/App.js

Related

how place a button at the center of the image on hover with Material UI (MUI) and reacts?

I have tried looking online and there are some examples of hovering using material ui and more specifically there are some examples using the CardMedia from MUI but I am having trouble adapting it to my case.
I want to add transparency to the existing picture and add a button in the center when the user hovers over the image.
But so far this is the code I have:
const [Hover, setHover] = useState(false);
const handleMouseEnter = () => {
setHover(true);
}
const handleMouseLeave = () => {
setHover(false);
}
const Butt = <Button variant="contained">Get a Free Quote</Button>
return (
<Box p={5}>
<Grid container spacing={5} justify="center">
{images.map((product, i) => {
return (
<Grid key={i} item xs={12} sm={6} md={4}>
<Card sx={{ minWidth: 200 }}>
<CardMedia
component="img"
height="200"
image={product.img}
alt="work portfolio"
onMouseOver={handleMouseEnter}
onMouseOut={handleMouseLeave}/>
</Card>
{Hover && (
<div>
<Butt/>
</div>
)}
</Grid>
);
})}
</Grid>
</Box>
)
using useState you can toggle between display=none to not display the button on onMouseLeave and display=block to display the button onMouseEnter
this is an example using your code :
import React, { useState } from "react";
import "./style.css";
import Grid from "#material-ui/core/Grid";
import Button from "#material-ui/core/Button";
import Box from "#material-ui/core/Box";
import Card from "#material-ui/core/Card";
import CardMedia from "#material-ui/core/CardMedia";
const Butt = ({ display }) => {
return (
<div className={display}>
<Button
style={{
position: "absolute",
top: "80%",
left: "50%",
transform: "translate(-50%, -50%)",
}}
variant="contained"
>
Get a Free Quote
</Button>
</div>
);
};
export default function App() {
const [display, setDisplay] = useState("notdisplayed");
const showButton = (e) => {
e.preventDefault();
setDisplay("displayed");
};
const hideButton = (e) => {
e.preventDefault();
setDisplay("notdisplayed");
};
return (
<Box p={5}>
<Grid container spacing={5} justifyContent="center">
<Grid item xs={12} md={4} sm={6}>
<Card
sx={{ minWidth: 200 }}
style={{ position: "relative", width: "100%" }}
>
<div
onMouseEnter={(e) => showButton(e)}
onMouseLeave={(e) => hideButton(e)}
>
<CardMedia
style={{
marginLeft: "auto",
marginRight: "auto",
width: "100%",
height: "auto",
zIndex: "1",
}}
component="img"
height="200"
image="https://st.depositphotos.com/1001894/3115/i/600/depositphotos_31157709-stock-photo-hassan-ii-mosque-in-casablanca.jpg"
alt="work portfolio"
/>
<Butt display={display} />
</div>
</Card>
</Grid>
</Grid>
</Box>
);
}
add style.css to make these styling in it :
.notdisplayed {
display: none;
}
.displayed {
display: block;
}
this is a demo in codesandbox .
You can achieve the same with just css. Have a look at the code below and this working codesandbox
What it does is just creating a Container that has the image and the Button. Then I styled the button to be hidden initially and is shown when hovering on the container (which is your Card).
import * as React from "react";
import { styled } from "#mui/material/styles";
import Card from "#mui/material/Card";
import CardMedia from "#mui/material/CardMedia";
import Grid from "#mui/material/Grid";
import Button from "#mui/material/Button";
const ButtonStyled = styled(Button)`
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: fit-content;
height: 40px;
display: none;
`;
const ContainerStyled = styled("div")`
position: absolute;
&:hover {
.test-button {
display: block;
}
}
}`;
export default function RecipeReviewCard() {
return (
<Grid container spacing={5} justify="center">
<Grid item xs={12} sm={6} md={4}>
<ContainerStyled>
<Card sx={{ minWidth: 200 }}>
<CardMedia
component="img"
height="200"
image="https://mui.com/static/images/cards/paella.jpg"
alt="work portfolio"
/>
</Card>
<ButtonStyled variant="contained" className="test-button">
Test button
</ButtonStyled>
</ContainerStyled>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<ContainerStyled>
<Card sx={{ minWidth: 200 }}>
<CardMedia
component="img"
height="200"
image="https://mui.com/static/images/cards/paella.jpg"
alt="work portfolio"
/>
</Card>
<ButtonStyled variant="contained" className="test-button">
Test button 2
</ButtonStyled>
</ContainerStyled>
</Grid>
</Grid>
);
}
Let me know if it helps.

Get All TextField values from loop in Next.js when I press Submit button

first of all look at these below screenshots:
There are two tasks which I want to achieve:
There are two questions shown on the page using the array map method, by default I'm showing only one question, and when I press the next part button the second question will appear with the same question and a TextField (multiline). Now I've implemented a word counter in TextField but when I type something in 1st question the counter works properly. But when I go to the next question the here counter shows the previous question's word counter value, I want them to separately work for both questions.
When I click on the next part and again when I click on the previous part then the values from TextField are removed automatically. I want the values there if I navigate to the previous and next part questions. Also, I want to get both TextField values for a form submission when I press the Submit Test button.
Below are my codes for this page. I'm using Next.js and MUI
import { Grid, Typography, Box, NoSsr, TextField } from '#mui/material';
import PersonIcon from '#mui/icons-material/Person';
import Timer from '../../../components/timer';
import Button from '#mui/material/Button';
import { useState } from 'react';
import ArrowForwardIosIcon from '#mui/icons-material/ArrowForwardIos';
import { Scrollbars } from 'react-custom-scrollbars';
import AppBar from '#mui/material/AppBar';
import Toolbar from '#mui/material/Toolbar';
import ArrowBackIosIcon from '#mui/icons-material/ArrowBackIos';
import axios from '../../../lib/axios';
import { decode } from 'html-entities';
import { blueGrey } from '#mui/material/colors';
export default function Writing({ questions }) {
const [show, setShow] = useState(false);
const [show1, setShow1] = useState(true);
const [showQuestionCounter, setShowQuestionCounter] = useState(0);
const [wordsCount, setWordsCount] = useState(0);
return (
<>
<Box sx={{ flexGrow: 1 }}>
<AppBar position="fixed" style={{ background: blueGrey[900] }}>
<Toolbar>
<Grid container spacing={2} alignItems="center">
<Grid item xs={4} display="flex" alignItems="center">
<PersonIcon
sx={{ background: '#f2f2f2', borderRadius: '50px' }}
/>
<Typography variant="h6" color="#f2f2f2" ml={1}>
xxxxx xxxxx-1234
</Typography>
</Grid>
<Grid item xs={4} container justifyContent="center">
<Timer timeValue={2400} />
</Grid>
<Grid item xs={4} container justifyContent={'right'}>
<Button
variant="contained"
style={{ background: 'white', color: 'black' }}
size="small">
Settings
</Button>
<Button
variant="contained"
style={{
background: 'white',
color: 'black',
margin: '0px 10px',
}}
size="small">
Hide
</Button>
<Button
variant="contained"
style={{ background: 'white', color: 'black' }}
size="small">
Help
</Button>
</Grid>
</Grid>
</Toolbar>
</AppBar>
</Box>
<Box
sx={{
background: blueGrey[50],
height: '100%',
width: '100%',
position: 'absolute',
}}
pt={{ xs: 13, sm: 11, md: 10, lg: 11, xl: 11 }}>
{questions.map((question, index) =>
index === showQuestionCounter ? (
<Box
key={question.id}
px={3}
sx={{ background: '#f2f2f2', pb: 4 }}
position={{
xs: 'sticky',
sm: 'sticky',
lg: 'initial',
md: 'initial',
xl: 'initial',
}}>
<Box
style={{ background: '#f7fcff', borderRadius: '4px' }}
py={1}
px={2}>
<Box>
<Typography variant="h6" component="h6" ml={1}>
Part {question.id}
</Typography>
<Typography variant="subtitle2" component="div" ml={1} mt={1}>
<NoSsr>
<div
dangerouslySetInnerHTML={{
__html: decode(question.questions[0].question, {
level: 'html5',
}),
}}></div>
</NoSsr>
</Typography>
</Box>
</Box>
<Box
style={{
background: '#f7fcff',
borderRadius: '4px',
marginBottom: '75px',
}}
pt={1}
px={3}
mt={{ xs: 2, sm: 2, md: 2, lg: 0, xl: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={12} lg={6} md={6} xl={6}>
<Box
py={{ lg: 1, md: 1, xl: 1 }}
style={{ height: '50vh' }}>
<Scrollbars universal>
<Typography
variant="body1"
component="div"
style={{ textAlign: 'justify' }}
mr={2}>
<NoSsr>
<div
dangerouslySetInnerHTML={{
__html: decode(question.question_text, {
level: 'html5',
}),
}}></div>
</NoSsr>
</Typography>
</Scrollbars>
</Box>
</Grid>
<Grid
item
xs={12}
sm={12}
lg={6}
md={6}
xl={6}
mt={{ md: 4, lg: 4, xl: 4 }}>
<TextField
id={`${question.id}`}
label="Type your answer here"
multiline
name={`answer_${question.id}`}
rows={12}
variant="outlined"
fullWidth
helperText={`Words Count: ${wordsCount}`}
onChange={(e) => {
setWordsCount(
e.target.value.trim().split(/\s+/).length
);
}}
/>
</Grid>
</Grid>
</Box>
</Box>
) : null
)}
<Box sx={{ position: 'fixed', width: '100%', left: 0, bottom: 0 }}>
<Grid
container
style={{ background: blueGrey[300], display: 'flex' }}
py={2}
px={3}>
<Grid
item
xs={3}
sm={3}
lg={6}
md={6}
xl={6}
container
justifyContent={'start'}>
<Button
variant="contained"
style={{ background: 'white', color: 'black' }}
size="small">
Save Draft
</Button>
</Grid>
<Grid
item
xs={9}
sm={9}
lg={6}
md={6}
xl={6}
container
justifyContent={'end'}>
<Button
variant="contained"
size="small"
style={{
background: 'white',
color: 'black',
visibility: show1 ? 'visible' : 'hidden',
}}
endIcon={<ArrowForwardIosIcon />}
onClick={() => {
setShow((prev) => !prev);
setShowQuestionCounter(showQuestionCounter + 1);
setShow1((s) => !s);
}}>
Next Part
</Button>
{show && (
<>
<Box>
<Button
variant="contained"
style={{
background: 'white',
color: 'black',
margin: '0 10px',
visibility: show ? 'visible' : 'hidden',
}}
startIcon={<ArrowBackIosIcon />}
size="small"
onClick={() => {
setShow1((s) => !s);
setShowQuestionCounter(showQuestionCounter - 1);
setShow((prev) => !prev);
}}>
previous Part
</Button>
<Button variant="contained" color="success">
Submit Test
</Button>
</Box>
</>
)}
</Grid>
</Grid>
</Box>
</Box>
</>
);
}
export async function getServerSideProps(context) {
const { id } = context.query;
const token = context.req.cookies.token;
if (!token) {
context.res.writeHead(302, {
Location: '/',
});
context.res.end();
}
const res = await axios.get(`test/${id}/questions`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (res.data.success) {
return {
props: {
questions: res.data.data.questions,
},
};
}
}
The wordsCount state is shared between both questions, which means that when you go to the next question the state remains unchanged and shows the wordsCount from the first question. To solve it, each question needs to have it's own state which you can do by creating a Question component and mapping over it:
export default function Question({ question }) {
const [wordsCount, setWordsCount] = useState(0)
return (
<Box
// ...
>
{/* ... */}
<TextField
// ...
helperText={`${wordsCount} words`}
onChange={(e) => {
setWordsCount(e.target.value.trim().split(/\s+/).length)
}}
/>
{/* ... */}
</Box>
)
}
Then map over it:
{questions.map((question, index) =>
index === showQuestionCounter ? (
<Question key={question.id} question={question} />
) : null
)}
Currently, the value of TextField gets reset you the component is unmounted (i.e. when you go to the next question). You need to make the TextField component a controlled component, meaning that you store the value of the field in useState. And if you need to submit the value of TextField later, then you probably need to store the values in the parent component:
export default function Writing({ questions }) {
// ...
const [answers, setAnswers] = useState([])
function handleChange(id, answer) {
// copy the current answers
let newAnswers = [...answers]
// find the index of the id of the answer in the current answers
const index = newAnswers.findIndex((item) => item.id === id)
// if the answer does exist, replace the previous answer with the new one, else add the new answer
if (index) {
newAnswers[index] = { id, answer }
setAnswers(newAnswers)
} else {
setAnswers([...answers, { id, answer }])
}
}
return (
<>
{/* ... */}
{questions.map((question, index) =>
index === showQuestionCounter ? (
<Question
key={question.id}
question={question}
value={answers.find((item) => item.id === question.id)?.answer || ''}
handleChange={handleChange}
/>
) : null
)}
</>
}
In the Question component, add the handler.
export default function Question({ question, value, handleInputChange }) {
const [wordsCount, setWordsCount] = useState(0)
return (
<Box>
{/* ... */}
<TextField
helperText={`${wordsCount} words`}
value={value}
onChange={(e) => {
handleInputChange(question.id, e.target.value)
setWordsCount(e.target.value.trim().split(/\s+/).length)
}}
/>
{/* ... */}
</Box>
)
}
In the parent component (Writing) you should be able to use the values for form submission.

Use Refs In Material UI

I'm trying to use Refs in Material UI to change Image src but it gives me an 'Undefined' error. It looks like the link is getting created but not being applied as the Images src, I feel like the problem lies in line 10 .
CodeSandBox - https://codesandbox.io/s/complexgrid-material-demo-forked-h6zfqh?file=/demo.tsx
const [loading] = useState(true);
const imageRef = React.useRef();
let txt = "IGO";
useEffect(() => {
imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
console.log(imageRef.current.src);
},
[loading, imageRef]);
<ButtonBase sx={{ width: 128, height: 128 }}>
<Img alt="complex" ref={imageRef} />
</ButtonBase>
You can use a list of references an change the image like you was doing.
I let you a functional code that it works like I think you want :)
import * as React from "react";
import { styled } from "#mui/material/styles";
import Grid from "#mui/material/Grid";
import D34, { useEffect, useState } from "react";
import Paper from "#mui/material/Paper";
import Typography from "#mui/material/Typography";
import ButtonBase from "#mui/material/ButtonBase";
import Data from "./abc.json";
const Img = styled("img")({
margin: "auto",
display: "block",
maxWidth: "100%",
maxHeight: "100%"
});
export default function ComplexGrid() {
const [loading] = useState(true);
const imagesRef = [];
let txt = "IGO";
useEffect(() => {
imagesRef.forEach((refImg) => {
refImg.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
});
/*imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
console.log(imageRef.current.src);*/
}, [loading]);
return (
<div className="hello">
{Data.response.map((post, posPost) => {
return (
<Paper
sx={{
pt: 1,
border: 1,
boxShadow: 0,
mt: 1,
maxWidth: 900,
flexGrow: 1,
backgroundColor: (theme) =>
theme.palette.mode === "dark" ? "#1A2027" : "#fff"
}}
>
<Grid container spacing={2}>
<Grid item>
<ButtonBase sx={{ width: 128, height: 128 }}>
<Img alt="complex" ref={(imageRef) => {
if (!imagesRef[posPost]) {
imagesRef.push(imageRef);
}
}} />
</ButtonBase>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
gutterBottom
variant="subtitle1"
component="div"
>
Standard license
</Typography>
<Typography variant="body2" gutterBottom>
Full resolution 1920x1080 • JPEG
</Typography>
<Typography variant="body2" color="text.secondary">
ID: 1030114
</Typography>
</Grid>
<Grid item></Grid>
</Grid>
<Grid item>
<Typography
variant="subtitle1"
component="div"
sx={{ px: 2, p: 2 }}
>
$19.00
</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
);
})}
</div>
);
}
you can use useState to change the src
const [img, setImg] = useState()
let txt = "IGO";
useEffect(() => {
setImg(`https://flightaware.com/images/airline_logos/90p/${txt}.png`)
}, [loading]);
{img && <Img alt="complex" src={img} />}
The main problem is the way to use ref.
At the moment, you are using same ref for same image component.
In order to manage the image tags well, you should use different ref for each image tab.
Please refer this code.
import * as React from "react";
import { styled } from "#mui/material/styles";
import Grid from "#mui/material/Grid";
import D34, { useEffect, useState } from "react";
import Paper from "#mui/material/Paper";
import RootRef from "#material-ui/core/RootRef";
import Typography from "#mui/material/Typography";
import ButtonBase from "#mui/material/ButtonBase";
import Data from "./abc.json";
import { red } from "#mui/material/colors";
const Img = styled("img")({
margin: "auto",
display: "block",
maxWidth: "100%",
maxHeight: "100%"
});
export default function ComplexGrid() {
const [loading] = useState(true);
const imageRef = React.useRef();
let txt = "IGO";
useEffect(() => {
console.log(imageRef.current.src);
if (imageRef.current.src === "")
imageRef.current.src = `https://flightaware.com/images/airline_logos/90p/${txt}.png`;
}, [loading, imageRef]);
return (
<div className="hello">
<Img alt="complex" ref={imageRef} />
{Data.response.map((post) => {
return (
<Paper
sx={{
pt: 1,
border: 1,
boxShadow: 0,
mt: 1,
maxWidth: 900,
flexGrow: 1,
backgroundColor: (theme) =>
theme.palette.mode === "dark" ? "#1A2027" : "#fff"
}}
>
<Grid container spacing={2}>
<Grid item>
<ButtonBase sx={{ width: 128, height: 128 }}>
{/* <Img alt="complex" ref={imageRef} /> */}
</ButtonBase>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
gutterBottom
variant="subtitle1"
component="div"
>
Standard license
</Typography>
<Typography variant="body2" gutterBottom>
Full resolution 1920x1080 • JPEG
</Typography>
<Typography variant="body2" color="text.secondary">
ID: 1030114
</Typography>
</Grid>
<Grid item></Grid>
</Grid>
<Grid item>
<Typography
variant="subtitle1"
component="div"
sx={{ px: 2, p: 2 }}
>
$19.00
</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
);
})}
</div>
);
}
Hope it would be helpful for you.
Thanks

Putting gradient background using makeStyles

For some reason, it doesn't respect background: 'linear-gradient(to right, blue.200, blue.700)' under makeStyles. Why is that? All I need to do is put a gradient background on the entire space. <Container className={classes.root}> should probably be a div, what do you think?
import { useState, useEffect } from 'react';
import type { NextPage } from 'next';
import Container from '#mui/material/Container';
import Box from '#mui/material/Box';
import { DataGrid, GridColDef } from '#mui/x-data-grid';
import { createStyles, Grid, Paper, Theme, Typography } from '#mui/material';
import { makeStyles } from '#mui/styles';
import Skeleton from '#mui/material/Skeleton';
import FormOne from './../src/FormOne';
const LoadingSkeleton = () => (
<Box
sx={{
height: 'max-content',
}}
>
{[...Array(10)].map((_, index) => (
<Skeleton variant="rectangular" sx={{ my: 4, mx: 1 }} key={index} />
))}
</Box>
);
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID' },
{ field: 'title', headerName: 'Title', width: 300 },
{ field: 'body', headerName: 'Body', width: 600 },
];
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
height: '100vh',
overflow: 'auto',
background: `linear-gradient(to right, blue.200, blue.700)`,
},
})
);
const Home: NextPage = () => {
const classes = useStyles();
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
// fetch data from fake API
useEffect(() => {
setInterval(
() =>
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => {
setPosts(data);
setLoading(false);
}),
3000
);
}, []);
return (
<Container
maxWidth={false}
// sx={{
// height: '100vh',
// overflow: 'auto',
// background: `linear-gradient(to right, ${blue[200]}, ${blue[700]})`,
// }}
className={classes.root}
>
<Container component="main" maxWidth="lg" sx={{ mt: 3, mb: 3 }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
<Grid item xs={6}>
<Paper sx={{ padding: 3 }}>
<Typography component="h1" variant="h4" align="center">
GUI #1
</Typography>
<FormOne />
</Paper>
</Grid>
<Grid item xs={6}>
<Paper sx={{ padding: 3 }}>
<Typography component="h1" variant="h4" align="center">
GUI #2
</Typography>
<FormOne />
</Paper>
</Grid>
<Grid item xs={12}>
<Paper sx={{ padding: 3 }}>
<DataGrid
sx={{ height: '650px' }} // either autoHeight or this
rows={posts}
columns={columns}
pageSize={10}
// autoHeight
rowsPerPageOptions={[10]}
disableSelectionOnClick
disableColumnMenu
disableColumnSelector
components={{
LoadingOverlay: LoadingSkeleton,
}}
loading={loading}
/>
</Paper>
</Grid>
</Grid>
</Container>
</Container>
);
};
export default Home;
I think its because you pass it as a string and it simply doesnt recognice what blue.200 is etc.
try:
background: `linear-gradient(to right, ${blue[200]}, ${blue[700])}`,
#Edit
You actualy need to import color that you want to use from #mui/color
import { blue } from "#mui/material/colors";
and then use it as I mentioned before
here is codesandbox preview and here is codesandbox code
hope this is what we want to achieve
Instead of using background use backgroundImage. This should fix the problem.
The code should be
backgroundImage: `linear-gradient(to right, blue[200], blue[700])`,

Update className attribute

For the avatarColor I am selecting a random color AKA -> rendomColor.
render() {
const { classes } = this.props;
let colorArr = [classes.redAvatar, classes.greenAvatar, classes.blueAvatar, classes.redAvatar];
const usersListedItems = this.state.ownersArr.map((owner, index) => {
return (
<Grid item xs={6} sm={3} key={owner.ownerId}>
<UsersListedItems
ownerId={owner.ownerId}
userName={owner.userName}
avatarColor={colorArr[Math.floor(Math.random() * colorArr.length)]}>
</UsersListedItems>
</Grid>
)
How can I update (in UsersListedItems component) the card style borderColor with the same random color that I calculated for the avatar?
const styles = (theme) => ({
root: {
flexGrow: 1,
},
card: {
borderRadius: '14px',
border: '1px solid',
borderColor: ?????
},
});
........
return (
<Card className={classes.card}>
<CardHeader
avatar={
<Avatar id="av" aria-label="Recipe" className={this.props.avatarColor}>
Thank you
There may be other ways, but at least you can do it through styles specifically:
<Card
className={classes.card}
style={{
borderColor: this.props.avatarColor
}} >
<CardHeader
avatar={
<Avatar id="av" aria-label="Recipe" className={this.props.avatarColor}>

Resources