From 0ea5e0f3b808b3bbd2dc0a48c0115b2fa84d43b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Kie=C3=9Fling?= Date: Thu, 30 Aug 2018 14:49:15 +0200 Subject: [PATCH 1/2] [docs] Explain how to pass props down to overridden components --- .../customization/overrides/overrides.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/src/pages/customization/overrides/overrides.md b/docs/src/pages/customization/overrides/overrides.md index 0aa3d82919b23f..0279fe3496aaaf 100644 --- a/docs/src/pages/customization/overrides/overrides.md +++ b/docs/src/pages/customization/overrides/overrides.md @@ -26,6 +26,25 @@ of the `` to ensure the components always render correctly. {{"demo": "pages/customization/overrides/ClassNames.js"}} +Note that by creating an overridden component this way, you fully "inherit" the original component, but when using the +overridden component, passing props known to the original component are simply lost. That is, using the overridden +component like this: `` will not have the desired effect - the `type` prop is not passed down +to the original `Button`. You can work around this without manually passing down each prop that the original +component supports by using [JSX spread attributes](https://zhenyong.github.io/react/docs/jsx-spread.html), like so: + +```jsx +function ClassNames(props) { + return ( + + ); +} +``` + +The only requirement is that your environment supports [Object Rest and Spread Properties](https://github.com/tc39/proposal-object-rest-spread). For example, Babel does +this via the [object rest spread plugin](https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-object-rest-spread). + ### Overriding with classes When the `className` property isn't enough, and you need to access deeper elements, you can take advantage of the `classes` property to customize all the CSS injected by Material-UI for a given component. From 9bfa4155f38500f44fdc36a78734ffdd0f933e5f Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 1 Sep 2018 19:19:33 +0200 Subject: [PATCH 2/2] [docs] Add a shorthand override section --- .../customization/overrides/ClassNames.js | 8 +++- .../overrides/ClassesShorthand.js | 24 +++++++++++ .../customization/overrides/overrides.md | 43 +++++++++++-------- pages/customization/overrides.js | 7 +++ 4 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 docs/src/pages/customization/overrides/ClassesShorthand.js diff --git a/docs/src/pages/customization/overrides/ClassNames.js b/docs/src/pages/customization/overrides/ClassNames.js index b0262785eeb350..fe0547e319e075 100644 --- a/docs/src/pages/customization/overrides/ClassNames.js +++ b/docs/src/pages/customization/overrides/ClassNames.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import classNames from 'classnames'; import { withStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; @@ -17,9 +18,11 @@ const styles = { }; function ClassNames(props) { + const { classes, children, className, ...other } = props; + return ( - ); } @@ -27,6 +30,7 @@ function ClassNames(props) { ClassNames.propTypes = { children: PropTypes.node, classes: PropTypes.object.isRequired, + className: PropTypes.string, }; export default withStyles(styles)(ClassNames); diff --git a/docs/src/pages/customization/overrides/ClassesShorthand.js b/docs/src/pages/customization/overrides/ClassesShorthand.js new file mode 100644 index 00000000000000..a04a7a408e0032 --- /dev/null +++ b/docs/src/pages/customization/overrides/ClassesShorthand.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { withStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; + +// The `withStyles()` higher-order component is injecting a `classes` +// property that is used by the `Button` component. +const StyledButton = withStyles({ + root: { + background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', + borderRadius: 3, + border: 0, + color: 'white', + height: 48, + padding: '0 30px', + boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', + }, + label: { + textTransform: 'capitalize', + }, +})(Button); + +export default function ClassesShorthand() { + return Classes Shorthand +} diff --git a/docs/src/pages/customization/overrides/overrides.md b/docs/src/pages/customization/overrides/overrides.md index 0279fe3496aaaf..026a5b2f3be67f 100644 --- a/docs/src/pages/customization/overrides/overrides.md +++ b/docs/src/pages/customization/overrides/overrides.md @@ -26,25 +26,6 @@ of the `` to ensure the components always render correctly. {{"demo": "pages/customization/overrides/ClassNames.js"}} -Note that by creating an overridden component this way, you fully "inherit" the original component, but when using the -overridden component, passing props known to the original component are simply lost. That is, using the overridden -component like this: `` will not have the desired effect - the `type` prop is not passed down -to the original `Button`. You can work around this without manually passing down each prop that the original -component supports by using [JSX spread attributes](https://zhenyong.github.io/react/docs/jsx-spread.html), like so: - -```jsx -function ClassNames(props) { - return ( - - ); -} -``` - -The only requirement is that your environment supports [Object Rest and Spread Properties](https://github.com/tc39/proposal-object-rest-spread). For example, Babel does -this via the [object rest spread plugin](https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-object-rest-spread). - ### Overriding with classes When the `className` property isn't enough, and you need to access deeper elements, you can take advantage of the `classes` property to customize all the CSS injected by Material-UI for a given component. @@ -62,6 +43,30 @@ Notice that in addition to the button styling, the button label's capitalization {{"demo": "pages/customization/overrides/ClassesNesting.js"}} +#### Shorthand + +The above code example can be condensed by using **the same CSS API** than the child component. +In this example, the `withStyles()` higher-order component is injecting a `classes` property that is used by the [`Button` component](/api/button#css-api). + +```jsx +const StyledButton = withStyles({ + root: { + background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', + borderRadius: 3, + border: 0, + color: 'white', + height: 48, + padding: '0 30px', + boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', + }, + label: { + textTransform: 'capitalize', + }, +})(Button); +``` + +{{"demo": "pages/customization/overrides/ClassesShorthand.js"}} + #### Internal states Aside from accessing nested elements, the `classes` property can be used to customize the internal states of Material-UI components. diff --git a/pages/customization/overrides.js b/pages/customization/overrides.js index 2c8dee80f36499..855b6431e64df2 100644 --- a/pages/customization/overrides.js +++ b/pages/customization/overrides.js @@ -22,6 +22,13 @@ module.exports = require('fs') raw: preval` module.exports = require('fs') .readFileSync(require.resolve('docs/src/pages/customization/overrides/ClassesNesting'), 'utf8') +`, + }, + 'pages/customization/overrides/ClassesShorthand.js': { + js: require('docs/src/pages/customization/overrides/ClassesShorthand').default, + raw: preval` +module.exports = require('fs') + .readFileSync(require.resolve('docs/src/pages/customization/overrides/ClassesShorthand'), 'utf8') `, }, 'pages/customization/overrides/ClassesState.js': {