|
4 | 4 | */ |
5 | 5 | const BLOB_PADDING_TOP = 8 |
6 | 6 |
|
| 7 | +interface CalculateOverlayPositionOptions { |
| 8 | + /** The closest parent element that is `position: relative` */ |
| 9 | + relativeElement: HTMLElement |
| 10 | + /** The DOM Node that was hovered */ |
| 11 | + target: HTMLElement |
| 12 | + /** The DOM Node of the tooltip */ |
| 13 | + hoverOverlayElement: HTMLElement |
| 14 | +} |
| 15 | + |
7 | 16 | /** |
8 | 17 | * Calculates the desired position of the hover overlay depending on the container, |
9 | 18 | * the hover target and the size of the hover overlay |
10 | | - * |
11 | | - * @param scrollable The closest container that is scrollable |
12 | | - * @param target The DOM Node that was hovered |
13 | | - * @param tooltip The DOM Node of the tooltip |
14 | 19 | */ |
15 | | -export const calculateOverlayPosition = ( |
16 | | - scrollable: HTMLElement, |
17 | | - target: HTMLElement, |
18 | | - tooltip: HTMLElement |
19 | | -): { left: number; top: number } => { |
| 20 | +export const calculateOverlayPosition = ({ |
| 21 | + relativeElement, |
| 22 | + target, |
| 23 | + hoverOverlayElement, |
| 24 | +}: CalculateOverlayPositionOptions): { left: number; top: number } => { |
20 | 25 | // The scrollable element is the one with scrollbars. The scrolling element is the one with the content. |
21 | | - const scrollableBounds = scrollable.getBoundingClientRect() |
| 26 | + const relativeElementBounds = relativeElement.getBoundingClientRect() |
22 | 27 | const targetBound = target.getBoundingClientRect() // our target elements bounds |
23 | 28 |
|
24 | 29 | // Anchor it horizontally, prior to rendering to account for wrapping |
25 | 30 | // changes to vertical height if the tooltip is at the edge of the viewport. |
26 | | - const relLeft = targetBound.left - scrollableBounds.left |
| 31 | + const relLeft = targetBound.left - relativeElementBounds.left |
27 | 32 |
|
28 | 33 | // Anchor the tooltip vertically. |
29 | | - const tooltipBound = tooltip.getBoundingClientRect() |
30 | | - const relTop = targetBound.top + scrollable.scrollTop - scrollableBounds.top |
| 34 | + const tooltipBound = hoverOverlayElement.getBoundingClientRect() |
| 35 | + const relTop = targetBound.top + relativeElement.scrollTop - relativeElementBounds.top |
31 | 36 | // This is the padding-top of the blob element |
32 | 37 | let tooltipTop = relTop - (tooltipBound.height - BLOB_PADDING_TOP) |
33 | | - if (tooltipTop - scrollable.scrollTop < 0) { |
| 38 | + if (tooltipTop - relativeElement.scrollTop < 0) { |
34 | 39 | // Tooltip wouldn't be visible from the top, so display it at the |
35 | 40 | // bottom. |
36 | | - const relBottom = targetBound.bottom + scrollable.scrollTop - scrollableBounds.top |
| 41 | + const relBottom = targetBound.bottom + relativeElement.scrollTop - relativeElementBounds.top |
37 | 42 | tooltipTop = relBottom |
38 | 43 | } else { |
39 | 44 | tooltipTop -= BLOB_PADDING_TOP |
|
0 commit comments