Material UI card rendering Issues with dynamic data from GraphQL - reactjs

I'm having issues with the Card rendering using Material UI in a GRANDstack application I'm building.
When I set the cards up with static data they render as expected:
const getMemsCard = (memID) => {
return (
<>
<Grid item xs={12} sm={4} lg={4} key={memID}>
<Card style={{ paddingTop: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
<Typography>Hi</Typography>
</CardContent>
</Card>
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
However, when I set them up with dynamic data from GraphQL they are rendering vertically as opposed to being in a grid:
const getMemsCard = (memID) => {
return (
<>
<Grid item xs={12} sm={4} lg={4} key={memID}>
{data.Mem.map(memID => (
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
))}
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
When I add a "row" property to the grid container to try and get them displayed in a grid, it makes them even worse:
const getMemsCard = (memID) => {
return (
<>
<Grid container direction: "row" item xs={12} sm={4} lg={4} key={memID}>
{data.Mem.map(memID => (
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
))}
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
I would like to get the cards to display like they do with the static data when I have added the dynamic data from GraphQL.

You are using {data.Mem.map(memID => ...)} inside an grid item so that's why it's not rendered as expected. Try this:
const getMemsCard = (memID) => {
return data.Mem.map(memID => (
<Grid item xs={12} sm={4} lg={4} key={memID}>
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
</Grid>
))
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >

Related

Put Clear Icon Card Material-UI in React

How do I put the clear icon on the card on the top right side of the card overlapping it.
What is the proper way to do it?
CLICK HERE = CODESANDBOX
<Paper
sx={{
padding: "1em",
background: "black"
}}
>
<IconButton color="error" aria-label="add to shopping cart">
<ClearIcon />
</IconButton>
<Grid
component="div"
container
spacing={2}
sx={{
marginBottom: "1em"
}}
>
<Grid component="div" item sm={12}>
<Alert>SUCCESS</Alert>
</Grid>
</Grid>
</Paper>;
Try this:
<Paper
sx={{
padding: "1em",
background: "black",
position: "relative"
}}
>
<IconButton
sx={{
position: "absolute",
top: "-15px",
right: "-15px",
// not necessary, just added this coz it looks weird
background: "white"
}}
color="error"
aria-label="add to shopping cart"
>
<ClearIcon />
</IconButton>
<Grid
component="div"
container
spacing={2}
sx={{
marginBottom: "1em"
}}
>
<Grid component="div" item sm={12}>
<Alert>SUCCESS</Alert>
</Grid>
</Grid>
</Paper>
What I did is simple, make the Paper position relative, then make the icon button absolute.
This way the button will follow whenever you move/animate the Paper.
The outcome would be something like this: https://wphyd.csb.app/

getting an error for Warning: Validating DOM nesting descendant of <p>

I am facing this issue. I had attached the code and error is in the DOM. Tried to fix the issue in various methods and ways but it's not fixing.
I am not able to know why it's getting DOM nesting I don't understand the exact issue in the code. Could anyone help with the solution
import React, { useRef, useState } from "react";
import AvatarEditor from "react-avatar-editor";
import Avatar from "#material-ui/core/Avatar";
import {MuiThemeProvider} from "#material-ui/core/styles";
import Slider from "#material-ui/core/Slider";
import { Grid, Button, Paper } from "#material-ui/core";
import ImageIcon from "#material-ui/icons/Image";
export default function Image() {
const [ state, setState ] = useState({
cropperOpen: false,
img: null,
remove: "",
zoom: 1,
croppedImg: "",
});
const editorRef = useRef(null);
const inputRef = useRef(null);
function handleZoomSlider(event, value) {
setState((prev) => ({ ...prev, zoom: value }));
}
function handleRemove() {
setState((prev) => ({ ...prev, croppedImg: null }));
}
function handleFileChange(e) {
window.URL = window.URL || window.webkitURL;
let url = window.URL.createObjectURL(e.target.files[0]);
inputRef.current.value = "";
setState((prev) => ({ ...prev, img: url, cropperOpen: true }));
}
function handleCancel() {
setState((prev) => ({ ...prev, cropperOpen: false }));
}
function handleSave() {
if (editorRef.current) {
const canvasScaled = editorRef.current.getImageScaledToCanvas();
const croppedImg = canvasScaled.toDataURL();
setState((prev) => ({ ...prev, cropperOpen: false, croppedImg }));
}
}
return (
<MuiThemeProvider>
<Grid container spacing={2} alignItems="center">
<Grid item xs={2} sm={2} md={2} lg={2} xl={2}>
<Avatar style={{ width: "90px", height: "90px" }} src={state.croppedImg} />
</Grid>
<Grid item xs={5} sm={5} md={4} lg={4} xl={3}>
<input
accept="image/*"
ref={inputRef}
onChange={handleFileChange}
id="Upload an Image"
type="file"
multiple
hidden
/>
<label htmlFor="Upload an Image">
<Button fullWidth variant="contained" color="secondary" component={"span"}>
Upload an Image
</Button>
</label>
</Grid>
<Grid item xs={5} sm={5} md={4} lg={3} xl={3}>
<input accept="image/*" onChange={handleRemove} id="Remove Image" multiple hidden />
<label htmlFor="Remove Image">
<Button fullWidth variant="outlined" color="secondary" component={"span"} onClick={handleRemove}>
Remove Image
</Button>
</label>
</Grid>
</Grid>
{state.cropperOpen && (
<Paper
style={{
position: "absolute",
left: "440px",
right: "100px",
top: "100px",
width: "30%",
background: "rgba(200,200,200,.8)",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
zIndex: "1",
}}
>
<Grid container justify="center">
<Grid
item
xs={12}
style={{
fontFamily: "Campaign",
fontSize: "20px",
fontWeight: "bold",
fontStretch: "normal",
fontStyle: "normal",
lineHeight: "1.6",
letterSpacing: "normal",
textAlign: "center",
color: "#181d1e",
height: "60px",
padding: "20px",
background: "#FFFFFF",
}}
>
<span>Create Profile Image</span>
</Grid>
</Grid>
<AvatarEditor
ref={editorRef}
image={state.img}
width={370}
height={400}
disableBoundaryChecks={true}
disableHiDPIScaling={true}
opacity={10}
border={1}
color={[ 255, 255, 255, 0.6 ]}
scale={state.zoom}
borderRadius={200}
/>
<Grid container justify="center" style={{ background: "rgba(255,255,255,0.8)" }}>
<Grid item xs={8} display="flex" justify="center" alignItems="center" container height="55px">
<ImageIcon />
<Slider
min={1}
max={10}
step={0.1}
value={state.zoom}
onChange={handleZoomSlider}
style={{ width: "150px", marginLeft: "10px" }}
/>
<ImageIcon fontSize="large" />
</Grid>
</Grid>
<Grid
container
justify="space-evenly"
alignItems="center"
style={{ background: "#FFFFFF", height: "60px" }}
>
<Grid item xs={5} sm={5}>
<Button
fullWidth
type="button"
variant="outlined"
color="primary"
onClick={handleCancel}
width="100%"
>
Cancel
</Button>
</Grid>
<Grid item xs={5} sm={5}>
<Button
fullWidth
type="button"
variant="contained"
color="secondary"
onClick={handleSave}
width="100%"
>
Save
</Button>
</Grid>
</Grid>
</Paper>
)}
</MuiThemeProvider>
);
}

Material UI grid items overflow their grid container on Safari

I ran into a problem on Safari browser where my Material UI Grid container does not hold its Grid item elements within it's boundaries. This seems to be a problem only for Safari browsers.
And here is my code for the page.
<Grid
item
container
direction="column"
justify="space-between"
className={classes.questionContainer}
>
<Grid item>
<Typography component="h1" variant="h1">
{question.text}
</Typography>
</Grid>
<Grid
item
container
xs={12}
justify="flex-start"
className={classes.btnBlock}
>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle1 || 'Yes'}
</Button>
</Grid>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle2 || 'No'}
</Button>
</Grid>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle3}
</Button>
</Grid>
</Grid>
</Grid>
const useStyles = makeStyles((theme: Theme) => ({
questionContainer: {
padding: theme.spacing(6, 6),
minHeight: '340px',
},
btnBlock: {
flexBasis: 0,
},
btnContainer: {
marginRight: '12px',
},
btn: {
fontSize: '16px',
lineHeight: '24px',
color: theme.palette.text.secondary,
padding: '10px 0',
width: '100%',
margin: '0 12px',
},
}))
Why is this happening and how can I fix that for Safari and not break for other browser?
Unfortunately, I do not have access to a Mac OS to test it myself properly
Can you try remove "item" in your Grid container?
<Grid
container
direction="column"
justify="space-between"
className={classes.questionContainer}
>

MUI Grid System

Currently using MUI grid system, and I am by no means an expert. I have currently have a grid that looks like this by default on you typical screen
if you make the screen a bit smaller all the way up until 600px the grid becomes mashed and looks kinda wonky like this
Once you get below 600 px the grid finally stacks like this
and I would like this desired effect to happen way before like around 900 px is there a way to achieve this??? Ive tried almost everything but the grid won't stack like i would like in the last picture. My grid is as follows:
<Grid
container
spacing={2}
className={classes.grid}
alignItems='center'
>
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ marginBottom: 20 }}
>
<Img
placeholder={BarhopPlace}
src={BarHop}
alt='barhop'
cache={false}
className={classes.image}
/>
</Grid>
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ width: "100%", textAlign: "center", padding: 0 }}
>
<Container
component='main'
maxWidth='xs'
style={{
marginBottom: 20,
visibility: ready ? "visible" : "hidden",
}}
>
<Typography
variant='h5'
variant='h5'
style={{ marginBottom: 10 }}
>
Bar Hop
</Typography>
<Typography variant='body2'>
A platform that provides users with the top drinking places
based on their location. Technologies used: ReactJS, NodeJS,
JavaScript, and the Yelp API .
</Typography>
<br />
<Box className={classes.alumniChips}>
<Tooltip
title='Please Note: Hosted on free tier of Heroku, site takes a few minutes to load'
aria-label='add'
>
<a
rel='noopener noreferrer'
href='https://barhop-wyncode.herokuapp.com/'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<LanguageIcon />}
label='View Site'
clickable
color='primary'
/>
</a>
</Tooltip>
<a
rel='noopener noreferrer'
href='https://github.com/Rterrell25/Bar_Hop_React_App'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<GitHubIcon />}
label='View Code'
clickable
color='primary'
/>
</a>
<BarHopModal />
</Box>
</Container>
</Grid>
<br />
<Divider style={{ width: "100%" }} />
<br />
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ marginTop: 20, marginBottom: 20 }}
>
<Img
placeholder={OddjobsPlace}
src={Oddjobs}
alt='oddjobs'
cache={false}
className={classes.image}
/>
</Grid>
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ width: "100%", textAlign: "center", padding: 0 }}
>
<Container
component='main'
maxWidth='xs'
style={{
marginBottom: 20,
visibility: ready ? "visible" : "hidden",
}}
>
<Typography
variant='h5'
variant='h5'
style={{ marginBottom: 10 }}
>
Odd Jobs
</Typography>
<Typography variant='body2'>
A platform that pairs consumers with reliable contractors.
Technologies used: ReactJS, Ruby on Rails, PostgreSQL, Calendly
Integration and Google Maps API.
</Typography>
<br />
<Box className={classes.alumniChips}>
<Tooltip
title='Please Note: Hosted on free tier of Heroku, site takes a few minutes to load'
aria-label='add'
>
<a
rel='noopener noreferrer'
href='https://oddjobs-react.herokuapp.com/'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<LanguageIcon />}
label='View Site'
clickable
color='primary'
/>
</a>
</Tooltip>
<a
rel='noopener noreferrer'
href='https://github.com/Rterrell25/Oddjobs_React_App'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<GitHubIcon />}
label='View Code'
clickable
color='primary'
/>
</a>
<OddjobsModal />
</Box>
</Container>
</Grid>
<br />
<Divider style={{ width: "100%" }} />
<br />
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ marginTop: 20 }}
>
<Img
placeholder={JobTrackerPlace}
src={JobTracker}
cache={false}
alt='JobTracker'
className={classes.image}
/>
</Grid>
<Grid
item
sm={6}
xs={12}
className={classes.grid}
style={{ width: "100%", textAlign: "center", padding: 0 }}
>
<Container
component='main'
maxWidth='xs'
style={{
marginBottom: 20,
visibility: ready ? "visible" : "hidden",
}}
>
<Typography variant='h5' style={{ marginBottom: 10 }}>
JobTracker
</Typography>
<Typography variant='body2'>
A platform that allows recent graduates from Wyncode Academy to
track job applications, store resume's, and monitor follow ups.
Technologies used: ReactJS, NodeJS, Google Cloud Functions, and
Google Firestore.
</Typography>
<br />
<Box className={classes.alumniChips}>
<a
rel='noopener noreferrer'
href='https://jobtracker.netlify.app/'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<LanguageIcon />}
label='View Site'
clickable
color='primary'
/>
</a>
<a
rel='noopener noreferrer'
href='https://github.com/Rterrell25/JobTracker_Client'
target='_blank'
style={{ margin: "1%" }}
>
<Chip
icon={<GitHubIcon />}
label='View Code'
clickable
color='primary'
/>
</a>
<JobTrackerModal />
</Box>
</Container>
</Grid>
</Grid>
Sorry for the long post!! Thanks!
All you should need to do is change sm={6} to md={6} (see https://material-ui.com/customization/breakpoints/#breakpoints). sm is 600px and up, md is 960px and up. Then your items will be full-width (12 columns) from 0px (xs) up till 960px (md).

How to catch when component is Hidden?

I want to know when Hidden works. I have a two component, categories and news.
When screen resolution is a xsUp i want to show boths. When categories is visible news component paddingLeft = categiries.Width, But xsDown i want to hide categories grid and news component paddingLeft make to 0.
This is how it works.
render() {
const { classes } = this.props;
let news = this.props.news.map((item, index) =>{
return (
<Zoom in={true} timeout={500}>
<Grid item lg={3} xs={12} sm={12} md={6} lg={4} key={item.uid} spacing={16}>
<Paper elevation={0} className={classes.paper}>
<RecipeReviewCard info={item} />
</Paper>
</Grid>
</Zoom>
)
});
return (
<div className={classes.root}>
<Grid container className={classes.root}>
<Grid item xs={12}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={this.state.alignItems}
direction={this.state.direction}
justify={this.state.justify}
>
<Hidden xsDown>
<Grid
item
lg={2}
md={4}
style={{
width: 270,
maxWidth: 280,
minWidth: 270,
position: 'absolute',
height: '100%',
zIndex: 1
}}>
<Categories />
</Grid>
</Hidden>
<Grid container item lg={12} md={12} spacing={16} style={{paddingLeft: 300, zIndex: 0}}
>
{news}
</Grid>
</Grid>
</Grid>
</Grid>
</div>
);
}
I found solution simple solution myself. I send my function for Categories component, And when Component didMounted or willUnmounted I send Boolean what happend.
Something like this:
Categories.js
componentDidMount = () => {
console.log('CREATED');
this.props.showFull(false);
};
componentWillUnmount = () => {
this.props.showFull(true);
}
Main.js
constructor(props) {
super(props);
this.state = {
direction: 'row',
justify: 'flex-start',
alignItems: 'stretch',
hidden: true
}
}
updateState = (ok) => {
this.setState({
hidden: ok,
});
console.log('updated ' + ' ' + ok);
}
return (
<div className={classes.root}>
<Grid container className={classes.root}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={this.state.alignItems}
direction={this.state.direction}
justify={this.state.justify}
>
<Hidden xsDown>
<Grid
item
lg={2}
md={4}
style={{
width: '100%',
maxWidth: 280,
minWidth: 0,
position: 'fixed',
height: '100%',
zIndex: 1,
}}>
<Categories showFull={this.updateState} />
</Grid>
</Hidden>
<Grid container item lg={12} md={12} spacing={16}
style={{paddingLeft: this.state.hidden ? 0 : 300, zIndex: 3}}
>
{news}
</Grid>
</Grid>
</Grid>
</div>
);

Resources