fix: coordinate tooltip pointer and touch state

This commit is contained in:
gitea_admin committed 2026-09-21 16:24:20 +02:00
1 parent 060eb86e85
commit 3e9ba6c017
1 file changed
+30 -9
+30 -9
View File
@@ -1,6 +1,7 @@
(function initTooltipOverlayModule() { (function initTooltipOverlayModule() {
let tooltipId = 0; let tooltipId = 0;
const states = new WeakMap(); const states = new WeakMap();
const tooltipStates = new Set();
const getViewport = () => ({ const getViewport = () => ({
width: window.visualViewport?.width || window.innerWidth, width: window.visualViewport?.width || window.innerWidth,
@@ -156,6 +157,11 @@
}; };
const openTooltip = (state) => { const openTooltip = (state) => {
tooltipStates.forEach((otherState) => {
if (otherState !== state) {
closeTooltip(otherState);
}
});
movePanelToPortal(state); movePanelToPortal(state);
setOpenState(state, true); setOpenState(state, true);
positionTooltip(state); positionTooltip(state);
@@ -219,10 +225,14 @@
wrap.dataset.tooltipInit = 'true'; wrap.dataset.tooltipInit = 'true';
wrap.dataset.tooltipPlacement = 'bottom'; wrap.dataset.tooltipPlacement = 'bottom';
states.set(wrap, state); states.set(wrap, state);
tooltipStates.add(state);
ensureAccessibility(state); ensureAccessibility(state);
setOpenState(state, false); setOpenState(state, false);
wrap.addEventListener('pointerenter', () => { wrap.addEventListener('pointerenter', (event) => {
if (event.pointerType !== 'mouse') {
return;
}
if (state.dismissed) { if (state.dismissed) {
return; return;
} }
@@ -231,6 +241,9 @@
}); });
wrap.addEventListener('pointerleave', (event) => { wrap.addEventListener('pointerleave', (event) => {
if (event.pointerType !== 'mouse') {
return;
}
state.hoverTrigger = false; state.hoverTrigger = false;
state.dismissed = false; state.dismissed = false;
if (!state.panel.contains(event.relatedTarget)) { if (!state.panel.contains(event.relatedTarget)) {
@@ -238,14 +251,20 @@
} }
}); });
state.panel.addEventListener('pointerenter', () => { state.panel.addEventListener('pointerenter', (event) => {
if (event.pointerType !== 'mouse') {
return;
}
if (!state.dismissed) { if (!state.dismissed) {
state.hoverPanel = true; state.hoverPanel = true;
openTooltip(state); openTooltip(state);
} }
}); });
state.panel.addEventListener('pointerleave', () => { state.panel.addEventListener('pointerleave', (event) => {
if (event.pointerType !== 'mouse') {
return;
}
state.hoverPanel = false; state.hoverPanel = false;
state.dismissed = false; state.dismissed = false;
closeIfInactive(state); closeIfInactive(state);
@@ -268,7 +287,6 @@
}); });
state.trigger.addEventListener('click', (event) => { state.trigger.addEventListener('click', (event) => {
event.stopPropagation();
togglePinned(state); togglePinned(state);
}); });
@@ -314,14 +332,17 @@
}); });
observer.observe(document.body, { childList: true, subtree: true }); observer.observe(document.body, { childList: true, subtree: true });
document.addEventListener('click', (event) => { const closeFromOutside = (event) => {
document.querySelectorAll('.sg-tooltip-wrap').forEach((wrap) => { tooltipStates.forEach((state) => {
const state = states.get(wrap); if (!state.wrap.contains(event.target) && !state.panel.contains(event.target)) {
if (state && !wrap.contains(event.target) && !state.panel.contains(event.target)) {
closeTooltip(state); closeTooltip(state);
} }
}); });
}); };
document.addEventListener('pointerdown', closeFromOutside, true);
document.addEventListener('touchstart', closeFromOutside, true);
document.addEventListener('click', closeFromOutside, true);
const repositionOpenTooltips = () => { const repositionOpenTooltips = () => {
document.querySelectorAll('.sg-tooltip-wrap[data-tooltip-open="true"]').forEach((wrap) => { document.querySelectorAll('.sg-tooltip-wrap[data-tooltip-open="true"]').forEach((wrap) => {