Skip to content

Commit 892027d

Browse files
authored
fix(tooltip): improve SSR compatibility for FloatingPortal
1 parent 01f9d70 commit 892027d

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

src/components/Tooltip.tsx

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export function Tooltip({
2424
className = '',
2525
}: TooltipProps) {
2626
const [isOpen, setIsOpen] = React.useState(false)
27+
const [isMounted, setIsMounted] = React.useState(false)
28+
const portalRoot = React.useRef<HTMLElement | null>(null)
2729

2830
const { refs, floatingStyles, context } = useFloating({
2931
open: isOpen,
@@ -37,6 +39,21 @@ export function Tooltip({
3739

3840
const { getReferenceProps, getFloatingProps } = useInteractions([hover])
3941

42+
// Ensure DOM is ready before rendering the portal
43+
React.useEffect(() => {
44+
// Only set portalRoot if we're in a browser environment
45+
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
46+
portalRoot.current = document.body
47+
setIsMounted(true)
48+
}
49+
50+
return () => {
51+
// Clean up on unmount to prevent memory leaks
52+
setIsMounted(false)
53+
portalRoot.current = null
54+
}
55+
}, [])
56+
4057
return (
4158
<>
4259
{/* eslint-disable-next-line react-hooks/refs */}
@@ -45,18 +62,20 @@ export function Tooltip({
4562
ref: refs.setReference,
4663
...getReferenceProps(),
4764
} as any)}
48-
<FloatingPortal>
49-
{isOpen && (
50-
<div
51-
ref={refs.setFloating /* eslint-disable-line react-hooks/refs */}
52-
style={floatingStyles}
53-
{...getFloatingProps()}
54-
className={`z-50 rounded-md bg-gray-900 px-3 py-1.5 text-sm text-white shadow-lg dark:bg-gray-800 ${className}`}
55-
>
56-
{content}
57-
</div>
58-
)}
59-
</FloatingPortal>
65+
{isMounted && portalRoot.current && (
66+
<FloatingPortal root={portalRoot.current}>
67+
{isOpen && (
68+
<div
69+
ref={refs.setFloating /* eslint-disable-line react-hooks/refs */}
70+
style={floatingStyles}
71+
{...getFloatingProps()}
72+
className={`z-50 rounded-md bg-gray-900 px-3 py-1.5 text-sm text-white shadow-lg dark:bg-gray-800 ${className}`}
73+
>
74+
{content}
75+
</div>
76+
)}
77+
</FloatingPortal>
78+
)}
6079
</>
6180
)
6281
}

0 commit comments

Comments
 (0)