From b8f326ae1a65e1bb6232af07c7a3ac359e3e71ba Mon Sep 17 00:00:00 2001 From: Ayush8923 <80516839+Ayush8923@users.noreply.github.com> Date: Fri, 17 Apr 2026 23:43:42 +0530 Subject: [PATCH 1/2] fix(*): tooltip updates --- app/components/InfoTooltip.tsx | 68 +++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/app/components/InfoTooltip.tsx b/app/components/InfoTooltip.tsx index 902841d..95a6f04 100644 --- a/app/components/InfoTooltip.tsx +++ b/app/components/InfoTooltip.tsx @@ -1,27 +1,77 @@ "use client"; -import type { ReactNode } from "react"; +import { + type ReactNode, + useState, + useRef, + useEffect, + useCallback, +} from "react"; +import { createPortal } from "react-dom"; interface InfoTooltipProps { text: ReactNode; } export default function InfoTooltip({ text }: InfoTooltipProps) { + const [visible, setVisible] = useState(false); + const [position, setPosition] = useState({ top: 0, left: 0 }); + const triggerRef = useRef(null); + const tooltipRef = useRef(null); + + const updatePosition = useCallback(() => { + if (!triggerRef.current || !tooltipRef.current) return; + + const triggerRect = triggerRef.current.getBoundingClientRect(); + const tooltipRect = tooltipRef.current.getBoundingClientRect(); + + let top = triggerRect.top - tooltipRect.height - 8; + let left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2; + + // Keep tooltip within viewport horizontally + if (left < 8) left = 8; + if (left + tooltipRect.width > window.innerWidth - 8) { + left = window.innerWidth - tooltipRect.width - 8; + } + + // If no room above, show below + if (top < 8) { + top = triggerRect.bottom + 8; + } + + setPosition({ top, left }); + }, []); + + useEffect(() => { + if (!visible) return; + updatePosition(); + }, [visible, updatePosition]); + return ( - + -
- {text} - -
+ {visible && + createPortal( +
+ {text} +
, + document.body, + )}
); } From 8d5abd609e5d090e2cd4a5c018d4b7a53363494b Mon Sep 17 00:00:00 2001 From: Ayush8923 <80516839+Ayush8923@users.noreply.github.com> Date: Fri, 17 Apr 2026 23:49:23 +0530 Subject: [PATCH 2/2] fix(*): added positioned paramter --- app/components/InfoTooltip.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/components/InfoTooltip.tsx b/app/components/InfoTooltip.tsx index 95a6f04..eda02b7 100644 --- a/app/components/InfoTooltip.tsx +++ b/app/components/InfoTooltip.tsx @@ -4,7 +4,7 @@ import { type ReactNode, useState, useRef, - useEffect, + useLayoutEffect, useCallback, } from "react"; import { createPortal } from "react-dom"; @@ -15,6 +15,7 @@ interface InfoTooltipProps { export default function InfoTooltip({ text }: InfoTooltipProps) { const [visible, setVisible] = useState(false); + const [positioned, setPositioned] = useState(false); const [position, setPosition] = useState({ top: 0, left: 0 }); const triggerRef = useRef(null); const tooltipRef = useRef(null); @@ -40,10 +41,15 @@ export default function InfoTooltip({ text }: InfoTooltipProps) { } setPosition({ top, left }); + setPositioned(true); }, []); - useEffect(() => { - if (!visible) return; + // useLayoutEffect to position before paint — prevents flash at (0,0) + useLayoutEffect(() => { + if (!visible) { + setPositioned(false); + return; + } updatePosition(); }, [visible, updatePosition]); @@ -65,7 +71,11 @@ export default function InfoTooltip({ text }: InfoTooltipProps) {
{text}