Alex
Alex

Reputation: 323

Material UI, make Cards appear in a row, instead of 1 column

I'm trying to use flex to make my Cards appear side by side. However, they are still appearing in a column. My goal is to make the cards appear 4 in a row, and as 1 column on mobile.

Is there a better approach I should be taking?

Code snippet:

<div className={classes.root}>
                {loading ?
                            (filterProducts.map((a, index) => (
                              <Grid
                                container
                                spacing={2}
                                direction="row"
                                justify="flex-start"
                                alignItems="flex-start"
                              >
                                <Grid item xs={3}>
                                  <Card className={classes.cardSize}>
                                    <CardContent>
                                        <Link to={`/Item/${a.id}`}>
                                          <div key={index} className="productStyle">
                                            <CardMedia
                                              component="img"
                                              image={require(`../images/${a.image}`)}
                                             />
                                            <p>{a.title}</p>
                                            <p>${priceUSD(a.price)}</p>
                                          </div>
                                        </Link>
                                    </CardContent>
                                  </Card>
                              </Grid>
                            </Grid>
                          )))

                          : (<ReactBootStrap.Spinner className="spinner" animation="border" />)
                          }
      </div>

Full code for context

import React, { useState, useEffect } from 'react';
import './../App.css';
import * as ReactBootStrap from 'react-bootstrap';
import {Link} from 'react-router-dom';
import {Grid, Paper, CssBaseline, Button, Typography, useMediaQuery, useTheme} from '@material-ui/core';
import {makeStyles} from '@material-ui/core/styles';
import TopMenu from './TopMenu';
import BottomMenu from './BottomMenu';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';

function Shop() {

const [products, setProducts] = useState([]);
const [filterProducts, setFilteredProducts] = useState([]);
const [item, setItem] = useState('');
const [currentSort, setCurrentSort] = useState('');
const [loading, setLoading] = useState(false);

useEffect(async () => {
  fetchItems();
}, [])

const fetchItems = async () => {
  const data = await fetch('http://localhost:8000/items');
  const items = await data.json();
  setProducts(items)
  setLoading(true)
}

function priceUSD(change){
  return change.toFixed(2)
}

useEffect(() => {
  const filteredItems = products.filter((a) => {
    if (item === '') {return a} else {return a.category === item}
  });
  setFilteredProducts(filteredItems);
}, [item, products])

 useEffect(() => {
  if (currentSort === '') {
    return
  }
  const sortedItems = filterProducts.sort((a, b) => {
    return currentSort === 'ASE' ? a.price - b.price : b.price - a.price
  });
  setFilteredProducts([...sortedItems]);
}, [currentSort])


const useStyles = makeStyles((theme) => ({
    logo: {
    color: 'black'
},
    buttonFont: {
    fontSize: 12
},
    cardSize: {
    width: 275
},
    root: {
    flexGrow: 1,
    padding: theme.spacing(2)
}
}));

  const theme = useTheme();
  const isMatch = useMediaQuery(theme.breakpoints.down('xs'));

  const classes = useStyles();

    return (
        <div>
         <CssBaseline />
           <Grid container spacing={1} direction="column">
            <Grid item xs={12} container>

                <Grid item xs={3} />

                <Grid item xs={6} >
                  <Typography>
                    {isMatch ? <TopMenu setItem={setItem} />  : (
                      <div>
                        <Button onClick={() => setItem("")} className={classes.buttonFont} >
                          All items
                        </Button>
                        <Button onClick={() => setItem("men clothing")} className={classes.buttonFont} >
                          Men clothing
                        </Button>
                        <Button onClick={() => setItem("women clothing")} className={classes.buttonFont} >
                          Women clothing
                        </Button>
                        <Button onClick={() => setItem("jewelery")} className={classes.buttonFont} >
                          Jewelery
                        </Button>
                        <Button onClick={() => setItem("electronics")} className={classes.buttonFont} >
                          Electronics
                        </Button>
                      </div>
                    )}
                  </Typography>
                </Grid>

               <Grid item xs={3} />
            </Grid>

            <Grid item xs={12} container>
            <Grid item xs={3} />
            <Grid item xs={6} >
              <Typography>
                {isMatch ? <BottomMenu setCurrentSort={setCurrentSort}/> : (
                  <div>
                    <Button onClick={() => setCurrentSort('DESC')} className={classes.buttonFont}>
                      Highest
                    </Button>
                    <Button onClick={() => setCurrentSort('ASE')} className={classes.buttonFont}>
                      Lowest
                    </Button>
                  </div>
                )}
              </Typography>
            </Grid>
           <Grid item xs={3} />
            </Grid>
           </Grid>

    <div className={classes.root}>
                {loading ?
                            (filterProducts.map((a, index) => (
                              <Grid
                                container
                                spacing={2}
                                direction="row"
                                justify="flex-start"
                                alignItems="flex-start"
                              >
                                <Grid item xs={3}>
                                  <Card className={classes.cardSize}>
                                    <CardContent>
                                        <Link to={`/Item/${a.id}`}>
                                          <div key={index} className="productStyle">
                                            <CardMedia
                                              component="img"
                                              image={require(`../images/${a.image}`)}
                                             />
                                            <p>{a.title}</p>
                                            <p>${priceUSD(a.price)}</p>
                                          </div>
                                        </Link>
                                    </CardContent>
                                  </Card>
                              </Grid>
                            </Grid>
                          )))

                          : (<ReactBootStrap.Spinner className="spinner" animation="border" />)
                          }
      </div>

        </div>
    )
}

export default Shop;

Screenshot: enter image description here

Upvotes: 0

Views: 1820

Answers (1)

amreshk005
amreshk005

Reputation: 106

Just add display: flex here:

    const useStyles = makeStyles((theme) => ({
    root: {
        display: "flex",
        flexGrow: 1,
        padding: theme.spacing(2)
    }
}));

Upvotes: 1

Related Questions