mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
108 lines
2.7 KiB
Vue
108 lines
2.7 KiB
Vue
<template>
|
|
<div>
|
|
<!-- trigger -->
|
|
<div
|
|
ref="trigger"
|
|
@mouseenter="showTooltip"
|
|
@mousemove="mousemove"
|
|
@mouseleave="hideTooltip"
|
|
:aria-expanded="isOpen"
|
|
aria-haspopup="true"
|
|
>
|
|
<slot name="trigger"></slot>
|
|
</div>
|
|
|
|
<!-- tooltip content -->
|
|
<portal v-if="isOpen" to="tooltip-destination">
|
|
<div
|
|
v-show="isOpen"
|
|
ref="content"
|
|
class="bg-blue-1000 fixed z-50 py-2 rounded-md shadow"
|
|
:style="{ ...position }"
|
|
>
|
|
<slot></slot>
|
|
</div>
|
|
</portal>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
isOpen: false,
|
|
left: 0,
|
|
offset: 12,
|
|
top: 0,
|
|
directionBottom: true,
|
|
directionRight: true,
|
|
directionChecked: false,
|
|
width: 0,
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
position() {
|
|
const valuetoRemove = this.directionBottom ? 0 : this.height()
|
|
const leftValue = this.directionRight
|
|
? this.left + this.offset
|
|
: this.left - this.width - this.offset / 2
|
|
return {
|
|
left: `${leftValue}px`,
|
|
top: `${this.top + this.offset - valuetoRemove}px`,
|
|
}
|
|
},
|
|
},
|
|
|
|
created() {
|
|
window.addEventListener('scroll', this.handleScroll)
|
|
},
|
|
destroyed() {
|
|
window.removeEventListener('scroll', this.handleScroll)
|
|
},
|
|
|
|
methods: {
|
|
checkTooltipVisibility() {
|
|
this.directionChecked = true
|
|
const contentRect = this.$refs.content.getBoundingClientRect()
|
|
const triggerRect = this.$refs.trigger.getBoundingClientRect()
|
|
this.width = contentRect.width
|
|
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight)
|
|
const viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth)
|
|
this.directionBottom = contentRect.bottom + this.offset < viewHeight
|
|
this.directionRight = this.left + this.width + triggerRect.width + this.offset < viewWidth
|
|
},
|
|
handleScroll() {
|
|
this.isOpen = false
|
|
},
|
|
height() {
|
|
return this.$refs.content ? this.$refs.content.clientHeight : 0
|
|
},
|
|
hideTooltip() {
|
|
this.isOpen = false
|
|
this.directionBottom = true
|
|
this.directionRight = true
|
|
this.directionChecked = false
|
|
},
|
|
async mousemove(event) {
|
|
this.left = event.clientX
|
|
this.top = event.clientY
|
|
|
|
if (!this.directionChecked) {
|
|
// Component has been destroyed
|
|
if (!this.$refs.content || !this.$refs.trigger) {
|
|
return
|
|
}
|
|
|
|
await this.$nextTick()
|
|
this.checkTooltipVisibility()
|
|
}
|
|
},
|
|
showTooltip(event) {
|
|
this.left = event.clientX
|
|
this.top = event.clientY
|
|
this.isOpen = true
|
|
},
|
|
},
|
|
}
|
|
</script>
|