This commit is contained in:
Ivan
2021-06-07 11:56:04 +08:00
commit c3c9fee2fb
1071 changed files with 195655 additions and 0 deletions

69
packages/steps/README.md Normal file
View File

@@ -0,0 +1,69 @@
# element-steps
> A element-steps component for Vue.js.
## Demo
http://element-component.github.io/element-steps
## Installation
```shell
npm i element-steps -D
```
## Usage
```javascript
import Vue from 'vue'
import ElStep from 'element-steps'
import 'element-theme-chalk/dist/step.css'
Vue.use(ElStep)
```
or
```javascript
import Vue from 'vue'
import { ElSteps, ElStep } from 'element-steps'
Vue.component('el-steps', ElSteps)
Vue.component('el-step', ElStep)
```
### Steps Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| space | 每个 step 的间距,不填写将自适应间距 | Number | — | — |
| 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 |
### Step Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| title | 标题 | string | — | — |
| description | 描述性文字 | string | — | — |
| icon | 图标 | Element Icon 提供的图标,如果要使用自定义图标可以通过 slot 方式写入 | string | — |
### Step Slot
| name | 说明 |
|----|----|
| icon | 图标 |
| title | 标题 |
| description | 描述性文字 |
## Development
```shell
make dev
## test
make test
## build
make build
```
# License
[MIT](https://opensource.org/licenses/MIT)

8
packages/steps/index.js Normal file
View File

@@ -0,0 +1,8 @@
import Steps from './src/steps';
/* istanbul ignore next */
Steps.install = function(Vue) {
Vue.component(Steps.name, Steps);
};
export default Steps;

184
packages/steps/src/step.vue Normal file
View File

@@ -0,0 +1,184 @@
<template>
<div
class="el-step"
:style="style"
: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}`">
<div
class="el-step__line"
:style="isLast ? '' : { marginRight: $parent.stepOffset + 'px' }"
>
<i class="el-step__line-inner" :style="lineStyle"></i>
</div>
<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-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-step__icon-inner is-status"
>
</i>
</div>
</div>
<!-- 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>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ElStep',
props: {
title: String,
icon: String,
description: String,
status: String
},
data() {
return {
index: -1,
lineStyle: {},
internalStatus: ''
};
},
beforeCreate() {
this.$parent.steps.push(this);
},
beforeDestroy() {
const steps = this.$parent.steps;
const index = steps.indexOf(this);
if (index >= 0) {
steps.splice(index, 1);
}
},
computed: {
currentStatus() {
return this.status || this.internalStatus;
},
prevStatus() {
const prevStep = this.$parent.steps[this.index - 1];
return prevStep ? prevStep.currentStatus : 'wait';
},
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 style = {};
const parent = this.$parent;
const len = parent.steps.length;
const space = (typeof this.space === 'number'
? this.space + 'px'
: this.space
? this.space
: 100 / (len - (this.isCenter ? 0 : 1)) + '%');
style.flexBasis = space;
if (this.isVertical) return style;
if (this.isLast) {
style.maxWidth = 100 / this.stepsCount + '%';
} else {
style.marginRight = -this.$parent.stepOffset + 'px';
}
return style;
}
},
methods: {
updateStatus(val) {
const prevChild = this.$parent.$children[this.index - 1];
if (val > this.index) {
this.internalStatus = this.$parent.finishStatus;
} else if (val === this.index && this.prevStatus !== 'error') {
this.internalStatus = this.$parent.processStatus;
} else {
this.internalStatus = 'wait';
}
if (prevChild) prevChild.calcProgress(this.internalStatus);
},
calcProgress(status) {
let step = 100;
const style = {};
style.transitionDelay = 150 * this.index + 'ms';
if (status === this.$parent.processStatus) {
step = this.currentStatus !== 'error' ? 0 : 0;
} else if (status === 'wait') {
step = 0;
style.transitionDelay = (-150 * this.index) + 'ms';
}
style.borderWidth = step && !this.isSimple ? '1px' : 0;
this.$parent.direction === 'vertical'
? style.height = step + '%'
: style.width = step + '%';
this.lineStyle = style;
}
},
mounted() {
const unwatch = this.$watch('index', val => {
this.$watch('$parent.active', this.updateStatus, { immediate: true });
this.$watch('$parent.processStatus', () => {
const activeIndex = this.$parent.active;
this.updateStatus(activeIndex);
}, { immediate: true });
unwatch();
});
}
};
</script>

View File

@@ -0,0 +1,68 @@
<template>
<div
class="el-steps"
:class="[
!simple && 'el-steps--' + direction,
simple && 'el-steps--simple'
]">
<slot></slot>
</div>
</template>
<script>
import Migrating from 'element-ui/src/mixins/migrating';
export default {
name: 'ElSteps',
mixins: [Migrating],
props: {
space: [Number, String],
active: Number,
direction: {
type: String,
default: 'horizontal'
},
alignCenter: Boolean,
simple: Boolean,
finishStatus: {
type: String,
default: 'finish'
},
processStatus: {
type: String,
default: 'process'
}
},
data() {
return {
steps: [],
stepOffset: 0
};
},
methods: {
getMigratingConfig() {
return {
props: {
'center': 'center is removed.'
}
};
}
},
watch: {
active(newVal, oldVal) {
this.$emit('change', newVal, oldVal);
},
steps(steps) {
steps.forEach((child, index) => {
child.index = index;
});
}
}
};
</script>