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 StepLabel to emotion #25372

Merged
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
5 changes: 3 additions & 2 deletions docs/pages/api-docs/step-label.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"icon": { "type": { "name": "node" } },
"optional": { "type": { "name": "node" } },
"StepIconComponent": { "type": { "name": "elementType" } },
"StepIconProps": { "type": { "name": "object" } }
"StepIconProps": { "type": { "name": "object" } },
"sx": { "type": { "name": "object" } }
},
"name": "StepLabel",
"styles": {
Expand All @@ -31,6 +32,6 @@
"filename": "/packages/material-ui/src/StepLabel/StepLabel.js",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/steppers/\">Steppers</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
3 changes: 2 additions & 1 deletion docs/translations/api-docs/step-label/step-label.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"icon": "Override the default label of the step icon.",
"optional": "The optional node to display.",
"StepIconComponent": "The component to render in place of the <a href=\"/api/step-icon/\"><code>StepIcon</code></a>.",
"StepIconProps": "Props applied to the <a href=\"/api/step-icon/\"><code>StepIcon</code></a> element."
"StepIconProps": "Props applied to the <a href=\"/api/step-icon/\"><code>StepIcon</code></a> element.",
"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
11 changes: 4 additions & 7 deletions packages/material-ui/src/Step/Step.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import * as React from 'react';
import { expect } from 'chai';
import { getClasses, createMount, createClientRender, describeConformanceV5 } from 'test/utils';
import Step from './Step';
import Stepper from '../Stepper';
import StepLabel from '../StepLabel';
import StepButton from '../StepButton';
import classes from './stepClasses';
import Step, { stepClasses as classes } from '@material-ui/core/Step';
import Stepper from '@material-ui/core/Stepper';
import StepLabel, { stepLabelClasses } from '@material-ui/core/StepLabel';
import StepButton from '@material-ui/core/StepButton';

describe('<Step />', () => {
let stepButtonClasses;
let stepLabelClasses;
const render = createClientRender();
const mount = createMount();

before(() => {
stepButtonClasses = getClasses(<StepButton />);
stepLabelClasses = getClasses(<StepLabel />);
});

describeConformanceV5(<Step />, () => ({
Expand Down
10 changes: 4 additions & 6 deletions packages/material-ui/src/StepButton/StepButton.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ import { expect } from 'chai';
import { spy } from 'sinon';
import { getClasses, createMount, createClientRender, describeConformance } from 'test/utils';
import { fireEvent } from '@testing-library/dom';
import StepButton from './StepButton';
import Step from '../Step';
import StepLabel from '../StepLabel';
import ButtonBase from '../ButtonBase';
import StepButton from '@material-ui/core/StepButton';
import Step from '@material-ui/core/Step';
import StepLabel, { stepLabelClasses } from '@material-ui/core/StepLabel';
import ButtonBase from '@material-ui/core/ButtonBase';

describe('<StepButton />', () => {
let classes;
let stepLabelClasses;
const render = createClientRender();

before(() => {
classes = getClasses(<StepButton />);
stepLabelClasses = getClasses(<StepLabel />);
});

describe('internals', () => {
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui/src/StepLabel/StepLabel.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import { SxProps } from '@material-ui/system';
import { InternalStandardProps as StandardProps } from '..';
import { StepIconProps } from '../StepIcon';
import { Theme } from '../styles';

export interface StepLabelProps extends StandardProps<React.HTMLAttributes<HTMLDivElement>> {
/**
Expand Down Expand Up @@ -55,6 +57,10 @@ export interface StepLabelProps extends StandardProps<React.HTMLAttributes<HTMLD
* Props applied to the [`StepIcon`](/api/step-icon/) element.
*/
StepIconProps?: Partial<StepIconProps>;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
}

export type StepLabelClasskey = keyof NonNullable<StepLabelProps['classes']>;
Expand Down
237 changes: 151 additions & 86 deletions packages/material-ui/src/StepLabel/StepLabel.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,147 @@
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 experimentalStyled from '../styles/experimentalStyled';
import useThemeProps from '../styles/useThemeProps';
import Typography from '../Typography';
import StepIcon from '../StepIcon';
import StepperContext from '../Stepper/StepperContext';
import StepContext from '../Step/StepContext';
import stepLabelClasses, { getStepLabelUtilityClass } from './stepLabelClasses';

export const styles = (theme) => ({
/* Styles applied to the root element. */
root: {
display: 'flex',
alignItems: 'center',
'&$alternativeLabel': {
flexDirection: 'column',
},
'&$disabled': {
cursor: 'default',
const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(
{
...styles[styleProps.orientation],
[`& .${stepLabelClasses.label}`]: styles.label,
[`& .${stepLabelClasses.iconContainer}`]: styles.iconContainer,
[`& .${stepLabelClasses.labelContainer}`]: styles.labelContainer,
},
styles.root || {},
);
};

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

const slots = {
root: [
'root',
orientation,
error && 'error',
disabled && 'disabled',
alternativeLabel && 'alternativeLabel',
],
label: [
'label',
active && 'active',
completed && 'completed',
error && 'error',
disabled && 'disabled',
alternativeLabel && 'alternativeLabel',
],
iconContainer: ['iconContainer', alternativeLabel && 'alternativeLabel'],
labelContainer: ['labelContainer'],
};

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

const StepLabelRoot = experimentalStyled(
'span',
{},
{
name: 'MuiStepLabel',
slot: 'Root',
overridesResolver,
},
)(({ styleProps }) => ({
/* Styles applied to the root element. */
display: 'flex',
alignItems: 'center',
[`&.${stepLabelClasses.alternativeLabel}`]: {
flexDirection: 'column',
},
[`&.${stepLabelClasses.disabled}`]: {
cursor: 'default',
},
/* Styles applied to the root element if `orientation="horizontal"`. */
horizontal: {},
/* Styles applied to the root element if `orientation="vertical"`. */
vertical: {
...(styleProps.orientation === 'vertical' && {
textAlign: 'left',
padding: '8px 0',
}),
}));

const StepLabelLabel = experimentalStyled(
Typography,
{},
{
name: 'MuiStepLabel',
slot: 'Label',
overridesResolver,
},
)(({ theme }) => ({
/* Styles applied to the Typography component that wraps `children`. */
label: {
transition: theme.transitions.create('color', {
duration: theme.transitions.duration.shortest,
}),
'&$active': {
color: theme.palette.text.primary,
fontWeight: 500,
},
'&$completed': {
color: theme.palette.text.primary,
fontWeight: 500,
},
'&$alternativeLabel': {
textAlign: 'center',
marginTop: 16,
},
'&$error': {
color: theme.palette.error.main,
},
transition: theme.transitions.create('color', {
duration: theme.transitions.duration.shortest,
}),
[`&.${stepLabelClasses.active}`]: {
color: theme.palette.text.primary,
fontWeight: 500,
},
[`&.${stepLabelClasses.completed}`]: {
color: theme.palette.text.primary,
fontWeight: 500,
},
[`&.${stepLabelClasses.alternativeLabel}`]: {
textAlign: 'center',
marginTop: 16,
},
/* Pseudo-class applied to the `Typography` component if `active={true}`. */
active: {},
/* Pseudo-class applied to the `Typography` component if `completed={true}`. */
completed: {},
/* Pseudo-class applied to the root element and `Typography` component if `error={true}`. */
error: {},
/* Pseudo-class applied to the root element and `Typography` component if `disabled={true}`. */
disabled: {},
[`&.${stepLabelClasses.error}`]: {
color: theme.palette.error.main,
},
}));

const StepLabelIconContainer = experimentalStyled(
'span',
{},
{
name: 'MuiStepLabel',
slot: 'IconContainer',
overridesResolver,
},
)(() => ({
/* Styles applied to the `icon` container element. */
iconContainer: {
flexShrink: 0, // Fix IE11 issue
display: 'flex',
paddingRight: 8,
'&$alternativeLabel': {
paddingRight: 0,
},
flexShrink: 0, // Fix IE11 issue
display: 'flex',
paddingRight: 8,
[`&.${stepLabelClasses.alternativeLabel}`]: {
paddingRight: 0,
},
/* Pseudo-class applied to the root and icon container and `Typography` if `alternativeLabel={true}`. */
alternativeLabel: {},
/* Styles applied to the container element which wraps `Typography` and `optional`. */
labelContainer: {
width: '100%',
color: theme.palette.text.secondary,
}));

const StepLabelLabelContainer = experimentalStyled(
'span',
{},
{
name: 'MuiStepLabel',
slot: 'LabelContainer',
overridesResolver,
},
});
)(({ theme }) => ({
/* Styles applied to the container element which wraps `Typography` and `optional`. */
width: '100%',
color: theme.palette.text.secondary,
}));

const StepLabel = React.forwardRef(function StepLabel(props, ref) {
const StepLabel = React.forwardRef(function StepLabel(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiStepLabel' });
const {
children,
classes,
className,
error = false,
icon: iconProp,
Expand All @@ -96,55 +161,51 @@ const StepLabel = React.forwardRef(function StepLabel(props, ref) {
StepIconComponent = StepIcon;
}

const styleProps = {
...props,
active,
alternativeLabel,
completed,
disabled,
error,
orientation,
};

const classes = useUtilityClasses(styleProps);

return (
<span
className={clsx(
classes.root,
classes[orientation],
{
[classes.disabled]: disabled,
[classes.alternativeLabel]: alternativeLabel,
[classes.error]: error,
},
className,
)}
<StepLabelRoot
className={clsx(classes.root, className)}
ref={ref}
styleProps={styleProps}
{...other}
>
{icon || StepIconComponent ? (
<span
className={clsx(classes.iconContainer, {
[classes.alternativeLabel]: alternativeLabel,
})}
>
<StepLabelIconContainer className={classes.iconContainer} styleProps={styleProps}>
<StepIconComponent
completed={completed}
active={active}
error={error}
icon={icon}
{...StepIconProps}
/>
</span>
</StepLabelIconContainer>
) : null}
<span className={classes.labelContainer}>
<StepLabelLabelContainer className={classes.labelContainer} styleProps={styleProps}>
{children ? (
<Typography
<StepLabelLabel
variant="body2"
component="span"
display="block"
className={clsx(classes.label, {
[classes.alternativeLabel]: alternativeLabel,
[classes.completed]: completed,
[classes.active]: active,
[classes.error]: error,
})}
className={classes.label}
styleProps={styleProps}
>
{children}
</Typography>
</StepLabelLabel>
) : null}
{optional}
</span>
</span>
</StepLabelLabelContainer>
</StepLabelRoot>
);
});

Expand Down Expand Up @@ -186,8 +247,12 @@ StepLabel.propTypes /* remove-proptypes */ = {
* Props applied to the [`StepIcon`](/api/step-icon/) element.
*/
StepIconProps: PropTypes.object,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
};

StepLabel.muiName = 'StepLabel';

export default withStyles(styles, { name: 'MuiStepLabel' })(StepLabel);
export default StepLabel;
Loading