diff --git a/docs/pages/api-docs/step-content.json b/docs/pages/api-docs/step-content.json index 54de19651c97d9..710079dcd4096e 100644 --- a/docs/pages/api-docs/step-content.json +++ b/docs/pages/api-docs/step-content.json @@ -2,6 +2,7 @@ "props": { "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" } }, + "sx": { "type": { "name": "object" } }, "TransitionComponent": { "type": { "name": "elementType" }, "default": "Collapse" }, "transitionDuration": { "type": { @@ -23,6 +24,6 @@ "filename": "/packages/material-ui/src/StepContent/StepContent.js", "inheritance": null, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } diff --git a/docs/translations/api-docs/step-content/step-content.json b/docs/translations/api-docs/step-content/step-content.json index d5d9ed79fffaff..33a61bd77b844a 100644 --- a/docs/translations/api-docs/step-content/step-content.json +++ b/docs/translations/api-docs/step-content/step-content.json @@ -3,6 +3,7 @@ "propDescriptions": { "children": "The content of the component.", "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.", "TransitionComponent": "The component used for the transition. Follow this guide to learn more about the requirements for this component.", "transitionDuration": "Adjust the duration of the content expand transition. Passed as a prop to the transition component.
Set to 'auto' to automatically calculate transition time based on height.", "TransitionProps": "Props applied to the transition element. By default, the element is based on this Transition component." diff --git a/packages/material-ui/src/StepContent/StepContent.d.ts b/packages/material-ui/src/StepContent/StepContent.d.ts index c3f10f4dc789a1..63d95491683cc6 100644 --- a/packages/material-ui/src/StepContent/StepContent.d.ts +++ b/packages/material-ui/src/StepContent/StepContent.d.ts @@ -1,5 +1,7 @@ import * as React from 'react'; +import { SxProps } from '@material-ui/system'; import { InternalStandardProps as StandardProps } from '..'; +import { Theme } from '../styles'; import { TransitionProps } from '../transitions/transition'; export interface StepContentProps extends StandardProps> { @@ -18,6 +20,10 @@ export interface StepContentProps extends StandardProps; /** * The component used for the transition. * [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. diff --git a/packages/material-ui/src/StepContent/StepContent.js b/packages/material-ui/src/StepContent/StepContent.js index cd590fabcc8904..2d79e0caf5841d 100644 --- a/packages/material-ui/src/StepContent/StepContent.js +++ b/packages/material-ui/src/StepContent/StepContent.js @@ -1,33 +1,72 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; +import { deepmerge } from '@material-ui/utils'; +import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled'; +import experimentalStyled from '../styles/experimentalStyled'; +import useThemeProps from '../styles/useThemeProps'; import Collapse from '../Collapse'; -import withStyles from '../styles/withStyles'; import StepperContext from '../Stepper/StepperContext'; import StepContext from '../Step/StepContext'; +import stepContentClasses, { getStepContentUtilityClass } from './stepContentClasses'; -export const styles = (theme) => ({ - /* Styles applied to the root element. */ - root: { - marginLeft: 12, // half icon - paddingLeft: 8 + 12, // margin + half icon - paddingRight: 8, - borderLeft: `1px solid ${ - theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600] - }`, +const overridesResolver = (props, styles) => { + const { styleProps } = props; + + return deepmerge( + { + ...(styleProps.last && styles.last), + [`& .${stepContentClasses.transition}`]: styles.transition, + }, + styles.root || {}, + ); +}; + +const useUtilityClasses = (styleProps) => { + const { classes, last } = styleProps; + + const slots = { root: ['root', last && 'last'], transition: ['transition'] }; + + return composeClasses(slots, getStepContentUtilityClass, classes); +}; + +const StepContentRoot = experimentalStyled( + 'div', + {}, + { + name: 'MuiStepContent', + slot: 'Root', + overridesResolver, }, +)(({ styleProps, theme }) => ({ + /* Styles applied to the root element. */ + marginLeft: 12, // half icon + paddingLeft: 8 + 12, // margin + half icon + paddingRight: 8, + borderLeft: `1px solid ${ + theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600] + }`, /* Styles applied to the root element if `last={true}` (controlled by `Step`). */ - last: { + ...(styleProps.last && { borderLeft: 'none', + }), +})); + +/* Styles applied to the Transition component. */ +const StepContentTransition = experimentalStyled( + Collapse, + {}, + { + name: 'MuiStepContent', + slot: 'Transition', + overridesResolver, }, - /* Styles applied to the Transition component. */ - transition: {}, -}); +)(); -const StepContent = React.forwardRef(function StepContent(props, ref) { +const StepContent = React.forwardRef(function StepContent(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'MuiStepContent' }); const { children, - classes, className, TransitionComponent = Collapse, transitionDuration: transitionDurationProp = 'auto', @@ -38,6 +77,9 @@ const StepContent = React.forwardRef(function StepContent(props, ref) { const { orientation } = React.useContext(StepperContext); const { active, last, expanded } = React.useContext(StepContext); + const styleProps = { ...props, last }; + const classes = useUtilityClasses(styleProps); + if (process.env.NODE_ENV !== 'production') { if (orientation !== 'vertical') { console.error( @@ -53,17 +95,24 @@ const StepContent = React.forwardRef(function StepContent(props, ref) { } return ( -
- + {children} - -
+ + ); }); @@ -84,6 +133,10 @@ StepContent.propTypes = { * @ignore */ className: PropTypes.string, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, /** * The component used for the transition. * [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. @@ -113,4 +166,4 @@ StepContent.propTypes = { TransitionProps: PropTypes.object, }; -export default withStyles(styles, { name: 'MuiStepContent' })(StepContent); +export default StepContent; diff --git a/packages/material-ui/src/StepContent/StepContent.test.js b/packages/material-ui/src/StepContent/StepContent.test.js index f1065be2196370..3c695155472b64 100644 --- a/packages/material-ui/src/StepContent/StepContent.test.js +++ b/packages/material-ui/src/StepContent/StepContent.test.js @@ -1,21 +1,16 @@ import * as React from 'react'; import { expect } from 'chai'; -import { getClasses, createClientRender, createMount, describeConformance } from 'test/utils'; -import { collapseClasses } from '../Collapse'; -import Stepper from '../Stepper'; -import Step from '../Step'; -import StepContent from './StepContent'; +import { createClientRender, createMount, describeConformanceV5 } from 'test/utils'; +import { collapseClasses } from '@material-ui/core/Collapse'; +import Stepper from '@material-ui/core/Stepper'; +import Step from '@material-ui/core/Step'; +import StepContent, { stepContentClasses as classes } from '@material-ui/core/StepContent'; describe('', () => { - let classes; - const mount = createMount({ strict: true }); const render = createClientRender(); + const mount = createMount({ strict: true }); - before(() => { - classes = getClasses(); - }); - - describeConformance(, () => ({ + describeConformanceV5(, () => ({ classes, inheritComponent: 'div', mount: (node) => { @@ -26,8 +21,17 @@ describe('', () => { ); return wrapper.find(Step).childAt(0).childAt(0).childAt(0); }, + muiName: 'MuiStepContent', refInstanceof: window.HTMLDivElement, - skip: ['componentProp', 'reactTestRenderer'], + render: (node) => { + const { container, ...rest } = render( + + {node} + , + ); + return { container: container.firstChild.firstChild, ...rest }; + }, + skip: ['componentProp', 'componentsProp', 'themeVariants', 'reactTestRenderer'], })); it('renders children inside an Collapse component', () => { diff --git a/packages/material-ui/src/StepContent/index.d.ts b/packages/material-ui/src/StepContent/index.d.ts index 6da9b436ed4cf2..13daa5038a9a04 100644 --- a/packages/material-ui/src/StepContent/index.d.ts +++ b/packages/material-ui/src/StepContent/index.d.ts @@ -1,2 +1,5 @@ export { default } from './StepContent'; export * from './StepContent'; + +export { default as stepContentClasses } from './stepContentClasses'; +export * from './stepContentClasses'; diff --git a/packages/material-ui/src/StepContent/index.js b/packages/material-ui/src/StepContent/index.js index fbc65ed33640a4..d0fb5c7da6b77d 100644 --- a/packages/material-ui/src/StepContent/index.js +++ b/packages/material-ui/src/StepContent/index.js @@ -1 +1,4 @@ export { default } from './StepContent'; + +export { default as stepContentClasses } from './stepContentClasses'; +export * from './stepContentClasses'; diff --git a/packages/material-ui/src/StepContent/stepContentClasses.d.ts b/packages/material-ui/src/StepContent/stepContentClasses.d.ts new file mode 100644 index 00000000000000..f88f388ef70ab4 --- /dev/null +++ b/packages/material-ui/src/StepContent/stepContentClasses.d.ts @@ -0,0 +1,7 @@ +import { StepContentClasskey } from './StepContent'; + +declare const stepContentClasses: Record; + +export function getStepContentUtilityClass(slot: string): string; + +export default stepContentClasses; diff --git a/packages/material-ui/src/StepContent/stepContentClasses.js b/packages/material-ui/src/StepContent/stepContentClasses.js new file mode 100644 index 00000000000000..1218d59f2cd403 --- /dev/null +++ b/packages/material-ui/src/StepContent/stepContentClasses.js @@ -0,0 +1,9 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getStepContentUtilityClass(slot) { + return generateUtilityClass('MuiStepContent', slot); +} + +const stepContentClasses = generateUtilityClasses('MuiStepContent', ['root', 'last', 'transition']); + +export default stepContentClasses; diff --git a/packages/material-ui/src/Stepper/Stepper.test.js b/packages/material-ui/src/Stepper/Stepper.test.js index 817b4aa826060e..2e1d8659f96743 100644 --- a/packages/material-ui/src/Stepper/Stepper.test.js +++ b/packages/material-ui/src/Stepper/Stepper.test.js @@ -4,7 +4,7 @@ import { getClasses, createMount, createClientRender, describeConformance } from import Step, { stepClasses } from '@material-ui/core/Step'; import StepLabel from '@material-ui/core/StepLabel'; import StepConnector, { stepConnectorClasses } from '@material-ui/core/StepConnector'; -import StepContent from '@material-ui/core/StepContent'; +import StepContent, { stepContentClasses } from '@material-ui/core/StepContent'; import Stepper from '@material-ui/core/Stepper'; describe('', () => { @@ -267,8 +267,6 @@ describe('', () => { , ); - const stepContentClasses = getClasses(); - const stepContent = container.querySelectorAll(`.${stepContentClasses.root}`); expect(stepContent[0]).not.to.have.class(stepContentClasses.last);