Skip to content

Commit

Permalink
[Stepper] Migrate StepConnector to emotion (#25092)
Browse files Browse the repository at this point in the history
  • Loading branch information
praveenkumar-kalidass authored Mar 1, 2021
1 parent c85bc0b commit 4f7797e
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 75 deletions.
4 changes: 2 additions & 2 deletions docs/pages/api-docs/step-connector.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"props": { "classes": { "type": { "name": "object" } } },
"props": { "classes": { "type": { "name": "object" } }, "sx": { "type": { "name": "object" } } },
"name": "StepConnector",
"styles": {
"classes": [
Expand All @@ -22,6 +22,6 @@
"filename": "/packages/material-ui/src/StepConnector/StepConnector.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/steppers/\">Steppers</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"componentDescription": "",
"propDescriptions": {
"classes": "Override or extend the styles applied to the component. See <a href=\"#css\">CSS API</a> below for more details."
"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."
},
"classDescriptions": {
"root": { "description": "Styles applied to the root element." },
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/StepConnector/StepConnector.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';

export type StepConnectorIcon = React.ReactElement | string | number;

Expand Down Expand Up @@ -30,6 +32,10 @@ export interface StepConnectorProps
/** Styles applied to the root element if `orientation="vertical"`. */
lineVertical?: string;
};
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
}

export type StepConnectorClasskey = keyof NonNullable<StepConnectorProps['classes']>;
Expand Down
133 changes: 85 additions & 48 deletions packages/material-ui/src/StepConnector/StepConnector.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,114 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import { deepmerge } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import capitalize from '../utils/capitalize';
import experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import StepperContext from '../Stepper/StepperContext';
import StepContext from '../Step/StepContext';
import stepConnectorClasses, { getStepConnectorUtilityClass } from './stepConnectorClasses';

export const styles = (theme) => ({
/* Styles applied to the root element. */
root: {
flex: '1 1 auto',
const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(styles.root || {}, {
...styles[styleProps.orientation],
...(styleProps.alternativeLabel && styles.alternativeLabel),
...(styleProps.completed && styles.completed),
[`& .${stepConnectorClasses.line}`]: {
...styles.line,
...styles[`line${capitalize(styleProps.orientation)}`],
},
});
};

const useUtilityClasses = (styleProps) => {
const { classes, orientation, alternativeLabel, active, completed, disabled } = styleProps;

const slots = {
root: [
'root',
orientation,
alternativeLabel && 'alternativeLabel',
active && 'active',
completed && 'completed',
disabled && 'disabled',
],
line: ['line', `line${capitalize(orientation)}`],
};

return composeClasses(slots, getStepConnectorUtilityClass, classes);
};

const StepConnectorRoot = experimentalStyled(
'div',
{},
{
name: 'MuiStepConnector',
slot: 'Root',
overridesResolver,
},
/* Styles applied to the root element if `orientation="horizontal"`. */
horizontal: {},
)(({ styleProps }) => ({
/* Styles applied to the root element. */
flex: '1 1 auto',
/* Styles applied to the root element if `orientation="vertical"`. */
vertical: {
...(styleProps.orientation === 'vertical' && {
marginLeft: 12, // half icon
},
}),
/* Styles applied to the root element if `alternativeLabel={true}`. */
alternativeLabel: {
...(styleProps.alternativeLabel && {
position: 'absolute',
top: 8 + 4,
left: 'calc(-50% + 20px)',
right: 'calc(50% + 20px)',
}),
}));

const StepConnectorLine = experimentalStyled(
'span',
{},
{
name: 'MuiStepConnector',
slot: 'Line',
},
/* Pseudo-class applied to the root element if `active={true}`. */
active: {},
/* Pseudo-class applied to the root element if `completed={true}`. */
completed: {},
/* Pseudo-class applied to the root element if `disabled={true}`. */
disabled: {},
)(({ styleProps, theme }) => ({
/* Styles applied to the line element. */
line: {
display: 'block',
borderColor: theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600],
},
display: 'block',
borderColor: theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600],
/* Styles applied to the root element if `orientation="horizontal"`. */
lineHorizontal: {
...(styleProps.orientation === 'horizontal' && {
borderTopStyle: 'solid',
borderTopWidth: 1,
},
}),
/* Styles applied to the root element if `orientation="vertical"`. */
lineVertical: {
...(styleProps.orientation === 'vertical' && {
borderLeftStyle: 'solid',
borderLeftWidth: 1,
minHeight: 24,
},
});
}),
}));

const StepConnector = React.forwardRef(function StepConnector(props, ref) {
const { classes, className, ...other } = props;
const StepConnector = React.forwardRef(function StepConnector(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiStepConnector' });
const { className, ...other } = props;

const { alternativeLabel, orientation } = React.useContext(StepperContext);
const { alternativeLabel, orientation = 'horizontal' } = React.useContext(StepperContext);
const { active, disabled, completed } = React.useContext(StepContext);

const styleProps = { ...props, alternativeLabel, orientation, active, completed, disabled };
const classes = useUtilityClasses(styleProps);

return (
<div
className={clsx(
classes.root,
classes[orientation],
{
[classes.alternativeLabel]: alternativeLabel,
[classes.active]: active,
[classes.completed]: completed,
[classes.disabled]: disabled,
},
className,
)}
<StepConnectorRoot
className={clsx(classes.root, className)}
ref={ref}
styleProps={styleProps}
{...other}
>
<span
className={clsx(classes.line, {
[classes.lineHorizontal]: orientation === 'horizontal',
[classes.lineVertical]: orientation === 'vertical',
})}
/>
</div>
<StepConnectorLine className={classes.line} styleProps={styleProps} />
</StepConnectorRoot>
);
});

Expand All @@ -92,6 +125,10 @@ StepConnector.propTypes = {
* @ignore
*/
className: PropTypes.string,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiStepConnector' })(StepConnector);
export default StepConnector;
21 changes: 9 additions & 12 deletions packages/material-ui/src/StepConnector/StepConnector.test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createClientRender, createMount, describeConformance } from 'test/utils';
import Stepper from '../Stepper';
import Step from '../Step';
import StepConnector from './StepConnector';
import { createClientRender, createMount, describeConformanceV5 } from 'test/utils';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepConnector, { stepConnectorClasses as classes } from '@material-ui/core/StepConnector';

describe('<StepConnector />', () => {
let classes;
const mount = createMount();
const render = createClientRender();
const mount = createMount();

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

describeConformance(<StepConnector />, () => ({
describeConformanceV5(<StepConnector />, () => ({
classes,
inheritComponent: 'div',
render,
mount,
muiName: 'MuiStepConnector',
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
skip: ['componentProp', 'componentsProp', 'themeVariants'],
}));

describe('rendering', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/StepConnector/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default } from './StepConnector';
export * from './StepConnector';

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

export { default as stepConnectorClasses } from './stepConnectorClasses';
export * from './stepConnectorClasses';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { StepConnectorClasskey } from './StepConnector';

declare const stepConnectorClasses: Record<StepConnectorClasskey, string>;

export function getStepConnectorUtilityClass(slot: string): string;

export default stepConnectorClasses;
20 changes: 20 additions & 0 deletions packages/material-ui/src/StepConnector/stepConnectorClasses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getStepConnectorUtilityClass(slot) {
return generateUtilityClass('MuiStepConnector', slot);
}

const stepConnectorClasses = generateUtilityClasses('MuiStepConnector', [
'root',
'horizontal',
'vertical',
'alternativeLabel',
'active',
'completed',
'disabled',
'line',
'lineHorizontal',
'lineVertical',
]);

export default stepConnectorClasses;
12 changes: 5 additions & 7 deletions packages/material-ui/src/Stepper/Stepper.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils';
import Step, { stepClasses } from '../Step';
import StepLabel from '../StepLabel';
import StepConnector from '../StepConnector';
import StepContent from '../StepContent';
import Stepper from './Stepper';
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 Stepper from '@material-ui/core/Stepper';

describe('<Stepper />', () => {
let classes;
let stepConnectorClasses;
const mount = createMount({ strict: true });
const render = createClientRender();

before(() => {
classes = getClasses(<Stepper />);
stepConnectorClasses = getClasses(<StepConnector />);
});

describeConformance(
Expand Down
14 changes: 9 additions & 5 deletions test/utils/describeConformanceV5.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
* @param {() => ConformanceOptions} getOptions
*/
function testComponentsProp(element, getOptions) {
describe('prop: components', () => {
describe('prop components:', () => {
it('can render another root component with the `components` prop', () => {
const { mount, testComponentsRootPropWith: component = 'em' } = getOptions();

Expand All @@ -37,7 +37,7 @@ function testComponentsProp(element, getOptions) {
* @param {() => ConformanceOptions} getOptions
*/
function testThemeDefaultProps(element, getOptions) {
describe('theme: default components', () => {
describe('theme default components:', () => {
it("respect theme's defaultProps", () => {
const testProp = 'data-id';
const { muiName, render } = getOptions();
Expand Down Expand Up @@ -65,7 +65,7 @@ function testThemeDefaultProps(element, getOptions) {
* @param {() => ConformanceOptions} getOptions
*/
function testThemeStyleOverrides(element, getOptions) {
describe('theme: style overrides', () => {
describe('theme style overrides:', () => {
it("respect theme's styleOverrides custom state", function test() {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
Expand Down Expand Up @@ -187,13 +187,17 @@ function testThemeStyleOverrides(element, getOptions) {
* @param {() => ConformanceOptions} getOptions
*/
function testThemeVariants(element, getOptions) {
describe('theme: variants', () => {
describe('theme variants:', () => {
it("respect theme's variants", function test() {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
}

const { muiName, testVariantProps = {}, render } = getOptions();
const { muiName, testVariantProps, render } = getOptions();

if (!testVariantProps) {
throw new Error('missing testVariantProps');
}

const testStyle = {
marginTop: '13px',
Expand Down

0 comments on commit 4f7797e

Please sign in to comment.