/
githubmirror
/
pocketbase
Обзор
Документация
Войти
/
githubmirror
/
pocketbase
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
ui/src/base/tooltip.js
161 строка
5 KB
Gani Georgiev
hide related tooltip on element removal
12 июн 2026, 12:31
12 июн 2026, 12:31
2e9cc27
Код
Авторство
О чём код?
const tolerance = 5; const tooltip = t.div({ ariaHidden: true, popover: "manual", className: "pb-tooltip", }); document.body.appendChild(tooltip); function updateTooltipPosition(node, position, styleClass) { tooltip._relatedNode = node; let nodeRect = node.getBoundingClientRect(); tooltip.setAttribute("data-style", styleClass || ""); tooltip.setAttribute("data-position", position); // reset tooltip position tooltip.style.top = "0px"; tooltip.style.left = "0px"; // note: doesn't use getBoundingClientRect() here because the // tooltip could be animated/scaled/transformed and we need the real size let tooltipHeight = tooltip.offsetHeight; let tooltipWidth = tooltip.offsetWidth; let top = 0; let left = 0; // calculate tooltip position based if (position == "left") { top = nodeRect.top + nodeRect.height / 2 - tooltipHeight / 2; left = nodeRect.left - tooltipWidth - tolerance; } else if (position == "right") { top = nodeRect.top + nodeRect.height / 2 - tooltipHeight / 2; left = nodeRect.right + tolerance; } else if (position == "top") { top = nodeRect.top - tooltipHeight - tolerance; left = nodeRect.left + nodeRect.width / 2 - tooltipWidth / 2; } else if (position == "top-left") { top = nodeRect.top - tooltipHeight - tolerance; left = nodeRect.left; } else if (position == "top-right") { top = nodeRect.top - tooltipHeight - tolerance; left = nodeRect.right - tooltipWidth; } else if (position == "bottom-left") { top = nodeRect.top + nodeRect.height + tolerance; left = nodeRect.left; } else if (position == "bottom-right") { top = nodeRect.top + nodeRect.height + tolerance; left = nodeRect.right - tooltipWidth; } else { // bottom top = nodeRect.top + nodeRect.height + tolerance; left = nodeRect.left + nodeRect.width / 2 - tooltipWidth / 2; } // right edge boundary if (left + tooltipWidth > document.documentElement.clientWidth) { left = document.documentElement.clientWidth - tooltipWidth; } // left edge boundary left = left >= 0 ? left : 0; // bottom edge boundary if (top + tooltipHeight > document.documentElement.clientHeight) { top = document.documentElement.clientHeight - tooltipHeight; } // top edge boundary top = top >= 0 ? top : 0; tooltip.style.top = top + "px"; tooltip.style.left = left + "px"; } function hideTooltip() { tooltip._relatedNode = null; tooltip.hidePopover(); } function showTooltip(node, text, position, styleClass) { if (!node || !text) { hideTooltip(); return; } tooltip.showPopover(); tooltip.textContent = text; updateTooltipPosition(node, position, styleClass); } document.body.addEventListener("mouseleave", () => { hideTooltip(); }); function tooltipAction(textOrFunc, position = "top", styleClass = "") { return (el) => { if (!el._tooltipText) { el._tooltipText = store({ value: "", }); let tooltipTextWatcher; function showEventHandler() { tooltipTextWatcher?.unwatch(); tooltipTextWatcher = watch( () => el._tooltipText.value, async (result) => { showTooltip(el, result, position, styleClass); }, ); } async function hideEventHandler() { tooltipTextWatcher?.unwatch(); tooltipTextWatcher = null; hideTooltip(); } el.addEventListener("mouseenter", showEventHandler); el.addEventListener("focusin", showEventHandler); el.addEventListener("mouseleave", hideEventHandler); el.addEventListener("focusout", hideEventHandler); el.addEventListener("blur", hideEventHandler); const originalOnunmount = el.onunmount; el.onunmount = (el) => { if (tooltip._relatedNode == el) { hideTooltip(); } tooltipTextWatcher?.unwatch(); el._tooltipText = null; el?.removeEventListener("mouseenter", showEventHandler); el?.removeEventListener("focusin", showEventHandler); el?.removeEventListener("mouseleave", hideEventHandler); el?.removeEventListener("focusout", hideEventHandler); el?.removeEventListener("blur", hideEventHandler); originalOnunmount(el); }; } if (typeof textOrFunc == "function") { el._tooltipText.value = textOrFunc(); } else { el._tooltipText.value = textOrFunc; } return el._tooltipText.value; }; } window.app = window.app || {}; window.app.attrs = window.app.attrs || {}; window.app.attrs.tooltip = tooltipAction;