Material-ui: using <Divider> breaks the grid - reactjs

so I have this annoying issue I can't find a result for.
I'm new to material-ui and it feels like I'm missing something here...
I just want a divider between the grid items, without it breaking the order of the grid. What am I missing?
Sandbox: https://vpbyd.csb.app/
import React from "react";
import "./styles.css";
import {Grid, Typography, Divider} from '#material-ui/core'
export default function App() {
return (
<div className="App">
<Grid container spacing={3}>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
One
</Typography>
</Grid>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
Two
</Typography>
</Grid>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
Three
</Typography>
</Grid>
</Grid>
<Grid container spacing={0} alignItems="center">
<Grid item xs={4}>
<Typography variant="h6" component="h2">
first value
</Typography>
</Grid>
<Divider orientation="vertical" flexItem/>
<Grid item xs={4}>
<Typography variant="h6" component="h2">
second value
</Typography>
</Grid>
<Divider orientation="vertical" flexItem/>
<Grid item xs={4}>
<Typography variant="h6" component="h2">
third value
</Typography>
</Grid>
</Grid>
</div>
);
}

I had the same issue and found a trick : add a negative right margin to your Divider
<Grid item xs={4}>
<Typography variant="h6" component="h2">
first value
</Typography>
</Grid>
<Divider orientation="vertical" flexItem sx={{ mr: "-1px" }} />
<Grid item xs={4}>
<Typography variant="h6" component="h2">
second value
</Typography>
</Grid>

Try putting the divider inside of a grid container of its own.
<Grid item xs={2}>
<Divider orientation="vertical" flexItem/>
</Grid>
The material ui grid uses flexbox so dropping an item inside of it that does not have the correct properties is going to mess up the grid.

A good generic solution to me is adding this global style
.MuiGrid-container > .MuiDivider-vertical.MuiDivider-flexItem {
margin-right: -1px;
}
in conjunction with adding the JSX property flexItem to the Divider:
<Grid container>
<Grid item xs={4}>
...
</Grid>
<Divider flexItem orientation="vertical" />
<Grid item xs={8}>
...
</Grid>
</Grid>
That's a clean, transparent workaround to me which keeps the grid flowing as expected.

None of those solutions above were ideal for me, so I ended up simulating a Divider by showing the right side left border (you could obviously also do it by showing the left side right border), with the same CSS properties that the Divider uses. Here's a small example:
<Grid
container
direction="row"
justifyContent="space-evenly"
alignItems="top"
>
<Grid
item
xs={6}
style={{
paddingRight: '10px',
}}
Left Side
</Grid>
<Grid
item
xs={6}
style={{
paddingLeft: '10px',
borderStyle: 'solid',
borderColor: 'rgba(0, 0, 0, 0.12)',
borderWidth: '0 0 0 1px'
}}
>
Right Side
</Grid>
</Grid>

note that you are passing 14 column in total to de grid container, at least on the sandbox. Anyway sometimes it happen with 12 columns, it work for me to pass empty breakpoints props at the last grid item, or even for all the Grid Items in your case will be:
import React from "react";
import "./styles.css";
import { Grid, Typography, Divider } from "#material-ui/core";
export default function App() {
return (
<div className="App">
<Grid container spacing={3}>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
One
</Typography>
</Grid>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
Two
</Typography>
</Grid>
<Grid item xs={4}>
<Typography variant="h5" component="h2">
Three
</Typography>
</Grid>
</Grid>
<Grid container spacing={0} alignItems="center">
<Grid item xs={4}>
<Typography variant="h6" component="h2">
first value
</Typography>
</Grid>
<Divider orientation="vertical" flexItem />
<Grid item xs={4}>
<Typography variant="h6" component="h2">
second value
</Typography>
</Grid>
<Divider orientation="vertical" flexItem />
<Grid item **xs**>
<Typography variant="h6" component="h2">
third value
</Typography>
</Grid>
</Grid>
</div>
);
}
This will say to the item to occupy all the available space.
The problem is that giving the 12 columns you are stablishing the 100% of the available space, and adding a divider then you have 100% + 1px. normally without grid you'll need to set a calc(100% - 1px).

Related

How do I center a vertical divider within a Material UI (v5) Grid?

I'm trying to put two centered paragraphs into a column <Grid>, separated by a vertical <Divider>. I added the divider as a Grid item, but the divider appears justified to the right instead of the center, between the two paragraphs. Here is my code:
<Grid item container direction="row" spacing={{ xs: 1, md: 3 }}>
<Grid item xs={5}>
<Typography variant="body2" align="center">
Paragraph A text
</Typography>
</Grid>
<Grid item xs={2}>
<Divider orientation="vertical" />
</Grid>
<Grid item xs={5}>
<Typography variant="body2" align="center">
Paragraph B text
</Typography>
</Grid>
</Grid>
With this code, the vertical divider is justified to the right. There is no change if I add justifyContent="center" to the container Grid, I assume because the divider is a right border. I think I need to add padding-right somehow, but calculated so that it is responsive to different screen widths. Any help would be much appreciated!
you need to remove spacing={{ xs: 1, md: 3 }} or change it
and for change Divider orientation use container in grid :
<Grid item container direction="row" >
<Grid item xs={5}>
<Typography variant="body2" align="center">
Paragraph A text
</Typography>
</Grid>
<Grid item xs={2}
container
direction="row"
justifyContent="center"
alignItems="center"
>
<Divider orientation="vertical" style={{height:'100%',width:'1px'}}/>
</Grid>
<Grid item xs={5}>
<Typography variant="body2" align="center">
Paragraph B text
</Typography>
</Grid>
</Grid>
codesandbox

Is there a prop in Material UI that allows to center everything inside a grid?

I am learning to use Material UI and I cannot figure out something that should be easy.
Given the card below
I want to make all the content centered except for the abcd, efgh, ijkl lines.
This is the final result I would like to have:
And This is the code:
<Grid container spacing={4} >
<Grid item xs={12} sm={6} md={4}>
<Card style={{ padding: '30px 40px 20px'}} >
<CardContent>
<Typography variant="h4" color="textSecondary" >
TEST
</Typography>
<Typography color="textSecondary">Something in here</Typography>
<Divider />
<Grid container justify={'space-between'}>
<Typography item color="textSecondary">
abcd
</Typography>
<Typography item color="textSecondary">
25
</Typography>
</Grid>
<Grid container justify={'space-between'}>
<Typography color="textSecondary">efgh</Typography>
<Typography color="textSecondary">15</Typography>
</Grid>
<Grid container justify={'space-between'}>
<Typography color="textSecondary">ijkl</Typography>
<Typography color="textSecondary">05</Typography>
</Grid>
</CardContent>
<CardActions disableSpacing>
<Button variant="contained" color="primary">
Action 1
</Button>
<Button variant="contained" color="primary">
Action 2
</Button>
</CardActions>
</Card>
</Grid>
</Grid>
I could get the result by giving to the Typograhy elements a style={{textAlign: 'center'}} and to the CardActions a style={{display: 'flex', justifyContent: 'space-between'}} but I was wondering if there is a better way, like a MUI prop to give to grid container that tells to center align everything inside.
I tried giving the grid a justify='center' but it is not doing anything.

Failed prop type: The prop justify of Grid must be used on container

I got the error while using Material-UI in react
<Grid container justify="center">
<Box className={classes.box}>
<Grid item className={classes.item1}>
<Typography variant="h5" className={classes.loginTitle}>
Login
</Typography>
<Typography variant="body1" className={classes.subTitle}>
to continue to Program
</Typography>
</Grid>
{renderForm(window.location.pathname)}
<Grid
item
className={classes.component}
alignItems="center"
justify="space-between"
>
<Typography
variant="body2"
color="primary"
className={classes.createAccountLink}
>
<Link
style={{ cursor: "pointer" }}
onClick={(e) => e.preventDefault()}
>
Create account
</Link>
</Typography>
<Button
variant="contained"
color="primary"
disableElevation
className={classes.btn}
>
Login
</Button>
</Grid>
Grid uses CSS flexbox for layout. You cannot set alignItems in a Grid item, it must be placed in a Grid container. See this interactive example to know how to use alignItems in
Grid.
// invalid
<Grid container>
<Grid item alignItems="center">
</Grid>
</Grid>
// valid
<Grid container alignItems="center">
<Grid item>
</Grid>
</Grid>

MaterialUI Grid direction=row not working

I am trying to make a grid of buttons aligned in specific order, but I am having difficulties with making both buttons on the same row:
Expected:
Instead, row2 (the two columns in red), appear in a column direction (the second column goes bellow the first columnt, screenshot: http://prntscr.com/x4amxf) and not in a row direction like I am expecting them to be.
Here is my grid:
<Grid container direction="column"> // this is another container that wraps everything, not in the picture above
<Grid item container direction="row"></Grid> // another row of stuff, not related, works just fine
// picture represents this grid
<Grid item container direction="row" spacing={1}>
<Grid align="center" direction="row" justify="center" item container xs={1}>
<Grid item container direction="column">
<Grid item></Grid>
<Grid item></Grid>
</Grid>
<Grid item container direction="column">
<Grid item></Grid>
<Grid item></Grid>
</Grid>
</Grid>
</Grid>
</Grid>
I have tried to increase xs to 2 to see if its a size issue, but it just stretched the items.
And the actual code (but the structure above represents the same):
<Grid container direction="column">
<Grid item container>
</Grid>
<Grid item container direction="row" spacing={1}>
<Grid item>
<AddPrice open={open} handleClosePopup={handleClose} item={item} />
<IconButton variant="contained" onClick={handleClose}>
<AddCircleOutlineIcon color="primary" style={{ fontSize: 40, marginRight: 5 }} />
<Typography>Цена</Typography>
</IconButton>
</Grid>
{item.prices.map(({ price, quantity }) => (
<React.Fragment key={`itemPrice1${price}`}>
<Grid align="center" direction="row" justify="center" item container xs={1}>
<Grid item container direction="column">
<Grid item>
<Button>
<Grid item direction="column" container>
<Grid item>
<Typography variant="button">{price} лв.</Typography>
</Grid>
<Grid item>
<Typography variant="button">
{quantity.available} {item.quantity.type}.
</Typography>
</Grid>
</Grid>
</Button>
</Grid>
</Grid>
{editing && (
<Grid item container direction="column">
<Grid item>
<IconButton style={{ border: "1px solid #f44336" }} variant="contained" color="secondary">
<DeleteForever color="secondary" style={{ fontSize: 30 }} />
</IconButton>
</Grid>
<Grid item>
<IconButton style={{ border: "1px solid #3f51b5" }}>
<EditIcon color="primary" style={{ fontSize: 30 }} />
</IconButton>
</Grid>
</Grid>
)}
</Grid>
</React.Fragment>
))}
</Grid>
<Grid item container></Grid>
</Grid>
Basically, the editing buttons, should appear on the right of the price buttons.
Sandbox: https://codesandbox.io/s/material-demo-forked-6v50s?file=/demo.js
If I understood the task correctly, you have to refactor your layout like this:
<Grid container direction="column">
<Grid item container direciton="row">
Row1
</Grid>
<Grid align="center" direction="row" container>
<Grid item xs={2} style={{ border: "1px solid black" }}>
<Grid item>BR</Grid>
<Grid item>TXT</Grid>
</Grid>
<Grid item xs={2} style={{ border: "1px solid black" }}>
<Grid item>EDIT</Grid>
<Grid item>DELETE</Grid>
</Grid>
</Grid>
</Grid>
Please, check out the example

Centered icon and text (React Material-UI)

I am interested in best way to present a React Material-UI with icon and text, so it is all vertically aligned. Right now it does not work as expected, especially with conditional rendering.
<Typography gutterBottom variant="subtitle2" component="h2" align="center">
<Grid container direction="row" alignItems="center" wrap="nowrap">
{p.numRooms > 0 && (
<Grid item xs={2} alignItems="center">
<HotelRoundedIcon color="secondary" />
{p.numRooms}
</Grid>
)}
{p.area > 0 && (
<Grid item xs={2}>
<AspectRatioRounded color="secondary" />
{p.area}
</Grid>
)}
</Grid>
</Typography>
You can add container in your secondary Grids to make icons and text vertically aligned.
<Typography gutterBottom variant="subtitle2" component="h2" align="center">
<Grid container direction="row" alignItems="center" wrap="nowrap">
{p.numRooms > 0 && (
<Grid item xs={2} container >
<HotelRoundedIcon color="secondary" />
{p.numRooms}
</Grid>
)}
{p.area > 0 && (
<Grid item xs={2} container>
<AspectRatioRounded color="secondary" />
{p.area}
</Grid>
)}
</Grid>
</Typography>

Resources