85 lines
2.9 KiB
JavaScript
85 lines
2.9 KiB
JavaScript
import { showTooltip, hideTooltip, tooltipState } from '../composables/useTooltip'
|
|
|
|
export const tooltipDirective = {
|
|
mounted(el, binding) {
|
|
el._tooltipText = binding.value;
|
|
let touchTimeout = null;
|
|
let isTouch = false;
|
|
|
|
el._handleMouseEnter = () => {
|
|
if (!isTouch) showTooltip(el, el._tooltipText);
|
|
};
|
|
el._handleMouseLeave = () => {
|
|
if (!isTouch) hideTooltip();
|
|
};
|
|
el._handleFocus = () => {
|
|
if (!isTouch) showTooltip(el, el._tooltipText);
|
|
};
|
|
el._handleBlur = () => {
|
|
if (!isTouch) hideTooltip();
|
|
};
|
|
|
|
el._handleTouchStart = () => {
|
|
isTouch = true;
|
|
if (touchTimeout) clearTimeout(touchTimeout);
|
|
touchTimeout = setTimeout(() => {
|
|
showTooltip(el, el._tooltipText);
|
|
}, 400); // 400ms long press threshold
|
|
};
|
|
|
|
el._handleTouchEnd = () => {
|
|
if (touchTimeout) clearTimeout(touchTimeout);
|
|
hideTooltip();
|
|
// Block ensuing simulated mouseenter events
|
|
setTimeout(() => { isTouch = false; }, 500);
|
|
};
|
|
|
|
el._handleTouchCancel = () => {
|
|
if (touchTimeout) clearTimeout(touchTimeout);
|
|
hideTooltip();
|
|
setTimeout(() => { isTouch = false; }, 500);
|
|
};
|
|
|
|
el._handleContextMenu = (e) => {
|
|
// Prevent the OS context menu if we're showing a tooltip via long press
|
|
if (isTouch && tooltipState.isVisible && tooltipState.text === el._tooltipText) {
|
|
e.preventDefault();
|
|
}
|
|
};
|
|
|
|
el.addEventListener('mouseenter', el._handleMouseEnter);
|
|
el.addEventListener('mouseleave', el._handleMouseLeave);
|
|
el.addEventListener('focus', el._handleFocus);
|
|
el.addEventListener('blur', el._handleBlur);
|
|
|
|
el.addEventListener('touchstart', el._handleTouchStart, { passive: true });
|
|
el.addEventListener('touchend', el._handleTouchEnd);
|
|
el.addEventListener('touchmove', el._handleTouchCancel, { passive: true });
|
|
el.addEventListener('touchcancel', el._handleTouchCancel);
|
|
el.addEventListener('contextmenu', el._handleContextMenu);
|
|
},
|
|
updated(el, binding) {
|
|
el._tooltipText = binding.value;
|
|
|
|
if (tooltipState.isVisible && tooltipState.text !== binding.value) {
|
|
if (el.matches(':hover') || document.activeElement === el) {
|
|
showTooltip(el, binding.value);
|
|
}
|
|
}
|
|
},
|
|
unmounted(el) {
|
|
if (el._handleMouseEnter) {
|
|
el.removeEventListener('mouseenter', el._handleMouseEnter);
|
|
el.removeEventListener('mouseleave', el._handleMouseLeave);
|
|
el.removeEventListener('focus', el._handleFocus);
|
|
el.removeEventListener('blur', el._handleBlur);
|
|
el.removeEventListener('touchstart', el._handleTouchStart);
|
|
el.removeEventListener('touchend', el._handleTouchEnd);
|
|
el.removeEventListener('touchmove', el._handleTouchCancel);
|
|
el.removeEventListener('touchcancel', el._handleTouchCancel);
|
|
el.removeEventListener('contextmenu', el._handleContextMenu);
|
|
}
|
|
hideTooltip();
|
|
}
|
|
};
|