Repository: mui/material-ui (TypeScript)
Date: 2022-03-06 14:07:52+00:00
Task type: Bug Fix

Issue:
[Grid] Wrong grid item width for nested containers with custom columns prop
### Duplicates

- [X] I have searched the existing issues

### Latest version

- [X] I have tested the latest version

### Current behavior 😯

Cell width is calculating incorrect for nested containers with custom `columns` prop.

```html
<Grid container columns={11}>
    <Grid item xs={4}>
        <Grid container>
            <Grid item xs={12}>
                Calculated width is 109.090909%
            </Grid>
        </Grid>
    </Grid>
    <Grid item xs={4}>
        <Grid container columns={12}>
            <Grid item xs={12}>
                Calculated width is 109.090909%
            </Grid>
        </Grid>
    </Grid>
    <Grid item xs={3}>
        ...
    </Grid>
</Grid>
```

So, the value of `columns` prop from top-level container is used for calculating all item widths. All nested `columns` props are ignored.

I guess, this issue is related to #28554 

### Expected behavior 🤔

Cell width should be calculating based on `columns` prop value of the parent grid container.

### Steps to reproduce 🕹

_No response_

### Context 🔦

_No response_

### Your environment 🌎

<details>
  <summary>`npx @mui/envinfo`</summary>

```
  System:
    OS: macOS 11.6.1
  Binaries:
    Node: 16.8.0 - /usr/local/bin/node
    Yarn: 1.22.11 - /usr/local/bin/yarn
    npm: 7.21.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 96.0.4664.110
    Edge: Not Found
    Firefox: 92.0
    Safari: 15.1
  npmPackages:
    @emotion/react: ^11.5.0 => 11.6.0 
    @emotion/styled: ^11.3.0 => 11.6.0 
    @mui/base:  5.0.0-alpha.55 
    @mui/icons-material: ^5.0.4 => 5.1.1 
    @mui/lab: ^5.0.0-alpha.55 => 5.0.0-alpha.55 
    @mui/material: ^5.1.0 => 5.1.1 
    @mui/private-theming:  5.1.1 
    @mui/styled-engine:  5.1.1 
    @mui/system:  5.1.1 
    @mui/types:  7.1.0 
    @mui/utils:  5.1.1 
    @types/react: ^17.0.0 => 17.0.35 
    react: ^17.0.2 => 17.0.2 
    react-dom: ^17.0.2 => 17.0.2 
    typescript: ^4.4.3 => 4.4.4 
```
</details>



Issue discussion:
I'm not sure if I understand the problem. I tried to reproduce it in codesandbox using the code you provided (I used 5-column grid for better visibility): https://codesandbox.io/s/proud-shape-gz9n1?file=/src/Demo.tsx

The whole grid is 500px wide and the grey and green cells have 200px and 100px respectively, as I expected. Could you explain in more detail what you would expect?
Hi @michaldudak ,
please check the calculated value of `max-width` property for nested grid items. 
<img width="1612" alt="Screen Shot 2021-12-21 at 22 32 51" src="https://user-images.githubusercontent.com/5411244/146994321-e3bf1298-e69a-4f0b-ae75-4c3abdbcf912.png">

@AlexKrupko indeed, this doesn't look correct.
@alonmatthew and I found if you set the nested columns grid explicitly to: `<Grid columns={12}>`, it will still inherit the parent grid column count.

However, if you set either of these, it will work:
- `<Grid columns={{xs: 12}}/>`
- `<Grid columns={'12'}/>`
@michaldudak Is there somewhere in the documentation that says Grid's should inherit their parent Grid container's column prop? IMO this is not intuitive.

I would expect the nested grid here to be 12 columns, as is default:
https://codesandbox.io/s/nestedgrid-material-demo-forked-ghqye

Here's an example of trying to manually override it in a basic shorthand use case but it doesn't work:
https://codesandbox.io/s/nestedgrid-material-demo-forked-u65ly

Hacky version to get it to actually override:
- https://codesandbox.io/s/nestedgrid-material-demo-forked-zfy4j?file=/index.js => String works but not number?
- https://codesandbox.io/s/nestedgrid-material-demo-forked-hu2x0?file=/index.js => Object works
No, I believe it shouldn't work like that and it's a bug. The columns prop should behave the same no matter if it's a top-level or nested grid. Would you like to take a look at it and contribute a fix?
@michaldudak Sure. Thanks for clarifying.
Hi @michaldudak, I think @ConnerAiken isn't available, I will work on this.
Thanks @boutahlilsoufiane, my 9-5 is blocking me from helping.

Solution patch:
diff --git a/packages/mui-material/src/Grid/Grid.js b/packages/mui-material/src/Grid/Grid.js
--- a/packages/mui-material/src/Grid/Grid.js
+++ b/packages/mui-material/src/Grid/Grid.js
@@ -312,9 +312,8 @@ const Grid = React.forwardRef(function Grid(inProps, ref) {
 
   const columnsContext = React.useContext(GridContext);
 
-  // setting prop before context to accomodate nesting
-  // colums set with default breakpoint unit of 12
-  const columns = columnsProp || columnsContext || 12;
+  // columns set with default breakpoint unit of 12
+  const columns = container ? columnsProp || 12 : columnsContext;
 
   const ownerState = {
     ...props,
@@ -335,21 +334,16 @@ const Grid = React.forwardRef(function Grid(inProps, ref) {
 
   const classes = useUtilityClasses(ownerState);
 
-  const wrapChild = (element) =>
-    columns !== 12 ? (
-      <GridContext.Provider value={columns}>{element}</GridContext.Provider>
-    ) : (
-      element
-    );
-
-  return wrapChild(
-    <GridRoot
-      ownerState={ownerState}
-      className={clsx(classes.root, className)}
-      as={component}
-      ref={ref}
-      {...other}
-    />,
+  return (
+    <GridContext.Provider value={columns}>
+      <GridRoot
+        ownerState={ownerState}
+        className={clsx(classes.root, className)}
+        as={component}
+        ref={ref}
+        {...other}
+      />
+    </GridContext.Provider>
   );
 });
 


Test patch:
diff --git a/packages/mui-material/src/Grid/Grid.test.js b/packages/mui-material/src/Grid/Grid.test.js
--- a/packages/mui-material/src/Grid/Grid.test.js
+++ b/packages/mui-material/src/Grid/Grid.test.js
@@ -45,6 +45,36 @@ describe('<Grid />', () => {
       // otherwise, max-width would be 50% in this test
       expect(container.firstChild).toHaveComputedStyle({ maxWidth: '100%' });
     });
+
+    it('should apply the correct number of columns for nested containers with undefined prop columns', () => {
+      const { getByTestId } = render(
+        <Grid container columns={16}>
+          <Grid item xs={8}>
+            <Grid container data-testid="nested-container-in-item">
+              <Grid item xs={12} />
+            </Grid>
+          </Grid>
+        </Grid>,
+      );
+
+      const container = getByTestId('nested-container-in-item');
+      expect(container.firstChild).toHaveComputedStyle({ maxWidth: '100%' });
+    });
+
+    it('should apply the correct number of columns for nested containers with columns=12 (default)', () => {
+      const { getByTestId } = render(
+        <Grid container columns={16}>
+          <Grid item xs={8}>
+            <Grid container columns={12} data-testid="nested-container-in-item">
+              <Grid item xs={12} />
+            </Grid>
+          </Grid>
+        </Grid>,
+      );
+
+      const container = getByTestId('nested-container-in-item');
+      expect(container.firstChild).toHaveComputedStyle({ maxWidth: '100%' });
+    });
   });
 
   describe('prop: item', () => {