@@ -23,26 +23,17 @@ export const isElementInViewport = (element, container = null, position) => {
2323 const viewportWidth = window . innerWidth || document . documentElement . clientWidth ;
2424 const viewportHeight = window . innerHeight || document . documentElement . clientHeight ;
2525
26- let isInsideViewport = (
27- rect . bottom > 0 &&
28- rect . top < viewportHeight &&
29- rect . right > 0 &&
30- rect . left < viewportWidth
31- ) ;
26+ let isInsideViewport = rect . bottom > 0 && rect . top < viewportHeight && rect . right > 0 && rect . left < viewportWidth ;
3227
3328 if ( container ) {
3429 const containerRect = container . getBoundingClientRect ( ) ;
3530
3631 if ( position === 'top' || position === 'bottom' ) {
37- isInsideViewport = (
38- ( containerRect . bottom + containerRect . height ) < viewportHeight &&
39- containerRect . top < viewportHeight
40- ) ;
32+ isInsideViewport =
33+ containerRect . bottom + containerRect . height < viewportHeight && containerRect . top < viewportHeight ;
4134 } else {
42- isInsideViewport = (
43- ( containerRect . right + containerRect . width ) < viewportWidth &&
44- containerRect . left < viewportWidth
45- ) ;
35+ isInsideViewport =
36+ containerRect . right + containerRect . width < viewportWidth && containerRect . left < viewportWidth ;
4637 }
4738
4839 return isInsideViewport ;
@@ -56,25 +47,55 @@ export const computeTooltipPosition = (containerRef, tooltipRef, position, coord
5647 return coords ;
5748 }
5849
50+ let cumulativeOffsetTop = 0 ;
51+ let cumulativeOffsetLeft = 0 ;
52+
53+ let fixedOffsetTop = 0 ;
54+ let stickyOffsetTop = 0 ;
55+ let fixedOffsetLeft = 0 ;
56+
57+ let currentElement = containerRef ;
58+
59+ while ( currentElement !== document . body ) {
60+ const computedStyle = window . getComputedStyle ( currentElement ) ;
61+ const elementPosition = computedStyle . position ;
62+
63+ if ( elementPosition === 'fixed' ) {
64+ fixedOffsetTop += currentElement . getBoundingClientRect ( ) . top + window . scrollY ;
65+ fixedOffsetLeft += currentElement . getBoundingClientRect ( ) . left + window . scrollX ;
66+ } else if ( elementPosition === 'sticky' ) {
67+ stickyOffsetTop += currentElement . getBoundingClientRect ( ) . top ;
68+ fixedOffsetLeft += currentElement . getBoundingClientRect ( ) . left + window . scrollX ;
69+ } else if ( elementPosition === 'absolute' || elementPosition === 'relative' ) {
70+ cumulativeOffsetTop -= parseFloat ( computedStyle . top ) || 0 ;
71+ cumulativeOffsetLeft -= parseFloat ( computedStyle . left ) || 0 ;
72+ }
73+
74+ currentElement = currentElement . parentElement ;
75+ }
76+
5977 const containerRect = containerRef . getBoundingClientRect ( ) ;
6078 const tooltipRect = tooltipRef . getBoundingClientRect ( ) ;
6179
80+ let finalTop = containerRect . top + cumulativeOffsetTop + stickyOffsetTop - fixedOffsetTop ;
81+ let finalLeft = containerRect . left + cumulativeOffsetLeft - fixedOffsetLeft ;
82+
6283 switch ( position ) {
6384 case 'top' :
64- coords . top = containerRect . top ;
65- coords . left = containerRect . left + ( containerRect . width / 2 ) ;
85+ coords . top = finalTop ;
86+ coords . left = finalLeft + containerRect . width / 2 ;
6687 break ;
6788 case 'bottom' :
68- coords . top = containerRect . top - tooltipRect . height ;
69- coords . left = containerRect . left + ( containerRect . width / 2 ) ;
89+ coords . top = finalTop - tooltipRect . height ;
90+ coords . left = finalLeft + containerRect . width / 2 ;
7091 break ;
7192 case 'left' :
72- coords . left = containerRect . left ;
73- coords . top = containerRect . top + ( containerRect . height / 2 ) ;
93+ coords . left = finalLeft ;
94+ coords . top = finalTop + containerRect . height / 2 ;
7495 break ;
7596 case 'right' :
76- coords . left = containerRect . right - tooltipRect . width ;
77- coords . top = containerRect . top + ( containerRect . height / 2 ) ;
97+ coords . left = finalLeft + containerRect . width - tooltipRect . width ;
98+ coords . top = finalTop + containerRect . height / 2 ;
7899 break ;
79100 }
80101
0 commit comments