1

I’m having an issue with React and using the material-ui library. My cards are getting rendered vertically instead of side by side horizontally. I tried messing around with the react grid component but it didn’t help.

Output: enter image description here

Expected: enter image description here

Here is the original code that perfectly renders cards side by side: https://github.com/acm-uic/roll-call/blob/feature/home-page/src/App.tsx

  return (
    <React.Fragment>
      <CssBaseline />
      <AppBar position="relative">
        <Toolbar>
          <Typography variant="h6" color="inherit" noWrap>
            ACM Roll Call
          </Typography>
        </Toolbar>
      </AppBar>
      <main>
        {/* Hero unit */}
        <div className={classes.heroContent}>
          <Container maxWidth="sm">
            <Typography component="h1" variant="h2" align="center" color="textPrimary" gutterBottom>
              ACM Roll Call
            </Typography>
            <Typography variant="h5" align="center" color="textSecondary" paragraph>
            The Association for Computing Machinery Student Chapter at the University of Illinois at Chicago (ACM@UIC) is a community for all UIC students interested in computing, computing machinery and related technologies.
            </Typography>

          </Container>
        </div>
        <Container className={classes.cardGrid} maxWidth="md">
          {/* End hero unit */}
          <Grid container spacing={4}>
            {cards.map(card => (
              <Grid item key={card} xs={12} sm={6} md={4}>
                <Card className={classes.card} raised>
                  <CardMedia
                    className={classes.cardMedia}
                    image="https://avatars3.githubusercontent.com/u/20177515?s=280&v=4"
                    title="Image title"
                  />
                  <CardContent className={classes.cardContent}>
                    <Typography gutterBottom variant="h5" component="h2">
                      Event Name
                    </Typography>
                    <Typography>
                      This is a media card. You can use this section to describe the content.
                    </Typography>
                  </CardContent>
                  <CardActions>
                    <Button size="small" color="primary">
                      View
                    </Button>
                    <Button size="small" color="primary">
                      Edit
                    </Button>
                  </CardActions>
                </Card>
              </Grid>
            ))}
          </Grid>
        </Container>
      </main>
      {/* Footer */}
      <footer className={classes.footer}>
        <Typography variant="h6" align="center" gutterBottom>
          ACM Roll Call
        </Typography>
        <Typography variant="subtitle1" align="center" color="textSecondary" component="p">
          Attendance tracking for events and meetings
        </Typography>
      </footer>
      {/* End footer */}
    </React.Fragment>
  );

I modified the original code since I had to fetch data for the cards. Here is the modified version in two separate files (Event.tsx & Events.tsx): https://github.com/acm-uic/roll-call/tree/feature/printEvents/src/components

return (



<React.Fragment>
<CssBaseline />

  <Container className={classes.cardGrid} maxWidth="md">
    {/* End hero unit */}
    <Grid container spacing={4}>
      {cards.map(card => (
        <Grid item key={card} xs={12} sm={6} md={4}>
          <Card className={classes.card} raised>
            <CardMedia
              className={classes.cardMedia}
              image="https://avatars3.githubusercontent.com/u/20177515?s=280&v=4"
              title="Image title"
            />
            <CardContent className={classes.cardContent}>
              <Typography gutterBottom variant="h5" component="h2">

              {summary ? summary : 'Busy'}

              </Typography>
              <Typography>

        <div>  
            {start ? (start.dateTime ? start.dateTime : start.date) : <></>} | {end ? (end.dateTime ? end.dateTime : end.date) : <></>} | {location}
        </div>

              </Typography>
            </CardContent>
            <CardActions>
              <Button size="small" color="primary">

                
                View
              </Button>
              <Button size="small" color="primary">
                Edit
              </Button>
            </CardActions>
          </Card>
        </Grid>
      ))}
    </Grid>
  </Container>


</React.Fragment>
    );

2 Answers 2

1

You can use MUI's autolayout feature on the Grid to help you customize your card rendering.

import React from 'react';
import { Grid } from '@material-ui/core';
import CardData from 'path to get your data'; // Data must be an array 

export default const Main = props => {
    return (
        <Grid container direction="row" justify="center" alignItems="center" spacing={3}>
            {
                CardData.map(data => (
                    <Grid item xs sm md lg key={data.key}>
                        <CustomCard data={data} />
                    </Grid>
                ))
            }
        </Grid>
    );
}

By just providing the property xs, md, sm, lg and xl without the numbering, MUI will do the stacking for you as equally as possible within the same row. So all you need to do is adjusting the size of your card content to allow for several card placement within the same row.

Sign up to request clarification or add additional context in comments.

Comments

0

I downloaded your repo and ran it on my machine. It only rendered AppBar so please let me know how to get the data to be displayed. However, I also looked at the code and I noticed one thing. We are looping through the events and rendering component like so:

 {(this.state.events && this.state.events.items)
    ? this.state.events.items.map((ev, key) =>
        (<Event key={key} ev={ev} />)) //render material card for each event
    : (<></>)}

But the <Container /> and <Grid /> components are being rendered from <Event /> component. It means that event cards will be contained in its own container and Grid. In my opinion, this is what could be causing the issue. If we pull container and Grid out of Event.tsx and put in inside Events.tsx then it might fix it.

e.g.,

<Container>
<Grid ..>
this.state.events.items.map((ev, key) =>
            (<Event key={key} ev={ev} />)) //render material card for each event
        : (<></>)}
</Grid .. />
<Container />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.