From 2cee6f9bef4c5eb73ca609cd8dc5822affab34d6 Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 14:14:38 +0800 Subject: [PATCH] add progress --- components/index.js | 2 + components/progress/demo/circle-dynamic.md | 48 ++++++ components/progress/demo/circle-mini.md | 28 ++++ components/progress/demo/circle.md | 27 ++++ components/progress/demo/dashboard.md | 17 +++ components/progress/demo/dynamic.md | 47 ++++++ components/progress/demo/format.md | 25 +++ components/progress/demo/index.vue | 69 +++++++++ components/progress/demo/line-mini.md | 22 +++ components/progress/demo/line.md | 22 +++ components/progress/demo/segment.md | 18 +++ components/progress/index.en-US.md | 15 ++ components/progress/index.jsx | 5 + components/progress/index.zh-CN.md | 15 ++ components/progress/progress.jsx | 135 +++++++++++++++++ components/progress/style/index.js | 2 + components/progress/style/index.less | 167 +++++++++++++++++++++ components/style.js | 1 + components/vc-progress/src/Circle.js | 10 +- examples/demo.js | 2 + examples/routes.js | 2 +- 21 files changed, 675 insertions(+), 4 deletions(-) create mode 100644 components/progress/demo/circle-dynamic.md create mode 100644 components/progress/demo/circle-mini.md create mode 100644 components/progress/demo/circle.md create mode 100644 components/progress/demo/dashboard.md create mode 100644 components/progress/demo/dynamic.md create mode 100644 components/progress/demo/format.md create mode 100644 components/progress/demo/index.vue create mode 100644 components/progress/demo/line-mini.md create mode 100644 components/progress/demo/line.md create mode 100644 components/progress/demo/segment.md create mode 100644 components/progress/index.en-US.md create mode 100644 components/progress/index.jsx create mode 100644 components/progress/index.zh-CN.md create mode 100644 components/progress/progress.jsx create mode 100644 components/progress/style/index.js create mode 100644 components/progress/style/index.less diff --git a/components/index.js b/components/index.js index 89e1c44df..e896f363f 100644 --- a/components/index.js +++ b/components/index.js @@ -140,3 +140,5 @@ export { Table, TableColumn, TableColumnGroup } export { default as version } from './version' export { default as Slider } from './slider' + +export { default as Progress } from './progress' diff --git a/components/progress/demo/circle-dynamic.md b/components/progress/demo/circle-dynamic.md new file mode 100644 index 000000000..a4bbae24a --- /dev/null +++ b/components/progress/demo/circle-dynamic.md @@ -0,0 +1,48 @@ + +#### 进度圈动态展示 +会动的进度条才是好进度条。 + + + +#### Dynamic circular progress bar +A dynamic progress bar is better. + + +```html + + +``` + + diff --git a/components/progress/demo/circle-mini.md b/components/progress/demo/circle-mini.md new file mode 100644 index 000000000..3a6c4788d --- /dev/null +++ b/components/progress/demo/circle-mini.md @@ -0,0 +1,28 @@ + +#### 小型进度圈 +小一号的圈形进度。 + + + +#### Mini size circular progress bar +A smaller circular progress bar. + + +```html + + +``` + + diff --git a/components/progress/demo/circle.md b/components/progress/demo/circle.md new file mode 100644 index 000000000..14262d59a --- /dev/null +++ b/components/progress/demo/circle.md @@ -0,0 +1,27 @@ + +#### 进度圈 +圈形的进度。 + + + +#### Circular progress bar +A circular progress bar. + + +```html + + +``` + diff --git a/components/progress/demo/dashboard.md b/components/progress/demo/dashboard.md new file mode 100644 index 000000000..a8af3fe03 --- /dev/null +++ b/components/progress/demo/dashboard.md @@ -0,0 +1,17 @@ + +#### 仪表盘 +By setting `type=dashboard`, you can get a dashboard style of progress easily. + + + +#### Dashboard +A standard progress bar. + + +```html + +``` diff --git a/components/progress/demo/dynamic.md b/components/progress/demo/dynamic.md new file mode 100644 index 000000000..2fc11e7a2 --- /dev/null +++ b/components/progress/demo/dynamic.md @@ -0,0 +1,47 @@ + +#### 动态展示 +会动的进度条才是好进度条。 + + + +#### Dynamic +A dynamic progress bar is better. + + +```html + + +``` + diff --git a/components/progress/demo/format.md b/components/progress/demo/format.md new file mode 100644 index 000000000..78ce2d577 --- /dev/null +++ b/components/progress/demo/format.md @@ -0,0 +1,25 @@ + +#### 自定义文字格式 +`format` 属性指定格式。 + + + +#### Custom text format +You can custom text format by setting `format`. + + +```html + + +``` diff --git a/components/progress/demo/index.vue b/components/progress/demo/index.vue new file mode 100644 index 000000000..132ce293c --- /dev/null +++ b/components/progress/demo/index.vue @@ -0,0 +1,69 @@ + diff --git a/components/progress/demo/line-mini.md b/components/progress/demo/line-mini.md new file mode 100644 index 000000000..8ab918057 --- /dev/null +++ b/components/progress/demo/line-mini.md @@ -0,0 +1,22 @@ + +#### 小型进度条 +适合放在较狭窄的区域内。 + + + +#### Mini size progress bar +Appropriate for a narrow area. + + +```html + +``` + + diff --git a/components/progress/demo/line.md b/components/progress/demo/line.md new file mode 100644 index 000000000..1ab165137 --- /dev/null +++ b/components/progress/demo/line.md @@ -0,0 +1,22 @@ + +#### 进度条 +标准的进度条。 + + + +#### Progress bar +A standard progress bar. + + +```html + +``` + diff --git a/components/progress/demo/segment.md b/components/progress/demo/segment.md new file mode 100644 index 000000000..96bcd52c4 --- /dev/null +++ b/components/progress/demo/segment.md @@ -0,0 +1,18 @@ + +#### 分段进度条 +标准的进度条。 + + + +#### Progress bar with success segment +A standard progress bar. + + +```html + +``` + diff --git a/components/progress/index.en-US.md b/components/progress/index.en-US.md new file mode 100644 index 000000000..f02afe4a6 --- /dev/null +++ b/components/progress/index.en-US.md @@ -0,0 +1,15 @@ +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| format | template function of the content | function(percent) | `percent => percent + '%'` | +| gapDegree `(type=circle)` | the gap degree of half circle, 0 ~ 360 | number | 0 | +| gapPosition `(type=circle)` | the gap position, options: `top` `bottom` `left` `right` | string | `top` | +| percent | to set the completion percentage | number | 0 | +| showInfo | whether to display the progress value and the status icon | boolean | true | +| status | to set the status of the Progress, options: `success` `exception` `active` | string | - | +| strokeWidth `(type=line)` | to set the width of the progress bar, unit: `px` | number | 10 | +| strokeWidth `(type=circle)` | to set the width of the circular progress bar, unit: percentage of the canvas width | number | 6 | +| 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 | 120 | +| successPercent | segmented success percent, works when `type="line"` | number | 0 | diff --git a/components/progress/index.jsx b/components/progress/index.jsx new file mode 100644 index 000000000..bb7433762 --- /dev/null +++ b/components/progress/index.jsx @@ -0,0 +1,5 @@ +import Progress from './progress' + +export { ProgressProps } from './progress' + +export default Progress diff --git a/components/progress/index.zh-CN.md b/components/progress/index.zh-CN.md new file mode 100644 index 000000000..31af297fa --- /dev/null +++ b/components/progress/index.zh-CN.md @@ -0,0 +1,15 @@ +## API + +| 属性 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| format | 内容的模板函数 | function(percent) | `percent => percent + '%'` | +| gapDegree `(type=circle)` | 圆形进度条缺口角度,可取值 0 ~ 360 | number | 0 | +| gapPosition `(type=circle)` | 圆形进度条缺口位置 | Enum{ 'top', 'bottom', 'left', 'right' } | `top` | +| percent | 百分比 | number | 0 | +| showInfo | 是否显示进度数值或状态图标 | boolean | true | +| status | 状态,可选:`success` `exception` `active` | string | - | +| strokeWidth `(type=line)` | 进度条线的宽度,单位 px | number | 10 | +| strokeWidth `(type=circle)` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | +| type | 类型,可选 `line` `circle` `dashboard` | string | line | +| width `(type=circle)` | 圆形进度条画布宽度,单位 px | number | 120 | +| successPercent | 已完成的分段百分比,`type="line"` 时有效 | number | 0 | diff --git a/components/progress/progress.jsx b/components/progress/progress.jsx new file mode 100644 index 000000000..3bc163e2e --- /dev/null +++ b/components/progress/progress.jsx @@ -0,0 +1,135 @@ +import classNames from 'classnames' +import PropTypes from '../_util/vue-types' +import { getOptionProps, initDefaultProps } from '../_util/props-util' +import Icon from '../icon' +import { Circle } from '../vc-progress' + +function addUnit (num, unit) { + const unitType = unit || 'px' + return num ? num + unitType : null +} +const statusColorMap = { + normal: '#108ee9', + exception: '#ff5500', + success: '#87d068', +} + +export const ProgressProps = { + prefixCls: PropTypes.string, + type: PropTypes.oneOf(['line', 'circle', 'dashboard']), + percent: PropTypes.number, + successPercent: PropTypes.number, + format: PropTypes.func, + status: PropTypes.oneOf(['success', 'active', 'exception']), + showInfo: PropTypes.bool, + strokeWidth: PropTypes.number, + trailColor: PropTypes.string, + width: PropTypes.number, + gapDegree: PropTypes.number, + gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']), + size: PropTypes.oneOf(['default', 'small']), +} + +export default { + name: 'Progress', + props: initDefaultProps(ProgressProps, { + type: 'line', + percent: 0, + showInfo: true, + trailColor: '#f3f3f3', + prefixCls: 'ant-progress', + size: 'default', + }), + + render () { + const { + prefixCls, percent = 0, status, format, trailColor, size, successPercent, + type, strokeWidth, width, showInfo, gapDegree = 0, gapPosition, + } = getOptionProps(this) + const progressStatus = parseInt(percent.toString(), 10) >= 100 && !(status) + ? 'success' : (status || 'normal') + let progressInfo + let progress + const textFormatter = format || (percentNumber => `${percentNumber}%`) + + if (showInfo) { + let text + const iconType = (type === 'circle' || type === 'dashboard') ? '' : '-circle' + if (progressStatus === 'exception') { + text = format ? textFormatter(percent) : + } else if (progressStatus === 'success') { + text = format ? textFormatter(percent) : + } else { + text = textFormatter(percent) + } + progressInfo = {text} + } + + if (type === 'line') { + const percentStyle = { + width: `${percent}%`, + height: addUnit(strokeWidth) || (size === 'small' ? '6px' : '8px'), + } + const successPercentStyle = { + width: `${successPercent}%`, + height: addUnit(strokeWidth) || (size === 'small' ? '6px' : '8px'), + } + const successSegment = successPercent !== undefined + ?
+ : null + progress = ( +
+
+
+
+ {successSegment} +
+
+ {progressInfo} +
+ ) + } else if (type === 'circle' || type === 'dashboard') { + const circleSize = width || 120 + const circleStyle = { + width: addUnit(circleSize), + height: addUnit(circleSize), + fontSize: addUnit(circleSize * 0.15 + 6), + } + const circleWidth = strokeWidth || 6 + const gapPos = gapPosition || type === 'dashboard' && 'bottom' || 'top' + const gapDeg = gapDegree || (type === 'dashboard' && 75) + progress = ( +
+ + {progressInfo} +
+ ) + } + + const classString = classNames(prefixCls, { + [`${prefixCls}-${type === 'dashboard' && 'circle' || type}`]: true, + [`${prefixCls}-status-${progressStatus}`]: true, + [`${prefixCls}-show-info`]: showInfo, + [`${prefixCls}-${size}`]: size, + }) + + const progressProps = { + on: this.$listeners, + class: classString, + } + return ( +
+ {progress} +
+ ) + }, +} diff --git a/components/progress/style/index.js b/components/progress/style/index.js new file mode 100644 index 000000000..cf31ed80f --- /dev/null +++ b/components/progress/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less' +import './index.less' diff --git a/components/progress/style/index.less b/components/progress/style/index.less new file mode 100644 index 000000000..8043fd022 --- /dev/null +++ b/components/progress/style/index.less @@ -0,0 +1,167 @@ +@import "../../style/themes/default"; +@import "../../style/mixins/index"; + +@progress-prefix-cls: ~"@{ant-prefix}-progress"; + +.@{progress-prefix-cls} { + .reset-component; + display: inline-block; + + &-line { + width: 100%; + font-size: @font-size-base; + position: relative; + } + + &-small&-line, + &-small&-line &-text .@{iconfont-css-prefix} { + font-size: @font-size-sm; + } + + &-outer { + display: inline-block; + width: 100%; + margin-right: 0; + padding-right: 0; + .@{progress-prefix-cls}-show-info & { + padding-right: ~"calc(2em + 8px)"; + margin-right: ~"calc(-2em - 8px)"; + } + } + + &-inner { + display: inline-block; + width: 100%; + background-color: @progress-remaining-color; + border-radius: 100px; + vertical-align: middle; + position: relative; + } + + &-circle-trail { + stroke: @progress-remaining-color; + } + + &-circle-path { + stroke: @progress-default-color; + animation: ~"@{ant-prefix}-progress-appear" .3s; + } + + &-success-bg, + &-bg { + border-radius: 100px; + background-color: @progress-default-color; + transition: all .4s @ease-out-circ 0s; + position: relative; + } + + &-success-bg { + background-color: @success-color; + position: absolute; + top: 0; + left: 0; + } + + &-text { + word-break: normal; + width: 2em; + text-align: left; + font-size: 1em; + margin-left: 8px; + vertical-align: middle; + display: inline-block; + color: @text-color-secondary; + line-height: 1; + .@{iconfont-css-prefix} { + font-size: @font-size-base; + } + } + + &-status-active { + .@{progress-prefix-cls}-bg:before { + content: ""; + opacity: 0; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: @component-background; + border-radius: 10px; + animation: ~"@{ant-prefix}-progress-active" 2.4s @ease-out-quint infinite; + } + } + + &-status-exception { + .@{progress-prefix-cls}-bg { + background-color: @error-color; + } + .@{progress-prefix-cls}-text { + color: @error-color; + } + .@{progress-prefix-cls}-circle-path { + stroke: @error-color; + } + } + + &-status-success { + .@{progress-prefix-cls}-bg { + background-color: @success-color; + } + .@{progress-prefix-cls}-text { + color: @success-color; + } + .@{progress-prefix-cls}-circle-path { + stroke: @success-color; + } + } + + &-circle &-inner { + position: relative; + line-height: 1; + background-color: transparent; + } + + &-circle &-text { + display: block; + position: absolute; + width: 100%; + text-align: center; + line-height: 1; + top: 50%; + transform: translateY(-50%); + left: 0; + margin: 0; + color: @text-color; + + .@{iconfont-css-prefix} { + font-size: 14 / 12em; + } + } + + &-circle&-status-exception { + .@{progress-prefix-cls}-text { + color: @error-color; + } + } + &-circle&-status-success { + .@{progress-prefix-cls}-text { + color: @success-color; + } + } +} + +@keyframes ~"@{ant-prefix}-progress-active" { + 0% { + opacity: 0.1; + width: 0; + } + 20% { + opacity: 0.5; + width: 0; + } + 100% { + opacity: 0; + width: 100%; + } +} diff --git a/components/style.js b/components/style.js index c272e39ac..51d741d25 100644 --- a/components/style.js +++ b/components/style.js @@ -36,3 +36,4 @@ import './calendar/style' import './date-picker/style' import './slider/style' import './table/style' +import './progress/style' diff --git a/components/vc-progress/src/Circle.js b/components/vc-progress/src/Circle.js index f491694f0..7cafaaf4c 100644 --- a/components/vc-progress/src/Circle.js +++ b/components/vc-progress/src/Circle.js @@ -100,9 +100,13 @@ const Circle = { - + { + percent > 0 ? ( + + ) : null + } ) }, diff --git a/examples/demo.js b/examples/demo.js index 6b4eecb94..f80c853f1 100644 --- a/examples/demo.js +++ b/examples/demo.js @@ -35,3 +35,5 @@ export { default as steps } from 'antd/steps/demo/index.vue' export { default as calendar } from 'antd/calendar/demo/index.vue' export { default as datePicker } from 'antd/date-picker/demo/index.vue' export { default as localeProvider } from 'antd/locale-provider/demo/index.vue' +// export { default as slider } from 'antd/slider/demo/index.vue' +export { default as progress } from 'antd/progress/demo/index.vue' diff --git a/examples/routes.js b/examples/routes.js index bc9c6245d..d5cf1ac00 100644 --- a/examples/routes.js +++ b/examples/routes.js @@ -3,7 +3,7 @@ const AsyncComp = () => { const hashs = window.location.hash.split('/') const d = hashs[hashs.length - 1] return { - component: import(`../components/vc-progress/demo/${d}`), + component: import(`../components/progress/demo/${d}`), } } export default [