Skip to content

Commit ca43852

Browse files
committed
support custon finish icon & error icon
1 parent 9e62045 commit ca43852

File tree

7 files changed

+288
-4
lines changed

7 files changed

+288
-4
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ online example: http://react-component.github.io/steps/examples/
8686
<td>wait</td>
8787
<td>status of current Steps, could be `error` `process` `finish` `wait`</td>
8888
</tr>
89+
<tr>
90+
<td>finishIcon</td>
91+
<td>ReactNode</td>
92+
<td></td>
93+
<td>spicify the finish icon</td>
94+
</tr>
95+
<tr>
96+
<td>errorIcon</td>
97+
<td>ReactNode</td>
98+
<td></td>
99+
<td>spicify the error icon</td>
100+
</tr>
89101
</tbody>
90102
</table>
91103

examples/custom-svg-icon.html

Whitespace-only changes.

examples/custom-svg-icon.jsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import Steps, { Step } from 'rc-steps';
4+
5+
function getFinishIcon() {
6+
const path = 'M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.' +
7+
'5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139' +
8+
'.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5' +
9+
'-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 ' +
10+
'55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33' +
11+
'.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99' +
12+
'.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.' +
13+
'7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 10' +
14+
'1.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 ' +
15+
'20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z';
16+
return (
17+
<svg
18+
width="1em"
19+
height="1em"
20+
fill="currentColor"
21+
viewBox="0 0 1024 1024"
22+
style={{ verticalAlign: '-.125em' }}
23+
>
24+
<path d={path} />
25+
</svg>
26+
);
27+
}
28+
29+
function getErrorIcon() {
30+
const path1 = 'M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229' +
31+
'.2 512-512S794.8 0 512 0zm311.1 823.1c-40.4 40.4-87.5 72.2-139.9 9' +
32+
'4.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99' +
33+
'.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.' +
34+
'4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-4' +
35+
'0.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72s117 11.6 171.2 3' +
36+
'4.5c52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C' +
37+
'940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 9' +
38+
'9.5-94.4 139.9z';
39+
const path2 = 'M640.3 765.5c-19.9 0-36-16.1-36-36 0-50.9-41.4-92.3-92' +
40+
'.3-92.3s-92.3 41.4-92.3 92.3c0 19.9-16.1 36-36 36s-36-16.1-36-36c0' +
41+
'-90.6 73.7-164.3 164.3-164.3s164.3 73.7 164.3 164.3c0 19.9-16.1 36' +
42+
'-36 36zM194.2 382.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0zM709.5 382' +
43+
'.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0z';
44+
return (
45+
<svg
46+
width="1em"
47+
height="1em"
48+
fill="currentColor"
49+
viewBox="0 0 1024 1024"
50+
style={{ verticalAlign: '-.125em' }}
51+
>
52+
<path d={path1} />
53+
<path d={path2} />
54+
</svg>
55+
);
56+
}
57+
58+
ReactDOM.render(
59+
<Steps current={1} status="error" finishIcon={getFinishIcon()} errorIcon={getErrorIcon()}>
60+
<Step title="Finished" description="This is a description" />
61+
<Step title="In Process" description="This is a description" />
62+
<Step title="Waiting" description="This is a description" />
63+
</Steps>
64+
, document.getElementById('__react-content'));

src/Step.jsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ export default class Step extends React.Component {
3131
PropTypes.func,
3232
]),
3333
tailContent: PropTypes.any,
34+
finishIcon: PropTypes.node,
35+
errorIcon: PropTypes.node,
3436
};
3537
renderIconNode() {
3638
const {
3739
prefixCls, progressDot, stepNumber, status, title, description, icon,
38-
iconPrefix,
40+
iconPrefix, finishIcon, errorIcon,
3941
} = this.props;
4042
let iconNode;
4143
const iconClassName = classNames(`${prefixCls}-icon`, `${iconPrefix}icon`, {
4244
[`${iconPrefix}icon-${icon}`]: icon && isString(icon),
43-
[`${iconPrefix}icon-check`]: !icon && status === 'finish',
44-
[`${iconPrefix}icon-cross`]: !icon && status === 'error',
45+
[`${iconPrefix}icon-check`]: !icon && status === 'finish' && !finishIcon,
46+
[`${iconPrefix}icon-close`]: !icon && status === 'error' && !errorIcon,
4547
});
4648
const iconDot = <span className={`${prefixCls}-icon-dot`}></span>;
4749
// `progressDot` enjoy the highest priority
@@ -57,11 +59,16 @@ export default class Step extends React.Component {
5759
}
5860
} else if (icon && !isString(icon)) {
5961
iconNode = <span className={`${prefixCls}-icon`}>{icon}</span>;
62+
} else if (finishIcon && status === 'finish') {
63+
iconNode = <span className={`${prefixCls}-icon`}>{finishIcon}</span>;
64+
} else if (errorIcon && status === 'error') {
65+
iconNode = <span className={`${prefixCls}-icon`}>{errorIcon}</span>;
6066
} else if (icon || status === 'finish' || status === 'error') {
6167
iconNode = <span className={iconClassName} />;
6268
} else {
6369
iconNode = <span className={`${prefixCls}-icon`}>{stepNumber}</span>;
6470
}
71+
6572
return iconNode;
6673
}
6774
render() {
@@ -70,6 +77,7 @@ export default class Step extends React.Component {
7077
status = 'wait', iconPrefix, icon, wrapperStyle,
7178
adjustMarginRight, stepNumber,
7279
description, title, progressDot, tailContent,
80+
finishIcon, errorIcon,
7381
...restProps,
7482
} = this.props;
7583

src/Steps.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export default class Steps extends Component {
2323
style: PropTypes.object,
2424
initial: PropTypes.number,
2525
current: PropTypes.number,
26+
finishIcon: PropTypes.node,
27+
errorIcon: PropTypes.node,
2628
};
2729
static defaultProps = {
2830
prefixCls: 'rc-steps',
@@ -88,6 +90,7 @@ export default class Steps extends Component {
8890
const {
8991
prefixCls, style = {}, className, children, direction,
9092
labelPlacement, iconPrefix, status, size, current, progressDot, initial,
93+
finishIcon, errorIcon,
9194
...restProps,
9295
} = this.props;
9396
const { lastStepOffsetWidth, flexSupported } = this.state;
@@ -114,6 +117,8 @@ export default class Steps extends Component {
114117
iconPrefix,
115118
wrapperStyle: style,
116119
progressDot,
120+
finishIcon,
121+
errorIcon,
117122
...child.props,
118123
};
119124
if (!flexSupported && direction !== 'vertical' && index !== lastIndex) {

tests/__snapshots__/index.test.js.snap

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ exports[`Steps render renders status correctly 1`] = `
669669
class="rc-steps-item-icon"
670670
>
671671
<span
672-
class="rc-steps-icon rcicon rcicon-cross"
672+
class="rc-steps-icon rcicon rcicon-close"
673673
>
674674
675675
</span>
@@ -1370,3 +1370,135 @@ exports[`Steps render renders with fasly children 1`] = `
13701370
</div>
13711371
</div>
13721372
`;
1373+
1374+
exports[`Steps render should render svg finishIcon and errorIcon correctly 1`] = `
1375+
<div
1376+
class="rc-steps rc-steps-horizontal rc-steps-label-horizontal"
1377+
>
1378+
<div
1379+
class="rc-steps-item rc-steps-item-finish rc-steps-next-error"
1380+
>
1381+
<div
1382+
class="rc-steps-item-tail"
1383+
>
1384+
1385+
</div>
1386+
<div
1387+
class="rc-steps-item-icon"
1388+
>
1389+
<span
1390+
class="rc-steps-icon"
1391+
>
1392+
<svg
1393+
fill="currentColor"
1394+
height="1em"
1395+
style="vertical-align:-.125em"
1396+
viewBox="0 0 1024 1024"
1397+
width="1em"
1398+
>
1399+
<path
1400+
d="M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z"
1401+
>
1402+
1403+
</path>
1404+
</svg>
1405+
</span>
1406+
</div>
1407+
<div
1408+
class="rc-steps-item-content"
1409+
>
1410+
<div
1411+
class="rc-steps-item-title"
1412+
>
1413+
Finished
1414+
</div>
1415+
<div
1416+
class="rc-steps-item-description"
1417+
>
1418+
This is a description
1419+
</div>
1420+
</div>
1421+
</div>
1422+
<div
1423+
class="rc-steps-item rc-steps-item-error"
1424+
>
1425+
<div
1426+
class="rc-steps-item-tail"
1427+
>
1428+
1429+
</div>
1430+
<div
1431+
class="rc-steps-item-icon"
1432+
>
1433+
<span
1434+
class="rc-steps-icon"
1435+
>
1436+
<svg
1437+
fill="currentColor"
1438+
height="1em"
1439+
style="vertical-align:-.125em"
1440+
viewBox="0 0 1024 1024"
1441+
width="1em"
1442+
>
1443+
<path
1444+
d="M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0zm311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72s117 11.6 171.2 34.5c52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 99.5-94.4 139.9z"
1445+
>
1446+
1447+
</path>
1448+
<path
1449+
d="M640.3 765.5c-19.9 0-36-16.1-36-36 0-50.9-41.4-92.3-92.3-92.3s-92.3 41.4-92.3 92.3c0 19.9-16.1 36-36 36s-36-16.1-36-36c0-90.6 73.7-164.3 164.3-164.3s164.3 73.7 164.3 164.3c0 19.9-16.1 36-36 36zM194.2 382.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0zM709.5 382.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0z"
1450+
>
1451+
1452+
</path>
1453+
</svg>
1454+
</span>
1455+
</div>
1456+
<div
1457+
class="rc-steps-item-content"
1458+
>
1459+
<div
1460+
class="rc-steps-item-title"
1461+
>
1462+
In Process
1463+
</div>
1464+
<div
1465+
class="rc-steps-item-description"
1466+
>
1467+
This is a description
1468+
</div>
1469+
</div>
1470+
</div>
1471+
<div
1472+
class="rc-steps-item rc-steps-item-wait"
1473+
>
1474+
<div
1475+
class="rc-steps-item-tail"
1476+
>
1477+
1478+
</div>
1479+
<div
1480+
class="rc-steps-item-icon"
1481+
>
1482+
<span
1483+
class="rc-steps-icon"
1484+
>
1485+
3
1486+
</span>
1487+
</div>
1488+
<div
1489+
class="rc-steps-item-content"
1490+
>
1491+
<div
1492+
class="rc-steps-item-title"
1493+
>
1494+
Waiting
1495+
</div>
1496+
<div
1497+
class="rc-steps-item-description"
1498+
>
1499+
This is a description
1500+
</div>
1501+
</div>
1502+
</div>
1503+
</div>
1504+
`;

tests/index.test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,68 @@ describe('Steps', () => {
9898
);
9999
expect(wrapper).toMatchSnapshot();
100100
});
101+
102+
function getFinishIcon() {
103+
const path = 'M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.' +
104+
'5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139' +
105+
'.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5' +
106+
'-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 ' +
107+
'55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33' +
108+
'.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99' +
109+
'.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.' +
110+
'7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 10' +
111+
'1.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 ' +
112+
'20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z';
113+
return (
114+
<svg
115+
width="1em"
116+
height="1em"
117+
fill="currentColor"
118+
viewBox="0 0 1024 1024"
119+
style={{ verticalAlign: '-.125em' }}
120+
>
121+
<path d={path} />
122+
</svg>
123+
);
124+
}
125+
126+
function getErrorIcon() {
127+
const path1 = 'M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229' +
128+
'.2 512-512S794.8 0 512 0zm311.1 823.1c-40.4 40.4-87.5 72.2-139.9 9' +
129+
'4.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99' +
130+
'.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.' +
131+
'4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-4' +
132+
'0.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72s117 11.6 171.2 3' +
133+
'4.5c52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C' +
134+
'940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 9' +
135+
'9.5-94.4 139.9z';
136+
const path2 = 'M640.3 765.5c-19.9 0-36-16.1-36-36 0-50.9-41.4-92.3-92' +
137+
'.3-92.3s-92.3 41.4-92.3 92.3c0 19.9-16.1 36-36 36s-36-16.1-36-36c0' +
138+
'-90.6 73.7-164.3 164.3-164.3s164.3 73.7 164.3 164.3c0 19.9-16.1 36' +
139+
'-36 36zM194.2 382.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0zM709.5 382' +
140+
'.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0z';
141+
return (
142+
<svg
143+
width="1em"
144+
height="1em"
145+
fill="currentColor"
146+
viewBox="0 0 1024 1024"
147+
style={{ verticalAlign: '-.125em' }}
148+
>
149+
<path d={path1} />
150+
<path d={path2} />
151+
</svg>
152+
);
153+
}
154+
it('should render svg finishIcon and errorIcon correctly', () => {
155+
const wrapper = render(
156+
<Steps current={1} status="error" finishIcon={getFinishIcon()} errorIcon={getErrorIcon()}>
157+
<Step title="Finished" description="This is a description" />
158+
<Step title="In Process" description="This is a description" />
159+
<Step title="Waiting" description="This is a description" />
160+
</Steps>
161+
);
162+
expect(wrapper).toMatchSnapshot();
163+
});
101164
});
102165
});

0 commit comments

Comments
 (0)