PostsList component renders list of posts, I want to make it such that when clicked over the div item of a post it gets redirected to that specific post's link
const PostsListView = ({ posts, setError, isloggedin }) => {
const [redirectCreatePost, setRedirectCreatePost] = React.useState(false)
if (redirectCreatePost) return (<Navigate to='createPost' />)
return (
<Grid container
align="center"
alignItems="center"
justify="center"
direction="column"
>
{
posts.map(({ category, username, postHeading, createdAt, postid }) => {
return (
<Link to={`post/${postid}`} style={{ textDecoration: 'none', color: 'black' }}>
<Grid
key={postid}
item container
alignItems="center"
style={{
width: 600,
borderRadius: 10,
margin: 5,
backgroundColor: '#D3D3D3'
}}>
<Grid container direction="column">
<Grid item container justify="flex-end">
<Grid item style={{ marginTop: 5, marginLeft: 20 }}> <b>{`c/${category}`}</b> </Grid>
<Grid item style={{ marginTop: 5, marginLeft: 5 }}> {` posted by u/${username} ${getTime(createdAt)}`} </Grid>
</Grid>
</Grid>
<Grid item container alignItems="center" align="left">
<Typography variant="h6" style={{ width: 600, marginLeft: 20, marginRight: 20 }}>{postHeading}</Typography>
</Grid>
</Grid>
</Link>
)
})
}
</Grid>
)
}
Although this seems to create an <a> tag around the grid item <div> in the DOM it is not clickable. I have tried giving the <Link> as component prop to the Grid item and yet no luck. Weirdly enough, it works fine when I replace the <Link> with <a>, but on doing so on clicking the link it refreshes the entire page losing all the state of the App. Appreciate any help. Thanks!
Related
SO im using a MUI dialog, and MUI grid together. I took this code directly from the website. The only changes are the box wrapping the dialog, and the slight change in the dialog functions IE 'openDialog' instead of 'open'. No matter what size I change the dialog to, the grid items remain in a three-column layout, when at 'xs' for example, they should stack to 12. I have no idea why, the code looks right to me.
<Box sx={{flexGrow: 1}}>
<Dialog
fullWidth={fullWidth}
maxWidth={maxWidth}
open={openDialog}
onClose={handleCloseDialog}
>
<DialogTitle>Optional sizes</DialogTitle>
<DialogContent>
<DialogContentText>
You can set my maximum width and whether to adapt or not.
</DialogContentText>
<Box
noValidate
component="form"
sx={{
display: 'flex',
flexDirection: 'column',
m: 'auto',
width: 'fit-content',
}}
>
<FormControl sx={{ mt: 2, minWidth: 120 }}>
<InputLabel htmlFor="max-width">maxWidth</InputLabel>
<Select
autoFocus
value={maxWidth}
onChange={handleMaxWidthChange}
label="maxWidth"
inputProps={{
name: 'max-width',
id: 'max-width',
}}
>
<MenuItem value={false}>false</MenuItem>
<MenuItem value="xs">xs</MenuItem>
<MenuItem value="sm">sm</MenuItem>
<MenuItem value="md">md</MenuItem>
<MenuItem value="lg">lg</MenuItem>
<MenuItem value="xl">xl</MenuItem>
</Select>
</FormControl>
<FormControlLabel
sx={{ mt: 1 }}
control={
<Switch checked={fullWidth} onChange={handleFullWidthChange} />
}
label="Full width"
/>
</Box>
<Grid container>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid item xs={12} sm={4} md={4} key={index}>
<Item>xs=2</Item>
</Grid>
))}
</Grid>
</Box>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog}>Close</Button>
</DialogActions>
</Dialog>
It seems that this is because the Grid is changing layout based on responsive breakpoints of the viewport, instead of the container width. In the posted code, the Grid should change to just 1 column when the window is actually resized below sm, which is 600px.
If the purpose is to mock the responsive sizes, perhaps for a demo, consider to have Grid take value on conditions calculated from the selected maxWidth and fullWidth, instead of the actual viewport width.
Minimized demo on: stackblitz (might need to view in new tab for changes).
<Grid container spacing={{ xs: 2, md: 3 }}>
{Array.from(Array(6)).map((_, index) => {
const responsive = { xs: 12, sm: 4, md: 4, lg: 2, xl: 2 };
const selected = responsive[`${maxWidth}`] || 0;
const mockedResponsive = Object.keys(responsive).reduce(
(acc, cur) =>
!fullWidth
? {
...acc,
[cur]: Math.max(
responsive[cur],
Math.max(selected, responsive["md"])
),
}
: { ...acc, [cur]: Math.max(responsive[cur], selected) },
{}
);
return (
<Grid item key={index} {...mockedResponsive}>
<Typography>xs=2</Typography>
</Grid>
);
})}
</Grid>
everyone, i have a frontend code that displaying card with rectangular but i want to display it in square, please help since i have tried so many time and didn't change to square
const useStyles = makeStyles({
gridContainer: {
paddingLeft: "40px",
paddingRight: "40px",
// borderWidth:100
},
root: {
// minWidth:50,
flex:1
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
});
function Home() {
return (
<div>
<div>
<h1>Product List</h1>
</div>
<Grid
container
spacing={4}
className={classes.gridContainer}
justify="center"
>
{getData.map((x, index) => {
return (
<Grid key={index} item xs={12} sm={6} md={4} style={{
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "stretch",
}}
>
<Card className={classes.root} variant="outlined">
<CardContent>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.sku}
</center>
</Typography>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.name}
</center>
</Typography>
<Typography className={classes.pos} color="textSecondary">
<center>
{x.price}
</center>
</Typography>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</div>
);
}
From above, it shows that card will display in rectangular
Current output
I'm struggle with the styling issue so please advise and correct me if i'm wrong, thanks :)
I am using the grid system in material Ui. And make a list of statements with a divider. I want to remove the very last divider from the list.
Here is the code snippet of my TSX file
return (
<Grid key={index}>
<Grid style={{ display: 'flex', flexDirection: 'row' }}>
<Grid item direction="column">
<FontAwesomeIcon icon={listItem.className} color={listItem.color} />
</Grid>
<Grid item xs={3} direction="column">
<span style={{ paddingLeft: '5px', fontSize: '12px', fontWeight: 'bold' }}>{listItem.title}:</span>
</Grid>
<Grid item xs={9}>
<span
className={classes.listSubHeader}
style={
listItem.title === 'Spread & Liquidity' && listItem.color === theme.palette.error.main
? { color: theme.palette.error.main, fontWeight: 'bold' }
: { color: theme.palette.text.primary }
}>
{listItem.sentence}
</span>
</Grid>
</Grid>
<hr className={classes.divider} />
</Grid>
);
I want to remove(border: 'none') the last divider only from the grid system. Your precious suggestions would be helpful. Thanks in Advance.
Just in case you would rather use #mui's divider component rather than the hr tag:
import * as React from 'react';
import Divider from '#mui/material/Divider';
const dividerStyle = {
borderTop: "2px dashed black"
}
export default function DashedDivider() {
return (
<Divider sx={dividerStyle}/>
);
}
I'm having a very difficult time trying to achieve something simple with the Grid Component from MaterialUI. Specifically, I'd like to align one item to the left, and another to the right on one layout row.
I've searched extensively, and have not found any solutions that work. I've tried many suggestions, including the use of justifyContent and alignContent within a Grid component, and within JSS, and the flex: 1 technique of 'pushing' content.
Relevant Code Snippets
Trying to put the <Typography> element on the left, and the <FormGroup> on the right:
<Container>
<Grid container spacing={3}>
<Grid className={classes.rowLayout}>
// Goal is to align this to the LEFT
<Grid item xs={6}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
// Goal is to align this to the RIGHT
<Grid item xs={3}>
<FormGroup>
// Simple `Switch` button goes here
</FormGroup>
</Grid>
</Grid>
</Grid>
</Container>
MaterialUI JSS styling:
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '100%'
},
rowLayout: {
display: 'flex',
alignItems: 'baseline'
},
}));
I'm also finding that, generally speaking, this is requiring the use of many Grid components, and I'd love to write cleaner code if possible.
Do you have any tips or fixes to this problem?
Thanks a million,
Davis
I'm using this at the moment and it works well to align one to the far left, and one to the far right.
Inspired from: How to align flexbox columns left and right?
const useStyles = makeStyles((theme) => ({
right: {
marginLeft: 'auto'
}
}));
<Grid container alignItems="center">
<Grid>
<Typography variant="h4" component="h4">Left</Typography>
</Grid>
<Grid className={classes.right}>
<Button variant="contained" color="primary">Right</Button>
</Grid>
</Grid>
I used a different approach to list one grid item to right. Similar approach can be use to show grid items to right and one at left.
<Grid container>
<Grid item>Left</Grid>
<Grid item xs>
<Grid container direction="row-reverse">
<Grid item>Right</Grid>
</Grid>
</Grid>
</Grid>
I think the best option here is to use flex like this:
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '100%'
},
rowLayout: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center' // To be vertically aligned
},
}));
As a second choice (and for me the best since you are using Material UI at its fullest expression which if you are using it, it's the best thing to do. Use the library as much as you can) you could do something like this:
<Container>
<Grid container spacing={3}>
<Grid container direction="row" justify="space-between" alignItems="center">
// Goal is to align this to the LEFT
<Grid item xs={6}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
// Goal is to align this to the RIGHT
<Grid item xs={3}>
<FormGroup>
// Simple `Switch` button goes here
</FormGroup>
</Grid>
</Grid>
</Grid>
</Container>
I have solved a similar issue using justifyContent on each of the Grid items.
<Container>
<Grid container spacing={3} alignItems="baseline">
<Grid item xs={6} sx={{
justifyContent: "flex-start"
}}>
<Typography variant="h6" gutterBottom>Some Text</Typography>
</Grid>
<Grid item xs={3} sx={{
display: "flex",
justifyContent: "flex-end"
}}>
<FormGroup>
<Typography variant="h6" gutterBottom>Some Switch</Typography>
</FormGroup>
</Grid>
</Grid>
</Container>
This page gives you a really good visually interpretation of how flex works: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
I need to vertically center text inside grid item, which has minHeigh attribute set, here's short codesandbox example of the problem i'm facing, justify, alignItems, does not seem to be working.
<Grid container className={classes.root}>
<Grid item xs={12}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={alignItems}
direction={direction}
justify={justify}
>
{[0, 1, 2].map(value => (
<Grid
key={value}
item
style={{
padding: "0 12px",
minHeight: 48,
borderStyle: "solid"
}}
>
{`Cell ${value + 2}`}
</Grid>
))}
</Grid>
</Grid>
When style={{ minHeight: 48 }} is applied to <Grid item /> children of grid item is not being aligned, justify, alignItems, does not have any effect on it.
You need to add two other properties to the element as well.
display: inline-flex;
align-items: center;
If this is the result that you are expecting
<Grid
container
spacing={16}
className={classes.demo}
alignItems={alignItems}
direction={direction}
justify={justify}
>
{[0, 1, 2].map(value => (
<Grid
key={value}
item
style={{
display: "inline-flex", // <--
alignItems: "center", // <--
padding: "0 12px",
minHeight: 48,
borderStyle: "solid"
}}
>
<p>{`Cell ${value + 2}`}</p>
</Grid>
))}
</Grid>
Try vertical-align: middle, and see if that works? Or if the box is a fixed height you could always add margin to the top of it. Hope that helps!
here is how you can do it. Wrap your text inside div and use alignItems:
https://codesandbox.io/s/8nw8v9yv02