Steps: add chalk theme (#7274)

* Steps: add chalk theme

* Update steps.md

* Update steps.md

* Update steps.md
This commit is contained in:
Black Wayne 2017-09-28 22:41:59 -05:00 committed by 杨奕
parent d34e38a936
commit 5ce0e22823
7 changed files with 405 additions and 214 deletions

View File

@ -25,7 +25,7 @@ Simple step bar.
:::demo Set `active` attribute with `Number` type, which indicates the index of steps and starts from 0. You can set `space` attribute when the width of the step needs to be fixed which accepts `Boolean` type. The unit of the `space` attribute is `px`. If not set, it is responsive. Setting the `finish-status` attribute can change the state of the steps that have been completed.
```html
<el-steps :space="100" :active="active" finish-status="success">
<el-steps :active="active" finish-status="success">
<el-step title="Step 1"></el-step>
<el-step title="Step 2"></el-step>
<el-step title="Step 3"></el-step>
@ -58,7 +58,7 @@ Shows the status of the step for each step.
:::demo Use `title` attribute to set the name of the step, or override the attribute by using a named `slot`. We have listed all the slot names for you at the end of this page.
```html
<el-steps :space="100" :active="1" finish-status="success">
<el-steps :space="200" :active="1" finish-status="success">
<el-step title="Done"></el-step>
<el-step title="Processing"></el-step>
<el-step title="Step 3"></el-step>
@ -66,13 +66,28 @@ Shows the status of the step for each step.
```
:::
### Center
Title and desription can be centered.
:::demo
```html
<el-steps :active="2" align-center>
<el-step title="Step 1" description="Some description"></el-step>
<el-step title="Step 2" description="Some description"></el-step>
<el-step title="Step 3" description="Some description"></el-step>
<el-step title="Step 4" description="Some description"></el-step>
</el-steps>
```
:::
### Step bar with description
There is description for each step.
:::demo
```html
<el-steps :space="200" :active="1">
<el-steps :active="1">
<el-step title="Step 1" description="Some description"></el-step>
<el-step title="Step 2" description="Some description"></el-step>
<el-step title="Step 3" description="Some description"></el-step>
@ -87,10 +102,10 @@ A variety of custom icons can be used in the step bar.
:::demo The icon is set by the `icon` property. The types of icons can be found in the document for the Icon component. In addition, you can customize the icon through a named `slot`.
```html
<el-steps :space="100" :active="1">
<el-step title="Step 1" icon="edit"></el-step>
<el-step title="Step 2" icon="upload"></el-step>
<el-step title="Step 3" icon="picture"></el-step>
<el-steps :active="1">
<el-step title="Step 1" icon="el-icon-edit"></el-step>
<el-step title="Step 2" icon="el-icon-upload"></el-step>
<el-step title="Step 3" icon="el-icon-picture"></el-step>
</el-steps>
```
:::
@ -102,10 +117,32 @@ Vertical step bars.
:::demo You only need to set the `direction` attribute to` vertical` in the `el-steps` element.
```html
<el-steps :space="100" direction="vertical" :active="1">
<el-step title="Step 1"></el-step>
<el-step title="Step 2"></el-step>
<el-step title="Step 3"></el-step>
<div style="height: 300px;">
<el-steps direction="vertical" :active="1">
<el-step title="Step 1"></el-step>
<el-step title="Step 2"></el-step>
<el-step title="Step 3"></el-step>
</el-steps>
</div>
```
:::
### Simple step bar
Simple step bars, where `align-center`, `description`, `direction` and `space` will be ignored.
:::demo
```html
<el-steps :space="200" active="1" simple>
<el-step title="Step 1" icon="el-icon-edit"></el-step>
<el-step title="Step 2" icon="el-icon-upload"></el-step>
<el-step title="Step 3" icon="el-icon-picture"></el-step>
</el-steps>
<el-steps :active="1" finish-status="success" simple style="margin-top: 20px">
<el-step title="Step 1" ></el-step>
<el-step title="Step 2" ></el-step>
<el-step title="Step 3" ></el-step>
</el-steps>
```
:::
@ -114,21 +151,21 @@ Vertical step bars.
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------- |---------- |------------- |-------- |
| space | the spacing of each step, will be responsive if omitted. Support percentage. | Number,String | — | — |
| space | the spacing of each step, will be responsive if omitted. Supports percentage. | number / string | — | — |
| direction | display direction | string | vertical/horizontal | horizontal |
| active | current activation step | number | — | 0 |
| process-status | status of current step | string | wait/process/finish/error/success | process |
| finish-status | status of end step | string | wait/process/finish/error/success | finish |
| align-center | whether step description is centered | boolean | — | false |
| center | center whole `Steps` component | boolean | - | false |
| process-status | status of current step | string | wait / process / finish / error / success | process |
| finish-status | status of end step | string | wait / process / finish / error / success | finish |
| align-center | center title and description | boolean | — | false |
| simple | whether to apply simple theme | boolean | - | false |
### Step Attributes
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------- |---------- |------------- |-------- |
| title | step title | string | — | — |
| description | step description | string | — | — |
| icon | step icon | icons provided by Element Icon. Can be overwritten by a named slot if you want to use custom icons | string | — |
| status | current status. It will be automatically set by Steps if not configured. | wait/process/finish/error/success | - |
| icon | step icon | step icon's class name. Icons can be passed via named slot as well | string | — |
| status | current status. It will be automatically set by Steps if not configured. | wait / process / finish / error / success | - |
### Step Slot
| Name | Description |

View File

@ -23,7 +23,7 @@
:::demo 设置`active`属性,接受一个`Number`,表明步骤的 index从 0 开始。需要定宽的步骤条时,设置`space`属性即可,它接受`Boolean`,单位为`px`,如果不设置,则为自适应。设置`finish-status`属性可以改变已经完成的步骤的状态。
```html
<el-steps :space="100" :active="active" finish-status="success">
<el-steps :active="active" finish-status="success">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
<el-step title="步骤 3"></el-step>
@ -55,7 +55,7 @@
:::demo 也可以使用`title`具名分发,可以用`slot`的方式来取代属性的设置,在本文档最后的列表中有所有的 slot name 可供参考。
```html
<el-steps :space="100" :active="1" finish-status="success">
<el-steps :space="200" :active="1" finish-status="success">
<el-step title="已完成"></el-step>
<el-step title="进行中"></el-step>
<el-step title="步骤 3"></el-step>
@ -69,10 +69,25 @@
:::demo
```html
<el-steps :space="200" :active="1">
<el-steps :active="1">
<el-step title="步骤 1" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤 2" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤 3" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤 3" description="这段就没那么长了"></el-step>
</el-steps>
```
:::
### 居中的步骤条
标题和描述都将居中。
:::demo
```html
<el-steps :active="2" align-center>
<el-step title="步骤1" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤2" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤3" description="这是一段很长很长很长的描述性文字"></el-step>
<el-step title="步骤4" description="这是一段很长很长很长的描述性文字"></el-step>
</el-steps>
```
:::
@ -82,10 +97,11 @@
:::demo 通过`icon`属性来设置图标,图标的类型可以参考 Icon 组件的文档,除此以外,还能通过具名`slot`来使用自定义的图标。
```html
<el-steps :space="100" :active="1">
<el-step title="步骤 1" icon="edit"></el-step>
<el-step title="步骤 2" icon="upload"></el-step>
<el-step title="步骤 3" icon="picture"></el-step>
<el-steps :active="1">
<el-step title="步骤 1" icon="el-icon-edit"></el-step>
<el-step title="步骤 2" icon="el-icon-upload"></el-step>
<el-step title="步骤 3" icon="el-icon-picture"></el-step>
</el-steps>
```
:::
@ -96,10 +112,32 @@
:::demo 只需要在`el-steps`元素中设置`direction`属性为`vertical`即可。
```html
<el-steps :space="100" direction="vertical" :active="1">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
<el-step title="步骤 3"></el-step>
<div style="height: 300px;">
<el-steps direction="vertical" :active="1">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
<el-step title="步骤 3" description="这是一段很长很长很长的描述性文字"></el-step>
</el-steps>
</div>
```
:::
### 简洁风格的步骤条
设置 `simple` 可应用简洁风格,该条件下 `align-center` / `description` / `direction` / `space` 都将失效。
:::demo
```html
<el-steps :active="1" simple>
<el-step title="步骤 1" icon="el-icon-edit"></el-step>
<el-step title="步骤 2" icon="el-icon-upload"></el-step>
<el-step title="步骤 3" icon="el-icon-picture"></el-step>
</el-steps>
<el-steps :active="1" finish-status="success" simple style="margin-top: 20px">
<el-step title="步骤 1" ></el-step>
<el-step title="步骤 2" ></el-step>
<el-step title="步骤 3" ></el-step>
</el-steps>
```
:::
@ -108,21 +146,21 @@
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| space | 每个 step 的间距,不填写将自适应间距。支持百分比。 | Number,String | — | — |
| space | 每个 step 的间距,不填写将自适应间距。支持百分比。 | number / string | — | — |
| direction | 显示方向 | string | vertical/horizontal | horizontal |
| active | 设置当前激活步骤 | number | — | 0 |
| process-status | 设置当前步骤的状态 | string | wait/process/finish/error/success | process |
| finish-status | 设置结束步骤的状态 | string | wait/process/finish/error/success | finish |
| align-center | 标题描述居中对齐 | boolean | - | false |
| center | 组件居中显示 | boolean | - | false |
| process-status | 设置当前步骤的状态 | string | wait / process / finish / error / success | process |
| finish-status | 设置结束步骤的状态 | string | wait / process / finish / error / success | finish |
| align-center | 进行居中对齐 | boolean | - | false |
| simple | 是否应用简洁风格 | boolean | - | false |
### Step Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| title | 标题 | string | — | — |
| description | 描述性文字 | string | — | — |
| icon | 图标 | Element Icon 提供的图标,如果要使用自定义图标可以通过 slot 方式写入 | string | — |
| status | 设置当前步骤的状态,不设置则根据 steps 确定状态 | wait/process/finish/error/success | - |
| icon | 图标 | 传入 icon 的 class 全名来自定义 icon也支持 slot 方式写入 | string | — |
| status | 设置当前步骤的状态,不设置则根据 steps 确定状态 | wait / process / finish / error / success | - |
### Step Slot
| name | 说明 |

View File

@ -1,41 +1,50 @@
<template>
<div
class="el-step"
:style="[style, isLast ? '' : { marginRight: - $parent.stepOffset + 'px' }]"
:class="['is-' + $parent.direction]">
:style="[style, isLast ? { maxWidth: 100 / stepsCount + '%' } : { marginRight: - $parent.stepOffset + 'px' }]"
:class="[
!isSimple && `is-${$parent.direction}`,
isSimple && 'is-simple',
isLast && !space && !isCenter && 'is-flex',
isCenter && !isVertical && !isSimple && 'is-center'
]">
<!-- icon & line -->
<div
class="el-step__head"
:class="['is-' + currentStatus, { 'is-text': !icon }]">
:class="`is-${currentStatus}`">
<div
class="el-step__line"
:style="isLast ? '' : { marginRight: $parent.stepOffset + 'px' }"
:class="['is-' + $parent.direction, { 'is-icon': icon }]">
>
<i class="el-step__line-inner" :style="lineStyle"></i>
</div>
<span class="el-step__icon">
<div class="el-step__icon" :class="`is-${icon ? 'icon' : 'text'}`">
<slot
v-if="currentStatus !== 'success' && currentStatus !== 'error'"
name="icon">
<i v-if="icon" :class="['el-icon-' + icon]"></i>
<div v-else>{{ index + 1 }}</div>
<i v-if="icon" class="el-step__icon-inner" :class="[icon]"></i>
<div class="el-step__icon-inner" v-if="!icon && !isSimple">{{ index + 1 }}</div>
</slot>
<i
v-else
:class="['el-icon-' + (currentStatus === 'success' ? 'check' : 'close')]">
:class="['el-icon-' + (currentStatus === 'success' ? 'check' : 'close')]"
class="el-step__icon-inner is-status"
>
</i>
</span>
</div>
</div>
<div
class="el-step__main"
:style="{ marginLeft: mainOffset }">
<!-- title & description -->
<div class="el-step__main">
<div
class="el-step__title"
ref="title"
:class="['is-' + currentStatus]">
<slot name="title">{{ title }}</slot>
</div>
<div v-if="isSimple" class="el-step__arrow"></div>
<div
v-else
class="el-step__description"
:class="['is-' + currentStatus]">
<slot name="description">{{ description }}</slot>
@ -59,7 +68,6 @@ export default {
return {
index: -1,
lineStyle: {},
mainOffset: 0,
internalStatus: ''
};
},
@ -84,31 +92,37 @@ export default {
const prevStep = this.$parent.steps[this.index - 1];
return prevStep ? prevStep.currentStatus : 'wait';
},
isLast: function() {
isCenter() {
return this.$parent.alignCenter;
},
isVertical() {
return this.$parent.direction === 'vertical';
},
isSimple() {
return this.$parent.simple;
},
isLast() {
const parent = this.$parent;
return parent.steps[parent.steps.length - 1] === this;
},
stepsCount() {
return this.$parent.steps.length;
},
space() {
const { isSimple, $parent: { space } } = this;
return isSimple ? '' : space ;
},
style: function() {
const parent = this.$parent;
const isCenter = parent.center;
const len = parent.steps.length;
if (isCenter && this.isLast) {
return {};
}
const space = (typeof this.space === 'number'
? this.space + 'px'
: this.space
? this.space
: 100 / (len - 1) + '%');
const space = (typeof parent.space === 'number'
? parent.space + 'px'
: parent.space
? parent.space
: 100 / (isCenter ? len - 1 : len) + '%');
if (parent.direction === 'horizontal') {
return { width: space };
} else {
if (!this.isLast) {
return { height: space };
}
}
return { flexBasis: space };
}
},
@ -133,7 +147,7 @@ export default {
style.transitionDelay = 150 * this.index + 'ms';
if (status === this.$parent.processStatus) {
step = this.currentStatus !== 'error' ? 50 : 0;
step = this.currentStatus !== 'error' ? 0 : 0;
} else if (status === 'wait') {
step = 0;
style.transitionDelay = (-150 * this.index) + 'ms';
@ -149,14 +163,6 @@ export default {
},
mounted() {
const parent = this.$parent;
if (parent.direction === 'horizontal') {
if (parent.alignCenter) {
this.mainOffset = -this.$refs.title.getBoundingClientRect().width / 2 + 16 + 'px';
}
}
const unwatch = this.$watch('index', val => {
this.$watch('$parent.active', this.updateStatus, { immediate: true });
unwatch();

View File

@ -1,8 +1,11 @@
<template>
<div
class="el-steps"
:class="['is-' + direction, center ? 'is-center' : '']">
<slot></slot>
:class="[
!simple && 'el-steps--' + direction,
simple && 'el-steps--simple'
]">
<slot></slot>
</div>
</template>
@ -19,6 +22,7 @@ export default {
},
alignCenter: Boolean,
center: Boolean,
simple: Boolean,
finishStatus: {
type: String,
default: 'finish'

View File

@ -3,131 +3,37 @@
@include b(step) {
position: relative;
vertical-align: top;
flex-shrink: 1;
&:last-child .el-step__main {
padding-right: 0;
}
@include when(horizontal) {
display: inline-block;
}
@include when(vertical) {
& .el-step__head,
& .el-step__main {
display: inline-block;
@include pseudo(last-of-type) {
@include e(line) {
display: none;
}
& .el-step__main {
padding-left: 10px;
}
}
@include e(line) {
display: inline-block;
position: absolute;
border-color: inherit;
background-color: $--color-black;
@include when(icon) {
@include when(horizontal) {
right: 4px;
}
// 只有未设置 space 的情况下才自适应宽度
@include when(flex) {
flex-basis: auto !important;
flex-shrink: 0;
flex-grow: 0;
}
@include when(horizontal) {
top: 15px;
height: 2px;
left: 32px;
right: 0;
}
@include when(vertical) {
width: 2px;
box-sizing: border-box;
top: 32px;
bottom: 0;
left: 15px;
}
}
@include e(line-inner) {
display: block;
border-width: 1px;
border-style: solid;
border-color: inherit;
transition: all 150ms;
box-sizing: border-box;
width: 0;
height: 0;
}
@include e(icon) {
display: block;
line-height: 28px;
> * {
line-height: inherit;
vertical-align: middle;
@include e((main, description)) {
padding-right: 0;
}
}
@include e(head) {
width: 28px;
height: 28px;
border-radius: 50%;
border-color: transparent;
text-align: center;
line-height: 28px;
font-size: 28px;
vertical-align: top;
transition: all 150ms;
@include when(text) {
font-size: 14px;
border-width: 2px;
border-style: solid;
@include when(process) {
color: $--color-white;
background-color: $--color-black;
border-color: $--color-black;
}
@include when(wait) {
color: $--color-black;
background-color: $--color-white;
border-color: $--color-black;
}
@include when(success) {
color: $--color-white;
background-color: $--color-success;
border-color: $--color-success;
}
@include when(error) {
color: $--color-white;
background-color: $--color-danger;
border-color: $--color-danger;
}
@include when(finish) {
color: $--color-white;
background-color: $--color-primary;
border-color: $--color-primary;
}
}
position: relative;
width: 100%;
@include when(process) {
color: $--color-black;
border-color: $--color-black;
color: $--color-text-primary;
border-color: $--color-text-primary;
}
@include when(wait) {
color: $--color-black;
border-color: $--color-black;
color: $--color-text-placeholder;
border-color: $--color-text-placeholder;
}
@include when(success) {
@ -146,54 +52,110 @@
}
}
@include e(icon) {
position: relative;
z-index: 1;
display: inline-flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
font-size: 14px;
box-sizing: border-box;
background: $--color-white;
transition: .15s ease-out;
@include when(text) {
border-radius: 50%;
border: 2px solid;
border-color: inherit;
}
@include when(icon) {
width: 40px;
}
}
@include e(icon-inner) {
display: inline-block;
user-select: none;
text-align: center;
font-weight: bold;
line-height: 1;
color: inherit;
&[class*=el-icon]:not(.is-status) {
font-size: 25px;
font-weight: normal;
}
// 组件自身表示状态的图标
@include when(status) {
transform: scale(.65) translateY(1px);
}
}
@include e(line) {
position: absolute;
border-color: inherit;
background-color: $--color-text-placeholder;
}
@include e(line-inner) {
display: block;
border-width: 1px;
border-style: solid;
border-color: inherit;
transition: .15s ease-out;
box-sizing: border-box;
width: 0;
height: 0;
}
@include e(main) {
white-space: normal;
padding-right: 10px;
text-align: left;
}
@include e(title) {
font-size: 14px;
line-height: 32px;
display: inline-block;
font-size: 15px;
line-height: 38px;
@include when(process) {
font-weight: 700;
color: $--color-black;
font-weight: bold;
color: $--color-text-primary;
}
@include when(wait) {
font-weight: normal;
color: $--color-black;
color: $--color-text-placeholder;
}
@include when(success) {
font-weight: 700;
color: $--color-success;
}
@include when(error) {
font-weight: 700;
color: $--color-danger;
}
@include when(finish) {
font-weight: 700;
color: $--color-primary;
}
}
@include e(description) {
padding-right: 10%;
margin-top: -5px;
font-size: 12px;
line-height: 20px;
font-weight: normal;
line-height: 14px;
@include when(process) {
color: $--color-black;
color: $--color-text-primary;
}
@include when(wait) {
color: $--color-black;
color: $--color-text-placeholder;
}
@include when(success) {
@ -208,4 +170,146 @@
color: $--color-primary;
}
}
@include when(horizontal) {
display: inline-block;
@include e(line) {
height: 2px;
top: 11px;
left: 0;
right: 0;
}
}
@include when(vertical) {
display: flex;
@include e(head) {
flex-grow: 0;
width: 24px;
}
@include e(main) {
padding-left: 10px;
flex-grow: 1;
}
@include e(title) {
line-height: 24px;
padding-bottom: 8px;
}
@include e(line) {
width: 2px;
top: 0;
bottom: 0;
left: 11px;
}
}
@include when(center) {
@include e(head) {
text-align: center;
}
@include e(main) {
text-align: center;
}
@include e(description) {
padding-left: 20%;
padding-right: 20%;
}
@include e(line) {
left: 50%;
right: -50%;
}
}
@include when(simple) {
display: flex;
align-items: center;
@include e(head) {
width: auto;
font-size: 0;
padding-right: 10px;
}
@include e(icon) {
background: transparent;
width: 16px;
height: 16px;
font-size: 12px;
@include when(icon) {
width: 30px;
}
}
@include e(icon-inner) {
&[class*=el-icon]:not(.is-status) {
font-size: 18px;
}
&.is-status {
transform: scale(.5) translateY(1px);
}
}
@include e(main) {
position: relative;
display: flex;
align-items: stretch;
flex-grow: 1;
}
@include e(title) {
font-size: 16px;
line-height: 20px;
}
@include pseudo('not(:last-of-type)') {
@include e(title) {
max-width: 50%;
word-break: break-all;
}
}
@include e(arrow) {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
&::before,
&::after {
content: '';
display: inline-block;
position: absolute;
height: 15px;
width: 1px;
background: $--color-text-placeholder;
}
&::before {
transform: rotate(-45deg) translateY(-4px);
transform-origin: 0 0;
}
&::after {
transform: rotate(45deg) translateY(4px);
transform-origin: 100% 100%;
}
}
@include pseudo(last-of-type) {
@include e(arrow) {
display: none;
}
}
}
}

View File

@ -1,17 +1,20 @@
@import "mixins/mixins";
@include b(steps) {
font-size: 0;
display: flex;
> :last-child .el-step__line {
display: none;
@include m(simple) {
padding: 13px 8%;
border-radius: 4px;
background: $--background-color-base;
}
@include when(horizontal) {
@include m(horizontal) {
white-space: nowrap;
}
@include when(center) {
text-align: center;
}
@include m(vertical) {
height: 100%;
flex-flow: column;
}
}

View File

@ -25,7 +25,6 @@ describe('Steps', () => {
<el-step title="step1"></el-step>
<el-step title="step2"></el-step>
<el-step title="step3"></el-step>
<el-step title="step4"></el-step>
</el-steps>
`);
@ -39,8 +38,8 @@ describe('Steps', () => {
`);
Vue.nextTick(_ => {
expect(vm.$el.querySelector('.el-step')).have.deep.property('style.width').equal('25%');
expect(vm2.$el.querySelector('.el-step')).have.deep.property('style.width').equal('100px');
expect(vm.$el.querySelector('.el-step')).have.deep.property('style.webkitFlexBasis').equal('50%');
expect(vm2.$el.querySelector('.el-step')).have.deep.property('style.webkitFlexBasis').equal('100px');
done();
});
});
@ -118,7 +117,7 @@ describe('Steps', () => {
`);
vm.$nextTick(_ => {
expect(vm.$el.querySelector('.el-step')).have.deep.property('style.height').equal('200px');
expect(vm.$el.querySelector('.el-step')).have.deep.property('style.webkitFlexBasis').equal('200px');
done();
});
});