Merge branch 'hotfix/add_progress_tests' into 'master'

Hotfix/add progress tests

增加unit tests
优化toast

See merge request !18
This commit is contained in:
pangxie 2017-03-22 17:24:38 +08:00
commit 5c41e13357
15 changed files with 384 additions and 50 deletions

15
docs/build/0.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

13
docs/dist/0.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,10 +3,22 @@
<zan-button @click="showLoadingToast">加载Toast</zan-button> <zan-button @click="showLoadingToast">加载Toast</zan-button>
<zan-button @click="showSuccessToast">成功</zan-button> <zan-button @click="showSuccessToast">成功</zan-button>
<zan-button @click="showFailToast">失败</zan-button> <zan-button @click="showFailToast">失败</zan-button>
<zan-button @click="showForbidClickToast">背景不能点击</zan-button>
<zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button> <zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button>
</example-block><example-block title="手动关闭">
<zan-button @click="showToast">打开</zan-button>
<zan-button @click="closeToast">关闭</zan-button>
</example-block><example-block title="手动关闭">
<zan-button @click="showHtmlToast">打开</zan-button>
</example-block></section></template> </example-block></section></template>
<style> <style>
@component-namespace demo { @component-namespace demo {
@ -35,6 +47,12 @@ export default {
showFailToast() { showFailToast() {
Toast.fail('失败文案'); Toast.fail('失败文案');
}, },
showForbidClickToast() {
Toast({
message: '背景不能点击',
forbidClick: true
})
},
showCustomizedToast(duration) { showCustomizedToast(duration) {
let leftSec = duration / 1000; let leftSec = duration / 1000;
let toast = Toast({ let toast = Toast({
@ -50,6 +68,18 @@ export default {
} }
toast.message = (--leftSec).toString(); toast.message = (--leftSec).toString();
}, 1000); }, 1000);
},
showToast() {
this.toast = Toast('我是提示文案,建议不超过十五字~');
},
closeToast() {
this.toast.clear();
},
showHtmlToast() {
Toast({
type: 'html',
message: '<em>HTML<em>'
})
} }
} }
}; };

View File

@ -25,6 +25,12 @@ export default {
showFailToast() { showFailToast() {
Toast.fail('失败文案'); Toast.fail('失败文案');
}, },
showForbidClickToast() {
Toast({
message: '背景不能点击',
forbidClick: true
})
},
showCustomizedToast(duration) { showCustomizedToast(duration) {
let leftSec = duration / 1000; let leftSec = duration / 1000;
let toast = Toast({ let toast = Toast({
@ -40,6 +46,18 @@ export default {
} }
toast.message = (--leftSec).toString(); toast.message = (--leftSec).toString();
}, 1000); }, 1000);
},
showToast() {
this.toast = Toast('我是提示文案,建议不超过十五字~');
},
closeToast() {
this.toast.clear();
},
showHtmlToast() {
Toast({
type: 'html',
message: '<em>HTML<em>'
})
} }
} }
}; };
@ -55,6 +73,7 @@ export default {
<zan-button @click="showLoadingToast">加载Toast</zan-button> <zan-button @click="showLoadingToast">加载Toast</zan-button>
<zan-button @click="showSuccessToast">成功</zan-button> <zan-button @click="showSuccessToast">成功</zan-button>
<zan-button @click="showFailToast">失败</zan-button> <zan-button @click="showFailToast">失败</zan-button>
<zan-button @click="showForbidClickToast">背景不能点击</zan-button>
<zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button> <zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button>
<script> <script>
@ -74,6 +93,12 @@ export default {
showFailToast() { showFailToast() {
Toast.fail('失败文案'); Toast.fail('失败文案');
}, },
showForbidClickToast() {
Toast({
message: '背景不能点击',
forbidClick: true
})
},
showCustomizedToast(duration) { showCustomizedToast(duration) {
let leftSec = duration / 1000; let leftSec = duration / 1000;
let toast = Toast({ let toast = Toast({
@ -96,9 +121,96 @@ export default {
``` ```
::: :::
### API ### 手动关闭
:::demo 手动关闭
```html
<zan-button @click="showToast">打开</zan-button>
<zan-button @click="closeToast">关闭</zan-button>
<script>
import { Toast } from 'src/index';
export default {
methods: {
showToast() {
this.toast = Toast('我是提示文案,建议不超过十五字~');
},
closeToast() {
this.toast.clear();
}
}
};
</script>
```
:::
### 传入html
:::demo 手动关闭
```html
<zan-button @click="showHtmlToast">打开</zan-button>
<script>
import { Toast } from 'src/index';
export default {
methods: {
showHtmlToast() {
Toast({
type: 'html',
message: '<em>HTML<em>'
})
}
}
};
</script>
```
:::
### 基础用法
### Toast(options)
| 参数 | 说明 | 类型 | 默认值 | 可选值 | | 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------| |-----------|-----------|-----------|-------------|-------------|
| type | 类型 | `string` | `text` | `text`, `loading`, `success`, `failure` | | type | 类型 | String | 'text' | 'text', 'loading', 'success', 'fail', 'html' |
| message | 内容 | `string` | | - | | message | 内容 | String | '' | - |\| message | 内容 | String | '' | -
| forbidClick | 不允许背景点击 | Boolean | false | true, false|
| duration | 时长(ms) | Number | 3000ms | -|
### 快速用法
### Toast(message) || Toast(message, options)
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| message | 内容 | String | '' | - |
| forbidClick | 不允许背景点击 | Boolean | false | true, false|
| duration | 时长(ms) | Number | 3000ms | -|
### Toast.loading() || Toast.loading(message, options)
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| forbidClick | 不允许背景点击 | Boolean | false | true, false|
| duration | 时长(ms) | Number | 3000ms | -|
### Toast.success(message) || Toast.success(message, options)
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| type | 类型 | String | 'text' | 'text', 'loading', 'success', 'failure' |
| forbidClick | 不允许背景点击 | Boolean | false | true, false|
| duration | 时长(ms) | Number | 3000ms | -|
### Toast.fail(message) || Toast.fail(message, options)
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| type | 类型 | String | 'text' | 'text', 'loading', 'success', 'failure' |
| forbidClick | 不允许背景点击 | Boolean | false | true, false|
| duration | 时长(ms) | Number | 3000ms | -|
### instanceOfToast.clear()
关闭toast。

View File

@ -2,9 +2,7 @@
<div class="zan-progress"> <div class="zan-progress">
<div class="zan-progress__bar"> <div class="zan-progress__bar">
<span class="zan-progress__bar__finished-portion" :style="{backgroundColor: componentColor, width: percentage + '%'}"></span> <span class="zan-progress__bar__finished-portion" :style="{backgroundColor: componentColor, width: percentage + '%'}"></span>
<span class="zan-progress__bar__pivot" :style="pivotStyle"> <span class="zan-progress__bar__pivot" :style="pivotStyle">{{currentPivotText}}</span>
{{pivotText}}
</span>
</div> </div>
</div> </div>
</template> </template>
@ -29,7 +27,7 @@ export default {
props: { props: {
percentage: { percentage: {
type: Number, type: Number,
default: 0, required: true,
validate(value) { validate(value) {
return value <= 100 && value >= 0; return value <= 100 && value >= 0;
} }
@ -55,6 +53,9 @@ export default {
}, },
computed: { computed: {
currentPivotText() {
return this.pivotText ? this.pivotText : this.this.percentage.toString() + '%';
},
componentColor() { componentColor() {
return this.inactive ? '#cacaca' : this.color; return this.inactive ? '#cacaca' : this.color;
}, },
@ -65,7 +66,6 @@ export default {
left: this.percentage + '%', left: this.percentage + '%',
marginLeft: '-14px' marginLeft: '-14px'
}; };
console.log(this.percentage);
if (this.percentage <= 5) { if (this.percentage <= 5) {
pivotStyle.left = '0%'; pivotStyle.left = '0%';
pivotStyle.marginLeft = '0'; pivotStyle.marginLeft = '0';

View File

@ -36,16 +36,20 @@ var Toast = (options = {}) => {
clearTimeout(instance.timer); clearTimeout(instance.timer);
instance.type = options.type ? options.type : 'text'; instance.type = options.type ? options.type : 'text';
instance.message = typeof options === 'string' ? options : options.message; instance.message = typeof options === 'string' ? options : options.message;
instance.forbidClick = options.forbidClick ? options.forbidClick : false;
instance.clear = () => {
if (instance.closed) return;
instance.visible = false;
instance.$el.addEventListener('transitionend', removeDom);
instance.closed = true;
};
document.body.appendChild(instance.$el); document.body.appendChild(instance.$el);
Vue.nextTick(function() { Vue.nextTick(function() {
instance.visible = true; instance.visible = true;
instance.$el.removeEventListener('transitionend', removeDom); instance.$el.removeEventListener('transitionend', removeDom);
instance.timer = setTimeout(function() { instance.timer = setTimeout(function() {
if (instance.closed) return; instance.clear();
instance.visible = false;
instance.$el.addEventListener('transitionend', removeDom);
instance.closed = true;
}, duration); }, duration);
}); });
return instance; return instance;

View File

@ -1,9 +1,10 @@
<template> <template>
<transition name="zan-toast"> <transition name="zan-toast">
<div class="zan-toast" :class="['zan-toast--' + displayStyle]" v-show="visible"> <div class="zan-toast-wrapper" v-show="visible">
<div class="zan-toast" :class="['zan-toast--' + displayStyle]">
<!-- 只显示文字 --> <!-- 只显示文字 -->
<template v-if="displayStyle === 'text'" > <template v-if="displayStyle === 'text'" >
<div class="zan-toast__text" v-html="message"></div> <div class="zan-toast__text">{{message}}</div>
</template> </template>
<!-- 加载中 --> <!-- 加载中 -->
<template v-if="displayStyle === 'loading'"> <template v-if="displayStyle === 'loading'">
@ -11,10 +12,16 @@
</template> </template>
<!-- 图案加文字 --> <!-- 图案加文字 -->
<template v-if="displayStyle === 'default'"> <template v-if="displayStyle === 'default'">
<zan-icon class="zan-toast__icon" name="check"></zan-icon> <zan-icon class="zan-toast__icon" :name="type"></zan-icon>
<div class="zan-toast__text">{{message}}</div>
</template>
<!-- 传入html -->
<template v-if="displayStyle === 'html'">
<div class="zan-toast__text" v-html="message"></div> <div class="zan-toast__text" v-html="message"></div>
</template> </template>
</div> </div>
<div class="zan-toast__overlay" v-if="forbidClick"></div>
</div>
</transition> </transition>
</template> </template>
@ -22,7 +29,8 @@
import zanLoading from 'packages/loading'; import zanLoading from 'packages/loading';
import zanIcon from 'packages/icon'; import zanIcon from 'packages/icon';
const TOAST_TYPES = ['text', 'loading', 'success', 'fail']; const TOAST_TYPES = ['text', 'html', 'loading', 'success', 'fail'];
const DEFAULT_STYLE_LIST = ['success', 'fail'];
/** /**
* zan-toast * zan-toast
* @module components/toast * @module components/toast
@ -54,6 +62,10 @@ export default {
return value.length <= 16; return value.length <= 16;
} }
} }
},
forbidClick: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -63,18 +75,7 @@ export default {
}, },
computed: { computed: {
displayStyle() { displayStyle() {
switch (this.type) { return DEFAULT_STYLE_LIST.indexOf(this.type) > -1 ? 'default' : this.type;
case 'text':
return 'text';
case 'loading':
return 'loading';
default:
return 'default';
}
},
iconName() {
// TODO: icon
return 'check';
} }
} }
}; };

View File

@ -3,7 +3,7 @@
@component-namespace zan { @component-namespace zan {
@b toast { @b toast {
position: fixed; position: fixed;
z-index: 3000; z-index: 3001;
border-radius: 5px; border-radius: 5px;
background-color: #272727; background-color: #272727;
opacity: .7; opacity: .7;
@ -13,12 +13,23 @@
font-size: 12px; font-size: 12px;
color: $c-white; color: $c-white;
text-align: center; text-align: center;
line-height: 12px;
@e overlay {
position: fixed;
left: 0;
top: 0;
background: transparent;
height: 100vh;
width: 100vh;
z-index: 3000;
}
@m loading { @m loading {
padding: 45px; padding: 45px;
} }
@m text { @m text, html {
padding: 12px; padding: 12px;
min-width: 200px; min-width: 200px;
} }
@ -26,12 +37,15 @@
@m default { @m default {
width: 120px; width: 120px;
height: 120px; height: 120px;
.zan-toast__icon { .zan-toast__icon {
padding: 20px; padding-top: 20px;
font-size: 36px; font-size: 50px;
} }
.zan-toast__text { .zan-toast__text {
padding-bottom: 20px; padding-bottom: 20px;
font-size: 14px;
} }
} }
} }

View File

@ -0,0 +1,82 @@
import Progress from 'packages/progress';
import { mount } from 'avoriaz';
describe('Progress', () => {
let wrapper;
let bar;
let pivot;
const initProgressBar = function(propsData) {
wrapper = mount(Progress, {
propsData: propsData
});
bar = wrapper.find('.zan-progress__bar__finished-portion')[0];
pivot = wrapper.find('.zan-progress__bar__pivot')[0];
};
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create active 3% progress bar', () => {
initProgressBar({ percentage: 3 });
expect(wrapper.hasClass('zan-progress')).to.be.true;
expect(bar.is('span')).to.be.true;
expect(bar.hasStyle('width', '3%'));
expect(pivot.is('span')).to.be.true;
expect(pivot.hasStyle('left', '0%'));
expect(pivot.hasStyle('marginLeft', '0'));
expect(pivot.text()).to.equal('3%');
});
it('create active 35% progress bar', () => {
initProgressBar({ percentage: 35 });
expect(wrapper.hasClass('zan-progress')).to.be.true;
expect(bar.is('span')).to.be.true;
expect(bar.hasStyle('width', '35%'));
expect(pivot.is('span')).to.be.true;
expect(pivot.hasStyle('left', '35%'));
expect(pivot.hasStyle('marginLeft', '-14px'));
expect(pivot.text()).to.equal('35%');
});
it('create active 98% progress bar', () => {
initProgressBar({ percentage: 98 });
expect(wrapper.hasClass('zan-progress')).to.be.true;
expect(bar.is('span')).to.be.true;
expect(bar.hasStyle('width', '98%'));
expect(pivot.is('span')).to.be.true;
expect(pivot.hasStyle('left', '100%'));
expect(pivot.hasStyle('marginLeft', '-28px'));
expect(pivot.text()).to.equal('98%');
});
it('create inactive 35% progress bar', () => {
initProgressBar({ percentage: 35, inactive: true });
expect(pivot.hasStyle('backgroundColor', '#cacaca'));
});
it('create progress bar with custom text', () => {
initProgressBar({ percentage: 35, pivotText: 'pivotText' });
expect(pivot.text()).to.equal('pivotText');
});
it('create progress bar with custom color', () => {
initProgressBar({ percentage: 35, color: 'red' });
expect(pivot.hasStyle('backgroundColor', 'red'));
});
it('create progress bar with text color', () => {
initProgressBar({ percentage: 35, textColor: 'red' });
expect(pivot.hasStyle('color', 'red'));
});
});

View File

@ -1,7 +1,6 @@
import Switch from 'packages/switch'; import Switch from 'packages/switch';
import ZanLoading from 'packages/loading'; import ZanLoading from 'packages/loading';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
// import { stub } from 'sinon';
describe('Switch', () => { describe('Switch', () => {
let wrapper; let wrapper;

View File

@ -0,0 +1,36 @@
import Toast from 'packages/toast';
import { mount } from 'avoriaz';
describe('Toast', () => {
it('create simple toast', () => {
Toast('a message');
var toast = document.querySelector('.zan-toast');
expect(toast).not.to.be.underfined;
setTimeout(() => {
expect(toast.hidden).to.be.true;
}, 301);
});
it('create loading toast', () => {
Toast.loading('');
var toast = document.querySelector('.zan-toast');
expect(toast).not.to.be.underfined;
setTimeout(() => {
expect(toast.hidden).to.be.true;
}, 301);
});
it('create loading toast', () => {
Toast.success('');
var toast = document.querySelector('.zan-toast');
expect(toast).not.to.be.underfined;
setTimeout(() => {
expect(toast.hidden).to.be.true;
}, 301);
});
});