Grid Items are in a column instead of a row Material-UI - javascript

I am trying to have a grid that has 3 items in a row. However the grid in my code continues vertically and there is only one item per row. There is an image in each grid item as well. How can I change it so there is 3 grid items in a row. Here's my code:
Grid.js:
const styles = theme => ({
root: {
display: "flex",
flexWrap: "wrap",
justifyContent: "space-around",
overflow: "hidden",
backgroundColor: theme.palette.background.paper,
margin: 0
},
paper: {
margin: "1%",
padding: "1%",
width: "80%"
},
});
class GridListings extends Component {
componentDidMount() {
this.props.getPosts();
}
render() {
const { classes } = this.props;
const { posts, loading } = this.props.post;
let postContent;
if (posts === null || loading) {
postContent = <div> loading</div>;
} else {
postContent = <PostFeed posts={posts} />;
}
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Typography align="center" variant="display2">
Sneaker Listings
</Typography>
{postContent}
</Paper>
</div>
);
}
}
postfeed.js:
class PostFeed extends Component {
render() {
const { posts } = this.props;
return posts.map(post => <ListingPost key={post._id} post={post} />);
}
}
ListingPost.js:
const styles = theme => ({
root: {
flexGrow: 1,
maxWidth: "30%",
padding: theme.spacing.unit * 2
},
image: {
maxWidth: "100%",
maxHeight: "100%"
},
img: {
margin: "auto",
display: "block",
maxWidth: "100%",
maxHeight: "100%"
}
});
class ListingPost extends Component {
onDeleteClick(id) {
console.log(id);
}
render() {
const { post, auth, classes } = this.props;
return (
<Paper className={classes.root}>
<Grid container spacing={16} direction="row">
<Grid item>
<ButtonBase className={classes.image}>
<img
className={classes.img}
alt="complex"
src={post.productImage}
/>
</ButtonBase>
</Grid>
<Grid item xs={12} sm container direction="row">
<Grid item xs container spacing={16}>
<Grid item xs>
<Typography gutterBottom variant="subheading">
Shoes
</Typography>
<Typography gutterBottom>Size:12</Typography>
<Typography color="textSecondary">Brand New</Typography>
</Grid>
<Grid item>
<Typography style={{ cursor: "pointer" }}>Remove</Typography>
</Grid>
</Grid>
<Grid item>
<Typography variant="subheading">$19.00</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
);
}
}
Any help is appreciated.

You have to use the bootstrap class row in below component. Try below code
PostFeed.js
class PostFeed extends Component {
render() {
const { posts } = this.props;
let postss= [];
posts.map(post => {
postss.push(<ListingPost key={post._id} post={post} />);
});
return (
<div className="row">
{postss}
</div>
);
}
}
OR
In your grid.js just add div with className row
<Paper className={classes.paper}>
<Typography align="center" variant="display2">
Sneaker Listings
</Typography>
<div className="row">
{postContent}
</div>
</Paper>

Related

i wan to get timely divided number of slot in reactjs

i just create this timepicker using mui and momentjs. 2 timepicker, one input, and one button, when user selects particular time like in first picker 8:am and in second one is 9:00am, and enter the slot like 6 so output will be 8:00-8:10, 8:10-8:20, 8:20 - 8:30, 8:40 - 8:50, 8:50 - 9:00. i am done with this to think about logic.
import * as React from "react";
import TextField from "#mui/material/TextField";
import { AdapterDateFns } from "#mui/x-date-pickers/AdapterDateFns";
import { LocalizationProvider } from "#mui/x-date-pickers/LocalizationProvider";
import { TimePicker } from "#mui/x-date-pickers/TimePicker";
import { Box } from "#mui/system";
import moment from "moment";
import { Button, Grid } from "#mui/material";
import Paper from "#mui/material/Paper";
export default function BasicDatePicker() {
const [startTime, setStartTime] = React.useState([]);
const [endTime, setEndTime] = React.useState([]);
return (
<Box
component="main"
sx={{ flexGrow: 1, p: 3 }}
style={{ marginTop: "100px" }}
>
<LocalizationProvider
dateAdapter={AdapterDateFns}
sx={{ flexGrow: 1, p: 3 }}
>
<Box
sx={{
display: "flex",
flexWrap: "wrap",
"& > :not(style)": {
m: "0 auto",
width: 300,
height: 350,
},
}}
>
<Paper elevation={3}>
<Grid container>
<Grid item xs={12} style={{ margin: "25px" }}>
<TimePicker
label="Start Time"
value={startTime}
onChange={(newValue) => {
setStartTime(newValue);
// setStartTime(moment(newValue).add(1, "days"));
// console.log(newValue)
}}
renderInput={(params) => <TextField {...params} />}
/>
</Grid>
<Grid item xs={12} style={{ margin: "25px" }}>
<TimePicker label="End Time"
// disabled
value={endTime}
onChange={(newValue) => {
setEndTime(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
</Grid>
<Grid item xs={12} style={{ textAlign: "center" , }}>
{" "}
<TextField id="outlined-basic" label="Slot" variant="outlined"/>
</Grid>
<Grid item xs={12} style={{ textAlign: "center", margin: "10px" }}>
{" "}
<Button variant="contained">Action</Button>
</Grid>
</Grid>
</Paper>
</Box>
</LocalizationProvider>
</Box>
);
}
Here you can use this function, pass the moment objects to the function.
const today = moment();
const someday = moment().add(1,"h");
function getSlots(one, two){
const slots = [];
while(one.unix() < two.unix()){
const tmp = one;
const slot = `${tmp.format("h:mm")}-${one.add(10,"m").format("h:mm")}`;
}
return slots;
}
console.log(getSlots(today, someday,"10 min"));

I am passing the state to a function component via history (react-router-dom) but it says the state is 'undefined'

I need to pass the state value to a different component and I want to use it in the different component.
Code in the first component:
const handleFormSubmit = async (event) => {
event.preventDefault()
console.log(formData)
try {
await axios
.post(`http://localhost:4000/accounts/register`, formData)
.then(function (response) {
console.log(response)
console.log(response.data)
setServerMessage(response.data)
})
} catch (error) {
console.log(error)
}
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage.message },
})
}
The second component where I am trying to access the state.
const navigate = useNavigate()
let data = useLocation()
console.log(data)
I have tried to log the current state value in the console using this:
useEffect(() => {
console.log(serverMessage)
}, [serverMessage])
I have tried to set the state in useffect like this:
useEffect(() => {
setServerMessage(serverMessage)
}, [serverMessage])
The output I am getting in the browser console is:
Object { pathname: "/session/verifyotp", search: "", hash: "", state: null, key: "n1jhatdj" }
This is the complete code in the page :
import React, { useEffect, useState } from 'react'
import { Box, styled } from '#mui/system'
import { Grid, Button } from '#mui/material'
import { ValidatorForm, TextValidator } from 'react-material-ui-form-validator'
import Typography from '#mui/material/Typography'
import { FormLabel } from '#mui/material'
import Link from '#mui/material/Link'
import axios from 'axios'
import Appbar from '../Appbar'
import Alert from '#mui/material/Alert'
import Snackbar from '#mui/material/Snackbar'
import { useNavigate } from 'react-router-dom'
const FlexBox = styled(Box)(() => ({
display: 'flex',
alignItems: 'center',
}))
const JustifyBox = styled(FlexBox)(() => ({
justifyContent: 'center',
}))
const IMG = styled('img')(() => ({
width: '100%',
}))
const JWTRegister = styled(JustifyBox)(() => ({
background: '#ffffff',
minHeight: '100vh !important',
input: {
background: 'white',
borderRadius: 25,
},
}))
const JwtRegister = (props) => {
const [serverMessage, setServerMessage] = useState('')
const [open, setOpen] = useState(false)
const history = useNavigate()
const [formData, setFormData] = useState({
name: '',
mobile: '',
email: '',
password: '',
})
const handleClick = () => {
setOpen(true)
}
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
const { name, mobile, email, password } = formData
const handleChange = (event) => {
setFormData({
...formData,
[event.target.name]: event.target.value,
})
}
const handleFormSubmit = async (event) => {
event.preventDefault()
console.log(formData)
try {
await axios
.post(`http://localhost:4000/accounts/register`, formData)
.then(function (response) {
console.log(response)
console.log(response.data)
const newValue = response.data
setServerMessage(newValue)
})
} catch (error) {
console.log(error)
}
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage },
})
}
useEffect(() => {
console.log(serverMessage)
setServerMessage(serverMessage)
console.log(serverMessage)
}, [serverMessage])
return (
<JWTRegister>
<Grid container>
<Appbar />
<Grid
pt={0}
pl={10}
pr={10}
item
lg={6}
md={6}
sm={6}
xs={12}
sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
>
<Typography
component="h1"
variant="h3"
sx={{ textTransform: 'none', color: '#000' }}
>
Sign up
</Typography>
<Typography component="h1" variant="h5">
Register now to get 100 free credits
</Typography>
{serverMessage ? (
<>
<Alert
variant="filled"
autohideduration={6000}
severity="success"
>
{serverMessage.message}
</Alert>
<Snackbar
open={open}
autoHideDuration={3000}
onClose={handleClose}
>
<Alert
onClose={handleClose}
severity="success"
sx={{ width: '100%' }}
>
{serverMessage.message}
</Alert>
</Snackbar>
</>
) : null}
<ValidatorForm id="Register" onSubmit={handleFormSubmit}>
<Grid container spacing={2}>
<Grid
item
lg={6}
md={6}
sm={12}
xs={12}
sx={{ mt: 2 }}
>
<FormLabel sx={{ color: '#000000' }}>
Name
</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="text"
name="name"
value={name}
autoFocus
onChange={handleChange}
validators={['required']}
errorMessages={['Name field is required']}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
/>
</Grid>
<Grid
item
lg={6}
md={6}
sm={12}
xs={12}
sx={{ mt: 2 }}
>
<FormLabel sx={{ color: '#000000' }}>
Mobile
</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="text"
name="mobile"
value={mobile}
onChange={handleChange}
validators={['required']}
errorMessages={[
'Mobile Number field is required',
]}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
/>
</Grid>
</Grid>
<FormLabel sx={{ color: '#000000' }}>Email</FormLabel>
<TextValidator
sx={{ mb: 3, width: '100%' }}
size="small"
type="email"
name="email"
value={email}
onChange={handleChange}
validators={['required', 'isEmail']}
inputProps={{
style: {
borderRadius: 25,
backgroundColor: 'white',
disableUnderline: true,
},
}}
errorMessages={[
'Email field is required',
'Email is not valid',
]}
/>
<FormLabel sx={{ color: '#000000' }}>
Password
</FormLabel>
<TextValidator
sx={{ mb: '16px', width: '100%' }}
size="small"
name="password"
type="password"
value={password}
onChange={handleChange}
validators={['required']}
errorMessages={['Password field is required']}
inputProps={{
style: {
borderRadius: 25,
disableUnderline: true,
backgroundColor: 'white',
},
}}
/>
<FlexBox pb={2}>
<Button
type="submit"
variant="contained"
sx={{
borderRadius: 25,
textTransform: 'none',
background: '#C7FF80',
color: '#000000',
}}
onClick={handleClick}
>
Verify OTP
</Button>
</FlexBox>
</ValidatorForm>
<Typography
variant="subtitle1"
display="inline"
sx={{
textTransform: 'none',
color: '#000000',
}}
>
Already a member?
<Link
href="/session/signin"
sx={{
textTransform: 'none',
color: '#FFFFFF',
}}
>
Sign in
</Link>
instead.
</Typography>
</Grid>
<Grid
pt={1}
pl={10}
item
lg={6}
md={6}
sm={6}
xs={12}
sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
>
<Typography pb={3} variant="body">
or sign up with
</Typography>
<Grid
pb={3}
pt={3}
container
alignItems="center"
spacing={2}
>
<Grid item>
<IMG
src="/assets/images/signup-linkedin.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Linkedin
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-google.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Google
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-facebook.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography pb={1} component="h6" variant="h6">
Facebook
</Typography>
</Grid>
</Grid>
<Grid pb={3} container alignItems="center" spacing={2}>
<Grid item>
<IMG
src="/assets/images/signup-email.svg"
height={55}
width={55}
/>
</Grid>
<Grid item>
<Typography component="h6" variant="h6">
Corporate Email ID
</Typography>
<span pb={1} component="h6" variant="h6">
(Use only Business email)
</span>
</Grid>
</Grid>
</Grid>
</Grid>
</JWTRegister>
)
}
export default JwtRegister
No matter what I try I am not able to pass the state to the different component. I have followed this question but does not solve my problem.
How can I access the state value? Why is it coming as null?
I have found the answer to this question. react-router v6 In You need to use your history like this for react-router v6.
This is not the right way to pass state:
history({
pathname: '/session/verifyotp',
state: { serverMessage: serverMessage.message },
})
Correct way to pass state in react-router v6 is the following:
history("/session/verifyotp", {
state: { serverMessage: serverMessage },
});

TypeError: currentTodos.map is not a function

I can not send currentTodos array to Cardhouse I want to send currentTodos array from seach-result.component.jsx to render loop card-house.component.jsx it show error TypeError: currentTodos.map is not a function Cardhouse
C:/Users/pimdo/Desktop/BF-property/src/components/card-house/card-house.component.jsx:45
seach-result.component.jsx
import React from "react";
import Pagination from '#material-ui/lab/Pagination';
import Typography from '#material-ui/core/Typography';
import Cardhouse from '../card-house/card-house.component.jsx'
class Seachresult extends React.Component {
constructor() {
super();
this.state = {
todos: [1,2, 3, 4, 5, 6, 7, 8, 9, 8, 10],
currentPage: 1,
todosPerPage: 6,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(event, value) {
this.setState({
currentPage: Number(value),
});
}
render() {
const { todos, currentPage, todosPerPage } = this.state;
// Logic for displaying todos
const indexOfLastTodo = currentPage * todosPerPage;
const indexOfFirstTodo = indexOfLastTodo - todosPerPage;
const currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo);
// Logic for displaying page numbers
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(todos.length / todosPerPage); i++) {
pageNumbers.push(i);
}
return (
<div>
<Typography>Page: {currentPage}</Typography>
<Cardhouse currentTodos={currentTodos} />
<Pagination count={pageNumbers.length} page={currentPage} size="large" id={currentPage} onChange={this.handleClick} showFirstButton showLastButton />
</div>
);
}
}
export default Seachresult;
card-house.component.jsx
import React from "react";
import CardMedia from "#material-ui/core/CardMedia";
import CardActionArea from "#material-ui/core/CardActionArea";
import Grid from "#material-ui/core/Grid";
import Container from "#material-ui/core/Container";
import Typography from "#material-ui/core/Typography";
import FavoriteIcon from "#material-ui/icons/Favorite";
import HotelIcon from "#material-ui/icons/Hotel";
import BathtubIcon from "#material-ui/icons/Bathtub";
import SquareFootIcon from "#material-ui/icons/SquareFoot";
import RoomIcon from "#material-ui/icons/Room";
import HouseIcon from "#material-ui/icons/House";
import ShareIcon from "#material-ui/icons/Share";
import IconButton from "#material-ui/core/IconButton";
import { Link } from "react-router-dom";
import Card from "#material-ui/core/Card";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
cardGrid: {
paddingTop: theme.spacing(8),
paddingBottom: theme.spacing(8),
},
card: {
height: "100%",
display: "flex",
flexDirection: "column",
},
cardMedia: {
paddingTop: "56.25%", // 16:9
},
cardContent: {
flexGrow: 1,
},
}));
export default function Cardhouse(currentTodos) {
const classes = useStyles();
return (
<Container className={classes.cardGrid} maxWidth="lg">
{/* End hero unit */}
<Grid container spacing={3} style={{ marginTop: 15 }}>
{currentTodos.map(currentTodo=> (
<Grid item key={currentTodo} xs={12} sm={6} md={4}>
<Card className={classes.card}>
<CardActionArea component={Link}
to="/property-detail">
<CardMedia
className={classes.cardMedia}
image="https://source.unsplash.com/random"
title="Image title"
/>
<CardContent className={classes.cardContent}>
<Grid container spacing={1}>
<Grid item xs={12}>
<Typography variant="h5">{"บ้านแสนสุข"}</Typography>
</Grid>
<Grid item xs={12}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
<RoomIcon fontSize="small" />
{
"ซอย ลาดพร้าว 101 Khlong Chan, Bang Kapi District, Bangkok, Thailand"
}
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant="h6" style={{ color: "#26ae61" }}>
{"$"} {"1,900,000"} {"บาท"}
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
<HotelIcon fontSize="large" />
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
<BathtubIcon fontSize="large" />
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
<SquareFootIcon fontSize="large" />
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
<HouseIcon fontSize="large" />
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
{"ห้องนอน 1"}
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
{"น้องน้ำ 1"}
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
{"256 ตารางเมตร"}
</Typography>
</Grid>
<Grid item xs={3}>
<Typography
variant="subtitle2"
style={{ color: "#969696" }}
>
{"บ้านเดี่ยว"}
</Typography>
</Grid>
</Grid>
</CardContent>
</CardActionArea>
<CardActions>
<div style={{ marginLeft: "auto" }}>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
</div>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
);
}
What you are passing to Cardhouse is actually a props object, not an array. Thus you are getting this error. Ways to resolve this is to change function Cardhouse argument like:
Using props:
export default function Cardhouse( props )
and then change the map() method to:
{props.currentTodos.map(currentTodo=> (
Using Object Destructuring:
Or, you can simply destructure the props object and you will not have to change anything inside the function like:
export default function Cardhouse({ currentTodos })
For more information: Components and Props
This is because the CardHouse component is treating currentTodos as the prop object instead of a prop attribute.
Change:
export default function Cardhouse(currentTodos) {
// code here
}
into:
export default function Cardhouse({ currentTodos }) {
// code here
}

How to position content perfectly within the left center of Paper component and remain that way on smaller devices?

I am putting together a component for my Goal Sharing social media app. This is what I have so far:
I'm trying to position the Avatar component as well as the two typography components beneath the Avatar component within the center of the left section of this Paper component. I have tried doing this by altering marginLeft and marginTop as you can see in the code below, but the issue when I do this is the components in this Goal component jumble on top of each other when I switch over to smaller devices. So, what's the best way to position these components in the center of the left section, and to ensure they remain that way on smaller devices?
This is the parent component file:
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Card,
Avatar,
CardContent,
CardActions
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
submit: {
margin: theme.spacing(2, 0, 2)
},
form: {
marginTop: theme.spacing(5)
},
cardGrid: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
},
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center"
},
cardContent: {
flexGrow: 1
},
profileHeader: {
textAlign: "center",
marginBottom: 10
},
avatar: {
width: theme.spacing(10),
height: theme.spacing(10),
marginLeft: "2.5vw",
marginTop: "5vh"
},
name: {
textAlign: "center",
marginLeft: "2vw"
},
goalText: {
marginTop: "5vh",
marginLeft: "3vw"
},
postedOn: {
marginLeft: "2vw"
}
}));
const Goals = ({ getGoals, auth, goal: { goals, user, loading } }) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container className={classes.cardGrid} maxWidth="md">
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid item key={singleGoal._id} xs={12}>
<Card fullwidth="true" className={classes.card}>
<Grid container spacing={2}>
<Grid item>
<Avatar
className={classes.avatar}
src={singleGoal.avatar}
/>
<Typography variant="subtitle2" className={classes.name}>
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography
variant="caption"
className={classes.postedOn}
>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
className={classes.goalText}
variant="body1"
gutterBottom
>
{singleGoal.text}
</Typography>
<Typography variant="h5"></Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<CardContent className={classes.cardContent}></CardContent>
<CardActions>
<ThumbUpAltIcon />
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<ThumbDownAltIcon />
<Link to={`/goal/${singleGoal.user}`}>
<ChatIcon />
</Link>
<Typography variant="caption">
{singleGoal.comments.length}
</Typography>
{!auth.loading && singleGoal.user === auth.user._id && (
<DoneIcon />
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<DeleteIcon />
)}
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals })(Goals);
Try this
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},

Grid Items aren't beside eachother Material UI

I am using the Grid component in material-ui. I am having trouble having the grid items stack beside each other. Right now they are stacking below each other. I am not sure what is making them stack below each other. I have made it so only on small screens the grid items will stack on top of each other, other wise each grid item should take up 4 columns. I am using react for the front-end. Here is my code:
GridItem:
const styles = theme => ({
image: {
maxWidth: "100%",
maxHeight: "100%"
},
});
render() {
const { post, auth, classes } = this.props;
<div className={classes.root}>
<Link to={`/post/${post._id}`}>
<Grid
item
key={post.key}
sm={12}
md={4}
lg={4}
>
<img src={post.productImage} className={classes.image} />
<Typography>
{post.name}
<br />
{post.size}
</Typography>
</Grid>
</Link>
</div>
PostFeed:
render() {
const { posts } = this.props;
return posts.map(post => <ListingPost key={post._id} post={post} />);
}
}
Grid:
const styles = theme => ({
root: {
display: "flex",
flexWrap: "wrap",
justifyContent: "space-around",
overflow: "hidden",
backgroundColor: theme.palette.background.paper,
margin: 0
},
grid: {
margin: "auto",
width: "80%",
display: "inner-block"
},
paper: {
margin: "1%",
padding: "1%",
width: "80%"
},
});
render() {
const { classes } = this.props;
const { posts, loading } = this.props.post;
let postContent;
if (posts === null || loading) {
postContent = <div> loading</div>;
} else {
postContent = <PostFeed posts={posts} />;
}
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Typography align="center" variant="display2">
Listings
</Typography>
<Grid container className={classes.grid} spacing={16}>
{postContent}
</Grid>
</Paper>
</div>
);
}
}
Like Yash Rahurikar said, remove the line flexWrap: "wrap" of the Grid style, and add wrap='nowrap' to your Grid container.
You can try to use
<Grid container direction={'row'}></Grid>
so you inner items may arrange themselves beside each other.
Hope that helps
<Grid
container
direction="row"
justify="flex-start"
alignItems="flex-start"
spacing={1}
>
//above 👆🏻 should be your main grid container
//wrap your grid item with the link using component prop
<Grid item key={post.key} component={Link} to={`/post/${post._id}`} >
// Your rest content #here
</Grid>
</Grid>
Try using align-items property.
<Grid container spacing={1} alignItems="flex-end">

Categories

Resources