File size: 1,573 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import type { Directive, DirectiveBinding } from 'vue'
import tippy, { type Instance, type Placement } from 'tippy.js'
import './tooltip.scss'
const TOOLTIP_INSTANCE = 'TOOLTIP_INSTANCE'
interface CustomHTMLElement extends HTMLElement {
[TOOLTIP_INSTANCE]?: Instance
}
type Delay = number | [number | null, number | null]
interface BindingValue {
content: string
placement?: Placement
delay?: Delay
}
const TooltipDirective: Directive = {
mounted(el: CustomHTMLElement, binding: DirectiveBinding<BindingValue | string>) {
let content = ''
let placement: Placement = 'top'
let delay: Delay = [300, 0]
if (typeof binding.value === 'string') {
content = binding.value
}
else {
content = binding.value.content
if (binding.value.placement !== undefined) placement = binding.value.placement
if (binding.value.delay !== undefined) delay = binding.value.delay
}
el[TOOLTIP_INSTANCE] = tippy(el, {
content,
theme: 'tooltip',
duration: 100,
animation: 'scale',
allowHTML: true,
placement,
delay,
})
},
updated(el: CustomHTMLElement, binding: DirectiveBinding<BindingValue | string>) {
let content = ''
if (typeof binding.value === 'string') {
content = binding.value
}
else {
content = binding.value.content
}
if (el[TOOLTIP_INSTANCE]) el[TOOLTIP_INSTANCE].setContent(content)
},
unmounted(el: CustomHTMLElement) {
if (el[TOOLTIP_INSTANCE]) el[TOOLTIP_INSTANCE].destroy()
},
}
export default TooltipDirective |