import getFloatedTargetPos from '../utils/getFloatedTargetPos' import supportDom from '../decorators/supportDom' import { toPixel } from '../utils'
const TOOLTIP_PLACEMENTS = ['top', 'bottom', 'left', 'right']
@supportDom export default class Tooltip {
constructor(dom) { this.dom = dom this.tooltip = document.querySelector('[data-global-tooltip]') this.init() } init() { this.appendTooltip() this.addEvents() } appendTooltip() { if (this.tooltip) { return } const tooltip = document.createElement('div') tooltip.setAttribute('data-global-tooltip', '') tooltip.classList.add('tooltip') document.body.appendChild(tooltip) this.tooltip = tooltip } static remove() { const div = document.querySelector('[data-global-tooltip]') if (div) { div.remove() } } getPlace() { const str = this.dom.dataset.place return TOOLTIP_PLACEMENTS.includes(str) ? str : 'bottom' } getOffset() { const num = parseInt(this.dom.dataset.offset, 10) return Number.isInteger(num) ? num : 10 } setTooltipMsg() { const { msg } = this.dom.dataset if (this.tooltip.innerHTML !== msg) { this.tooltip.innerHTML = msg } } hide() { const { tooltip } = this if (tooltip) { tooltip.style.opacity = 0 tooltip.style.display = 'none' } } addEvents() { const { dom, tooltip } = this if ('onmouseover' in dom) { this.addEvent(dom, 'mouseover', () => { const msg = this.dom.dataset.msg || '' if (msg.length === 0) { return } this.setTooltipMsg() tooltip.style.opacity = 0 tooltip.style.display = 'block' const { pos, place } = getFloatedTargetPos({ src: dom, target: tooltip, place: this.getPlace(), offset: this.getOffset() }) tooltip.className = `tooltip ${place}` tooltip.style.left = toPixel(pos.left) tooltip.style.top = toPixel(pos.top) tooltip.style.opacity = 1 }) } if ('onmouseleave' in dom) { const handleMouseLeave = () => this.hide() this.addEvent(dom, 'click', handleMouseLeave) this.addEvent(dom, 'mouseleave', handleMouseLeave) } } destroy() { this.hide() }
}