import {controllerFactory} from '@utils/createController' import {computePosition, arrow, offset, flip, shift} from '@floating-ui/dom' import '~/stylesheets/tippy.js/themes/tomato.css' export default class TooltipController extends controllerFactory()({ targets: { activator: HTMLElement, wrapper: HTMLDivElement, tooltip: HTMLDivElement, arrow: HTMLDivElement, }, }) { async update() { computePosition(this.activatorTarget, this.tooltipTarget, { placement: 'top', middleware: [offset(10), flip(), shift({padding: 5}), arrow({element: this.arrowTarget})], // eslint-disable-next-line github/no-then }).then(({x, y, placement, middlewareData}) => { Object.assign(this.tooltipTarget.style, { left: `${x}px`, top: `${y}px`, }) // Reset any previously set styles on the arrow Object.assign(this.arrowTarget.style, { left: '', top: '', right: '', bottom: '', }) const {x: arrowX, y: arrowY} = middlewareData.arrow || {} const primaryPlacement = placement.split('-')[0] switch (primaryPlacement) { case 'top': Object.assign(this.arrowTarget.style, { left: arrowX ? `${arrowX}px` : '', bottom: '-4px', // Aligns arrow to the bottom edge of the tooltip }) break case 'bottom': Object.assign(this.arrowTarget.style, { left: arrowX ? `${arrowX}px` : '', top: '-4px', // Aligns arrow to the top edge of the tooltip }) break case 'left': Object.assign(this.arrowTarget.style, { top: arrowY ? `${arrowY}px` : '', right: '-4px', // Aligns arrow to the right edge of the tooltip }) break case 'right': Object.assign(this.arrowTarget.style, { top: arrowY ? `${arrowY}px` : '', left: '-4px', // Aligns arrow to the left edge of the tooltip }) break } }) } showTooltip(_event: Event) { this.wrapperTarget.classList.add('block') this.wrapperTarget.classList.remove('hidden') this.update() } hideTooltip(_event: Event) { this.wrapperTarget.classList.add('hidden') this.wrapperTarget.classList.remove('block') } }