89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import Vue from 'vue';
|
|
import Component from "vue-class-component";
|
|
import { Prop, Watch } from "vue-property-decorator";
|
|
|
|
type Events = {
|
|
[evnet: string]: (...any) => void,
|
|
}
|
|
|
|
type Trigger = "hover" | "focus";
|
|
|
|
const longPressTimeout = 1000;
|
|
|
|
@Component({ template: require('../../components/tooltip.html') })
|
|
export class TooltipComponent extends Vue {
|
|
@Prop({ type: String, default: "auto" }) public placement: string;
|
|
@Prop({ type: Number, default: 200 }) public delay: number;
|
|
@Prop({ type: Array, default: () => ["hover", "focus"]}) public triggers: Trigger[];
|
|
|
|
public show: boolean = false;
|
|
public root: Element = null;
|
|
|
|
private _events: Events = {};
|
|
|
|
mounted() {
|
|
this.root = (this.$refs['root'] as HTMLSpanElement).parentElement;
|
|
this.updateTriggers();
|
|
}
|
|
|
|
beforeDestroy() {
|
|
this._removeEventListeners();
|
|
}
|
|
|
|
@Watch('triggers')
|
|
updateTriggers() {
|
|
this._removeEventListeners();
|
|
|
|
this._events = {};
|
|
|
|
let blocked: boolean = false;
|
|
|
|
if (this.triggers.includes("hover")) {
|
|
let timeout;
|
|
|
|
this._events['mouseenter'] = () => {
|
|
timeout = window.setTimeout(() => { this.show = !blocked }, this.delay);
|
|
};
|
|
|
|
this._events['mouseleave'] = () => {
|
|
window.clearTimeout(timeout);
|
|
this.show = false
|
|
};
|
|
}
|
|
|
|
if (this.triggers.includes("focus") || (this.triggers.includes("hover") && this.$isTouch)) {
|
|
if (this.$isTouch) {
|
|
this._events['touchstart'] = () => {
|
|
// this is to prevent showing tooltips after tap
|
|
blocked = true;
|
|
setTimeout(() => blocked = false, longPressTimeout);
|
|
}
|
|
}
|
|
|
|
this._events['focus'] = () => {
|
|
this.show = !blocked;
|
|
};
|
|
|
|
this._events['blur'] = () => {
|
|
this.show = false
|
|
};
|
|
}
|
|
|
|
this._registerEventListeners();
|
|
}
|
|
|
|
private _registerEventListeners() {
|
|
for (const [event, handler] of Object.entries(this._events)) {
|
|
this.root.addEventListener(event, handler);
|
|
}
|
|
}
|
|
|
|
private _removeEventListeners() {
|
|
for (const [event, handler] of Object.entries(this._events)) {
|
|
this.root.removeEventListener(event, handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
Vue.component('Tooltip', TooltipComponent);
|