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) */ }}>
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>
I used Container this caused all my grid items to be in columns not rows how can I fix it ?
link for project
You need to give property container to your parent grid. Your return looks like,
return (
<Container>
<Grid
container
direction="row"
sx={{
backgroundColor: "blue"
}}
justify="center"
spacing={4}
>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
d
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
e
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
f
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
g
</Grid>
</Grid>
</Container>
);
Use this setup and it should work (remove direction="row" and add container)
<Grid
container
sx={{
backgroundColor: "blue",
width: "100%",
marginLeft: 0
}}
justify="center"
spacing={4}
>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
d
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
e
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
f
</Grid>
<Grid item xs={12} sm={4} sx={{ backgroundColor: "yellow" }}>
g
</Grid>
</Grid>
demo
I am relatively new to React and Javascript. I am trying to declare a temporary variable and assign the value companyData.name to it as I need to collect the 2 variables like companyData.name.
This is my code.
<Box sx={{ flexGrow: 3 }} display="flex"
justifyContent="center"
alignItems="center" marginLeft={8} marginRight={1} mt={2.5}>
<Grid container spacing={{ xs: 1, md: 2, lg: 2 }} columns={{ xs: 2, sm: 2, md: 12, lg: 16 }} display="flex"
justifyContent="center"
alignItems="center" >
<Grid item xs={2} sm={4} md={6} lg={7.3} >
Company 1:
<Box
sx={{ flexGrow: 1, alignItems: "baseline" }}
display="flex"
justifyContent="flex-end"
alignItems="flex-end">
<Grid item sx={{ flexGrow: 1 }} spacing={{ xs: 1, md: 2, lg: 2 }} columns={{ xs: 2, sm: 2, md: 12, lg: 22 }} display="flex"
justifyContent="center"
alignItems="center" marginLeft={8} marginRight={1} mt={4} mb="30px" width='100%'>
<Autocomplete
id="input"
options={allCompanies}
renderInput={(params) => {
const { InputLabelProps, InputProps, ...rest } = params;
return <InputBase placeholder='Search for a company...' sx={{ color: light ? "white" : "black", width: "100%" }} {...params.InputProps} {...rest} />
}}
onChange={(event, value) => fetchCompanyData(value)}
color="primary"
style={{ width: "75%", border: light ? "1px solid white" : "1px solid black", borderRadius: "15px", padding: "10px" }}
defaultValue={companyData.name}
/>
</Grid>
</Box>
</Grid>
<Grid item xs={2} sm={4} md={6} lg={7.3} >
Company 2:
<Box
sx={{ flexGrow: 1, alignItems: "baseline" }}
display="flex"
justifyContent="flex-end"
alignItems="flex-end">
<Grid item sx={{ flexGrow: 1 }} spacing={{ xs: 1, md: 2, lg: 2 }} columns={{ xs: 2, sm: 2, md: 12, lg: 22 }} display="flex"
justifyContent="center"
alignItems="center" marginLeft={8} marginRight={1} mt={4} mb="30px" width='100%'>
<Autocomplete
id="input"
options={allCompanies}
renderInput={(params) => {
const { InputLabelProps, InputProps, ...rest } = params;
return <InputBase placeholder='Search for a company...' sx={{ color: light ? "white" : "black", width: "100%" }} {...params.InputProps} {...rest} />
}}
onChange={(event, value) => fetchCompanyData(value)}
color="primary"
style={{ width: "75%", border: light ? "1px solid white" : "1px solid black", borderRadius: "15px", padding: "10px" }}
defaultValue={companyData.name}
/>
</Grid>
</Box>
</Grid>
</Grid>
</Box>
{chartData ? <CompanyChart dataset={chartData} companyName={companyData.name} companyName2={companyData.name}/>:<div> Loading chart...</div>}
I need to assign companyData.name of Company 1 to companyName in the above line.
I have tried using React.useState for this purpose. But I am unable to set the state inside a UI component.
const [company1,setCompany1]=React.useState([]);
setCompany1(companyData.name)
Any help regarding how to proceed would be appreciated. I just need to pass the names of 2 companies to .
You are using an array as default state ([]) and then trying to pass a string as a value setCompany(companyData.name).
Try this:
const [company1,setCompany1]=React.useState('');
setCompany1(companyData.name)
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 have these text and icon which are really far from each other
How can I put the Icon on the right side of the text? Something like this:
Water Jug->
Codesandbox: https://codesandbox.io/s/responsivestack-material-demo-forked-330ogi?file=/demo.js
Codes:
<Grid
container
spacing={{ xs: 2, md: 3 }}
columns={{ xs: 4, sm: 8, md: 12 }}
>
{product &&
product.map((item, i) => (
<Grid item xs={2} sm={4} md={4} key={i}>
<Stack direction="row" spacing={2}>
<ListItemText primary={item.prodName} />
<ListItemIcon>
<ArrowForwardIcon style={{ marginLeft: "1px" }} />
</ListItemIcon>
</Stack>
</Grid>
))}
</Grid>
Replace with this:
<div style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
<ListItemText primary={item.prodName} />
<ListItemIcon>
<ArrowForwardIcon style={{ marginLeft: "1px" }} />
</ListItemIcon>
</div>