From b4ade6ec09dc00646581859e9edb8c9521ee50dc Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 22 Mar 2023 05:18:40 +0700 Subject: [PATCH 1/5] determine if there is an overlapping element at top --- src/styles/getTooltipStyles.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 3c8b0ff0a4b3..48afea6314b2 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -49,6 +49,24 @@ function computeHorizontalShift(windowWidth, xOffset, componentWidth, tooltipWid return 0; } +/** + * Determines if there is an overlapping element at the top of a given coordinate. + * @param {Number} xOffset - The distance between the left edge of the window + * and the left edge of the wrapped component. + * @param {Number} yOffset - The distance between the left edge of the window + * and the left edge of the wrapped component. + * @returns {Boolean} + */ +function isOverlappingAtTop(xOffset, yOffset) { + const element = document.elementFromPoint(xOffset, yOffset); + + const rect = element.getBoundingClientRect(); + + // Ensure it's not itself by checking if the yOffset is greater than the top of the element + // and less than the bottom of the element + return yOffset > rect.top && yOffset < rect.bottom; +} + /** * Generate styles for the tooltip component. * @@ -86,9 +104,10 @@ export default function getTooltipStyles( manualShiftVertical = 0, ) { // Determine if the tooltip should display below the wrapped component. - // If a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen, + // If either a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen, + // Or a tooltip is overlapping at top-left with another element // we'll display it beneath its wrapped component rather than above it as usual. - const shouldShowBelow = (yOffset - tooltipHeight) < GUTTER_WIDTH; + const shouldShowBelow = (yOffset - tooltipHeight) < GUTTER_WIDTH || isOverlappingAtTop(xOffset, yOffset); // Determine if we need to shift the tooltip horizontally to prevent it // from displaying too near to the edge of the screen. From aef1196b293751c1acc7660e71947987f7cb7c4e Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 22 Mar 2023 05:49:40 +0700 Subject: [PATCH 2/5] ensure it won't raise error on unsupported browser --- src/styles/getTooltipStyles.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 48afea6314b2..200dcd1c7df7 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -58,6 +58,10 @@ function computeHorizontalShift(windowWidth, xOffset, componentWidth, tooltipWid * @returns {Boolean} */ function isOverlappingAtTop(xOffset, yOffset) { + if (typeof document.elementFromPoint !== 'function') { + return false; + } + const element = document.elementFromPoint(xOffset, yOffset); const rect = element.getBoundingClientRect(); From 107c607062daa3df029246e1f51530c6e92e4e74 Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 22 Mar 2023 06:20:50 +0700 Subject: [PATCH 3/5] Ensure it won't raise error if element not found --- src/styles/getTooltipStyles.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 200dcd1c7df7..f9ccc391653a 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -64,6 +64,10 @@ function isOverlappingAtTop(xOffset, yOffset) { const element = document.elementFromPoint(xOffset, yOffset); + if (!element) { + return false; + } + const rect = element.getBoundingClientRect(); // Ensure it's not itself by checking if the yOffset is greater than the top of the element From 6ba71eceecf4d8e9adeba0b9c036f3162a1adda5 Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 22 Mar 2023 10:06:02 +0700 Subject: [PATCH 4/5] update comment --- src/styles/getTooltipStyles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index f9ccc391653a..5b2c7dc22599 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -70,7 +70,7 @@ function isOverlappingAtTop(xOffset, yOffset) { const rect = element.getBoundingClientRect(); - // Ensure it's not itself by checking if the yOffset is greater than the top of the element + // Ensure it's not itself + overlapping with another element by checking if the yOffset is greater than the top of the element // and less than the bottom of the element return yOffset > rect.top && yOffset < rect.bottom; } @@ -113,7 +113,7 @@ export default function getTooltipStyles( ) { // Determine if the tooltip should display below the wrapped component. // If either a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen, - // Or a tooltip is overlapping at top-left with another element + // Or the wrapped component is overlapping at top-left with another element // we'll display it beneath its wrapped component rather than above it as usual. const shouldShowBelow = (yOffset - tooltipHeight) < GUTTER_WIDTH || isOverlappingAtTop(xOffset, yOffset); From eac6c738d5a2df0d08484514fdd89ea67ce510d8 Mon Sep 17 00:00:00 2001 From: Vinh Hoang Date: Wed, 22 Mar 2023 12:33:51 +0700 Subject: [PATCH 5/5] Update function description from code review Co-authored-by: Aimane Chnaif <96077027+aimane-chnaif@users.noreply.github.com> --- src/styles/getTooltipStyles.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 5b2c7dc22599..7b7deb707f84 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -51,10 +51,11 @@ function computeHorizontalShift(windowWidth, xOffset, componentWidth, tooltipWid /** * Determines if there is an overlapping element at the top of a given coordinate. + * * @param {Number} xOffset - The distance between the left edge of the window * and the left edge of the wrapped component. - * @param {Number} yOffset - The distance between the left edge of the window - * and the left edge of the wrapped component. + * @param {Number} yOffset - The distance between the top edge of the window + * and the top edge of the wrapped component. * @returns {Boolean} */ function isOverlappingAtTop(xOffset, yOffset) {