|
1 |
| -import { bringInView, getFocusableElements } from "./utils"; |
2 | 1 | import { Config, DriverHook, getConfig, getCurrentDriver } from "./config";
|
3 |
| -import { getState, setState, State } from "./state"; |
4 | 2 | import { Driver, DriveStep } from "./driver";
|
5 |
| -import { onDriverClick } from "./events"; |
6 | 3 | import { emit } from "./emitter";
|
| 4 | +import { onDriverClick } from "./events"; |
| 5 | +import { getState, setState, State } from "./state"; |
| 6 | +import { bringInView, getFocusableElements } from "./utils"; |
7 | 7 |
|
8 | 8 | export type Side = "top" | "right" | "bottom" | "left" | "over";
|
9 | 9 | export type Alignment = "start" | "center" | "end";
|
@@ -585,14 +585,41 @@ function renderPopoverArrow(alignment: Alignment, side: Side, element: Element)
|
585 | 585 | arrowSide = "right";
|
586 | 586 | arrowAlignment = "end";
|
587 | 587 | }
|
588 |
| - } else { |
589 | 588 | }
|
590 | 589 |
|
591 | 590 | if (!arrowSide) {
|
592 | 591 | popoverArrow.classList.add("driver-popover-arrow-none");
|
593 | 592 | } else {
|
594 | 593 | popoverArrow.classList.add(`driver-popover-arrow-side-${arrowSide}`);
|
595 | 594 | popoverArrow.classList.add(`driver-popover-arrow-align-${arrowAlignment}`);
|
| 595 | + |
| 596 | + const elementRect = element.getBoundingClientRect(); |
| 597 | + const arrowRect = popoverArrow.getBoundingClientRect(); |
| 598 | + const stagePadding = getConfig("stagePadding") || 0; |
| 599 | + |
| 600 | + const isElementPartiallyInViewPort = |
| 601 | + elementRect.left - stagePadding < window.innerWidth && |
| 602 | + elementRect.right + stagePadding > 0 && |
| 603 | + elementRect.top - stagePadding < window.innerHeight && |
| 604 | + elementRect.bottom + stagePadding > 0; |
| 605 | + |
| 606 | + if (side === "bottom" && isElementPartiallyInViewPort) { |
| 607 | + const isArrowWithinElementBounds = |
| 608 | + arrowRect.x > elementRect.x && arrowRect.x + arrowRect.width < elementRect.x + elementRect.width; |
| 609 | + |
| 610 | + if (!isArrowWithinElementBounds) { |
| 611 | + popoverArrow.classList.remove(`driver-popover-arrow-align-${arrowAlignment}`); |
| 612 | + popoverArrow.classList.add(`driver-popover-arrow-none`); |
| 613 | + // reduce the top position by the padding |
| 614 | + popover.wrapper.style.transform = `translateY(-${stagePadding / 2}px)`; |
| 615 | + } else { |
| 616 | + popover.wrapper.style.transform = `translateY(0)`; |
| 617 | + } |
| 618 | + |
| 619 | + // TODO: implement this using either of the following: |
| 620 | + // 1 - move the arrow to the center of the element and point it towards the popover. This way, scrolling or resizing the window will move the arrow to the correct position. |
| 621 | + // 2 - calculate the center position of the element and point the arrow towards the popover. However, we will have to re-calculate the position of the arrow when the window is resized or scrolled. |
| 622 | + } |
596 | 623 | }
|
597 | 624 | }
|
598 | 625 |
|
|
0 commit comments