From 99b6606d3dbcac594267e06dbb7711480971891d Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 11:00:05 +0800 Subject: [PATCH 1/5] add vc-progress --- components/vc-progress/assets/index.less | 0 components/vc-progress/demo/fast-progress.jsx | 42 +++++++ components/vc-progress/demo/gap.jsx | 72 ++++++++++++ components/vc-progress/demo/simple.jsx | 49 ++++++++ components/vc-progress/index.js | 8 ++ components/vc-progress/src/Circle.js | 111 ++++++++++++++++++ components/vc-progress/src/Line.js | 73 ++++++++++++ components/vc-progress/src/enhancer.js | 21 ++++ components/vc-progress/src/index.js | 12 ++ components/vc-progress/src/types.js | 25 ++++ .../vc-slider/src/common/createSlider.jsx | 2 - examples/routes.js | 2 +- 12 files changed, 414 insertions(+), 3 deletions(-) create mode 100644 components/vc-progress/assets/index.less create mode 100644 components/vc-progress/demo/fast-progress.jsx create mode 100644 components/vc-progress/demo/gap.jsx create mode 100644 components/vc-progress/demo/simple.jsx create mode 100644 components/vc-progress/index.js create mode 100644 components/vc-progress/src/Circle.js create mode 100644 components/vc-progress/src/Line.js create mode 100644 components/vc-progress/src/enhancer.js create mode 100644 components/vc-progress/src/index.js create mode 100644 components/vc-progress/src/types.js 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 ( +
+ + + +
+ ) + }, +} 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 ( +
+
+ +
+
+ +
+
+ +
+
+ +
+

+ +

+
+ ) + }, +} 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}%

+
+ +
+

+ +

+
+ ) + }, +} 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..f491694f0 --- /dev/null +++ b/components/vc-progress/src/Circle.js @@ -0,0 +1,111 @@ +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 ( + + + + + ) + }, +} + +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/examples/routes.js b/examples/routes.js index 674f13d15..bc9c6245d 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/vc-progress/demo/${d}`), } } export default [ From 21ea62a736f16ad7ae4900e9f69fa0e88f45384a Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 14:14:38 +0800 Subject: [PATCH 2/5] 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 [ From 6dfd2717ee787ec1929b9dc0c8bd291a9ad3e21e Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 15:51:44 +0800 Subject: [PATCH 3/5] add timeline --- components/index.js | 4 ++ components/slider/demo/index.vue | 4 +- components/style.js | 1 + components/timeline/Timeline.jsx | 58 +++++++++++++++++ components/timeline/TimelineItem.jsx | 52 ++++++++++++++++ components/timeline/demo/basic.md | 22 +++++++ components/timeline/demo/color.md | 31 ++++++++++ components/timeline/demo/custom.md | 26 ++++++++ components/timeline/demo/index.vue | 54 ++++++++++++++++ components/timeline/demo/pending.md | 23 +++++++ components/timeline/index.en-US.md | 27 ++++++++ components/timeline/index.jsx | 9 +++ components/timeline/index.zh-CN.md | 27 ++++++++ components/timeline/style/index.jsx | 2 + components/timeline/style/index.less | 93 ++++++++++++++++++++++++++++ contributors.md | 7 +-- examples/demo.js | 3 +- examples/routes.js | 2 +- 18 files changed, 436 insertions(+), 9 deletions(-) create mode 100644 components/timeline/Timeline.jsx create mode 100644 components/timeline/TimelineItem.jsx create mode 100644 components/timeline/demo/basic.md create mode 100644 components/timeline/demo/color.md create mode 100644 components/timeline/demo/custom.md create mode 100644 components/timeline/demo/index.vue create mode 100644 components/timeline/demo/pending.md create mode 100644 components/timeline/index.en-US.md create mode 100644 components/timeline/index.jsx create mode 100644 components/timeline/index.zh-CN.md create mode 100644 components/timeline/style/index.jsx create mode 100644 components/timeline/style/index.less diff --git a/components/index.js b/components/index.js index e896f363f..e3650b104 100644 --- a/components/index.js +++ b/components/index.js @@ -142,3 +142,7 @@ 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/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 + +``` + + + + 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/contributors.md b/contributors.md index fadb8c3d6..79aa47e5d 100644 --- a/contributors.md +++ b/contributors.md @@ -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 f80c853f1..063ceb7eb 100644 --- a/examples/demo.js +++ b/examples/demo.js @@ -35,5 +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 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 d5cf1ac00..b73615c7c 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/progress/demo/${d}`), + component: import(`../components/timeline/demo/${d}`), } } export default [ From 5e02aed8c2b0ec83fb155ee51b38a116c6b0713c Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 17:03:32 +0800 Subject: [PATCH 4/5] add grid demo --- components/grid/demo/index.vue | 4 +- components/grid/demo/playfround.md | 97 ++++++++++++++++++++++++++++++ contributors.md | 2 +- examples/routes.js | 2 +- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 components/grid/demo/playfround.md 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..4d2a82cbf --- /dev/null +++ b/components/grid/demo/playfround.md @@ -0,0 +1,97 @@ + +#### 栅格配置器 +可以简单配置几种等分栅格和间距。 + + + +#### Playground +A simple playground for column count and gutter. + + +```html + + + +``` + + diff --git a/contributors.md b/contributors.md index 79aa47e5d..43064e78b 100644 --- a/contributors.md +++ b/contributors.md @@ -33,7 +33,7 @@ Carousel Mention ##万 -Grid | done slider完成后补全playground demo +Grid | done Layout Anchor Tree diff --git a/examples/routes.js b/examples/routes.js index b73615c7c..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/timeline/demo/${d}`), + component: import(`../components/grid/demo/${d}`), } } export default [ From e98bb7e4e817202f573e9ec30eb20e48a7f64bd0 Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 3 Apr 2018 17:09:25 +0800 Subject: [PATCH 5/5] fix grid demo --- components/grid/demo/playfround.md | 1 - 1 file changed, 1 deletion(-) diff --git a/components/grid/demo/playfround.md b/components/grid/demo/playfround.md index 4d2a82cbf..212152f60 100644 --- a/components/grid/demo/playfround.md +++ b/components/grid/demo/playfround.md @@ -62,7 +62,6 @@ A simple playground for column count and gutter. rowColHtml() { const colCount = this.colCounts[this.colCountKey] const getter = this.gutters[this.gutterKey] - // ${colCode} let colCode = '\n' for (let i = 0; i < colCount; i++) { const spanNum = 24 / colCount