Skip to content

Commit edb2d63

Browse files
authored
[Stepper] Always pass state props to connector (mui#21370)
1 parent 9d5598b commit edb2d63

File tree

3 files changed

+71
-47
lines changed

3 files changed

+71
-47
lines changed

packages/material-ui/src/Step/Step.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const Step = React.forwardRef(function Step(props, ref) {
3333
className,
3434
completed = false,
3535
// eslint-disable-next-line react/prop-types
36-
connector,
36+
connector: connectorProp,
3737
disabled = false,
3838
expanded = false,
3939
// eslint-disable-next-line react/prop-types
@@ -45,7 +45,18 @@ const Step = React.forwardRef(function Step(props, ref) {
4545
...other
4646
} = props;
4747

48-
return (
48+
const connector = connectorProp
49+
? React.cloneElement(connectorProp, {
50+
orientation,
51+
alternativeLabel,
52+
index,
53+
active,
54+
completed,
55+
disabled,
56+
})
57+
: null;
58+
59+
const newChildren = (
4960
<div
5061
className={clsx(
5162
classes.root,
@@ -59,17 +70,7 @@ const Step = React.forwardRef(function Step(props, ref) {
5970
ref={ref}
6071
{...other}
6172
>
62-
{connector &&
63-
alternativeLabel &&
64-
index !== 0 &&
65-
React.cloneElement(connector, {
66-
orientation,
67-
alternativeLabel,
68-
index,
69-
active,
70-
completed,
71-
disabled,
72-
})}
73+
{connector && alternativeLabel && index !== 0 ? connector : null}
7374

7475
{React.Children.map(children, (child) => {
7576
if (!React.isValidElement(child)) {
@@ -101,6 +102,16 @@ const Step = React.forwardRef(function Step(props, ref) {
101102
})}
102103
</div>
103104
);
105+
106+
if (connector && !alternativeLabel && index !== 0) {
107+
return (
108+
<React.Fragment>
109+
{connector}
110+
{newChildren}
111+
</React.Fragment>
112+
);
113+
}
114+
return newChildren;
104115
});
105116

106117
Step.propTypes = {

packages/material-ui/src/Stepper/Stepper.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,6 @@ const Stepper = React.forwardRef(function Stepper(props, ref) {
4646
: null;
4747
const childrenArray = React.Children.toArray(children);
4848
const steps = childrenArray.map((step, index) => {
49-
const controlProps = {
50-
alternativeLabel,
51-
connector: connectorProp,
52-
last: index + 1 === childrenArray.length,
53-
orientation,
54-
};
55-
5649
const state = {
5750
index,
5851
active: false,
@@ -68,16 +61,14 @@ const Stepper = React.forwardRef(function Stepper(props, ref) {
6861
state.disabled = true;
6962
}
7063

71-
return [
72-
!alternativeLabel &&
73-
connector &&
74-
index !== 0 &&
75-
React.cloneElement(connector, {
76-
key: index,
77-
...state,
78-
}),
79-
React.cloneElement(step, { ...controlProps, ...state, ...step.props }),
80-
];
64+
return React.cloneElement(step, {
65+
alternativeLabel,
66+
connector,
67+
last: index + 1 === childrenArray.length,
68+
orientation,
69+
...state,
70+
...step.props,
71+
});
8172
});
8273

8374
return (

packages/material-ui/src/Stepper/Stepper.test.js

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import * as React from 'react';
22
import { expect } from 'chai';
3-
import CheckCircle from '../internal/svg-icons/CheckCircle';
43
import { createShallow, getClasses } from '@material-ui/core/test-utils';
54
import createMount from 'test/utils/createMount';
65
import describeConformance from '../test-utils/describeConformance';
6+
import { createClientRender } from 'test/utils/createClientRender';
77
import Paper from '../Paper';
88
import Step from '../Step';
99
import StepLabel from '../StepLabel';
@@ -16,6 +16,7 @@ describe('<Stepper />', () => {
1616
let shallow;
1717
// StrictModeViolation: test uses StepContent
1818
const mount = createMount({ strict: false });
19+
const render = createClientRender({ strict: false });
1920

2021
before(() => {
2122
classes = getClasses(<Stepper />);
@@ -45,20 +46,17 @@ describe('<Stepper />', () => {
4546
});
4647

4748
describe('rendering children', () => {
48-
it('renders 3 children with connectors as separators', () => {
49-
const wrapper = shallow(
49+
it('renders 3 Step and 2 StepConnector components', () => {
50+
const wrapper = mount(
5051
<Stepper>
51-
<div />
52-
<div />
53-
<div />
52+
<Step />
53+
<Step />
54+
<Step />
5455
</Stepper>,
5556
);
5657

57-
const children = wrapper.children();
58-
59-
expect(children.length).to.equal(5);
60-
expect(wrapper.childAt(1).find(StepConnector).length).to.equal(1);
61-
expect(wrapper.childAt(3).find(StepConnector).length).to.equal(1);
58+
expect(wrapper.find(StepConnector).length).to.equal(2);
59+
expect(wrapper.find(Step).length).to.equal(3);
6260
});
6361
});
6462

@@ -122,7 +120,7 @@ describe('<Stepper />', () => {
122120

123121
describe('step connector', () => {
124122
it('should have a default step connector', () => {
125-
const wrapper = shallow(
123+
const wrapper = mount(
126124
<Stepper>
127125
<Step />
128126
<Step />
@@ -133,14 +131,15 @@ describe('<Stepper />', () => {
133131
});
134132

135133
it('should allow the developer to specify a custom step connector', () => {
136-
const wrapper = shallow(
137-
<Stepper connector={<CheckCircle />}>
134+
const CustomConnector = () => null;
135+
const wrapper = mount(
136+
<Stepper connector={<CustomConnector />}>
138137
<Step />
139138
<Step />
140139
</Stepper>,
141140
);
142141

143-
expect(wrapper.find(CheckCircle).length).to.equal(1);
142+
expect(wrapper.find(CustomConnector).length).to.equal(1);
144143
expect(wrapper.find(StepConnector).length).to.equal(0);
145144
});
146145

@@ -156,7 +155,7 @@ describe('<Stepper />', () => {
156155
});
157156

158157
it('should pass active prop to connector when second step is active', () => {
159-
const wrapper = shallow(
158+
const wrapper = mount(
160159
<Stepper activeStep={1}>
161160
<Step />
162161
<Step />
@@ -167,7 +166,7 @@ describe('<Stepper />', () => {
167166
});
168167

169168
it('should pass completed prop to connector when second step is completed', () => {
170-
const wrapper = shallow(
169+
const wrapper = mount(
171170
<Stepper activeStep={2}>
172171
<Step />
173172
<Step />
@@ -176,6 +175,29 @@ describe('<Stepper />', () => {
176175
const connectors = wrapper.find(StepConnector);
177176
expect(connectors.first().props().completed).to.equal(true);
178177
});
178+
179+
it('should pass correct active and completed props to the StepConnector with nonLinear prop', () => {
180+
const steps = ['Step1', 'Step2', 'Step3'];
181+
182+
const { container } = render(
183+
<Stepper orientation="horizontal" nonLinear connector={<StepConnector />}>
184+
{steps.map((label, index) => (
185+
<Step key={label} active completed={index === 2}>
186+
<StepLabel>{label}</StepLabel>
187+
</Step>
188+
))}
189+
</Stepper>,
190+
);
191+
192+
const connectors = container.querySelectorAll('.MuiStepConnector-root');
193+
194+
expect(connectors).to.have.length(2);
195+
expect(connectors[0]).to.have.class('MuiStepConnector-active');
196+
expect(connectors[0]).to.not.have.class('MuiStepConnector-completed');
197+
198+
expect(connectors[1]).to.have.class('MuiStepConnector-active');
199+
expect(connectors[1]).to.have.class('MuiStepConnector-completed');
200+
});
179201
});
180202

181203
it('renders with a null child', () => {

0 commit comments

Comments
 (0)