From 1bd4d245c201010fb90499a3e2e85c8d82a5d52d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 29 Aug 2020 09:39:28 +0200 Subject: [PATCH 1/2] added theme.mixins.gutters() in adaptV4Theme --- .../material-ui/src/styles/adaptV4Theme.js | 24 ++ .../src/styles/adaptV4Theme.test.js | 356 +++++++++++------- 2 files changed, 243 insertions(+), 137 deletions(-) diff --git a/packages/material-ui/src/styles/adaptV4Theme.js b/packages/material-ui/src/styles/adaptV4Theme.js index f58be7d62a028f..e2a61e6adf68ca 100644 --- a/packages/material-ui/src/styles/adaptV4Theme.js +++ b/packages/material-ui/src/styles/adaptV4Theme.js @@ -1,3 +1,6 @@ +import createBreakpoints from './createBreakpoints'; +import createSpacing from './createSpacing'; + export default function adaptV4Theme(inputTheme) { if (process.env.NODE_ENV !== 'production') { console.warn( @@ -13,6 +16,7 @@ export default function adaptV4Theme(inputTheme) { defaultProps = {}, styleOverrides = {}, overrides = {}, + mixins = {}, ...other } = inputTheme; const theme = { @@ -46,5 +50,25 @@ export default function adaptV4Theme(inputTheme) { theme.components[component] = componentValue; }); + // theme.mixins.gutters + const breakpoints = createBreakpoints(inputTheme.breakpoints || {}); + const spacing = createSpacing(inputTheme.spacing); + + theme.mixins = { + gutters: (styles = {}) => { + return { + paddingLeft: spacing(2), + paddingRight: spacing(2), + ...styles, + [breakpoints.up('sm')]: { + paddingLeft: spacing(3), + paddingRight: spacing(3), + ...styles[breakpoints.up('sm')], + }, + }; + }, + ...mixins, + }; + return theme; } diff --git a/packages/material-ui/src/styles/adaptV4Theme.test.js b/packages/material-ui/src/styles/adaptV4Theme.test.js index f527a93e80e5e8..4dcf262a8b41b7 100644 --- a/packages/material-ui/src/styles/adaptV4Theme.test.js +++ b/packages/material-ui/src/styles/adaptV4Theme.test.js @@ -2,183 +2,265 @@ import { expect } from 'chai'; import adaptV4Theme from './adaptV4Theme'; describe('adaptV4Theme', () => { - it("moves props to components' defaultProps", () => { - const theme = { - props: { - MuiButton: { - disabled: true, + describe('theme.components', () => { + it("moves props to components' defaultProps", () => { + const theme = { + props: { + MuiButton: { + disabled: true, + }, }, - }, - }; + }; - let transformedTheme; + let transformedTheme; - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); - expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal(theme.props.MuiButton); - }); + expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( + theme.props.MuiButton, + ); + }); - it("moves overrides to components' styleOverrides", () => { - const theme = { - overrides: { - MuiTable: { - root: { - background: 'red', + it("moves overrides to components' styleOverrides", () => { + const theme = { + overrides: { + MuiTable: { + root: { + background: 'red', + }, }, }, - }, - }; + }; - let transformedTheme; + let transformedTheme; - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); - expect(transformedTheme.components.MuiTable.styleOverrides).to.deep.equal( - theme.overrides.MuiTable, - ); - }); + expect(transformedTheme.components.MuiTable.styleOverrides).to.deep.equal( + theme.overrides.MuiTable, + ); + }); - it('moves props, and overrides to components', () => { - const theme = { - props: { - MuiButton: { - disabled: true, + it('moves props, and overrides to components', () => { + const theme = { + props: { + MuiButton: { + disabled: true, + }, }, - }, - overrides: { - MuiTable: { - root: { - background: 'red', + overrides: { + MuiTable: { + root: { + background: 'red', + }, }, }, - }, - }; + }; - let transformedTheme; + let transformedTheme; - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); - expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal(theme.props.MuiButton); - expect(transformedTheme.components.MuiTable.styleOverrides).to.deep.equal( - theme.overrides.MuiTable, - ); - }); + expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( + theme.props.MuiButton, + ); + expect(transformedTheme.components.MuiTable.styleOverrides).to.deep.equal( + theme.overrides.MuiTable, + ); + }); - it('merges props and overrides to components', () => { - const theme = { - props: { - MuiButton: { - disabled: true, + it('merges props and overrides to components', () => { + const theme = { + props: { + MuiButton: { + disabled: true, + }, }, - }, - overrides: { - MuiButton: { - root: { - background: 'red', + overrides: { + MuiButton: { + root: { + background: 'red', + }, }, }, - }, - }; + }; - let transformedTheme; + let transformedTheme; - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); - expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal(theme.props.MuiButton); - expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( - theme.overrides.MuiButton, - ); - }); + expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( + theme.props.MuiButton, + ); + expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( + theme.overrides.MuiButton, + ); + }); - it('merges props and overrides from different components in appropriate key', () => { - const theme = { - props: { - MuiButton: { - disabled: true, + it('merges props and overrides from different components in appropriate key', () => { + const theme = { + props: { + MuiButton: { + disabled: true, + }, + MuiFab: { + color: 'primary', + }, }, - MuiFab: { - color: 'primary', + overrides: { + MuiButton: { + root: { + background: 'red', + }, + }, + MuiFab: { + root: { + color: 'red', + }, + }, }, - }, - overrides: { - MuiButton: { - root: { - background: 'red', + }; + + let transformedTheme; + + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); + + expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( + theme.props.MuiButton, + ); + expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( + theme.overrides.MuiButton, + ); + + expect(transformedTheme.components.MuiFab.defaultProps).to.deep.equal(theme.props.MuiFab); + expect(transformedTheme.components.MuiFab.styleOverrides).to.deep.equal( + theme.overrides.MuiFab, + ); + }); + + it('merges partially migrated props and overrides from different components in appropriate key', () => { + const theme = { + defaultProps: { + MuiButton: { + disabled: true, + }, + MuiFab: { + color: 'primary', }, }, - MuiFab: { - root: { - color: 'red', + styleOverrides: { + MuiButton: { + root: { + background: 'red', + }, + }, + MuiFab: { + root: { + color: 'red', + }, }, }, - }, - }; + }; - let transformedTheme; + let transformedTheme; - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); - expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal(theme.props.MuiButton); - expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( - theme.overrides.MuiButton, - ); + expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( + theme.defaultProps.MuiButton, + ); + expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( + theme.styleOverrides.MuiButton, + ); - expect(transformedTheme.components.MuiFab.defaultProps).to.deep.equal(theme.props.MuiFab); - expect(transformedTheme.components.MuiFab.styleOverrides).to.deep.equal(theme.overrides.MuiFab); + expect(transformedTheme.components.MuiFab.defaultProps).to.deep.equal( + theme.defaultProps.MuiFab, + ); + expect(transformedTheme.components.MuiFab.styleOverrides).to.deep.equal( + theme.styleOverrides.MuiFab, + ); + }); }); - it('merges partially migrated props and overrides from different components in appropriate key', () => { - const theme = { - defaultProps: { - MuiButton: { - disabled: true, + describe('theme.mixins.gutters()', () => { + it('is added to the theme', () => { + const defaultSpacing = 8; + const theme = {}; + + let transformedTheme; + + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); + + expect(transformedTheme.mixins.gutters()).to.deep.equal({ + paddingLeft: defaultSpacing * 2, + paddingRight: defaultSpacing * 2, + '@media (min-width:600px)': { + paddingLeft: defaultSpacing * 3, + paddingRight: defaultSpacing * 3, }, - MuiFab: { - color: 'primary', + }); + }); + + it('respects theme spacing', () => { + const spacing = 100; + const theme = { spacing }; + + let transformedTheme; + + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); + + expect(transformedTheme.mixins.gutters()).to.deep.equal({ + paddingLeft: spacing * 2, + paddingRight: spacing * 2, + '@media (min-width:600px)': { + paddingLeft: spacing * 3, + paddingRight: spacing * 3, }, - }, - styleOverrides: { - MuiButton: { - root: { - background: 'red', - }, + }); + }); + + it('does not remove the mixins defined in the input theme', () => { + const defaultSpacing = 8; + const theme = { + mixins: { + test: { display: 'block' }, }, - MuiFab: { - root: { - color: 'red', - }, + }; + + let transformedTheme; + + expect(() => { + transformedTheme = adaptV4Theme(theme); + }).toWarnDev(['adaptV4Theme() is deprecated']); + + expect(transformedTheme.mixins.test).to.deep.equal({ + display: 'block', + }); + + expect(transformedTheme.mixins.gutters()).to.deep.equal({ + paddingLeft: defaultSpacing * 2, + paddingRight: defaultSpacing * 2, + '@media (min-width:600px)': { + paddingLeft: defaultSpacing * 3, + paddingRight: defaultSpacing * 3, }, - }, - }; - - let transformedTheme; - - expect(() => { - transformedTheme = adaptV4Theme(theme); - }).toWarnDev(['adaptV4Theme() is deprecated']); - - expect(transformedTheme.components.MuiButton.defaultProps).to.deep.equal( - theme.defaultProps.MuiButton, - ); - expect(transformedTheme.components.MuiButton.styleOverrides).to.deep.equal( - theme.styleOverrides.MuiButton, - ); - - expect(transformedTheme.components.MuiFab.defaultProps).to.deep.equal( - theme.defaultProps.MuiFab, - ); - expect(transformedTheme.components.MuiFab.styleOverrides).to.deep.equal( - theme.styleOverrides.MuiFab, - ); + }); + }); }); }); From d0564b1a2ad4acf3bfab04131465d15eda6df6a9 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 29 Aug 2020 12:08:07 +0200 Subject: [PATCH 2/2] [docs] Mention adaptV4Theme first in the migration --- .../pages/guides/migration-v4/migration-v4.md | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/docs/src/pages/guides/migration-v4/migration-v4.md b/docs/src/pages/guides/migration-v4/migration-v4.md index 20e3021c69fee7..4ea29c46e2e80f 100644 --- a/docs/src/pages/guides/migration-v4/migration-v4.md +++ b/docs/src/pages/guides/migration-v4/migration-v4.md @@ -53,6 +53,21 @@ This change affects almost all components where you're using the `component` pro ### Theme +For a smoother transition, the `adaptV4Theme` helper allows you to iteratively upgrade to the new theme structure. + +```diff +-import { createMuiTheme } from '@material-ui/core/styles'; ++import { createMuiTheme, adaptV4Theme } from '@material-ui/core/styles'; + +-const theme = createMuitheme({ ++const theme = createMuitheme(adaptV4Theme({ + // v4 theme +-}); ++})); +``` + +#### Changes + - The "gutters" abstraction hasn't proven to be used frequently enough to be valuable. ```diff @@ -109,28 +124,6 @@ const theme = createMuitheme({ }); ``` -For a smoother transition, the `adaptV4Theme` helper allows you to iteratively upgrade to the new theme structure. Note that it will display a deprecation warning in the console, since it will be removed at the next major release. - -```diff --import { createMuiTheme } from '@material-ui/core/styles'; -+import { createMuiTheme, adaptV4Theme } from '@material-ui/core/styles'; - --const theme = createMuitheme({ -+const theme = createMuitheme(adaptV4Theme({ - props: { - MuiButton: { - disableRipple: true, - }, - }, - overrides: { - MuiButton: { - root: { padding: 0 }, - }, - }, --}); -+})); -``` - ### Avatar - Rename `circle` to `circular` for consistency. The possible values should be adjectives, not nouns: