MUI Grid not working on any size in a dialog - javascript

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>

Related

Skeleton-Avatar and ImageButton in MUI React are forced to oval background shapes

When using mui Stack I get weird side effect of geting all the background shapes of Skeleton Avatar and background area smeared to oval|elipsoid shapes. I tried setting equal width and height for Avatar but id does not help.
How can I fix it throguh sx mui component property or css?
code fragment
<Box
noValidate autoComplete="off"
sx={{ marginLeft: '15%','& .MuiTextField-root': { m: 2, width: '25ch' }}}>
<div>
<form onSubmit={onSubmit} >
{formFields.map((form, index) => {
return (
<Fade in={true} sx = {{width: '95%'}} {...{ timeout: 500 }}>
<Stack direction="row" borderRadius="0" spacing={2} key={index} style ={{marginLeft: '-50px', }}>
{form.img? <Avatar alt="release img" src={form.img} sx={{ width: 56, height: 56 }} /> : <Skeleton animation={false} variant ='circular'> <Avatar sx={{ width: 56, height: 56}} /> </Skeleton>}
<TextField {/* ... */}/>
<IconButton onClick={() => removeFields(index)}><DeleteIcon /</IconButton>
</Stack>
</Fade>
)
})}
</form>
<IconButton onClick={addFields} color={'warning'}> <AddCircleOutlineOutlinedIcon /></IconButton>
<br></br><br></br>
<Button onClick={onSubmit} color={'warning'} variant="contained" endIcon= {<SendIcon/>} > Search links </Button>
Normally, the default value of align-items for flex items will be stretch, that's why you see your icon is stretched in the cross axis
The solution is simple, set alignItems prop in Stack to a different value rather than normal/stretch. Here I use center
<Stack
direction="row"
borderRadius="0"
spacing={2}
alignItems="center" // this line
style={{ marginLeft: "-50px" }}
>
Demo
References
CSS align-items

Different Appbars in two different lines - width

I'm in my first project with Material UI and React and there's a problem I've encountered in terms of design, I want to make sure that each AppBar is in a separate row, and stays the same size as in the image.
Note that I've already tried changing the container direction to columns'/rows, then it does each in a separate row but each AppBar takes up all the screen width and if I try to change the width to a certain percentage of the screen it loses proportion.
I would appreciate your assistance!
I'm attaching a picture of what my current situation is (I just want to put the slider under the Buttons AppBar )
this is the problem
return (
<main className={classes.content}>
{/* <div className={classes.toolbar} /> */}
<Grid container spacing={2} justify='center'>
<Grid item>
<AppBar
position='static'
sx={{
backgroundColor: '#212121 !important ',
borderRadius: 8,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-around',
// width: "min",
// margin: "auto",
}}
style={{
border: 'solid white 0.1px',
}}
>
<Toolbar>
<Button
className={classes.btn}
sx={{
m: 2,
textTransform: 'capitalize',
}}
variant='outlined'
size='small'
//onClick={handleCategoryClicked}
>
filter by category
</Button>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'price')}
>
filter by price
</Button>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'rating')}
>
filter by rating
</Button>
</Toolbar>
</AppBar>
</Grid>
<Grid>
<AppBar
position='static'
sx={{
backgroundColor: '#212121 !important ',
borderRadius: 8,
}}
style={{ border: 'solid white 0.1px' }}
>
<Box sx={{ width: 300 }}>
<Slider
getAriaLabel={() => 'Temperature range'}
value={value}
onChange={handleChange}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
/>
<Button
className={classes.btn}
sx={{ m: 2, textTransform: 'capitalize' }}
variant='outlined'
size='small'
onClick={(e) => sortResults(e, 'pricerange')}
>
filter by Price Range
</Button>
</Box>
</AppBar>
</Grid>

How to make a Grid item clickable with Link component?

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!

React MUI: Matching the heights of two grid sections

Using MUI have two separate grids next to each other, both taking up 50% of a larger grid.
As seen in the image below, I am having a hard time matching the heights of the two sections. I would like the smaller grid items (cards) to dynamically fill in the height of the left portion and match the height of the right portion.
How is this possible with Mui?
Here is my current code:
import React from "react";
import Grid from "#mui/material/Grid";
import Box from "#mui/material/Box";
import Card from "#mui/material/Card";
import CardContent from "#mui/material/CardContent";
import Typography from "#mui/material/Typography";
import Chart from "./testChart.js";
function GeneralDashboard(props) {
const defaultStats = [
{ name: "Opportunitys Entered", value: 102 },
{ name: "Wins Reported", value: 23 },
{ name: "Win Rate", value: "60%" },
{ name: "Total Revenue", value: "$20m" },
];
return (
<>
<Box sx={{ flexGrow: 1 }}>
<Grid
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 8, sm: 8, md: 8, lg: 8 }}
>
<Grid item xs={8} sm={8} md={4} lg={4}>
<Box sx={{ flexGrow: 1 }}>
<Grid
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 4, sm: 4, md: 8, lg: 8 }}
>
{defaultStats.map((stat) => {
return (
<>
<Grid item xs={2} sm={4} md={4}>
<Card>
<CardContent>
<Typography
sx={{ fontSize: 14 }}
color="text.secondary"
gutterBottom
>
{stat.name}
</Typography>
<Typography variant="h3" component="div">
{stat.value}
</Typography>
</CardContent>
</Card>
</Grid>
</>
);
})}
</Grid>
</Box>
</Grid>
<Grid item xs={8} sm={8} md={4} lg={4}>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 1, sm: 1, lg: 1 }}>
<Grid item xs={12}>
<Card>
<CardContent>
<Typography
sx={{ fontSize: 14 }}
color="text.secondary"
gutterBottom
>
<h5>
<span>
<span className="fw-semi-bold">Re-entry</span>{" "}
timing by industry
</span>
</h5>
</Typography>
<Chart />
</CardContent>
</Card>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
</Box>
</>
);
}
You need to set the height of all containers and the item to 100%:
<Box sx={{ flexGrow: 1, height: "100%" /* <----------------------- (1) */ }}>
<Grid
sx={{ height: "100%" /* <----------------------- (2) */ }}
container
spacing={{ xs: 1, sm: 2, lg: 2 }}
columns={{ xs: 4, sm: 4, md: 8, lg: 8 }}
>
{defaultStats.map((stat) => {
return (
<>
<Grid item xs={2} sm={4} md={4}>
<Card sx={{ height: "100%" /* <----------------------- (3) */ }}>

How to Align One Item Left, and Another Right using Material UI Grid Components

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/

Categories