Well I wanted to leave a page with 100% screen height
without scroll bar:
const SignIn = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={2} direction="column" justify="center" alignItems="center" >
<Grid item lg={12} md={12} sm={12} xs={12} >
<img src={require("../nodejs-icon.svg")} alt="bug" height={100} />
</Grid>
</Grid>
</div>
);
}
and my css:
const loginStyle = (muiBaseTheme => ({
root:{
background: "#000",
minHeight: '100vh',
}
}));
But i'm getting a horizontal and vertical scroll bar like this:
enter image description here
Use:
const loginStyle = (muiBaseTheme => ({
root:{
background: "#000",
minHeight: '100vh',
overflow: 'hidden',
}
}));
to hide the scroll bars.
Related
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.
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
I have this component that contains a card and inside this card there are elements and I want to separate them through a vertical line and the problem is that the vertical line does not work.
const useStyles = makeStyles((theme: Theme) =>
createStyles({
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
}
}),
);
const SpaceForm: FC = (props) => {
const classes = useStyles()
const workspaceData = useWorkspaceModule((state) => state.workspace)
console.log("inside component 1: ", workspaceData);
return (
<>
<Grid
container
spacing={3}
>
<Grid
item
lg={8}
md={6}
xs={12}
>
<Card>
<CardHeader title="Name your Workspace:"/>
<CardContent>
<Avatar style={{width: '3.4rem', height: '3.4rem'}} className={classes.orange}>N</Avatar>
{/*llll*/}
<Divider style={{ backgroundColor:'red'}} orientation="vertical" flexItem />
</CardContent>
</Card>
</Grid>
</Grid>
</>
);
};
export default SpaceForm;
You just wrap Avatar inside a flex Box and it will show Divider after Avatar:
<Box display="flex">
<Avatar
style={{ width: "3.4rem", height: "3.4rem" }}
className={classes.orange}
>
N
</Avatar>
{/*llll*/}
<Divider
style={{ backgroundColor: "red" }}
orientation="vertical"
flexItem
/>
</Box>
I have 2 grids and I want one of them to be a black background and one to be a white background, both of these backgrounds are set in a theme in the app.js. Im wanting to use theme.palette.common.black or theme.palette.common.white if i pass in a white tag prop inside the second grid. Im trying to use a ternary statement but not sure how to implement it.
const styles = (theme) => ({
root: {
background: theme => theme.palette.common ? "black" : "white",
// background: theme.palette.common.black,
// background: theme.palette.common.white,
},
});
const HomePage = ({ classes }) => (
<>
<FullScreenBanners>
<Grid
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone SE</Typography>
<Typography>From £10.99/mo. or £279 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
<Grid
white
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone 7</Typography>
<Typography>From £7/mo. or £200 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
</FullScreenBanners>
</>
);
I hope I haven't misunderstood your question.
Wouldn't it be easier to just have two different classes - a standard one (root) and one for the white background (e.g. white)? Then, instead of passing in a 'white' prop to one of your Grid elements, you can just apply the second class name.
const useStyles = makeStyles({
root: {
background: theme.palette.common.black,
},
white: {
background: theme.palette.common.white,
},
});
const HomePage = () => {
const classes = useStyles();
return (
<>
<FullScreenBanners>
<Grid
//give this one just the root class
className={classes.root}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone SE</Typography>
<Typography>From £10.99/mo. or £279 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
<Grid
//give this one the root class and the white class
className={`${classes.root} ${classes.white}`}
container
spacing={0}
alignItems="center"
justify="center"
direction="column"
>
<Typography>iPhone 7</Typography>
<Typography>From £7/mo. or £200 with trade-in.</Typography>
<LearnMoreBuy />
<img src="./images/iphone-se.jpg" />
</Grid>
</FullScreenBanners>
</>
);
};
When I try compiling the app it displays a certain error "TypeError:undefined has no properties" though I want to render styled components into the grid tags though in function based component method
const styles = theme => ({
root: {
height: '100vh',
},
image: {
},
paper: {
margin: theme.spacing(8, 4),
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%',
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
});
const SignIn = (props) => {
const classes = this.props;
return(
<Grid container component="main" className={classes.root}>
<CssBaseline />
<Grid item xs={false} sm={4} md={7} className={classes.image} />
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Welcome to web
</Typography>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<form className={classes.form} noValidate>
//content
</form>
</div>
</Grid>
</Grid>
);
}
export default withStyles(styles)(SignIn);
Access or destructure classes from props, not this.props.
const { classes } = props;
You can also destructure props right in the function definition.
const SignIn = ({ classes }) => {...