mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
Merge branch 'master' of gitlab.qima-inc.com:fe/zanui-vue
This commit is contained in:
commit
5120356351
@ -23,7 +23,8 @@ module.exports = {
|
||||
document: false,
|
||||
navigator: false,
|
||||
window: false,
|
||||
require: true
|
||||
require: true,
|
||||
FileReader: true
|
||||
},
|
||||
|
||||
rules: {
|
||||
|
@ -31,6 +31,9 @@
|
||||
"actionsheet": "./packages/actionsheet/index.js",
|
||||
"quantity": "./packages/quantity/index.js",
|
||||
"progress": "./packages/progress/index.js",
|
||||
"toast": "./packages/toast/index.js",
|
||||
"uploader": "./packages/uploader/index.js",
|
||||
"swipe": "./packages/swipe/index.js",
|
||||
"swipe-item": "./packages/swipe-item/index.js"
|
||||
"swipe-item": "./packages/swipe-item/index.js",
|
||||
"datetime-picker": "./packages/datetime-picker/index.js"
|
||||
}
|
||||
|
@ -4,6 +4,9 @@
|
||||
<i class="zan-icon zan-icon-arrow"></i>
|
||||
</router-link>
|
||||
<router-view></router-view>
|
||||
<div class="footer">
|
||||
<img src="https://b.yzcdn.cn/v2/image/wap/zanui-logo.png" alt="logo" class="zanui-logo">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -43,8 +46,16 @@ export default {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body, html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.examples-container {
|
||||
padding-bottom: 30px;
|
||||
padding-bottom: 10px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background: #f9fafb;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-back {
|
||||
@ -76,4 +87,17 @@ export default {
|
||||
font-size: 16px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
width: 100%;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.zanui-logo {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 150px;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
2
docs/build/0.js
vendored
2
docs/build/0.js
vendored
File diff suppressed because one or more lines are too long
2
docs/build/1.js
vendored
2
docs/build/1.js
vendored
@ -1 +1 @@
|
||||
webpackJsonp([1],{250:function(t,e,a){a(455);var i=a(0)(a(264),a(401),null,null);t.exports=i.exports},264:function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var n=a(28),s=i(n);e.default={data:function(){return{highlights:[],navState:[],data:s.default["zh-CN"],base:"/component"}}}},309:function(t,e,a){e=t.exports=a(16)(),e.push([t.i,".side-nav{width:100%;box-sizing:border-box;padding:40px 20px;background:#f9fafb}.side-nav li{list-style:none}.side-nav ul{padding:0;margin:0;overflow:hidden}.side-nav .nav-item a{font-size:16px;color:#5e6d82;line-height:40px;height:40px;margin:0;padding:0;text-decoration:none;display:block;position:relative;-webkit-transition:all .3s;transition:all .3s}.side-nav .nav-item a.active{color:#20a0ff}.side-nav .nav-item .nav-item a{display:block;height:40px;line-height:40px;font-size:13px;padding-left:24px}.side-nav .nav-item .nav-item a:hover{color:#20a0ff}.side-nav .nav-group__title{font-size:12px;color:#99a9bf;padding-left:8px;line-height:26px;margin-top:10px}",""])},401:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"side-nav"},[a("ul",t._l(t.data,function(e){return a("li",{staticClass:"nav-item"},[e.path?a("router-link",{attrs:{"active-class":"active",to:t.base+e.path,exact:""},domProps:{textContent:t._s(e.title||e.name)}}):a("a",[t._v(t._s(e.name))]),t._v(" "),e.children?a("ul",{staticClass:"pure-menu-list sub-nav"},t._l(e.children,function(e){return a("li",{staticClass:"nav-item"},[a("router-link",{attrs:{"active-class":"active",to:t.base+e.path},domProps:{textContent:t._s(e.title||e.name)}})],1)})):t._e(),t._v(" "),e.groups?t._l(e.groups,function(e){return a("div",{staticClass:"nav-group"},[a("div",{staticClass:"nav-group__title"},[t._v(t._s(e.groupName))]),t._v(" "),a("ul",{staticClass:"pure-menu-list"},[t._l(e.list,function(e){return[e.disabled?t._e():a("li",{staticClass:"nav-item"},[a("router-link",{attrs:{"active-class":"active",to:t.base+e.path},domProps:{textContent:t._s(e.title)}})],1)]})],2)])}):t._e()],2)}))])},staticRenderFns:[]}},455:function(t,e,a){var i=a(309);"string"==typeof i&&(i=[[t.i,i,""]]),i.locals&&(t.exports=i.locals);a(29)("1517d9c0",i,!0)}});
|
||||
webpackJsonp([1],{259:function(e,t,n){n(490);var i=n(0)(n(273),n(431),null,null);e.exports=i.exports},273:function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var o=n(30),a=i(o),s=n(372),r=i(s);t.default={data:function(){return{highlights:[],navState:[],data:a.default["zh-CN"],base:"/component"}},components:{MobileNav:r.default}}},275:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:{group:{type:Object,default:function(){return[]}},base:String},data:function(){return{isOpen:!1}}}},325:function(e,t,n){t=e.exports=n(18)(),t.push([e.i,".side-nav{width:100%;box-sizing:border-box;padding:90px 15px 20px;position:relative;z-index:1}.side-nav .zanui-desc,.side-nav .zanui-title{text-align:center;font-weight:400}.side-nav .zanui-title{font-size:26px;color:#333}.side-nav .zanui-desc{font-size:14px;color:#666;margin-bottom:50px}",""])},341:function(e,t,n){t=e.exports=n(18)(),t.push([e.i,".mobile-nav-group{border-radius:2px;margin-bottom:15px;padding-left:20px;background-color:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1)}.mobile-nav-group li{list-style:none}.mobile-nav-group ul{padding:0;margin:0;overflow:hidden}.mobile-nav-group__title{font-size:16px;color:#333;line-height:56px;position:relative}.mobile-nav-group__title a{color:#333;display:block;border-top:1px solid #e5e5e5}.mobile-nav-group__title .zan-icon-arrow{position:absolute;font-size:12px;line-height:1;top:24px;right:20px}.mobile-nav-group__title--open{color:#999}",""])},372:function(e,t,n){n(506);var i=n(0)(n(275),n(450),null,null);e.exports=i.exports},431:function(e,t){e.exports={render:function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"side-nav"},[n("h1",{staticClass:"zanui-title"},[e._v("Zan UI Wap")]),e._v(" "),n("h2",{staticClass:"zanui-desc"},[e._v("有赞移动wap端组件库")]),e._v(" "),n("div",{staticClass:"mobile-navs"},[e._l(e.data,function(t){return[t.showInMobile?n("div",{staticClass:"mobile-nav-item"},e._l(t.groups,function(t){return n("mobile-nav",{attrs:{group:t,base:e.base}})})):e._e()]})],2)])},staticRenderFns:[]}},450:function(e,t){e.exports={render:function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"mobile-nav-group"},[n("div",{staticClass:"mobile-nav-group__title",class:{"mobile-nav-group__title--open":e.isOpen},on:{click:function(t){e.isOpen=!e.isOpen}}},[e._v("\n "+e._s(e.group.groupName)+"\n ")]),e._v(" "),n("ul",{directives:[{name:"show",rawName:"v-show",value:e.isOpen,expression:"isOpen"}],staticClass:"pure-menu-list"},[e._l(e.group.list,function(t){return[t.disabled?e._e():n("li",{staticClass:"mobile-nav-group__title"},[n("router-link",{attrs:{"active-class":"active",to:e.base+t.path},domProps:{textContent:e._s(t.title)}}),e._v(" "),n("zan-icon",{attrs:{name:"arrow"}})],1)]})],2)])},staticRenderFns:[]}},490:function(e,t,n){var i=n(325);"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);n(31)("1517d9c0",i,!0)},506:function(e,t,n){var i=n(341);"string"==typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);n(31)("8bcdd7d6",i,!0)}});
|
2
docs/build/zanui-docs.js
vendored
2
docs/build/zanui-docs.js
vendored
File diff suppressed because one or more lines are too long
2
docs/build/zanui-examples.js
vendored
2
docs/build/zanui-examples.js
vendored
File diff suppressed because one or more lines are too long
@ -1,49 +1,20 @@
|
||||
<template>
|
||||
<div class="side-nav">
|
||||
<ul>
|
||||
<li class="nav-item" v-for="item in data">
|
||||
<a v-if="!item.path">{{item.name}}</a>
|
||||
<router-link
|
||||
v-else
|
||||
active-class="active"
|
||||
:to="base + item.path"
|
||||
exact
|
||||
v-text="item.title || item.name">
|
||||
</router-link>
|
||||
<ul class="pure-menu-list sub-nav" v-if="item.children">
|
||||
<li class="nav-item" v-for="navItem in item.children">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="base + navItem.path"
|
||||
v-text="navItem.title || navItem.name">
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<template v-if="item.groups">
|
||||
<div class="nav-group" v-for="group in item.groups">
|
||||
<div class="nav-group__title">{{group.groupName}}</div>
|
||||
<ul class="pure-menu-list">
|
||||
<template v-for="navItem in group.list">
|
||||
<li
|
||||
class="nav-item"
|
||||
v-if="!navItem.disabled">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="base + navItem.path"
|
||||
v-text="navItem.title">
|
||||
</router-link>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
<h1 class="zanui-title">Zan UI Wap</h1>
|
||||
<h2 class="zanui-desc">有赞移动wap端组件库</h2>
|
||||
<div class="mobile-navs">
|
||||
<template v-for="item in data">
|
||||
<div class="mobile-nav-item" v-if="item.showInMobile">
|
||||
<mobile-nav v-for="group in item.groups" :group="group" :base="base"></mobile-nav>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navConfig from '../nav.config.json';
|
||||
import MobileNav from './mobile-nav';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -53,6 +24,10 @@ export default {
|
||||
data: navConfig['zh-CN'],
|
||||
base: '/component'
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
MobileNav
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@ -61,56 +36,25 @@ export default {
|
||||
.side-nav {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 20px;
|
||||
background: #f9fafb;
|
||||
padding: 90px 15px 20px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
.zanui-title,
|
||||
.zanui-desc {
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
a {
|
||||
font-size: 16px;
|
||||
color: #5e6d82;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
position: relative;
|
||||
transition: all .3s;
|
||||
|
||||
&.active {
|
||||
color: #20a0ff;
|
||||
}
|
||||
}
|
||||
.nav-item {
|
||||
a {
|
||||
display: block;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 13px;
|
||||
padding-left: 24px;
|
||||
|
||||
|
||||
&:hover {
|
||||
color: #20a0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.zanui-title {
|
||||
font-size: 26px;
|
||||
color: #333;
|
||||
}
|
||||
.nav-group__title {
|
||||
font-size: 12px;
|
||||
color: #99a9bf;
|
||||
padding-left: 8px;
|
||||
line-height: 26px;
|
||||
margin-top: 10px;
|
||||
|
||||
.zanui-desc {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
94
docs/components/mobile-nav.vue
Normal file
94
docs/components/mobile-nav.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="mobile-nav-group">
|
||||
<div
|
||||
class="mobile-nav-group__title"
|
||||
:class="{
|
||||
'mobile-nav-group__title--open': isOpen
|
||||
}"
|
||||
@click="isOpen = !isOpen">
|
||||
{{group.groupName}}
|
||||
</div>
|
||||
<ul class="pure-menu-list" v-show="isOpen">
|
||||
<template v-for="navItem in group.list">
|
||||
<li
|
||||
class="mobile-nav-group__title"
|
||||
v-if="!navItem.disabled">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="base + navItem.path"
|
||||
v-text="navItem.title">
|
||||
</router-link>
|
||||
<zan-icon name="arrow"></zan-icon>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
base: String
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isOpen: false
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@component-namespace mobile {
|
||||
@b nav-group {
|
||||
border-radius: 2px;
|
||||
margin-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.10);
|
||||
|
||||
@e title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
line-height: 56px;
|
||||
position: relative;
|
||||
|
||||
@m open {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
display: block;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.zan-icon-arrow {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
top: 24px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -33,13 +33,19 @@ export default {
|
||||
|
||||
<style>
|
||||
.mobile-popup {
|
||||
width: 380px;
|
||||
height: 500px;
|
||||
border: 5px solid #e5e5e5;
|
||||
width: 375px;
|
||||
height: 650px;
|
||||
background: url(https://b.yzcdn.cn/v2/image/wap/zanui-mobile-container.png) no-repeat;
|
||||
}
|
||||
|
||||
.mobile-popup-iframe {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
box-sizing: border-box;
|
||||
border-left: 1px solid #e5e5e5;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
position: relative;
|
||||
top: 64px;
|
||||
height: 586px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,21 +1,30 @@
|
||||
<template><section class="demo-icon"><h1 class="demo-title">icon</h1><example-block title="所有Icon">
|
||||
<zan-icon name="album"></zan-icon>
|
||||
<zan-icon name="arrow"></zan-icon>
|
||||
<zan-icon name="camera"></zan-icon>
|
||||
<zan-icon name="certificate"></zan-icon>
|
||||
<zan-icon name="qr-invalid"></zan-icon>
|
||||
<zan-icon name="qr"></zan-icon>
|
||||
<zan-icon name="exchange"></zan-icon>
|
||||
<zan-icon name="close"></zan-icon>
|
||||
<zan-icon name="location"></zan-icon>
|
||||
<zan-icon name="upgrade"></zan-icon>
|
||||
<zan-icon name="check"></zan-icon>
|
||||
<zan-icon name="checked"></zan-icon>
|
||||
<zan-icon name="close"></zan-icon>
|
||||
<zan-icon name="like-o"></zan-icon>
|
||||
<zan-icon name="like"></zan-icon>
|
||||
<zan-icon name="chat"></zan-icon>
|
||||
<zan-icon name="shop"></zan-icon>
|
||||
<zan-icon name="photograph"></zan-icon>
|
||||
<zan-icon name="add"></zan-icon>
|
||||
<zan-icon name="add2"></zan-icon>
|
||||
<zan-icon name="photo"></zan-icon>
|
||||
<zan-icon name="logistics"></zan-icon>
|
||||
<zan-icon name="edit"></zan-icon>
|
||||
<zan-icon name="passed"></zan-icon>
|
||||
<zan-icon name="cart"></zan-icon>
|
||||
<zan-icon name="arrow"></zan-icon>
|
||||
<zan-icon name="gift"></zan-icon>
|
||||
<zan-icon name="home"></zan-icon>
|
||||
<zan-icon name="location"></zan-icon>
|
||||
<zan-icon name="message"></zan-icon>
|
||||
<zan-icon name="send"></zan-icon>
|
||||
<zan-icon name="shopping-cart"></zan-icon>
|
||||
<zan-icon name="sign"></zan-icon>
|
||||
<zan-icon name="store"></zan-icon>
|
||||
<zan-icon name="topay"></zan-icon>
|
||||
<zan-icon name="tosend"></zan-icon>
|
||||
<zan-icon name="search"></zan-icon>
|
||||
<zan-icon name="clear"></zan-icon>
|
||||
<zan-icon name="success"></zan-icon>
|
||||
<zan-icon name="fail"></zan-icon>
|
||||
|
||||
</example-block></section></template>
|
||||
<style>
|
||||
|
@ -1,4 +1,30 @@
|
||||
<template><section class="demo-image-preview"><h1 class="demo-title">image-preview</h1></section></template>
|
||||
<template><section class="demo-image-preview"><h1 class="demo-title">image-preview</h1><example-block title="">
|
||||
<zan-button @click="handleImagePreview">预览图片</zan-button>
|
||||
|
||||
|
||||
|
||||
</example-block></section></template>
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b image-preview {
|
||||
.zan-button {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);</script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);
|
||||
import { ImagePreview } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
handleImagePreview() {
|
||||
ImagePreview([
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp',
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp'
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -7,7 +7,7 @@
|
||||
</zan-popup>
|
||||
|
||||
<div class="zan-row">
|
||||
<zan-button @click="popupShow2 = true">从上方方弹出popup</zan-button>
|
||||
<zan-button @click="popupShow2 = true">从上方弹出popup</zan-button>
|
||||
</div>
|
||||
<zan-popup v-model="popupShow2" position="top" class="zan-popup-2" :overlay="false">
|
||||
更新成功
|
||||
@ -55,7 +55,10 @@
|
||||
|
||||
.zan-popup-4 {
|
||||
width: 60%;
|
||||
height: 200px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.zan-button {
|
||||
|
@ -3,9 +3,19 @@
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
</zan-swipe>
|
||||
|
||||
</example-block><example-block title="自动轮播">
|
||||
<zan-swipe :auto-play="true">
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
</zan-swipe>
|
||||
|
||||
</example-block></section></template>
|
||||
@ -14,6 +24,10 @@
|
||||
@b swipe {
|
||||
.zan-swipe {
|
||||
height: 200px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template><section class="demo-switch"><h1 class="demo-title">switch</h1><example-block title="基础用法">
|
||||
<div class="demo-switch__wrapper">
|
||||
<zan-switch class="some-customized-class" :checked="switchState" :on-change="updateState"></zan-switch>
|
||||
<zan-switch class="some-customized-class" :checked="switchState" @change="updateState"></zan-switch>
|
||||
<div class="demo-switch__text">{{switchStateText}}</div>
|
||||
</div>
|
||||
<div class="demo-switch__wrapper">
|
||||
@ -41,4 +41,22 @@
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);</script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
switchState: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
switchStateText() {
|
||||
return this.switchState ? ' ON' : 'OFF';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateState(newState) {
|
||||
this.switchState = newState;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -38,6 +38,15 @@
|
||||
|
||||
</example-block></section></template>
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b tab {
|
||||
.zan-tabs-pane {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style><style>
|
||||
.page-tab {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
56
docs/examples-dist/toast.vue
Normal file
56
docs/examples-dist/toast.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template><section class="demo-toast"><h1 class="demo-title">toast</h1><example-block title="基础用法">
|
||||
<zan-button @click="showSimpleToast">普通文字提示</zan-button>
|
||||
<zan-button @click="showLoadingToast">加载Toast</zan-button>
|
||||
<zan-button @click="showSuccessToast">成功</zan-button>
|
||||
<zan-button @click="showFailToast">失败</zan-button>
|
||||
<zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button>
|
||||
|
||||
|
||||
|
||||
</example-block></section></template>
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b toast {
|
||||
.zan-button {
|
||||
margin: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);
|
||||
import { Toast } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
showSimpleToast() {
|
||||
Toast('我是提示文案,建议不超过十五字~');
|
||||
},
|
||||
showLoadingToast() {
|
||||
Toast.loading();
|
||||
},
|
||||
showSuccessToast() {
|
||||
Toast.success('成功文案');
|
||||
},
|
||||
showFailToast() {
|
||||
Toast.fail('失败文案');
|
||||
},
|
||||
showCustomizedToast(duration) {
|
||||
let leftSec = duration / 1000;
|
||||
let toast = Toast({
|
||||
duration: duration + 1000,
|
||||
type: 'success',
|
||||
message: leftSec.toString()
|
||||
});
|
||||
window.setInterval(() => {
|
||||
if (leftSec <= 1) {
|
||||
window.clearInterval();
|
||||
toast.message = '跳转中...'
|
||||
return;
|
||||
}
|
||||
toast.message = (--leftSec).toString();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
29
docs/examples-dist/uploader.vue
Normal file
29
docs/examples-dist/uploader.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template><section class="demo-uploader"><h1 class="demo-title">uploader</h1><example-block title="基础用法">
|
||||
<div class="uploader-container">
|
||||
<zan-uploader :before-read="logContent" @file-readed="logContent">
|
||||
</zan-uploader>
|
||||
</div>
|
||||
|
||||
</example-block><example-block title="自定义上传图标">
|
||||
<div class="uploader-container">
|
||||
<zan-uploader @file-readed="logContent">
|
||||
<zan-icon name="photograph"></zan-icon>
|
||||
</zan-uploader>
|
||||
</div>
|
||||
|
||||
</example-block></section></template>
|
||||
<style>
|
||||
.uploader-container {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Vue from "vue";import ExampleBlock from "../components/example-block";Vue.component("example-block", ExampleBlock);
|
||||
export default {
|
||||
methods: {
|
||||
logContent(file) {
|
||||
console.log(file)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -29,6 +29,18 @@ export default {
|
||||
```
|
||||
:::
|
||||
|
||||
### 带*号,标明必填
|
||||
|
||||
传入`required`属性
|
||||
|
||||
:::demo 带*号,标明必填
|
||||
```html
|
||||
<zan-cell-group>
|
||||
<zan-cell title="单元格1" required></zan-cell>
|
||||
</zan-cell-group>
|
||||
```
|
||||
:::
|
||||
|
||||
### 标题带描述信息
|
||||
|
||||
传入`label`属性,属性值为描述信息的值。
|
||||
|
94
docs/examples-docs/datetime-picker.md
Normal file
94
docs/examples-docs/datetime-picker.md
Normal file
@ -0,0 +1,94 @@
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
minHour: 10,
|
||||
maxHour: 20,
|
||||
minDate: new Date()
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
handlePickerChange(picker, values) {
|
||||
// picker.setColumnValues(1, citys[values[0]]);
|
||||
console.log(values);
|
||||
},
|
||||
handlePickerCancel() {
|
||||
alert('picker cancel');
|
||||
},
|
||||
handlePickerConfirm() {
|
||||
alert('picker confirm');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
## Picker组件
|
||||
|
||||
模仿iOS中的`UIPickerView`。
|
||||
|
||||
### 基础用法
|
||||
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<zan-datetime-picker
|
||||
type="time"
|
||||
:min-hour="minHour"
|
||||
:max-hour="maxHour"
|
||||
:min-date="minDate"
|
||||
@change="handlePickerChange">
|
||||
</zan-datetime-picker>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
minHour: 10,
|
||||
maxHour: 20,
|
||||
minDate: new Date()
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
handlePickerChange(picker, values) {
|
||||
picker.setColumnValues(1, citys[values[0]]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| visibileColumnCount | 每一列可见备选元素的个数 | Number | 5 | |
|
||||
| itemHeight | 选中元素区高度 | Number | 44 | |
|
||||
| columns | 对象数组,配置每一列显示的数据 | Array | | |
|
||||
| showToolbar | 是否在组件顶部显示一个toolbar | Boolean | true | |
|
||||
|
||||
### columns
|
||||
|
||||
`API`中的`columns`为一个对象数组,数组中的每一个对象配置每一列,每一列有以下`key`:
|
||||
|
||||
| key | 说明 |
|
||||
|-----------|-----------|
|
||||
| values | 列中对应的备选值 |
|
||||
| defaultIndex | 初始选中值的索引,默认为0 |
|
||||
| className | 为对应列添加特殊的`class` |
|
||||
|
||||
### change事件
|
||||
|
||||
在`change`事件中,可以获取到`picker`实例,对`picker`进行相应的更新等操作:
|
||||
|
||||
| 函数 | 说明 |
|
||||
|-----------|-----------|
|
||||
| getColumnValue(index) | 获取对应列中选中的值 |
|
||||
| setColumnValue(index, value) | 设置对应列中选中的值 |
|
||||
| getColumnValues(index) | 获取对应列中所有的备选值 |
|
||||
| setColumnValues(index, values) | 设置对应列中所有的备选值 |
|
||||
| getValues() | 获取所有列中被选中的值,返回一个数组 |
|
||||
| setValues(values) | `values`为一个数组,设置所有列中被选中的值 |
|
@ -29,9 +29,9 @@ export default {
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<zan-cell-group>
|
||||
<zan-field type="text" label="用户名:" placeholder="请输入用户名" v-model="username"></zan-field>
|
||||
<zan-field type="password" label="密码:" placeholder="请输入密码"></zan-field>
|
||||
<zan-field type="textarea" label="个人介绍:" placeholder="请输入个人介绍"></zan-field>
|
||||
<zan-field type="text" label="用户名:" placeholder="请输入用户名" v-model="username" required></zan-field>
|
||||
<zan-field type="password" label="密码:" placeholder="请输入密码" required></zan-field>
|
||||
<zan-field type="textarea" label="个人介绍:" placeholder="请输入个人介绍" required></zan-field>
|
||||
</zan-cell-group>
|
||||
```
|
||||
:::
|
||||
@ -84,6 +84,19 @@ export default {
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
### Autosize的输入框(仅支持textarea)
|
||||
|
||||
传入`autosize`属性, 且将`rows`设为1。
|
||||
|
||||
:::demo 错误的输入框
|
||||
```html
|
||||
<zan-cell-group>
|
||||
<zan-field label="留言:" type="textarea" placeholder="请输入留言" rows="1" autosize></zan-field>
|
||||
</zan-cell-group>
|
||||
```
|
||||
:::
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
@ -96,4 +109,7 @@ export default {
|
||||
| error | 输入框是否有错误 | boolean | false | |
|
||||
| readonly | 输入框是否只读 | boolean | false | |
|
||||
| maxlength | 输入框maxlength | [String, Number] | '' | |
|
||||
| rows | textarea rows | [String, Number] | '' | |
|
||||
| cols | textarea cols | [String, Number] | '' | |
|
||||
| autosize | 自动调整高度(仅支持textarea) | Boolean | false | true, false |
|
||||
|
||||
|
@ -16,23 +16,32 @@
|
||||
|
||||
:::demo 所有Icon
|
||||
```html
|
||||
<zan-icon name="album"></zan-icon>
|
||||
<zan-icon name="arrow"></zan-icon>
|
||||
<zan-icon name="camera"></zan-icon>
|
||||
<zan-icon name="certificate"></zan-icon>
|
||||
<zan-icon name="qr-invalid"></zan-icon>
|
||||
<zan-icon name="qr"></zan-icon>
|
||||
<zan-icon name="exchange"></zan-icon>
|
||||
<zan-icon name="close"></zan-icon>
|
||||
<zan-icon name="location"></zan-icon>
|
||||
<zan-icon name="upgrade"></zan-icon>
|
||||
<zan-icon name="check"></zan-icon>
|
||||
<zan-icon name="checked"></zan-icon>
|
||||
<zan-icon name="close"></zan-icon>
|
||||
<zan-icon name="like-o"></zan-icon>
|
||||
<zan-icon name="like"></zan-icon>
|
||||
<zan-icon name="chat"></zan-icon>
|
||||
<zan-icon name="shop"></zan-icon>
|
||||
<zan-icon name="photograph"></zan-icon>
|
||||
<zan-icon name="add"></zan-icon>
|
||||
<zan-icon name="add2"></zan-icon>
|
||||
<zan-icon name="photo"></zan-icon>
|
||||
<zan-icon name="logistics"></zan-icon>
|
||||
<zan-icon name="edit"></zan-icon>
|
||||
<zan-icon name="passed"></zan-icon>
|
||||
<zan-icon name="cart"></zan-icon>
|
||||
<zan-icon name="arrow"></zan-icon>
|
||||
<zan-icon name="gift"></zan-icon>
|
||||
<zan-icon name="home"></zan-icon>
|
||||
<zan-icon name="location"></zan-icon>
|
||||
<zan-icon name="message"></zan-icon>
|
||||
<zan-icon name="send"></zan-icon>
|
||||
<zan-icon name="shopping-cart"></zan-icon>
|
||||
<zan-icon name="sign"></zan-icon>
|
||||
<zan-icon name="store"></zan-icon>
|
||||
<zan-icon name="topay"></zan-icon>
|
||||
<zan-icon name="tosend"></zan-icon>
|
||||
<zan-icon name="search"></zan-icon>
|
||||
<zan-icon name="clear"></zan-icon>
|
||||
<zan-icon name="success"></zan-icon>
|
||||
<zan-icon name="fail"></zan-icon>
|
||||
```
|
||||
:::
|
||||
|
||||
|
@ -1,3 +1,50 @@
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b image-preview {
|
||||
.zan-button {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { ImagePreview } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
handleImagePreview() {
|
||||
ImagePreview([
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp',
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp'
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
## ImagePreview 图片预览
|
||||
|
||||
### 基础用法
|
||||
|
||||
:::demo
|
||||
```html
|
||||
<zan-button @click="handleImagePreview">预览图片</zan-button>
|
||||
|
||||
<script>
|
||||
import { ImagePreview } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
handleImagePreview() {
|
||||
ImagePreview([
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp',
|
||||
'https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp'
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
|
@ -22,7 +22,10 @@
|
||||
|
||||
.zan-popup-4 {
|
||||
width: 60%;
|
||||
height: 200px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.zan-button {
|
||||
@ -87,7 +90,7 @@ export default {
|
||||
</zan-popup>
|
||||
|
||||
<div class="zan-row">
|
||||
<zan-button @click="popupShow2 = true">从上方方弹出popup</zan-button>
|
||||
<zan-button @click="popupShow2 = true">从上方弹出popup</zan-button>
|
||||
</div>
|
||||
<zan-popup v-model="popupShow2" position="top" class="zan-popup-2" :overlay="false">
|
||||
更新成功
|
||||
|
@ -3,6 +3,10 @@
|
||||
@b swipe {
|
||||
.zan-swipe {
|
||||
height: 200px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,7 +23,22 @@
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
</zan-swipe>
|
||||
```
|
||||
:::
|
||||
|
||||
### 自动轮播
|
||||
|
||||
:::demo 自动轮播
|
||||
```html
|
||||
<zan-swipe :auto-play="true">
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/14/FmTPs0SeyQaAOSK1rRe1sL8RcwSY.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
<zan-swipe-item>
|
||||
<img src="https://img.yzcdn.cn/upload_files/2017/03/15/FvexrWlG_WxtCE9Omo5l27n_mAG_.jpeg?imageView2/2/w/980/h/980/q/75/format/webp" alt="">
|
||||
</zan-swipe-item>
|
||||
</zan-swipe>
|
||||
```
|
||||
|
@ -16,6 +16,25 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
switchState: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
switchStateText() {
|
||||
return this.switchState ? ' ON' : 'OFF';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateState(newState) {
|
||||
this.switchState = newState;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
## Switch组件
|
||||
|
||||
@ -24,7 +43,7 @@
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<div class="demo-switch__wrapper">
|
||||
<zan-switch class="some-customized-class" :checked="switchState" :on-change="updateState"></zan-switch>
|
||||
<zan-switch class="some-customized-class" :checked="switchState" @change="updateState"></zan-switch>
|
||||
<div class="demo-switch__text">{{switchStateText}}</div>
|
||||
</div>
|
||||
<div class="demo-switch__wrapper">
|
||||
@ -73,4 +92,3 @@ export default {
|
||||
| checked | 开关状态 | boolean | false | true, false |
|
||||
| loading | loading状态 | boolean | false | true, false |
|
||||
| disabled | 禁用状态 | boolean | false | true, false |
|
||||
| onChange | 回调 | function | function(){} | - |
|
||||
|
@ -1,3 +1,14 @@
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b tab {
|
||||
.zan-tabs-pane {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
## Tab 组件
|
||||
|
||||
### 基础用法
|
||||
|
104
docs/examples-docs/toast.md
Normal file
104
docs/examples-docs/toast.md
Normal file
@ -0,0 +1,104 @@
|
||||
<style>
|
||||
@component-namespace demo {
|
||||
@b toast {
|
||||
.zan-button {
|
||||
margin: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { Toast } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
showSimpleToast() {
|
||||
Toast('我是提示文案,建议不超过十五字~');
|
||||
},
|
||||
showLoadingToast() {
|
||||
Toast.loading();
|
||||
},
|
||||
showSuccessToast() {
|
||||
Toast.success('成功文案');
|
||||
},
|
||||
showFailToast() {
|
||||
Toast.fail('失败文案');
|
||||
},
|
||||
showCustomizedToast(duration) {
|
||||
let leftSec = duration / 1000;
|
||||
let toast = Toast({
|
||||
duration: duration + 1000,
|
||||
type: 'success',
|
||||
message: leftSec.toString()
|
||||
});
|
||||
window.setInterval(() => {
|
||||
if (leftSec <= 1) {
|
||||
window.clearInterval();
|
||||
toast.message = '跳转中...'
|
||||
return;
|
||||
}
|
||||
toast.message = (--leftSec).toString();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
## Toast
|
||||
|
||||
### 基础用法
|
||||
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<zan-button @click="showSimpleToast">普通文字提示</zan-button>
|
||||
<zan-button @click="showLoadingToast">加载Toast</zan-button>
|
||||
<zan-button @click="showSuccessToast">成功</zan-button>
|
||||
<zan-button @click="showFailToast">失败</zan-button>
|
||||
<zan-button @click="showCustomizedToast(5000)">倒数5秒</zan-button>
|
||||
|
||||
<script>
|
||||
import { Toast } from 'src/index';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
showSimpleToast() {
|
||||
Toast('我是提示文案,建议不超过十五字~');
|
||||
},
|
||||
showLoadingToast() {
|
||||
Toast.loading();
|
||||
},
|
||||
showSuccessToast() {
|
||||
Toast.success('成功文案');
|
||||
},
|
||||
showFailToast() {
|
||||
Toast.fail('失败文案');
|
||||
},
|
||||
showCustomizedToast(duration) {
|
||||
let leftSec = duration / 1000;
|
||||
let toast = Toast({
|
||||
duration: duration + 1000,
|
||||
type: 'success',
|
||||
message: leftSec.toString()
|
||||
});
|
||||
window.setInterval(() => {
|
||||
if (leftSec <= 1) {
|
||||
window.clearInterval();
|
||||
toast.message = '跳转中...'
|
||||
return;
|
||||
}
|
||||
toast.message = (--leftSec).toString();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| type | 类型 | String | 'text' | 'text', 'loading', 'success', 'failure' |
|
||||
| message | 内容 | String | '' | - |
|
54
docs/examples-docs/uploader.md
Normal file
54
docs/examples-docs/uploader.md
Normal file
@ -0,0 +1,54 @@
|
||||
<style>
|
||||
.uploader-container {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
logContent(file) {
|
||||
console.log(file)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
## Uploader 组件
|
||||
|
||||
### 基础用法
|
||||
|
||||
:::demo 基础用法
|
||||
```html
|
||||
<div class="uploader-container">
|
||||
<zan-uploader
|
||||
:before-read="logContent"
|
||||
@file-readed="logContent">
|
||||
</zan-uploader>
|
||||
</div>
|
||||
```
|
||||
:::
|
||||
### 自定义上传图标
|
||||
:::demo 自定义上传图标
|
||||
```html
|
||||
<div class="uploader-container">
|
||||
<zan-uploader @file-readed="logContent">
|
||||
<zan-icon name="photograph"></zan-icon>
|
||||
</zan-uploader>
|
||||
</div>
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| result-type | 读取文件的方式,以base64的方式读取;以文本的方式读取 | String | 'dataUrl' | 'dataUrl','text' |
|
||||
| disable | 是否禁用上传,在图片上传期间设置为true,禁止用户点击此组件上传图片 | boolean | false | |
|
||||
| before-read | 读文件之前的钩子,参数为选择的文件,若返回 false 则停止读取文件。 | Function | | |
|
||||
| file-readed | 文件读完之后出发此事件,参数为{name:'文件名',type:'文件类型',size:'文件大小',content:'读的内容'} | Function | | |
|
||||
|
||||
### Slot
|
||||
|
||||
| name | 描述 |
|
||||
|-----------|-----------|
|
||||
| - | 自定义上传显示图标 |
|
@ -19,9 +19,10 @@
|
||||
},
|
||||
{
|
||||
"name": "ZanUI组件",
|
||||
"showInMobile": true,
|
||||
"groups": [
|
||||
{
|
||||
"groupName": "CSS组件",
|
||||
"groupName": "基础组件",
|
||||
"list": [
|
||||
{
|
||||
"path": "/button",
|
||||
@ -63,14 +64,42 @@
|
||||
"path": "/badge",
|
||||
"title": "Badge"
|
||||
},
|
||||
{
|
||||
"path": "/tab",
|
||||
"title": "Tab"
|
||||
},
|
||||
{
|
||||
"path": "/lazyload",
|
||||
"title": "Lazyload"
|
||||
},
|
||||
{
|
||||
"path": "/popup",
|
||||
"title": "Popup"
|
||||
},
|
||||
{
|
||||
"path": "/swipe",
|
||||
"title": "Swipe"
|
||||
},
|
||||
{
|
||||
"path": "/search",
|
||||
"title": "Search"
|
||||
},
|
||||
{
|
||||
"path": "/quantity",
|
||||
"title": "Quantity"
|
||||
},
|
||||
{
|
||||
"path": "/waterfall",
|
||||
"title": "Waterfall"
|
||||
},
|
||||
{
|
||||
"path": "/image-preview",
|
||||
"title": "ImagePreview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupName": "Form",
|
||||
"groupName": "表单",
|
||||
"list": [
|
||||
{
|
||||
"path": "/switch",
|
||||
@ -87,28 +116,24 @@
|
||||
{
|
||||
"path": "/checkbox",
|
||||
"title": "Checkbox"
|
||||
},
|
||||
{
|
||||
"path": "/uploader",
|
||||
"title": "Uploader"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupName": "JS组件",
|
||||
"groupName": "操作反馈",
|
||||
"list": [
|
||||
{
|
||||
"path": "/actionsheet",
|
||||
"title": "ActionSheet"
|
||||
},
|
||||
{
|
||||
"path": "/tab",
|
||||
"title": "Tab"
|
||||
},
|
||||
{
|
||||
"path": "/toast",
|
||||
"title": "Toast"
|
||||
},
|
||||
{
|
||||
"path": "/img-uploader",
|
||||
"title": "Img Uploader"
|
||||
},
|
||||
{
|
||||
"path": "/picker",
|
||||
"title": "Picker"
|
||||
@ -117,33 +142,9 @@
|
||||
"path": "/datetime-picker",
|
||||
"title": "Datetime Picker"
|
||||
},
|
||||
{
|
||||
"path": "/lazyload",
|
||||
"title": "Lazyload"
|
||||
},
|
||||
{
|
||||
"path": "/popup",
|
||||
"title": "Popup"
|
||||
},
|
||||
{
|
||||
"path": "/dialog",
|
||||
"title": "Dialog"
|
||||
},
|
||||
{
|
||||
"path": "/swipe",
|
||||
"title": "Swipe"
|
||||
},
|
||||
{
|
||||
"path": "/quantity",
|
||||
"title": "Quantity"
|
||||
},
|
||||
{
|
||||
"path": "/waterfall",
|
||||
"title": "Waterfall"
|
||||
},
|
||||
{
|
||||
"path": "/image-preview",
|
||||
"title": "ImagePreview"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@youzan/zanui-vue",
|
||||
"version": "0.0.31",
|
||||
"version": "0.0.38",
|
||||
"description": "有赞vue wap组件库",
|
||||
"main": "lib/zanui.js",
|
||||
"style": "lib/zanui-css/index.css",
|
||||
@ -47,6 +47,7 @@
|
||||
"devDependencies": {
|
||||
"2webpack2": "^1.2.1",
|
||||
"autoprefixer": "^6.7.5",
|
||||
"avoriaz": "^1.9.1",
|
||||
"babel-cli": "^6.14.0",
|
||||
"babel-core": "^6.17.0",
|
||||
"babel-eslint": "^6.1.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a class="zan-cell" :href="url" @click="handleClick">
|
||||
<div class="zan-cell__title">
|
||||
<div :class="{ 'zan-cell__title': true, 'zan-cell__required': required }">
|
||||
<slot name="icon">
|
||||
<i v-if="icon" class="zan-icon" :class="'zan-icon-' + icon"></i>
|
||||
</slot>
|
||||
@ -31,7 +31,8 @@ export default {
|
||||
value: [String, Number],
|
||||
url: String,
|
||||
label: String,
|
||||
isLink: Boolean
|
||||
isLink: Boolean,
|
||||
required: Boolean
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
8
packages/datetime-picker/CHANGELOG.md
Normal file
8
packages/datetime-picker/CHANGELOG.md
Normal file
@ -0,0 +1,8 @@
|
||||
## 0.0.2 (2017-01-20)
|
||||
|
||||
* 改了bug A
|
||||
* 加了功能B
|
||||
|
||||
## 0.0.1 (2017-01-10)
|
||||
|
||||
* 第一版
|
26
packages/datetime-picker/README.md
Normal file
26
packages/datetime-picker/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# @youzan/<%= name %>
|
||||
|
||||
!!! 请在此处填写你的文档最简单描述 !!!
|
||||
|
||||
[![version][version-image]][download-url]
|
||||
[![download][download-image]][download-url]
|
||||
|
||||
[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
|
||||
[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
|
||||
[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
|
||||
|
||||
## Demo
|
||||
|
||||
## Usage
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| className | 自定义额外类名 | string | '' | '' |
|
||||
|
||||
|
||||
|
||||
|
||||
## License
|
||||
[MIT](https://opensource.org/licenses/MIT)
|
3
packages/datetime-picker/index.js
Normal file
3
packages/datetime-picker/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import DateTimePicker from './src/datetime-picker';
|
||||
|
||||
export default DateTimePicker;
|
10
packages/datetime-picker/package.json
Normal file
10
packages/datetime-picker/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@youzan/zan-datetime-picker",
|
||||
"version": "0.0.1",
|
||||
"description": "datetime picker component",
|
||||
"main": "./index.js",
|
||||
"author": "niunai <niunai@youzan.com>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {},
|
||||
"dependencies": {}
|
||||
}
|
222
packages/datetime-picker/src/datetime-picker.vue
Normal file
222
packages/datetime-picker/src/datetime-picker.vue
Normal file
@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<zan-picker
|
||||
:columns="columns"
|
||||
:visible-item-count="visibleItemCount"
|
||||
@change="handlePickerChange"
|
||||
@confirm="handlePickerConfirm"
|
||||
showToolbar>
|
||||
</zan-picker>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Picker from 'packages/picker';
|
||||
|
||||
const allowedType = ['time', 'date', 'datetime'];
|
||||
|
||||
export default {
|
||||
name: 'zan-datetime-picker',
|
||||
|
||||
components: {
|
||||
Picker
|
||||
},
|
||||
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'datetime',
|
||||
validator(value) {
|
||||
return allowedType.indexOf(value) > -1;
|
||||
}
|
||||
},
|
||||
visibleItemCount: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
minDate: {
|
||||
type: Date,
|
||||
default() {
|
||||
return new Date(new Date().getFullYear() - 10, 0, 1);
|
||||
}
|
||||
},
|
||||
maxDate: {
|
||||
type: Date,
|
||||
default() {
|
||||
return new Date(new Date().getFullYear() + 10, 11, 31);
|
||||
}
|
||||
},
|
||||
minHour: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
maxHour: {
|
||||
type: Number,
|
||||
default: 23
|
||||
},
|
||||
value: null
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
innerValue: this.val
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(val) {
|
||||
this.innerValue = val;
|
||||
},
|
||||
innerValue(val) {
|
||||
console.log(val + '!!!');
|
||||
this.$emit('input', val);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
ranges() {
|
||||
console.log(this.innerValue + '!!');
|
||||
// return this.innerValue + '!!';
|
||||
if (this.type === 'time') {
|
||||
return [
|
||||
[this.minHour, this.maxHour],
|
||||
[0, 59]
|
||||
];
|
||||
}
|
||||
debugger
|
||||
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', this.innerValue);
|
||||
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', this.innerValue);
|
||||
|
||||
const result = [
|
||||
[minYear, maxYear],
|
||||
[minMonth, maxMonth],
|
||||
[minDate, maxDate],
|
||||
[minHour, maxHour],
|
||||
[minMinute, maxMinute]
|
||||
];
|
||||
|
||||
if (this.type === 'date') result.splice(3, 2);
|
||||
return result;
|
||||
},
|
||||
columns() {
|
||||
return this.ranges.map(range => {
|
||||
const values = this.times(range[1] - range[0] + 1, index => {
|
||||
const value = range[0] + index;
|
||||
return value < 10 ? `0${value}` : `${value}`;
|
||||
});
|
||||
|
||||
return {
|
||||
values
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
times(n, iteratee) {
|
||||
let index = -1;
|
||||
const result = Array(n);
|
||||
|
||||
while (++index < n) {
|
||||
result[index] = iteratee(index);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getBoundary(type, value) {
|
||||
const boundary = this[`${type}Date`];
|
||||
const year = boundary.getFullYear();
|
||||
let month = 1;
|
||||
let date = 1;
|
||||
let hour = 0;
|
||||
let minute = 0;
|
||||
|
||||
if (type === 'max') {
|
||||
month = 12;
|
||||
date = this.getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
|
||||
hour = 23;
|
||||
minute = 59;
|
||||
}
|
||||
|
||||
if (value.getFullYear() === year) {
|
||||
month = boundary.getMonth() + 1;
|
||||
if (value.getMonth() + 1 === month) {
|
||||
date = value.getDate();
|
||||
if (value.getDate() === date) {
|
||||
hour = value.getHours();
|
||||
if (value.getHours() === hour) {
|
||||
minute = value.getMinutes();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
[`${type}Year`]: year,
|
||||
[`${type}Month`]: month,
|
||||
[`${type}Date`]: date,
|
||||
[`${type}Hour`]: hour,
|
||||
[`${type}Minute`]: minute
|
||||
};
|
||||
},
|
||||
getTrueValue(formattedValue) {
|
||||
if (!formattedValue) return;
|
||||
while (isNaN(parseInt(formattedValue, 10))) {
|
||||
formattedValue = formattedValue.slice(1);
|
||||
}
|
||||
return parseInt(formattedValue, 10);
|
||||
},
|
||||
getMonthEndDay(year, month) {
|
||||
if (this.isShortMonth(month)) {
|
||||
return 30;
|
||||
} else if (month === 2) {
|
||||
return this.isLeapYear(year) ? 29 : 28;
|
||||
} else {
|
||||
return 31;
|
||||
}
|
||||
},
|
||||
isLeapYear(year) {
|
||||
return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
|
||||
},
|
||||
isShortMonth(month) {
|
||||
return [4, 6, 9, 11].indexOf(month) > -1;
|
||||
},
|
||||
handlePickerConfirm(values) {
|
||||
this.$emit('confirm', this.innerValue);
|
||||
},
|
||||
handlePickerChange(picker, values, index) {
|
||||
console.log(this.innerValue);
|
||||
let value;
|
||||
|
||||
if (this.type === 'time') {
|
||||
value = values.join(':');
|
||||
} else {
|
||||
const year = this.getTrueValue(values[0]);
|
||||
const month = this.getTrueValue(values[1]);
|
||||
const maxDate = this.getMonthEndDay(year, month);
|
||||
let date = this.getTrueValue(values[2]);
|
||||
date = date > maxDate ? maxDate : date;
|
||||
let hour = 0;
|
||||
let minute = 0;
|
||||
if (this.type === 'datetime') {
|
||||
hour = this.getTrueValue(values[3]);
|
||||
minute = this.getTrueValue(values[4]);
|
||||
}
|
||||
value = new Date(year, month - 1, date, hour, minute);
|
||||
}
|
||||
this.innerValue = value;
|
||||
console.log(value, this.innerValue);
|
||||
// this.$emit('input', value);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.innerValue = this.value;
|
||||
if (!this.innerValue) {
|
||||
if (this.type.indexOf('date') > -1) {
|
||||
this.innerValue = this.minDate;
|
||||
} else {
|
||||
const minHour = this.minHour;
|
||||
this.innerValue = `${minHour > 10 ? minHour : '0' + minHour}:00`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -2,21 +2,26 @@
|
||||
<zan-cell
|
||||
class="zan-field"
|
||||
:title="label"
|
||||
:required="required"
|
||||
:class="{
|
||||
'zan-field--hastextarea': type === 'textarea',
|
||||
'zan-field--nolabel': !label,
|
||||
'zan-field--disabled': disabled,
|
||||
'zan-field--error': error,
|
||||
'zan-field--border': border
|
||||
'zan-field--border': border,
|
||||
'zan-field--autosize': autosize
|
||||
}">
|
||||
<textarea
|
||||
v-if="type === 'textarea'"
|
||||
ref="textareaElement"
|
||||
class="zan-field__control"
|
||||
v-model="currentValue"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly">
|
||||
:readonly="readonly"
|
||||
:rows="rows"
|
||||
:cols="cols">
|
||||
</textarea>
|
||||
<input
|
||||
v-else
|
||||
@ -32,6 +37,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const VALID_TYPES = ['text', 'number', 'email', 'url', 'tel', 'date', 'datetime', 'password', 'textarea'];
|
||||
import zanCell from 'packages/cell';
|
||||
|
||||
export default {
|
||||
@ -44,7 +50,10 @@ export default {
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
default: 'text',
|
||||
validate(value) {
|
||||
return VALID_TYPES.indexOf(value) > -1;
|
||||
}
|
||||
},
|
||||
placeholder: String,
|
||||
value: {},
|
||||
@ -52,8 +61,18 @@ export default {
|
||||
disabled: Boolean,
|
||||
error: Boolean,
|
||||
readonly: Boolean,
|
||||
required: Boolean,
|
||||
maxlength: [String, Number],
|
||||
border: Boolean
|
||||
border: Boolean,
|
||||
rows: [String, Number],
|
||||
cols: [String, Number],
|
||||
autosize: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
validate(value) {
|
||||
if (value && this.type !== 'textarea') return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -68,6 +87,7 @@ export default {
|
||||
},
|
||||
|
||||
currentValue(val) {
|
||||
if (this.autosize && this.type === 'textarea') this.sizeAdjust();
|
||||
this.$emit('input', val);
|
||||
}
|
||||
},
|
||||
@ -75,6 +95,15 @@ export default {
|
||||
methods: {
|
||||
handleInput(event) {
|
||||
this.currentValue = event.target.value;
|
||||
},
|
||||
|
||||
sizeAdjust() {
|
||||
const textareaElement = this.$refs.textareaElement;
|
||||
const textAreaDiff = (parseInt(textareaElement.style.paddingBottom, 10) +
|
||||
parseInt(textareaElement.style.paddingTop, 10)) || 0;
|
||||
// 需要先设为0, 才可以让scrollHeight正确计算。
|
||||
textareaElement.style.height = 0 + 'px';
|
||||
textareaElement.style.height = (textareaElement.scrollHeight - textAreaDiff) + 'px';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -12,13 +12,13 @@ const initInstance = () => {
|
||||
});
|
||||
};
|
||||
|
||||
var ImagePreviewBox = image => {
|
||||
var ImagePreviewBox = images => {
|
||||
if (!instance) {
|
||||
initInstance();
|
||||
}
|
||||
|
||||
if (!instance.value) {
|
||||
instance.image = image;
|
||||
instance.images = images;
|
||||
|
||||
document.body.appendChild(instance.$el);
|
||||
|
||||
|
@ -1,22 +1,32 @@
|
||||
<template>
|
||||
<transition name="image-fade">
|
||||
<div class="zan-image-preview" ref="previewContainer" v-show="value" @click="handlePreviewClick">
|
||||
<img class="zan-image-preview__image" :src="image" alt="" :class="{
|
||||
'zan-image-preview__image--center': true,
|
||||
'zan-image-preview__image--top': imageIsLargeView
|
||||
}">
|
||||
<zan-swipe>
|
||||
<zan-swipe-item v-for="item in images">
|
||||
<img class="zan-image-preview__image" :src="item" alt="" :class="{
|
||||
'zan-image-preview__image--center': true
|
||||
}">
|
||||
</zan-swipe-item>
|
||||
</zan-swipe>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Popup from 'src/mixins/popup';
|
||||
import ZanSwipe from 'packages/swipe';
|
||||
import ZanSwipeItem from 'packages/swipe-item';
|
||||
|
||||
export default {
|
||||
name: 'zan-image-preview',
|
||||
|
||||
mixins: [Popup],
|
||||
|
||||
components: {
|
||||
ZanSwipe,
|
||||
ZanSwipeItem
|
||||
},
|
||||
|
||||
props: {
|
||||
overlay: {
|
||||
default: true
|
||||
@ -33,7 +43,7 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
image: '',
|
||||
images: [],
|
||||
viewportSize: null
|
||||
};
|
||||
},
|
||||
@ -42,36 +52,6 @@ export default {
|
||||
handlePreviewClick() {
|
||||
this.value = false;
|
||||
},
|
||||
/**
|
||||
* 图片样式计算
|
||||
* 根据屏幕自适应显示最长边
|
||||
*/
|
||||
computeImageStyle() {
|
||||
// const previewSize = this.$refs.previewContainer.getBoundingClientRect();
|
||||
// const img = new Image();
|
||||
// const _this = this;
|
||||
|
||||
// img.onload = function() {
|
||||
// const imgRatio = parseFloat(this.width / this.height);
|
||||
// const previewRatio = parseFloat(previewSize.width / previewSize.height);
|
||||
|
||||
// if (previewRatio <= imgRatio) {
|
||||
// const top = (previewSize.height - parseInt(previewSize.width / imgRatio, 10)) / 2;
|
||||
// _this.imageStyle = {
|
||||
// width: '100%',
|
||||
// height: 'auto',
|
||||
// top: top + 'px'
|
||||
// };
|
||||
// } else if (previewRatio > imgRatio) {
|
||||
// _this.imageStyle = {
|
||||
// width: 'auto',
|
||||
// height: '100%'
|
||||
// };
|
||||
// }
|
||||
// };
|
||||
|
||||
// img.src = this.image;
|
||||
},
|
||||
|
||||
close() {
|
||||
if (this.closing) return;
|
||||
|
@ -1,3 +1,3 @@
|
||||
import Loading from './src/loading';
|
||||
import ZanLoading from './src/loading';
|
||||
|
||||
export default Loading;
|
||||
export default ZanLoading;
|
||||
|
@ -1,16 +1,22 @@
|
||||
<template>
|
||||
<div class="zan-search" :class="{ 'is-focus' : isFocus }">
|
||||
<div class="zan-search" :class="{ 'zan-search--focus' : isFocus }">
|
||||
<div class="zan-search__input-wrap">
|
||||
<zan-icon name="search"></zan-icon>
|
||||
<input type="text" :placeholder="placeholder" v-model="value" v-refocus="focusStatus" @focus="handleFocus" @keyup.enter="handleSearch">
|
||||
<span class="zan-icon zan-icon-close" @click="handleClean"></span>
|
||||
<zan-icon name="clear" @click="handleClean"></zan-icon>
|
||||
</div>
|
||||
<div class="zan-search__cancel" :class="{ 'is-focus' : isFocus }" @click="handleBack">取消</div>
|
||||
<div class="zan-search__cancel" :class="{ 'zan-search__cancel--focus' : isFocus }" @click="handleBack">取消</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ZanIcon from 'packages/icon';
|
||||
|
||||
export default {
|
||||
name: 'zan-search',
|
||||
components: {
|
||||
ZanIcon
|
||||
},
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String
|
||||
|
@ -34,7 +34,7 @@ extend(Scroll.prototype, {
|
||||
|
||||
update: function() {
|
||||
const oldPages = this.pages
|
||||
this.pages = this.wrapElem.querySelectorAll('.swp-page');
|
||||
this.pages = this.wrapElem.querySelectorAll('.zan-swipe-item');
|
||||
if (oldPages && oldPages.length === this.pages.length) {
|
||||
const isSame = Array.prototype.every.call(this.pages, (elem, index) => {
|
||||
return this.pages[index] === oldPages[index]
|
||||
@ -49,8 +49,8 @@ extend(Scroll.prototype, {
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'block',
|
||||
'-webkit-transform': 'translate3d(-9999px, 0, 0)'
|
||||
'-webkit-transform': 'translate3d(-9999px, 0, 0)',
|
||||
'pointer-events': 'none'
|
||||
};
|
||||
setElementsStyles(this.pages, defaultStyle);
|
||||
this.mCache = {
|
||||
@ -74,6 +74,7 @@ extend(Scroll.prototype, {
|
||||
page = this.getCurrentPage();
|
||||
if (page) {
|
||||
page.style['-webkit-transform'] = 'translate3d(' + offset + 'px, 0, 0)';
|
||||
page.style['display'] = 'block';
|
||||
}
|
||||
|
||||
leftPage = this.pages[this.mapLoopPage(currentOffsetPage - 1)];
|
||||
|
@ -8,6 +8,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ZanLoading from 'packages/loading';
|
||||
/**
|
||||
* zan-switch
|
||||
* @module components/switch
|
||||
@ -15,13 +16,15 @@
|
||||
* @param {boolean} [checked=false] - 开关状态
|
||||
* @param {boolean} [disabled=false] - 禁用
|
||||
* @param {boolean} [loading=false] - loading状态
|
||||
* @param {callback} [onChange] - 开关状态改变回调函数。
|
||||
*
|
||||
* @example
|
||||
* <zan-switch checked="true" disabled="false"></zan-switch>
|
||||
*/
|
||||
export default {
|
||||
name: 'zan-switch',
|
||||
components: {
|
||||
'zan-loading': ZanLoading
|
||||
},
|
||||
props: {
|
||||
checked: {
|
||||
type: Boolean,
|
||||
@ -34,10 +37,6 @@ export default {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: function() {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -54,7 +53,7 @@ export default {
|
||||
*/
|
||||
toggleState: function() {
|
||||
if (this.disabled || this.loading) return;
|
||||
this.onChange(!this.checked);
|
||||
this.$emit('change', !this.checked);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
26
packages/toast/README.md
Normal file
26
packages/toast/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# @youzan/<%= name %>
|
||||
|
||||
!!! 请在此处填写你的文档最简单描述 !!!
|
||||
|
||||
[![version][version-image]][download-url]
|
||||
[![download][download-image]][download-url]
|
||||
|
||||
[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
|
||||
[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
|
||||
[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
|
||||
|
||||
## Demo
|
||||
|
||||
## Usage
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||
|-----------|-----------|-----------|-------------|-------------|
|
||||
| className | 自定义额外类名 | string | '' | '' |
|
||||
|
||||
|
||||
|
||||
|
||||
## License
|
||||
[MIT](https://opensource.org/licenses/MIT)
|
3
packages/toast/index.js
Normal file
3
packages/toast/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import Toast from './src/toast';
|
||||
|
||||
export default Toast;
|
10
packages/toast/package.json
Normal file
10
packages/toast/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@youzan/zan-toast",
|
||||
"version": "0.0.1",
|
||||
"description": "toast component",
|
||||
"main": "./index.js",
|
||||
"author": "jiangruowei",
|
||||
"license": "MIT",
|
||||
"devDependencies": {},
|
||||
"dependencies": {}
|
||||
}
|
76
packages/toast/src/toast.js
Normal file
76
packages/toast/src/toast.js
Normal file
@ -0,0 +1,76 @@
|
||||
import Vue from 'vue';
|
||||
import merge from 'src/utils/merge';
|
||||
|
||||
const ToastConstructor = Vue.extend(require('./toast.vue'));
|
||||
let toastQueue = [];
|
||||
|
||||
const getInstance = () => {
|
||||
if (toastQueue.length > 0) {
|
||||
const instance = toastQueue[0];
|
||||
toastQueue.splice(0, 1);
|
||||
return instance;
|
||||
}
|
||||
return new ToastConstructor({
|
||||
el: document.createElement('div')
|
||||
});
|
||||
};
|
||||
|
||||
const returnInstance = instance => {
|
||||
if (instance) {
|
||||
toastQueue.push(instance);
|
||||
}
|
||||
};
|
||||
|
||||
const removeDom = event => {
|
||||
if (event.target.parentNode) {
|
||||
event.target.parentNode.removeChild(event.target);
|
||||
}
|
||||
};
|
||||
|
||||
var Toast = (options = {}) => {
|
||||
const duration = options.duration || 3000;
|
||||
|
||||
let instance = getInstance();
|
||||
returnInstance(instance);
|
||||
instance.closed = false;
|
||||
clearTimeout(instance.timer);
|
||||
instance.type = options.type ? options.type : 'text';
|
||||
instance.message = typeof options === 'string' ? options : options.message;
|
||||
|
||||
document.body.appendChild(instance.$el);
|
||||
Vue.nextTick(function() {
|
||||
instance.visible = true;
|
||||
instance.$el.removeEventListener('transitionend', removeDom);
|
||||
instance.timer = setTimeout(function() {
|
||||
if (instance.closed) return;
|
||||
instance.visible = false;
|
||||
instance.$el.addEventListener('transitionend', removeDom);
|
||||
instance.closed = true;
|
||||
}, duration);
|
||||
});
|
||||
return instance;
|
||||
};
|
||||
|
||||
Toast.loading = (options) => {
|
||||
return new Toast(merge({
|
||||
type: 'loading'
|
||||
}, options));
|
||||
};
|
||||
|
||||
Toast.success = (options) => {
|
||||
const message = typeof options === 'string' ? options : options.message;
|
||||
return new Toast(merge({
|
||||
type: 'success',
|
||||
message: message
|
||||
}, options));
|
||||
};
|
||||
|
||||
Toast.fail = (options) => {
|
||||
const message = typeof options === 'string' ? options : options.message;
|
||||
return new Toast(merge({
|
||||
type: 'fail',
|
||||
message: message
|
||||
}, options));
|
||||
};
|
||||
|
||||
export default Toast;
|
81
packages/toast/src/toast.vue
Normal file
81
packages/toast/src/toast.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<transition name="zan-toast">
|
||||
<div class="zan-toast" :class="['zan-toast--' + displayStyle]" v-show="visible">
|
||||
<!-- 只显示文字 -->
|
||||
<template v-if="displayStyle === 'text'" >
|
||||
<div class="zan-toast__text">{{message}}</div>
|
||||
</template>
|
||||
<!-- 加载中 -->
|
||||
<template v-if="displayStyle === 'loading'">
|
||||
<zan-loading v-if="type === 'loading'" type="gradient-circle" color="white"></zan-loading>
|
||||
</template>
|
||||
<!-- 图案加文字 -->
|
||||
<template v-if="displayStyle === 'default'">
|
||||
<zan-icon class="zan-toast__icon" name="check"></zan-icon>
|
||||
<div class="zan-toast__text">{{message}}</div>
|
||||
</template>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import zanLoading from 'packages/loading';
|
||||
import zanIcon from 'packages/icon';
|
||||
|
||||
const TOAST_TYPES = ['text', 'loading', 'success', 'fail'];
|
||||
/**
|
||||
* zan-toast
|
||||
* @module components/toast
|
||||
* @desc toast
|
||||
* @param {string} [type=false] - 类型
|
||||
* @param {string} [message] - 信息
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
name: 'zan-toast',
|
||||
|
||||
components: {
|
||||
'zan-loading': zanLoading,
|
||||
'zan-icon': zanIcon
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
validate(value) {
|
||||
return TOAST_TYPES.indexOf(value) > -1;
|
||||
}
|
||||
},
|
||||
message: {
|
||||
type: String,
|
||||
default: '',
|
||||
validate(value) {
|
||||
if (this.type === 'success' || this.type === 'fail') {
|
||||
return value.length <= 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
displayStyle() {
|
||||
switch (this.type) {
|
||||
case 'text':
|
||||
return 'text';
|
||||
case 'loading':
|
||||
return 'loading';
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
},
|
||||
iconName() {
|
||||
// TODO: 更新icon
|
||||
return 'check';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
3
packages/uploader/index.js
Normal file
3
packages/uploader/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import Uploader from './src/main';
|
||||
|
||||
export default Uploader;
|
57
packages/uploader/src/main.vue
Normal file
57
packages/uploader/src/main.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="zan-uploader">
|
||||
<slot>
|
||||
<div>
|
||||
<zan-button block>上传文件</zan-button>
|
||||
</div>
|
||||
</slot>
|
||||
<input type="file" @change="onValueChange" class="zan-uploader__input" ref="input" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'zan-uploader',
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
beforeRead: Function,
|
||||
resultType: {
|
||||
type: String,
|
||||
default: 'dataUrl',
|
||||
validator(value) {
|
||||
return value === 'dataUrl' || value === 'text';
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onValueChange(event) {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
var files = event.target.files;
|
||||
var file = files[0];
|
||||
if (!file) return;
|
||||
if (this.beforeRead && !this.beforeRead(file)) return;
|
||||
var reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
this.$emit('file-readed',
|
||||
{
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
size: file.size,
|
||||
content: e.target.result
|
||||
});
|
||||
this.$refs.input.value = '';
|
||||
};
|
||||
if (this.resultType === 'dataUrl') {
|
||||
reader.readAsDataURL(file);
|
||||
} else if (this.resultType === 'text') {
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -30,21 +30,21 @@ function doBindEvent() {
|
||||
|
||||
// 处理滚动函数
|
||||
function handleScrollEvent() {
|
||||
let element = this.el;
|
||||
let scrollEventTarget = this.scrollEventTarget;
|
||||
const element = this.el;
|
||||
const scrollEventTarget = this.scrollEventTarget;
|
||||
|
||||
// 已被禁止的滚动处理
|
||||
if (this.disabled) return;
|
||||
|
||||
let targetScrollTop = Utils.getScrollTop(scrollEventTarget);
|
||||
let targetBottom = targetScrollTop + Utils.getVisibleHeight(scrollEventTarget);
|
||||
const targetScrollTop = Utils.getScrollTop(scrollEventTarget);
|
||||
const targetBottom = targetScrollTop + Utils.getVisibleHeight(scrollEventTarget);
|
||||
|
||||
// 判断是否到了底
|
||||
let needLoadMoreToLower = false;
|
||||
if (element === scrollEventTarget) {
|
||||
needLoadMoreToLower = scrollEventTarget.scollHeight - targetBottom < this.offset;
|
||||
} else {
|
||||
let elementBottom = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget) + Utils.getVisibleHeight(element);
|
||||
const elementBottom = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget) + Utils.getVisibleHeight(element);
|
||||
needLoadMoreToLower = elementBottom - Utils.getVisibleHeight(scrollEventTarget) < this.offset;
|
||||
}
|
||||
if (needLoadMoreToLower) {
|
||||
@ -56,7 +56,7 @@ function handleScrollEvent() {
|
||||
if (element === scrollEventTarget) {
|
||||
needLoadMoreToUpper = targetScrollTop < this.offset;
|
||||
} else {
|
||||
let elementTop = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget);
|
||||
const elementTop = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget);
|
||||
needLoadMoreToUpper = elementTop + this.offset > 0;
|
||||
}
|
||||
if (needLoadMoreToUpper) {
|
||||
@ -64,6 +64,30 @@ function handleScrollEvent() {
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定事件
|
||||
function startBind(el) {
|
||||
const context = el[CONTEXT];
|
||||
|
||||
context.vm.$nextTick(function() {
|
||||
if (Utils.isAttached(el)) {
|
||||
doBindEvent.call(el[CONTEXT]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 确认何时绑事件监听函数
|
||||
function doCheckStartBind(el) {
|
||||
const context = el[CONTEXT];
|
||||
|
||||
if (context.vm._isMounted) {
|
||||
startBind(el);
|
||||
} else {
|
||||
context.vm.$on('hook:mounted', function() {
|
||||
startBind(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default function(type) {
|
||||
return {
|
||||
bind(el, binding, vnode) {
|
||||
@ -76,11 +100,7 @@ export default function(type) {
|
||||
}
|
||||
el[CONTEXT].cb[type] = binding.value;
|
||||
|
||||
vnode.context.$on('hook:mounted', function() {
|
||||
if (Utils.isAttached(el)) {
|
||||
doBindEvent.call(el[CONTEXT]);
|
||||
}
|
||||
});
|
||||
doCheckStartBind(el);
|
||||
},
|
||||
|
||||
update(el) {
|
||||
|
BIN
packages/zanui-css/assets/icons.sketch
Normal file
BIN
packages/zanui-css/assets/icons.sketch
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@youzan/zanui-css",
|
||||
"version": "0.0.31",
|
||||
"version": "0.0.38",
|
||||
"description": "zanui css.",
|
||||
"main": "lib/index.css",
|
||||
"style": "lib/index.css",
|
||||
@ -9,7 +9,8 @@
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "gulp build"
|
||||
"build": "gulp build",
|
||||
"build:icons": "sh scripts/build.sh"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
83
packages/zanui-css/scripts/build.sh
Normal file
83
packages/zanui-css/scripts/build.sh
Normal file
@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
basepath=$(dirname $0)
|
||||
server_prefix=/zanui/icon
|
||||
|
||||
# convert relative path to absolute path
|
||||
function abspath() {
|
||||
pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname \"$1\"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename \"$1\"`"; else echo "$cur_dir/`basename \"$1\"`"; fi; fi; popd > /dev/null;
|
||||
}
|
||||
|
||||
command_exists () {
|
||||
type "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
fontname() {
|
||||
if command_exists superman ; then
|
||||
echo "//b.yzcdn.cn$server_prefix/$(basename $basepath/../build/font/zanui-icon-*.$1)"
|
||||
else
|
||||
echo "$(abspath $basepath/../build/font/zanui-icon-*.$1)"
|
||||
fi
|
||||
}
|
||||
|
||||
# generate font files from sketch file
|
||||
$basepath/extract-icons.sh
|
||||
$basepath/generate-font.sh
|
||||
|
||||
if command_exists superman ; then
|
||||
# upload to cdn
|
||||
superman cdn $server_prefix $basepath/../build/font/zanui-icon-*
|
||||
fi
|
||||
|
||||
# generate fontface style
|
||||
eot=$(fontname eot)
|
||||
cat > $basepath/../src/icon.css <<EOF
|
||||
/* DO NOT EDIT! Generated by fount */
|
||||
|
||||
@font-face {
|
||||
font-family: 'zan-icon';
|
||||
src: url('$eot');
|
||||
src: url('$eot?#iefix') format('embedded-opentype'),
|
||||
url('$(fontname woff2)') format('woff2'),
|
||||
url('$(fontname woff)') format('woff'),
|
||||
url('$(fontname ttf)') format('truetype')
|
||||
}
|
||||
|
||||
.zan-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.zan-icon::before {
|
||||
font-family: "zan-icon" !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
|
||||
/* For safety - reset parent styles, that can break glyph codes*/
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
/* fix buttons height, for twitter bootstrap */
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
/* remove if not needed */
|
||||
/* margin-left: .2em; */
|
||||
|
||||
/* you can be more comfortable with increased icons size */
|
||||
/* font-size: 120%; */
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
EOF
|
||||
|
||||
cat $basepath/../build/css/zanui-icon-codes.css >> $basepath/../src/icon.css
|
6
packages/zanui-css/scripts/extract-icons.sh
Executable file
6
packages/zanui-css/scripts/extract-icons.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
basepath=$(dirname $0)
|
||||
|
||||
rm -rf $basepath/../icons
|
||||
sketchtool export slices --formats=svg --overwriting=YES --save-for-web=YES --output=$basepath/../icons $basepath/../assets/icons.sketch
|
147
packages/zanui-css/scripts/fount-config.js
Normal file
147
packages/zanui-css/scripts/fount-config.js
Normal file
@ -0,0 +1,147 @@
|
||||
module.exports = {
|
||||
name: 'zanui-icon',
|
||||
output: '../build',
|
||||
meta: {
|
||||
author: 'houzi, zhangmin',
|
||||
license: 'MIT',
|
||||
license_url: 'https://opensource.org/licenses/MIT',
|
||||
homepage: 'http://github.com/youzan',
|
||||
css_prefix_text: 'zan-icon-',
|
||||
filename_hash: true
|
||||
},
|
||||
hinting: true,
|
||||
glyphs_dir: '../icons',
|
||||
glyphs: [
|
||||
{
|
||||
keywords: ['qr', 'invalid'],
|
||||
src: '二维码失效.svg',
|
||||
css: 'qr-invalid'
|
||||
},
|
||||
{
|
||||
keywords: ['qr'],
|
||||
src: '二维码.svg',
|
||||
css: 'qr'
|
||||
},
|
||||
{
|
||||
keywords: ['exchange'],
|
||||
src: '兑换.svg',
|
||||
css: 'exchange',
|
||||
'correct_contour_direction': true
|
||||
},
|
||||
{
|
||||
keywords: ['close'],
|
||||
src: '关闭.svg',
|
||||
css: 'close'
|
||||
},
|
||||
{
|
||||
keywords: ['location'],
|
||||
src: '其他分店.svg',
|
||||
css: 'location'
|
||||
},
|
||||
{
|
||||
keywords: ['upgrade'],
|
||||
src: '升级地址.svg',
|
||||
css: 'upgrade'
|
||||
},
|
||||
{
|
||||
keywords: ['check'],
|
||||
src: '单选.svg',
|
||||
css: 'check'
|
||||
},
|
||||
{
|
||||
keywords: ['checked'],
|
||||
src: '选中.svg',
|
||||
css: 'checked'
|
||||
},
|
||||
{
|
||||
keywords: ['like', 'outline'],
|
||||
src: '喜欢.svg',
|
||||
css: 'like-o'
|
||||
},
|
||||
{
|
||||
keywords: ['like', 'filled'],
|
||||
src: '喜欢2.svg',
|
||||
css: 'like'
|
||||
},
|
||||
{
|
||||
keywords: ['chat'],
|
||||
src: '客服.svg',
|
||||
css: 'chat'
|
||||
},
|
||||
{
|
||||
keywords: ['shop'],
|
||||
src: '店铺.svg',
|
||||
css: 'shop'
|
||||
},
|
||||
{
|
||||
keywords: ['photograph'],
|
||||
src: '拍照.svg',
|
||||
css: 'photograph'
|
||||
},
|
||||
{
|
||||
keywords: ['add'],
|
||||
src: '新增地址.svg',
|
||||
css: 'add'
|
||||
},
|
||||
{
|
||||
keywords: ['add2'],
|
||||
src: '添加.svg',
|
||||
css: 'add2'
|
||||
},
|
||||
{
|
||||
keywords: ['photo'],
|
||||
src: '照片.svg',
|
||||
css: 'photo'
|
||||
},
|
||||
{
|
||||
keywords: ['logistics'],
|
||||
src: '物流.svg',
|
||||
css: 'logistics'
|
||||
},
|
||||
{
|
||||
keywords: ['edit'],
|
||||
src: '编辑地址.svg',
|
||||
css: 'edit'
|
||||
},
|
||||
{
|
||||
keywords: ['passed'],
|
||||
src: '认证通过.svg',
|
||||
css: 'passed'
|
||||
},
|
||||
{
|
||||
keywords: ['cart'],
|
||||
src: '购物车.svg',
|
||||
css: 'cart'
|
||||
},
|
||||
{
|
||||
keywords: ['arrow'],
|
||||
src: '进入箭头.svg',
|
||||
css: 'arrow'
|
||||
},
|
||||
{
|
||||
keywords: ['gift'],
|
||||
src: '送礼.svg',
|
||||
css: 'gift'
|
||||
},
|
||||
{
|
||||
keywords: ['search'],
|
||||
src: '搜索.svg',
|
||||
css: 'search'
|
||||
},
|
||||
{
|
||||
keywords: ['clear'],
|
||||
src: '清除搜索.svg',
|
||||
css: 'clear'
|
||||
},
|
||||
{
|
||||
keywords: ['success'],
|
||||
src: '成功.svg',
|
||||
css: 'success'
|
||||
},
|
||||
{
|
||||
keywords: ['fail'],
|
||||
src: '失败.svg',
|
||||
css: 'fail'
|
||||
}
|
||||
]
|
||||
};
|
5
packages/zanui-css/scripts/generate-font.sh
Executable file
5
packages/zanui-css/scripts/generate-font.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
basepath=$(dirname $0)
|
||||
|
||||
iconfount --config $basepath/fount-config.js
|
@ -32,6 +32,10 @@
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
& + .zan-button--block {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@m default {
|
||||
color: $button-default-color;
|
||||
background-color: $button-default-background-color;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
@component-namespace zan {
|
||||
@b cell-group {
|
||||
padding-left: 10px;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
|
||||
@ -14,9 +14,8 @@
|
||||
|
||||
@b cell {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 10px 10px 10px 0;
|
||||
padding: 10px 15px 10px 0;
|
||||
box-sizing: border-box;
|
||||
line-height: 22px;
|
||||
background-color: $c-white;
|
||||
@ -35,8 +34,19 @@
|
||||
}
|
||||
|
||||
@e title {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
/* 清除空白字符对高度的影响 */
|
||||
vertical-align: bottom;
|
||||
|
||||
&.zan-cell__required {
|
||||
&::before {
|
||||
content: '*';
|
||||
position: absolute;
|
||||
left: -7px;
|
||||
font-size: 14px;
|
||||
color: #f44;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@e label {
|
||||
@ -62,7 +72,7 @@
|
||||
.zan-icon-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 10px;
|
||||
right: 15px;
|
||||
transform: translateY(-50%);
|
||||
color: $c-gray-dark;
|
||||
font-size: 12px;
|
||||
|
@ -5,7 +5,6 @@
|
||||
@component-namespace zan {
|
||||
@b field {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@m hastextarea {
|
||||
.zan-field__control {
|
||||
@ -31,8 +30,7 @@
|
||||
}
|
||||
|
||||
@m error {
|
||||
.zan-field__control,
|
||||
.zan-cell__title {
|
||||
.zan-field__control {
|
||||
color: $c-red;
|
||||
}
|
||||
}
|
||||
@ -52,6 +50,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@m autosize {
|
||||
.zan-field__control {
|
||||
min-height: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.zan-cell__title,
|
||||
.zan-cell__value {
|
||||
float: none;
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* DO NOT EDIT! Generated by fount */
|
||||
|
||||
@font-face {
|
||||
font-family: 'zuiicon';
|
||||
src: url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.eot');
|
||||
src: url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.eot?#iefix') format('embedded-opentype'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.woff2') format('woff2'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.woff') format('woff'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.ttf') format('truetype')
|
||||
font-family: 'zan-icon';
|
||||
src: url('//b.yzcdn.cn/zanui/icon/zanui-icon-d64cb2f719.eot');
|
||||
src: url('//b.yzcdn.cn/zanui/icon/zanui-icon-d64cb2f719.eot?#iefix') format('embedded-opentype'),
|
||||
url('//b.yzcdn.cn/zanui/icon/zanui-icon-d64cb2f719.woff2') format('woff2'),
|
||||
url('//b.yzcdn.cn/zanui/icon/zanui-icon-d64cb2f719.woff') format('woff'),
|
||||
url('//b.yzcdn.cn/zanui/icon/zanui-icon-d64cb2f719.ttf') format('truetype')
|
||||
}
|
||||
|
||||
.zan-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.zan-icon::before {
|
||||
font-family: "zuiicon" !important;
|
||||
font-family: "zan-icon" !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
@ -39,28 +39,37 @@
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-mozan-osx-font-smoothing: grayscale;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
/* DO NOT EDIT! Generated by fount */
|
||||
/* DO NOT EDIT! Generated by iconfount */
|
||||
|
||||
|
||||
.zan-icon-album:before { content: '\e800'; } /* '' */
|
||||
.zan-icon-arrow:before { content: '\e801'; } /* '' */
|
||||
.zan-icon-camera:before { content: '\e802'; } /* '' */
|
||||
.zan-icon-certificate:before { content: '\e803'; } /* '' */
|
||||
.zan-icon-check:before { content: '\e804'; } /* '' */
|
||||
.zan-icon-checked:before { content: '\e805'; } /* '' */
|
||||
.zan-icon-close:before { content: '\e806'; } /* '' */
|
||||
.zan-icon-gift:before { content: '\e807'; } /* '' */
|
||||
.zan-icon-home:before { content: '\e808'; } /* '' */
|
||||
.zan-icon-location:before { content: '\e809'; } /* '' */
|
||||
.zan-icon-message:before { content: '\e80a'; } /* '' */
|
||||
.zan-icon-send:before { content: '\e80b'; } /* '' */
|
||||
.zan-icon-shopping-cart:before { content: '\e80c'; } /* '' */
|
||||
.zan-icon-sign:before { content: '\e80d'; } /* '' */
|
||||
.zan-icon-store:before { content: '\e80e'; } /* '' */
|
||||
.zan-icon-topay:before { content: '\e80f'; } /* '' */
|
||||
.zan-icon-tosend:before { content: '\e810'; } /* '' */
|
||||
.zan-icon-qr-invalid:before { content: '\e800'; } /* '' */
|
||||
.zan-icon-qr:before { content: '\e801'; } /* '' */
|
||||
.zan-icon-exchange:before { content: '\e802'; } /* '' */
|
||||
.zan-icon-close:before { content: '\e803'; } /* '' */
|
||||
.zan-icon-location:before { content: '\e804'; } /* '' */
|
||||
.zan-icon-upgrade:before { content: '\e805'; } /* '' */
|
||||
.zan-icon-check:before { content: '\e806'; } /* '' */
|
||||
.zan-icon-checked:before { content: '\e807'; } /* '' */
|
||||
.zan-icon-like-o:before { content: '\e808'; } /* '' */
|
||||
.zan-icon-like:before { content: '\e809'; } /* '' */
|
||||
.zan-icon-chat:before { content: '\e80a'; } /* '' */
|
||||
.zan-icon-shop:before { content: '\e80b'; } /* '' */
|
||||
.zan-icon-photograph:before { content: '\e80c'; } /* '' */
|
||||
.zan-icon-add:before { content: '\e80d'; } /* '' */
|
||||
.zan-icon-add2:before { content: '\e80e'; } /* '' */
|
||||
.zan-icon-photo:before { content: '\e80f'; } /* '' */
|
||||
.zan-icon-logistics:before { content: '\e810'; } /* '' */
|
||||
.zan-icon-edit:before { content: '\e811'; } /* '' */
|
||||
.zan-icon-passed:before { content: '\e812'; } /* '' */
|
||||
.zan-icon-cart:before { content: '\e813'; } /* '' */
|
||||
.zan-icon-arrow:before { content: '\e814'; } /* '' */
|
||||
.zan-icon-gift:before { content: '\e815'; } /* '' */
|
||||
.zan-icon-search:before { content: '\e816'; } /* '' */
|
||||
.zan-icon-clear:before { content: '\e817'; } /* '' */
|
||||
.zan-icon-success:before { content: '\e818'; } /* '' */
|
||||
.zan-icon-fail:before { content: '\e819'; } /* '' */
|
@ -5,13 +5,13 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
overflow: auto;
|
||||
|
||||
@e image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transition: .2s;
|
||||
transition: .2s ease-out;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
@ -19,11 +19,10 @@
|
||||
top: 50%;
|
||||
transform: translate3d(0, -50%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@m top {
|
||||
top: 0;
|
||||
transform: none;
|
||||
}
|
||||
.zan-swipe {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,4 +25,6 @@
|
||||
@import './actionsheet.css';
|
||||
@import './quantity.css';
|
||||
@import './progress.css';
|
||||
@import './toast.css';
|
||||
@import './uploader.css';
|
||||
@import './swipe.css';
|
||||
|
7
packages/zanui-css/src/mixins/clearfix.css
Normal file
7
packages/zanui-css/src/mixins/clearfix.css
Normal file
@ -0,0 +1,7 @@
|
||||
@define-mixin clearfix {
|
||||
&::after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
@component-namespace zan {
|
||||
@b picker {
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
@e toolbar {
|
||||
height: 40px;
|
||||
@ -47,6 +48,18 @@
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@m 4 {
|
||||
.zan-picker-column {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
@m 5 {
|
||||
.zan-picker-column {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,14 @@
|
||||
padding: 1px;
|
||||
border: 1px solid $c-gray-dark;
|
||||
border-width: 1px 0;
|
||||
border-radius: 0;
|
||||
box-sizing: content-box;
|
||||
color: $c-gray-darker;
|
||||
font-size: 14px;
|
||||
outline: 0;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,16 @@
|
||||
box-sizing: border-box;
|
||||
padding: 4px 15px;
|
||||
background-color: #F2F2F2;
|
||||
@when focus {
|
||||
|
||||
@m focus {
|
||||
.zan-search__input-wrap {
|
||||
width: 82%;
|
||||
}
|
||||
span {
|
||||
.zan-icon-clear {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
@e input-wrap {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
@ -25,12 +27,7 @@
|
||||
border: 1px solid $c-gray-light;
|
||||
border-radius: 4px;
|
||||
background-color: $c-white;
|
||||
span {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
@ -40,14 +37,33 @@
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
@e cancel {
|
||||
display: none;
|
||||
color: #44BB00;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
@when focus {
|
||||
margin-left: 5px;
|
||||
|
||||
@m focus {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.zan-icon-search {
|
||||
color: $c-gray-darker;
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
left: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.zan-icon-clear {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 8px;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
|
38
packages/zanui-css/src/toast.css
Normal file
38
packages/zanui-css/src/toast.css
Normal file
@ -0,0 +1,38 @@
|
||||
@import './common/var.css';
|
||||
|
||||
@component-namespace zan {
|
||||
@b toast {
|
||||
position: fixed;
|
||||
z-index: 3000;
|
||||
border-radius: 5px;
|
||||
background-color: #272727;
|
||||
opacity: .7;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
font-size: 12px;
|
||||
color: $c-white;
|
||||
text-align: center;
|
||||
|
||||
@m loading {
|
||||
padding: 45px;
|
||||
}
|
||||
|
||||
@m text {
|
||||
padding: 12px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
@m default {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
.zan-toast__icon {
|
||||
padding: 20px;
|
||||
font-size: 36px;
|
||||
}
|
||||
.zan-toast__text {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
packages/zanui-css/src/uploader.css
Normal file
24
packages/zanui-css/src/uploader.css
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
@component-namespace zan {
|
||||
@b uploader {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
@e input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
input[type="file" i]::-webkit-file-upload-button {
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
}
|
12
src/index.js
12
src/index.js
@ -30,8 +30,11 @@ import Row from '../packages/row/index.js';
|
||||
import Actionsheet from '../packages/actionsheet/index.js';
|
||||
import Quantity from '../packages/quantity/index.js';
|
||||
import Progress from '../packages/progress/index.js';
|
||||
import Toast from '../packages/toast/index.js';
|
||||
import Uploader from '../packages/uploader/index.js';
|
||||
import Swipe from '../packages/swipe/index.js';
|
||||
import SwipeItem from '../packages/swipe-item/index.js';
|
||||
import DatetimePicker from '../packages/datetime-picker/index.js';
|
||||
|
||||
const install = function(Vue) {
|
||||
if (install.installed) return;
|
||||
@ -64,8 +67,10 @@ const install = function(Vue) {
|
||||
Vue.component(Actionsheet.name, Actionsheet);
|
||||
Vue.component(Quantity.name, Quantity);
|
||||
Vue.component(Progress.name, Progress);
|
||||
Vue.component(Uploader.name, Uploader);
|
||||
Vue.component(Swipe.name, Swipe);
|
||||
Vue.component(SwipeItem.name, SwipeItem);
|
||||
Vue.component(DatetimePicker.name, DatetimePicker);
|
||||
};
|
||||
|
||||
// auto install
|
||||
@ -75,7 +80,7 @@ if (typeof window !== 'undefined' && window.Vue) {
|
||||
|
||||
module.exports = {
|
||||
install,
|
||||
version: '0.0.31',
|
||||
version: '0.0.38',
|
||||
Button,
|
||||
Switch,
|
||||
Field,
|
||||
@ -108,6 +113,9 @@ module.exports = {
|
||||
Actionsheet,
|
||||
Quantity,
|
||||
Progress,
|
||||
Toast,
|
||||
Uploader,
|
||||
Swipe,
|
||||
SwipeItem
|
||||
SwipeItem,
|
||||
DatetimePicker
|
||||
};
|
||||
|
@ -2,13 +2,15 @@ import Vue from 'vue';
|
||||
import { addClass } from 'src/utils/dom';
|
||||
|
||||
const getModal = function() {
|
||||
let modalDom = PopupManager.modalDom;
|
||||
let modalDom = window.popupContext && window.popupContext.modalDom;
|
||||
|
||||
if (modalDom) {
|
||||
PopupManager.popupContext.hasModal = true;
|
||||
window.popupContext.hasModal = true;
|
||||
} else {
|
||||
PopupManager.popupContext.hasModal = false;
|
||||
window.popupContext.hasModal = false;
|
||||
|
||||
modalDom = document.createElement('div');
|
||||
PopupManager.modalDom = modalDom;
|
||||
window.popupContext.modalDom = modalDom;
|
||||
|
||||
modalDom.addEventListener('touchmove', function(event) {
|
||||
event.preventDefault();
|
||||
@ -75,7 +77,11 @@ const PopupManager = {
|
||||
|
||||
addClass(modalDom, 'zan-modal');
|
||||
|
||||
document.body.appendChild(modalDom);
|
||||
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {
|
||||
dom.parentNode.appendChild(modalDom);
|
||||
} else {
|
||||
document.body.appendChild(modalDom);
|
||||
}
|
||||
|
||||
if (zIndex) {
|
||||
modalDom.style.zIndex = zIndex;
|
||||
|
@ -1,57 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
let id = 0;
|
||||
|
||||
class Creater {
|
||||
constructor(Compo, propsData) {
|
||||
let Ctor = Vue.extend(Compo);
|
||||
this.vue = new Ctor({ propsData });
|
||||
this.el = null;
|
||||
}
|
||||
|
||||
mount() {
|
||||
const elem = exports.createElm();
|
||||
this.vue.$mount(elem);
|
||||
this.el = this.vue.$el;
|
||||
}
|
||||
|
||||
triggerEvent(name, ...opts) {
|
||||
let eventName;
|
||||
let elem = this.el;
|
||||
|
||||
if (/^mouse|click/.test(name)) {
|
||||
eventName = 'MouseEvents';
|
||||
} else if (/^key/.test(name)) {
|
||||
eventName = 'KeyboardEvent';
|
||||
} else {
|
||||
eventName = 'HTMLEvents';
|
||||
}
|
||||
const evt = document.createEvent(eventName);
|
||||
|
||||
evt.initEvent(name, ...opts);
|
||||
elem.dispatchEvent
|
||||
? elem.dispatchEvent(evt)
|
||||
: elem.fireEvent('on' + name, evt);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.el &&
|
||||
this.el.parentNode &&
|
||||
this.el.parentNode.removeChild(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
exports.createElm = function() {
|
||||
const elm = document.createElement('div');
|
||||
|
||||
elm.id = 'app' + ++id;
|
||||
document.body.appendChild(elm);
|
||||
|
||||
return elm;
|
||||
};
|
||||
|
||||
exports.createVue = function(Compo, propsData = {}) {
|
||||
return new Creater(Compo, propsData);
|
||||
};
|
@ -1,16 +1,17 @@
|
||||
import { createVue } from '../creater';
|
||||
import ActionSheet from 'packages/actionsheet';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('ActionSheet', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createVue(ActionSheet);
|
||||
vm.mount();
|
||||
wrapper = mount(ActionSheet, {
|
||||
propsData: {}
|
||||
});
|
||||
|
||||
expect(vm.el.classList.contains('zan-actionsheet')).to.true;
|
||||
expect(wrapper.hasClass('zan-actionsheet')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { createVue } from '../creater';
|
||||
import Card from 'packages/card';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('Card', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createVue(Card, {
|
||||
title: 'card',
|
||||
desc: 'card',
|
||||
thumb: 'https://img.yzcdn.cn/upload_files/2017/02/17/FnDwvwHmU-OiqsbjAO5X7wh1KWrR.jpg!100x100.jpg'
|
||||
wrapper = mount(Card, {
|
||||
propsData: {
|
||||
thumb: 'thumb'
|
||||
}
|
||||
});
|
||||
vm.mount();
|
||||
|
||||
expect(vm.el.classList.contains('zan-card')).to.true;
|
||||
expect(wrapper.hasClass('zan-card')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { createVue } from '../creater';
|
||||
import CellGroup from 'packages/cell-group';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('Cell', () => {
|
||||
let vm;
|
||||
describe('CellGroup', () => {
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('cell group create', () => {
|
||||
vm = createVue(CellGroup);
|
||||
vm.mount();
|
||||
it('create', () => {
|
||||
wrapper = mount(CellGroup, {
|
||||
propsData: {}
|
||||
});
|
||||
|
||||
expect(vm.el.classList.contains('zan-cell-group')).to.true;
|
||||
expect(wrapper.hasClass('zan-cell-group')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { createVue } from '../creater';
|
||||
import Checkbox from 'packages/checkbox';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('Checkbox', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createVue(Checkbox);
|
||||
vm.mount();
|
||||
wrapper = mount(Checkbox, {
|
||||
propsData: {}
|
||||
});
|
||||
|
||||
expect(vm.el.classList.contains('zan-checkbox')).to.true;
|
||||
expect(wrapper.hasClass('zan-checkbox')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { createVue } from '../creater';
|
||||
import Field from 'packages/field';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('Field', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createVue(Field);
|
||||
vm.mount();
|
||||
wrapper = mount(Field, {
|
||||
propsData: {}
|
||||
});
|
||||
|
||||
expect(vm.el.classList.contains('zan-field')).to.true;
|
||||
expect(wrapper.hasClass('zan-field')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
67
test/unit/specs/loading.spec.js
Normal file
67
test/unit/specs/loading.spec.js
Normal file
@ -0,0 +1,67 @@
|
||||
import Loading from 'packages/loading';
|
||||
import { mount } from 'avoriaz';
|
||||
|
||||
describe('Loading', () => {
|
||||
let wrapper;
|
||||
afterEach(() => {
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create default', () => {
|
||||
wrapper = mount(Loading);
|
||||
|
||||
expect(wrapper.hasClass('zan-loading')).to.be.true;
|
||||
});
|
||||
|
||||
it('create gradient-circle black', () => {
|
||||
wrapper = mount(Loading, {
|
||||
propsData: {
|
||||
type: 'gradient-circle',
|
||||
color: 'black'
|
||||
}
|
||||
});
|
||||
const spinner = wrapper.find('.zan-loading__spinner')[0];
|
||||
|
||||
expect(spinner.hasClass('zan-loading__spinner--gradient-circle')).to.be.true;
|
||||
expect(spinner.hasClass('zan-loading__spinner--black')).to.be.true;
|
||||
});
|
||||
|
||||
it('create gradient-circle white', () => {
|
||||
wrapper = mount(Loading, {
|
||||
propsData: {
|
||||
type: 'gradient-circle',
|
||||
color: 'white'
|
||||
}
|
||||
});
|
||||
const spinner = wrapper.find('.zan-loading__spinner')[0];
|
||||
|
||||
expect(spinner.hasClass('zan-loading__spinner--gradient-circle')).to.be.true;
|
||||
expect(spinner.hasClass('zan-loading__spinner--white')).to.be.true;
|
||||
});
|
||||
|
||||
it('create circle black', () => {
|
||||
wrapper = mount(Loading, {
|
||||
propsData: {
|
||||
type: 'circle',
|
||||
color: 'black'
|
||||
}
|
||||
});
|
||||
const spinner = wrapper.find('.zan-loading__spinner')[0];
|
||||
|
||||
expect(spinner.hasClass('zan-loading__spinner--circle')).to.be.true;
|
||||
expect(spinner.hasClass('zan-loading__spinner--black')).to.be.true;
|
||||
});
|
||||
|
||||
it('create circle white', () => {
|
||||
wrapper = mount(Loading, {
|
||||
propsData: {
|
||||
type: 'circle',
|
||||
color: 'white'
|
||||
}
|
||||
});
|
||||
const spinner = wrapper.find('.zan-loading__spinner')[0];
|
||||
|
||||
expect(spinner.hasClass('zan-loading__spinner--circle')).to.be.true;
|
||||
expect(spinner.hasClass('zan-loading__spinner--white')).to.be.true;
|
||||
});
|
||||
});
|
@ -1,83 +1,100 @@
|
||||
import Switch from 'packages/switch';
|
||||
import { createVue } from '../creater';
|
||||
import ZanLoading from 'packages/loading';
|
||||
import { mount } from 'avoriaz';
|
||||
// import { stub } from 'sinon';
|
||||
|
||||
describe('Switch', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
|
||||
afterEach(() => {
|
||||
vm && vm.destroy();
|
||||
wrapper && wrapper.destroy();
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createVue(Switch, {
|
||||
checked: true
|
||||
it('create on switch', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
checked: true
|
||||
}
|
||||
});
|
||||
vm.mount();
|
||||
|
||||
expect(vm.el.classList.contains('zan-switch')).to.true;
|
||||
expect(vm.el.classList.contains('zan-switch--on')).to.true;
|
||||
expect(wrapper.hasClass('zan-switch')).to.be.true;
|
||||
expect(wrapper.hasClass('zan-switch--on')).to.be.true;
|
||||
});
|
||||
|
||||
it('create off switch', () => {
|
||||
vm = createVue(Switch, {
|
||||
checked: false
|
||||
});
|
||||
vm.mount();
|
||||
|
||||
expect(vm.el.classList.contains('zan-switch')).to.true;
|
||||
});
|
||||
|
||||
it('switch click default', done => {
|
||||
vm = createVue({
|
||||
data() {
|
||||
return {
|
||||
checked: false
|
||||
};
|
||||
},
|
||||
components: {
|
||||
'zan-switch': Switch
|
||||
},
|
||||
template: `
|
||||
<zan-switch :checked="checked"></zan-switch>
|
||||
`
|
||||
});
|
||||
vm.mount();
|
||||
expect(vm.el.classList.contains('zan-switch')).to.true;
|
||||
expect(vm.el.classList.contains('zan-switch--off')).to.true;
|
||||
vm.el.click();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.el.classList.contains('zan-switch--off')).to.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('switch click', done => {
|
||||
vm = createVue({
|
||||
data() {
|
||||
return {
|
||||
checked: false
|
||||
};
|
||||
},
|
||||
components: {
|
||||
'zan-switch': Switch
|
||||
},
|
||||
template: `
|
||||
<zan-switch :checked="checked" :onChange="handleClick"></zan-switch>
|
||||
`,
|
||||
methods: {
|
||||
handleClick(e) {
|
||||
this.checked = !this.checked;
|
||||
}
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
checked: false
|
||||
}
|
||||
});
|
||||
vm.mount();
|
||||
expect(vm.el.classList.contains('zan-switch')).to.true;
|
||||
expect(vm.el.classList.contains('zan-switch--off')).to.true;
|
||||
vm.el.click();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.el.classList.contains('zan-switch--on')).to.true;
|
||||
done();
|
||||
expect(wrapper.hasClass('zan-switch')).to.be.true;
|
||||
expect(wrapper.hasClass('zan-switch--off')).to.be.true;
|
||||
});
|
||||
|
||||
it('create loading switch', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
const loading = wrapper.find(ZanLoading)[0];
|
||||
|
||||
expect(wrapper.hasClass('zan-switch')).to.be.true;
|
||||
expect(loading.isVueComponent).to.be.true;
|
||||
});
|
||||
|
||||
it('loading switch should be unclickable', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
loading: true,
|
||||
checked: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper.hasClass('zan-switch--on')).to.be.true;
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('zan-switch--on')).to.be.true;
|
||||
});
|
||||
|
||||
it('create disabled switch', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
disabled: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper.hasClass('zan-switch')).to.be.true;
|
||||
expect(wrapper.hasClass('zan-switch--disabled')).to.be.true;
|
||||
});
|
||||
|
||||
it('disabled switch should be unclickable', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
disabled: true,
|
||||
checked: false
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper.hasClass('zan-switch--off')).to.be.true;
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('zan-switch--off')).to.be.true;
|
||||
});
|
||||
|
||||
it('click event should fire change event', () => {
|
||||
wrapper = mount(Switch, {
|
||||
propsData: {
|
||||
checked: false
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
});
|
||||
const eventStub = sinon.stub(wrapper.vm, '$emit');
|
||||
|
||||
expect(wrapper.hasClass('zan-switch--off')).to.be.true;
|
||||
wrapper.simulate('click');
|
||||
expect(eventStub.calledOnce).to.be.true;
|
||||
expect(eventStub.calledWith('change')).to.be.true;
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user