Skip to content

Instantly share code, notes, and snippets.

@Christilut
Last active January 8, 2019 09:29
Show Gist options
  • Save Christilut/17f04f470d6316aa970733d8883c8b39 to your computer and use it in GitHub Desktop.
Save Christilut/17f04f470d6316aa970733d8883c8b39 to your computer and use it in GitHub Desktop.
Vue component for showing a simple tooltip
Vue.component('tooltip', {
name: 'tooltip',
props: {
disabled: Boolean,
x: {
type: Number,
default: 0
},
y: {
type: Number,
default: 0
}
},
data () {
return {
visible: false,
top: 0,
left: 0
}
},
template: `
<div class='tooltip-trigger' v-on:mouseover='mouseover' v-on:mouseleave='mouseleave' ref='trigger'>
<slot></slot>
<div class='tooltip' :style='{ top: top + "px", left: left + "px", visibility: visible ? "visible" : "hidden", opacity: visible ? 1 : 0 }' ref='tooltip'>
<slot name='tooltip'></slot>
</div>
</div>`,
methods: {
mouseover (e) {
if (this.disabled || e.target.classList.contains('tooltip')) return
this.show()
},
mouseleave (e) {
if (this.disabled) return
this.hide()
},
show () {
if (this.visible) return
this.visible = true
const triggerRect = this.$refs.trigger.getBoundingClientRect()
const tooltipRect = this.$refs.tooltip.getBoundingClientRect()
const TOOLTIP_OFFSET_Y = -7
this.left = Math.max(triggerRect.x - tooltipRect.width / 2 + triggerRect.width / 2 + this.x, 0)
this.top = Math.max(triggerRect.y + window.scrollY - tooltipRect.height + TOOLTIP_OFFSET_Y + this.y, 0)
document.body.append(this.$refs.tooltip)
},
hide () {
if (!this.visible) return
this.visible = false
setTimeout(() => {
this.$refs.trigger.append(this.$refs.tooltip)
this.top = 0
this.left = 0
}, 100)
}
},
watch: {
disabled (v) {
if (v) this.hide()
}
}
})
@import '../variables.scss';
@import '../base/mixins.scss';
@import '../base/responsive.scss';
.tooltip {
visibility: hidden;
opacity: 0;
color: white;
position: absolute;
transition: opacity $transition;
z-index: 1;
padding: $g;
background-color: $primary;
font-size: 12px;
font-style: normal;
line-height: 18px;
box-shadow: 0 0 20px 0 $accent-light;
b {
color: white;
}
&:after {
content: "";
position: absolute;
top: calc(100% - 3px);
left: calc(50% - 6px);
border-style: solid;
border-width: 8px;
border-color: $primary transparent transparent transparent;
transform: scaleY(0.7);
pointer-events: none;
@include phablet {
content: none;
}
}
}
<tooltip class="flex" :x='33' :y='-4'>
<button class="button">
<i class="icons8-truck"></i>
</button>
<template slot="tooltip">Tooltip message</template>
</tooltip>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment