From cb0740b60c998a879e69d160e4675396c36cfdaa Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Fri, 9 Mar 2018 18:52:31 +0800 Subject: [PATCH] add vc-steps demo --- components/index.js | 4 + components/pagination/Pagination.vue | 1 + components/steps/demo/index.vue | 18 ++ components/steps/index.vue | 45 +++++ components/steps/style/custom-icon.less | 21 +++ components/steps/style/index.js | 2 + components/steps/style/index.less | 187 ++++++++++++++++++++ components/steps/style/label-placement.less | 28 +++ components/steps/style/progress-dot.less | 75 ++++++++ components/steps/style/small.less | 45 +++++ components/steps/style/vertical.less | 67 +++++++ components/vc-pagination/Pagination.vue | 1 + components/vc-steps/Step.vue | 3 +- components/vc-steps/Steps.vue | 21 ++- components/vc-steps/assets/iconfont.less | 2 +- components/vc-steps/demo/customIcon.vue | 5 +- components/vc-steps/demo/dynamic.vue | 41 +++++ components/vc-steps/demo/errorStep.vue | 24 +++ components/vc-steps/demo/nextStep.vue | 70 ++++++++ components/vc-steps/demo/progressDot.vue | 25 +++ components/vc-steps/demo/simple.vue | 38 ++++ components/vc-steps/demo/smallSize.vue | 30 ++++ components/vc-steps/demo/vertical.vue | 25 +++ components/vc-steps/demo/verticalSmall.vue | 25 +++ examples/routes.js | 2 +- 25 files changed, 795 insertions(+), 10 deletions(-) create mode 100644 components/steps/demo/index.vue create mode 100644 components/steps/index.vue create mode 100644 components/steps/style/custom-icon.less create mode 100644 components/steps/style/index.js create mode 100644 components/steps/style/index.less create mode 100644 components/steps/style/label-placement.less create mode 100644 components/steps/style/progress-dot.less create mode 100644 components/steps/style/small.less create mode 100644 components/steps/style/vertical.less create mode 100644 components/vc-steps/demo/dynamic.vue create mode 100644 components/vc-steps/demo/errorStep.vue create mode 100644 components/vc-steps/demo/nextStep.vue create mode 100644 components/vc-steps/demo/progressDot.vue create mode 100644 components/vc-steps/demo/simple.vue create mode 100644 components/vc-steps/demo/smallSize.vue create mode 100644 components/vc-steps/demo/vertical.vue create mode 100644 components/vc-steps/demo/verticalSmall.vue diff --git a/components/index.js b/components/index.js index 04b0ca7b7..61e55c926 100644 --- a/components/index.js +++ b/components/index.js @@ -108,3 +108,7 @@ const api = { modalConfirm: confirm, } export { api } + +import Steps from './steps' +const { Step } = Steps +export { Steps, Step } diff --git a/components/pagination/Pagination.vue b/components/pagination/Pagination.vue index b2e95f583..a82cbdfb4 100644 --- a/components/pagination/Pagination.vue +++ b/components/pagination/Pagination.vue @@ -39,6 +39,7 @@ export default { }, model: { prop: 'current', + event: 'change', }, methods: { renderPagination (locale) { diff --git a/components/steps/demo/index.vue b/components/steps/demo/index.vue new file mode 100644 index 000000000..af00b5ef1 --- /dev/null +++ b/components/steps/demo/index.vue @@ -0,0 +1,18 @@ + + diff --git a/components/steps/index.vue b/components/steps/index.vue new file mode 100644 index 000000000..e0feac949 --- /dev/null +++ b/components/steps/index.vue @@ -0,0 +1,45 @@ + diff --git a/components/steps/style/custom-icon.less b/components/steps/style/custom-icon.less new file mode 100644 index 000000000..95415faa9 --- /dev/null +++ b/components/steps/style/custom-icon.less @@ -0,0 +1,21 @@ +.@{steps-prefix-cls}-item-custom { + .@{steps-prefix-cls}-item-icon { + background: none; + border: 0; + width: auto; + height: auto; + > .@{steps-prefix-cls}-icon { + font-size: 24px; + line-height: @steps-icon-size; + top: 0; + left: 0.5px; + width: @steps-icon-size; + height: @steps-icon-size; + } + } + &.@{steps-prefix-cls}-item-process { + .@{steps-prefix-cls}-item-icon > .@{steps-prefix-cls}-icon { + color: @process-icon-color; + } + } +} diff --git a/components/steps/style/index.js b/components/steps/style/index.js new file mode 100644 index 000000000..cf31ed80f --- /dev/null +++ b/components/steps/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less' +import './index.less' diff --git a/components/steps/style/index.less b/components/steps/style/index.less new file mode 100644 index 000000000..2fd37dae2 --- /dev/null +++ b/components/steps/style/index.less @@ -0,0 +1,187 @@ +@import "../../style/themes/default"; +@import "../../style/mixins/index"; + +@steps-prefix-cls: ~"@{ant-prefix}-steps"; +@process-icon-color: @processing-color; +@process-title-color: @heading-color; +@process-description-color: @text-color; +@process-tail-color: @border-color-split; +@process-icon-text-color: #fff; +@wait-icon-color: @disabled-color; +@wait-title-color: @text-color-secondary; +@wait-description-color: @wait-title-color; +@wait-tail-color: @process-tail-color; +@finish-icon-color: @process-icon-color; +@finish-title-color: @text-color; +@finish-description-color: @text-color-secondary; +@finish-tail-color: @primary-color; +@error-icon-color: @error-color; +@error-title-color: @error-color; +@error-description-color: @error-color; +@error-tail-color: @wait-tail-color; +@steps-background: @component-background; + +@steps-icon-size: 32px; +@steps-small-icon-size: 24px; +@steps-dot-size: 8px; +@steps-current-dot-size: 10px; +@steps-desciption-max-width: 140px; + +.@{steps-prefix-cls} { + .reset-component; + font-size: 0; + width: 100%; + display: flex; +} + +.@{steps-prefix-cls}-item { + position: relative; + display: inline-block; + vertical-align: top; + flex: 1; + overflow: hidden; + + &:last-child { + flex: none; + } + + &:last-child &-tail, + &:last-child &-title:after { + display: none; + } + + &-icon, + &-content { + display: inline-block; + vertical-align: top; + } + + &-icon { + border: @border-width-base @border-style-base @wait-icon-color; + width: @steps-icon-size; + height: @steps-icon-size; + line-height: @steps-icon-size; + text-align: center; + border-radius: @steps-icon-size; + font-size: @font-size-lg; + margin-right: 8px; + transition: background-color .3s, border-color .3s; + font-family: @font-family-no-number; + + > .@{steps-prefix-cls}-icon { + line-height: 1; + top: -1px; + color: @primary-color; + position: relative; + } + } + &-tail { + position: absolute; + left: 0; + width: 100%; + top: 12px; + padding: 0 10px; + &:after { + content: ''; + display: inline-block; + background: @border-color-split; + height: 1px; + border-radius: 1px; + width: 100%; + transition: background .3s; + } + } + &-title { + font-size: @font-size-lg; + color: @text-color; + display: inline-block; + padding-right: 16px; + position: relative; + line-height: @steps-icon-size; + &:after { + content: ''; + height: 1px; + width: 9999px; + background: @wait-tail-color; + display: block; + position: absolute; + top: @steps-icon-size / 2; + left: 100%; + } + } + &-description { + font-size: @font-size-base; + color: @text-color-secondary; + } + .step-item-status(wait); + .step-item-status(process); + &-process &-icon { + background: @process-icon-color; + > .@{steps-prefix-cls}-icon { + color: @process-icon-text-color; + } + } + &-process &-title { + font-weight: 500; + } + .step-item-status(finish); + .step-item-status(error); + + &.@{steps-prefix-cls}-next-error .@{steps-prefix-cls}-item-title:after { + background: @error-icon-color; + } +} + +.@{steps-prefix-cls}-horizontal:not(.@{steps-prefix-cls}-label-vertical) { + .@{steps-prefix-cls}-item { + margin-right: 16px; + white-space: nowrap; + &:last-child { + margin-right: 0; + } + &:last-child .@{steps-prefix-cls}-item-title { + padding-right: 0; + } + &-tail { + display: none; + } + &-description { + max-width: @steps-desciption-max-width; + } + } +} + +.step-item-status(@status) { + @icon-color: "@{status}-icon-color"; + @title-color: "@{status}-title-color"; + @description-color: "@{status}-description-color"; + @tail-color: "@{status}-tail-color"; + &-@{status} &-icon { + border-color: @@icon-color; + background-color: @steps-background; + > .@{steps-prefix-cls}-icon { + color: @@icon-color; + .@{steps-prefix-cls}-icon-dot { + background: @@icon-color; + } + } + } + &-@{status} > &-content > &-title { + color: @@title-color; + &:after { + background-color: @@tail-color; + } + } + &-@{status} > &-content > &-description { + color: @@description-color; + } + &-@{status} > &-tail:after { + background-color: @@tail-color; + } +} + +@import 'custom-icon'; +@import 'small'; +@import 'vertical'; +@import 'label-placement'; +@import 'progress-dot'; diff --git a/components/steps/style/label-placement.less b/components/steps/style/label-placement.less new file mode 100644 index 000000000..f5a2957b2 --- /dev/null +++ b/components/steps/style/label-placement.less @@ -0,0 +1,28 @@ +.@{steps-prefix-cls}-label-vertical { + .@{steps-prefix-cls}-item { + overflow: visible; + &-tail { + padding: 0 24px; + margin-left: 48px; + } + &-content { + display: block; + text-align: center; + margin-top: 8px; + width: @steps-desciption-max-width; + } + &-icon { + display: inline-block; + margin-left: 36px; + } + &-title { + padding-right: 0; + &:after { + display: none; + } + } + &-description { + text-align: left; + } + } +} diff --git a/components/steps/style/progress-dot.less b/components/steps/style/progress-dot.less new file mode 100644 index 000000000..e7aa109fc --- /dev/null +++ b/components/steps/style/progress-dot.less @@ -0,0 +1,75 @@ +.@{steps-prefix-cls}-dot { + .@{steps-prefix-cls}-item { + &-title { + line-height: @line-height-base; + } + &-tail { + width: 100%; + top: 2px; + margin: 0 0 0 @steps-desciption-max-width / 2; + padding: 0; + &:after { + height: 3px; + width: ~"calc(100% - 20px)"; + margin-left: 12px; + } + } + &:first-child .@{steps-prefix-cls}-icon-dot { + left: 2px; + } + &-icon { + padding-right: 0; + width: @steps-dot-size; + height: @steps-dot-size; + line-height: @steps-dot-size; + border: 0; + margin-left: 67px; + background: transparent; + .@{steps-prefix-cls}-icon-dot { + float: left; + width: 100%; + height: 100%; + border-radius: 100px; + position: relative; + transition: all .3s; + /* expand hover area */ + &:after { + content: ""; + background: rgba(0, 0, 0, .001); + width: 60px; + height: 32px; + position: absolute; + top: -12px; + left: -26px; + } + } + } + &-process .@{steps-prefix-cls}-item-icon { + width: @steps-current-dot-size; + height: @steps-current-dot-size; + line-height: @steps-current-dot-size; + .@{steps-prefix-cls}-icon-dot { + top: -1px; + } + } + } +} + +.@{steps-prefix-cls}-vertical.@{steps-prefix-cls}-dot { + .@{steps-prefix-cls}-item-icon { + margin-left: 0; + margin-top: 8px; + } + .@{steps-prefix-cls}-item-tail { + margin: 0; + left: -9px; + top: 2px; + padding: 22px 0 4px; + } + .@{steps-prefix-cls}-item:first-child .@{steps-prefix-cls}-icon-dot { + left: 0; + } + .@{steps-prefix-cls}-item-process .@{steps-prefix-cls}-icon-dot { + left: -2px; + } +} diff --git a/components/steps/style/small.less b/components/steps/style/small.less new file mode 100644 index 000000000..4bcb22601 --- /dev/null +++ b/components/steps/style/small.less @@ -0,0 +1,45 @@ +.@{steps-prefix-cls}-small { + &.@{steps-prefix-cls}-horizontal:not(.@{steps-prefix-cls}-label-vertical) .@{steps-prefix-cls}-item { + margin-right: 12px; + &:last-child { + margin-right: 0; + } + } + .@{steps-prefix-cls}-item-icon { + width: @steps-small-icon-size; + height: @steps-small-icon-size; + line-height: @steps-small-icon-size; + text-align: center; + border-radius: @steps-small-icon-size; + font-size: @font-size-sm; + } + .@{steps-prefix-cls}-item-title { + font-size: @font-size-base; + line-height: @steps-small-icon-size; + padding-right: 12px; + &:after { + top: @steps-small-icon-size / 2; + } + } + .@{steps-prefix-cls}-item-description { + font-size: @font-size-base; + color: @text-color-secondary; + } + .@{steps-prefix-cls}-item-tail { + top: 8px; + padding: 0 8px; + } + .@{steps-prefix-cls}-item-custom .@{steps-prefix-cls}-item-icon { + width: inherit; + height: inherit; + line-height: inherit; + border-radius: 0; + border: 0; + background: none; + > .@{steps-prefix-cls}-icon { + font-size: @steps-small-icon-size; + line-height: @steps-small-icon-size; + transform: none; + } + } +} diff --git a/components/steps/style/vertical.less b/components/steps/style/vertical.less new file mode 100644 index 000000000..702e8143e --- /dev/null +++ b/components/steps/style/vertical.less @@ -0,0 +1,67 @@ +.steps-vertical() { + display: block; + .@{steps-prefix-cls}-item { + display: block; + overflow: visible; + &-icon { + float: left; + margin-right: 16px; + } + &-content { + min-height: 48px; + overflow: hidden; + display: block; + } + &-title { + line-height: @steps-icon-size; + } + &-description { + padding-bottom: 12px; + } + } + + > .@{steps-prefix-cls}-item > .@{steps-prefix-cls}-item-tail { + position: absolute; + left: 16px; + top: 0; + height: 100%; + width: 1px; + padding: @steps-icon-size + 6px 0 6px; + &:after { + height: 100%; + width: 1px; + } + } + + > .@{steps-prefix-cls}-item:not(:last-child) > .@{steps-prefix-cls}-item-tail { + display: block; + } + + > .@{steps-prefix-cls}-item > .@{steps-prefix-cls}-item-content > .@{steps-prefix-cls}-item-title { + &:after { + display: none; + } + } + + &.@{steps-prefix-cls}-small { + .@{steps-prefix-cls}-item-tail { + position: absolute; + left: 12px; + top: 0; + padding: @steps-small-icon-size + 6px 0 6px; + } + .@{steps-prefix-cls}-item-title { + line-height: @steps-small-icon-size; + } + } +} + +.@{steps-prefix-cls}-vertical { + .steps-vertical; +} + +@media (max-width: @screen-xs) { + .@{steps-prefix-cls}-horizontal.@{steps-prefix-cls}-label-horizontal { + .steps-vertical; + } +} diff --git a/components/vc-pagination/Pagination.vue b/components/vc-pagination/Pagination.vue index 9e37ec597..6cf4b4fec 100644 --- a/components/vc-pagination/Pagination.vue +++ b/components/vc-pagination/Pagination.vue @@ -49,6 +49,7 @@ export default { }, model: { prop: 'current', + event: 'change', }, data () { const hasOnChange = this.onChange !== noop diff --git a/components/vc-steps/Step.vue b/components/vc-steps/Step.vue index 858129eee..b920d04ca 100644 --- a/components/vc-steps/Step.vue +++ b/components/vc-steps/Step.vue @@ -34,9 +34,10 @@ export default { methods: { renderIconNode () { const { - prefixCls, progressDot, stepNumber, status, title, description, icon, + prefixCls, progressDot, stepNumber, status, title, description, iconPrefix, } = getOptionProps(this) + const icon = this.icon || this.$slots.default let iconNode const iconClassName = { [`${prefixCls}-icon`]: true, diff --git a/components/vc-steps/Steps.vue b/components/vc-steps/Steps.vue index 15cdce2c0..3967aa4d9 100644 --- a/components/vc-steps/Steps.vue +++ b/components/vc-steps/Steps.vue @@ -3,8 +3,17 @@ import PropTypes from '../_util/vue-types' import BaseMixin from '../_util/BaseMixin' import debounce from 'lodash/debounce' import isFlexSupported from '../_util/isFlexSupported' -import { getOptionProps, filterEmpty, getEvents, getClass, getStyle, getValueByProp } from '../_util/props-util' -import { cloneElement } from '../_util/vnode' +import { + getOptionProps, + filterEmpty, + getEvents, + getClass, + getStyle, + getValueByProp, + getPropsData, + getComponentFromProp, +} from '../_util/props-util' +import Step from './Step' export default { name: 'Steps', @@ -64,8 +73,8 @@ export default { // +1 for fit edge bug of digit width, like 35.4px const lastStepOffsetWidth = (domNode.lastChild.offsetWidth || 0) + 1 // Reduce shake bug - if (this.state.lastStepOffsetWidth === lastStepOffsetWidth || - Math.abs(this.state.lastStepOffsetWidth - lastStepOffsetWidth) <= 3) { + if (this.lastStepOffsetWidth === lastStepOffsetWidth || + Math.abs(this.lastStepOffsetWidth - lastStepOffsetWidth) <= 3) { return } this.setState({ lastStepOffsetWidth }) @@ -102,6 +111,7 @@ export default {
{ filteredChildren.map((child, index) => { + const childProps = getPropsData(child) let className = getClass(child) // fix tail color if (status === 'error' && index === current - 1) { @@ -124,6 +134,7 @@ export default { } const stepProps = { props: { + ...childProps, stepNumber: `${index + 1}`, prefixCls, iconPrefix, @@ -134,7 +145,7 @@ export default { class: className, style: stepStyle, } - return cloneElement(child, stepProps) + return {getComponentFromProp(child, 'icon')} }) }
diff --git a/components/vc-steps/assets/iconfont.less b/components/vc-steps/assets/iconfont.less index ecbf1b188..f80ba2e82 100644 --- a/components/vc-steps/assets/iconfont.less +++ b/components/vc-steps/assets/iconfont.less @@ -1,4 +1,4 @@ -@icon-url : "//at.alicdn.com/t/font_1434092639_4910953"; +@icon-url : "http://at.alicdn.com/t/font_1434092639_4910953"; .ie-rotate(@rotation) { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); } diff --git a/components/vc-steps/demo/customIcon.vue b/components/vc-steps/demo/customIcon.vue index cf65b54f9..08a81356e 100644 --- a/components/vc-steps/demo/customIcon.vue +++ b/components/vc-steps/demo/customIcon.vue @@ -10,10 +10,11 @@ export default { } }, render () { - const Icon = ({ type }) => return ( - } /> + + + diff --git a/components/vc-steps/demo/dynamic.vue b/components/vc-steps/demo/dynamic.vue new file mode 100644 index 000000000..d6df3f6e6 --- /dev/null +++ b/components/vc-steps/demo/dynamic.vue @@ -0,0 +1,41 @@ + diff --git a/components/vc-steps/demo/errorStep.vue b/components/vc-steps/demo/errorStep.vue new file mode 100644 index 000000000..575f770c9 --- /dev/null +++ b/components/vc-steps/demo/errorStep.vue @@ -0,0 +1,24 @@ + diff --git a/components/vc-steps/demo/nextStep.vue b/components/vc-steps/demo/nextStep.vue new file mode 100644 index 000000000..ba91c61c7 --- /dev/null +++ b/components/vc-steps/demo/nextStep.vue @@ -0,0 +1,70 @@ + + + diff --git a/components/vc-steps/demo/progressDot.vue b/components/vc-steps/demo/progressDot.vue new file mode 100644 index 000000000..a8f8e16a3 --- /dev/null +++ b/components/vc-steps/demo/progressDot.vue @@ -0,0 +1,25 @@ + diff --git a/components/vc-steps/demo/simple.vue b/components/vc-steps/demo/simple.vue new file mode 100644 index 000000000..13197ef93 --- /dev/null +++ b/components/vc-steps/demo/simple.vue @@ -0,0 +1,38 @@ + diff --git a/components/vc-steps/demo/smallSize.vue b/components/vc-steps/demo/smallSize.vue new file mode 100644 index 000000000..0efb30ea7 --- /dev/null +++ b/components/vc-steps/demo/smallSize.vue @@ -0,0 +1,30 @@ + diff --git a/components/vc-steps/demo/vertical.vue b/components/vc-steps/demo/vertical.vue new file mode 100644 index 000000000..9fab2b510 --- /dev/null +++ b/components/vc-steps/demo/vertical.vue @@ -0,0 +1,25 @@ + diff --git a/components/vc-steps/demo/verticalSmall.vue b/components/vc-steps/demo/verticalSmall.vue new file mode 100644 index 000000000..2c9adcf8f --- /dev/null +++ b/components/vc-steps/demo/verticalSmall.vue @@ -0,0 +1,25 @@ + diff --git a/examples/routes.js b/examples/routes.js index ed8f5d208..0b00be869 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-steps/demo/${d}`), + component: import(`../components/steps/demo/${d}`), } } export default [