Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Grid2] Replace context with cloneElement #36399

Merged
merged 12 commits into from
Apr 17, 2023

Conversation

siriwatknp
Copy link
Member

@siriwatknp siriwatknp commented Mar 2, 2023

BREAKING CHANGE

Grid2 now uses React.cloneElement (was React context) to pass the spacing and columns to the next container. The change is close to how CSS flexbox behaves.


closes #36372, closes #36777 visual regression added.

Before

https://stackblitz.com/edit/react-ts-v9cb4z?file=App.tsx

image

After

https://codesandbox.io/s/material-cra-ts-forked-h3qicw?file=/src/App.tsx

image


@siriwatknp siriwatknp added component: Grid The React component. package: system Specific to @mui/system labels Mar 2, 2023
@mui-bot
Copy link

mui-bot commented Mar 2, 2023

Netlify deploy preview

@material-ui/core: parsed: +0.06% , gzip: +0.06%
@material-ui/system: parsed: +0.52% , gzip: +0.43%
@mui/joy: parsed: +0.08% , gzip: +0.08%

Bundle size report

Details of bundle changes

Generated by 🚫 dangerJS against 44a703f

@siriwatknp siriwatknp marked this pull request as ready for review March 3, 2023 04:23
@siriwatknp siriwatknp added the bug 🐛 Something doesn't work label Mar 3, 2023
@siriwatknp siriwatknp requested review from mnajdova and a team March 3, 2023 04:38
@omermizr
Copy link

omermizr commented Mar 3, 2023

Hey @siriwatknp, thanks for looking into this!
However, I tried this out with a few more test cases and found some issues. Here's the demo: https://codesandbox.io/s/material-cra-ts-forked-6hnmq4?file=/src/App.tsx
And more in depth:

  1. A container that's a direct child of another container, but no child grids items has negative margins applied, but no padding. I'm not sure if this is just how it's supposed to work, but with the standard Grid (at least in v4) it was ok. Here the content looks off. (see Item 3 in the demo)
  2. A container that's a direct child of another container and has a child grid item has extra padding applied to the top. (see Item 4 in the demo)
  3. I don't think the last grid item should have a bottom padding (the first item doesn't have top padding), but I'm not sure about that. If you look at my example it seems pretty arbitrary. (see Item 5 in the demo)

Thanks again!

@ghost
Copy link

ghost commented Mar 10, 2023

Is having no padding and spacing the intended way ? When do you think it will be fixed ?

@siriwatknp
Copy link
Member Author

@omermizr It looks all correct to me.

(1) The usage is wrong. Grid containers and items should be used together, otherwise, there is no point in using the Grid component. We could make the docs more explicit on this point in https://mui.com/material-ui/react-grid2/#basic-grid.

(2, 3) Those padding is correct. The goal of the grid is to create consistent spacing between grid items. If you take a look at this https://codesandbox.io/s/material-cra-ts-forked-01y0gm?file=/src/App.tsx, you will see that the spacing between grid items is 24px which corresponds to the spacing={3}.

@siriwatknp
Copy link
Member Author

Is having no padding and spacing the intended way ? When do you think it will be fixed ?

I guess you meant to use CSS flexbox gap instead of margin, and padding? It is not possible with the current Grid APIs (I have tried but failed).

It is definitely better to have Flexbox Grid using gap but it must be a different component and different API (not with container and item).

* <Grid> // level 1
* ```
*/
level?: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation of making this a public API? If we don't want it to be public, maybe we should prefix it with internal_.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this question, it's still not clear to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will make it unstable_ for consistency.

/>
>
{React.Children.map(children, (child) => {
if (React.isValidElement(child) && isMuiElement(child, ['Grid'])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work if the Grid is styled? Should we add a test for it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Good point. Visual regression added.

@omermizr
Copy link

@omermizr It looks all correct to me.

(1) The usage is wrong. Grid containers and items should be used together, otherwise, there is no point in using the Grid component. We could make the docs more explicit on this point in https://mui.com/material-ui/react-grid2/#basic-grid.

(2, 3) Those padding is correct. The goal of the grid is to create consistent spacing between grid items. If you take a look at this https://codesandbox.io/s/material-cra-ts-forked-01y0gm?file=/src/App.tsx, you will see that the spacing between grid items is 24px which corresponds to the spacing={3}.

Thanks @siriwatknp!
(1) - ok, I thought that might not be the correct usage but I wasn't sure because it worked fine with Grid in MUI 4. Yeah I think the docs could be more explicit about this.
(2) - I get it, so the padding comes from it being a grid item. That makes sense, but the current implementation doesn't feel ergonomically correct. If I create a simple Grid2, with one of the items being a container, the padding is all off and I'd have to change it explicitly in order for the spacing to be consistent. See this simplified example: https://codesandbox.io/s/material-cra-ts-forked-60ryz2 (Just 3 grid items, the middle one is a container, but they are all differently sized and padded).
(3) - This still seems inconsistent to me, especially because of your wording "between grid items". If I have 2 grid items, the first one doesn't seem to have any padding applied to the top (it actually does, but it gets offset by the negative margin), but the second one does have bottom padding. See here: https://codesandbox.io/s/material-cra-ts-forked-jvm2g0

@siriwatknp
Copy link
Member Author

siriwatknp commented Mar 20, 2023

(2) - I get it, so the padding comes from it being a grid item. That makes sense, but the current implementation doesn't feel ergonomically correct. If I create a simple Grid2, with one of the items being a container, the padding is all off and I'd have to change it explicitly in order for the spacing to be consistent. See this simplified example: https://codesandbox.io/s/material-cra-ts-forked-60ryz2 (Just 3 grid items, the middle one is a container, but they are all differently sized and padded).

Honestly, I don't understand your point on the padding is all off and I'd have to change it explicitly in order for the spacing to be consistent.

What do you have to change? because if I remove the background from your sandbox, the spacing looks correct https://codesandbox.io/s/material-cra-ts-forked-jcio79?file=/src/App.tsx.

If you really want to add backgrounds, you should add them to grid items (not containers).

(3) - This still seems inconsistent to me, especially because of your wording "between grid items". If I have 2 grid items, the first one doesn't seem to have any padding applied to the top (it actually does, but it gets offset by the negative margin), but the second one does have bottom padding. See here: https://codesandbox.io/s/material-cra-ts-forked-jvm2g0

My bad, it is not between grid items but between grid items' content. I hope this picture is clearer.

image


One thing I notice in all of your examples is direction="column". I don't see any reason to use Grid with direction="column", if you have a valid use case please share it.

Comment on lines +223 to +225
if (tag.muiName) {
Component.muiName = tag.muiName;
}
Copy link
Member Author

@siriwatknp siriwatknp Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnajdova This is required to make styled(Grid2) works. Some Joy UI components would benefit from this fix as well.

@omermizr
Copy link

Honestly, I don't understand your point on the padding is all off and I'd have to change it explicitly in order for the spacing to be consistent.

What do you have to change? because if I remove the background from your sandbox, the spacing looks correct https://codesandbox.io/s/material-cra-ts-forked-jcio79?file=/src/App.tsx.

If you really want to add backgrounds, you should add them to grid items (not containers).

Ok yes, if we remove the background color the Grid items look better, but does that mean we shouldn't expect styling to behave "normally"? If I need to set a background color for a container, how would I go about doing that? And background color is one thing, but I suspect there would be other things (like borders?) that might feel strange.

My bad, it is not between grid items but between grid items' content. I hope this picture is clearer.

image

But my issue is that the last grid item content has extra spacing after it, but the first one doesn't have extra spacing before it... Even without background color, it just means the next element in the dom would be further away for no apparent reason. Maybe this clarifies it:
image

This might be the same issue as before actually, because the negative margin means the next dom element would be affected by the negative margin 🤔

@siriwatknp
Copy link
Member Author

siriwatknp commented Mar 21, 2023

Ok yes, if we remove the background color the Grid items look better, but does that mean we shouldn't expect styling to behave "normally"? If I need to set a background color for a container, how would I go about doing that? And background color is one thing, but I suspect there would be other things (like borders?) that might feel strange.

You might be able to style the root grid container but not a nested container. I think styling grid items should be the first option:

<Grid container sx={{ '& > .MuiGrid2-root:not(.MuiGrid2-container)': {
  backgroundColor: 'red',
}}}>
  <Grid></Grid>
  <Grid></Grid>
</Grid>

But my issue is that the last grid item content has extra spacing after it, but the first one doesn't have extra spacing before it... Even without background color, it just means the next element in the dom would be further away for no apparent reason. Maybe this clarifies it:

Now I got it. I don't think that's an issue. It is the effect of a negative margin that behaves the same since Material UI v4. You could say that it is a limitation, so you have to manually add spacing to the next element of the grid.

<Grid container spacing={3}></Grid>
<Box sx={{ mt: 1.5 }}>test</Box>

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 22, 2023
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 3, 2023
@siriwatknp
Copy link
Member Author

This will fix #36777

Proof: https://codesandbox.io/s/material-cra-forked-hc042i?file=/src/App.js

@siriwatknp
Copy link
Member Author

@mnajdova I think this PR is ready to go.

Copy link
Member

@mnajdova mnajdova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments, the logic looks good 👍


A nested grid container will inherits the columns from its parent unless the `columns` prop is specified to the instance.
Note that a nested grid container should be a direct child of another grid container. If there are non-grid elements in between, the grid container will start as the new root container.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes much more sense 👍 Note, we need to add a BREAKING CHANGE section in the PR description (and in the chalengelog entry).

* <Grid> // level 1
* ```
*/
level?: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this question, it's still not clear to me.

</Grid>
</Grid>
</Box>
<Grid container xs={6} spacing={3}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Grid container xs={6} spacing={3}>
<Grid container xs={6}>

Should we remove the spacing from some of these children and test that it will be inherited from the parent?

@siriwatknp siriwatknp merged commit 7310533 into mui:master Apr 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change bug 🐛 Something doesn't work component: Grid The React component. package: system Specific to @mui/system
Projects
None yet
4 participants