From eb5426b2021f8f6744769e49f64d4d4a45dade12 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 11:23:35 +0100 Subject: [PATCH 01/84] wip --- docs/pages/system/sx.js | 20 ++++++++++++++++++++ docs/src/pages.js | 1 + docs/src/pages/system/sx/GettingStarted.js | 18 ++++++++++++++++++ docs/src/pages/system/sx/GettingStarted.ts | 18 ++++++++++++++++++ docs/src/pages/system/sx/sx.md | 9 +++++++++ 5 files changed, 66 insertions(+) create mode 100644 docs/pages/system/sx.js create mode 100644 docs/src/pages/system/sx/GettingStarted.js create mode 100644 docs/src/pages/system/sx/GettingStarted.ts create mode 100644 docs/src/pages/system/sx/sx.md diff --git a/docs/pages/system/sx.js b/docs/pages/system/sx.js new file mode 100644 index 00000000000000..34ff54f916ea4a --- /dev/null +++ b/docs/pages/system/sx.js @@ -0,0 +1,20 @@ +import React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; + +const pageFilename = 'system/sx'; +const requireDemo = require.context('docs/src/pages/system/sx', false, /\.(js|tsx)$/); +const requireRaw = require.context( + '!raw-loader!../../src/pages/system/sx', + false, + /\.(js|md|tsx)$/, +); + +export default function Page({ demos, docs }) { + return ; +} + +Page.getInitialProps = () => { + const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); + return { demos, docs }; +}; diff --git a/docs/src/pages.js b/docs/src/pages.js index 0abcbefb7047d5..93f46178f73506 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -174,6 +174,7 @@ const pages = [ { pathname: '/system', children: [ + { pathname: '/system/sx' }, { pathname: '/system/basics' }, { pathname: '/system/borders' }, { pathname: '/system/display' }, diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js new file mode 100644 index 00000000000000..83e014fb529a58 --- /dev/null +++ b/docs/src/pages/system/sx/GettingStarted.js @@ -0,0 +1,18 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function GettingStarted() { + return ( + How to use the sx prop + ); +} \ No newline at end of file diff --git a/docs/src/pages/system/sx/GettingStarted.ts b/docs/src/pages/system/sx/GettingStarted.ts new file mode 100644 index 00000000000000..83e014fb529a58 --- /dev/null +++ b/docs/src/pages/system/sx/GettingStarted.ts @@ -0,0 +1,18 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function GettingStarted() { + return ( + How to use the sx prop + ); +} \ No newline at end of file diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md new file mode 100644 index 00000000000000..ccb02b0eb6ab7b --- /dev/null +++ b/docs/src/pages/system/sx/sx.md @@ -0,0 +1,9 @@ +# The `sx` prop + +

Utility for styling elements inline, using the theme values.

+ +## Getting Started + +Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you in keeping your elements consistent. + +{{"demo": "pages/system/sx/GettingStarted.js", "defaultCodeOpen": true}} From 4cc8ceb455d0274ffcf0000d0c24e9598635dee1 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 13:53:59 +0100 Subject: [PATCH 02/84] finished doc page --- .../src/pages/system/sx/BreakpointsAsArray.js | 14 ++++++ .../pages/system/sx/BreakpointsAsArray.tsx | 14 ++++++ .../pages/system/sx/BreakpointsAsObject.js | 20 +++++++++ .../pages/system/sx/BreakpointsAsObject.tsx | 20 +++++++++ docs/src/pages/system/sx/CustomBreakpoints.js | 31 +++++++++++++ .../src/pages/system/sx/CustomBreakpoints.tsx | 44 +++++++++++++++++++ docs/src/pages/system/sx/GettingStarted.js | 30 +++++++------ docs/src/pages/system/sx/GettingStarted.ts | 18 -------- docs/src/pages/system/sx/GettingStarted.tsx | 20 +++++++++ docs/src/pages/system/sx/ValueAsFunction.js | 16 +++++++ docs/src/pages/system/sx/ValueAsFunction.tsx | 17 +++++++ docs/src/pages/system/sx/sx.md | 34 ++++++++++++++ 12 files changed, 246 insertions(+), 32 deletions(-) create mode 100644 docs/src/pages/system/sx/BreakpointsAsArray.js create mode 100644 docs/src/pages/system/sx/BreakpointsAsArray.tsx create mode 100644 docs/src/pages/system/sx/BreakpointsAsObject.js create mode 100644 docs/src/pages/system/sx/BreakpointsAsObject.tsx create mode 100644 docs/src/pages/system/sx/CustomBreakpoints.js create mode 100644 docs/src/pages/system/sx/CustomBreakpoints.tsx delete mode 100644 docs/src/pages/system/sx/GettingStarted.ts create mode 100644 docs/src/pages/system/sx/GettingStarted.tsx create mode 100644 docs/src/pages/system/sx/ValueAsFunction.js create mode 100644 docs/src/pages/system/sx/ValueAsFunction.tsx diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.js b/docs/src/pages/system/sx/BreakpointsAsArray.js new file mode 100644 index 00000000000000..47fa8b43b2a3c1 --- /dev/null +++ b/docs/src/pages/system/sx/BreakpointsAsArray.js @@ -0,0 +1,14 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function BreakpointsAsArray() { + return ( + + This box has a responsive width + + ); +} diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.tsx b/docs/src/pages/system/sx/BreakpointsAsArray.tsx new file mode 100644 index 00000000000000..47fa8b43b2a3c1 --- /dev/null +++ b/docs/src/pages/system/sx/BreakpointsAsArray.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function BreakpointsAsArray() { + return ( + + This box has a responsive width + + ); +} diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.js b/docs/src/pages/system/sx/BreakpointsAsObject.js new file mode 100644 index 00000000000000..cdb06686a2883f --- /dev/null +++ b/docs/src/pages/system/sx/BreakpointsAsObject.js @@ -0,0 +1,20 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function BreakpointsAsArray() { + return ( + + This box has a responsive width + + ); +} diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.tsx b/docs/src/pages/system/sx/BreakpointsAsObject.tsx new file mode 100644 index 00000000000000..cdb06686a2883f --- /dev/null +++ b/docs/src/pages/system/sx/BreakpointsAsObject.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function BreakpointsAsArray() { + return ( + + This box has a responsive width + + ); +} diff --git a/docs/src/pages/system/sx/CustomBreakpoints.js b/docs/src/pages/system/sx/CustomBreakpoints.js new file mode 100644 index 00000000000000..db9233eec244cd --- /dev/null +++ b/docs/src/pages/system/sx/CustomBreakpoints.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; + +const theme = createMuiTheme({ + breakpoints: { + values: { + tablet: 640, + laptop: 1024, + desktop: 1280, + }, + }, +}); + +export default function BreakpointsAsArray() { + return ( + + + This box has a responsive width + + + ); +} diff --git a/docs/src/pages/system/sx/CustomBreakpoints.tsx b/docs/src/pages/system/sx/CustomBreakpoints.tsx new file mode 100644 index 00000000000000..2542c1bce1f848 --- /dev/null +++ b/docs/src/pages/system/sx/CustomBreakpoints.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; + +declare module '@material-ui/core/styles/createBreakpoints' { + interface BreakpointOverrides { + xs: false; // removes the `xs` breakpoint + sm: false; + md: false; + lg: false; + xl: false; + tablet: true; // adds the `tablet` breakpoint + laptop: true; + desktop: true; + } +} + +const theme = createMuiTheme({ + breakpoints: { + values: { + tablet: 640, + laptop: 1024, + desktop: 1280, + }, + }, +}); + +export default function BreakpointsAsArray() { + return ( + + + This box has a responsive width + + + ); +} diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js index 83e014fb529a58..00c0d16f18a96e 100644 --- a/docs/src/pages/system/sx/GettingStarted.js +++ b/docs/src/pages/system/sx/GettingStarted.js @@ -2,17 +2,19 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; export default function GettingStarted() { - return ( - How to use the sx prop - ); -} \ No newline at end of file + return ( + + How to use the sx prop + + ); +} diff --git a/docs/src/pages/system/sx/GettingStarted.ts b/docs/src/pages/system/sx/GettingStarted.ts deleted file mode 100644 index 83e014fb529a58..00000000000000 --- a/docs/src/pages/system/sx/GettingStarted.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; - -export default function GettingStarted() { - return ( - How to use the sx prop - ); -} \ No newline at end of file diff --git a/docs/src/pages/system/sx/GettingStarted.tsx b/docs/src/pages/system/sx/GettingStarted.tsx new file mode 100644 index 00000000000000..00c0d16f18a96e --- /dev/null +++ b/docs/src/pages/system/sx/GettingStarted.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function GettingStarted() { + return ( + + How to use the sx prop + + ); +} diff --git a/docs/src/pages/system/sx/ValueAsFunction.js b/docs/src/pages/system/sx/ValueAsFunction.js new file mode 100644 index 00000000000000..e3a96c3a13820e --- /dev/null +++ b/docs/src/pages/system/sx/ValueAsFunction.js @@ -0,0 +1,16 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function ValueAsFunction() { + return ( + theme.palette.primary.main, + }} + > + Border color with theme value + + ); +} diff --git a/docs/src/pages/system/sx/ValueAsFunction.tsx b/docs/src/pages/system/sx/ValueAsFunction.tsx new file mode 100644 index 00000000000000..2dc233d5209651 --- /dev/null +++ b/docs/src/pages/system/sx/ValueAsFunction.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { Theme } from '@material-ui/core/styles'; + +export default function ValueAsFunction() { + return ( + theme.palette.primary.main, + }} + > + Border color with theme value + + ); +} diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index ccb02b0eb6ab7b..7d1e50546cb5bf 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -6,4 +6,38 @@ Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you in keeping your elements consistent. +We recommend you use this prop whenever you need to add one-of style overrides on the Material-UI components. If you repetedly add the same styles on some component, than the `styled()` is better alternative, as it allows you to specify them only one and reuse them in all component instances. + {{"demo": "pages/system/sx/GettingStarted.js", "defaultCodeOpen": true}} + +# Property to theme key mapping + +You can explore the [System API](system/api/) page to discover how the different css (and custom) properties are mapped to the theme keys. + +# Value as function + +If you wish to use the theme for some css property that is not supported by the system, you can use function as a value, where you willl have access to the theme object. + +{{"demo": "pages/system/sx/ValueAsFunction.js", "defaultCodeOpen": true}} + +# Breakpoints + +If you would like to have responsive values for some CSS property, you may use the breakpoints shorthand syntax. We offer two ways of defining the breakpoints: + +## Breakpoints as array + +The first option is to define your breakpoints in an array, from the smallest to the largest breakpoint. + +{{"demo": "pages/system/sx/BreakpointsAsArray.js", "defaultCodeOpen": true}} + +## Breakpoints as object + +The second option for defining breakpoints is to define them with object, having the breakpoints as keys. Here is an example of how you may define the previous example by using breakpoints as object. + +{{"demo": "pages/system/sx/BreakpointsAsObject.js", "defaultCodeOpen": true}} + +## Custom breakpoints + +You can also specify your own custom breakpoints and use them as keys when defining the breakpoint object. Here is an example of how to do that. + +{{"demo": "pages/system/sx/CustomBreakpoints.js", "defaultCodeOpen": true}} From 4ce768785816d81d524a20fa1e821c73edd2c182 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 14:00:53 +0100 Subject: [PATCH 03/84] typos --- docs/src/pages/system/sx/sx.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 7d1e50546cb5bf..c3c78968f8188e 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -4,9 +4,9 @@ ## Getting Started -Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you in keeping your elements consistent. +Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. -We recommend you use this prop whenever you need to add one-of style overrides on the Material-UI components. If you repetedly add the same styles on some component, than the `styled()` is better alternative, as it allows you to specify them only one and reuse them in all component instances. +We recommend you use this prop whenever you need to add one-of style overrides on the Material-UI components. If you repetedly add the same styles on some component, than the `styled()` is better alternative, as it allows you to specify the overrides only ones and reuse them in all component instances. {{"demo": "pages/system/sx/GettingStarted.js", "defaultCodeOpen": true}} @@ -16,7 +16,7 @@ You can explore the [System API](system/api/) page to discover how the different # Value as function -If you wish to use the theme for some css property that is not supported by the system, you can use function as a value, where you willl have access to the theme object. +If you wish to use the theme for some css property that is not supported by the system, you can use function as a value, where you can have access to the theme object. {{"demo": "pages/system/sx/ValueAsFunction.js", "defaultCodeOpen": true}} @@ -26,18 +26,18 @@ If you would like to have responsive values for some CSS property, you may use t ## Breakpoints as array -The first option is to define your breakpoints in an array, from the smallest to the largest breakpoint. +The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. {{"demo": "pages/system/sx/BreakpointsAsArray.js", "defaultCodeOpen": true}} ## Breakpoints as object -The second option for defining breakpoints is to define them with object, having the breakpoints as keys. Here is an example of how you may define the previous example by using breakpoints as object. +The second option for defining breakpoints is to define them as object, using the breakpoints as keys. Here is an example of how you may define the previous example by using the object syntax. {{"demo": "pages/system/sx/BreakpointsAsObject.js", "defaultCodeOpen": true}} ## Custom breakpoints -You can also specify your own custom breakpoints and use them as keys when defining the breakpoint object. Here is an example of how to do that. +You can also specify your own custom breakpoints and use them as keys when defining the breakpoints object. Here is an example of how to do that. {{"demo": "pages/system/sx/CustomBreakpoints.js", "defaultCodeOpen": true}} From e99de3bd8ef0e0cfa6b330d388ce8dcec4260f1b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 15:18:17 +0100 Subject: [PATCH 04/84] docs:i18n & docs:typescript:formatted --- docs/src/pages/components/hidden/BreakpointDown.js | 2 +- docs/src/pages/components/hidden/BreakpointOnly.js | 2 +- docs/src/pages/components/hidden/BreakpointUp.js | 2 +- docs/src/pages/components/hidden/GridIntegration.js | 2 +- docs/src/pages/customization/breakpoints/WithWidth.js | 2 +- docs/translations/translations.json | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/src/pages/components/hidden/BreakpointDown.js b/docs/src/pages/components/hidden/BreakpointDown.js index b9954e659ca1cc..ad60dc8873b805 100644 --- a/docs/src/pages/components/hidden/BreakpointDown.js +++ b/docs/src/pages/components/hidden/BreakpointDown.js @@ -52,7 +52,7 @@ function BreakpointDown(props) { } BreakpointDown.propTypes = { - width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, + width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, }; export default withWidth()(BreakpointDown); diff --git a/docs/src/pages/components/hidden/BreakpointOnly.js b/docs/src/pages/components/hidden/BreakpointOnly.js index 1d56e779049a3e..87973ab3c20518 100644 --- a/docs/src/pages/components/hidden/BreakpointOnly.js +++ b/docs/src/pages/components/hidden/BreakpointOnly.js @@ -46,7 +46,7 @@ function BreakpointOnly(props) { } BreakpointOnly.propTypes = { - width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, + width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, }; export default withWidth()(BreakpointOnly); diff --git a/docs/src/pages/components/hidden/BreakpointUp.js b/docs/src/pages/components/hidden/BreakpointUp.js index d7575c6c7e75a5..772fa491f3e160 100644 --- a/docs/src/pages/components/hidden/BreakpointUp.js +++ b/docs/src/pages/components/hidden/BreakpointUp.js @@ -52,7 +52,7 @@ function BreakpointUp(props) { } BreakpointUp.propTypes = { - width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, + width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, }; export default withWidth()(BreakpointUp); diff --git a/docs/src/pages/components/hidden/GridIntegration.js b/docs/src/pages/components/hidden/GridIntegration.js index 519c976ac4e9fd..2aeeeedca1389b 100644 --- a/docs/src/pages/components/hidden/GridIntegration.js +++ b/docs/src/pages/components/hidden/GridIntegration.js @@ -59,7 +59,7 @@ function GridIntegration(props) { } GridIntegration.propTypes = { - width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, + width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, }; export default withWidth()(GridIntegration); diff --git a/docs/src/pages/customization/breakpoints/WithWidth.js b/docs/src/pages/customization/breakpoints/WithWidth.js index 3b40fcd5eb4897..19f1d4461e6192 100644 --- a/docs/src/pages/customization/breakpoints/WithWidth.js +++ b/docs/src/pages/customization/breakpoints/WithWidth.js @@ -21,7 +21,7 @@ function WithWidth(props) { } WithWidth.propTypes = { - width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, + width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, }; export default withWidth()(WithWidth); diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 2e9b713d681202..80100eeadb8b37 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -211,6 +211,7 @@ "/styles/basics": "Basics", "/styles/advanced": "Advanced", "/system": "System", + "/system/sx": "Sx", "/system/basics": "Basics", "/system/borders": "Borders", "/system/display": "Display", From cae97614b70d2bc593b7136bfeaa09c1d37c2d8c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 15:23:23 +0100 Subject: [PATCH 05/84] fixes --- .../pages/components/hidden/BreakpointDown.js | 2 +- .../pages/components/hidden/BreakpointOnly.js | 2 +- .../pages/components/hidden/BreakpointUp.js | 2 +- .../components/hidden/GridIntegration.js | 2 +- .../customization/breakpoints/WithWidth.js | 2 +- .../pages/system/sx/BreakpointsAsObject.js | 2 +- .../pages/system/sx/BreakpointsAsObject.tsx | 2 +- docs/src/pages/system/sx/CustomBreakpoints.js | 31 ----------- .../src/pages/system/sx/CustomBreakpoints.tsx | 44 ---------------- docs/src/pages/system/sx/sx.md | 51 ++++++++++++++++++- 10 files changed, 57 insertions(+), 83 deletions(-) delete mode 100644 docs/src/pages/system/sx/CustomBreakpoints.js delete mode 100644 docs/src/pages/system/sx/CustomBreakpoints.tsx diff --git a/docs/src/pages/components/hidden/BreakpointDown.js b/docs/src/pages/components/hidden/BreakpointDown.js index ad60dc8873b805..b9954e659ca1cc 100644 --- a/docs/src/pages/components/hidden/BreakpointDown.js +++ b/docs/src/pages/components/hidden/BreakpointDown.js @@ -52,7 +52,7 @@ function BreakpointDown(props) { } BreakpointDown.propTypes = { - width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, }; export default withWidth()(BreakpointDown); diff --git a/docs/src/pages/components/hidden/BreakpointOnly.js b/docs/src/pages/components/hidden/BreakpointOnly.js index 87973ab3c20518..1d56e779049a3e 100644 --- a/docs/src/pages/components/hidden/BreakpointOnly.js +++ b/docs/src/pages/components/hidden/BreakpointOnly.js @@ -46,7 +46,7 @@ function BreakpointOnly(props) { } BreakpointOnly.propTypes = { - width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, }; export default withWidth()(BreakpointOnly); diff --git a/docs/src/pages/components/hidden/BreakpointUp.js b/docs/src/pages/components/hidden/BreakpointUp.js index 772fa491f3e160..d7575c6c7e75a5 100644 --- a/docs/src/pages/components/hidden/BreakpointUp.js +++ b/docs/src/pages/components/hidden/BreakpointUp.js @@ -52,7 +52,7 @@ function BreakpointUp(props) { } BreakpointUp.propTypes = { - width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, }; export default withWidth()(BreakpointUp); diff --git a/docs/src/pages/components/hidden/GridIntegration.js b/docs/src/pages/components/hidden/GridIntegration.js index 2aeeeedca1389b..519c976ac4e9fd 100644 --- a/docs/src/pages/components/hidden/GridIntegration.js +++ b/docs/src/pages/components/hidden/GridIntegration.js @@ -59,7 +59,7 @@ function GridIntegration(props) { } GridIntegration.propTypes = { - width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, }; export default withWidth()(GridIntegration); diff --git a/docs/src/pages/customization/breakpoints/WithWidth.js b/docs/src/pages/customization/breakpoints/WithWidth.js index 19f1d4461e6192..3b40fcd5eb4897 100644 --- a/docs/src/pages/customization/breakpoints/WithWidth.js +++ b/docs/src/pages/customization/breakpoints/WithWidth.js @@ -21,7 +21,7 @@ function WithWidth(props) { } WithWidth.propTypes = { - width: PropTypes.oneOf(['desktop', 'laptop', 'tablet']).isRequired, + width: PropTypes.oneOf(['lg', 'md', 'sm', 'xl', 'xs']).isRequired, }; export default withWidth()(WithWidth); diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.js b/docs/src/pages/system/sx/BreakpointsAsObject.js index cdb06686a2883f..a81ebd10b4452d 100644 --- a/docs/src/pages/system/sx/BreakpointsAsObject.js +++ b/docs/src/pages/system/sx/BreakpointsAsObject.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -export default function BreakpointsAsArray() { +export default function BreakpointsAsObject() { return ( - - This box has a responsive width - - - ); -} diff --git a/docs/src/pages/system/sx/CustomBreakpoints.tsx b/docs/src/pages/system/sx/CustomBreakpoints.tsx deleted file mode 100644 index 2542c1bce1f848..00000000000000 --- a/docs/src/pages/system/sx/CustomBreakpoints.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; -import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; - -declare module '@material-ui/core/styles/createBreakpoints' { - interface BreakpointOverrides { - xs: false; // removes the `xs` breakpoint - sm: false; - md: false; - lg: false; - xl: false; - tablet: true; // adds the `tablet` breakpoint - laptop: true; - desktop: true; - } -} - -const theme = createMuiTheme({ - breakpoints: { - values: { - tablet: 640, - laptop: 1024, - desktop: 1280, - }, - }, -}); - -export default function BreakpointsAsArray() { - return ( - - - This box has a responsive width - - - ); -} diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index c3c78968f8188e..da0566460169aa 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -40,4 +40,53 @@ The second option for defining breakpoints is to define them as object, using th You can also specify your own custom breakpoints and use them as keys when defining the breakpoints object. Here is an example of how to do that. -{{"demo": "pages/system/sx/CustomBreakpoints.js", "defaultCodeOpen": true}} +```jsx +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; + +const theme = createMuiTheme({ + breakpoints: { + values: { + tablet: 640, + laptop: 1024, + desktop: 1280, + }, + }, +}); + +export default function CustomBreakpoints() { + return ( + + + This box has a responsive width + + + ); +} +``` + +If you are using TypeScript, you would also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. + +```ts +declare module '@material-ui/core/styles/createBreakpoints' { + interface BreakpointOverrides { + xs: false; // removes the `xs` breakpoint + sm: false; + md: false; + lg: false; + xl: false; + tablet: true; // adds the `tablet` breakpoint + laptop: true; + desktop: true; + } +} +``` From 54d8a5587f02a64523370dce77845afa23b2bca3 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 17:26:19 +0100 Subject: [PATCH 06/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index da0566460169aa..dc1b574fb3dbf3 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -2,7 +2,7 @@

Utility for styling elements inline, using the theme values.

-## Getting Started +## Getting started Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. From b8fb9ddd77d92c41b623493c49bf197115c098e6 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 17:26:44 +0100 Subject: [PATCH 07/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index dc1b574fb3dbf3..accad0a779f6ee 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -14,7 +14,7 @@ We recommend you use this prop whenever you need to add one-of style overrides o You can explore the [System API](system/api/) page to discover how the different css (and custom) properties are mapped to the theme keys. -# Value as function +## Value as a function If you wish to use the theme for some css property that is not supported by the system, you can use function as a value, where you can have access to the theme object. From 9b5686703ab86f71160bbcdcc77a8338a7072aa4 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 17:26:56 +0100 Subject: [PATCH 08/84] Update docs/src/pages.js Co-authored-by: Olivier Tassinari --- docs/src/pages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages.js b/docs/src/pages.js index 93f46178f73506..108790a5332cea 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -174,8 +174,8 @@ const pages = [ { pathname: '/system', children: [ - { pathname: '/system/sx' }, { pathname: '/system/basics' }, + { pathname: '/system/sx', title: 'sx' }, { pathname: '/system/borders' }, { pathname: '/system/display' }, { pathname: '/system/flexbox' }, From e5978a474cfaff42f0bfd9e41f83817c55013a68 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 17:27:04 +0100 Subject: [PATCH 09/84] Update docs/translations/translations.json Co-authored-by: Olivier Tassinari --- docs/translations/translations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 80100eeadb8b37..64f09bc03b6890 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -211,7 +211,7 @@ "/styles/basics": "Basics", "/styles/advanced": "Advanced", "/system": "System", - "/system/sx": "Sx", + "/system/sx": "sx", "/system/basics": "Basics", "/system/borders": "Borders", "/system/display": "Display", From d99cf004584d758f864d4055ee8ccd192abef18a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 17:27:20 +0100 Subject: [PATCH 10/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index accad0a779f6ee..ca696db5cf5ca9 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -12,7 +12,7 @@ We recommend you use this prop whenever you need to add one-of style overrides o # Property to theme key mapping -You can explore the [System API](system/api/) page to discover how the different css (and custom) properties are mapped to the theme keys. +You can explore the [System API](/system/api/) page to discover how the different css (and custom) properties are mapped to the theme keys. ## Value as a function From c94ca93156def89692135f382386a3adddc91447 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:48:34 +0100 Subject: [PATCH 11/84] Update docs/src/pages/system/sx/BreakpointsAsArray.tsx Co-authored-by: Matt --- docs/src/pages/system/sx/BreakpointsAsArray.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.tsx b/docs/src/pages/system/sx/BreakpointsAsArray.tsx index 47fa8b43b2a3c1..7682f576afb1f1 100644 --- a/docs/src/pages/system/sx/BreakpointsAsArray.tsx +++ b/docs/src/pages/system/sx/BreakpointsAsArray.tsx @@ -8,7 +8,7 @@ export default function BreakpointsAsArray() { width: [100, 200, 300, 400, 500], }} > - This box has a responsive width + This box has a responsive width.
); } From 79a7d8b7fb59de797652d10f498b96f19403233b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:48:47 +0100 Subject: [PATCH 12/84] Update docs/src/pages/system/sx/BreakpointsAsObject.js Co-authored-by: Matt --- docs/src/pages/system/sx/BreakpointsAsObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.js b/docs/src/pages/system/sx/BreakpointsAsObject.js index a81ebd10b4452d..69a2c04d50d78e 100644 --- a/docs/src/pages/system/sx/BreakpointsAsObject.js +++ b/docs/src/pages/system/sx/BreakpointsAsObject.js @@ -14,7 +14,7 @@ export default function BreakpointsAsObject() { }, }} > - This box has a responsive width + This box has a responsive width. ); } From e07060ad9edf2d44cd9d1a5c8761928e55dc16b9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:49:02 +0100 Subject: [PATCH 13/84] Update docs/src/pages/system/sx/BreakpointsAsArray.js Co-authored-by: Matt --- docs/src/pages/system/sx/BreakpointsAsArray.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.js b/docs/src/pages/system/sx/BreakpointsAsArray.js index 47fa8b43b2a3c1..7682f576afb1f1 100644 --- a/docs/src/pages/system/sx/BreakpointsAsArray.js +++ b/docs/src/pages/system/sx/BreakpointsAsArray.js @@ -8,7 +8,7 @@ export default function BreakpointsAsArray() { width: [100, 200, 300, 400, 500], }} > - This box has a responsive width + This box has a responsive width. ); } From acbc8668040d591fcd8cd087aa9259d28ebe8973 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:49:11 +0100 Subject: [PATCH 14/84] Update docs/src/pages/system/sx/BreakpointsAsObject.tsx Co-authored-by: Matt --- docs/src/pages/system/sx/BreakpointsAsObject.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.tsx b/docs/src/pages/system/sx/BreakpointsAsObject.tsx index a81ebd10b4452d..69a2c04d50d78e 100644 --- a/docs/src/pages/system/sx/BreakpointsAsObject.tsx +++ b/docs/src/pages/system/sx/BreakpointsAsObject.tsx @@ -14,7 +14,7 @@ export default function BreakpointsAsObject() { }, }} > - This box has a responsive width + This box has a responsive width. ); } From e2652f96b7c3ac3c39f9f485f41e0ec8aaed6679 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:49:29 +0100 Subject: [PATCH 15/84] Update docs/src/pages/system/sx/GettingStarted.js Co-authored-by: Matt --- docs/src/pages/system/sx/GettingStarted.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js index 00c0d16f18a96e..3644af77340792 100644 --- a/docs/src/pages/system/sx/GettingStarted.js +++ b/docs/src/pages/system/sx/GettingStarted.js @@ -14,7 +14,7 @@ export default function GettingStarted() { }, }} > - How to use the sx prop + How to use the sx prop. ); } From a1bafa7349b3288f784809e89cc0933bf59371c0 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:49:49 +0100 Subject: [PATCH 16/84] Update docs/src/pages/system/sx/GettingStarted.tsx Co-authored-by: Matt --- docs/src/pages/system/sx/GettingStarted.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/GettingStarted.tsx b/docs/src/pages/system/sx/GettingStarted.tsx index 00c0d16f18a96e..3644af77340792 100644 --- a/docs/src/pages/system/sx/GettingStarted.tsx +++ b/docs/src/pages/system/sx/GettingStarted.tsx @@ -14,7 +14,7 @@ export default function GettingStarted() { }, }} > - How to use the sx prop + How to use the sx prop. ); } From f8e965d91c9fb0d48488d013eda01fa88eb31222 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:50:03 +0100 Subject: [PATCH 17/84] Update docs/src/pages/system/sx/ValueAsFunction.js Co-authored-by: Matt --- docs/src/pages/system/sx/ValueAsFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/ValueAsFunction.js b/docs/src/pages/system/sx/ValueAsFunction.js index e3a96c3a13820e..55ad8fed220d81 100644 --- a/docs/src/pages/system/sx/ValueAsFunction.js +++ b/docs/src/pages/system/sx/ValueAsFunction.js @@ -10,7 +10,7 @@ export default function ValueAsFunction() { borderColor: (theme) => theme.palette.primary.main, }} > - Border color with theme value + Border color with theme value. ); } From aa081b841b3f0e2736543c290bf4c39f99dae050 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:50:22 +0100 Subject: [PATCH 18/84] Update docs/src/pages/system/sx/ValueAsFunction.tsx Co-authored-by: Matt --- docs/src/pages/system/sx/ValueAsFunction.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/ValueAsFunction.tsx b/docs/src/pages/system/sx/ValueAsFunction.tsx index 2dc233d5209651..c96bf8291464cf 100644 --- a/docs/src/pages/system/sx/ValueAsFunction.tsx +++ b/docs/src/pages/system/sx/ValueAsFunction.tsx @@ -11,7 +11,7 @@ export default function ValueAsFunction() { borderColor: (theme: Theme) => theme.palette.primary.main, }} > - Border color with theme value + Border color with theme value. ); } From b30e24ba9cd7694a714ad4a0e71082f5ed3dfc46 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:51:21 +0100 Subject: [PATCH 19/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index ca696db5cf5ca9..95e445625c8f90 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -6,7 +6,7 @@ Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. -We recommend you use this prop whenever you need to add one-of style overrides on the Material-UI components. If you repetedly add the same styles on some component, than the `styled()` is better alternative, as it allows you to specify the overrides only ones and reuse them in all component instances. +You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly add the same styles on a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. {{"demo": "pages/system/sx/GettingStarted.js", "defaultCodeOpen": true}} From 14a908c5231382c9a71d86b35a4ee00f8f0f9c86 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:51:41 +0100 Subject: [PATCH 20/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 95e445625c8f90..5a8073735ceeb8 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -12,7 +12,7 @@ You should use this prop whenever you need to add a style override to a Material # Property to theme key mapping -You can explore the [System API](/system/api/) page to discover how the different css (and custom) properties are mapped to the theme keys. +You can explore the [System API](/system/api/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. ## Value as a function From c029718346936348a2e934197946ecb956e933ef Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:52:35 +0100 Subject: [PATCH 21/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 5a8073735ceeb8..9ba636f364b2e4 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -16,7 +16,7 @@ You can explore the [System API](/system/api/) page to discover how the differen ## Value as a function -If you wish to use the theme for some css property that is not supported by the system, you can use function as a value, where you can have access to the theme object. +If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. {{"demo": "pages/system/sx/ValueAsFunction.js", "defaultCodeOpen": true}} From 682a5a81f50dcecd2610b80fa95c3a9ca9223e7f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:53:11 +0100 Subject: [PATCH 22/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 9ba636f364b2e4..3d9c4069196b99 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -22,7 +22,7 @@ If you wish to use the theme for a CSS property that is not supported by the sys # Breakpoints -If you would like to have responsive values for some CSS property, you may use the breakpoints shorthand syntax. We offer two ways of defining the breakpoints: +If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: ## Breakpoints as array From cb867a92b566d78ddd9ba4cc5058923814740109 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:53:41 +0100 Subject: [PATCH 23/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 3d9c4069196b99..05bd9d6c6e19b5 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -24,7 +24,7 @@ If you wish to use the theme for a CSS property that is not supported by the sys If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: -## Breakpoints as array +## 1. Breakpoints as an array The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. From 52720d593af2b89c57fbc69c553905870d6c4db8 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:53:51 +0100 Subject: [PATCH 24/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 05bd9d6c6e19b5..cda40e8537433b 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -30,7 +30,7 @@ The first option is to define your breakpoints as an array, from the smallest to {{"demo": "pages/system/sx/BreakpointsAsArray.js", "defaultCodeOpen": true}} -## Breakpoints as object +## 2. Breakpoints as an object The second option for defining breakpoints is to define them as object, using the breakpoints as keys. Here is an example of how you may define the previous example by using the object syntax. From dbd50261d00e51e791a262581b7fda21da45986d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:54:14 +0100 Subject: [PATCH 25/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index cda40e8537433b..41e76e14cf2598 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -32,7 +32,7 @@ The first option is to define your breakpoints as an array, from the smallest to ## 2. Breakpoints as an object -The second option for defining breakpoints is to define them as object, using the breakpoints as keys. Here is an example of how you may define the previous example by using the object syntax. +The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. {{"demo": "pages/system/sx/BreakpointsAsObject.js", "defaultCodeOpen": true}} From 35fe80e4980fb7511217359c6204d9ea3e2c667a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:54:33 +0100 Subject: [PATCH 26/84] Update docs/src/pages/system/sx/sx.md Co-authored-by: Matt --- docs/src/pages/system/sx/sx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 41e76e14cf2598..d4e04ce0fbe93d 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -38,7 +38,7 @@ The second option for defining breakpoints is to define them as an object, using ## Custom breakpoints -You can also specify your own custom breakpoints and use them as keys when defining the breakpoints object. Here is an example of how to do that. +You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that. ```jsx import * as React from 'react'; From c6a8d46b68fc73b4640a544febf3dd8460721724 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sun, 1 Nov 2020 11:59:25 +0100 Subject: [PATCH 27/84] converted border demos --- .../pages/system/borders/BorderAdditive.js | 15 ++++---- .../pages/system/borders/BorderAdditive.tsx | 15 ++++---- docs/src/pages/system/borders/BorderColor.js | 15 ++++---- docs/src/pages/system/borders/BorderColor.tsx | 15 ++++---- docs/src/pages/system/borders/BorderRadius.js | 11 +++--- .../src/pages/system/borders/BorderRadius.tsx | 11 +++--- .../pages/system/borders/BorderSubtractive.js | 15 ++++---- .../system/borders/BorderSubtractive.tsx | 15 ++++---- docs/src/pages/system/borders/borders.md | 36 +++++++++---------- 9 files changed, 78 insertions(+), 70 deletions(-) diff --git a/docs/src/pages/system/borders/BorderAdditive.js b/docs/src/pages/system/borders/BorderAdditive.js index 4f0c45b90f515c..84bc8b64a81b56 100644 --- a/docs/src/pages/system/borders/BorderAdditive.js +++ b/docs/src/pages/system/borders/BorderAdditive.js @@ -1,21 +1,22 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', m: 1, - style: { width: '5rem', height: '5rem' }, borderColor: 'text.primary', + width: '5rem', + height: '5rem', }; export default function BorderAdditive() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderAdditive.tsx b/docs/src/pages/system/borders/BorderAdditive.tsx index 4f0c45b90f515c..84bc8b64a81b56 100644 --- a/docs/src/pages/system/borders/BorderAdditive.tsx +++ b/docs/src/pages/system/borders/BorderAdditive.tsx @@ -1,21 +1,22 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', m: 1, - style: { width: '5rem', height: '5rem' }, borderColor: 'text.primary', + width: '5rem', + height: '5rem', }; export default function BorderAdditive() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderColor.js b/docs/src/pages/system/borders/BorderColor.js index 6e46f63f3c6535..81378b2a27865e 100644 --- a/docs/src/pages/system/borders/BorderColor.js +++ b/docs/src/pages/system/borders/BorderColor.js @@ -1,21 +1,22 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', m: 1, border: 1, - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderColor() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderColor.tsx b/docs/src/pages/system/borders/BorderColor.tsx index 6e46f63f3c6535..81378b2a27865e 100644 --- a/docs/src/pages/system/borders/BorderColor.tsx +++ b/docs/src/pages/system/borders/BorderColor.tsx @@ -1,21 +1,22 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', m: 1, border: 1, - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderColor() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderRadius.js b/docs/src/pages/system/borders/BorderRadius.js index 4ade51187315c7..489a893350f6a8 100644 --- a/docs/src/pages/system/borders/BorderRadius.js +++ b/docs/src/pages/system/borders/BorderRadius.js @@ -1,20 +1,21 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', borderColor: 'text.primary', m: 1, border: 1, - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderRadius() { return ( - - - + + + ); } diff --git a/docs/src/pages/system/borders/BorderRadius.tsx b/docs/src/pages/system/borders/BorderRadius.tsx index 4ade51187315c7..489a893350f6a8 100644 --- a/docs/src/pages/system/borders/BorderRadius.tsx +++ b/docs/src/pages/system/borders/BorderRadius.tsx @@ -1,20 +1,21 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', borderColor: 'text.primary', m: 1, border: 1, - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderRadius() { return ( - - - + + + ); } diff --git a/docs/src/pages/system/borders/BorderSubtractive.js b/docs/src/pages/system/borders/BorderSubtractive.js index 98633eae8e3847..5374d1649c64a4 100644 --- a/docs/src/pages/system/borders/BorderSubtractive.js +++ b/docs/src/pages/system/borders/BorderSubtractive.js @@ -1,22 +1,23 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', border: 1, m: 1, borderColor: 'text.primary', - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderSubtractive() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderSubtractive.tsx b/docs/src/pages/system/borders/BorderSubtractive.tsx index 98633eae8e3847..5374d1649c64a4 100644 --- a/docs/src/pages/system/borders/BorderSubtractive.tsx +++ b/docs/src/pages/system/borders/BorderSubtractive.tsx @@ -1,22 +1,23 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -const defaultProps = { +const commonStyles = { bgcolor: 'background.paper', border: 1, m: 1, borderColor: 'text.primary', - style: { width: '5rem', height: '5rem' }, + width: '5rem', + height: '5rem', }; export default function BorderSubtractive() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/borders.md b/docs/src/pages/system/borders/borders.md index 5dae895f1b4797..dd715a11a66dc7 100644 --- a/docs/src/pages/system/borders/borders.md +++ b/docs/src/pages/system/borders/borders.md @@ -11,11 +11,11 @@ Use border utilities to add or remove an element’s borders. Choose from all bo {{"demo": "pages/system/borders/BorderAdditive.js", "defaultCodeOpen": false, "bg": true}} ```jsx -… -… -… -… -… +… +… +… +… +… ``` ### Subtractive @@ -23,11 +23,11 @@ Use border utilities to add or remove an element’s borders. Choose from all bo {{"demo": "pages/system/borders/BorderSubtractive.js", "defaultCodeOpen": false, "bg": true}} ```jsx -… -… -… -… -… +… +… +… +… +… ``` ## Border color @@ -35,11 +35,11 @@ Use border utilities to add or remove an element’s borders. Choose from all bo {{"demo": "pages/system/borders/BorderColor.js", "defaultCodeOpen": false}} ```jsx -… -… -… -… -… +… +… +… +… +… ``` ## Border-radius @@ -47,9 +47,9 @@ Use border utilities to add or remove an element’s borders. Choose from all bo {{"demo": "pages/system/borders/BorderRadius.js", "defaultCodeOpen": false}} ```jsx -… -… -… +… +… +… ``` ## API From d909c632d848fdf3c5a254781d35d32d7f2f64ff Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 2 Nov 2020 10:55:58 +0100 Subject: [PATCH 28/84] displays examples converted --- .../pages/system/borders/BorderAdditive.js | 2 +- docs/src/pages/system/borders/BorderColor.js | 10 ++-- docs/src/pages/system/borders/BorderRadius.js | 4 +- docs/src/pages/system/display/Block.js | 20 ++++--- docs/src/pages/system/display/Block.tsx | 20 ++++--- docs/src/pages/system/display/Hiding.js | 4 +- docs/src/pages/system/display/Hiding.tsx | 4 +- docs/src/pages/system/display/Inline.js | 20 ++++--- docs/src/pages/system/display/Inline.tsx | 20 ++++--- docs/src/pages/system/display/Overflow.js | 10 +++- docs/src/pages/system/display/Overflow.tsx | 4 +- docs/src/pages/system/display/Print.js | 4 +- docs/src/pages/system/display/Print.tsx | 4 +- docs/src/pages/system/display/TextOverflow.js | 20 ++++--- .../src/pages/system/display/TextOverflow.tsx | 20 ++++--- docs/src/pages/system/display/Visibility.js | 20 ++++--- docs/src/pages/system/display/Visibility.tsx | 20 ++++--- docs/src/pages/system/display/WhiteSpace.js | 16 +++--- docs/src/pages/system/display/WhiteSpace.tsx | 16 +++--- docs/src/pages/system/display/display.md | 54 +++++++++---------- 20 files changed, 169 insertions(+), 123 deletions(-) diff --git a/docs/src/pages/system/borders/BorderAdditive.js b/docs/src/pages/system/borders/BorderAdditive.js index 84bc8b64a81b56..8ce5e091dbef74 100644 --- a/docs/src/pages/system/borders/BorderAdditive.js +++ b/docs/src/pages/system/borders/BorderAdditive.js @@ -12,7 +12,7 @@ const commonStyles = { export default function BorderAdditive() { return ( - + diff --git a/docs/src/pages/system/borders/BorderColor.js b/docs/src/pages/system/borders/BorderColor.js index 81378b2a27865e..db8e6fc45f51df 100644 --- a/docs/src/pages/system/borders/BorderColor.js +++ b/docs/src/pages/system/borders/BorderColor.js @@ -12,11 +12,11 @@ const commonStyles = { export default function BorderColor() { return ( - - - - - + + + + + ); } diff --git a/docs/src/pages/system/borders/BorderRadius.js b/docs/src/pages/system/borders/BorderRadius.js index 489a893350f6a8..8e1f0e04eb122b 100644 --- a/docs/src/pages/system/borders/BorderRadius.js +++ b/docs/src/pages/system/borders/BorderRadius.js @@ -13,8 +13,8 @@ const commonStyles = { export default function BorderRadius() { return ( - - + + ); diff --git a/docs/src/pages/system/display/Block.js b/docs/src/pages/system/display/Block.js index c3888097dd7f2c..2135fd6e8f355d 100644 --- a/docs/src/pages/system/display/Block.js +++ b/docs/src/pages/system/display/Block.js @@ -6,19 +6,23 @@ export default function Block() {
block block diff --git a/docs/src/pages/system/display/Block.tsx b/docs/src/pages/system/display/Block.tsx index c3888097dd7f2c..729e83a97404db 100644 --- a/docs/src/pages/system/display/Block.tsx +++ b/docs/src/pages/system/display/Block.tsx @@ -6,19 +6,23 @@ export default function Block() {
block block diff --git a/docs/src/pages/system/display/Hiding.js b/docs/src/pages/system/display/Hiding.js index 8a9e8ccecbb0f1..4ff5604cec1cd5 100644 --- a/docs/src/pages/system/display/Hiding.js +++ b/docs/src/pages/system/display/Hiding.js @@ -4,10 +4,10 @@ import Box from '@material-ui/core/Box'; export default function Hiding() { return (
- + hide on screens wider than md - + hide on screens smaller than md
diff --git a/docs/src/pages/system/display/Hiding.tsx b/docs/src/pages/system/display/Hiding.tsx index 8a9e8ccecbb0f1..4ff5604cec1cd5 100644 --- a/docs/src/pages/system/display/Hiding.tsx +++ b/docs/src/pages/system/display/Hiding.tsx @@ -4,10 +4,10 @@ import Box from '@material-ui/core/Box'; export default function Hiding() { return (
- + hide on screens wider than md - + hide on screens smaller than md
diff --git a/docs/src/pages/system/display/Inline.js b/docs/src/pages/system/display/Inline.js index dc494f25941b70..5edb5e7ce512aa 100644 --- a/docs/src/pages/system/display/Inline.js +++ b/docs/src/pages/system/display/Inline.js @@ -6,19 +6,23 @@ export default function Inline() {
inline inline diff --git a/docs/src/pages/system/display/Inline.tsx b/docs/src/pages/system/display/Inline.tsx index dc494f25941b70..5b3bf534cf73c3 100644 --- a/docs/src/pages/system/display/Inline.tsx +++ b/docs/src/pages/system/display/Inline.tsx @@ -6,19 +6,23 @@ export default function Inline() {
inline inline diff --git a/docs/src/pages/system/display/Overflow.js b/docs/src/pages/system/display/Overflow.js index b52770ec491e69..0a9e8a8fe1184c 100644 --- a/docs/src/pages/system/display/Overflow.js +++ b/docs/src/pages/system/display/Overflow.js @@ -4,10 +4,16 @@ import Box from '@material-ui/core/Box'; export default function Overflow() { return (
- + Overflow Hidden. Overflow Hidden. Overflow Hidden. - + Overflow Auto. Overflow Auto. Overflow Auto.
diff --git a/docs/src/pages/system/display/Overflow.tsx b/docs/src/pages/system/display/Overflow.tsx index b52770ec491e69..03bb60c49477da 100644 --- a/docs/src/pages/system/display/Overflow.tsx +++ b/docs/src/pages/system/display/Overflow.tsx @@ -4,10 +4,10 @@ import Box from '@material-ui/core/Box'; export default function Overflow() { return (
- + Overflow Hidden. Overflow Hidden. Overflow Hidden. - + Overflow Auto. Overflow Auto. Overflow Auto.
diff --git a/docs/src/pages/system/display/Print.js b/docs/src/pages/system/display/Print.js index 603ad229762192..525b18708b54c7 100644 --- a/docs/src/pages/system/display/Print.js +++ b/docs/src/pages/system/display/Print.js @@ -4,10 +4,10 @@ import Box from '@material-ui/core/Box'; export default function Print() { return (
- + Screen Only (Hide on print only) - + Print Only (Hide on screen only)
diff --git a/docs/src/pages/system/display/Print.tsx b/docs/src/pages/system/display/Print.tsx index 603ad229762192..806d6feeb5aa18 100644 --- a/docs/src/pages/system/display/Print.tsx +++ b/docs/src/pages/system/display/Print.tsx @@ -4,10 +4,10 @@ import Box from '@material-ui/core/Box'; export default function Print() { return (
- + Screen Only (Hide on print only) - + Print Only (Hide on screen only)
diff --git a/docs/src/pages/system/display/TextOverflow.js b/docs/src/pages/system/display/TextOverflow.js index 0eadc4d60340f2..1de14063538b87 100644 --- a/docs/src/pages/system/display/TextOverflow.js +++ b/docs/src/pages/system/display/TextOverflow.js @@ -6,19 +6,23 @@ export default function TextOverflow() {
Text Overflow Clip. Text Overflow Clip. Text Overflow Ellipsis. Text Overflow Ellipsis diff --git a/docs/src/pages/system/display/TextOverflow.tsx b/docs/src/pages/system/display/TextOverflow.tsx index 0eadc4d60340f2..158c705b4af7c4 100644 --- a/docs/src/pages/system/display/TextOverflow.tsx +++ b/docs/src/pages/system/display/TextOverflow.tsx @@ -6,19 +6,23 @@ export default function TextOverflow() {
Text Overflow Clip. Text Overflow Clip. Text Overflow Ellipsis. Text Overflow Ellipsis diff --git a/docs/src/pages/system/display/Visibility.js b/docs/src/pages/system/display/Visibility.js index 142a8ebc1287b1..c1e6aced841cf1 100644 --- a/docs/src/pages/system/display/Visibility.js +++ b/docs/src/pages/system/display/Visibility.js @@ -6,19 +6,23 @@ export default function Visibility() {
Visibility Visible Visibility Hidden diff --git a/docs/src/pages/system/display/Visibility.tsx b/docs/src/pages/system/display/Visibility.tsx index 142a8ebc1287b1..fc7a799d138630 100644 --- a/docs/src/pages/system/display/Visibility.tsx +++ b/docs/src/pages/system/display/Visibility.tsx @@ -6,19 +6,23 @@ export default function Visibility() {
Visibility Visible Visibility Hidden diff --git a/docs/src/pages/system/display/WhiteSpace.js b/docs/src/pages/system/display/WhiteSpace.js index c1341640d16477..9ac9527f16aba4 100644 --- a/docs/src/pages/system/display/WhiteSpace.js +++ b/docs/src/pages/system/display/WhiteSpace.js @@ -6,17 +6,21 @@ export default function WhiteSpace() {
White Space Nowrap. White Space Nowrap. White Space Normal. White Space Normal. diff --git a/docs/src/pages/system/display/WhiteSpace.tsx b/docs/src/pages/system/display/WhiteSpace.tsx index c1341640d16477..a5b58f78fbb139 100644 --- a/docs/src/pages/system/display/WhiteSpace.tsx +++ b/docs/src/pages/system/display/WhiteSpace.tsx @@ -6,17 +6,21 @@ export default function WhiteSpace() {
White Space Nowrap. White Space Nowrap. White Space Normal. White Space Normal. diff --git a/docs/src/pages/system/display/display.md b/docs/src/pages/system/display/display.md index 030313cd6e33fc..b071e2df16a387 100644 --- a/docs/src/pages/system/display/display.md +++ b/docs/src/pages/system/display/display.md @@ -9,8 +9,8 @@ {{"demo": "pages/system/display/Inline.js", "defaultCodeOpen": false, "bg": true}} ```jsx -inline -inline +inline +inline ``` ### Block @@ -18,8 +18,8 @@ {{"demo": "pages/system/display/Block.js", "defaultCodeOpen": false, "bg": true}} ```jsx -block -block +block +block ``` ## Hiding elements @@ -28,25 +28,25 @@ For faster mobile-friendly development, use responsive display classes for showi | Screen Size | Class | | :----------------- | :--------------------------------------------------- | -| Hidden on all | `display="none"` | -| Hidden only on xs | `display={{ xs: 'none', sm: 'block' }}` | -| Hidden only on sm | `display={{ xs: 'block', sm: 'none', md: 'block' }}` | -| Hidden only on md | `display={{ xs: 'block', md: 'none', lg: 'block' }}` | -| Hidden only on lg | `display={{ xs: 'block', lg: 'none', xl: 'block' }}` | -| Hidden only on xl | `display={{ xs: 'block', xl: 'none' }}` | -| Visible only on xs | `display={{ xs: 'block', sm: 'none' }}` | -| Visible only on sm | `display={{ xs: 'none', sm: 'block', md: 'none' }}` | -| Visible only on md | `display={{ xs: 'none', md: 'block', lg: 'none' }}` | -| Visible only on lg | `display={{ xs: 'none', lg: 'block', xl: 'none' }}` | -| Visible only on xl | `display={{ xs: 'none', xl: 'block' }}` | +| Hidden on all | `sx={{ display: "none" }}` | +| Hidden only on xs | `sx={{ display: { xs: 'none', sm: 'block' }}}` | +| Hidden only on sm | `sx={{ display: { xs: 'block', sm: 'none', md: 'block' }}}` | +| Hidden only on md | `sx={{ display: { xs: 'block', md: 'none', lg: 'block' }}}` | +| Hidden only on lg | `sx={{ display: { xs: 'block', lg: 'none', xl: 'block' }}}` | +| Hidden only on xl | `sx={{ display: { xs: 'block', xl: 'none' }}}` | +| Visible only on xs | `sx={{ display: { xs: 'block', sm: 'none' }}}` | +| Visible only on sm | `sx={{ display: { xs: 'none', sm: 'block', md: 'none' }}}` | +| Visible only on md | `sx={{ display: { xs: 'none', md: 'block', lg: 'none' }}}` | +| Visible only on lg | `sx={{ display: { xs: 'none', lg: 'block', xl: 'none' }}}` | +| Visible only on xl | `sx={{ display: { xs: 'none', xl: 'block' }}}` | {{"demo": "pages/system/display/Hiding.js", "defaultCodeOpen": false}} ```jsx - + hide on screens wider than md - + hide on screens smaller than md ``` @@ -56,10 +56,10 @@ For faster mobile-friendly development, use responsive display classes for showi {{"demo": "pages/system/display/Print.js", "defaultCodeOpen": false}} ```jsx - + Screen Only (Hide on print only) - + Print Only (Hide on screen only) ``` @@ -69,10 +69,10 @@ For faster mobile-friendly development, use responsive display classes for showi {{"demo": "pages/system/display/Overflow.js", "defaultCodeOpen": false}} ```jsx - + Overflow Hidden - + Overflow visible ``` @@ -82,10 +82,10 @@ For faster mobile-friendly development, use responsive display classes for showi {{"demo": "pages/system/display/TextOverflow.js", "defaultCodeOpen": false}} ```jsx - + Text Overflow Clip - + Text Overflow Ellipsis ``` @@ -95,10 +95,10 @@ For faster mobile-friendly development, use responsive display classes for showi {{"demo": "pages/system/display/Visibility.js", "defaultCodeOpen": false}} ```jsx - + Visibility Visible - + Visibility Hidden ``` @@ -108,10 +108,10 @@ For faster mobile-friendly development, use responsive display classes for showi {{"demo": "pages/system/display/WhiteSpace.js", "defaultCodeOpen": false}} ```jsx - + White Space Nowrap - + White Space Normal ``` From e28a683bf49f9cf7f67fdfe30003fdeb6d0474f2 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 3 Nov 2020 13:40:06 +0100 Subject: [PATCH 29/84] addressing comments --- docs/src/pages/system/sx/sx.md | 21 ++++++++++++++++++- packages/material-ui/src/Box/index.js | 2 +- .../material-ui/src/Box/styleFunction.d.ts | 12 ++++++++++- packages/material-ui/src/Box/styleFunction.js | 7 ++++--- .../src/styles/experimentalStyled.js | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index d4e04ce0fbe93d..74124ac71a18f6 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -4,7 +4,26 @@ ## Getting started -Each `@material-ui/core` component supports the `sx` prop. The prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. +The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. + +You can include this prop in your own components too by using the `styleFunctionSx` style function from `@material-ui/core/Box`, or by using the `experimentalStyled` from `@material-ui/core/styles` for creating the custom component. + +```jsx +import { styleFunctionSx } from '@material-ui/core/Box'; +import styled from '@emotion/styled'; + +const Div = styled('div')(styleFunctionSx); +``` + +or + +```jsx +import { experimentalStyled as styled } from '@material-ui/core/styles'; + +const Div = styled('div')``; +``` + +Note: You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly add the same styles on a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. diff --git a/packages/material-ui/src/Box/index.js b/packages/material-ui/src/Box/index.js index c15b792255b474..41385e35794da3 100644 --- a/packages/material-ui/src/Box/index.js +++ b/packages/material-ui/src/Box/index.js @@ -1,2 +1,2 @@ export { default } from './Box'; -export { default as styleFunction } from './styleFunction'; +export { default as styleFunction, styleFunctionSx } from './styleFunction'; diff --git a/packages/material-ui/src/Box/styleFunction.d.ts b/packages/material-ui/src/Box/styleFunction.d.ts index 3c201089140988..890c1a1d73dde2 100644 --- a/packages/material-ui/src/Box/styleFunction.d.ts +++ b/packages/material-ui/src/Box/styleFunction.d.ts @@ -1,4 +1,14 @@ -import { BoxStyleFunction } from './Box'; +import { BoxStyleFunction, SxProps } from './Box'; +import { Theme as DefaultTheme } from '../styles'; +import { CSSObject } from '../styles/experimentalStyled'; + +type Props = { + [key: string]: any; + sx?: SxProps; + theme: Theme; +} + +export function styleFunctionSx(props: Props): CSSObject; declare const styleFunction: BoxStyleFunction; export default styleFunction; diff --git a/packages/material-ui/src/Box/styleFunction.js b/packages/material-ui/src/Box/styleFunction.js index 344b588ecd2e04..6a9ddd815549ba 100644 --- a/packages/material-ui/src/Box/styleFunction.js +++ b/packages/material-ui/src/Box/styleFunction.js @@ -72,7 +72,8 @@ const getThemeValue = (prop, value, theme) => { return { [prop]: value }; }; -export const styleFunctionSx = (styles, theme) => { +export const styleFunctionSx = (props = {}) => { + const { sx: styles, theme } = props; if (!styles) return null; if (typeof styles === 'function') { @@ -96,7 +97,7 @@ export const styleFunctionSx = (styles, theme) => { })); if (objectsHaveSameKeys(breakpointsValues, styles[styleKey])) { - const transformedValue = styleFunctionSx(styles[styleKey], theme); + const transformedValue = styleFunctionSx({ sx: styles[styleKey], theme }); css[styleKey] = transformedValue; } else { css = deepmerge(css, breakpointsValues); @@ -119,7 +120,7 @@ const styleFunction = (props) => { } }); - const sxValue = styleFunctionSx(props.sx, props.theme); + const sxValue = styleFunctionSx(props); return deepmerge(result, sxValue); }; diff --git a/packages/material-ui/src/styles/experimentalStyled.js b/packages/material-ui/src/styles/experimentalStyled.js index 579065381963c6..9062ea1956fe03 100644 --- a/packages/material-ui/src/styles/experimentalStyled.js +++ b/packages/material-ui/src/styles/experimentalStyled.js @@ -108,7 +108,7 @@ const experimentalStyled = (tag, options, muiOptions = {}) => { expressionsWithDefaultTheme.push((props) => { const theme = isEmpty(props.theme) ? defaultTheme : props.theme; - return styleFunctionSx(props.sx, theme); + return styleFunctionSx({ ...props, theme }); }); return defaultStyledResolver(transformedStyleArg, ...expressionsWithDefaultTheme); From 87c118e760369821d2241a28801891d17f2c275d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 3 Nov 2020 13:55:27 +0100 Subject: [PATCH 30/84] prettier & interface --- docs/src/pages/system/sx/sx.md | 4 ++-- packages/material-ui/src/Box/styleFunction.d.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md index 74124ac71a18f6..0fa2fffb0d0291 100644 --- a/docs/src/pages/system/sx/sx.md +++ b/docs/src/pages/system/sx/sx.md @@ -35,7 +35,7 @@ You can explore the [System API](/system/api/) page to discover how the differen ## Value as a function -If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. +If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. {{"demo": "pages/system/sx/ValueAsFunction.js", "defaultCodeOpen": true}} @@ -51,7 +51,7 @@ The first option is to define your breakpoints as an array, from the smallest to ## 2. Breakpoints as an object -The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. +The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. {{"demo": "pages/system/sx/BreakpointsAsObject.js", "defaultCodeOpen": true}} diff --git a/packages/material-ui/src/Box/styleFunction.d.ts b/packages/material-ui/src/Box/styleFunction.d.ts index 890c1a1d73dde2..4f9eeef6f50ae6 100644 --- a/packages/material-ui/src/Box/styleFunction.d.ts +++ b/packages/material-ui/src/Box/styleFunction.d.ts @@ -2,13 +2,15 @@ import { BoxStyleFunction, SxProps } from './Box'; import { Theme as DefaultTheme } from '../styles'; import { CSSObject } from '../styles/experimentalStyled'; -type Props = { +interface Props { [key: string]: any; sx?: SxProps; theme: Theme; } -export function styleFunctionSx(props: Props): CSSObject; +export function styleFunctionSx( + props: Props +): CSSObject; declare const styleFunction: BoxStyleFunction; export default styleFunction; From b0fa09c5c43d1c5ec87ece159fd862e39547ba25 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 16:56:21 +0100 Subject: [PATCH 31/84] demo update --- docs/src/pages/system/basics/Demo.js | 112 ++++++++++++++----- docs/src/pages/system/basics/Demo.tsx | 147 ++++++++++++++++++------- docs/src/pages/system/basics/basics.md | 2 +- 3 files changed, 195 insertions(+), 66 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index e72cd857c524f9..deddee6a0833d5 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -1,36 +1,92 @@ import * as React from 'react'; -import styled, { ThemeProvider } from 'styled-components'; -import NoSsr from '@material-ui/core/NoSsr'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { palette, spacing, typography } from '@material-ui/system'; +import Box from '@material-ui/core/Box'; -const Box = styled.div` - ${palette} - ${spacing} - ${typography} -`; -// or import Box from '@material-ui/core/Box'; +const CardHeader = (props) => { + const imgSize = [60, 90, 90, 120, 150]; + return + + +} + +const CardContent = (props) => { + return ( + + + {props.header} + + + {props.description} + + + ); +} -const theme = createMuiTheme(); +const Card = (props) => { + return ( + + + + ) +} export default function Demo() { return ( - - - - @material-ui/system - - - + ); } diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index f4179c467d69f4..2fd18c416ed052 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -1,43 +1,116 @@ import * as React from 'react'; -import styled, { ThemeProvider } from 'styled-components'; -import NoSsr from '@material-ui/core/NoSsr'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { - palette, - PaletteProps, - spacing, - SpacingProps, - typography, - TypographyProps, -} from '@material-ui/system'; - -const Box = styled.div` - ${palette} - ${spacing} - ${typography} -`; -// or import Box from '@material-ui/core/Box'; - -const theme = createMuiTheme(); +import Box, { SxProps } from '@material-ui/core/Box'; + +type Color = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; + +interface CardHeaderProps { + color?: Color; + sx?: SxProps; + src?: string; + alt?: string; +} + +const CardHeader: React.FC = (props) => { + const imgSize = [60, 90, 90, 120, 150]; + return + + +} + +interface CardContentProps { + color?: Color; + header?: string; + description?: string; + sx?: SxProps +} + +const CardContent: React.FC = (props) => { + return ( + + + {props.header} + + + {props.description} + + + ); +} + +interface CardProps { + color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; + header?: string; + description: string; + sx?: SxProps; + profileImage?: string; +} + +const Card: React.FC = (props) => { + return ( + + + + ) +} export default function Demo() { return ( - - - - @material-ui/system - - - + ); } diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 36f366cdd8c999..17eab5624e0592 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -2,7 +2,7 @@

Styled system & style functions for building powerful design systems.

-## Getting Started +{{"demo": "pages/system/basics/Demo.js", "defaultCodeOpen": true}} `@material-ui/system` provides low-level utility functions called "_style functions_" for building powerful design systems. Some of the key features: From e3808bb2fef84379f4b307f8131d6906eff51e8a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 17:26:29 +0100 Subject: [PATCH 32/84] wip update content --- docs/pages/system/sx.js | 20 - docs/src/pages.js | 1 - .../{sx => basics}/BreakpointsAsArray.js | 0 .../{sx => basics}/BreakpointsAsArray.tsx | 0 .../{sx => basics}/BreakpointsAsObject.js | 0 .../{sx => basics}/BreakpointsAsObject.tsx | 0 .../system/{sx => basics}/ValueAsFunction.js | 0 .../system/{sx => basics}/ValueAsFunction.tsx | 0 docs/src/pages/system/basics/basics.md | 364 +++++------------- docs/src/pages/system/sx/GettingStarted.js | 20 - docs/src/pages/system/sx/GettingStarted.tsx | 20 - docs/src/pages/system/sx/sx.md | 111 ------ 12 files changed, 100 insertions(+), 436 deletions(-) delete mode 100644 docs/pages/system/sx.js rename docs/src/pages/system/{sx => basics}/BreakpointsAsArray.js (100%) rename docs/src/pages/system/{sx => basics}/BreakpointsAsArray.tsx (100%) rename docs/src/pages/system/{sx => basics}/BreakpointsAsObject.js (100%) rename docs/src/pages/system/{sx => basics}/BreakpointsAsObject.tsx (100%) rename docs/src/pages/system/{sx => basics}/ValueAsFunction.js (100%) rename docs/src/pages/system/{sx => basics}/ValueAsFunction.tsx (100%) delete mode 100644 docs/src/pages/system/sx/GettingStarted.js delete mode 100644 docs/src/pages/system/sx/GettingStarted.tsx delete mode 100644 docs/src/pages/system/sx/sx.md diff --git a/docs/pages/system/sx.js b/docs/pages/system/sx.js deleted file mode 100644 index 34ff54f916ea4a..00000000000000 --- a/docs/pages/system/sx.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; - -const pageFilename = 'system/sx'; -const requireDemo = require.context('docs/src/pages/system/sx', false, /\.(js|tsx)$/); -const requireRaw = require.context( - '!raw-loader!../../src/pages/system/sx', - false, - /\.(js|md|tsx)$/, -); - -export default function Page({ demos, docs }) { - return ; -} - -Page.getInitialProps = () => { - const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); - return { demos, docs }; -}; diff --git a/docs/src/pages.js b/docs/src/pages.js index 108790a5332cea..0abcbefb7047d5 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -175,7 +175,6 @@ const pages = [ pathname: '/system', children: [ { pathname: '/system/basics' }, - { pathname: '/system/sx', title: 'sx' }, { pathname: '/system/borders' }, { pathname: '/system/display' }, { pathname: '/system/flexbox' }, diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.js b/docs/src/pages/system/basics/BreakpointsAsArray.js similarity index 100% rename from docs/src/pages/system/sx/BreakpointsAsArray.js rename to docs/src/pages/system/basics/BreakpointsAsArray.js diff --git a/docs/src/pages/system/sx/BreakpointsAsArray.tsx b/docs/src/pages/system/basics/BreakpointsAsArray.tsx similarity index 100% rename from docs/src/pages/system/sx/BreakpointsAsArray.tsx rename to docs/src/pages/system/basics/BreakpointsAsArray.tsx diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.js b/docs/src/pages/system/basics/BreakpointsAsObject.js similarity index 100% rename from docs/src/pages/system/sx/BreakpointsAsObject.js rename to docs/src/pages/system/basics/BreakpointsAsObject.js diff --git a/docs/src/pages/system/sx/BreakpointsAsObject.tsx b/docs/src/pages/system/basics/BreakpointsAsObject.tsx similarity index 100% rename from docs/src/pages/system/sx/BreakpointsAsObject.tsx rename to docs/src/pages/system/basics/BreakpointsAsObject.tsx diff --git a/docs/src/pages/system/sx/ValueAsFunction.js b/docs/src/pages/system/basics/ValueAsFunction.js similarity index 100% rename from docs/src/pages/system/sx/ValueAsFunction.js rename to docs/src/pages/system/basics/ValueAsFunction.js diff --git a/docs/src/pages/system/sx/ValueAsFunction.tsx b/docs/src/pages/system/basics/ValueAsFunction.tsx similarity index 100% rename from docs/src/pages/system/sx/ValueAsFunction.tsx rename to docs/src/pages/system/basics/ValueAsFunction.tsx diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 17eab5624e0592..467842a3224d98 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -4,335 +4,171 @@ {{"demo": "pages/system/basics/Demo.js", "defaultCodeOpen": true}} -`@material-ui/system` provides low-level utility functions called "_style functions_" for building powerful design systems. Some of the key features: +## Why -- ⚛️ Access the theme values directly from the component props. -- 🦋 Encourage UI consistency. -- 🌈 Write responsive style effortlessly. -- 🦎 Work with any theme object. -- 💅 Work with the most popular CSS-in-JS solutions. -- 📦 Less than [4 KB gzipped](https://bundlephobia.com/result?p=@material-ui/system). -- 🚀 [Fast enough](https://github.com/mui-org/material-ui/blob/next/packages/material-ui-benchmark/README.md#material-uisystem) not to be a bottleneck at runtime. +There are several reasons for why you may need the system offered by Material-UI. Here are few of them: -It's important to understand that this package exposes pure (side-effect free) style functions with this signature: `({ theme, ...style }) => style`, **that's it**. +### 1. Building consistent UIs is hard -### Demo +This is especially true, when there is at least more than one person building the application. There has to be some synchronization to what are the design tokens and how are those used. What parts of the theme structure should be used with what CSS proeprties. -In the rest of this _Getting Started_ section we are using **styled-components** as the reference example (to emphasize the universality of this package). Alternatively, you can [emotion](#interoperability) or any other CSS-in-JS styling solution. -The demos are also based on the **default** Material-UI [theme object](/customization/default-theme/). +### 2. Switching context between JS and CSS -{{"demo": "pages/system/basics/Demo.js", "defaultCodeOpen": true}} +Often we find ourselves jumping from the JS to the CSS files, or from the components definition to the instance usage in order to conclude where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component you are working on increases. We could save a lot of time by removing this contraint. -### Installation +### 3. Less code to type -```jsx -// with npm -npm install @material-ui/system +Usually when defining styles for a react component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch the context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. -// with yarn -yarn add @material-ui/system -``` +## How do we solve this? -### Create a component +In order to solve these issues, we need to have simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the react element where we want the styles to be applied, by a prop, that can be easily discoverable. -In order to use the `Box` component, you first need to create it. -To start with, add a `spacing` and `palette` function to the style argument. +The `sx` prop, as part of the system is the solution we see for solving this problems. In the example above, you may see how it can be used on the MUI components. -```jsx -import styled from 'styled-components'; -import { spacing, palette } from '@material-ui/system'; +It behaves as a superset of CSS and allows using values from the theme directly, by pulling specific values depending on the CSS property used. In addition to this, it allows a simple way of defining responsive values, that corresponds to the breakpoints values defined in the theme. -const Box = styled.div` - ${spacing}${palette} -`; +With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system needs to. -export default Box; -``` +In the next sections, we will dive deeper into all features of the `sx` prop. -This Box component now supports new [spacing props](/system/spacing/#api) and [color props](/system/palette/#api). -For example, you can provide a padding prop: `p` and a color prop: `color`. +## Installation ```jsx - - Give me some space! - +// with npm +npm install @material-ui/system + +// with yarn +yarn add @material-ui/system ``` -The component can be styled providing any valid CSS values. +## The `sx` prop -### Theming +The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. -But most of the time, you want to rely on a theme's values to increase the UI consistency. -It's preferable to have a predetermined set of padding and color values. -Import the theme provider of your styling solution. +You can include this prop in your own components too by using the `styleFunctionSx` style function from `@material-ui/core/Box`, or by using the `experimentalStyled` from `@material-ui/core/styles` for creating the custom component. ```jsx -import * as React from 'react'; -import { ThemeProvider } from 'styled-components'; - -const theme = { - spacing: 4, - palette: { - primary: '#007bff', - }, -}; - -export default function App() { - return {/* children */}; -} -``` - -Now, you can provide a spacing multiplier value: +import { styleFunctionSx } from '@material-ui/core/Box'; +import styled from '@emotion/styled'; -```jsx -4px -8px --4px +const Div = styled('div')(styleFunctionSx); ``` -and a primary color: +or ```jsx -blue -``` - -### All-inclusive - -To make the Box component more useful, we have been building a collection of style functions, here is the full list: - -- [borders](/system/borders/#api) -- [display](/system/display/#api) -- [flexbox](/system/flexbox/#api) -- [palette](/system/palette/#api) -- [positions](/system/positions/#api) -- [shadows](/system/shadows/#api) -- [sizing](/system/sizing/#api) -- [spacing](/system/spacing/#api) -- [typography](/system/typography/#api) - -If you are already using `@material-ui/core`, you can use the [Box component](/components/box/) (using emotion internally by default): +import { experimentalStyled as styled } from '@material-ui/core/styles'; -```jsx -import Box from '@material-ui/core/Box'; +const Div = styled('div')``; ``` -## Interoperability - -`@material-ui/system` works with most CSS-in-JS libraries, including JSS, styled-components, and emotion. Here are a few examples usages. - -### Styled components - -{{"demo": "pages/system/basics/StyledComponents.js", "defaultCodeOpen": true}} +Note: -### Emotion +You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly add the same styles on a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. -{{"demo": "pages/system/basics/Emotion.js", "defaultCodeOpen": true}} +### Design tokens in the theme -## Responsive +You can explore the [System API](/system/api/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. -**All** the props are responsive. There are three different APIs – Array, Object, and Collocation – that each use this default (but customizable) breakpoints theme structure: +### Many shorthands -```js -const values = { - xs: 0, - sm: 600, - md: 960, - lg: 1280, - xl: 1920, -}; - -const theme = { - breakpoints: { - keys: ['xs', 'sm', 'md', 'lg', 'xl'], - up: (key) => `@media (min-width:${values[key]}px)`, - }, -}; -``` +### Superset of CSS -### Array +Child selector, pseudo selector, media queries, raw value. -```jsx - - -/** - * Outputs: - * - * padding: 16px; - * @media (min-width: 600px) { - * padding: 24px; - * } - * @media (min-width: 960px) { - * padding: 32px; - * } - */ -``` +## Usage -### Object +It can be used from 3 different sources: -```jsx - - -/** - * Outputs: - * - * padding: 16px; - * @media (min-width: 600px) { - * padding: 24px; - * } - * @media (min-width: 960px) { - * padding: 32px; - * } - */ -``` +### Box -### Collocation +The `Box` component is a light component that gives you access to this functionality. -If you want to group the breakpoint values, you can use the `breakpoints()` helper. +### Babel plugin -```jsx -import { compose, spacing, palette, breakpoints } from '@material-ui/system'; -import styled from 'styled-components'; - -const Box = styled.div` - ${breakpoints(compose(spacing, palette))} -`; - -; - -/** - * Outputs: - * - * padding: 16px; - * @media (min-width: 600px) { - * padding: 24px; - * } - * @media (min-width: 960px) { - * padding: 32px; - * } - */ -``` +TODO: For #23220 -{{"demo": "pages/system/basics/CollocationApi.js"}} +### Core components -## Custom style props +All core Material-UI components will suppor the `sx` prop. -### `style(options) => style function` +## Responsive values -Use this helper to create your own style function. +If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: -Not all CSS properties are supported. -It's possible that you want to support new ones. -It's also possible that you want to change the theme path prefix. +### 1. Breakpoints as an array -#### Arguments +The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. -1. `options` (_Object_): +{{"demo": "pages/system/basics/BreakpointsAsArray.js", "defaultCodeOpen": true}} -- `options.prop` (_String_): The prop the style function will be triggered on. -- `options.cssProperty` (_String|Boolean_ [optional]): Defaults to `options.prop`. The CSS property used. - You can disabled this option by providing `false`. When disabled, the property value will be handled as a style object on it's own. It can be used for [rendering variants](#variants). -- `options.themeKey` (_String_ [optional]): The theme path prefix. -- `options.transform` (_Function_ [optional]): Apply a transformation before outputing a CSS value. +### 2. Breakpoints as an object -#### Returns +The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. -`style function`: The style function created. +{{"demo": "pages/system/basics/BreakpointsAsObject.js", "defaultCodeOpen": true}} -#### Examples +## Custom breakpoints -You can create a component that supports some CSS grid properties such as `grid-gap`. By supplying `spacing` as the `themeKey` you can reuse logic enabling the behavior we see in other spacing properties like `padding`. +You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that. ```jsx -import styled from 'styled-components'; -import { style } from '@material-ui/system'; -import { Box } from '@material-ui/core'; - -const gridGap = style({ - prop: 'gridGap', - themeKey: 'spacing', -}); - -const Grid = styled(Box)` - ${gridGap} -`; -const example = ( - - ... - -); -``` - -You can also customize the prop name by adding both a `prop` and `cssProperty` and transform the value by adding a `transform` function. +import * as React from 'react'; +import Box from '@material-ui/core/Box'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; -```jsx -import styled from 'styled-components'; -import { style } from '@material-ui/system'; - -const borderColor = style({ - prop: 'bc', - cssProperty: 'borderColor', - themeKey: 'palette', - transform: (value) => `${value} !important`, +const theme = createMuiTheme({ + breakpoints: { + values: { + tablet: 640, + laptop: 1024, + desktop: 1280, + }, + }, }); -const Colored = styled.div` - ${borderColor} -`; -const example = ...; +export default function CustomBreakpoints() { + return ( + + + This box has a responsive width + + + ); +} ``` -### `compose(...style functions) => style function` - -Merge multiple style functions into one. - -#### Returns - -`style function`: The style function created. - -#### Examples - -```js -import { style, compose } from '@material-ui/system'; - -export const textColor = style({ - prop: 'color', - themeKey: 'palette', -}); - -export const bgcolor = style({ - prop: 'bgcolor', - cssProperty: 'backgroundColor', - themeKey: 'palette', -}); - -const palette = compose(textColor, bgcolor); +If you are using TypeScript, you would also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. + +```ts +declare module '@material-ui/core/styles/createBreakpoints' { + interface BreakpointOverrides { + xs: false; // removes the `xs` breakpoint + sm: false; + md: false; + lg: false; + xl: false; + tablet: true; // adds the `tablet` breakpoint + laptop: true; + desktop: true; + } +} ``` -## Variants - -The `style()` helper can also be used to maps props to style objects in a theme. -In this example, the `variant` prop supports all the keys present in `theme.typography`. - -{{"demo": "pages/system/basics/Variant.js", "defaultCodeOpen": true}} - -## CSS prop - -If you want to support custom CSS values, you can use the `css()` helper. -It will process the `css` prop. - -{{"demo": "pages/system/basics/CssProp.js", "defaultCodeOpen": true}} - -## How it works - -styled-system has done a great job at [explaining how it works](https://github.com/jxnblk/styled-system/blob/master/docs/how-it-works.md#how-it-works). -It can help building a mental model for this "style function" concept. - -## Real-world use case +## Theme getter -In practice, a Box component can save you a lot of time. -In this example, we demonstrate how to reproduce a Banner component. +If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. -{{"demo": "pages/system/basics/RealWorld.js", "bg": true}} +{{"demo": "pages/system/basics/ValueAsFunction.js", "defaultCodeOpen": true}} ## Prior art diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js deleted file mode 100644 index 3644af77340792..00000000000000 --- a/docs/src/pages/system/sx/GettingStarted.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; - -export default function GettingStarted() { - return ( - - How to use the sx prop. - - ); -} diff --git a/docs/src/pages/system/sx/GettingStarted.tsx b/docs/src/pages/system/sx/GettingStarted.tsx deleted file mode 100644 index 3644af77340792..00000000000000 --- a/docs/src/pages/system/sx/GettingStarted.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; - -export default function GettingStarted() { - return ( - - How to use the sx prop. - - ); -} diff --git a/docs/src/pages/system/sx/sx.md b/docs/src/pages/system/sx/sx.md deleted file mode 100644 index 0fa2fffb0d0291..00000000000000 --- a/docs/src/pages/system/sx/sx.md +++ /dev/null @@ -1,111 +0,0 @@ -# The `sx` prop - -

Utility for styling elements inline, using the theme values.

- -## Getting started - -The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. - -You can include this prop in your own components too by using the `styleFunctionSx` style function from `@material-ui/core/Box`, or by using the `experimentalStyled` from `@material-ui/core/styles` for creating the custom component. - -```jsx -import { styleFunctionSx } from '@material-ui/core/Box'; -import styled from '@emotion/styled'; - -const Div = styled('div')(styleFunctionSx); -``` - -or - -```jsx -import { experimentalStyled as styled } from '@material-ui/core/styles'; - -const Div = styled('div')``; -``` - -Note: - -You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly add the same styles on a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. - -{{"demo": "pages/system/sx/GettingStarted.js", "defaultCodeOpen": true}} - -# Property to theme key mapping - -You can explore the [System API](/system/api/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. - -## Value as a function - -If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. - -{{"demo": "pages/system/sx/ValueAsFunction.js", "defaultCodeOpen": true}} - -# Breakpoints - -If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: - -## 1. Breakpoints as an array - -The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. - -{{"demo": "pages/system/sx/BreakpointsAsArray.js", "defaultCodeOpen": true}} - -## 2. Breakpoints as an object - -The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. - -{{"demo": "pages/system/sx/BreakpointsAsObject.js", "defaultCodeOpen": true}} - -## Custom breakpoints - -You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that. - -```jsx -import * as React from 'react'; -import Box from '@material-ui/core/Box'; -import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; - -const theme = createMuiTheme({ - breakpoints: { - values: { - tablet: 640, - laptop: 1024, - desktop: 1280, - }, - }, -}); - -export default function CustomBreakpoints() { - return ( - - - This box has a responsive width - - - ); -} -``` - -If you are using TypeScript, you would also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. - -```ts -declare module '@material-ui/core/styles/createBreakpoints' { - interface BreakpointOverrides { - xs: false; // removes the `xs` breakpoint - sm: false; - md: false; - lg: false; - xl: false; - tablet: true; // adds the `tablet` breakpoint - laptop: true; - desktop: true; - } -} -``` From 01bc2414c2e8c726907fe7210ea54b0d6571d8c8 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 19:56:30 +0100 Subject: [PATCH 33/84] Updated docs --- docs/pages/system/{api.js => properties.js} | 6 +- docs/src/pages.js | 2 +- docs/src/pages/system/basics/Demo.js | 166 +++++++++++++----- docs/src/pages/system/basics/Demo.tsx | 126 +++++++------ docs/src/pages/system/basics/basics.md | 77 +++++--- .../api-de.md => properties/properties-de.md} | 0 .../api-es.md => properties/properties-es.md} | 0 .../api-fr.md => properties/properties-fr.md} | 0 .../api-ja.md => properties/properties-ja.md} | 0 .../api-pt.md => properties/properties-pt.md} | 0 .../api-ru.md => properties/properties-ru.md} | 0 .../api-zh.md => properties/properties-zh.md} | 0 .../{api/api.md => properties/properties.md} | 4 +- 13 files changed, 258 insertions(+), 123 deletions(-) rename docs/pages/system/{api.js => properties.js} (72%) rename docs/src/pages/system/{api/api-de.md => properties/properties-de.md} (100%) rename docs/src/pages/system/{api/api-es.md => properties/properties-es.md} (100%) rename docs/src/pages/system/{api/api-fr.md => properties/properties-fr.md} (100%) rename docs/src/pages/system/{api/api-ja.md => properties/properties-ja.md} (100%) rename docs/src/pages/system/{api/api-pt.md => properties/properties-pt.md} (100%) rename docs/src/pages/system/{api/api-ru.md => properties/properties-ru.md} (100%) rename docs/src/pages/system/{api/api-zh.md => properties/properties-zh.md} (100%) rename docs/src/pages/system/{api/api.md => properties/properties.md} (99%) diff --git a/docs/pages/system/api.js b/docs/pages/system/properties.js similarity index 72% rename from docs/pages/system/api.js rename to docs/pages/system/properties.js index 075fe269330d45..11716668d36780 100644 --- a/docs/pages/system/api.js +++ b/docs/pages/system/properties.js @@ -2,10 +2,10 @@ import React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; -const pageFilename = 'system/api'; -const requireDemo = require.context('docs/src/pages/system/api', false, /\.(js|tsx)$/); +const pageFilename = 'system/properties'; +const requireDemo = require.context('docs/src/pages/system/properties', false, /\.(js|tsx)$/); const requireRaw = require.context( - '!raw-loader!../../src/pages/system/api', + '!raw-loader!../../src/pages/system/properties', false, /\.(js|md|tsx)$/, ); diff --git a/docs/src/pages.js b/docs/src/pages.js index 0abcbefb7047d5..663088aa77f74d 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -185,7 +185,7 @@ const pages = [ { pathname: '/system/spacing' }, { pathname: '/system/screen-readers' }, { pathname: '/system/typography' }, - { pathname: '/system/api', title: 'API' }, + { pathname: '/system/properties' }, ], }, { diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index deddee6a0833d5..3a5fea248aa197 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -1,36 +1,51 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import Box from '@material-ui/core/Box'; const CardHeader = (props) => { const imgSize = [60, 90, 90, 120, 150]; - return - - -} + > + + + ); +}; + +CardHeader.propTypes = { + color: PropTypes.oneOf([ + 'error', + 'info', + 'primary', + 'secondary', + 'success', + 'warning', + ]), + sx: PropTypes.object, +}; const CardContent = (props) => { return ( @@ -38,12 +53,13 @@ const CardContent = (props) => { {...props} sx={{ display: 'inline-block', - px:1, + px: 1, py: 2, ...props.sx, }} > - { > {props.header} - + {props.description} ); -} +}; + +CardContent.propTypes = { + color: PropTypes.oneOf([ + 'error', + 'info', + 'primary', + 'secondary', + 'success', + 'warning', + ]), + description: PropTypes.string, + header: PropTypes.string, + sx: PropTypes.object, +}; const Card = (props) => { - return ( - - - - ) -} + const { + color = 'primary', + profileImage, + header, + description, + sx, + ...rest + } = props; + return ( + + + + + ); +}; + +Card.propTypes = { + color: PropTypes.oneOf([ + 'error', + 'info', + 'primary', + 'secondary', + 'success', + 'warning', + ]), + description: PropTypes.string.isRequired, + header: PropTypes.string, + profileImage: PropTypes.string, + sx: PropTypes.object, +}; export default function Demo() { return ( diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 2fd18c416ed052..9dbcb06b48bc88 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -12,40 +12,42 @@ interface CardHeaderProps { const CardHeader: React.FC = (props) => { const imgSize = [60, 90, 90, 120, 150]; - return - - -} + > + + + ); +}; interface CardContentProps { color?: Color; header?: string; description?: string; - sx?: SxProps + sx?: SxProps; } const CardContent: React.FC = (props) => { @@ -54,12 +56,13 @@ const CardContent: React.FC = (props) => { {...props} sx={{ display: 'inline-block', - px:1, + px: 1, py: 2, ...props.sx, }} > - = (props) => { > {props.header} - + {props.description} ); -} +}; interface CardProps { color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; @@ -85,24 +94,43 @@ interface CardProps { } const Card: React.FC = (props) => { - return ( - - - - ) -} + const { + color = 'primary', + profileImage, + header, + description, + sx, + ...rest + } = props; + return ( + + + + + ); +}; export default function Demo() { return ( diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 467842a3224d98..ef726c5c5e41e8 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -2,7 +2,7 @@

Styled system & style functions for building powerful design systems.

-{{"demo": "pages/system/basics/Demo.js", "defaultCodeOpen": true}} +{{"demo": "pages/system/basics/Demo.js"}} ## Why @@ -10,11 +10,11 @@ There are several reasons for why you may need the system offered by Material-UI ### 1. Building consistent UIs is hard -This is especially true, when there is at least more than one person building the application. There has to be some synchronization to what are the design tokens and how are those used. What parts of the theme structure should be used with what CSS proeprties. +This is especially true, when there is at least more than one person building the application. There has to be some synchronization to what are the design tokens and how are those used. What parts of the theme structure should be used with what CSS properties etc. ### 2. Switching context between JS and CSS -Often we find ourselves jumping from the JS to the CSS files, or from the components definition to the instance usage in order to conclude where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component you are working on increases. We could save a lot of time by removing this contraint. +Often we find ourselves jumping from the JS to the CSS files, or from the components definition to the instance usage in order to conclude where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this contraint. ### 3. Less code to type @@ -22,13 +22,13 @@ Usually when defining styles for a react component we need to either define a se ## How do we solve this? -In order to solve these issues, we need to have simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the react element where we want the styles to be applied, by a prop, that can be easily discoverable. +In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the react element where we want the styles to be applied, by a prop, that can be easily discoverable. -The `sx` prop, as part of the system is the solution we see for solving this problems. In the example above, you may see how it can be used on the MUI components. +The `sx` prop, as part of the system is the solution we see for solving these problems. In the example above, you may see how it can be used on the MUI components. -It behaves as a superset of CSS and allows using values from the theme directly, by pulling specific values depending on the CSS property used. In addition to this, it allows a simple way of defining responsive values, that corresponds to the breakpoints values defined in the theme. +The property behaves as a superset of CSS that offers mapping values from the theme directly, by pulling specific values depending on the CSS property used. In addition to this, it allows a simple way of defining responsive values, that corresponds to the breakpoints values defined in the theme. -With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system needs to. +With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system specifies. In the next sections, we will dive deeper into all features of the `sx` prop. @@ -46,16 +46,7 @@ yarn add @material-ui/system The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. -You can include this prop in your own components too by using the `styleFunctionSx` style function from `@material-ui/core/Box`, or by using the `experimentalStyled` from `@material-ui/core/styles` for creating the custom component. - -```jsx -import { styleFunctionSx } from '@material-ui/core/Box'; -import styled from '@emotion/styled'; - -const Div = styled('div')(styleFunctionSx); -``` - -or +You can include this prop in your own components too by using the `experimentalStyled` utility from `@material-ui/core/styles` for creating your custom component. ```jsx import { experimentalStyled as styled } from '@material-ui/core/styles'; @@ -69,15 +60,61 @@ You should use this prop whenever you need to add a style override to a Material ### Design tokens in the theme -You can explore the [System API](/system/api/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. +You can explore the [System properties](/system/properties/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. ### Many shorthands +We offer lots of shorthands on the CSS properties. Here are few examples: + +```jsx + +``` + ### Superset of CSS -Child selector, pseudo selector, media queries, raw value. +As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw css values etc. On the example above, we had several examples of this. + +```jsx + // Using pseudo selectors + +``` + +```jsx + // Using media queries + +``` -## Usage +## Usage It can be used from 3 different sources: diff --git a/docs/src/pages/system/api/api-de.md b/docs/src/pages/system/properties/properties-de.md similarity index 100% rename from docs/src/pages/system/api/api-de.md rename to docs/src/pages/system/properties/properties-de.md diff --git a/docs/src/pages/system/api/api-es.md b/docs/src/pages/system/properties/properties-es.md similarity index 100% rename from docs/src/pages/system/api/api-es.md rename to docs/src/pages/system/properties/properties-es.md diff --git a/docs/src/pages/system/api/api-fr.md b/docs/src/pages/system/properties/properties-fr.md similarity index 100% rename from docs/src/pages/system/api/api-fr.md rename to docs/src/pages/system/properties/properties-fr.md diff --git a/docs/src/pages/system/api/api-ja.md b/docs/src/pages/system/properties/properties-ja.md similarity index 100% rename from docs/src/pages/system/api/api-ja.md rename to docs/src/pages/system/properties/properties-ja.md diff --git a/docs/src/pages/system/api/api-pt.md b/docs/src/pages/system/properties/properties-pt.md similarity index 100% rename from docs/src/pages/system/api/api-pt.md rename to docs/src/pages/system/properties/properties-pt.md diff --git a/docs/src/pages/system/api/api-ru.md b/docs/src/pages/system/properties/properties-ru.md similarity index 100% rename from docs/src/pages/system/api/api-ru.md rename to docs/src/pages/system/properties/properties-ru.md diff --git a/docs/src/pages/system/api/api-zh.md b/docs/src/pages/system/properties/properties-zh.md similarity index 100% rename from docs/src/pages/system/api/api-zh.md rename to docs/src/pages/system/properties/properties-zh.md diff --git a/docs/src/pages/system/api/api.md b/docs/src/pages/system/properties/properties.md similarity index 99% rename from docs/src/pages/system/api/api.md rename to docs/src/pages/system/properties/properties.md index 9d1ede4694679e..d14925be03fe08 100644 --- a/docs/src/pages/system/api/api.md +++ b/docs/src/pages/system/properties/properties.md @@ -1,6 +1,6 @@ -# API +# Properties -

The API reference of the @material-ui/system package.

+

The properties reference of the @material-ui/system package.

| Group | Import name | Prop | CSS property | Theme key | | :-------------------------------- | :--------------- | :----------------- | :------------------------------ | :--------------------------------------------------------------------- | From 780d5fde8fcb668c571371260f2d13db9f72006f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 19:58:23 +0100 Subject: [PATCH 34/84] Update packages/material-ui/src/Box/index.js --- packages/material-ui/src/Box/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/Box/index.js b/packages/material-ui/src/Box/index.js index 41385e35794da3..c15b792255b474 100644 --- a/packages/material-ui/src/Box/index.js +++ b/packages/material-ui/src/Box/index.js @@ -1,2 +1,2 @@ export { default } from './Box'; -export { default as styleFunction, styleFunctionSx } from './styleFunction'; +export { default as styleFunction } from './styleFunction'; From cc5f8c70bde49013ee8a857a4f59d7ef32621630 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:04:34 +0100 Subject: [PATCH 35/84] Update docs/translations/translations.json --- docs/translations/translations.json | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 64f09bc03b6890..2e9b713d681202 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -211,7 +211,6 @@ "/styles/basics": "Basics", "/styles/advanced": "Advanced", "/system": "System", - "/system/sx": "sx", "/system/basics": "Basics", "/system/borders": "Borders", "/system/display": "Display", From 6a9108db4a6c92dea8e8863d5160999b7918fdb5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:05:38 +0100 Subject: [PATCH 36/84] Update packages/material-ui/src/Box/styleFunction.d.ts --- packages/material-ui/src/Box/styleFunction.d.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/material-ui/src/Box/styleFunction.d.ts b/packages/material-ui/src/Box/styleFunction.d.ts index 4f9eeef6f50ae6..3c201089140988 100644 --- a/packages/material-ui/src/Box/styleFunction.d.ts +++ b/packages/material-ui/src/Box/styleFunction.d.ts @@ -1,16 +1,4 @@ -import { BoxStyleFunction, SxProps } from './Box'; -import { Theme as DefaultTheme } from '../styles'; -import { CSSObject } from '../styles/experimentalStyled'; - -interface Props { - [key: string]: any; - sx?: SxProps; - theme: Theme; -} - -export function styleFunctionSx( - props: Props -): CSSObject; +import { BoxStyleFunction } from './Box'; declare const styleFunction: BoxStyleFunction; export default styleFunction; From 9d5bd14786806928da52cbcc54f29a6b22d52f63 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:06:05 +0100 Subject: [PATCH 37/84] Update packages/material-ui/src/Box/styleFunction.js --- packages/material-ui/src/Box/styleFunction.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/material-ui/src/Box/styleFunction.js b/packages/material-ui/src/Box/styleFunction.js index 6a9ddd815549ba..85a8858dfa1f57 100644 --- a/packages/material-ui/src/Box/styleFunction.js +++ b/packages/material-ui/src/Box/styleFunction.js @@ -72,8 +72,7 @@ const getThemeValue = (prop, value, theme) => { return { [prop]: value }; }; -export const styleFunctionSx = (props = {}) => { - const { sx: styles, theme } = props; +export const styleFunctionSx = (styles, theme) => { if (!styles) return null; if (typeof styles === 'function') { From 2854661220b5388b32ce9f420cff4bfce49803d6 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:06:56 +0100 Subject: [PATCH 38/84] Update packages/material-ui/src/Box/styleFunction.js --- packages/material-ui/src/Box/styleFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/Box/styleFunction.js b/packages/material-ui/src/Box/styleFunction.js index 85a8858dfa1f57..617b6f25d0099b 100644 --- a/packages/material-ui/src/Box/styleFunction.js +++ b/packages/material-ui/src/Box/styleFunction.js @@ -96,7 +96,7 @@ export const styleFunctionSx = (styles, theme) => { })); if (objectsHaveSameKeys(breakpointsValues, styles[styleKey])) { - const transformedValue = styleFunctionSx({ sx: styles[styleKey], theme }); + const transformedValue = styleFunctionSx(styles[styleKey], theme); css[styleKey] = transformedValue; } else { css = deepmerge(css, breakpointsValues); From 8b7ea1086773c02b32a3e3805a66e8010be1fb32 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:07:20 +0100 Subject: [PATCH 39/84] Update packages/material-ui/src/Box/styleFunction.js --- packages/material-ui/src/Box/styleFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/Box/styleFunction.js b/packages/material-ui/src/Box/styleFunction.js index 617b6f25d0099b..344b588ecd2e04 100644 --- a/packages/material-ui/src/Box/styleFunction.js +++ b/packages/material-ui/src/Box/styleFunction.js @@ -119,7 +119,7 @@ const styleFunction = (props) => { } }); - const sxValue = styleFunctionSx(props); + const sxValue = styleFunctionSx(props.sx, props.theme); return deepmerge(result, sxValue); }; From a34ae169f8ebddda4c3bd03b75090054899fa932 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:07:41 +0100 Subject: [PATCH 40/84] Update packages/material-ui/src/styles/experimentalStyled.js --- packages/material-ui/src/styles/experimentalStyled.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/styles/experimentalStyled.js b/packages/material-ui/src/styles/experimentalStyled.js index 9062ea1956fe03..579065381963c6 100644 --- a/packages/material-ui/src/styles/experimentalStyled.js +++ b/packages/material-ui/src/styles/experimentalStyled.js @@ -108,7 +108,7 @@ const experimentalStyled = (tag, options, muiOptions = {}) => { expressionsWithDefaultTheme.push((props) => { const theme = isEmpty(props.theme) ? defaultTheme : props.theme; - return styleFunctionSx({ ...props, theme }); + return styleFunctionSx(props.sx, theme); }); return defaultStyledResolver(transformedStyleArg, ...expressionsWithDefaultTheme); From 8c5823ad1ebd0ce53b73d7f155ded351077131c6 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 5 Nov 2020 20:16:13 +0100 Subject: [PATCH 41/84] one-liner --- .../system/basics/BreakpointsAsArray.tsx | 12 +++++------ .../system/basics/BreakpointsAsObject.tsx | 18 +++++------------ .../pages/system/basics/ValueAsFunction.tsx | 20 ++++++++++--------- docs/src/pages/system/basics/basics.md | 6 +++--- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/docs/src/pages/system/basics/BreakpointsAsArray.tsx b/docs/src/pages/system/basics/BreakpointsAsArray.tsx index 7682f576afb1f1..8f865378143014 100644 --- a/docs/src/pages/system/basics/BreakpointsAsArray.tsx +++ b/docs/src/pages/system/basics/BreakpointsAsArray.tsx @@ -3,12 +3,10 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsArray() { return ( - - This box has a responsive width. - +
+ + This box has a responsive width. + +
); } diff --git a/docs/src/pages/system/basics/BreakpointsAsObject.tsx b/docs/src/pages/system/basics/BreakpointsAsObject.tsx index 69a2c04d50d78e..4a1cafd9a5e226 100644 --- a/docs/src/pages/system/basics/BreakpointsAsObject.tsx +++ b/docs/src/pages/system/basics/BreakpointsAsObject.tsx @@ -3,18 +3,10 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsObject() { return ( - - This box has a responsive width. - +
+ + This box has a responsive width. + +
); } diff --git a/docs/src/pages/system/basics/ValueAsFunction.tsx b/docs/src/pages/system/basics/ValueAsFunction.tsx index c96bf8291464cf..7fc4d157fe3ad9 100644 --- a/docs/src/pages/system/basics/ValueAsFunction.tsx +++ b/docs/src/pages/system/basics/ValueAsFunction.tsx @@ -4,14 +4,16 @@ import { Theme } from '@material-ui/core/styles'; export default function ValueAsFunction() { return ( - theme.palette.primary.main, - }} - > - Border color with theme value. - +
+ theme.palette.primary.main, + }} + > + Border color with theme value. + +
); } diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index ef726c5c5e41e8..59c9967780900c 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -138,13 +138,13 @@ If you would like to have responsive values for a CSS property, you can use the The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. -{{"demo": "pages/system/basics/BreakpointsAsArray.js", "defaultCodeOpen": true}} +{{"demo": "pages/system/basics/BreakpointsAsArray.js"}} ### 2. Breakpoints as an object The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. -{{"demo": "pages/system/basics/BreakpointsAsObject.js", "defaultCodeOpen": true}} +{{"demo": "pages/system/basics/BreakpointsAsObject.js"}} ## Custom breakpoints @@ -205,7 +205,7 @@ declare module '@material-ui/core/styles/createBreakpoints' { If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. -{{"demo": "pages/system/basics/ValueAsFunction.js", "defaultCodeOpen": true}} +{{"demo": "pages/system/basics/ValueAsFunction.js"}} ## Prior art From d50a6afff18715e3c071c7e9243bbb2b7eb612c9 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 5 Nov 2020 20:30:44 +0100 Subject: [PATCH 42/84] update header --- docs/src/pages/system/basics/basics.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 59c9967780900c..4ed8f16da75018 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -1,6 +1,10 @@ -# @material-ui/system +# Material-UI System -

Styled system & style functions for building powerful design systems.

+

Utility-first style functions for rapidly building custom designs & systems.

+ +The system lets you quickly build custom UI components leverating the design tokens defined in your theme. + +## Demo {{"demo": "pages/system/basics/Demo.js"}} From 28eb893e8d31e2efd22160ece4edee401d63e640 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 20:43:28 +0100 Subject: [PATCH 43/84] formatted --- .../pages/system/basics/BreakpointsAsArray.js | 12 +++++------ .../system/basics/BreakpointsAsObject.js | 18 +++++------------ .../pages/system/basics/ValueAsFunction.js | 20 ++++++++++--------- docs/translations/translations.json | 1 + 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/src/pages/system/basics/BreakpointsAsArray.js b/docs/src/pages/system/basics/BreakpointsAsArray.js index 7682f576afb1f1..8f865378143014 100644 --- a/docs/src/pages/system/basics/BreakpointsAsArray.js +++ b/docs/src/pages/system/basics/BreakpointsAsArray.js @@ -3,12 +3,10 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsArray() { return ( - - This box has a responsive width. - +
+ + This box has a responsive width. + +
); } diff --git a/docs/src/pages/system/basics/BreakpointsAsObject.js b/docs/src/pages/system/basics/BreakpointsAsObject.js index 69a2c04d50d78e..4a1cafd9a5e226 100644 --- a/docs/src/pages/system/basics/BreakpointsAsObject.js +++ b/docs/src/pages/system/basics/BreakpointsAsObject.js @@ -3,18 +3,10 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsObject() { return ( - - This box has a responsive width. - +
+ + This box has a responsive width. + +
); } diff --git a/docs/src/pages/system/basics/ValueAsFunction.js b/docs/src/pages/system/basics/ValueAsFunction.js index 55ad8fed220d81..f90b0ba724593a 100644 --- a/docs/src/pages/system/basics/ValueAsFunction.js +++ b/docs/src/pages/system/basics/ValueAsFunction.js @@ -3,14 +3,16 @@ import Box from '@material-ui/core/Box'; export default function ValueAsFunction() { return ( - theme.palette.primary.main, - }} - > - Border color with theme value. - +
+ theme.palette.primary.main, + }} + > + Border color with theme value. + +
); } diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 2e9b713d681202..69761b1452de6e 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -222,6 +222,7 @@ "/system/spacing": "Spacing", "/system/screen-readers": "Screen Readers", "/system/typography": "Typography", + "/system/properties": "Properties", "/customization": "Customization", "/customization/theme": "Theme", "/customization/theming": "Theming", From b19875341110502b765ea5b56de07220dbaa8268 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 21:20:49 +0100 Subject: [PATCH 44/84] updated demo --- docs/public/static/images/system/demo.jpg | Bin 0 -> 108101 bytes docs/src/pages/system/basics/Demo.js | 201 ++++++---------------- docs/src/pages/system/basics/Demo.tsx | 151 ++++------------ docs/src/pages/system/basics/basics.md | 6 +- 4 files changed, 86 insertions(+), 272 deletions(-) create mode 100644 docs/public/static/images/system/demo.jpg diff --git a/docs/public/static/images/system/demo.jpg b/docs/public/static/images/system/demo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e6cb96a59aff64e494cdbf2666a0e5b5286c6fc0 GIT binary patch literal 108101 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

Kd4olqMCL+5fWVQ>pZHh*Y4b1=(0-< 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 { - const imgSize = [60, 90, 90, 120, 150]; - return ( - - - - ); +const Image = (props) => { + return ; }; -CardHeader.propTypes = { - color: PropTypes.oneOf([ - 'error', - 'info', - 'primary', - 'secondary', - 'success', - 'warning', - ]), - sx: PropTypes.object, +const Span = (props) => { + return ; }; -const CardContent = (props) => { +export default function Demo() { return ( - - - {props.header} - +

- {props.description} + + + 123 Main St, Pheonix AZ + + + $280.000 - $310.000 + + alpha(theme.palette.primary.light, 0.2), + borderRadius: '5px', + color: 'primary.main', + display: 'flex', + alignItems: 'center', + }} + > + + CONFIDENCE SCORE 85% + - - ); -}; - -CardContent.propTypes = { - color: PropTypes.oneOf([ - 'error', - 'info', - 'primary', - 'secondary', - 'success', - 'warning', - ]), - description: PropTypes.string, - header: PropTypes.string, - sx: PropTypes.object, -}; - -const Card = (props) => { - const { - color = 'primary', - profileImage, - header, - description, - sx, - ...rest - } = props; - return ( - - - - - ); -}; - -Card.propTypes = { - color: PropTypes.oneOf([ - 'error', - 'info', - 'primary', - 'secondary', - 'success', - 'warning', - ]), - description: PropTypes.string.isRequired, - header: PropTypes.string, - profileImage: PropTypes.string, - sx: PropTypes.object, -}; - -export default function Demo() { - return ( - +
); } diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 9dbcb06b48bc88..bcbb4188c028ef 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -1,144 +1,51 @@ import * as React from 'react'; -import Box, { SxProps } from '@material-ui/core/Box'; +import Box, { BoxProps } from '@material-ui/core/Box'; +import { alpha, Theme } from '@material-ui/core/styles'; +import ErrorIcon from '@material-ui/icons/Error'; -type Color = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; - -interface CardHeaderProps { - color?: Color; - sx?: SxProps; +interface ImageProps extends BoxProps { src?: string; alt?: string; } -const CardHeader: React.FC = (props) => { - const imgSize = [60, 90, 90, 120, 150]; - return ( - - - - ); -}; - -interface CardContentProps { - color?: Color; - header?: string; - description?: string; - sx?: SxProps; +const Image: React.FC = (props) => { + return } -const CardContent: React.FC = (props) => { - return ( - - - {props.header} - - - {props.description} - - - ); -}; - -interface CardProps { - color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; - header?: string; - description: string; - sx?: SxProps; - profileImage?: string; +const Span: React.FC = props => { + return } -const Card: React.FC = (props) => { - const { - color = 'primary', - profileImage, - header, - description, - sx, - ...rest - } = props; +export default function Demo() { return ( - + - - + + + 123 Main St, Pheonix AZ + + + $280.000 - $310.000 + + alpha(theme.palette.primary.light, 0.2), borderRadius: '5px', color: 'primary.main', display: 'flex', alignItems: 'center'}}> + + CONFIDENCE SCORE 85% + - ); -}; - -export default function Demo() { - return ( - +
); } diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 4ed8f16da75018..844a420c5bc498 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -86,7 +86,7 @@ We offer lots of shorthands on the CSS properties. Here are few examples: ### Superset of CSS -As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw css values etc. On the example above, we had several examples of this. +As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw css values etc. Here are few examples: ```jsx // Using pseudo selectors @@ -94,10 +94,10 @@ As the property is a superset of CSS, you can use child or pseudo selectors, med sx={{ // some styles ":hover": { - '& .CardHeader': { + '& .ChildSelector': { bgcolor: `${props.color}.dark`, }, - '& .CardContent-header': { + '& .OtherChildSelector': { color: `${props.color}.dark`, }, boxShadow: 6, From 6a8b944941464e316bcc73254b2de53ce61480a9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 23:21:28 +0100 Subject: [PATCH 45/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 4ed8f16da75018..46e1b7f2a720a9 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -207,7 +207,7 @@ declare module '@material-ui/core/styles/createBreakpoints' { ## Theme getter -If you wish to use the theme for a CSS property that is not supported by the system, you can use a function as the value, in which you can access the theme object. +If you wish to use the theme for a CSS property that is not supported natively by the system, you can use a function as the value, in which you can access the theme object. {{"demo": "pages/system/basics/ValueAsFunction.js"}} From 64b51ccf0765c3c3a96730df0625357025991abb Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 23:21:56 +0100 Subject: [PATCH 46/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 46e1b7f2a720a9..b43e19c793d24e 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -1,6 +1,6 @@ # Material-UI System -

Utility-first style functions for rapidly building custom designs & systems.

+

Utility-first style functions for rapidly building custom design systems.

The system lets you quickly build custom UI components leverating the design tokens defined in your theme. From 47af38007ccec79144a2efc3b915671129604f2c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 23:22:45 +0100 Subject: [PATCH 47/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index b43e19c793d24e..5d0a81f7857484 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -2,7 +2,7 @@

Utility-first style functions for rapidly building custom design systems.

-The system lets you quickly build custom UI components leverating the design tokens defined in your theme. +The system lets you quickly build custom UI components leveraging the design tokens defined in your theme. ## Demo From 18752f5b8d9183c4387c01fc23ea20571a59d687 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 5 Nov 2020 23:23:52 +0100 Subject: [PATCH 48/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 5d0a81f7857484..e82f5e3d50b69e 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -10,7 +10,7 @@ The system lets you quickly build custom UI components leveraging the design tok ## Why -There are several reasons for why you may need the system offered by Material-UI. Here are few of them: +There are several reasons why you may need the system offered by Material-UI. Here are few of them: ### 1. Building consistent UIs is hard From 541d0b7dea57d39cb4e10705510b1f975958e47f Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Fri, 6 Nov 2020 00:28:52 +0100 Subject: [PATCH 49/84] polish --- docs/src/pages/system/basics/Demo.js | 80 +++++++++++----------- docs/src/pages/system/basics/Demo.tsx | 91 ++++++++++++++++---------- docs/src/pages/system/basics/basics.md | 2 +- 3 files changed, 96 insertions(+), 77 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index 53630222fa7198..c29aff0711c436 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -3,67 +3,65 @@ import Box from '@material-ui/core/Box'; import { alpha } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Error'; -const Image = (props) => { - return ; -}; - -const Span = (props) => { - return ; -}; - export default function Demo() { return ( -
+ + - - + 123 Main St, Pheonix AZ - - - $280.000 - $310.000 - + + + $280,000 — $310,000 + alpha(theme.palette.primary.light, 0.2), + backgroundColor: (theme) => alpha(theme.palette.primary.main, 0.1), borderRadius: '5px', color: 'primary.main', + fontWeight: 'fontWeightMedium', display: 'flex', + fontSize: 12, alignItems: 'center', + '& svg': { + fontSize: 21, + mr: 0.5, + }, }} > - CONFIDENCE SCORE 85% + {'CONFIDENCE SCORE 85%'} -
+
); } + +function Img(props) { + return ; +} diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index bcbb4188c028ef..d8c20d2ccdfc49 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -1,51 +1,72 @@ import * as React from 'react'; import Box, { BoxProps } from '@material-ui/core/Box'; -import { alpha, Theme } from '@material-ui/core/styles'; +import { alpha } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Error'; -interface ImageProps extends BoxProps { - src?: string; - alt?: string; -} - -const Image: React.FC = (props) => { - return -} - -const Span: React.FC = props => { - return -} - export default function Demo() { return ( -
- - - - 123 Main St, Pheonix AZ - - - $280.000 - $310.000 - - alpha(theme.palette.primary.light, 0.2), borderRadius: '5px', color: 'primary.main', display: 'flex', alignItems: 'center'}}> - - CONFIDENCE SCORE 85% + + + + 123 Main St, Pheonix AZ + + + $280,000 — $310,000 + + alpha(theme.palette.primary.main, 0.1), + borderRadius: '5px', + color: 'primary.main', + fontWeight: 'fontWeightMedium', + display: 'flex', + fontSize: 12, + alignItems: 'center', + '& svg': { + fontSize: 21, + mr: 0.5, + }, + }} + > + + {'CONFIDENCE SCORE 85%'} + -
); } + +interface ImgProps extends BoxProps { + src?: string; + alt?: string; +} + +function Img(props: ImgProps) { + return ; +} diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 844a420c5bc498..31ee158432442b 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -6,7 +6,7 @@ The system lets you quickly build custom UI components leverating the design tok ## Demo -{{"demo": "pages/system/basics/Demo.js"}} +{{"demo": "pages/system/basics/Demo.js", "bg": true, "defaultCodeOpen": true}} ## Why From af31b6c2d125a6ed41ef9507bf3bb679eb930c56 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:51:57 +0100 Subject: [PATCH 50/84] Update docs/src/pages/system/basics/Demo.js --- docs/src/pages/system/basics/Demo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index c29aff0711c436..b8bbbdfca70e8a 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -19,7 +19,7 @@ export default function Demo() { > Date: Fri, 6 Nov 2020 10:53:25 +0100 Subject: [PATCH 51/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index cd8683cfd517db..77d18bbb69dce4 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -14,7 +14,7 @@ There are several reasons why you may need the system offered by Material-UI. He ### 1. Building consistent UIs is hard -This is especially true, when there is at least more than one person building the application. There has to be some synchronization to what are the design tokens and how are those used. What parts of the theme structure should be used with what CSS properties etc. +This is especially true when there is more than one person building the application. There has to be some synchronization as to what the design tokens are and how they are used, what parts of the theme structure should be used with what CSS properties, etc. ### 2. Switching context between JS and CSS From 57960857c89afe5a47d39e9bd2aa7d2493d0cf73 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:53:55 +0100 Subject: [PATCH 52/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 77d18bbb69dce4..91914dd71fc55e 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -18,7 +18,7 @@ This is especially true when there is more than one person building the applicat ### 2. Switching context between JS and CSS -Often we find ourselves jumping from the JS to the CSS files, or from the components definition to the instance usage in order to conclude where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this contraint. +Often we find ourselves jumping from the JS to CSS, or from a component definition to an instance in order to understand where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this constraint. ### 3. Less code to type From 34c430916c0316be0da141552e9922105a384cc5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:56:05 +0100 Subject: [PATCH 53/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 91914dd71fc55e..6c247236dbf408 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -132,7 +132,7 @@ TODO: For #23220 ### Core components -All core Material-UI components will suppor the `sx` prop. +All core Material-UI components will support the `sx` prop. ## Responsive values From 304116cf1673e7b0d3573bb427440482c5b6d108 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:56:49 +0100 Subject: [PATCH 54/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 6c247236dbf408..e8dc22132c2f88 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -68,7 +68,7 @@ You can explore the [System properties](/system/properties/) page to discover ho ### Many shorthands -We offer lots of shorthands on the CSS properties. Here are few examples: +There are lots of shorthands on the CSS properties. Here are few examples: ```jsx Date: Fri, 6 Nov 2020 10:57:09 +0100 Subject: [PATCH 55/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index e8dc22132c2f88..028f8655dd87e7 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -22,7 +22,7 @@ Often we find ourselves jumping from the JS to CSS, or from a component definiti ### 3. Less code to type -Usually when defining styles for a react component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch the context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. +Usually when defining styles for a React component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. ## How do we solve this? From 71575b8dbef0b10f9aba23d4ca715ff38b623d3d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:58:40 +0100 Subject: [PATCH 56/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 028f8655dd87e7..bda9b3eacbe157 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -60,7 +60,7 @@ const Div = styled('div')``; Note: -You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly add the same styles on a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. +You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly apply the same styles to a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. ### Design tokens in the theme From 584b289fd4cfc69aaf8627a36c9fb70733291d85 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:59:17 +0100 Subject: [PATCH 57/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index bda9b3eacbe157..146416f16f454d 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -50,7 +50,7 @@ yarn add @material-ui/system The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. -You can include this prop in your own components too by using the `experimentalStyled` utility from `@material-ui/core/styles` for creating your custom component. +You can include this prop in your own components too by using the `experimentalStyled` utility from `@material-ui/core/styles` for creating your custom components. ```jsx import { experimentalStyled as styled } from '@material-ui/core/styles'; From 602d1d75defd1973b426bc3060b0f7e4b59e8c7b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 10:59:39 +0100 Subject: [PATCH 58/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 146416f16f454d..db2506012fb8e1 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -26,7 +26,7 @@ Usually when defining styles for a React component we need to either define a se ## How do we solve this? -In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the react element where we want the styles to be applied, by a prop, that can be easily discoverable. +In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the React element where we want the styles to be applied with a prop that is easily discoverable. The `sx` prop, as part of the system is the solution we see for solving these problems. In the example above, you may see how it can be used on the MUI components. From 153a18d56dde45068d0520c34f45b70c453d31aa Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:00:07 +0100 Subject: [PATCH 59/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index db2506012fb8e1..7b99a946b4366a 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -28,7 +28,7 @@ Usually when defining styles for a React component we need to either define a se In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the React element where we want the styles to be applied with a prop that is easily discoverable. -The `sx` prop, as part of the system is the solution we see for solving these problems. In the example above, you may see how it can be used on the MUI components. +The `sx` prop, as part of the system, solves these problems. The example above shows how it can be used in MUI components. The property behaves as a superset of CSS that offers mapping values from the theme directly, by pulling specific values depending on the CSS property used. In addition to this, it allows a simple way of defining responsive values, that corresponds to the breakpoints values defined in the theme. From 6d66c8082e6d306604cb98e5b030f6787fb3094d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:00:29 +0100 Subject: [PATCH 60/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 7b99a946b4366a..bc56b0525b3b68 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -30,7 +30,7 @@ In order to solve these issues, we need to have a simple way of pulling & wiring The `sx` prop, as part of the system, solves these problems. The example above shows how it can be used in MUI components. -The property behaves as a superset of CSS that offers mapping values from the theme directly, by pulling specific values depending on the CSS property used. In addition to this, it allows a simple way of defining responsive values, that corresponds to the breakpoints values defined in the theme. +The prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system specifies. From 16a1c95bb3968d134b4800fb93df4c36b818dcda Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:02:27 +0100 Subject: [PATCH 61/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index bc56b0525b3b68..bea9902d16f167 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -34,7 +34,7 @@ The prop provides a superset of CSS that maps values directly from the theme, de With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system specifies. -In the next sections, we will dive deeper into all features of the `sx` prop. +In the following sections we will dive deeper into the features of the `sx` prop. ## Installation From 357f73e573d83a218e2dd7e18b1f3c06527bcf3d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:18:50 +0100 Subject: [PATCH 62/84] switching context demo --- docs/src/pages/system/basics/basics.md | 51 +++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index bea9902d16f167..c5fd8ca318b22f 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -16,10 +16,57 @@ There are several reasons why you may need the system offered by Material-UI. He This is especially true when there is more than one person building the application. There has to be some synchronization as to what the design tokens are and how they are used, what parts of the theme structure should be used with what CSS properties, etc. -### 2. Switching context between JS and CSS +### 2. Switching context Often we find ourselves jumping from the JS to CSS, or from a component definition to an instance in order to understand where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this constraint. +```diff +import * as React from 'react'; +-import styled from 'styled-components'; ++import Box from '@material-ui/core/Box'; + +-const Card = styled('div)({ +- width: '200px', +- height: '200px', +- boxShadow: theme => theme.shadows[3], +-}); +- +-const Header = styled('h4')({ +- color: 'grey', +-}); +- +-const Content = styled('p')({ +- fontSize: '14px;, +- marginTop: '10px', +-}); + +export default function Demo() { +- return ( ++ return ( theme.shadows[3], ++ }} ++ > +-
++ + 123 Main St, Pheonix AZ +-
++
+- ++ + $280,000 — $310,000 +- ++
+- ); ++
); +} +``` + ### 3. Less code to type Usually when defining styles for a React component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. @@ -86,7 +133,7 @@ There are lots of shorthands on the CSS properties. Here are few examples: ### Superset of CSS -As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw css values etc. Here are few examples: +As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: ```jsx // Using pseudo selectors From b824976f7f46957054606b2b71ea6d0bc3289a91 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:21:53 +0100 Subject: [PATCH 63/84] fixed duplicated section --- docs/src/pages/system/basics/basics.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index c5fd8ca318b22f..b53c6962c3973f 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -95,10 +95,7 @@ yarn add @material-ui/system ## The `sx` prop -The `sx` prop is a superset of CSS, that let's you add any CSS to the underlaying component, while mapping values to different theme keys. This should help you to keep your application look consistent. The prop is available in all `@material-ui/core` components. - -You can include this prop in your own components too by using the `experimentalStyled` utility from `@material-ui/core/styles` for creating your custom components. - +We mentioned that you can use the `sx` prop on all MUI components. In addition to this, you may add the prop on your custom components too by using the `experimentalStyled` utility from `@material-ui/core/styles`. ```jsx import { experimentalStyled as styled } from '@material-ui/core/styles'; From 6a4630b4a4e29241a0bde6e00d84215e950328df Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 6 Nov 2020 11:40:34 +0100 Subject: [PATCH 64/84] prettier & formatted --- docs/src/pages/system/basics/Demo.tsx | 4 ++-- docs/src/pages/system/basics/basics.md | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index d8c20d2ccdfc49..887a28a16ea980 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -19,14 +19,14 @@ export default function Demo() { > + 123 Main St, Pheonix AZ -- +- + - + Date: Sat, 7 Nov 2020 00:31:40 +0100 Subject: [PATCH 65/84] improve-why --- docs/src/pages/system/basics/Demo.js | 8 +- docs/src/pages/system/basics/Demo.tsx | 8 +- docs/src/pages/system/basics/Why.js | 22 ++++ docs/src/pages/system/basics/Why.tsx | 22 ++++ docs/src/pages/system/basics/basics.md | 157 ++++++++++++++++--------- 5 files changed, 154 insertions(+), 63 deletions(-) create mode 100644 docs/src/pages/system/basics/Why.js create mode 100644 docs/src/pages/system/basics/Why.tsx diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index b8bbbdfca70e8a..05ef283bc87dd8 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; import { alpha } from '@material-ui/core/styles'; -import ErrorIcon from '@material-ui/icons/Error'; +import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; export default function Demo() { return ( @@ -32,10 +32,10 @@ export default function Demo() { }} > - 123 Main St, Pheonix AZ + {'123 Main St, Pheonix AZ'} - $280,000 — $310,000 + {'$280,000 — $310,000'} - + {'CONFIDENCE SCORE 85%'} diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 887a28a16ea980..a5697663c59ad4 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Box, { BoxProps } from '@material-ui/core/Box'; import { alpha } from '@material-ui/core/styles'; -import ErrorIcon from '@material-ui/icons/Error'; +import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; export default function Demo() { return ( @@ -32,10 +32,10 @@ export default function Demo() { }} > - 123 Main St, Pheonix AZ + {'123 Main St, Pheonix AZ'} - $280,000 — $310,000 + {'$280,000 — $310,000'} - + {'CONFIDENCE SCORE 85%'} diff --git a/docs/src/pages/system/basics/Why.js b/docs/src/pages/system/basics/Why.js new file mode 100644 index 00000000000000..385ef002a11b99 --- /dev/null +++ b/docs/src/pages/system/basics/Why.js @@ -0,0 +1,22 @@ +import * as React from 'react'; +import TrendingUpIcon from '@material-ui/icons/TrendingUp'; +import Box from '@material-ui/core/Box'; + +export default function Why() { + return ( + /* prettier-ignore */ + + Sessions + + {'98.3 K'} + + + + {'18.77%'} + + + {'vs last week'} + + + ); +} diff --git a/docs/src/pages/system/basics/Why.tsx b/docs/src/pages/system/basics/Why.tsx new file mode 100644 index 00000000000000..385ef002a11b99 --- /dev/null +++ b/docs/src/pages/system/basics/Why.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import TrendingUpIcon from '@material-ui/icons/TrendingUp'; +import Box from '@material-ui/core/Box'; + +export default function Why() { + return ( + /* prettier-ignore */ + + Sessions + + {'98.3 K'} + + + + {'18.77%'} + + + {'vs last week'} + + + ); +} diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index d34e3e6bf747b7..d36c04e667b8f1 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -2,74 +2,121 @@

Utility-first style functions for rapidly building custom design systems.

-The system lets you quickly build custom UI components leveraging the design tokens defined in your theme. +Material-UI comes with dozens or **ready-to-use** components in the core. +These components are an incredible starting point but when it comes to make your site stand out with a custom design, they can be challenging to customize. Introducing the system: -## Demo +The **system** lets you quickly build custom UI components leveraging the design tokens defined in your theme. + +## The demo + +_(Resize the window to see the responsive breakpoints)_ {{"demo": "pages/system/basics/Demo.js", "bg": true, "defaultCodeOpen": true}} -## Why +## Why utility-first? -There are several reasons why you may need the system offered by Material-UI. Here are few of them: +Compare how the same stat component can be built with two different APIs. -### 1. Building consistent UIs is hard +{{"demo": "pages/system/basics/Why.js", "bg": true, "defaultCodeOpen": false}} -This is especially true when there is more than one person building the application. There has to be some synchronization as to what the design tokens are and how they are used, what parts of the theme structure should be used with what CSS properties, etc. +- ❌ using the standard styled-components API: -### 2. Switching context +```jsx +const StatWrapper = styled('div')( + ({ theme }) => ` + background-color: ${theme.palette.background.paper}; + box-shadow: ${theme.shadows[1]}; + border-radius: ${theme.shape.borderRadius}px; + padding: ${theme.spacing(2)}; + min-width: 300px; +`, +); + +const StatHeader = styled('div')( + ({ theme }) => ` + color: ${theme.palette.text.secondary}; +`, +); + +const StyledTrend = styled(TrendingUpIcon)( + ({ theme }) => ` + color: ${theme.palette.success.dark}; + font-size: 16px; + vertical-alignment: sub; +`, +); + +const StatValue = styled('div')( + ({ theme }) => ` + color: ${theme.palette.text.primary}; + font-size: 34px; + font-weight: ${theme.typography.fontWeightMedium}; +`, +); + +const StatDiff = styled('div')( + ({ theme }) => ` + color: ${theme.palette.success.dark}; + display: inline; + font-weight: ${theme.typography.fontWeightMedium}; + margin-left: ${theme.spacing(0.5)}; + margin-right: ${theme.spacing(0.5)}; +`, +); + +const StatPrevious = styled('div')( + ({ theme }) => ` + color: ${theme.palette.text.secondary}; + display: inline; + font-size: 12px; +`, +); + +return ( + + Sessions + {'98.3 K'} + + {'18.77%'} + {'vs last week'} + +); +``` -Often we find ourselves jumping from the JS to CSS, or from a component definition to an instance in order to understand where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this constraint. +- ✅ using the system: -```diff -import * as React from 'react'; --import styled from 'styled-components'; -+import Box from '@material-ui/core/Box'; - --const Card = styled('div)({ -- width: '200px', -- height: '200px', -- boxShadow: theme => theme.shadows[3], --}); -- --const Header = styled('h4')({ -- color: 'grey', --}); -- --const Content = styled('p')({ -- fontSize: '14px;, -- marginTop: '10px', --}); - -export default function Demo() { -- return ( -+ return ( theme.shadows[3], -+ }} -+ > --
-+ - 123 Main St, Pheonix AZ --
-+
-- -+ - $280,000 — $310,000 -- -+
-- ); -+
); -} +```jsx +/* prettier-ignore */ + + Sessions + + {'98.3 K'} + + + + {'18.77%'} + + + {'vs last week'} + + ``` -### 3. Less code to type +The system solves 3 problems: + +**1. Switching context wastes time.** + +There's no need to constantly jump between the usage of the styled components and where they are defined. With the system, those descriptions are right where you need them. + +**2. Naming things is hard.** + +Have you ever found yourself struggling to find a good name for a styled component? +The system maps the styles directly to the element. +All you have to do is worry about actual style properties. + +**3. Building consistent UIs is hard.** -Usually when defining styles for a React component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. +This is especially true when more than one person is building the application, as there has to be some coordination amongst members of the team regarding choice of design tokens and how they are used, what parts of the theme structure should be used with what CSS properties, and so on. ## How do we solve this? From 9187099350bae1ad604d68dd88d5a28f1ae6e93b Mon Sep 17 00:00:00 2001 From: Matt Brookes Date: Sat, 7 Nov 2020 01:19:53 +0100 Subject: [PATCH 66/84] review --- docs/src/pages.js | 16 ++++++------- docs/src/pages/system/basics/Demo.js | 2 +- docs/src/pages/system/basics/Demo.tsx | 2 +- docs/src/pages/system/basics/basics.md | 32 ++++++++++++++------------ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/docs/src/pages.js b/docs/src/pages.js index 663088aa77f74d..3d09095bc26f67 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -163,14 +163,6 @@ const pages = [ a.pathname.replace('/api-docs/', '').localeCompare(b.pathname.replace('/api-docs/', '')), ), }, - { - pathname: '/styles', - children: [ - { pathname: '/styles/basics' }, - { pathname: '/styles/advanced' }, - { pathname: '/styles/api', title: 'API' }, - ], - }, { pathname: '/system', children: [ @@ -188,6 +180,14 @@ const pages = [ { pathname: '/system/properties' }, ], }, + { + pathname: '/styles', + children: [ + { pathname: '/styles/basics' }, + { pathname: '/styles/advanced' }, + { pathname: '/styles/api', title: 'API' }, + ], + }, { pathname: '/customization', children: [ diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index 05ef283bc87dd8..a5a1bc2fd1ee8a 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -32,7 +32,7 @@ export default function Demo() { }} > - {'123 Main St, Pheonix AZ'} + {'123 Main St, Phoenix AZ'} {'$280,000 — $310,000'} diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index a5697663c59ad4..d6c63bcf85720b 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -32,7 +32,7 @@ export default function Demo() { }} > - {'123 Main St, Pheonix AZ'} + {'123 Main St, Phoenix AZ'} {'$280,000 — $310,000'} diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index d36c04e667b8f1..e563fcaccd947f 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -158,27 +158,29 @@ You should use this prop whenever you need to add a style override to a Material You can explore the [System properties](/system/properties/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. -### Many shorthands +### Shorthands -There are lots of shorthands on the CSS properties. Here are few examples: +There are lots of shorthands available for the CSS properties. Here are few examples: ```jsx - + ``` +These are documented in the following sections. + ### Superset of CSS -As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: +As the prop supports a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: ```jsx // Using pseudo selectors @@ -280,7 +282,7 @@ export default function CustomBreakpoints() { } ``` -If you are using TypeScript, you would also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. +If you are using TypeScript, you will also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. ```ts declare module '@material-ui/core/styles/createBreakpoints' { From 90ba086aca9a04166b95b8438833a47411e830ef Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 01:36:03 +0100 Subject: [PATCH 67/84] improve last argument wording --- docs/src/pages/system/basics/basics.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index e563fcaccd947f..521dd7df3fe33b 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -114,10 +114,12 @@ Have you ever found yourself struggling to find a good name for a styled compone The system maps the styles directly to the element. All you have to do is worry about actual style properties. -**3. Building consistent UIs is hard.** +**3. Enforcing consistency in UIs is hard.** This is especially true when more than one person is building the application, as there has to be some coordination amongst members of the team regarding choice of design tokens and how they are used, what parts of the theme structure should be used with what CSS properties, and so on. +The system provide direct access to the value in the theme. It makes it easier to design with constraints. + ## How do we solve this? In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the React element where we want the styles to be applied with a prop that is easily discoverable. From 0b0670c37ef9a03a12b5fdd0a97db3c5dffed88e Mon Sep 17 00:00:00 2001 From: Matt Brookes Date: Sat, 7 Nov 2020 01:46:11 +0100 Subject: [PATCH 68/84] review --- docs/src/pages/system/basics/basics.md | 104 ++++++++++++------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 521dd7df3fe33b..e592295b0ebbbc 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -7,12 +7,22 @@ These components are an incredible starting point but when it comes to make your The **system** lets you quickly build custom UI components leveraging the design tokens defined in your theme. -## The demo +## Demo _(Resize the window to see the responsive breakpoints)_ {{"demo": "pages/system/basics/Demo.js", "bg": true, "defaultCodeOpen": true}} +## Installation + +```jsx +// with npm +npm install @material-ui/system + +// with yarn +yarn add @material-ui/system +``` + ## Why utility-first? Compare how the same stat component can be built with two different APIs. @@ -102,7 +112,7 @@ return ( ``` -The system solves 3 problems: +The system focus on solving 3 main problems: **1. Switching context wastes time.** @@ -120,41 +130,15 @@ This is especially true when more than one person is building the application, a The system provide direct access to the value in the theme. It makes it easier to design with constraints. -## How do we solve this? - -In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the React element where we want the styles to be applied with a prop that is easily discoverable. - -The `sx` prop, as part of the system, solves these problems. The example above shows how it can be used in MUI components. - -The prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. - -With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system specifies. - -In the following sections we will dive deeper into the features of the `sx` prop. - -## Installation - -```jsx -// with npm -npm install @material-ui/system - -// with yarn -yarn add @material-ui/system -``` - ## The `sx` prop -We mentioned that you can use the `sx` prop on all MUI components. In addition to this, you may add the prop on your custom components too by using the `experimentalStyled` utility from `@material-ui/core/styles`. +The sx prop, as part of the system, solves these problems by providing a simple way of applying the correct design tokens for specific CSS properties directly to a React element. The [demo above](#demo) shows how it can be used in Material-UI components. -```jsx -import { experimentalStyled as styled } from '@material-ui/core/styles'; - -const Div = styled('div')``; -``` +This prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. -Note: +With it you can easily build your custom visual components, such as card, badge, chip, exactly as your design system specifies. In the sections following this one, we will dive deeper into the features of the sx prop. -You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly apply the same styles to a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. +## Usage ### Design tokens in the theme @@ -214,39 +198,23 @@ As the prop supports a superset of CSS, you can use child or pseudo selectors, m > ``` -## Usage - -It can be used from 3 different sources: - -### Box - -The `Box` component is a light component that gives you access to this functionality. - -### Babel plugin - -TODO: For #23220 - -### Core components - -All core Material-UI components will support the `sx` prop. - -## Responsive values +### Responsive values If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: -### 1. Breakpoints as an array +#### 1. Breakpoints as an array The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. {{"demo": "pages/system/basics/BreakpointsAsArray.js"}} -### 2. Breakpoints as an object +#### 2. Breakpoints as an object The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. {{"demo": "pages/system/basics/BreakpointsAsObject.js"}} -## Custom breakpoints +### Custom breakpoints You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that. @@ -301,12 +269,42 @@ declare module '@material-ui/core/styles/createBreakpoints' { } ``` -## Theme getter +### Theme getter If you wish to use the theme for a CSS property that is not supported natively by the system, you can use a function as the value, in which you can access the theme object. {{"demo": "pages/system/basics/ValueAsFunction.js"}} +## Implementations + +The `sx` prop can be used in four different locations: + +### 1. Core components + +All core Material-UI components will support the `sx` prop. + +### 2. Box + +[`Box`](/components/box/) is a lightweight component that gives access to the `sx` prop, and can be used as a utility component, and as a wrapper for other components. + +### 3. Custom components + +In addition to Material-UI components, you can add the `sx` prop to your custom components too, by using the `experimentalStyled` utility from `@material-ui/core/styles`. + +```jsx +import { experimentalStyled as styled } from '@material-ui/core/styles'; + +const Div = styled('div')``; +``` + +> **Note:** +> +> You should use this prop whenever you need to add or override a component style. If you find you are repeatedly applying the same styles to a component, then `styled()` may be a better option, as it allows you to specify the styles only once, and reuse them in all component instances. See [Customizing components](/customization/components/) for all the alternatives. + +### 4. Babel plugin + +TODO [#23220](https://github.com/mui-org/material-ui/issues/23220). + ## Prior art `@material-ui/system` synthesizes ideas & APIs from several different sources: From 40fe4a7799ab10d8ca57a2f7f4bdd7f25b232a25 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 01:53:14 +0100 Subject: [PATCH 69/84] polish --- docs/src/pages/system/basics/Demo.js | 2 +- docs/src/pages/system/basics/Demo.tsx | 2 +- docs/src/pages/system/basics/basics.md | 41 ++++++++++++++++---------- docs/translations/translations.json | 6 ++-- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index a5a1bc2fd1ee8a..fa481ec16dca99 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -20,7 +20,7 @@ export default function Demo() { The house from the offer. ``` -These are documented in the following sections. +These are documented in the following sections, for instance, [the spacing](/system/spacing/). ### Superset of CSS As the prop supports a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: -```jsx - // Using pseudo selectors +- Using pseudo selectors: + + ```jsx -``` + ``` -```jsx - // Using media queries +- Using media queries: + + ```jsx -``` + ``` + +- Using nested selector: + + ```jsx + + ``` ### Responsive values @@ -301,7 +310,7 @@ const Div = styled('div')``; > > You should use this prop whenever you need to add or override a component style. If you find you are repeatedly applying the same styles to a component, then `styled()` may be a better option, as it allows you to specify the styles only once, and reuse them in all component instances. See [Customizing components](/customization/components/) for all the alternatives. -### 4. Babel plugin +### 4. Any element with the babel plugin TODO [#23220](https://github.com/mui-org/material-ui/issues/23220). diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 69761b1452de6e..87f8f223de547b 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -207,9 +207,6 @@ "/components/trap-focus": "Trap Focus", "/components/tree-view": "Tree View", "/api-docs": "Component API", - "/styles": "Styles", - "/styles/basics": "Basics", - "/styles/advanced": "Advanced", "/system": "System", "/system/basics": "Basics", "/system/borders": "Borders", @@ -223,6 +220,9 @@ "/system/screen-readers": "Screen Readers", "/system/typography": "Typography", "/system/properties": "Properties", + "/styles": "Styles", + "/styles/basics": "Basics", + "/styles/advanced": "Advanced", "/customization": "Customization", "/customization/theme": "Theme", "/customization/theming": "Theming", From cffb670b5c29fd02a81b3329b8b0013c83f5bf7d Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 13:40:13 +0100 Subject: [PATCH 70/84] more polish --- docs/src/pages/system/basics/basics.md | 48 +++++++++++--------------- test/regressions/index.js | 3 ++ 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index fbb7e3db9f5137..f248294b67243e 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -1,6 +1,6 @@ # Material-UI System -

Utility-first style functions for rapidly building custom design systems.

+

Utility style functions for rapidly building custom design systems.

Material-UI comes with dozens or **ready-to-use** components in the core. These components are an incredible starting point but when it comes to make your site stand out with a custom design, they can be challenging to customize. Introducing the system: @@ -23,13 +23,13 @@ npm install @material-ui/system yarn add @material-ui/system ``` -## Why utility-first? +## Why utility? Compare how the same stat component can be built with two different APIs. {{"demo": "pages/system/basics/Why.js", "bg": true, "defaultCodeOpen": false}} -- ❌ using the standard styled-components API: +1. ❌ using the styled-components's API: ```jsx const StatWrapper = styled('div')( @@ -93,7 +93,7 @@ return ( ); ``` -- ✅ using the system: +2. ✅ using the system: ```jsx /* prettier-ignore */ @@ -112,6 +112,8 @@ return (
``` +### Problem solved + The system focus on solving 3 main problems: **1. Switching context wastes time.** @@ -126,17 +128,21 @@ All you have to do is worry about actual style properties. **3. Enforcing consistency in UIs is hard.** -This is especially true when more than one person is building the application, as there has to be some coordination amongst members of the team regarding choice of design tokens and how they are used, what parts of the theme structure should be used with what CSS properties, and so on. +This is especially true when more than one person is building the application, as there has to be some coordination amongst members of the team regarding the choice of design tokens and how they are used, what parts of the theme structure should be used with what CSS properties, and so on. -The system provide direct access to the value in the theme. It makes it easier to design with constraints. +The system provides direct access to the value in the theme. It makes it easier to design with constraints. ## The `sx` prop -The `sx` prop, as part of the system, solves these problems by providing a simple way of applying the correct design tokens for specific CSS properties directly to a React element. The [demo above](#demo) shows how it can be used in Material-UI components. +The `sx` prop, as the main part of the system, solves these problems by providing a fast & simple way of applying the correct design tokens for specific CSS properties directly to a React element. The [demo above](#demo) shows how it can be used to create a one-off design. + +This prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. Also, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. + +### When to use it? -This prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. +The styled-components's API is great to build low-level components that need to support a wide variety of contexts. -With it you can easily build your custom visual components, such as card, badge, chip, exactly as your design system specifies. In the sections following this one, we will dive deeper into the features of the sx prop. +The `sx` prop is great anytime one-off styles need to be applied. It's called "utility" for this reason. ## Usage @@ -146,7 +152,9 @@ You can explore the [System properties](/system/properties/) page to discover ho ### Shorthands -There are lots of shorthands available for the CSS properties. Here are few examples: +There are lots of shorthands available for the CSS properties. +These are documented in the next pages, for instance, [the spacing](/system/spacing/). +Here are an example leveraging them: ```jsx ``` -These are documented in the following sections, for instance, [the spacing](/system/spacing/). +These shorthands are **optional**, they are great to save time when writing styles but it can be overwhelming to learn new custom APIs. +You might want to skip this part and bet on CSS, it has been standardized for decades, head to the next section. ### Superset of CSS -As the prop supports a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: +As the prop supports a superset of CSS, you can use child or pseudo-selectors, media queries, raw CSS values, etc. Here are a few examples: - Using pseudo selectors: @@ -313,18 +322,3 @@ const Div = styled('div')``; ### 4. Any element with the babel plugin TODO [#23220](https://github.com/mui-org/material-ui/issues/23220). - -## Prior art - -`@material-ui/system` synthesizes ideas & APIs from several different sources: - -- [Tachyons](https://tachyons.io/) was one of the first (2014) CSS libraries to promote the [Atomic CSS pattern](https://css-tricks.com/lets-define-exactly-atomic-css/) (or Functional CSS). -- Tachyons was later on (2017) followed by [Tailwind CSS](https://tailwindcss.com/). They have made Atomic CSS more popular. -- [Twitter Bootstrap](https://getbootstrap.com/docs/4.1/utilities/borders/) has slowly introduced atomic class names in v2, v3, and v4. The way they group their "Helper classes" was used as inspiration. -- In the React world, [Styled System](https://github.com/jxnblk/styled-system) was one of the first (2017) to promote the style functions. - It can be used as a generic Box component replacing the atomic CSS helpers as well as helpers to write new components. -- Large companies such as Pinterest, GitHub, and Segment.io are using the same approach in different flavours: - - [Evergreen Box](https://evergreen.segment.com/components/layout-primitives/) - - [Gestalt Box](https://pinterest.github.io/gestalt/#/Box) - - [Primer Box](https://primer.style/components/docs/Box) -- The actual implementation and the object responsive API was inspired by the [Smooth-UI's system](https://smooth-ui.smooth-code.com/docs-basics-system). diff --git a/test/regressions/index.js b/test/regressions/index.js index b742dc2c4b3863..de5b6802412fb0 100644 --- a/test/regressions/index.js +++ b/test/regressions/index.js @@ -131,6 +131,9 @@ const blacklist = [ 'docs-production-error', // No components, page for DX 'docs-styles-advanced', // Redudant 'docs-styles-basics/StressTest.png', // Need interaction + 'docs-system-basics/BreakpointsAsArray.png', // Unit tests are enough + 'docs-system-basics/BreakpointsAsObject.png', // Unit tests are enough + 'docs-system-basics/ValueAsFunction.png', // Unit tests are enough 'docs-system-borders', // Unit tests are enough 'docs-system-display', // Unit tests are enough 'docs-system-flexbox', // Unit tests are enough From 725c552747493a863f463c1c0efec412aef70f11 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 13:49:49 +0100 Subject: [PATCH 71/84] prefer the object by default over array --- .../pages/system/basics/BreakpointsAsArray.js | 2 +- .../system/basics/BreakpointsAsArray.tsx | 2 +- docs/src/pages/system/basics/basics.md | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/src/pages/system/basics/BreakpointsAsArray.js b/docs/src/pages/system/basics/BreakpointsAsArray.js index 8f865378143014..9b70c98d831234 100644 --- a/docs/src/pages/system/basics/BreakpointsAsArray.js +++ b/docs/src/pages/system/basics/BreakpointsAsArray.js @@ -4,7 +4,7 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsArray() { return (
- + This box has a responsive width.
diff --git a/docs/src/pages/system/basics/BreakpointsAsArray.tsx b/docs/src/pages/system/basics/BreakpointsAsArray.tsx index 8f865378143014..9b70c98d831234 100644 --- a/docs/src/pages/system/basics/BreakpointsAsArray.tsx +++ b/docs/src/pages/system/basics/BreakpointsAsArray.tsx @@ -4,7 +4,7 @@ import Box from '@material-ui/core/Box'; export default function BreakpointsAsArray() { return (
- + This box has a responsive width.
diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index f248294b67243e..6f09cb65d8fb13 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -220,17 +220,26 @@ As the prop supports a superset of CSS, you can use child or pseudo-selectors, m If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: -#### 1. Breakpoints as an array +#### 1. Breakpoints as an object -The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. +The first option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. + +{{"demo": "pages/system/basics/BreakpointsAsObject.js"}} + +#### 2. Breakpoints as an array + +The second option is to define your breakpoints as an array, from the smallest to the largest breakpoint. {{"demo": "pages/system/basics/BreakpointsAsArray.js"}} -#### 2. Breakpoints as an object +> ⚠️ This option is only recommended when the theme has a limited number of breakpoints, e.g. 3.
+> Prefer the object API if you have more breakpoints. For instance, the default theme of Material-UI has 5. -The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. +You can skip breakpoints with the `null` value: -{{"demo": "pages/system/basics/BreakpointsAsObject.js"}} +```jsx +This box has a responsive width. +``` ### Custom breakpoints From c0f226947eb8f31ece152b73accdc12989467da9 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 14:13:12 +0100 Subject: [PATCH 72/84] marked token are wrong, we could consider using reactjs.org approach in the future --- docs/src/pages/system/basics/Demo.js | 6 +++--- docs/src/pages/system/basics/Demo.tsx | 6 +++--- docs/src/pages/system/basics/Why.js | 10 ++++++---- docs/src/pages/system/basics/Why.tsx | 10 ++++++---- docs/src/pages/system/basics/basics.md | 16 +++++++++------- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index fa481ec16dca99..917e3db8ec1025 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -32,10 +32,10 @@ export default function Demo() { }} > - {'123 Main St, Phoenix AZ'} + 123 Main St, Phoenix AZ - {'$280,000 — $310,000'} + $280,000 — $310,000 - {'CONFIDENCE SCORE 85%'} + CONFIDENCE SCORE 85%
diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 0f85cddd123b62..797c853c4e5406 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -32,10 +32,10 @@ export default function Demo() { }} > - {'123 Main St, Phoenix AZ'} + 123 Main St, Phoenix AZ - {'$280,000 — $310,000'} + $280,000 — $310,000 - {'CONFIDENCE SCORE 85%'} + CONFIDENCE SCORE 85%
diff --git a/docs/src/pages/system/basics/Why.js b/docs/src/pages/system/basics/Why.js index 385ef002a11b99..84806e91bde6ad 100644 --- a/docs/src/pages/system/basics/Why.js +++ b/docs/src/pages/system/basics/Why.js @@ -6,16 +6,18 @@ export default function Why() { return ( /* prettier-ignore */ - Sessions + + Sessions + - {'98.3 K'} + 98.3 K - {'18.77%'} + 18.77% - {'vs last week'} + vs last week ); diff --git a/docs/src/pages/system/basics/Why.tsx b/docs/src/pages/system/basics/Why.tsx index 385ef002a11b99..84806e91bde6ad 100644 --- a/docs/src/pages/system/basics/Why.tsx +++ b/docs/src/pages/system/basics/Why.tsx @@ -6,16 +6,18 @@ export default function Why() { return ( /* prettier-ignore */ - Sessions + + Sessions + - {'98.3 K'} + 98.3 K - {'18.77%'} + 18.77% - {'vs last week'} + vs last week ); diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 6f09cb65d8fb13..7c21300d257b82 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -85,10 +85,10 @@ const StatPrevious = styled('div')( return ( Sessions - {'98.3 K'} + 98.3 K - {'18.77%'} - {'vs last week'} + 18.77% + vs last week ); ``` @@ -98,16 +98,18 @@ return ( ```jsx /* prettier-ignore */ - Sessions + + Sessions + - {'98.3 K'} + 98.3 K - {'18.77%'} + 18.77% - {'vs last week'} + vs last week ``` From 5514a6b74b21aa77200dab19cb69dd0a6fc36f0b Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 7 Nov 2020 16:09:36 +0100 Subject: [PATCH 73/84] add a note about performance --- benchmark/browser/README.md | 180 +++--------------- benchmark/browser/index.js | 18 +- .../basic-styled-components/index.js | 27 --- .../browser/scenarios/box-chakra-ui/index.js | 27 ++- .../browser/scenarios/box-emotion/index.js | 26 --- .../scenarios/box-material-ui-styles/index.js | 27 ++- .../scenarios/box-styled-components/index.js | 27 --- .../browser/scenarios/components/index.js | 15 ++ .../browser/scenarios/make-styles/index.js | 34 ++++ .../browser/scenarios/primitives/index.js | 11 ++ .../browser/scenarios/styled-emotion/index.js | 31 +++ .../scenarios/styled-material-ui/index.js | 28 +++ .../browser/scenarios/styled-sc/index.js | 33 ++++ .../sx-prop-box-material-ui/index.js | 8 +- .../scenarios/sx-prop-box-theme-ui/index.js | 2 +- .../scenarios/sx-prop-div-theme-ui/index.js | 2 +- benchmark/browser/scripts/benchmark.js | 50 +++-- docs/src/pages/system/basics/basics.md | 30 ++- 18 files changed, 278 insertions(+), 298 deletions(-) delete mode 100644 benchmark/browser/scenarios/basic-styled-components/index.js delete mode 100644 benchmark/browser/scenarios/box-emotion/index.js delete mode 100644 benchmark/browser/scenarios/box-styled-components/index.js create mode 100644 benchmark/browser/scenarios/components/index.js create mode 100644 benchmark/browser/scenarios/make-styles/index.js create mode 100644 benchmark/browser/scenarios/primitives/index.js create mode 100644 benchmark/browser/scenarios/styled-emotion/index.js create mode 100644 benchmark/browser/scenarios/styled-material-ui/index.js create mode 100644 benchmark/browser/scenarios/styled-sc/index.js diff --git a/benchmark/browser/README.md b/benchmark/browser/README.md index 97b3e69eccdf33..9b73c532d8a380 100644 --- a/benchmark/browser/README.md +++ b/benchmark/browser/README.md @@ -16,163 +16,45 @@ You should use these numbers exclusively for comparing performance between diffe yarn benchmark:browser noop (baseline): - -20.10ms -20.05ms -19.28ms -19.64ms -20.96ms -18.80ms -18.39ms -20.38ms -18.85ms -18.99ms +mean: 4.70ms, median: 4.72ms ------------- -Avg: 19.55ms -Median: 19.46ms - -styled-components Box + @material-ui/system: - -184.17ms -161.51ms -168.84ms -165.21ms -163.43ms -158.10ms -158.81ms -297.91ms -161.25ms -158.87ms +React primitives: +mean: 68.89ms, median: 64.02ms ------------- -Avg: 177.81ms -Median: 162.47ms - -styled-components Box + styled-system: - -142.66ms -146.55ms -141.12ms -141.04ms -139.45ms -145.63ms -141.36ms -134.98ms -123.98ms -146.09ms +React components: +mean: 74.38ms, median: 74.46ms ------------- -Avg: 140.29ms -Median: 141.24ms - -Box emotion: - -143.21ms -135.28ms -122.53ms -124.80ms -143.69ms -147.81ms -138.16ms -124.55ms -140.32ms -157.74ms +Styled Material-UI: +mean: 109.73ms, median: 109.46ms ------------- -Avg: 137.81ms -Median: 139.24ms - -Box @material-ui/styles: - -146.16ms -131.37ms -139.43ms -158.55ms -149.54ms -131.81ms -134.84ms -151.08ms -152.30ms -130.69ms +Styled emotion: +mean: 102.59ms, median: 104.28ms ------------- -Avg: 142.58ms -Median: 142.79ms - -Box styled-components: - -145.59ms -150.12ms -179.04ms -169.63ms -148.21ms -155.55ms -182.55ms -170.04ms -153.14ms -148.92ms +Styled SC: +mean: 104.06ms, median: 102.67ms ------------- -Avg: 160.28ms -Median: 154.35ms - -Basic styled-components box: - -141.73ms -139.71ms -121.01ms -120.02ms -121.81ms -143.22ms -135.67ms -120.85ms -121.08ms -120.59ms +makeStyles: +mean: 93.81ms, median: 92.90ms ------------- -Avg: 128.57ms -Median: 121.44ms - -Chakra-UI box component: - -147.42ms -128.51ms -118.74ms -110.01ms -133.05ms -130.20ms -121.57ms -119.11ms -108.57ms -134.90ms +sx Material-UI box: +mean: 187.98ms, median: 188.77ms ------------- -Avg: 125.21ms -Median: 125.04ms - -Theme-UI box sx prop: - -165.02ms -141.07ms -139.19ms -185.45ms -166.16ms -138.83ms -140.56ms -139.02ms -179.26ms -165.58ms +Box Material-UI: +mean: 159.24ms, median: 157.90ms ------------- -Avg: 156.01ms -Median: 153.05ms - -Theme-UI div sx prop: - -131.07ms -130.84ms -130.99ms -132.66ms -132.24ms -130.89ms -131.11ms -167.10ms -154.42ms -131.48ms +sx Theme-UI box: +mean: 164.22ms, median: 164.16ms +------------- +sx Theme-UI div: +mean: 153.10ms, median: 152.77ms +------------- +Box Chakra-UI: +mean: 154.95ms, median: 153.89ms +------------- +styled-components Box + @material-ui/system: +mean: 176.82ms, median: 176.60ms +------------- +styled-components Box + styled-system: +mean: 155.18ms, median: 154.63ms ------------- -Avg: 137.28ms -Median: 131.30ms -Done in 31.83s. ``` diff --git a/benchmark/browser/index.js b/benchmark/browser/index.js index 4bd1f0b727d96c..f997ff05f770e8 100644 --- a/benchmark/browser/index.js +++ b/benchmark/browser/index.js @@ -15,7 +15,7 @@ const Component = requirePerfScenarios(scenarioSuitePath).default; const start = performance.now(); let end; -function TestCase(props) { +function Measure(props) { const ref = React.useRef(null); React.useLayoutEffect(() => { @@ -28,20 +28,18 @@ function TestCase(props) { }; }); - return ( - -
{props.children}
-
- ); + return
{props.children}
; } -TestCase.propTypes = { +Measure.propTypes = { children: PropTypes.node, }; ReactDOM.render( - - - , + + + + + , rootEl, ); diff --git a/benchmark/browser/scenarios/basic-styled-components/index.js b/benchmark/browser/scenarios/basic-styled-components/index.js deleted file mode 100644 index ec26cbce611919..00000000000000 --- a/benchmark/browser/scenarios/basic-styled-components/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { spacing } from '@material-ui/system'; -import styledComponents, { - ThemeProvider as StyledComponentsThemeProvider, -} from 'styled-components'; - -const materialSystemTheme = createMuiTheme(); -const BasicStyleComponents = styledComponents('div')(spacing); - -export default function BasicStyledComponents() { - return ( - - {new Array(1000).fill().map(() => ( - - styled-components - - ))} - - ); -} diff --git a/benchmark/browser/scenarios/box-chakra-ui/index.js b/benchmark/browser/scenarios/box-chakra-ui/index.js index 7307bf072e00d5..8b29672f91a5e7 100644 --- a/benchmark/browser/scenarios/box-chakra-ui/index.js +++ b/benchmark/browser/scenarios/box-chakra-ui/index.js @@ -1,16 +1,11 @@ import * as React from 'react'; -import { Box, ThemeProvider, theme } from '@chakra-ui/core'; +import { Box, ThemeProvider } from '@chakra-ui/core'; -// Let's say you want to add custom colors const customTheme = { - ...theme, colors: { - ...theme.colors, - brand: { - 900: '#1a365d', - 800: '#153e75', - 700: '#2a69ac', - }, + text: '#000', + background: '#fff', + primary: '#33e', }, }; @@ -19,13 +14,15 @@ export default function BoxChakraUi() { {new Array(1000).fill().map(() => ( - chakra-ui + test case ))} diff --git a/benchmark/browser/scenarios/box-emotion/index.js b/benchmark/browser/scenarios/box-emotion/index.js deleted file mode 100644 index f7dd839c16ed4d..00000000000000 --- a/benchmark/browser/scenarios/box-emotion/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; -import { createMuiTheme } from '@material-ui/core/styles'; -import styledEmotion from '@emotion/styled'; -import { ThemeProvider as EmotionTheme } from 'emotion-theming'; -import { styleFunction } from '@material-ui/core/Box'; - -const materialSystemTheme = createMuiTheme(); -const Box = styledEmotion('div')(styleFunction); - -export default function BoxEmotion() { - return ( - - {new Array(1000).fill().map(() => ( - - emotion - - ))} - - ); -} diff --git a/benchmark/browser/scenarios/box-material-ui-styles/index.js b/benchmark/browser/scenarios/box-material-ui-styles/index.js index 35ebad0df4b0b8..6eab23af21e65c 100644 --- a/benchmark/browser/scenarios/box-material-ui-styles/index.js +++ b/benchmark/browser/scenarios/box-material-ui-styles/index.js @@ -1,24 +1,21 @@ import * as React from 'react'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { ThemeProvider as StylesThemeProvider } from '@material-ui/styles'; -import BoxStyles from '@material-ui/core/Box'; - -const materialSystemTheme = createMuiTheme(); +import Box from '@material-ui/core/Box'; export default function BoxMaterialUIStyles() { return ( - + {new Array(1000).fill().map(() => ( - - @material-ui/styles - + test case +
))} - + ); } diff --git a/benchmark/browser/scenarios/box-styled-components/index.js b/benchmark/browser/scenarios/box-styled-components/index.js deleted file mode 100644 index f9873fa8f6bcd4..00000000000000 --- a/benchmark/browser/scenarios/box-styled-components/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import { createMuiTheme } from '@material-ui/core/styles'; -import { styleFunction } from '@material-ui/core/Box'; -import styledComponents, { - ThemeProvider as StyledComponentsThemeProvider, -} from 'styled-components'; - -const materialSystemTheme = createMuiTheme(); -const BoxStyleComponents = styledComponents('div')(styleFunction); - -export default function BoxStyledComponents() { - return ( - - {new Array(1000).fill().map(() => ( - - styled-components - - ))} - - ); -} diff --git a/benchmark/browser/scenarios/components/index.js b/benchmark/browser/scenarios/components/index.js new file mode 100644 index 00000000000000..887bfb0971a875 --- /dev/null +++ b/benchmark/browser/scenarios/components/index.js @@ -0,0 +1,15 @@ +import * as React from 'react'; + +const Div = React.forwardRef(function Div(props, ref) { + return
; +}); + +export default function Components() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/make-styles/index.js b/benchmark/browser/scenarios/make-styles/index.js new file mode 100644 index 00000000000000..81173db4b3d970 --- /dev/null +++ b/benchmark/browser/scenarios/make-styles/index.js @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + root: { + width: 200, + height: 200, + borderWidth: 3, + borderColor: 'white', + ':hover': { + backgroundColor: theme.palette.secondary.dark, + }, + [theme.breakpoints.up('sm')]: { + backgroundColor: theme.palette.primary.main, + borderStyle: 'dashed', + }, + }, +})); + +const Div = React.forwardRef(function Div(props, ref) { + const classes = useStyles(); + + return
; +}); + +export default function MakeStyles() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/primitives/index.js b/benchmark/browser/scenarios/primitives/index.js new file mode 100644 index 00000000000000..03fcff93b9274b --- /dev/null +++ b/benchmark/browser/scenarios/primitives/index.js @@ -0,0 +1,11 @@ +import * as React from 'react'; + +export default function Primitives() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/styled-emotion/index.js b/benchmark/browser/scenarios/styled-emotion/index.js new file mode 100644 index 00000000000000..0edabb3f598958 --- /dev/null +++ b/benchmark/browser/scenarios/styled-emotion/index.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { createMuiTheme } from '@material-ui/core/styles'; +import emotionStyled from '@emotion/styled'; + +const Div = emotionStyled('div')( + ({ theme }) => ` + width: 200px; + height: 200px; + border-width: 3px; + border-color: white; + :hover { + background-color: ${theme.palette.secondary.dark}; + } + ${[theme.breakpoints.up('sm')]} { + background-color: ${theme.palette.primary.main}; + border-style: 'dashed'; + } +`, +); + +const theme = createMuiTheme(); + +export default function StyledEmotion() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/styled-material-ui/index.js b/benchmark/browser/scenarios/styled-material-ui/index.js new file mode 100644 index 00000000000000..18849ead2d3861 --- /dev/null +++ b/benchmark/browser/scenarios/styled-material-ui/index.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { experimentalStyled as styled } from '@material-ui/core/styles'; + +const Div = styled('div')( + ({ theme }) => ` + width: 200px; + height: 200px; + border-width: 3px; + border-color: white; + :hover { + background-color: ${theme.palette.secondary.dark}; + } + ${[theme.breakpoints.up('sm')]} { + background-color: ${theme.palette.primary.main}; + border-style: 'dashed'; + } +`, +); + +export default function StyledMaterialUI() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/styled-sc/index.js b/benchmark/browser/scenarios/styled-sc/index.js new file mode 100644 index 00000000000000..f81df8ad1317b5 --- /dev/null +++ b/benchmark/browser/scenarios/styled-sc/index.js @@ -0,0 +1,33 @@ +import * as React from 'react'; +import { createMuiTheme } from '@material-ui/core/styles'; +import styledComponents, { + ThemeProvider as StyledComponentsThemeProvider, +} from 'styled-components'; + +const Div = styledComponents('div')( + ({ theme }) => ` + width: 200px; + height: 200px; + border-width: 3px; + border-color: white; + :hover { + background-color: ${theme.palette.secondary.dark}; + } + ${[theme.breakpoints.up('sm')]} { + background-color: ${theme.palette.primary.main}; + border-style: 'dashed'; + } +`, +); + +const theme = createMuiTheme(); + +export default function StyledSC() { + return ( + + {new Array(1000).fill().map(() => ( +
test case
+ ))} +
+ ); +} diff --git a/benchmark/browser/scenarios/sx-prop-box-material-ui/index.js b/benchmark/browser/scenarios/sx-prop-box-material-ui/index.js index 1988668b132ec3..aa5e393dc627ed 100644 --- a/benchmark/browser/scenarios/sx-prop-box-material-ui/index.js +++ b/benchmark/browser/scenarios/sx-prop-box-material-ui/index.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; -export default function BoxSxPropMaterialUI() { +export default function SxPropBoxMaterialUI() { return ( {new Array(1000).fill().map(() => ( @@ -9,16 +9,16 @@ export default function BoxSxPropMaterialUI() { sx={{ width: 200, height: 200, - backgroundColor: [undefined, 'primary.light', 'primary.main', 'primary.dark'], borderWidth: '3px', borderColor: 'white', - borderStyle: [undefined, 'dashed', 'solid', 'dotted'], + backgroundColor: { sm: 'primary.main' }, + borderStyle: { sm: 'dashed' }, ':hover': { backgroundColor: (theme) => theme.palette.secondary.dark, }, }} > - material-ui + test case ))} diff --git a/benchmark/browser/scenarios/sx-prop-box-theme-ui/index.js b/benchmark/browser/scenarios/sx-prop-box-theme-ui/index.js index 588f1aa6fa0c36..95d329dc7668bb 100644 --- a/benchmark/browser/scenarios/sx-prop-box-theme-ui/index.js +++ b/benchmark/browser/scenarios/sx-prop-box-theme-ui/index.js @@ -32,7 +32,7 @@ export default function ThemeUISxPropBox() { }, }} > - theme-ui + test case ))} diff --git a/benchmark/browser/scenarios/sx-prop-div-theme-ui/index.js b/benchmark/browser/scenarios/sx-prop-div-theme-ui/index.js index 38e9abb777c964..e9d33a4d2e8704 100644 --- a/benchmark/browser/scenarios/sx-prop-div-theme-ui/index.js +++ b/benchmark/browser/scenarios/sx-prop-div-theme-ui/index.js @@ -32,7 +32,7 @@ export default function ThemeUiSxProp() { }, }} > - theme-ui + test case
))} diff --git a/benchmark/browser/scripts/benchmark.js b/benchmark/browser/scripts/benchmark.js index b4b9ed32bda7f5..6490072ee52bd6 100644 --- a/benchmark/browser/scripts/benchmark.js +++ b/benchmark/browser/scripts/benchmark.js @@ -56,22 +56,26 @@ const getMedian = (measures) => { }; const printMeasure = (name, measures) => { - console.log(`\n${name}:\n`); + console.log(`${name}:`); let sum = 0; const totalNum = measures.length; measures.forEach((measure) => { sum += measure; - console.log(`${measure.toFixed(2)}ms`); + // Uncomment for more details + // console.log(`${measure.toFixed(2)}ms`); }); + console.log( + `mean: ${Number(sum / totalNum).toFixed(2)}ms, median: ${Number(getMedian(measures)).toFixed( + 2, + )}ms`, + ); console.log('-------------'); - console.log(`Avg: ${Number(sum / totalNum).toFixed(2)}ms`); - console.log(`Median: ${Number(getMedian(measures)).toFixed(2)}ms`); }; -async function runMeasures(browser, testCaseName, testCase, times) { +async function runMeasures(browser, testCaseName, testCase, times = 10) { const measures = []; for (let i = 0; i < times; i += 1) { @@ -95,32 +99,36 @@ async function run() { const [server, browser] = await Promise.all([createServer({ port: PORT }), createBrowser()]); try { - await runMeasures(browser, 'noop (baseline)', './noop/index.js', 10); + // Test that there no significant offset + await runMeasures(browser, 'noop (baseline)', './noop/index.js'); + // Test the cost of React primitives + await runMeasures(browser, 'React primitives', './primitives/index.js'); + // Test the cost of React components abstraction + await runMeasures(browser, 'React components', './components/index.js'); + // Test that @material-ui/styled-engine doesn't add an signifiant overhead + await runMeasures(browser, 'Styled Material-UI', './styled-material-ui/index.js'); + await runMeasures(browser, 'Styled emotion', './styled-emotion/index.js'); + await runMeasures(browser, 'Styled SC', './styled-sc/index.js'); + // Test the performance compared to the v4 standard + await runMeasures(browser, 'makeStyles', './make-styles/index.js'); + // Test that the sx prop vs props spreaing has no signficiant difference + await runMeasures(browser, 'sx Material-UI box', './sx-prop-box-material-ui/index.js'); + await runMeasures(browser, 'Box Material-UI', './box-material-ui-styles/index.js'); + // Test the Box perf with alternatives + await runMeasures(browser, 'sx Theme-UI box', './sx-prop-box-theme-ui/index.js'); + await runMeasures(browser, 'sx Theme-UI div', './sx-prop-div-theme-ui/index.js'); + await runMeasures(browser, 'Box Chakra-UI', './box-chakra-ui/index.js'); + // Test the system perf difference with alternatives await runMeasures( browser, 'styled-components Box + @material-ui/system', './styled-components-box-material-ui-system/index.js', - 10, ); await runMeasures( browser, 'styled-components Box + styled-system', './styled-components-box-styled-system/index.js', - 10, ); - await runMeasures(browser, 'Box emotion', './box-emotion/index.js', 10); - await runMeasures(browser, 'Box @material-ui/styles', './box-material-ui-styles/index.js', 10); - await runMeasures(browser, 'Box styled-components', './box-styled-components/index.js', 10); - await runMeasures( - browser, - 'Basic styled-components box', - './basic-styled-components/index.js', - 10, - ); - await runMeasures(browser, 'Chakra-UI box component', './box-chakra-ui/index.js', 10); - await runMeasures(browser, 'Theme-UI box sx prop', './sx-prop-box-theme-ui/index.js', 10); - await runMeasures(browser, 'Theme-UI div sx prop', './sx-prop-div-theme-ui/index.js', 10); - await runMeasures(browser, 'Material-UI box sx prop', './sx-prop-box-material-ui/index.js', 10); } finally { await Promise.all([browser.close(), server.close()]); } diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 7c21300d257b82..6c3de1f29ce87a 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -142,9 +142,34 @@ This prop provides a superset of CSS that maps values directly from the theme, d ### When to use it? -The styled-components's API is great to build low-level components that need to support a wide variety of contexts. +- **styled-components**: the API is great to build components that need to support a wide variety of contexts. These components are used in many different parts of the application and support different combinations of props. +- **`sx` prop**: the API is great to apply one-off styles. It's called "utility" for this reason. -The `sx` prop is great anytime one-off styles need to be applied. It's called "utility" for this reason. +### Performance tradeoff + +The system relies on CSS-in-JS. It works with both emotion and styled-components. + +Pros: + +- 📚 It allows a lot of flexibility in the API. The `sx` prop supports a superset of CSS. There is **no need to learn CSS twice**. You are set once you have learn the standardized CSS syntax, it's safe, it hasn't changed for a decade. Then, you can **optionally** learn the shorthands if you value the save of time they bring. +- 📦 No need for purge. Only the used CSS on the page is included. The initial bundle size cost is **fixed**. It's not growing with the number of used CSS properties. + You pay the cost of [@emotion/react](https://bundlephobia.com/result?p=@emotion/react) and [@material-ui/system](https://bundlephobia.com/result?p=@material-ui/system). It cost around ~15 kB gzipped. + If you are already using the core components, it comes with no extra overhead. + +Cons: + +- The runtime performance take a hit. + + | Benchmark case | Code snippet | Time normalized | + | :-------------------------------- | :------------------- | --------------- | + | a. Render 1,000 primitives | `
` | 100ms | + | b. Render 1,000 components | `
` | 110ms | + | c. Render 1,000 styled components | `` | 160ms | + | d. Render 1,000 Box | `` | 270ms | + + _Head to the [benchmark folder](https://github.com/mui-org/material-ui/tree/next/benchmark/browser) for a reproduction of these metrics._ + + We believe that for most applications, it's **fast enough**. There are simple workarounds when performance becomes critical. For instance, when rendering a list with many items, you can use a CSS child selector to have a single "style injection" point (using d. for the wrapper and a. for each item). ## Usage @@ -315,6 +340,7 @@ All core Material-UI components will support the `sx` prop. ### 2. Box [`Box`](/components/box/) is a lightweight component that gives access to the `sx` prop, and can be used as a utility component, and as a wrapper for other components. +It renders a `
` element by default. ### 3. Custom components From 5e7fa1a6cfe535b80d74a9118a5fecb3be99f869 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 7 Nov 2020 21:25:56 +0100 Subject: [PATCH 74/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 6c3de1f29ce87a..fd856248fa21ce 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -1,6 +1,6 @@ # Material-UI System -

Utility style functions for rapidly building custom design systems.

+

CSS utilities for rapidly creating custom design.

Material-UI comes with dozens or **ready-to-use** components in the core. These components are an incredible starting point but when it comes to make your site stand out with a custom design, they can be challenging to customize. Introducing the system: From 873490d6bba69ec85f3e778f8dca2933d072ebff Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 7 Nov 2020 21:31:52 +0100 Subject: [PATCH 75/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Matt --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index fd856248fa21ce..78a96b92573c9a 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -23,7 +23,7 @@ npm install @material-ui/system yarn add @material-ui/system ``` -## Why utility? +## Why use the system? Compare how the same stat component can be built with two different APIs. From fb425020fc53892907cd9427e06af870bd157545 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 7 Nov 2020 21:32:08 +0100 Subject: [PATCH 76/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 78a96b92573c9a..9eec536ef34f33 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -335,7 +335,7 @@ The `sx` prop can be used in four different locations: ### 1. Core components -All core Material-UI components will support the `sx` prop. +All core Material-UI components support the `sx` prop. ### 2. Box From cb35c1ea12912dec619880ee6654e151f22f848a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 9 Nov 2020 11:42:58 +0100 Subject: [PATCH 77/84] comments --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 9eec536ef34f33..c5e370a2809d84 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -5,7 +5,7 @@ Material-UI comes with dozens or **ready-to-use** components in the core. These components are an incredible starting point but when it comes to make your site stand out with a custom design, they can be challenging to customize. Introducing the system: -The **system** lets you quickly build custom UI components leveraging the design tokens defined in your theme. +The **system** lets you quickly build custom UI components leveraging the values defined in your theme. ## Demo From 0f9a565548b04da64936d83a70d0b5b8f35f2277 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 9 Nov 2020 11:44:34 +0100 Subject: [PATCH 78/84] Update docs/src/pages/system/basics/basics.md --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index c5e370a2809d84..92ad8afe95cf5c 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -202,7 +202,7 @@ You might want to skip this part and bet on CSS, it has been standardized for de ### Superset of CSS -As the prop supports a superset of CSS, you can use child or pseudo-selectors, media queries, raw CSS values, etc. Here are a few examples: +As part of the prop, you can use any regular CSS too: child or pseudo-selectors, media queries, raw CSS values, etc. Here are a few examples: - Using pseudo selectors: From 6d1c0633aa97d150400f66183d26b1030c1d0c68 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 9 Nov 2020 11:46:32 +0100 Subject: [PATCH 79/84] Update docs/src/pages/system/basics/basics.md Co-authored-by: Olivier Tassinari --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 92ad8afe95cf5c..eab1801592a864 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -152,7 +152,7 @@ The system relies on CSS-in-JS. It works with both emotion and styled-components Pros: - 📚 It allows a lot of flexibility in the API. The `sx` prop supports a superset of CSS. There is **no need to learn CSS twice**. You are set once you have learn the standardized CSS syntax, it's safe, it hasn't changed for a decade. Then, you can **optionally** learn the shorthands if you value the save of time they bring. -- 📦 No need for purge. Only the used CSS on the page is included. The initial bundle size cost is **fixed**. It's not growing with the number of used CSS properties. +- 📦 Auto-purge. Only the used CSS on the page is sent to the client. The initial bundle size cost is **fixed**. It's not growing with the number of used CSS properties. You pay the cost of [@emotion/react](https://bundlephobia.com/result?p=@emotion/react) and [@material-ui/system](https://bundlephobia.com/result?p=@material-ui/system). It cost around ~15 kB gzipped. If you are already using the core components, it comes with no extra overhead. From 05b40fdfe84eac72151107acf5e8dcccf30ef4fe Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 9 Nov 2020 11:50:29 +0100 Subject: [PATCH 80/84] feedback --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index c5e370a2809d84..7e8c7b0ea58b0b 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -3,7 +3,7 @@

CSS utilities for rapidly creating custom design.

Material-UI comes with dozens or **ready-to-use** components in the core. -These components are an incredible starting point but when it comes to make your site stand out with a custom design, they can be challenging to customize. Introducing the system: +These components are an incredible starting point but when it comes to make your site stand out with a custom design, it can be simpler to start from an unstyled state. Introducing the system: The **system** lets you quickly build custom UI components leveraging the values defined in your theme. From 762b4cc1e0dad6aff9547ffa8e5ad64c0330d314 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 9 Nov 2020 19:22:57 +0100 Subject: [PATCH 81/84] make the link clear --- docs/src/pages/system/basics/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 18d73c903a6acf..98f4196b8a0ede 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -198,7 +198,7 @@ Here are an example leveraging them: ``` These shorthands are **optional**, they are great to save time when writing styles but it can be overwhelming to learn new custom APIs. -You might want to skip this part and bet on CSS, it has been standardized for decades, head to the next section. +You might want to skip this part and bet on CSS, it has been standardized for decades, head to the [next section](#superset-of-css). ### Superset of CSS From 2ad356c12d07474047cb5014613bc02998cd169b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 11 Nov 2020 12:51:49 +0100 Subject: [PATCH 82/84] typos and final fixes --- docs/src/pages/system/basics/basics.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 98f4196b8a0ede..d6a23ad66fbad1 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -3,7 +3,7 @@

CSS utilities for rapidly creating custom design.

Material-UI comes with dozens or **ready-to-use** components in the core. -These components are an incredible starting point but when it comes to make your site stand out with a custom design, it can be simpler to start from an unstyled state. Introducing the system: +These components are an incredible starting point but when it comes to making your site stand out with a custom design, it can be simpler to start from an unstyled state. Introducing the system: The **system** lets you quickly build custom UI components leveraging the values defined in your theme. @@ -181,7 +181,7 @@ You can explore the [System properties](/system/properties/) page to discover ho There are lots of shorthands available for the CSS properties. These are documented in the next pages, for instance, [the spacing](/system/spacing/). -Here are an example leveraging them: +Here is an example leveraging them: ```jsx **Note:** -> -> You should use this prop whenever you need to add or override a component style. If you find you are repeatedly applying the same styles to a component, then `styled()` may be a better option, as it allows you to specify the styles only once, and reuse them in all component instances. See [Customizing components](/customization/components/) for all the alternatives. - ### 4. Any element with the babel plugin TODO [#23220](https://github.com/mui-org/material-ui/issues/23220). From 6007e3b6f0060d5e37b424c25dd33d3293f00161 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 11 Nov 2020 15:24:51 +0100 Subject: [PATCH 83/84] test preview --- docs/src/pages/system/basics/Demo.js | 8 ++++---- docs/src/pages/system/basics/Demo.tsx | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index 917e3db8ec1025..249a41973f9a4f 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -3,6 +3,10 @@ import Box from '@material-ui/core/Box'; import { alpha } from '@material-ui/core/styles'; import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; +function Img(props) { + return ; +} + export default function Demo() { return ( ); } - -function Img(props) { - return ; -} diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 797c853c4e5406..ad24dbc2ef54e0 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -3,6 +3,15 @@ import Box, { BoxProps } from '@material-ui/core/Box'; import { alpha } from '@material-ui/core/styles'; import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; +interface ImgProps extends BoxProps { + src?: string; + alt?: string; +} + +function Img(props: ImgProps) { + return ; +} + export default function Demo() { return ( ); } - -interface ImgProps extends BoxProps { - src?: string; - alt?: string; -} - -function Img(props: ImgProps) { - return ; -} From 5aa6192ed814392dc8d672cad6ff0113b4c56b28 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 12 Nov 2020 15:08:47 +0100 Subject: [PATCH 84/84] Remove prettier-ignore directives from user-facing code --- docs/src/pages/system/basics/Why.js | 51 ++++++++++++++++++++++---- docs/src/pages/system/basics/Why.tsx | 51 ++++++++++++++++++++++---- docs/src/pages/system/basics/basics.md | 51 ++++++++++++++++++++++---- 3 files changed, 132 insertions(+), 21 deletions(-) diff --git a/docs/src/pages/system/basics/Why.js b/docs/src/pages/system/basics/Why.js index 84806e91bde6ad..9ccae3c38a8fe3 100644 --- a/docs/src/pages/system/basics/Why.js +++ b/docs/src/pages/system/basics/Why.js @@ -4,19 +4,56 @@ import Box from '@material-ui/core/Box'; export default function Why() { return ( - /* prettier-ignore */ - - + + Sessions - + 98.3 K - - + + 18.77% - + vs last week diff --git a/docs/src/pages/system/basics/Why.tsx b/docs/src/pages/system/basics/Why.tsx index 84806e91bde6ad..9ccae3c38a8fe3 100644 --- a/docs/src/pages/system/basics/Why.tsx +++ b/docs/src/pages/system/basics/Why.tsx @@ -4,19 +4,56 @@ import Box from '@material-ui/core/Box'; export default function Why() { return ( - /* prettier-ignore */ - - + + Sessions - + 98.3 K - - + + 18.77% - + vs last week diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index d6a23ad66fbad1..d7b0f9b1140ad5 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -96,19 +96,56 @@ return ( 2. ✅ using the system: ```jsx -/* prettier-ignore */ - - + + Sessions - + 98.3 K - - + + 18.77% - + vs last week