1- import { useState } from 'react' ;
1+ import { useState , useRef , useEffect } from 'react' ;
22import { HelpCircle } from 'lucide-react' ;
33
44interface CustomInfoTooltipProps {
@@ -7,18 +7,69 @@ interface CustomInfoTooltipProps {
77
88export 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