Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Stepper] Migrate StepContent to emotion #25210

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/pages/api-docs/step-content.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand All @@ -23,6 +24,6 @@
"filename": "/packages/material-ui/src/StepContent/StepContent.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/steppers/\">Steppers</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/translations/api-docs/step-content/step-content.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"propDescriptions": {
"children": "The content of the component.",
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details.",
"sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/basics/#the-sx-prop\">`sx` page</a> for more details.",
"TransitionComponent": "The component used for the transition. <a href=\"/components/transitions/#transitioncomponent-prop\">Follow this guide</a> 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.<br>Set to &#39;auto&#39; to automatically calculate transition time based on height.",
"TransitionProps": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition\"><code>Transition</code></a> component."
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/StepContent/StepContent.d.ts
Original file line number Diff line number Diff line change
@@ -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<React.HTMLAttributes<HTMLDivElement>> {
Expand All @@ -18,6 +20,10 @@ export interface StepContentProps extends StandardProps<React.HTMLAttributes<HTM
/** Styles applied to the Transition component. */
transition?: string;
};
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
/**
* The component used for the transition.
* [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
Expand Down
95 changes: 74 additions & 21 deletions packages/material-ui/src/StepContent/StepContent.js
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -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(
Expand All @@ -53,17 +95,24 @@ const StepContent = React.forwardRef(function StepContent(props, ref) {
}

return (
<div className={clsx(classes.root, { [classes.last]: last }, className)} ref={ref} {...other}>
<TransitionComponent
<StepContentRoot
className={clsx(classes.root, className)}
ref={ref}
styleProps={styleProps}
{...other}
>
<StepContentTransition
as={TransitionComponent}
in={active || expanded}
className={classes.transition}
styleProps={styleProps}
timeout={transitionDuration}
unmountOnExit
{...TransitionProps}
>
{children}
</TransitionComponent>
</div>
</StepContentTransition>
</StepContentRoot>
);
});

Expand All @@ -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.
Expand Down Expand Up @@ -113,4 +166,4 @@ StepContent.propTypes = {
TransitionProps: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiStepContent' })(StepContent);
export default StepContent;
30 changes: 17 additions & 13 deletions packages/material-ui/src/StepContent/StepContent.test.js
Original file line number Diff line number Diff line change
@@ -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('<StepContent />', () => {
let classes;
const mount = createMount({ strict: true });
const render = createClientRender();
const mount = createMount({ strict: true });

before(() => {
classes = getClasses(<StepContent />);
});

describeConformance(<StepContent />, () => ({
describeConformanceV5(<StepContent />, () => ({
classes,
inheritComponent: 'div',
mount: (node) => {
Expand All @@ -26,8 +21,17 @@ describe('<StepContent />', () => {
);
return wrapper.find(Step).childAt(0).childAt(0).childAt(0);
},
muiName: 'MuiStepContent',
refInstanceof: window.HTMLDivElement,
skip: ['componentProp', 'reactTestRenderer'],
render: (node) => {
const { container, ...rest } = render(
<Stepper orientation="vertical">
<Step>{node}</Step>
</Stepper>,
);
return { container: container.firstChild.firstChild, ...rest };
},
skip: ['componentProp', 'componentsProp', 'themeVariants', 'reactTestRenderer'],
}));

it('renders children inside an Collapse component', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/StepContent/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default } from './StepContent';
export * from './StepContent';

export { default as stepContentClasses } from './stepContentClasses';
export * from './stepContentClasses';
3 changes: 3 additions & 0 deletions packages/material-ui/src/StepContent/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export { default } from './StepContent';

export { default as stepContentClasses } from './stepContentClasses';
export * from './stepContentClasses';
7 changes: 7 additions & 0 deletions packages/material-ui/src/StepContent/stepContentClasses.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { StepContentClasskey } from './StepContent';

declare const stepContentClasses: Record<StepContentClasskey, string>;

export function getStepContentUtilityClass(slot: string): string;

export default stepContentClasses;
9 changes: 9 additions & 0 deletions packages/material-ui/src/StepContent/stepContentClasses.js
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 1 addition & 3 deletions packages/material-ui/src/Stepper/Stepper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<Stepper />', () => {
Expand Down Expand Up @@ -267,8 +267,6 @@ describe('<Stepper />', () => {
</Stepper>,
);

const stepContentClasses = getClasses(<StepContent />);

const stepContent = container.querySelectorAll(`.${stepContentClasses.root}`);

expect(stepContent[0]).not.to.have.class(stepContentClasses.last);
Expand Down