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 = (
+
+ )
+ } 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 [