Skip to content

Commit f7ad7de

Browse files
committed
feat: progress support custom line-gradiend
1 parent c250fbf commit f7ad7de

File tree

16 files changed

+389
-164
lines changed

16 files changed

+389
-164
lines changed

build/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
22
dev: {
3-
componentName: 'popover', // dev components
3+
componentName: 'progress', // dev components
44
},
55
};

components/progress/__tests__/__snapshots__/demo.test.js.snap

Lines changed: 120 additions & 65 deletions
Large diffs are not rendered by default.

components/progress/__tests__/__snapshots__/index.test.js.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ exports[`Progress render format 1`] = `
44
<div class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default">
55
<div class="ant-progress-inner" style="width: 120px; height: 120px; font-size: 24;"><svg viewBox="0 0 100 100" class="ant-progress-circle">
66
<path d="M 50,50 m 0,-47
7-
a 47,47 0 1 1 0,94
8-
a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"></path>
7+
a 47,47 0 1 1 0,94
8+
a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"></path>
99
<path d="M 50,50 m 0,-47
10-
a 47,47 0 1 1 0,94
11-
a 47,47 0 1 1 0,-94" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: red; stroke-dasharray: 147.6548547187203px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"></path>
10+
a 47,47 0 1 1 0,94
11+
a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: red; stroke-dasharray: 147.6548547187203px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"></path>
1212
</svg><span title="50%" class="ant-progress-text">50%</span></div>
1313
</div>
1414
`;
@@ -31,7 +31,7 @@ exports[`Progress render negetive successPercent 1`] = `
3131
<div class="ant-progress-outer">
3232
<div class="ant-progress-inner">
3333
<div class="ant-progress-bg" style="width: 50%; height: 8px; border-radius: 100px;"></div>
34-
<div class="ant-progress-success-bg" style="width: 0%; height: 8px; border-radius: 100px;"></div>
34+
<div class="ant-progress-success-bg" style="width: 0%; height: 8px;"></div>
3535
</div>
3636
</div><span title="50%" class="ant-progress-text">50%</span>
3737
</div>
@@ -44,7 +44,7 @@ exports[`Progress render negetive successPercent 2`] = `
4444
<div class="ant-progress-outer">
4545
<div class="ant-progress-inner">
4646
<div class="ant-progress-bg" style="width: 50%; height: 8px; border-radius: 100px;"></div>
47-
<div class="ant-progress-success-bg" style="width: 10%; height: 8px; border-radius: 100px;"></div>
47+
<div class="ant-progress-success-bg" style="width: 10%; height: 8px;"></div>
4848
</div>
4949
</div><span title="50 10" class="ant-progress-text">50 10</span>
5050
</div>

components/progress/circle.jsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,21 @@ const Circle = {
4444
const circleWidth = strokeWidth || 6;
4545
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
4646
const gapDeg = gapDegree || (type === 'dashboard' && 75);
47+
const strokeColor = getStrokeColor(props);
48+
const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]';
49+
50+
const wrapperClassName = {
51+
[`${prefixCls}-inner`]: true,
52+
[`${prefixCls}-circle-gradient`]: isGradient,
53+
};
4754

4855
return (
49-
<div class={`${prefixCls}-inner`} style={circleStyle}>
56+
<div class={wrapperClassName} style={circleStyle}>
5057
<VCCircle
5158
percent={getPercentage(props)}
5259
strokeWidth={circleWidth}
5360
trailWidth={circleWidth}
54-
strokeColor={getStrokeColor(props)}
61+
strokeColor={strokeColor}
5562
strokeLinecap={strokeLinecap}
5663
trailColor={trailColor}
5764
prefixCls={prefixCls}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<cn>
2+
#### 自定义进度条渐变色
3+
`linear-gradient` 的封装。推荐只传两种颜色。
4+
</cn>
5+
6+
<us>
7+
#### Custom line gradient
8+
A package of `linear-gradient`. It is recommended to only pass two colors.
9+
</us>
10+
11+
```tpl
12+
<template>
13+
<div>
14+
<a-progress
15+
:strokeColor="{
16+
'0%': '#108ee9',
17+
'100%': '#87d068',
18+
}"
19+
:percent="99.9"
20+
/>
21+
<a-progress
22+
:strokeColor="{
23+
from: '#108ee9',
24+
to: '#87d068',
25+
}"
26+
:percent="99.9"
27+
status="active"
28+
/>
29+
<a-progress
30+
type="circle"
31+
:strokeColor="{
32+
'0%': '#108ee9',
33+
'100%': '#87d068',
34+
}"
35+
:percent="90"
36+
/>
37+
<a-progress
38+
type="circle"
39+
:strokeColor="{
40+
'0%': '#108ee9',
41+
'100%': '#87d068',
42+
}"
43+
:percent="100"
44+
/>
45+
</div>
46+
</template>
47+
```

components/progress/demo/index.vue

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Dynamic from './dynamic.md';
99
import Dashboard from './dashboard.md';
1010
import Segment from './segment.md';
1111
import Linecap from './linecap.md';
12+
import GradientLine from './gradient-line';
1213
import CN from '../index.zh-CN.md';
1314
import US from '../index.en-US.md';
1415
@@ -40,27 +41,17 @@ export default {
4041
return (
4142
<div>
4243
<md cn={md.cn} us={md.us} />
43-
<br />
4444
<Line />
45-
<br />
4645
<Circle />
47-
<br />
4846
<LineMini />
49-
<br />
5047
<CircleMini />
51-
<br />
5248
<CircleDynamic />
53-
<br />
5449
<Format />
55-
<br />
5650
<Dynamic />
57-
<br />
5851
<Dashboard />
59-
<br />
6052
<Segment />
61-
<br />
6253
<Linecap />
63-
<br />
54+
<GradientLine />
6455
<api>
6556
<template slot="cn">
6657
<CN />

components/progress/index.en-US.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,25 @@ Properties that shared by all types.
88
| format | template function of the content | function(percent, successPercent) \| v-slot:format="percent, successPercent" | `percent => percent + '%'` |
99
| percent | to set the completion percentage | number | 0 |
1010
| showInfo | whether to display the progress value and the status icon | boolean | true |
11-
| status | to set the status of the Progress, options: `success` `exception` `active` `normal` | string | - |
11+
| status | to set the status of the Progress, options: `success` `exception` `normal` `active`(line only) | string | - |
1212
| strokeLinecap | to set the style of the progress linecap | Enum{ 'round', 'square' } | `round` |
1313
| strokeColor | color of progress bar | string | - |
1414
| successPercent | segmented success percent | number | 0 |
1515

1616
### `type="line"`
1717

18-
| Property | Description | Type | Default |
19-
| ----------- | ------------------------------------------------ | ------ | ------- |
20-
| strokeWidth | to set the width of the progress bar, unit: `px` | number | 10 |
18+
| Property | Description | Type | Default | Version |
19+
| --- | --- | --- | --- | --- |
20+
| strokeWidth | to set the width of the progress bar, unit: `px` | number | 10 | |
21+
| strokeColor | color of progress bar, render `linear-gradient` when passing an object | string \| { from: string; to: string; direction: string } | - | 1.5.0 |
2122

2223
### `type="circle"`
2324

24-
| Property | Description | Type | Default |
25-
| --- | --- | --- | --- |
26-
| width | to set the canvas width of the circular progress, unit: `px` | number | 132 |
27-
| strokeWidth | to set the width of the circular progress, unit: percentage of the canvas width | number | 6 |
25+
| Property | Description | Type | Default | Version |
26+
| --- | --- | --- | --- | --- |
27+
| width | to set the canvas width of the circular progress, unit: `px` | number | 132 | |
28+
| strokeWidth | to set the width of the circular progress, unit: percentage of the canvas width | number | 6 | |
29+
| strokeColor | color of circular progress, render `linear-gradient` when passing an object | string \| object | - | 1.5.0 |
2830

2931
### `type="dashboard"`
3032

components/progress/index.zh-CN.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,25 @@
88
| format | 内容的模板函数 | function(percent, successPercent) \| v-slot:format="percent, successPercent" | `percent => percent + '%'` |
99
| percent | 百分比 | number | 0 |
1010
| showInfo | 是否显示进度数值或状态图标 | boolean | true |
11-
| status | 状态,可选:`success` `exception` `active` `normal` | string | - |
11+
| status | 状态,可选:`success` `exception` `normal` `active`(仅限 line) | string | - |
1212
| strokeLinecap | | Enum{ 'round', 'square' } | `round` |
1313
| strokeColor | 进度条的色彩 | string | - |
1414
| successPercent | 已完成的分段百分比 | number | 0 |
1515

1616
### `type="line"`
1717

18-
| 属性 | 说明 | 类型 | 默认值 |
19-
| ----------- | ----------------------- | ------ | ------ |
20-
| strokeWidth | 进度条线的宽度,单位 px | number | 10 |
18+
| 属性 | 说明 | 类型 | 默认值 | 版本 |
19+
| --- | --- | --- | --- | --- |
20+
| strokeWidth | 进度条线的宽度,单位 px | number | 10 | |
21+
| strokeColor | 进度条的色彩,传入 object 时为渐变 | string \| { from: string; to: string; direction: string } | - | 1.5.0 |
2122

2223
### `type="circle"`
2324

24-
| 属性 | 说明 | 类型 | 默认值 |
25-
| ----------- | ------------------------------------------------ | ------ | ------ |
26-
| width | 圆形进度条画布宽度,单位 px | number | 132 |
27-
| strokeWidth | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 |
25+
| 属性 | 说明 | 类型 | 默认值 | 版本 |
26+
| --- | --- | --- | --- | --- |
27+
| width | 圆形进度条画布宽度,单位 px | number | 132 | |
28+
| strokeWidth | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | |
29+
| strokeColor | 圆形进度条线的色彩,传入 object 时为渐变 | string \| object | - | 1.5.0 |
2830

2931
### `type="dashboard"`
3032

components/progress/line.jsx

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
import { validProgress } from './utils';
22

3+
/**
4+
* {
5+
* '0%': '#afc163',
6+
* '75%': '#009900',
7+
* '50%': 'green', ====> '#afc163 0%, #66FF00 25%, #00CC00 50%, #009900 75%, #ffffff 100%'
8+
* '25%': '#66FF00',
9+
* '100%': '#ffffff'
10+
* }
11+
*/
12+
export const sortGradient = gradients => {
13+
let tempArr = [];
14+
// eslint-disable-next-line no-restricted-syntax
15+
for (const [key, value] of Object.entries(gradients)) {
16+
const formatKey = parseFloat(key.replace(/%/g, ''));
17+
if (isNaN(formatKey)) {
18+
return {};
19+
}
20+
tempArr.push({
21+
key: formatKey,
22+
value,
23+
});
24+
}
25+
tempArr = tempArr.sort((a, b) => a.key - b.key);
26+
return tempArr.map(({ key, value }) => `${value} ${key}%`).join(', ');
27+
};
28+
29+
/**
30+
* {
31+
* '0%': '#afc163',
32+
* '25%': '#66FF00',
33+
* '50%': '#00CC00', ====> linear-gradient(to right, #afc163 0%, #66FF00 25%,
34+
* '75%': '#009900', #00CC00 50%, #009900 75%, #ffffff 100%)
35+
* '100%': '#ffffff'
36+
* }
37+
*
38+
* Then this man came to realize the truth:
39+
* Besides six pence, there is the moon.
40+
* Besides bread and butter, there is the bug.
41+
* And...
42+
* Besides women, there is the code.
43+
*/
44+
export const handleGradient = strokeColor => {
45+
const { from = '#1890ff', to = '#1890ff', direction = 'to right', ...rest } = strokeColor;
46+
if (Object.keys(rest).length !== 0) {
47+
const sortedGradients = sortGradient(rest);
48+
return { backgroundImage: `linear-gradient(${direction}, ${sortedGradients})` };
49+
}
50+
return { backgroundImage: `linear-gradient(${direction}, ${from}, ${to})` };
51+
};
52+
353
const Line = {
454
functional: true,
555
render(h, context) {
@@ -13,16 +63,25 @@ const Line = {
1363
strokeColor,
1464
strokeLinecap,
1565
} = props;
66+
let backgroundProps;
67+
if (strokeColor && typeof strokeColor !== 'string') {
68+
backgroundProps = handleGradient(strokeColor);
69+
} else {
70+
backgroundProps = {
71+
background: strokeColor,
72+
};
73+
}
1674
const percentStyle = {
1775
width: `${validProgress(percent)}%`,
1876
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
1977
background: strokeColor,
2078
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
79+
...backgroundProps,
2180
};
2281
const successPercentStyle = {
2382
width: `${validProgress(successPercent)}%`,
2483
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
25-
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
84+
borderRadius: strokeLinecap === 'square' ? 0 : '',
2685
};
2786
const successSegment =
2887
successPercent !== undefined ? (

components/progress/progress.jsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function addUnit(num, unit) {
1111
const unitType = unit || 'px';
1212
return num ? num + unitType : null;
1313
}
14-
14+
const ProgressStatuses = ['normal', 'exception', 'active', 'success'];
1515
export const ProgressType = PropTypes.oneOf(['line', 'circle', 'dashboard']);
1616
export const ProgressSize = PropTypes.oneOf(['default', 'small']);
1717

@@ -21,11 +21,11 @@ export const ProgressProps = {
2121
percent: PropTypes.number,
2222
successPercent: PropTypes.number,
2323
format: PropTypes.func,
24-
status: PropTypes.oneOf(['normal', 'success', 'active', 'exception']),
24+
status: PropTypes.oneOf(ProgressStatuses),
2525
showInfo: PropTypes.bool,
2626
strokeWidth: PropTypes.number,
27-
strokeLinecap: PropTypes.oneOf(['round', 'square']),
28-
strokeColor: PropTypes.string,
27+
strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
28+
strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
2929
trailColor: PropTypes.string,
3030
width: PropTypes.number,
3131
gapDegree: PropTypes.number,
@@ -48,6 +48,21 @@ export default {
4848
configProvider: { default: () => ConfigConsumerProps },
4949
},
5050
methods: {
51+
getPercentNumber() {
52+
const { successPercent, percent = 0 } = this.$props;
53+
return parseInt(
54+
successPercent !== undefined ? successPercent.toString() : percent.toString(),
55+
10,
56+
);
57+
},
58+
59+
getProgressStatus() {
60+
const { status } = this.$props;
61+
if (ProgressStatuses.indexOf(status) < 0 && this.getPercentNumber() >= 100) {
62+
return 'success';
63+
}
64+
return status || 'normal';
65+
},
5166
renderProcessInfo(prefixCls, progressStatus) {
5267
const { showInfo, format, type, percent, successPercent } = this.$props;
5368
if (!showInfo) return null;
@@ -96,14 +111,10 @@ export default {
96111
} = props;
97112
const getPrefixCls = this.configProvider.getPrefixCls;
98113
const prefixCls = getPrefixCls('progress', customizePrefixCls);
114+
const progressStatus = this.getProgressStatus();
115+
const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
99116

100-
const progressStatus =
101-
parseInt(successPercent !== undefined ? successPercent.toString() : percent.toString(), 10) >=
102-
100 && !('status' in props)
103-
? 'success'
104-
: status || 'normal';
105117
let progress;
106-
const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
107118

108119
// Render progress shape
109120
if (type === 'line') {

0 commit comments

Comments
 (0)