interface Bounds { top: number; left: number; width: number; height: number; } export function getOffsetRect(el: HTMLElement | SVGElement | Text | null): Bounds { const isElement = el instanceof HTMLElement || el instanceof SVGElement; if (typeof window === 'undefined' || !isElement) { return { top: 0, left: 0, width: 0, height: 0, }; } const box = el.getBoundingClientRect(); const body = document.body; const doc = document.documentElement; const scrollTop = window.pageYOffset || doc.scrollTop || body.scrollTop; const scrollLeft = window.pageXOffset || doc.scrollLeft || body.scrollLeft; const clientTop = doc.clientTop || body.clientTop || 0; const clientLeft = doc.clientLeft || body.clientLeft || 0; return { top: Math.round(box.top + scrollTop - clientTop), left: Math.round(box.left + scrollLeft - clientLeft), width: Math.round(box.width), height: Math.round(box.height), }; }