From 99489e3e6f1e8f29c9dca421467a40a3b9a9c616 Mon Sep 17 00:00:00 2001 From: Sean Campbell Date: Mon, 25 Jan 2021 20:32:43 -0500 Subject: [PATCH 1/5] Migrate CardMedia to emotion --- docs/pages/api-docs/card-media.json | 3 +- .../api-docs/card-media/card-media.json | 3 +- .../material-ui/src/CardMedia/CardMedia.d.ts | 6 + .../material-ui/src/CardMedia/CardMedia.js | 116 +++++++++++------- .../src/CardMedia/CardMedia.test.js | 14 +-- .../src/CardMedia/cardMediaClasses.d.ts | 11 ++ .../src/CardMedia/cardMediaClasses.js | 9 ++ packages/material-ui/src/CardMedia/index.d.ts | 3 + packages/material-ui/src/CardMedia/index.js | 3 + 9 files changed, 118 insertions(+), 50 deletions(-) create mode 100644 packages/material-ui/src/CardMedia/cardMediaClasses.d.ts create mode 100644 packages/material-ui/src/CardMedia/cardMediaClasses.js diff --git a/docs/pages/api-docs/card-media.json b/docs/pages/api-docs/card-media.json index 6d6a6a01c294fc..e88a25ed8dcc51 100644 --- a/docs/pages/api-docs/card-media.json +++ b/docs/pages/api-docs/card-media.json @@ -4,7 +4,8 @@ "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, "image": { "type": { "name": "string" } }, - "src": { "type": { "name": "string" } } + "src": { "type": { "name": "string" } }, + "sx": { "type": { "name": "object" } } }, "name": "CardMedia", "styles": { "classes": ["root", "media", "img"], "globalClasses": {}, "name": "MuiCardMedia" }, diff --git a/docs/translations/api-docs/card-media/card-media.json b/docs/translations/api-docs/card-media/card-media.json index 549ce3ec7b894f..92515bce5e0bfc 100644 --- a/docs/translations/api-docs/card-media/card-media.json +++ b/docs/translations/api-docs/card-media/card-media.json @@ -5,7 +5,8 @@ "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", "image": "Image to be displayed as a background image. Either image or src prop must be specified. Note that caller must specify height otherwise the image will not be visible.", - "src": "An alias for image property. Available only with media components. Media components: video, audio, picture, iframe, img." + "src": "An alias for image property. Available only with media components. Media components: video, audio, picture, iframe, img.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { "root": { "description": "Styles applied to the root element." }, diff --git a/packages/material-ui/src/CardMedia/CardMedia.d.ts b/packages/material-ui/src/CardMedia/CardMedia.d.ts index 7d5a6299c820fb..3ec63fbf834e55 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.d.ts +++ b/packages/material-ui/src/CardMedia/CardMedia.d.ts @@ -1,4 +1,6 @@ +import { SxProps } from '@material-ui/system'; import * as React from 'react'; +import { Theme } from '..'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; export interface CardMediaTypeMap { @@ -30,6 +32,10 @@ export interface CardMediaTypeMap { * Media components: `video`, `audio`, `picture`, `iframe`, `img`. */ src?: string; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; }; defaultComponent: D; } diff --git a/packages/material-ui/src/CardMedia/CardMedia.js b/packages/material-ui/src/CardMedia/CardMedia.js index d28619ff1980e4..bca36805c997a3 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.js +++ b/packages/material-ui/src/CardMedia/CardMedia.js @@ -1,63 +1,93 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { chainPropTypes } from '@material-ui/utils'; -import withStyles from '../styles/withStyles'; +import { chainPropTypes, deepmerge } from '@material-ui/utils'; -export const styles = { - /* Styles applied to the root element. */ - root: { - display: 'block', - backgroundSize: 'cover', - backgroundRepeat: 'no-repeat', - backgroundPosition: 'center', +import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; +import useThemeProps from '../styles/useThemeProps'; +import experimentalStyled from '../styles/experimentalStyled'; +import { getCardMediaUtilityClass } from './cardMediaClasses'; + +const MEDIA_COMPONENTS = ['video', 'audio', 'picture', 'iframe', 'img']; +const IMAGE_COMPONENTS = ['picture', 'img']; + +const overridesResolver = (props, styles) => { + const { styleProps } = props; + + const isMediaComponent = MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1; + const isImageComponent = IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1; + + return deepmerge(styles.root || {}, { + ...(isMediaComponent && styles.media), + ...(isImageComponent && styles.img), + }); +}; + +const useUtilityClasses = (styleProps) => { + const { classes } = styleProps; + + const isMediaComponent = MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1; + const isImageComponent = IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1; + + const slots = { + root: ['root', isMediaComponent && 'media', isImageComponent && 'img'], + }; + + return composeClasses(slots, getCardMediaUtilityClass, classes); +}; + +const CardMediaRoot = experimentalStyled( + 'div', + {}, + { + name: 'MuiCardMedia', + slot: 'Root', + overridesResolver, }, - /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ - media: { +)(({ styleProps }) => ({ + /* Styles applied to the root element. */ + display: 'block', + backgroundSize: 'cover', + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center', + ...(MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1 && { + /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ width: '100%', - }, - /* Styles applied to the root element if `component="picture or img"`. */ - img: { + }), + ...(IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1 && { + /* Styles applied to the root element if `component="picture or img"`. */ // ⚠️ object-fit is not supported by IE11. objectFit: 'cover', - }, -}; + }), +})); -const MEDIA_COMPONENTS = ['video', 'audio', 'picture', 'iframe', 'img']; +const CardMedia = React.forwardRef(function CardMedia(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'MuiCardMedia' }); + const { children, className, component = 'div', image, src, style, ...other } = props; -const CardMedia = React.forwardRef(function CardMedia(props, ref) { - const { - children, - classes, - className, - component: Component = 'div', - image, - src, - style, - ...other - } = props; - - const isMediaComponent = MEDIA_COMPONENTS.indexOf(Component) !== -1; + const isMediaComponent = MEDIA_COMPONENTS.indexOf(component) !== -1; const composedStyle = !isMediaComponent && image ? { backgroundImage: `url("${image}")`, ...style } : style; + const styleProps = { + ...props, + component, + }; + + const classes = useUtilityClasses(styleProps); + return ( - {children} - + ); }); @@ -106,6 +136,10 @@ CardMedia.propTypes = { * @ignore */ style: PropTypes.object, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, }; -export default withStyles(styles, { name: 'MuiCardMedia' })(CardMedia); +export default CardMedia; diff --git a/packages/material-ui/src/CardMedia/CardMedia.test.js b/packages/material-ui/src/CardMedia/CardMedia.test.js index 2d6e8c93306dda..8cbba8334d5094 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.test.js +++ b/packages/material-ui/src/CardMedia/CardMedia.test.js @@ -1,23 +1,23 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { expect } from 'chai'; -import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils'; +import { createMount, createClientRender, describeConformanceV5 } from 'test/utils'; import CardMedia from './CardMedia'; +import classes from './cardMediaClasses'; describe('', () => { const mount = createMount(); - let classes; const render = createClientRender(); - before(() => { - classes = getClasses(); - }); - describeConformance(, () => ({ + describeConformanceV5(, () => ({ classes, inheritComponent: 'div', mount, + muiName: 'MuiCardMedia', refInstanceof: window.HTMLDivElement, testComponentPropWith: 'span', + testVariantProps: { variant: 'foo' }, + skip: ['componentsProp'], })); it('should have the backgroundImage specified', () => { @@ -79,7 +79,7 @@ describe('', () => { it('warns when neither `children`, nor `image`, nor `src`, nor `component` are provided', () => { expect(() => { - PropTypes.checkPropTypes(CardMedia.Naked.propTypes, { classes: {} }, 'prop', 'MockedName'); + PropTypes.checkPropTypes(CardMedia.propTypes, { classes: {} }, 'prop', 'MockedName'); }).toErrorDev( 'Material-UI: Either `children`, `image`, `src` or `component` prop must be specified.', ); diff --git a/packages/material-ui/src/CardMedia/cardMediaClasses.d.ts b/packages/material-ui/src/CardMedia/cardMediaClasses.d.ts new file mode 100644 index 00000000000000..4bf7f3f94b9a98 --- /dev/null +++ b/packages/material-ui/src/CardMedia/cardMediaClasses.d.ts @@ -0,0 +1,11 @@ +export interface CardMediaClasses { + root: string; + media: string; + img: string; +} + +declare const cardMediaClasses: CardMediaClasses; + +export function getCardMediaUtilityClass(slot: string): string; + +export default cardMediaClasses; diff --git a/packages/material-ui/src/CardMedia/cardMediaClasses.js b/packages/material-ui/src/CardMedia/cardMediaClasses.js new file mode 100644 index 00000000000000..5a1f4587377c8b --- /dev/null +++ b/packages/material-ui/src/CardMedia/cardMediaClasses.js @@ -0,0 +1,9 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getCardMediaUtilityClass(slot) { + return generateUtilityClass('MuiCardMedia', slot); +} + +const cardMediaClasses = generateUtilityClasses('MuiCardMedia', ['root', 'media', 'img']); + +export default cardMediaClasses; diff --git a/packages/material-ui/src/CardMedia/index.d.ts b/packages/material-ui/src/CardMedia/index.d.ts index e01400dab1b601..c61f21cc6b4d84 100644 --- a/packages/material-ui/src/CardMedia/index.d.ts +++ b/packages/material-ui/src/CardMedia/index.d.ts @@ -1,2 +1,5 @@ export { default } from './CardMedia'; export * from './CardMedia'; + +export { default as cardMediaClasses } from './cardMediaClasses'; +export * from './cardMediaClasses'; diff --git a/packages/material-ui/src/CardMedia/index.js b/packages/material-ui/src/CardMedia/index.js index 52c81c17a543a3..b20f3170c16b8a 100644 --- a/packages/material-ui/src/CardMedia/index.js +++ b/packages/material-ui/src/CardMedia/index.js @@ -1 +1,4 @@ export { default } from './CardMedia'; + +export { default as cardMediaClasses } from './cardMediaClasses'; +export * from './cardMediaClasses'; From 57f36d746d231cf5d0bf58e25b3b2b797fc21530 Mon Sep 17 00:00:00 2001 From: Sean Campbell Date: Tue, 26 Jan 2021 11:08:17 -0500 Subject: [PATCH 2/5] ran yarn docs:api on CardMedia emotion --- docs/pages/api-docs/card-media.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/api-docs/card-media.json b/docs/pages/api-docs/card-media.json index e88a25ed8dcc51..528452a3976a72 100644 --- a/docs/pages/api-docs/card-media.json +++ b/docs/pages/api-docs/card-media.json @@ -14,6 +14,6 @@ "filename": "/packages/material-ui/src/CardMedia/CardMedia.js", "inheritance": null, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } From d7c74f9abca5f6c1acde8d3ac6140db536fb421b Mon Sep 17 00:00:00 2001 From: Sean Campbell Date: Tue, 26 Jan 2021 12:18:06 -0500 Subject: [PATCH 3/5] Fixed component referencing with CardMedia --- .../material-ui/src/CardMedia/CardMedia.js | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/material-ui/src/CardMedia/CardMedia.js b/packages/material-ui/src/CardMedia/CardMedia.js index bca36805c997a3..73e287fc69c9fd 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.js +++ b/packages/material-ui/src/CardMedia/CardMedia.js @@ -2,20 +2,14 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { chainPropTypes, deepmerge } from '@material-ui/utils'; - import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; import useThemeProps from '../styles/useThemeProps'; import experimentalStyled from '../styles/experimentalStyled'; import { getCardMediaUtilityClass } from './cardMediaClasses'; -const MEDIA_COMPONENTS = ['video', 'audio', 'picture', 'iframe', 'img']; -const IMAGE_COMPONENTS = ['picture', 'img']; - const overridesResolver = (props, styles) => { const { styleProps } = props; - - const isMediaComponent = MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1; - const isImageComponent = IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1; + const { isMediaComponent, isImageComponent } = styleProps; return deepmerge(styles.root || {}, { ...(isMediaComponent && styles.media), @@ -24,10 +18,7 @@ const overridesResolver = (props, styles) => { }; const useUtilityClasses = (styleProps) => { - const { classes } = styleProps; - - const isMediaComponent = MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1; - const isImageComponent = IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1; + const { classes, isMediaComponent, isImageComponent } = styleProps; const slots = { root: ['root', isMediaComponent && 'media', isImageComponent && 'img'], @@ -50,17 +41,20 @@ const CardMediaRoot = experimentalStyled( backgroundSize: 'cover', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', - ...(MEDIA_COMPONENTS.indexOf(styleProps.component) !== -1 && { + ...(styleProps.isMediaComponent && { /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ width: '100%', }), - ...(IMAGE_COMPONENTS.indexOf(styleProps.component) !== -1 && { + ...(styleProps.isImageComponent && { /* Styles applied to the root element if `component="picture or img"`. */ // ⚠️ object-fit is not supported by IE11. objectFit: 'cover', }), })); +const MEDIA_COMPONENTS = ['video', 'audio', 'picture', 'iframe', 'img']; +const IMAGE_COMPONENTS = ['picture', 'img']; + const CardMedia = React.forwardRef(function CardMedia(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiCardMedia' }); const { children, className, component = 'div', image, src, style, ...other } = props; @@ -72,6 +66,8 @@ const CardMedia = React.forwardRef(function CardMedia(inProps, ref) { const styleProps = { ...props, component, + isMediaComponent, + isImageComponent: IMAGE_COMPONENTS.indexOf(component) !== -1, }; const classes = useUtilityClasses(styleProps); From 882bf2dd66daee82e601051c03a740e2fe752fb9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 26 Jan 2021 18:54:53 +0100 Subject: [PATCH 4/5] Update packages/material-ui/src/CardMedia/CardMedia.js --- packages/material-ui/src/CardMedia/CardMedia.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/CardMedia/CardMedia.js b/packages/material-ui/src/CardMedia/CardMedia.js index 73e287fc69c9fd..7b5c905ababf09 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.js +++ b/packages/material-ui/src/CardMedia/CardMedia.js @@ -45,8 +45,8 @@ const CardMediaRoot = experimentalStyled( /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ width: '100%', }), + /* Styles applied to the root element if `component="picture or img"`. */ ...(styleProps.isImageComponent && { - /* Styles applied to the root element if `component="picture or img"`. */ // ⚠️ object-fit is not supported by IE11. objectFit: 'cover', }), From 949f0edfbe4bf87084a3f092573fbfd1928346f9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 26 Jan 2021 18:54:59 +0100 Subject: [PATCH 5/5] Update packages/material-ui/src/CardMedia/CardMedia.js --- packages/material-ui/src/CardMedia/CardMedia.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/CardMedia/CardMedia.js b/packages/material-ui/src/CardMedia/CardMedia.js index 7b5c905ababf09..8e6e2fbd35bceb 100644 --- a/packages/material-ui/src/CardMedia/CardMedia.js +++ b/packages/material-ui/src/CardMedia/CardMedia.js @@ -41,8 +41,8 @@ const CardMediaRoot = experimentalStyled( backgroundSize: 'cover', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', + /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ ...(styleProps.isMediaComponent && { - /* Styles applied to the root element if `component="video, audio, picture, iframe, or img"`. */ width: '100%', }), /* Styles applied to the root element if `component="picture or img"`. */