diff --git a/components/progress/Circle.tsx b/components/progress/Circle.tsx new file mode 100644 index 0000000000..6aa7520d98 --- /dev/null +++ b/components/progress/Circle.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; +import { Circle as RCCircle } from 'rc-progress'; +import { validProgress } from './utils'; +import { ProgressProps } from './progress'; + +interface CircleProps extends ProgressProps { + prefixCls: string; + children: React.ReactNode; + progressStatus: string; +} + +const statusColorMap: Record = { + normal: '#108ee9', + exception: '#ff5500', + success: '#87d068', +}; + +function getPercentage({ percent, successPercent }: CircleProps) { + const ptg = validProgress(percent); + if (!successPercent) return ptg; + + const successPtg = validProgress(successPercent); + return [successPercent, validProgress(ptg - successPtg)]; +} + +function getStrokeColor({ progressStatus, successPercent, strokeColor }: CircleProps) { + const color = strokeColor || statusColorMap[progressStatus]; + if (!successPercent) return color; + return [statusColorMap.success, color]; +} + +const Circle: React.SFC = props => { + const { + prefixCls, + width, + strokeWidth, + trailColor, + strokeLinecap, + gapPosition, + gapDegree, + type, + children, + } = props; + const circleSize = width || 120; + const circleStyle = { + width: circleSize, + height: circleSize, + fontSize: circleSize * 0.15 + 6, + }; + const circleWidth = strokeWidth || 6; + const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top'; + const gapDeg = gapDegree || (type === 'dashboard' && 75); + + return ( +
+ + {children} +
+ ); +}; + +export default Circle; diff --git a/components/progress/Line.tsx b/components/progress/Line.tsx new file mode 100644 index 0000000000..01f21e0fce --- /dev/null +++ b/components/progress/Line.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import { validProgress } from './utils'; +import { ProgressProps } from './progress'; + +interface LineProps extends ProgressProps { + prefixCls: string; + children: React.ReactNode; +} + +const Line: React.SFC = props => { + const { + prefixCls, + percent, + successPercent, + strokeWidth, + size, + strokeColor, + strokeLinecap, + children, + } = props; + const percentStyle = { + width: `${validProgress(percent)}%`, + height: strokeWidth || (size === 'small' ? 6 : 8), + background: strokeColor, + borderRadius: strokeLinecap === 'square' ? 0 : '100px', + }; + const successPercentStyle = { + width: `${validProgress(successPercent)}%`, + height: strokeWidth || (size === 'small' ? 6 : 8), + borderRadius: strokeLinecap === 'square' ? 0 : '100px', + }; + const successSegment = + successPercent !== undefined ? ( +
+ ) : null; + return ( +
+
+
+
+ {successSegment} +
+
+ {children} +
+ ); +}; + +export default Line; diff --git a/components/progress/__tests__/__snapshots__/demo.test.js.snap b/components/progress/__tests__/__snapshots__/demo.test.js.snap index b650063732..1380be49e8 100644 --- a/components/progress/__tests__/__snapshots__/demo.test.js.snap +++ b/components/progress/__tests__/__snapshots__/demo.test.js.snap @@ -20,8 +20,9 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = ` a 47,47 0 1 1 0,-94" fill-opacity="0" stroke="#f3f3f3" + stroke-linecap="round" stroke-width="6" - style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s" + 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" /> -
-
+
+
+
-
+ class="ant-progress-inner" + > +
+
+
+ + 60% +
- +
+
- 60% - + + + + + + + 60% + +
+
+
+
+ + + + + + + 60% + +
`; diff --git a/components/progress/__tests__/__snapshots__/index.test.js.snap b/components/progress/__tests__/__snapshots__/index.test.js.snap index adf9a94b8f..6f6c97f2c1 100644 --- a/components/progress/__tests__/__snapshots__/index.test.js.snap +++ b/components/progress/__tests__/__snapshots__/index.test.js.snap @@ -221,8 +221,9 @@ exports[`Progress render strokeColor 1`] = ` a 47,47 0 1 1 0,-94" fill-opacity="0" stroke="#f3f3f3" + stroke-linecap="round" stroke-width="6" - style="stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px;" + style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px;" /> - - , +
+ + + + + + + + + + + +
, mountNode ); ```` diff --git a/components/progress/index.en-US.md b/components/progress/index.en-US.md index 7acd7739cb..b56daa5964 100644 --- a/components/progress/index.en-US.md +++ b/components/progress/index.en-US.md @@ -27,6 +27,6 @@ If it will take a long time to complete an operation, you can use `Progress` to | strokeWidth `(type=circle)` | to set the width of the circular progress bar, unit: percentage of the canvas width | number | 6 | | strokeLinecap | to set the style of the progress linecap | Enum{ 'round', 'square' } | `round` | | strokeColor | color of progress bar | string | - | -| successPercent | segmented success percent, works when `type="line"` | number | 0 | +| successPercent | segmented success percent | number | 0 | | type | to set the type, options: `line` `circle` `dashboard` | string | `line` | | width `(type=circle)` | to set the canvas width of the circular progress bar, unit: `px` | number | 132 | diff --git a/components/progress/index.zh-CN.md b/components/progress/index.zh-CN.md index aa23458624..5c958e42c4 100644 --- a/components/progress/index.zh-CN.md +++ b/components/progress/index.zh-CN.md @@ -28,6 +28,6 @@ title: Progress | strokeWidth `(type=circle)` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | | strokeLinecap | | Enum{ 'round', 'square' } | `round` | | strokeColor | 进度条的色彩 | string | - | -| successPercent | 已完成的分段百分比,`type="line"` 时有效 | number | 0 | +| successPercent | 已完成的分段百分比 | number | 0 | | type | 类型,可选 `line` `circle` `dashboard` | string | line | | width `(type=circle)` | 圆形进度条画布宽度,单位 px | number | 132 | diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx index 3502108bba..d73bcd4362 100644 --- a/components/progress/progress.tsx +++ b/components/progress/progress.tsx @@ -1,16 +1,12 @@ import * as PropTypes from 'prop-types'; import * as React from 'react'; -import Icon from '../icon'; -import { Circle } from 'rc-progress'; import classNames from 'classnames'; +import Icon from '../icon'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { tuple } from '../_util/type'; - -const statusColorMap: Record = { - normal: '#108ee9', - exception: '#ff5500', - success: '#87d068', -}; +import Line from './Line'; +import Circle from './Circle'; +import { validProgress } from './utils'; const ProgressTypes = tuple('line', 'circle', 'dashboard'); export type ProgressType = (typeof ProgressTypes)[number]; @@ -37,22 +33,15 @@ export interface ProgressProps { size?: ProgressSize; } -const validProgress = (progress: number | undefined) => { - if (!progress || progress < 0) { - return 0; - } else if (progress > 100) { - return 100; - } - return progress; -}; - export default class Progress extends React.Component { static defaultProps = { - type: 'line' as ProgressProps['type'], + type: 'line', percent: 0, showInfo: true, trailColor: '#f3f3f3', - size: 'default' as ProgressSize, + size: 'default', + gapDegree: 0, + strokeLinecap: 'round', }; static propTypes = { @@ -70,6 +59,27 @@ export default class Progress extends React.Component { default: PropTypes.oneOf(['default', 'small']), }; + renderProcessInfo(prefixCls: string, progressStatus: (typeof ProgressStatuses)[number]) { + const { showInfo, format, type, percent, successPercent } = this.props; + if (!showInfo) return null; + + let text; + const textFormatter = format || (percentNumber => `${percentNumber}%`); + const iconType = type === 'circle' || type === 'dashboard' ? '' : '-circle'; + if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) { + text = textFormatter(validProgress(percent), validProgress(successPercent)); + } else if (progressStatus === 'exception') { + text = ; + } else if (progressStatus === 'success') { + text = ; + } + return ( + + {text} + + ); + } + renderProgress = ({ getPrefixCls }: ConfigConsumerProps) => { const props = this.props; const { @@ -97,79 +107,22 @@ export default class Progress extends React.Component { !('status' in props) ? 'success' : status || 'normal'; - let progressInfo; let progress; - const textFormatter = format || (percentNumber => `${percentNumber}%`); - if (showInfo) { - let text; - const iconType = type === 'circle' || type === 'dashboard' ? '' : '-circle'; - if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) { - text = textFormatter(validProgress(percent), validProgress(successPercent)); - } else if (progressStatus === 'exception') { - text = ; - } else if (progressStatus === 'success') { - text = ; - } - progressInfo = ( - - {text} - - ); - } + const progressInfo = this.renderProcessInfo(prefixCls, progressStatus); + // Render progress shape if (type === 'line') { - const percentStyle = { - width: `${validProgress(percent)}%`, - height: strokeWidth || (size === 'small' ? 6 : 8), - background: strokeColor, - borderRadius: strokeLinecap === 'square' ? 0 : '100px', - }; - const successPercentStyle = { - width: `${validProgress(successPercent)}%`, - height: strokeWidth || (size === 'small' ? 6 : 8), - borderRadius: strokeLinecap === 'square' ? 0 : '100px', - }; - const successSegment = - successPercent !== undefined ? ( -
- ) : null; progress = ( -
-
-
-
- {successSegment} -
-
+ {progressInfo} -
+ ); } else if (type === 'circle' || type === 'dashboard') { - const circleSize = width || 120; - const circleStyle = { - width: circleSize, - height: circleSize, - fontSize: circleSize * 0.15 + 6, - }; - const circleWidth = strokeWidth || 6; - const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top'; - const gapDeg = gapDegree || (type === 'dashboard' && 75); progress = ( -
- + {progressInfo} -
+ ); } diff --git a/components/progress/utils.ts b/components/progress/utils.ts new file mode 100644 index 0000000000..502f0fb2a5 --- /dev/null +++ b/components/progress/utils.ts @@ -0,0 +1,8 @@ +export function validProgress(progress: number | undefined) { + if (!progress || progress < 0) { + return 0; + } else if (progress > 100) { + return 100; + } + return progress; +}; \ No newline at end of file diff --git a/package.json b/package.json index c480903fec..075b56bafe 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "rc-menu": "~7.4.12", "rc-notification": "~3.3.0", "rc-pagination": "~1.17.7", - "rc-progress": "~2.2.6", + "rc-progress": "~2.3.0", "rc-rate": "~2.5.0", "rc-select": "^8.6.7", "rc-slider": "~8.6.3",