diff --git a/.gitignore b/.gitignore index 65c33d5..46143e9 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ next-env.d.ts # local notes notes.md +AGENT.md diff --git a/src/app/page.tsx b/src/app/page.tsx index 3ce25ea..cf630d8 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -24,7 +24,7 @@ import { Tooltip, GlobalStyles, LoadingSkeleton } from '@/components/common'; export default function Home() { // All the state we need to make this thing work - const { tooltip, show: showTooltip, hide: hideTooltip, tooltipMouseEnter, tooltipMouseLeave } = useTooltip(); + const { tooltip, show: showTooltip, hide: hideTooltip, tooltipMouseEnter, tooltipMouseLeave, setTooltipRef } = useTooltip(); const { selectedDistro, @@ -203,7 +203,7 @@ export default function Home() { onClick={clearFocus} > - + {/* Header */}
diff --git a/src/components/common/Tooltip.tsx b/src/components/common/Tooltip.tsx index c7b7a59..1398e15 100644 --- a/src/components/common/Tooltip.tsx +++ b/src/components/common/Tooltip.tsx @@ -7,9 +7,10 @@ interface TooltipProps { tooltip: TooltipState | null; onMouseEnter: () => void; onMouseLeave: () => void; + setRef?: (el: HTMLDivElement | null) => void; } -export function Tooltip({ tooltip, onMouseEnter, onMouseLeave }: TooltipProps) { +export function Tooltip({ tooltip, onMouseEnter, onMouseLeave, setRef }: TooltipProps) { const [current, setCurrent] = useState(null); const [visible, setVisible] = useState(false); const timeoutRef = useRef(null); @@ -62,6 +63,7 @@ export function Tooltip({ tooltip, onMouseEnter, onMouseLeave }: TooltipProps) { return (
(null); const isOverTrigger = useRef(false); const isOverTooltip = useRef(false); + const tooltipRef = useRef(null); + + // Allow setting the tooltip element ref from the Tooltip component + const setTooltipRef = useCallback((el: HTMLDivElement | null) => { + tooltipRef.current = el; + }, []); const cancel = useCallback(() => { if (showTimeout.current) { @@ -74,7 +80,18 @@ export function useTooltip() { }, [tryHide]); useEffect(() => { - const dismiss = () => { + const dismiss = (e: MouseEvent) => { + // Don't dismiss if clicking inside the tooltip + if (tooltipRef.current && tooltipRef.current.contains(e.target as Node)) { + return; + } + cancel(); + isOverTrigger.current = false; + isOverTooltip.current = false; + setTooltip(null); + }; + + const dismissOnScroll = () => { cancel(); isOverTrigger.current = false; isOverTooltip.current = false; @@ -82,20 +99,20 @@ export function useTooltip() { }; const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Escape') dismiss(); + if (e.key === 'Escape') dismissOnScroll(); }; window.addEventListener('mousedown', dismiss, true); - window.addEventListener('scroll', dismiss, true); + window.addEventListener('scroll', dismissOnScroll, true); window.addEventListener('keydown', handleKeyDown); return () => { cancel(); window.removeEventListener('mousedown', dismiss, true); - window.removeEventListener('scroll', dismiss, true); + window.removeEventListener('scroll', dismissOnScroll, true); window.removeEventListener('keydown', handleKeyDown); }; }, [cancel]); - return { tooltip, show, hide, tooltipMouseEnter, tooltipMouseLeave }; + return { tooltip, show, hide, tooltipMouseEnter, tooltipMouseLeave, setTooltipRef }; }