I have a MUI Modal set up, it's currently working, however the backdrop is being displayed as black. I have styling in place, but for some reason the backdrop is not being updated and remains pitch black.
My code is below, a screenshot is also below of what I see when the Modal is opened. Please let me know how I can fix this issue.
import { Box, Modal, Typography } from "#material-ui/core";
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
modalStyle: {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 300,
bgcolor: "background.paper",
boxShadow: 24,
p: 4,
backgroundColor: "white",
borderRadius: "10px",
},
}));
const PopupModal = ({ postModalOpen, handleClose, children }) => {
const classes = useStyles();
return (
<Modal open={postModalOpen} onClose={handleClose}>
<Box className={classes.modalStyle}>
ModalText
<Typography
id="modal-modal-title"
variant="h6"
component="h2"
style={{
fontSize: "14px",
marginLeft: "5px",
}}
>
{children}
</Typography>
</Box>
</Modal>
);
};
export default PopupModal;
If you'd like to style the backdrop, your styles must be passed to the Modal component directly:
For example:
const useStyles = makeStyles((theme) => ({
/** Changed modalStyle */
modalStyle: { backgroundColor: "rgba(255, 0, 0, 0.5)" },
/** Moved content styling to new class */
contentStyle: {
/** Also removed some invalid attributes **/
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "300px",
backgroundColor: "white",
borderRadius: "10px"
}
}));
const PopupModal = ({ postModalOpen, handleClose, children }) => {
const classes = useStyles();
return (
// Note the changed className props with your sample code
<Modal
open={postModalOpen}
onClose={handleClose}
className={classes.modalStyle}
>
<Box className={classes.contentStyle}>
<Typography
id="modal-modal-title"
variant="h6"
component="h2"
style={{
fontSize: "14px",
marginLeft: "5px"
}}
>
{children}
</Typography>
</Box>
</Modal>
);
};
Working Example: https://codesandbox.io/s/material-demo-forked-edhqx?file=/demo.js
FYI: You can also override all backdrops in your application, on a global scale, by passing a MuiBackdrop override object to createMuiTheme().
This is how I customized my MUI Backdrop (MUI v5)
<Backdrop open={isOpen} sx={{ backgroundColor: 'rgba(0, 0, 0, 0.25)', zIndex: 1 }} onClick={handleCloseMenu} />
Related
Newbie to React, have mercy on my soul.
I'm attempting to create a card with a Collapse component. Cool. I have the following ugly result:
now, once I expand the Collapse component, my bottom bottoms move a bit upwards,
making my ugly result even uglier:
If I turn on pesticide extension, I get the following result once expanded:
it seems like the item below pushes my like and review buttons upwards, or perhaps I'm wrong.
Now, what is weird for me is that my buttons are absolute. by my understanding, they're supposed to be 'relative' to their parents, and act as a 'free entity', so I don't get why would it be moved anyway?
The code for that component:
import React, { useContext, useState } from "react";
import { styled } from "#mui/material/styles";
import Card from "#mui/material/Card";
import CardHeader from "#mui/material/CardHeader";
import CardMedia from "#mui/material/CardMedia";
import CardContent from "#mui/material/CardContent";
import CardActions from "#mui/material/CardActions";
import Collapse from "#mui/material/Collapse";
import Avatar from "#mui/material/Avatar";
import IconButton from "#mui/material/IconButton";
import Typography from "#mui/material/Typography";
import { red } from "#mui/material/colors";
import FavoriteIcon from "#mui/icons-material/Favorite";
import ShareIcon from "#mui/icons-material/Share";
import ExpandMoreIcon from "#mui/icons-material/ExpandMore";
import ExpandLessIcon from "#mui/icons-material/ExpandLess";
import MoreVertIcon from "#mui/icons-material/MoreVert";
import ThumbUpIcon from '#mui/icons-material/ThumbUp';
import ThumbDownIcon from '#mui/icons-material/ThumbDown';
import AuthContext from "../Contexts/isLoggedIn-context";
import usersAndProductsContext from "../Contexts/usersAndProducts-context";
import RateReviewIcon from '#mui/icons-material/RateReview';
import Farmers from "../Pages/Farmers";
import { useNavigate } from "react-router-dom";
import { Paper } from "#mui/material";
import ReviewText from "./ReviewText";
import { Box } from "#mui/system";
import { ExpandLess } from "#mui/icons-material";
// import logo_img from "../../Images/logo.png";
const ExpandMore = styled((props) => {
const { expand, ...other } = props;
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? "rotate(0deg)" : "rotate(180deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
}));
function FarmerComponent(props) {
let navigate = useNavigate();
let authCtx = useContext(AuthContext)
let usersAndItemsCtx = useContext(usersAndProductsContext)
let [isWritingReviewFlag, edit_isWritingReviewFlag] = useState(false);
let current_logged_user = usersAndItemsCtx.usersVal.find(user => user.id === authCtx.currentLoggedUserId);
console.log(current_logged_user.likedProfilesId)
let flag = (current_logged_user.likedProfilesId.find((id) =>id === props.id) ? true : false)
console.log(flag)
let [isCurrentFarmerLikedFlag, isCurrentFarmerLikedFlagToggle] = useState(flag)
const [expanded, setExpanded] = React.useState(false);
// let [favouriteClicked, set_favouriteClicked] = useState(false);
const handleFavouriteClicked = () => {
let prevLikedStatus = isCurrentFarmerLikedFlag
if(isCurrentFarmerLikedFlag){
current_logged_user.likedProfilesId = current_logged_user.likedProfilesId.filter(userid => props.id !== userid)
isCurrentFarmerLikedFlagToggle(!prevLikedStatus)
}
else {
current_logged_user.likedProfilesId.push(props.id);
isCurrentFarmerLikedFlagToggle(!prevLikedStatus)
}
}
const handleExpandClick = () => {
setExpanded(!expanded);
};
const handleCardClick = () => { //choosing a farmer to view his shop/products.
navigate('/farmershop/'+props.id)
}
const handleNewReview = () => {
edit_isWritingReviewFlag(true)
}
return (
<Paper sx={{width: "300px", border: "none"}}>
{/* props===the farmer card we're on */}
{isWritingReviewFlag ? <ReviewText
edit_isWritingReviewFlag={edit_isWritingReviewFlag}
reviewingFarmer={current_logged_user}
reviewedFarmer={props}
/> : <></>}
<Card
sx={{
height: "600px",
width: "350px",
padding: "5px",
backgroundColor: "#D37C65",
marginTop: "20px",
marginLeft: "20px",
marginRight: "20px",
boxShadow: "5px 16px 5px 0px rgba(0,0,0,0.75)",
borderRadius: "7px",
border: "none",
padding: "50px"
}}>
<div onClick={handleCardClick} style={{marginTop: "10%", letterSpacing: "2px", fontFamily: "sans-serif", cursor: "pointer"}}><h1>{props.firstname + " " + props.lastname}</h1></div>
<CardMedia
component="img"
height="194"
image={props.img}
sx={{borderRadius: "5px"}}
title={props.firstname + " " + props.lastname}
onClick={handleCardClick}
style={{cursor: "pointer", backgroundColor: "#5CBEFD"}}
/>
<Box sx={{borderRadius: "5px", opacity: "80%", position: "relative"}}>
<Typography variant="body2" color="text.secondary" sx={{backgroundColor: "#5CBEFD"}}> <span>Location: {props.location}</span></Typography>
{expanded ? <></> : <Typography variant="body2" color="text.secondary" sx={{backgroundColor: "#5CBEFD"}}><span>more info...</span></Typography>}
<IconButton onClick={handleExpandClick}>
{expanded ? <ExpandLessIcon/> : <ExpandMoreIcon/> }
</IconButton>
<Box sx={{marginTop: "80%"}}>
<Collapse sx={{position: "absolute", marginTop: "-70%" }} in={expanded}>{props.about}</Collapse>
</Box>
</Box>
<Box sx={{position: "absolute", marginTop: "-5%"}}>
<CardActions>
<IconButton onClick={handleFavouriteClicked} aria-label="add to favorites">
{!isCurrentFarmerLikedFlag ? <ThumbUpIcon style={{color: "rgba(0, 194, 0, 1)"}}/> : <ThumbDownIcon style={{color: "rgba(255, 30, 127, 1"}}/> }
</IconButton>
<IconButton onClick={handleNewReview} sx={{display: "flex", alignItems: "center", flexWrap: 'wrap'}} aria-label="add review">
<RateReviewIcon/>
<span style={{letterSpacing: "1px", marginLeft: "3px", marginBottom: "5px", fontSize: "15px"}}>add new review</span>
</IconButton>
</CardActions>
</Box>
</Card>
</Paper>
);
}
export default FarmerComponent;
Many thanks!
React / Material-UI Novice here. I am trying to configure a set of buttons inside my app Bar that have a background picture to make it look a little cleaner. I have used a lot of code from examples online (shock) and got it to a place where i am happy with how it has formatted on a full size view (md++). However, when i downsize it to a small breakpoint though, the button image then stack instead (which is what i want) but i lose my text to the left. I have tried shifting to the right in many different ways but i dont think thats the right way to do it, is there something i am missing in making the text flex, i want the text to be in the middle?
import React from 'react'
import { AppBar, Toolbar } from "#mui/material";
import { makeStyles } from '#mui/styles'
import Button from '#mui/material/Button'
import Stack from '#mui/material/Stack'
import ButtonBase from '#mui/material/ButtonBase';
import { styled } from '#mui/material/styles';
import Typography from '#mui/material/Typography';
import Box from '#mui/material/Box';
const useStyles = makeStyles(theme => ({
button: {
...theme.typography.mainmenu,
borderRadius: "40px",
marginLeft: "1px",
height: "45px",
"&:hover": {
backgroundColor: theme.palette.secondary
}
},
}))
const images = [
{
url: '/assets/breakfastMenu.jpg',
title: 'Breakfast',
width: '33.33%',
},
{
url: '/assets/steak.jpg',
title: 'Mains',
width: '33.33%',
},
{
url: '/assets/desserts.jpg',
title: 'Desserts',
width: '33.33%',
},
];
const Image = styled('span')(({ theme }) => ({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
color: theme.palette.common.primary,
}));
const ImageButton = styled(ButtonBase)(({ theme }) => ({
position: 'relative',
height: 150,
[theme.breakpoints.down('sm')]: {
width: '100% !important', // Overrides inline-style
height: 100,
},
'&:hover, &.Mui-focusVisible': {
zIndex: 1,
'& .MuiImageBackdrop-root': {
opacity: 0.15,
},
'& .MuiImageMarked-root': {
opacity: 0,
},
'& .MuiTypography-root': {
border: '4px solid currentColor',
},
},
}));
const ImageSrc = styled('span')({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundSize: 'cover',
backgroundPosition: 'center 40%',
});
const ImageBackdrop = styled('span')(({ theme }) => ({
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundColor: theme.palette.common.black,
opacity: 0.4,
transition: theme.transitions.create('opacity'),
}));
const ImageMarked = styled('span')(({ theme }) => ({
height: 3,
width: 18,
backgroundColor: theme.palette.common.white,
position: 'absolute',
bottom: -2,
left: 'calc(50% - 9px)',
transition: theme.transitions.create('opacity'),
}));
const Header = () => {
const classes = useStyles();
return (<React.Fragment><AppBar position="sticky" className={classes.appBar}>
<Toolbar disableGutters className={classes.mainToolbar} sx={{ justifyContent: "center" }}>
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={10}>
{/* <Button variant="contained" color="secondary" className={classes.button}>Breakfast</Button>
<Button variant="contained" color="secondary" className={classes.button}>Mains</Button>
<Button variant="contained" color="secondary" className={classes.button}>Desserts</Button> */}
<Box sx={{ display: 'flex', flexWrap: 'wrap', minWidth: 900, width: '100%' }}>
{images.map((image) => (
<ImageButton
focusRipple
key={image.title}
style={{
width: image.width,
}}
>
<ImageSrc style={{
backgroundImage: `url(${image.url})`
}} />
<ImageBackdrop className="MuiImageBackdrop-root" />
<Image>
<Typography
component="span"
variant="subtitle1"
color="white"
fontWeight="bold"
sx={{
position: 'relative',
p: "7em",
pt: "2em",
pb: (theme) => `calc(${theme.spacing(1)} + 6px)`,
}}
>
{image.title}
<ImageMarked className="MuiImageMarked-root" />
</Typography>
</Image>
</ImageButton>
))}
</Box>
</Stack>
</Toolbar>
</AppBar>
</React.Fragment >
)
}
export default Header
I have moved on from this, but in case anybody finds it, using MUI i completely adapted my application by using:
import useMediaQuery from '#mui/material/useMediaQuery'
and some example like:
const matches = useMediaQuery(theme.breakpoints.down("md"))
to control when the application changes its styles
I have here a CircularLoader using Material UI.
My only problem is that if the variant is indeterminate then show the loader as is with no percentage while if it is determinate show the percentage inside the loader and the text as is.
Codesandbox: CLICK HERE
const CircularLoader = (props) => {
const {
height = "auto",
color = "primary",
text = "",
value = 0,
variant = "indeterminate"
} = props;
return (
<Grid
component="div"
container
justifyContent="center"
alignItems="center"
flexDirection="column"
sx={{ height }}
>
<CircularProgress
// variant={variant}
// value={value}
disableShrink
color={color}
thickness={4}
sx={{ marginBottom: "0.5rem" }}
/>
<Typography variant="body1" component="div" color={color}>
{text}
</Typography>
</Grid>
);
};
export default CircularLoader;
I think it's probably best to split these components up (since they have different props). But if you want them in the same component, you need to provide a dynamic value from 0-100 to the determinate variant. See the docs source code example.
In your case you could have a ternary choose between which variant to render, as a quick demo the following should work (note i'm ignoring value prop and simulating it with progress for demo purposes):
import React from "react";
import Grid from "#mui/material/Grid";
import Stack from "#mui/material/Stack";
import Typography from "#mui/material/Typography";
import CircularProgress from "#mui/material/CircularProgress";
import Box from '#mui/material/Box';
const CircularLoader = ({
height = "auto",
color = "primary",
text = "",
value = 0,
variant = "indeterminate"
}) => {
const [progress, setProgress] = React.useState(0);
React.useEffect(() => {
const timer = setInterval(() => {
setProgress((prevProgress) =>
prevProgress >= 100 ? 0 : prevProgress + 10
);
}, 800);
return () => {
clearInterval(timer);
};
}, []);
return (
<Grid
component="div"
container
justifyContent="center"
alignItems="center"
flexDirection="column"
sx={{ height }}
>
{variant === "indeterminate" ? (
<CircularProgress />
) : (
<Stack spacing={2} direction="row">
<Box sx={{ position: 'relative', display: 'inline-flex' }}>
<CircularProgress variant="determinate" value={progress}/>
<Box
sx={{
top: 0,
left: 0,
bottom: 0,
right: 0,
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Typography variant="caption" component="div" color="text.secondary">
{`${Math.round(progress)}%`}
</Typography>
</Box>
</Box>
</Stack>
)}
<Typography variant="body1" component="div" color={color}>
{text}
</Typography>
</Grid>
);
};
export default CircularLoader;
progress is just simulated in this case for demo purposes, whereas you need to pass down progress as value via props and use that in the CircularProgress component (it should be some dynamic value linked to actual loading progress state).
Link to Sandbox
I've just created a one page website portfolio and it is pretty much complete, but having issues with setting the background position of the home screen to center right. Here is my site:
https://berkley-portfolio.netlify.app/
My repo: https://github.com/Bolmstead/Portfolio
I just want the image of me to appear when resizing the window to mobile. I believe background-position would fix this right? The background size is cover, and I believe I am doing it correctly, but seem to be missing something. Below is my home component:
import React, { useEffect } from "react";
import Grid from "#material-ui/core/Grid";
import Typography from "#material-ui/core/Typography";
import { makeStyles } from "#material-ui/core/styles";
import Container from "#material-ui/core/Container";
const useStyles = makeStyles((theme) => ({
homeContainer: {
backgroundImage: `url(/images/home2.jpg)`,
height: "103vh",
backgroundSize: "cover",
backgoundPosition: "center right"
},
overlay: {
zIndex: 1,
height: "100%",
width: "100%",
backgroundSize: "cover",
background: "rgba(0, 0, 0, 0.5)",
},
firstName: {
fontWeight: "bold",
color: "white"
},
lastName: {
fontWeight: "bold",
color: "#FFC220"
},
caption: {
fontWeight: "bold",
color: "white"
},
}));
export default function Home() {
const classes = useStyles();
const [fadedIn, setFadedIn] = React.useState(false);
useEffect(() => {
async function fadeInHomeScreen() {
setFadedIn((prev) => !prev);
}
fadeInHomeScreen();
}, []);
return (
<Grid item xs={12} className={classes.homeContainer}>
<a id="Home">
<Grid
container
alignItems="center"
justify="center"
direction="row"
className={classes.overlay}
>
<Grid item xs={12} align="center" justify="center">
<Container maxWidth="md" align="center" justify="center" className={classes.container}>
<Typography
m={12}
variant="h2"
component="h2"
className={classes.firstName}
display="inline"
>
Berkley{" "}
</Typography>
<Typography
m={12}
variant="h2"
component="h2"
className={classes.lastName}
display="inline"
>
Olmstead
</Typography>
<Typography
m={12}
variant="h6"
component="h6"
className={classes.caption}
>
I'm a Full-Stack Developer
</Typography>
</Container>
</Grid>
</Grid>
</a>
</Grid>
);
}
You have a typo, backgoundPosition should be backgroundPosition
homeContainer: {
backgroundImage: `url(/images/home2.jpg)`,
height: "103vh",
backgroundSize: "cover",
backgroundPosition: "center right"
},
I'm new at react. I'm using media cards to present some picture and small text and have been trying to give small sliding animation to my text and background layer. However I failed. Codes are below:
import React, { useState, Component } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import CardActionArea from '#material-ui/core/CardActionArea';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Typography from '#material-ui/core/Typography';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
export default function SectionCard(props) {
const [areaHeight, setAreaHeight] = useState(100);
const [imgSize, setImgSize] = useState(1);
const [lineColor, setLineColor] = useState('dodgerblue');
const [textPosition, setTextPosition] = useState(0);
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: 345,
},
media: {
height: 400,
scale: imgSize,
},
greyCover: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
height: areaHeight,
width: '100%',
bottom: 0,
position: 'absolute',
},
line: {
backgroundColor: lineColor,
height: 5,
width: '100%',
borderRadius: 0,
},
textPosition: {
paddingTop: textPosition,
fontFamily: 'Quicksand !important',
color: 'white !important',
},
body: {
fontFamily: 'Quicksand !important',
},
}));
const classes = useStyles();
return (
<Grid item xs={12} sm={4} onMouseEnter={() => (setAreaHeight('100%'), setLineColor('red'), setImgSize(1.2), setTextPosition('150px!important'))} onMouseLeave={() => (setAreaHeight(100), setLineColor('dodgerblue'), setImgSize(1), setTextPosition('0px !important'))}>
<CardActionArea>
<CardMedia
className={classes.media}
image={props.img}
/>
<CardContent className={classes.greyCover} style={{ fontFamily: 'Quicksand', }}>
<div className={classes.textPosition}>
<Typography gutterBottom variant="h5" component="h2" align="center">
{props.title}
</Typography>
<Typography component="p" align="center">
{props.text}
</Typography>
</div>
</CardContent>
</CardActionArea>
<Paper className={classes.line} />
</Grid>
);
}
Codes are probably messy. Sorry for that. onMouseEnter and onMouseLeave are working fine. I just want to see that greyCover class and text moves slowly to height 100% and text to mid of the frame.
I didn't want to use another packages yet I don't know how to use too to be honest.
What I'm doing wrong?