diff --git a/components/grid/demo/index.vue b/components/grid/demo/index.vue
index ede56aac1..b2dd1d080 100644
--- a/components/grid/demo/index.vue
+++ b/components/grid/demo/index.vue
@@ -8,6 +8,7 @@ import Offset from './offset'
import ResponsiveMore from './responsive-more'
import Responsive from './responsive'
import Sort from './sort'
+import Playfround from './playfround'
import CN from '../index.zh-CN.md'
import US from '../index.en-US.md'
const md = {
@@ -53,7 +54,7 @@ Following is a brief look at how it works:
## Flex layout
Our grid systems support Flex layout to allow the elements within the parent to be aligned horizontally - left, center, right, wide arrangement, and decentralized arrangement. The Grid system also supports vertical alignment - top aligned, vertically centered, bottom-aligned. You can also define the order of elements by using \`order\`.
Flex layout uses a 24 grid layout to define the width of each "box", but does not rigidly adhere to the grid layout.
-## Examples
+## Examples
`,
}
export default {
@@ -125,6 +126,7 @@ export default {
+
diff --git a/components/grid/demo/playfround.md b/components/grid/demo/playfround.md
new file mode 100644
index 000000000..212152f60
--- /dev/null
+++ b/components/grid/demo/playfround.md
@@ -0,0 +1,96 @@
+
+#### 栅格配置器
+可以简单配置几种等分栅格和间距。
+
+
+
+#### Playground
+A simple playground for column count and gutter.
+
+
+```html
+
+
+
+
Gutter (px):
+
+
Column Count:
+
+
+
+
+ Column
+
+
+
+
+
+
+
+
+```
+
+
diff --git a/components/index.js b/components/index.js
index 89e1c44df..e3650b104 100644
--- a/components/index.js
+++ b/components/index.js
@@ -140,3 +140,9 @@ export { Table, TableColumn, TableColumnGroup }
export { default as version } from './version'
export { default as Slider } from './slider'
+
+export { default as Progress } from './progress'
+
+import Timeline from './timeline'
+const TimelineItem = Timeline.Item
+export { Timeline, TimelineItem }
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/slider/demo/index.vue b/components/slider/demo/index.vue
index a04488de3..7d65ffaff 100644
--- a/components/slider/demo/index.vue
+++ b/components/slider/demo/index.vue
@@ -1,6 +1,6 @@
diff --git a/components/timeline/demo/pending.md b/components/timeline/demo/pending.md
new file mode 100644
index 000000000..50a67867f
--- /dev/null
+++ b/components/timeline/demo/pending.md
@@ -0,0 +1,23 @@
+
+#### 最后一个
+当任务状态正在发生,还在记录过程中,可用幽灵节点来表示当前的时间节点。(用于时间正序排列)
+
+
+
+#### Last node
+When the timeline is incomplete and ongoing, put a ghost node at last. set `pending={true}` or `pending={a React Element}`. Used in ascend chronological order.
+
+
+```html
+
+
+ Create a services site 2015-09-01
+ Solve initial network problems 2015-09-01
+ Technical testing 2015-09-01
+
+
+```
+
+
+
+
diff --git a/components/timeline/index.en-US.md b/components/timeline/index.en-US.md
new file mode 100644
index 000000000..5de3cd3c7
--- /dev/null
+++ b/components/timeline/index.en-US.md
@@ -0,0 +1,27 @@
+## API
+
+```` html
+
+ step1 2015-09-01
+ step2 2015-09-01
+ step3 2015-09-01
+ step4 2015-09-01
+
+````
+
+### Timeline
+
+Timeline
+
+| Property | Description | Type | Default |
+| -------- | ----------- | ---- | ------- |
+| pending | Set the last ghost node's existence or its content | boolean\|string\|slot | `false` |
+
+### Timeline.Item
+
+Node of timeline
+
+| Property | Description | Type | Default |
+| -------- | ----------- | ---- | ------- |
+| color | Set the circle's color to `blue`, `red`, `green` or other custom colors | string | `blue` |
+| dot | Customize timeline dot | string\|slot | - |
diff --git a/components/timeline/index.jsx b/components/timeline/index.jsx
new file mode 100644
index 000000000..48bd15f66
--- /dev/null
+++ b/components/timeline/index.jsx
@@ -0,0 +1,9 @@
+import Timeline from './Timeline'
+
+export { TimelineProps } from './Timeline'
+export { TimeLineItemProps } from './TimelineItem'
+import TimelineItem from './TimelineItem'
+
+Timeline.Item = TimelineItem
+
+export default Timeline
diff --git a/components/timeline/index.zh-CN.md b/components/timeline/index.zh-CN.md
new file mode 100644
index 000000000..c127fafdb
--- /dev/null
+++ b/components/timeline/index.zh-CN.md
@@ -0,0 +1,27 @@
+## API
+
+```` html
+
+ 创建服务现场 2015-09-01
+ 初步排除网络异常 2015-09-01
+ 技术测试异常 2015-09-01
+ 网络异常正在修复 2015-09-01
+
+````
+
+### Timeline
+
+时间轴。
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| pending | 指定最后一个幽灵节点是否存在或内容 | boolean\|string\|slot | false |
+
+### Timeline.Item
+
+时间轴的每一个节点。
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| color | 指定圆圈颜色 `blue, red, green`,或自定义的色值 | string | blue |
+| dot | 自定义时间轴点 | string\|slot | - |
diff --git a/components/timeline/style/index.jsx b/components/timeline/style/index.jsx
new file mode 100644
index 000000000..cf31ed80f
--- /dev/null
+++ b/components/timeline/style/index.jsx
@@ -0,0 +1,2 @@
+import '../../style/index.less'
+import './index.less'
diff --git a/components/timeline/style/index.less b/components/timeline/style/index.less
new file mode 100644
index 000000000..610ab815b
--- /dev/null
+++ b/components/timeline/style/index.less
@@ -0,0 +1,93 @@
+@import "../../style/themes/default";
+@import "../../style/mixins/index";
+
+@timeline-prefix-cls: ~"@{ant-prefix}-timeline";
+@timeline-color: @border-color-split;
+
+.@{timeline-prefix-cls} {
+ .reset-component;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+ &-item {
+ position: relative;
+ padding: 0 0 20px;
+ list-style: none;
+ margin: 0;
+ font-size: @font-size-base;
+
+ &-tail {
+ position: absolute;
+ left: 4px;
+ top: 0.75em;
+ height: 100%;
+ border-left: 2px solid @timeline-color;
+ }
+
+ &-pending &-head {
+ font-size: @font-size-sm;
+ }
+
+ &-pending &-tail {
+ display: none;
+ }
+
+ &-head {
+ position: absolute;
+ width: 10px;
+ height: 10px;
+ background-color: @component-background;
+ border-radius: 100px;
+ border: 2px solid transparent;
+
+ &-blue {
+ border-color: @primary-color;
+ color: @primary-color;
+ }
+ &-red {
+ border-color: @error-color;
+ color: @error-color;
+ }
+ &-green {
+ border-color: @success-color;
+ color: @success-color;
+ }
+ }
+
+ &-head-custom {
+ position: absolute;
+ text-align: center;
+ line-height: 1;
+ margin-top: 0;
+ border: 0;
+ height: auto;
+ border-radius: 0;
+ padding: 3px 0;
+ transform: translate(-50%, -50%);
+ top: 5px;
+ left: 5px;
+ width: auto;
+ }
+
+ &-content {
+ padding: 0 0 0 18px;
+ position: relative;
+ top: -(@font-size-base * @line-height-base - @font-size-base) + 1px;
+ }
+
+ &-last {
+ .@{timeline-prefix-cls}-item-tail {
+ border-left: 2px dotted @timeline-color;
+ display: none;
+ }
+ .@{timeline-prefix-cls}-item-content {
+ min-height: 48px;
+ }
+ }
+ }
+
+ &&-pending &-item-last &-item-tail {
+ display: block;
+ }
+}
diff --git a/components/vc-progress/assets/index.less b/components/vc-progress/assets/index.less
new file mode 100644
index 000000000..e69de29bb
diff --git a/components/vc-progress/demo/fast-progress.jsx b/components/vc-progress/demo/fast-progress.jsx
new file mode 100644
index 000000000..ba34dbedf
--- /dev/null
+++ b/components/vc-progress/demo/fast-progress.jsx
@@ -0,0 +1,42 @@
+import { Line, Circle } from '../index'
+import '../assets/index.less'
+
+export default {
+ data () {
+ return {
+ percent: 0,
+ }
+ },
+ mounted () {
+ this.$nextTick(() => {
+ this.increase()
+ })
+ },
+ methods: {
+ increase () {
+ const percent = this.percent + 1
+ if (percent >= 100) {
+ clearTimeout(this.tm)
+ return
+ }
+ this.percent = percent
+ this.tm = setTimeout(this.increase, 10)
+ },
+ restart () {
+ clearTimeout(this.tm)
+ this.percent = 0
+ this.$nextTick(() => {
+ this.increase()
+ })
+ },
+ },
+ render () {
+ return (
+
+
+
+ Restart
+
+ )
+ },
+}
diff --git a/components/vc-progress/demo/gap.jsx b/components/vc-progress/demo/gap.jsx
new file mode 100644
index 000000000..d13fe2ba4
--- /dev/null
+++ b/components/vc-progress/demo/gap.jsx
@@ -0,0 +1,72 @@
+import { Circle } from '../index'
+import '../assets/index.less'
+
+export default {
+ data () {
+ return {
+ percent: 30,
+ color: '#3FC7FA',
+ }
+ },
+ methods: {
+ changeState () {
+ const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A']
+ const value = parseInt(Math.random() * 100, 10)
+ this.percent = value
+ this.color = colorMap[parseInt(Math.random() * 3, 10)]
+ },
+ },
+ render () {
+ const circleContainerStyle = {
+ width: '200px',
+ height: '200px',
+ }
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Change State
+
+
+ )
+ },
+}
diff --git a/components/vc-progress/demo/simple.jsx b/components/vc-progress/demo/simple.jsx
new file mode 100644
index 000000000..4cacef15e
--- /dev/null
+++ b/components/vc-progress/demo/simple.jsx
@@ -0,0 +1,49 @@
+import { Line, Circle } from '../index'
+import '../assets/index.less'
+
+export default {
+ data () {
+ return {
+ percent: 30,
+ color: '#3FC7FA',
+ }
+ },
+ methods: {
+ changeState () {
+ const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A']
+ const value = parseInt(Math.random() * 100, 10)
+ this.percent = value
+ this.color = colorMap[parseInt(Math.random() * 3, 10)]
+ },
+ },
+ render () {
+ const containerStyle = {
+ width: '250px',
+ }
+ const circleContainerStyle = {
+ width: '250px',
+ height: '250px',
+ display: 'inline-block',
+ }
+ return (
+
+
Line Progress {this.percent}%
+
+
+
+
Circle Progress {this.percent}%
+
+
+
+
+ Change State
+
+
+ )
+ },
+}
diff --git a/components/vc-progress/index.js b/components/vc-progress/index.js
new file mode 100644
index 000000000..84efef7a6
--- /dev/null
+++ b/components/vc-progress/index.js
@@ -0,0 +1,8 @@
+import Progress, { Line, Circle } from './src/';
+
+export {
+ Line,
+ Circle,
+};
+
+export default Progress;
diff --git a/components/vc-progress/src/Circle.js b/components/vc-progress/src/Circle.js
new file mode 100644
index 000000000..7cafaaf4c
--- /dev/null
+++ b/components/vc-progress/src/Circle.js
@@ -0,0 +1,115 @@
+import PropTypes from '../../_util/vue-types'
+import { initDefaultProps } from '../../_util/props-util'
+import enhancer from './enhancer'
+import { propTypes, defaultProps } from './types'
+
+const circlePropTypes = {
+ ...propTypes,
+ gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
+ gapDegree: PropTypes.number,
+}
+
+const circleDefaultProps = {
+ ...defaultProps,
+ gapPosition: 'top',
+}
+
+const Circle = {
+ props: initDefaultProps(circlePropTypes, circleDefaultProps),
+ methods: {
+ getPathStyles () {
+ const { percent, strokeWidth, gapDegree = 0, gapPosition } = this.$props
+ const radius = 50 - (strokeWidth / 2)
+ let beginPositionX = 0
+ let beginPositionY = -radius
+ let endPositionX = 0
+ let endPositionY = -2 * radius
+ switch (gapPosition) {
+ case 'left':
+ beginPositionX = -radius
+ beginPositionY = 0
+ endPositionX = 2 * radius
+ endPositionY = 0
+ break
+ case 'right':
+ beginPositionX = radius
+ beginPositionY = 0
+ endPositionX = -2 * radius
+ endPositionY = 0
+ break
+ case 'bottom':
+ beginPositionY = radius
+ endPositionY = 2 * radius
+ break
+ default:
+ }
+ const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
+ a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
+ a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`
+ const len = Math.PI * 2 * radius
+ const trailPathStyle = {
+ strokeDasharray: `${len - gapDegree}px ${len}px`,
+ strokeDashoffset: `-${gapDegree / 2}px`,
+ transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s',
+ }
+ const strokePathStyle = {
+ strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,
+ strokeDashoffset: `-${gapDegree / 2}px`,
+ transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', // eslint-disable-line
+ }
+ return { pathString, trailPathStyle, strokePathStyle }
+ },
+ },
+ render () {
+ const {
+ prefixCls, strokeWidth, trailWidth, strokeColor,
+ trailColor, strokeLinecap, percent, ...restProps
+ } = this.$props
+ const { pathString, trailPathStyle, strokePathStyle } = this.getPathStyles()
+ delete restProps.percent
+ delete restProps.gapDegree
+ delete restProps.gapPosition
+ const pathFirst = {
+ attrs: {
+ 'd': pathString,
+ 'stroke': trailColor,
+ 'stroke-width': trailWidth || strokeWidth,
+ 'fill-opacity': '0',
+ },
+ class: `${prefixCls}-circle-trail`,
+ style: trailPathStyle,
+ }
+ const pathSecond = {
+ attrs: {
+ 'd': pathString,
+ 'stroke-linecap': strokeLinecap,
+ 'stroke': strokeColor,
+ 'stroke-width': percent === 0 ? 0 : strokeWidth,
+ 'fill-opacity': '0',
+ },
+ class: `${prefixCls}-circle-path`,
+ style: strokePathStyle,
+ ref: 'svgPathRef',
+ }
+ return (
+
+
+ {
+ percent > 0 ? (
+
+ ) : null
+ }
+
+ )
+ },
+}
+
+export default enhancer(Circle)
diff --git a/components/vc-progress/src/Line.js b/components/vc-progress/src/Line.js
new file mode 100644
index 000000000..3beff0df0
--- /dev/null
+++ b/components/vc-progress/src/Line.js
@@ -0,0 +1,73 @@
+import { initDefaultProps } from '../../_util/props-util'
+import enhancer from './enhancer'
+import { propTypes, defaultProps } from './types'
+
+const Line = {
+ props: initDefaultProps(propTypes, defaultProps),
+ render () {
+ const {
+ percent,
+ prefixCls,
+ strokeColor,
+ strokeLinecap,
+ strokeWidth,
+ trailColor,
+ trailWidth,
+ ...restProps
+ } = this.$props
+
+ delete restProps.gapPosition
+
+ const pathStyle = {
+ strokeDasharray: '100px, 100px',
+ strokeDashoffset: `${(100 - percent)}px`,
+ transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s linear',
+ }
+
+ const center = strokeWidth / 2
+ const right = 100 - (strokeWidth / 2)
+ const pathString =
+ `M ${strokeLinecap === 'round' ? center : 0},${center}
+ L ${strokeLinecap === 'round' ? right : 100},${center}`
+ const viewBoxString = `0 0 100 ${strokeWidth}`
+ const pathFirst = {
+ attrs: {
+ 'd': pathString,
+ 'stroke-linecap': strokeLinecap,
+ 'stroke': trailColor,
+ 'stroke-width': trailWidth || strokeWidth,
+ 'fill-opacity': '0',
+ },
+ class: `${prefixCls}-line-trail`,
+ }
+ const pathSecond = {
+ attrs: {
+ 'd': pathString,
+ 'stroke-linecap': strokeLinecap,
+ 'stroke': strokeColor,
+ 'stroke-width': strokeWidth,
+ 'fill-opacity': '0',
+ },
+ class: `${prefixCls}-line-path`,
+ style: pathStyle,
+ ref: 'svgPathRef',
+ }
+ return (
+
+
+
+
+ )
+ },
+}
+
+export default enhancer(Line)
diff --git a/components/vc-progress/src/enhancer.js b/components/vc-progress/src/enhancer.js
new file mode 100644
index 000000000..c4340b88d
--- /dev/null
+++ b/components/vc-progress/src/enhancer.js
@@ -0,0 +1,21 @@
+function enhancer (Component) {
+ return {
+ mixins: [Component],
+ updated () {
+ this.$nextTick(() => {
+ if (!this.$refs.svgPathRef) {
+ return
+ }
+ const pathStyle = this.$refs.svgPathRef.style
+ pathStyle.transitionDuration = '.3s, .3s, .3s, .06s'
+ const now = Date.now()
+ if (this.prevTimeStamp && now - this.prevTimeStamp < 100) {
+ pathStyle.transitionDuration = '0s, 0s'
+ }
+ this.prevTimeStamp = Date.now()
+ })
+ },
+ }
+}
+
+export default enhancer
diff --git a/components/vc-progress/src/index.js b/components/vc-progress/src/index.js
new file mode 100644
index 000000000..490ffd045
--- /dev/null
+++ b/components/vc-progress/src/index.js
@@ -0,0 +1,12 @@
+import Line from './Line'
+import Circle from './Circle'
+
+export {
+ Line,
+ Circle,
+}
+
+export default {
+ Line,
+ Circle,
+}
diff --git a/components/vc-progress/src/types.js b/components/vc-progress/src/types.js
new file mode 100644
index 000000000..03e54203f
--- /dev/null
+++ b/components/vc-progress/src/types.js
@@ -0,0 +1,25 @@
+import PropTypes from '../../_util/vue-types'
+
+export const defaultProps = {
+ // className: '',
+ percent: 0,
+ prefixCls: 'rc-progress',
+ strokeColor: '#2db7f5',
+ strokeLinecap: 'round',
+ strokeWidth: 1,
+ // style: {},
+ trailColor: '#D9D9D9',
+ trailWidth: 1,
+}
+
+export const propTypes = {
+ // className: PropTypes.string,
+ percent: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
+ prefixCls: PropTypes.string,
+ strokeColor: PropTypes.string,
+ strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
+ strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
+ // style: PropTypes.object,
+ trailColor: PropTypes.string,
+ trailWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
+}
diff --git a/components/vc-slider/src/common/createSlider.jsx b/components/vc-slider/src/common/createSlider.jsx
index 899da3afe..b1d0c86c9 100644
--- a/components/vc-slider/src/common/createSlider.jsx
+++ b/components/vc-slider/src/common/createSlider.jsx
@@ -13,7 +13,6 @@ function noop () {}
export default function createSlider (Component) {
// const displayName = `ComponentEnhancer(${Component.displayName})`
const propTypes = {
- ...Component.propTypes,
min: PropTypes.number,
max: PropTypes.number,
step: PropTypes.number,
@@ -41,7 +40,6 @@ export default function createSlider (Component) {
event: 'change',
},
props: initDefaultProps(propTypes, {
- ...Component.defaultProps,
prefixCls: 'rc-slider',
min: 0,
max: 100,
diff --git a/contributors.md b/contributors.md
index fadb8c3d6..43064e78b 100644
--- a/contributors.md
+++ b/contributors.md
@@ -33,7 +33,7 @@ Carousel
Mention
##万
-Grid | done slider完成后补全playground demo
+Grid | done
Layout
Anchor
Tree
@@ -50,8 +50,7 @@ Collapse | done
Spin | done
Switch | done
Steps | done
-Progress
-Slider
-Table
-Timeline
+Progress | done
+Slider | done InputNumber做完补全demo
+Timeline | done
Transfer
diff --git a/examples/demo.js b/examples/demo.js
index 6b4eecb94..063ceb7eb 100644
--- a/examples/demo.js
+++ b/examples/demo.js
@@ -35,3 +35,6 @@ 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'
+export { default as timeline } from 'antd/timeline/demo/index.vue'
diff --git a/examples/routes.js b/examples/routes.js
index 674f13d15..d9670c48e 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/table/demo/${d}`),
+ component: import(`../components/grid/demo/${d}`),
}
}
export default [