Merge pull request #41 from eleme/feat/update-popper

update popover and tooltip
pull/2/head
FuryBean 2016-08-08 17:47:59 +08:00 committed by GitHub
commit b3134b92b4
7 changed files with 115 additions and 121 deletions

View File

@ -117,7 +117,7 @@
<div class="demo-box demo-popover"> <div class="demo-box demo-popover">
<el-popover <el-popover
v-ref:popover1 ref="popover1"
placement="top-start" placement="top-start"
title="标题" title="标题"
width="200" width="200"
@ -126,7 +126,7 @@
</el-popover> </el-popover>
<el-popover <el-popover
v-ref:popover2 ref="popover2"
placement="bottom" placement="bottom"
title="标题" title="标题"
width="200" width="200"
@ -135,7 +135,7 @@
</el-popover> </el-popover>
<el-popover <el-popover
v-ref:popover3 ref="popover3"
placement="right" placement="right"
title="标题" title="标题"
width="200" width="200"
@ -146,13 +146,13 @@
<el-button v-popover:popover1>hover 激活</el-button> <el-button v-popover:popover1>hover 激活</el-button>
<el-button v-popover:popover2>click 激活</el-button> <el-button v-popover:popover2>click 激活</el-button>
<el-input :value="model" v-popover:popover3 placeholder="focus 激活"></el-input> <el-input v-model="model" v-popover:popover3 placeholder="focus 激活"></el-input>
</div> </div>
```html ```html
<el-popover <el-popover
v-ref:popover1 ref="popover1"
placement="top-start" placement="top-start"
title="标题" title="标题"
width="200" width="200"
@ -161,7 +161,7 @@
</el-popover> </el-popover>
<el-popover <el-popover
v-ref:popover2 ref="popover2"
placement="bottom" placement="bottom"
title="标题" title="标题"
width="200" width="200"
@ -170,7 +170,7 @@
</el-popover> </el-popover>
<el-popover <el-popover
v-ref:popover3 ref="popover3"
placement="right" placement="right"
title="标题" title="标题"
width="200" width="200"
@ -188,7 +188,7 @@
<div class="demo-box demo-popover"> <div class="demo-box demo-popover">
<el-popover <el-popover
v-ref:popover4 ref="popover4"
placement="right" placement="right"
width="400" width="400"
trigger="click"> trigger="click">
@ -204,7 +204,7 @@
```html ```html
<el-popover <el-popover
v-ref:popover4 ref="popover4"
placement="right" placement="right"
width="400" width="400"
trigger="click"> trigger="click">
@ -224,7 +224,7 @@
<div class="demo-box demo-popover"> <div class="demo-box demo-popover">
<el-popover <el-popover
v-ref:popover5 ref="popover5"
placement="top" placement="top"
width="160" width="160"
:visible.sync="visible2"> :visible.sync="visible2">
@ -240,7 +240,7 @@
```html ```html
<el-popover <el-popover
v-ref:popover5 ref="popover5"
placement="top" placement="top"
width="160" width="160"
:visible.sync="visible2"> :visible.sync="visible2">

View File

@ -30,73 +30,49 @@
} }
</style> </style>
<script>
module.exports = {
data() {
return {
value: true
}
},
computed: {
effect() {
return this.value ? 'dark' : 'light';
}
}
}
</script>
<el-switch
v-model="value"
on-text="黑色"
off-text="白色"
on-color="#1f2d3d"
off-color="#ccc">
</el-switch>
<div class="box"> <div class="box">
<div class="top"> <div class="top">
<el-tooltip class="item" :effect="effect" content="Top Left 提示文字" placement="top-start"> <el-tooltip class="item" effect="dark" content="Top Left 提示文字" placement="top-start">
<el-button>上左</el-button> <el-button>上左</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Top Center 提示文字" placement="top"> <el-tooltip class="item" effect="dark" content="Top Center 提示文字" placement="top">
<el-button>上边</el-button> <el-button>上边</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Top Right 提示文字" placement="top-end"> <el-tooltip class="item" effect="dark" content="Top Right 提示文字" placement="top-end">
<el-button>上右</el-button> <el-button>上右</el-button>
</el-tooltip> </el-tooltip>
</div> </div>
<div class="left"> <div class="left">
<el-tooltip class="item" :effect="effect" content="Left Top 提示文字" placement="left-start"> <el-tooltip class="item" effect="dark" content="Left Top 提示文字" placement="left-start">
<el-button>左上</el-button> <el-button>左上</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Left Center 提示文字" placement="left"> <el-tooltip class="item" effect="dark" content="Left Center 提示文字" placement="left">
<el-button>左边</el-button> <el-button>左边</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Left Bottom 提示文字" placement="left-end"> <el-tooltip class="item" effect="dark" content="Left Bottom 提示文字" placement="left-end">
<el-button>左下</el-button> <el-button>左下</el-button>
</el-tooltip> </el-tooltip>
</div> </div>
<div class="right"> <div class="right">
<el-tooltip class="item" :effect="effect" content="Right Top 提示文字" placement="right-start"> <el-tooltip class="item" effect="dark" content="Right Top 提示文字" placement="right-start">
<el-button>右上</el-button> <el-button>右上</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Right Center 提示文字" placement="right"> <el-tooltip class="item" effect="dark" content="Right Center 提示文字" placement="right">
<el-button>右边</el-button> <el-button>右边</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Right Bottom 提示文字" placement="right-end"> <el-tooltip class="item" effect="dark" content="Right Bottom 提示文字" placement="right-end">
<el-button>右下</el-button> <el-button>右下</el-button>
</el-tooltip> </el-tooltip>
</div> </div>
<div class="bottom"> <div class="bottom">
<el-tooltip class="item" :effect="effect" content="Bottom Left 提示文字" placement="bottom-start"> <el-tooltip class="item" effect="dark" content="Bottom Left 提示文字" placement="bottom-start">
<el-button>下左</el-button> <el-button>下左</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Bottom Center 提示文字" placement="bottom"> <el-tooltip class="item" effect="dark" content="Bottom Center 提示文字" placement="bottom">
<el-button>下边</el-button> <el-button>下边</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip class="item" :effect="effect" content="Bottom Right 提示文字" placement="bottom-end"> <el-tooltip class="item" effect="dark" content="Bottom Right 提示文字" placement="bottom-end">
<el-button>下右</el-button> <el-button>下右</el-button>
</el-tooltip> </el-tooltip>
</div> </div>

View File

@ -9,7 +9,7 @@
], ],
"scripts": { "scripts": {
"dev": "node bin/build-entry.js && cooking watch -c scripts/cooking.demo.js", "dev": "node bin/build-entry.js && cooking watch -c scripts/cooking.demo.js",
"dist": "rm -rf lib && cooking build -p && cooking build -c scripts/cooking.component.js -p", "dist": "rm -rf lib && cooking build -c scripts/cooking.conf.js -p && cooking build -c scripts/cooking.component.js -p",
"deploy": "cooking build -c scripts/cooking.demo.js -p", "deploy": "cooking build -c scripts/cooking.demo.js -p",
"gh-docs": "cooking build -c scripts/cooking.demo.js -p && gh-pages -d examples/element-ui --remote origin", "gh-docs": "cooking build -c scripts/cooking.demo.js -p && gh-pages -d examples/element-ui --remote origin",
"prepublish": "make dist" "prepublish": "make dist"

View File

@ -1,13 +1,14 @@
<template> <template>
<div <transition :name="transition">
class="el-popover" <div
v-el:popper class="el-popover"
v-show="visible" ref="popper"
:transition="transition" v-show="showPopper"
:style="{ width: width + 'px' }"> :style="{ width: width + 'px' }">
<div class="el-popover__title" v-if="title" v-text="title"></div> <div class="el-popover__title" v-if="title" v-text="title"></div>
<slot>{{ content }}</slot> <slot>{{ content }}</slot>
</div> </div>
</transition>
</template> </template>
<script> <script>
@ -16,10 +17,8 @@ import Vue from 'vue';
import { on, off } from 'wind-dom/src/event'; import { on, off } from 'wind-dom/src/event';
Vue.directive('popover', { Vue.directive('popover', {
update() { bind(el, binding, vnode) {
this.vm.$nextTick(() => { vnode.context.$refs[binding.arg].$refs.reference = el;
this.vm.$refs[this.arg].reference = this.el;
});
} }
}); });
@ -36,9 +35,7 @@ export default {
}, },
title: String, title: String,
content: String, content: String,
reference: { reference: {},
default: 'body'
},
width: {}, width: {},
visibleArrow: { visibleArrow: {
default: true default: true
@ -56,61 +53,64 @@ export default {
} }
}, },
ready() { mounted() {
let _timer; let _timer;
const reference = this.reference || this.$refs.reference;
this.$nextTick(() => { this.$nextTick(() => {
if (this.trigger === 'click') { if (this.trigger === 'click') {
on(this.reference, 'click', () => { this.visible = !this.visible; }); on(reference, 'click', () => { this.showPopper = !this.showPopper; });
on(document, 'click', (e) => { on(document, 'click', (e) => {
if (!this.$el || if (!this.$el ||
!this.reference || !reference ||
this.$el.contains(e.target) || this.$el.contains(e.target) ||
this.reference.contains(e.target)) return; reference.contains(e.target)) return;
this.visible = false; this.showPopper = false;
}); });
} else if (this.trigger === 'hover') { } else if (this.trigger === 'hover') {
on(this.reference, 'mouseenter', () => { on(reference, 'mouseenter', () => {
this.visible = true; this.showPopper = true;
clearTimeout(_timer); clearTimeout(_timer);
}); });
on(this.reference, 'mouseleave', () => { on(reference, 'mouseleave', () => {
_timer = setTimeout(() => { _timer = setTimeout(() => {
this.visible = false; this.showPopper = false;
}, 200); }, 200);
}); });
} else { } else {
if (this.reference.hasChildNodes()) { if ([].slice.call(reference.children).length) {
const children = this.reference.childNodes; const children = reference.childNodes;
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
if (children[i].nodeName === 'INPUT') { if (children[i].nodeName === 'INPUT') {
on(children[i], 'focus', () => { this.visible = true; }); on(children[i], 'focus', () => { this.showPopper = true; });
on(children[i], 'blur', () => { this.visible = false; }); on(children[i], 'blur', () => { this.showPopper = false; });
break; break;
} }
} }
} else if ( } else if (
this.reference.nodeName === 'INPUT' || reference.nodeName === 'INPUT' ||
this.reference.nodeName === 'TEXTAREA' reference.nodeName === 'TEXTAREA'
) { ) {
on(this.reference, 'focus', () => { this.visible = true; }); on(reference, 'focus', () => { this.showPopper = true; });
on(this.reference, 'blur', () => { this.visible = false; }); on(reference, 'blur', () => { this.showPopper = false; });
} else { } else {
on(this.reference, 'mousedown', () => { this.visible = true; }); on(reference, 'mousedown', () => { this.showPopper = true; });
on(this.reference, 'mouseup', () => { this.visible = false; }); on(reference, 'mouseup', () => { this.showPopper = false; });
} }
} }
}); });
}, },
destroyed() { destroyed() {
off(this.reference, 'mouseup'); const reference = this.reference || this.$refs.reference;
off(this.reference, 'mousedown');
off(this.reference, 'focus'); off(reference, 'mouseup');
off(this.reference, 'blur'); off(reference, 'mousedown');
off(this.reference, 'mouseleave'); off(reference, 'focus');
off(this.reference, 'mouseenter'); off(reference, 'blur');
off(reference, 'mouseleave');
off(reference, 'mouseenter');
} }
}; };
</script> </script>

View File

@ -6,11 +6,16 @@
transition: var(--fade-transition); transition: var(--fade-transition);
} }
.fade-in-linear-transition { .fade-in-linear-enter-active {
opacity: 1; opacity: 1;
transition: var(--fade-linear-transition); transition: var(--fade-linear-transition);
} }
.fade-in-linear-leave-active {
opacity: 0;
transition: var(--fade-linear-transition);
}
.fade-in-enter, .fade-in-enter,
.fade-in-leave, .fade-in-leave,
.fade-in-linear-enter, .fade-in-linear-enter,

View File

@ -1,20 +1,21 @@
<template> <template>
<div <div
class="el-tooltip" class="el-tooltip"
@mouseenter="visible = true" @mouseenter="showPopper = true"
@mouseleave="visible = false"> @mouseleave="showPopper = false">
<div class="el-tooltip__rel" v-el:reference> <div class="el-tooltip__rel" ref="reference">
<slot></slot> <slot></slot>
</div> </div>
<div <transition :name="transition">
class="el-tooltip__popper" <div
:class="['is-' + effect]" class="el-tooltip__popper"
v-el:popper :class="['is-' + effect]"
v-show="!disabled && visible" ref="popper"
:transition="transition"> v-show="!disabled && showPopper">
<slot name="content"><div v-text="content"></div></slot> <slot name="content"><div v-text="content"></div></slot>
</div> </div>
</transition>
</div> </div>
</template> </template>

View File

@ -34,9 +34,21 @@ export default {
} }
}, },
data() {
return {
showPopper: false
};
},
watch: { watch: {
'visible'(val) { visible: {
if (this.popperDestroying) return; immediate: true,
handler(val) {
this.showPopper = val;
}
},
showPopper(val) {
val ? this.updatePopper() : this.destroyPopper(); val ? this.updatePopper() : this.destroyPopper();
} }
}, },
@ -47,32 +59,32 @@ export default {
return; return;
} }
this.popper = this.popper || this.$refs.popper; const options = this.options;
this.reference = this.reference || this.$refs.reference; const popper = this.popper || this.$refs.popper;
const reference = this.reference || this.$refs.reference;
if (!this.popper || !this.reference) {
return;
}
if (!popper || !reference) return;
if (this.visibleArrow) { if (this.visibleArrow) {
this.appendArrow(this.popper); this.appendArrow(popper);
} }
if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) { if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
this.popperJS.destroy(); this.popperJS.destroy();
} }
this.$set('options.placement', this.placement); options.placement = this.placement;
this.$set('options.offset', this.offset); options.offset = this.offset;
this.popperJS = new PopperJS( this.$nextTick(() => {
this.reference, this.popperJS = new PopperJS(
this.popper, reference,
this.options popper,
); options
this.popperJS.onCreate(popper => { );
this.resetTransformOrigin(popper); this.popperJS.onCreate(popper => {
this.$emit('created', this); this.resetTransformOrigin(popper);
this.$emit('created', this);
});
}); });
}, },
@ -85,7 +97,7 @@ export default {
}, },
doDestroy() { doDestroy() {
if (this.visible) return; if (this.showPopper) return;
this.popperJS._popper.removeEventListener('transitionend', this.doDestroy); this.popperJS._popper.removeEventListener('transitionend', this.doDestroy);
this.popperJS.destroy(); this.popperJS.destroy();