A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 97 lines 4.2 kB view raw
1import {isMobile} from "../util/functions"; 2 3export const showTooltip = (message: string, target: Element, tooltipClass?: string) => { 4 if (isMobile()) { 5 return; 6 } 7 const targetRect = target.getBoundingClientRect(); 8 if (targetRect.height === 0 || !message) { 9 hideTooltip(); 10 return; 11 } 12 13 const messageElement = document.getElementById("tooltip"); 14 messageElement.className = tooltipClass ? `tooltip tooltip--${tooltipClass}` : "tooltip"; 15 messageElement.innerHTML = message; 16 // 避免原本的 top 和 left 影响计算 17 messageElement.removeAttribute("style"); 18 19 20 const position = target.getAttribute("data-position"); 21 const parentRect = target.parentElement.getBoundingClientRect(); 22 23 let left; 24 let top; 25 if (position === "parentE") { 26 // parentE: file tree and outline、backlink & viewcard 27 top = Math.max(0, parentRect.top - (messageElement.clientHeight - parentRect.height) / 2); 28 if (top > window.innerHeight - messageElement.clientHeight) { 29 top = window.innerHeight - messageElement.clientHeight; 30 } 31 left = parentRect.right + 8; 32 if (left + messageElement.clientWidth > window.innerWidth) { 33 left = parentRect.left - messageElement.clientWidth - 8; 34 } 35 } else if (position === "parentW") { 36 // ${number}parentW: av 属性视图 & col & select 37 top = Math.max(0, parentRect.top - (messageElement.clientHeight - parentRect.height) / 2); 38 if (top > window.innerHeight - messageElement.clientHeight) { 39 top = window.innerHeight - messageElement.clientHeight; 40 } 41 left = parentRect.left - messageElement.clientWidth; 42 if (left < 0) { 43 left = parentRect.right; 44 } 45 } else if (position?.endsWith("west")) { 46 // west: gutter & 标题图标 & av relation 47 const positionDiff = parseInt(position) || 0.5; 48 top = Math.max(0, targetRect.top - (messageElement.clientHeight - targetRect.height) / 2); 49 if (top > window.innerHeight - messageElement.clientHeight) { 50 top = window.innerHeight - messageElement.clientHeight; 51 } 52 left = targetRect.left - messageElement.clientWidth - positionDiff; 53 if (left < 0) { 54 left = targetRect.right; 55 } 56 } else if (position === "north") { 57 // north: av 视图,列,多选描述 58 const positionDiff = 0.5; 59 left = Math.max(0, targetRect.left - (messageElement.clientWidth - targetRect.width) / 2); 60 top = targetRect.top - messageElement.clientHeight - positionDiff; 61 if (top < 0) { 62 if (targetRect.top < window.innerHeight - targetRect.bottom) { 63 top = targetRect.bottom + positionDiff; 64 messageElement.style.maxHeight = (window.innerHeight - top) + "px"; 65 } else { 66 top = 0; 67 messageElement.style.maxHeight = (targetRect.top - positionDiff) + "px"; 68 } 69 } 70 if (left + messageElement.clientWidth > window.innerWidth) { 71 left = window.innerWidth - messageElement.clientWidth; 72 } 73 } else { 74 // ${number}south & 默认值 75 const positionDiff = parseInt(position) || 0.5; 76 left = Math.max(0, targetRect.left - (messageElement.clientWidth - targetRect.width) / 2); 77 top = targetRect.bottom + positionDiff; 78 79 if (top + messageElement.clientHeight > window.innerHeight) { 80 if (targetRect.top - positionDiff > window.innerHeight - top) { 81 top = targetRect.top - positionDiff - messageElement.clientHeight; 82 messageElement.style.maxHeight = (targetRect.top - positionDiff) + "px"; 83 } else { 84 messageElement.style.maxHeight = (window.innerHeight - top) + "px"; 85 } 86 } 87 if (left + messageElement.clientWidth > window.innerWidth) { 88 left = window.innerWidth - messageElement.clientWidth; 89 } 90 } 91 messageElement.style.top = top + "px"; 92 messageElement.style.left = left + "px"; 93}; 94 95export const hideTooltip = () => { 96 document.getElementById("tooltip").classList.add("fn__none"); 97};