Skip to content

Commit 413d5b0

Browse files
support custom transformations
1 parent ed54921 commit 413d5b0

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

.size-limit.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = [
2222
name: 'The size of the @material-ui/core modules',
2323
webpack: true,
2424
path: 'packages/material-ui/build/index.js',
25-
limit: '95.6 KB',
25+
limit: '95.7 KB',
2626
},
2727
{
2828
name: 'The size of the @material-ui/styles modules',

docs/src/pages/layout/grid/grid.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ The grid system is implemented with the `Grid` component:
2323
## Spacing
2424

2525
The responsive grid focuses on consistent spacing widths, rather than column width.
26-
Material design margins and columns follow an **8dp** square baseline grid.
27-
Spacing can be 8, 16, 24, 32 or 40dp wide.
26+
Material design margins and columns follow an **8px** square baseline grid.
27+
The spacing property is an integer in the [0, 8] interval.
28+
By default, the spacing between two grid items follows a linear function: `output(spacing) = spacing * 8px`, e.g. `spacing={2}` creates a 16px wide gap.
29+
30+
This output transformation function can be customized using the theme, exactly like [the system spacing](/system/spacing/#transformation).
2831

2932
{{"demo": "pages/layout/grid/SpacingGrid.js"}}
3033

packages/material-ui/src/Grid/Grid.js

+46-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111

1212
import React from 'react';
1313
import PropTypes from 'prop-types';
14+
import warning from 'warning';
1415
import classNames from 'classnames';
1516
import { componentPropType } from '@material-ui/utils';
1617
import withStyles from '../styles/withStyles';
1718
import { keys as breakpointKeys } from '../styles/createBreakpoints';
1819
import requirePropFactory from '../utils/requirePropFactory';
1920

20-
const GUTTERS = [0, 1, 2, 3, 4, 5, 6, 7, 8];
21+
const SPACINGS = [0, 1, 2, 3, 4, 5, 6, 7, 8];
2122
const GRID_SIZES = ['auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
2223

2324
function generateGrid(globalStyles, theme, breakpoint) {
@@ -65,16 +66,57 @@ function generateGrid(globalStyles, theme, breakpoint) {
6566
}
6667
}
6768

69+
// Same logic as /packages/material-ui-system/src/spacing.js
70+
function getTransformer(theme) {
71+
const themeTransformer =
72+
theme.spacing && theme.spacing.unit != null ? theme.spacing.unit : theme.spacing || 8;
73+
74+
if (typeof themeTransformer === 'number') {
75+
return abs => themeTransformer * abs;
76+
}
77+
78+
if (Array.isArray(themeTransformer)) {
79+
return abs => {
80+
warning(
81+
abs <= themeTransformer.length - 1,
82+
[
83+
`@material-ui/core: the value provided (${abs}) overflows.`,
84+
`The supported values are: ${JSON.stringify(themeTransformer)}.`,
85+
`${abs} > ${themeTransformer.length - 1}, you need to add the missing values.`,
86+
].join('\n'),
87+
);
88+
89+
return themeTransformer[abs];
90+
};
91+
}
92+
93+
if (typeof themeTransformer === 'function') {
94+
return themeTransformer;
95+
}
96+
97+
warning(
98+
false,
99+
[
100+
`@material-ui/core: the \`theme.spacing\` value (${themeTransformer}) is invalid.`,
101+
'It should be a number, an array or a function.',
102+
].join('\n'),
103+
);
104+
105+
return () => undefined;
106+
}
107+
68108
function generateGutter(theme, breakpoint) {
69109
const styles = {};
70110

71-
GUTTERS.forEach((spacing, index) => {
111+
const transformer = getTransformer(theme);
112+
113+
SPACINGS.forEach((spacing, index) => {
72114
if (index === 0) {
73115
// Skip the default style.
74116
return;
75117
}
76118

77-
const themeSpacing = spacing * theme.spacing.unit;
119+
const themeSpacing = transformer(spacing);
78120

79121
styles[`spacing-${breakpoint}-${spacing}`] = {
80122
margin: -themeSpacing / 2,
@@ -324,7 +366,7 @@ Grid.propTypes = {
324366
* Defines the space between the type `item` component.
325367
* It can only be used on a type `container` component.
326368
*/
327-
spacing: PropTypes.oneOf(GUTTERS),
369+
spacing: PropTypes.oneOf(SPACINGS),
328370
/**
329371
* Defines the `flex-wrap` style property.
330372
* It's applied for all screen sizes.

0 commit comments

Comments
 (0)