mirror of
https://github.com/duhanbalci/dreport.git
synced 2026-07-02 02:49:16 +00:00
fixes
This commit is contained in:
80
frontend/src/directives/tip.ts
Normal file
80
frontend/src/directives/tip.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
let tooltipEl: HTMLDivElement | null = null
|
||||
let currentTarget: HTMLElement | null = null
|
||||
|
||||
function getTooltip(): HTMLDivElement {
|
||||
if (!tooltipEl) {
|
||||
tooltipEl = document.createElement('div')
|
||||
tooltipEl.className = 'prop-tooltip'
|
||||
document.body.appendChild(tooltipEl)
|
||||
}
|
||||
return tooltipEl
|
||||
}
|
||||
|
||||
function show(el: HTMLElement) {
|
||||
const text = el.getAttribute('data-tip')
|
||||
if (!text) return
|
||||
|
||||
currentTarget = el
|
||||
const tip = getTooltip()
|
||||
tip.textContent = text
|
||||
|
||||
// Position before showing so we can measure
|
||||
tip.style.top = '0px'
|
||||
tip.style.left = '0px'
|
||||
tip.classList.add('prop-tooltip--visible')
|
||||
|
||||
const rect = el.getBoundingClientRect()
|
||||
const tipRect = tip.getBoundingClientRect()
|
||||
|
||||
let top = rect.top - tipRect.height - 6
|
||||
let left = rect.left + rect.width / 2 - tipRect.width / 2
|
||||
|
||||
// Clamp to viewport
|
||||
if (top < 4) top = rect.bottom + 6
|
||||
if (left < 4) left = 4
|
||||
if (left + tipRect.width > window.innerWidth - 4) {
|
||||
left = window.innerWidth - tipRect.width - 4
|
||||
}
|
||||
|
||||
tip.style.top = `${top}px`
|
||||
tip.style.left = `${left}px`
|
||||
}
|
||||
|
||||
function hide() {
|
||||
currentTarget = null
|
||||
if (tooltipEl) {
|
||||
tooltipEl.classList.remove('prop-tooltip--visible')
|
||||
}
|
||||
}
|
||||
|
||||
function closest(el: EventTarget | null): HTMLElement | null {
|
||||
if (!(el instanceof HTMLElement)) return null
|
||||
return el.closest('[data-tip]')
|
||||
}
|
||||
|
||||
let installed = false
|
||||
|
||||
/** Call once to enable data-tip tooltips globally via event delegation. */
|
||||
export function setupTooltips() {
|
||||
if (installed) return
|
||||
installed = true
|
||||
document.addEventListener('pointerenter', (e) => {
|
||||
const target = closest(e.target)
|
||||
if (target) show(target)
|
||||
}, true)
|
||||
|
||||
document.addEventListener('pointerleave', (e) => {
|
||||
const target = closest(e.target)
|
||||
if (target && target === currentTarget) hide()
|
||||
}, true)
|
||||
|
||||
document.addEventListener('focusin', (e) => {
|
||||
const target = closest(e.target)
|
||||
if (target) show(target)
|
||||
}, true)
|
||||
|
||||
document.addEventListener('focusout', (e) => {
|
||||
const target = closest(e.target)
|
||||
if (target && target === currentTarget) hide()
|
||||
}, true)
|
||||
}
|
||||
Reference in New Issue
Block a user