UPDATE
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
<script>
|
||||
const popoverCloseQueue = [];
|
||||
const popoverCloseAll = () => popoverCloseQueue.forEach(callback => callback());
|
||||
const triggerEvents = {
|
||||
hover(el) {},
|
||||
focus(el) {
|
||||
el.addEventListener("focus", e => {
|
||||
this.changeVisible();
|
||||
});
|
||||
el.addEventListener("blur", e => {
|
||||
this.changeVisible();
|
||||
});
|
||||
},
|
||||
click(el) {
|
||||
el.addEventListener("click", e => {
|
||||
e.stopPropagation();
|
||||
this.changeVisible();
|
||||
});
|
||||
},
|
||||
contextmenu(el) {
|
||||
el.addEventListener("contextmenu", e => {
|
||||
e.preventDefault();
|
||||
this.changeVisible();
|
||||
});
|
||||
}
|
||||
};
|
||||
export default {
|
||||
name: "LemonPopover",
|
||||
props: {
|
||||
trigger: {
|
||||
type: String,
|
||||
default: "click",
|
||||
validator(val) {
|
||||
return Object.keys(triggerEvents).includes(val);
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
popoverStyle: {},
|
||||
visible: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
document.addEventListener("click", this._documentClickEvent);
|
||||
popoverCloseQueue.push(this.close);
|
||||
},
|
||||
mounted() {
|
||||
triggerEvents[this.trigger].call(this, this.$slots.default[0].elm);
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<span style="position:relative">
|
||||
<transition name="slide-top">
|
||||
{this.visible && (
|
||||
<div
|
||||
class="lemon-popover"
|
||||
ref="popover"
|
||||
style={this.popoverStyle}
|
||||
on-click={e => e.stopPropagation()}
|
||||
>
|
||||
<div class="lemon-popover__title" />
|
||||
<div class="lemon-popover__content">{this.$slots.content}</div>
|
||||
<div class="lemon-popover__arrow" />
|
||||
</div>
|
||||
)}
|
||||
</transition>
|
||||
{this.$slots.default}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener("click", this._documentClickEvent);
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
async visible(val) {
|
||||
if (val) {
|
||||
await this.$nextTick();
|
||||
const defaultEl = this.$slots.default[0].elm;
|
||||
const contentEl = this.$refs.popover;
|
||||
|
||||
this.popoverStyle = {
|
||||
top: `-${contentEl.offsetHeight + 10}px`,
|
||||
left: `${defaultEl.offsetWidth / 2 - contentEl.offsetWidth / 2}px`
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
_documentClickEvent(e) {
|
||||
e.stopPropagation();
|
||||
if (this.visible) this.close();
|
||||
},
|
||||
changeVisible() {
|
||||
this.visible ? this.close() : this.open();
|
||||
},
|
||||
open() {
|
||||
popoverCloseAll();
|
||||
this.visible = true;
|
||||
},
|
||||
close() {
|
||||
this.visible = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="stylus">
|
||||
@import '~styles/utils/index'
|
||||
+b(lemon-popover)
|
||||
border 1px solid #eee
|
||||
border-radius 4px
|
||||
font-size 14px
|
||||
font-variant tabular-nums
|
||||
line-height 1.5
|
||||
color rgba(0, 0, 0, 0.65)
|
||||
z-index 10
|
||||
background-color #fff
|
||||
border-radius 4px
|
||||
box-shadow 0 2px 8px rgba(0, 0, 0, 0.15)
|
||||
position absolute
|
||||
transform-origin 50% 150%
|
||||
+e(content)
|
||||
padding 15px
|
||||
box-sizing border-box
|
||||
position relative
|
||||
z-index 1
|
||||
+e(arrow)
|
||||
left 50%
|
||||
transform translateX(-50%) rotate(45deg)
|
||||
position absolute
|
||||
z-index 0
|
||||
bottom -4px
|
||||
box-shadow 3px 3px 7px rgba(0, 0, 0, 0.07)
|
||||
width 8px
|
||||
height 8px
|
||||
background #fff
|
||||
.slide-top-leave-active ,.slide-top-enter-active
|
||||
transition all .3s cubic-bezier(0.645, 0.045, 0.355, 1)
|
||||
.slide-top-enter, .slide-top-leave-to
|
||||
transform translateY(-10px) scale(.8)
|
||||
opacity 0
|
||||
</style>
|
||||
Reference in New Issue
Block a user