CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
1.57 kB
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