How can I fix the columns of the dynamic card? - reactjs

How can I make the card appear where there are 2 columns for the 1st card and then another 2 columns far the second card? So for, this is what it shows.
but I wanted it to look like this:
these are my codes for the styling:
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
padding: theme.spacing(2),
},
media: {
height: 300,
},
}));
and these are my codes for the card:
<div className={classes.root}>
<Grid
container
spacing={12}
direction="row"
justify="flex-start"
alignItems="center"
>
{data.map((elem) => (
<Grid item xs={12} sm={6} md={3} key={data.indexOf(elem)}>
<Card>
<CardHeader title={name} subheader={desc} />
<CardMedia
className={classes.media}
image={img}
title={name}
/>
</Card>
</Grid>
))}
</Grid>
</div>

It seems like the cards are stretched to full width, which prevents them from sharing the same flex-row.
There are lots of possible solutions to this. One could be to set a max-width on the cards so they don't fill the whole row. That way they would have space to sit besides each other like in your example.

Related

Having grid items display based on their size MUI Quilted Grid Layout

Image of Issue
Apologies for the zoomed out image, but I am using MUI in React to display a bunch of nested cards dynamically (The data has nested components rendering other components).
Each grid has cards that has grids within them and cards within the grids. I am trying to have the cards fit the page.
So in the image below, I would like the grid component on the second row and second column to come up to where the grid component on the first row second column ends.
I've been searching around trying to find the answer this question but a newbie to frontend so I am not sure how to phrase it. Any advice would be helpful!
Edit:
I am curious about making a quilted grid layout
const useStyles = makeStyles({
gridContainer: {
paddingLeft: "85px",
paddingRight: "85px",
},
root: {
minWidth: 200,
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
parentFlexRight: {
display: "flex",
justifyContent: "flex-end",
},
leftAlignItem: {
marginRight: "auto",
marginTop: "auto",
},
stretch: { height: "100%" },
item: {
display: "flex",
flexDirection: "column",
},
});
var checkIndex = 0;
const renderCourseRequirements = (RequiredCourses) => {
return (
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
>
{RequiredCourses.map((course, index) => {
var Index = checkIndex;
checkIndex = checkIndex + 1;
return (
<Grid key={index} item xs={12} sm={6} md={4}>
<Card sx={{ width: 200 }} variant="outlined">
<CardContent>
<Typography color="textSecondary" gutterBottom>
{course}
</Typography>
<Checkbox
id={`custom-checkbox-${Index}`}
name={course}
value={course}
checked={checkedState.includes(course)}
onChange={() => handleOnChange(course)}
/>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
);
};
const renderComponents = (components) => {
return (
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
>
{components.map((component, index) => {
return (
<Grid
container
spacing={0}
direction="column"
alignItems="stretch"
justifyContent="center"
key={index}
item
xs={12}
sm={6}
md={4}
>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
{component.component_name}
</Typography>
<Typography className={classes.pos} color="textSecondary">
Required Number of Courses: {component.required_num_courses}
</Typography>
{renderCourseRequirements(component.course_list)}
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
);
};
const renderComponentFamilies = (componentFamilies) => {
return (
<Grid container spacing={4} className={classes.item}>
{componentFamilies.map((componentFamily, index) => {
if (componentFamily.component_list.length > 1)
return (
<Grid key={index} xs={8} sm={6} md={4}>
<Card className={classes.stretch} variant="outlined">
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
{componentFamily.component_family_name}
</Typography>
<Typography className={classes.pos} color="textSecondary">
Required Number of Components :{" "}
{componentFamily.required_num_components}
</Typography>
{renderComponents(componentFamily.component_list)}
</CardContent>
</Card>
</Grid>
);
return (
<>
<Grid key={index} item xs={12} sm={6} md={4}>
{renderComponents(componentFamily.component_list)}
</Grid>
</>
);
})}
</Grid>
);
};
A couple of resources that may point you in the right direction. Setting some CSS breakpoints may also work with your content.
https://mui.com/system/sizing/
https://mui.com/material-ui/customization/default-theme/?expand-path=$.breakpoints.values
If that's not what you're looking for, I'd recommend wrapping your elements in an element that references a method with a 'resize' event listener that makes your preferred changes after the resize is triggered.

How do I align cards in center with MUI?

I've created a grid that displays cards using MUI, but the cards are 'stuck' to the left side of the page. I've tried justify='center', mx: 'auto' and alignItems='center' but the cards stay stuck to the left. I'm sure I'm using some prop that overrides my attempts, but I can't find documentation that speaks to my issue. Below is the code:
export default function Home() {
return (
<Box sx={{ flexGrow: 1, mt: 6 }}>
<Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 4, sm: 8, md: 12 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid item xs={2} sm={4} md={4} key={index}>
<ProductCard />
</Grid>
))}
</Grid>
</Box>
);
}
Below is what React is rendering.
you can to in grid like this:
<Grid item xs={2} sm={4} md={4} key={index} alignItems="center" justify="center">
<ProductCard />
</Grid>

How to contain images in react material ui CardMedia component

Certain images are much bigger and parts of them are hidden:
The closest I get in getting it right was by playing around with width and height:
const useStyles = makeStyles((theme) => ({
...
media: {
height: 100,
width: 100,
margin: 'auto',
},
...
}));
const Brands = (props) => {
...
return <div style={{ marginTop: props._marginTop }}>
<Grid container justify='center'>
<Grid item xs={10}>
<Grid container spacing={2}>
{brands.map((brand, i)=> {
return <Grid item key={i} lg={3} xs={12}>
<Card>
<CardMedia
className={classes.media}
image={brand.image.length > 0 ? brand.image : knightdemon}
title={brand.name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{brand.name.toUpperCase()}
</Typography>
<Typography
onClick={()=>setFlip(true)}
className={classes.description}
gutterBottom variant="body2"
component="p"
>
DESCRIPTION
</Typography>
</CardContent>
</Card>
</Grid>
})}
</Grid>
</Grid>
</Grid>
</div>
}
export default Brands;
Height looks good on all of them, the problem is with width and if I increase it it affects height as well.
How do I contain them in the given space so they look something like this:
To fit image in CardMedia, add props component="img" like:
<CardMedia
className={classes.media}
image={brand.image.length > 0 ? brand.image : knightdemon}
title={brand.name}
component="img"
/>
This should solve your problem.

How do I organise 5 items evenly in a row with material-ui's grid system?

The grid system is 12, how can I evenly put 5 items in a row? 2.4 doesn't work... Thanks in advance :)
my code:
<Grid container spacing={10}>
{data.map(item => (
<Grid item xs={12} md={2.4}>
<div style={{ fontWeight: "700", textTransform: "capitalize" }}>
{item}
</div>
</Grid>
))}
</Grid>
See the Auto Layout section from the docs for an example of how to do this.
For your code, I believe the following should work:
<Grid container spacing={10}>
{data.map(item => (
<Grid item xs={12} md> // should also add a "key" prop here
<div style={{ fontWeight: "700", textTransform: "capitalize" }}>
{item}
</div>
</Grid>
))}
</Grid>
You can try adding <Grid lg={12/5}></Grid. this case works if you want to show 5 elements in one row
Make your Grid container flex direct to raw and give each item xs={2} for all of them to fit, also you can add some spacing and center elements to container itself. In case you want each item be bigger then 2, consider wrap the row in a ScrollY custom component
<Grid container spacing={1} direction="row" justify="center" alignItems="center" >
{data.map(item => (
<Grid item xs={2}}>
<div style={{ fontWeight: "700", textTransform: "capitalize" }}>
{item}
</div>
</Grid>
))}
</Grid>
// optional ScrollY wrapper, use like <ScrollY> {data.map ...}</ScrollY>
const ScrollY = (props) =>
<div style={{overflowX:'hidden', overflowY: 'scroll',dispaly:'none', height: '80%'}}>
{props.children}
</div>

Material UI and Grid system

I'm playing a little bit with Material-UI. Are there any options for creating a grid layout (like in Bootstrap)?
If not, what is the way to add this functionality?
There is a GridList component but I guess it has some different purpose.
Material UI have implemented their own Flexbox layout via the Grid component.
It appears they initially wanted to keep themselves as purely a 'components' library. But one of the core developers decided it was too important not to have their own. It has now been merged into the core code and was released with v1.0.0.
You can install it via:
npm install #material-ui/core
It is now in the official documentation with code examples.
From the description of material design specs:
Grid Lists are an alternative to standard list views. Grid lists are
distinct from grids used for layouts and other visual presentations.
If you are looking for a much lightweight Grid component library, I'm using React-Flexbox-Grid, the implementation of flexboxgrid.css in React.
On top of that, React-Flexbox-Grid played nicely with both material-ui, and react-toolbox (the alternative material design implementation).
I looked around for an answer to this and the best way I found was to use Flex and inline styling on different components.
For example, to make two paper components divide my full screen in 2 vertical components (in ration of 1:4), the following code works fine.
const styles = {
div:{
display: 'flex',
flexDirection: 'row wrap',
padding: 20,
width: '100%'
},
paperLeft:{
flex: 1,
height: '100%',
margin: 10,
textAlign: 'center',
padding: 10
},
paperRight:{
height: 600,
flex: 4,
margin: 10,
textAlign: 'center',
}
};
class ExampleComponent extends React.Component {
render() {
return (
<div>
<div style={styles.div}>
<Paper zDepth={3} style={styles.paperLeft}>
<h4>First Vertical component</h4>
</Paper>
<Paper zDepth={3} style={styles.paperRight}>
<h4>Second Vertical component</h4>
</Paper>
</div>
</div>
)
}
}
Now, with some more calculations, you can easily divide your components on a page.
Further Reading on flex
I hope this is not too late to give a response.
I was also looking for a simple, robust, flexible and highly customizable bootstrap like react grid system to use in my projects.
The best I know of is react-pure-grid https://www.npmjs.com/package/react-pure-grid
react-pure-grid gives you the power to customize every aspect of your grid system, while at the same time it has built in defaults which probably suits any project
Usage
npm install react-pure-grid --save
-
import {Container, Row, Col} from 'react-pure-grid';
const App = () => (
<Container>
<Row>
<Col xs={6} md={4} lg={3}>Hello, world!</Col>
</Row>
<Row>
<Col xsOffset={5} xs={7}>Welcome!</Col>
</Row>
</Container>
);
The way I do is go to http://getbootstrap.com/customize/ and only check "grid system" to download. There are bootstrap-theme.css and bootstrap.css in downloaded files, and I only need the latter.
In this way, I can use the grid system of Bootstrap, with everything else from Material UI.
Below is made by purely MUI Grid system,
With the code below,
// MuiGrid.js
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import Grid from "#material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary,
backgroundColor: "#b5b5b5",
margin: "10px"
}
}));
export default function FullWidthGrid() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={0}>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
</Grid>
</div>
);
}
↓ CodeSandbox ↓
Here is example of grid system with material-ui which is similar to bootstrap:
<Grid container>
<Grid item xs={12} sm={4} md={4} lg={4}>
</Grid>
<Grid item xs={12} sm={4} md={4} lg={4}>
</Grid>
</Grid>

Resources