Skip to content

Commit a5a5e43

Browse files
Fix tooltip z-index and overflow
Adjusted tooltip styling to ensure they appear in the foreground and are not cut off when exceeding parent window boundaries.
1 parent 6e7342f commit a5a5e43

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

src/components/CustomInfoTooltip.tsx

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useState, useRef, useEffect } from 'react';
22
import { HelpCircle } from 'lucide-react';
33

44
interface CustomInfoTooltipProps {
@@ -7,18 +7,69 @@ interface CustomInfoTooltipProps {
77

88
export const CustomInfoTooltip = ({ text }: CustomInfoTooltipProps) => {
99
const [isVisible, setIsVisible] = useState(false);
10+
const [position, setPosition] = useState({ top: false, left: '50%' });
11+
const tooltipRef = useRef<HTMLDivElement>(null);
12+
const triggerRef = useRef<HTMLDivElement>(null);
13+
14+
useEffect(() => {
15+
if (isVisible && tooltipRef.current && triggerRef.current) {
16+
const tooltip = tooltipRef.current;
17+
const trigger = triggerRef.current;
18+
const rect = trigger.getBoundingClientRect();
19+
const tooltipRect = tooltip.getBoundingClientRect();
20+
21+
// Vérifier si le tooltip dépasse à droite
22+
const spaceRight = window.innerWidth - rect.right;
23+
const spaceLeft = rect.left;
24+
25+
let newLeft = '50%';
26+
if (tooltipRect.width / 2 > spaceRight) {
27+
newLeft = 'auto';
28+
} else if (tooltipRect.width / 2 > spaceLeft) {
29+
newLeft = '0%';
30+
}
31+
32+
// Vérifier si il y a de la place en haut
33+
const spaceTop = rect.top;
34+
const showOnTop = spaceTop > tooltipRect.height + 10;
35+
36+
setPosition({ top: !showOnTop, left: newLeft });
37+
}
38+
}, [isVisible]);
1039

1140
return (
12-
<div className="relative inline-block">
41+
<div ref={triggerRef} className="relative inline-block">
1342
<HelpCircle
1443
className="h-3 w-3 text-gray-500 cursor-help"
1544
onMouseEnter={() => setIsVisible(true)}
1645
onMouseLeave={() => setIsVisible(false)}
1746
/>
1847
{isVisible && (
19-
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-1.5 bg-gray-900 text-white text-xs rounded-md shadow-lg z-50 w-48 text-center">
48+
<div
49+
ref={tooltipRef}
50+
className={`fixed px-3 py-1.5 bg-gray-900 text-white text-xs rounded-md shadow-lg w-48 text-center pointer-events-none`}
51+
style={{
52+
zIndex: 9999,
53+
top: position.top ? 'auto' : '-40px',
54+
bottom: position.top ? '-40px' : 'auto',
55+
left: position.left === '50%' ? '50%' : position.left === 'auto' ? 'auto' : '0%',
56+
right: position.left === 'auto' ? '0px' : 'auto',
57+
transform: position.left === '50%' ? 'translateX(-50%)' : 'none',
58+
}}
59+
>
2060
{text}
21-
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900"></div>
61+
<div
62+
className={`absolute w-0 h-0 border-l-4 border-r-4 border-transparent ${
63+
position.top
64+
? 'top-0 -mt-1 border-b-4 border-b-gray-900'
65+
: 'bottom-0 -mb-1 border-t-4 border-t-gray-900'
66+
}`}
67+
style={{
68+
left: position.left === '50%' ? '50%' : position.left === 'auto' ? 'auto' : '24px',
69+
right: position.left === 'auto' ? '24px' : 'auto',
70+
transform: position.left === '50%' ? 'translateX(-50%)' : 'none',
71+
}}
72+
/>
2273
</div>
2374
)}
2475
</div>

0 commit comments

Comments
 (0)