Skip to content

Commit

Permalink
polish
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Jun 6, 2021
1 parent 650c4d8 commit a018eed
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 23 deletions.
8 changes: 7 additions & 1 deletion docs/pages/api-docs/grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"props": {
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" } },
"columns": { "type": { "name": "number" }, "default": "12" },
"columns": {
"type": {
"name": "union",
"description": "Array&lt;number&gt;<br>&#124;&nbsp;number<br>&#124;&nbsp;object"
},
"default": "12"
},
"component": { "type": { "name": "elementType" } },
"container": { "type": { "name": "bool" } },
"direction": {
Expand Down
26 changes: 26 additions & 0 deletions docs/src/pages/components/grid/ResponsiveGrid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';

const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2,
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

export default function ResponsiveGrid() {
return (
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 4, sm: 8, md: 12 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid item xs={2} sm={4} md={4} key={index}>
<Item>xs=2</Item>
</Grid>
))}
</Grid>
</Box>
);
}
26 changes: 26 additions & 0 deletions docs/src/pages/components/grid/ResponsiveGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react';
import { experimentalStyled as styled } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';

const Item = styled(Paper)(({ theme }) => ({
...theme.typography.body2,
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

export default function ResponsiveGrid() {
return (
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 4, sm: 8, md: 12 }}>
{Array.from(Array(6)).map((_, index) => (
<Grid item xs={2} sm={4} md={4} key={index}>
<Item>xs=2</Item>
</Grid>
))}
</Grid>
</Box>
);
}
23 changes: 23 additions & 0 deletions docs/src/pages/components/grid/grid.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@ The prop is converted into a CSS property using the [`theme.spacing()`](/customi

{{"demo": "pages/components/grid/SpacingGrid.js", "bg": true}}

## Responsive values

You can switch the props' value based on the active breakpoint.
For instance, we can implement the ["recommended"](https://material.io/design/layout/responsive-layout-grid.html) responsive layout grid of Material Design.

{{"demo": "pages/components/grid/ResponsiveGrid.js", "bg": true}}

Responsive values is supported by:

- `spacing`
- `direction`
- `columns`
- all the [other props](#system-props) of the system

> ⚠️ When using a responsive `columns` prop, each grid item needs its corresponding breakpoint.
> For instance, this is not working. The grid item misses the value for `md`:
>
> ```jsx
> <Grid container columns={{ xs: 4, md: 12 }}>
> <Grid item xs={2} />
> </Grid>
> ```
## Interactive

Below is an interactive demo that lets you explore the visual results of the different settings:
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/components/stack/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Use the `divider` prop to insert an element between each child. This works parti

## Responsive values

Easily switch `direction` or `spacing` based on the active breakpoint.
You can switch the `direction` or `spacing` values based on the active breakpoint.

{{"demo": "pages/components/stack/ResponsiveStack.js", "bg": true}}

Expand Down
4 changes: 0 additions & 4 deletions packages/material-ui-system/src/breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ const defaultBreakpoints = {
export function handleBreakpoints(props, propValue, styleFromPropValue) {
const theme = props.theme || {};

if (propValue == null) {
return {};
}

if (Array.isArray(propValue)) {
const themeBreakpoints = theme.breakpoints || defaultBreakpoints;
return propValue.reduce((acc, item, index) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui/src/Grid/Grid.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface GridTypeMap<P = {}, D extends React.ElementType = 'div'> {
* The number of columns.
* @default 12
*/
columns?: number;
columns?: ResponsiveStyleValue<number>;
/**
* If `true`, the component will have the flex *container* behavior.
* You should be wrapping *items* with a *container*.
Expand Down
65 changes: 49 additions & 16 deletions packages/material-ui/src/Grid/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ function getOffset(val) {
return `${parse}${String(val).replace(String(parse), '') || 'px'}`;
}

// Duplicated with Stack.js
function resolveBreakpointValues({ values, base }) {
const keys = Object.keys(base);

if (keys.length === 0) {
return values;
}

let previous;

return keys.reduce((acc, breakpoint) => {
if (typeof values === 'object') {
acc[breakpoint] = values[breakpoint] != null ? values[breakpoint] : values[previous];
} else {
acc[breakpoint] = values;
}
previous = breakpoint;
return acc;
}, {});
}

function generateGrid(globalStyles, theme, breakpoint, styleProps) {
const size = styleProps[breakpoint];

Expand All @@ -46,8 +67,13 @@ function generateGrid(globalStyles, theme, breakpoint, styleProps) {
maxWidth: 'none',
};
} else {
const columnsBreakpointValues = resolveBreakpointValues({
values: styleProps.columns,
base: theme.breakpoints.values,
});

// Keep 7 significant numbers.
const width = `${Math.round((size / styleProps.columns) * 10e7) / 10e5}%`;
const width = `${Math.round((size / columnsBreakpointValues[breakpoint]) * 10e7) / 10e5}%`;
let more = {};

if (styleProps.container && styleProps.item && styleProps.spacing !== 0) {
Expand Down Expand Up @@ -79,6 +105,22 @@ function generateGrid(globalStyles, theme, breakpoint, styleProps) {
}
}

function generateDirection({ theme, styleProps }) {
return handleBreakpoints({ theme }, styleProps.direction, (propValue) => {
const output = {
flexDirection: propValue,
};

if (propValue.indexOf('column') === 0) {
output[`&> .${gridClasses.item}`] = {
maxWidth: 'none',
};
}

return output;
});
}

function generateGap({ theme, styleProps }) {
const { container, spacing } = styleProps;
let styles = {};
Expand Down Expand Up @@ -155,20 +197,7 @@ const GridRoot = styled('div', {
flexWrap: 'wrap-reverse',
}),
}),
({ theme, styleProps }) =>
handleBreakpoints({ theme }, styleProps.direction, (propValue) => {
const output = {
flexDirection: propValue,
};

if (propValue.indexOf('column') === 0) {
output[`&> .${gridClasses.item}`] = {
maxWidth: 'none',
};
}

return output;
}),
generateDirection,
generateGap,
({ theme, styleProps }) =>
theme.breakpoints.keys.reduce((globalStyles, breakpoint) => {
Expand Down Expand Up @@ -282,7 +311,11 @@ Grid.propTypes /* remove-proptypes */ = {
* The number of columns.
* @default 12
*/
columns: PropTypes.number,
columns: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.number),
PropTypes.number,
PropTypes.object,
]),
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui/src/Stack/Stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function joinChildren(children, separator) {
}, []);
}

// Duplicated with Grid.js
function resolveBreakpointValues({ values, base }) {
const keys = Object.keys(base);

Expand Down

0 comments on commit a018eed

Please sign in to comment.