2023-07-12 06:42:16 +00:00
|
|
|
import type { OffsetType, PositionType } from "./walkthroughContext";
|
|
|
|
|
|
|
|
|
|
const DEFAULT_POSITION: PositionType = "top";
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
export const PADDING_HIGHLIGHT = 10;
|
|
|
|
|
|
2023-10-11 07:35:24 +00:00
|
|
|
interface PositionCalculator {
|
2023-07-12 06:42:16 +00:00
|
|
|
offset?: OffsetType;
|
|
|
|
|
targetId: string;
|
2023-10-11 07:35:24 +00:00
|
|
|
}
|
2023-07-12 06:42:16 +00:00
|
|
|
|
|
|
|
|
export function getPosition({ offset, targetId }: PositionCalculator) {
|
2023-08-30 08:31:16 +00:00
|
|
|
const target = document.querySelector(targetId);
|
2023-07-12 06:42:16 +00:00
|
|
|
const bodyCoordinates = document.body.getBoundingClientRect();
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
if (!target) return null;
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
let coordinates;
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
if (target) {
|
|
|
|
|
coordinates = target.getBoundingClientRect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!coordinates) return null;
|
|
|
|
|
|
|
|
|
|
const offsetValues = { top: offset?.top || 0, left: offset?.left || 0 };
|
|
|
|
|
const extraStyles = offset?.style || {};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* . - - - - - - - - - - - - - - - - - .
|
|
|
|
|
* | Body |
|
|
|
|
|
* | |
|
|
|
|
|
* | . - - - - - - - - - - . |
|
|
|
|
|
* | | Offset | |
|
|
|
|
|
* | | . - - - - - - - . | |
|
|
|
|
|
* | | | / / / / / / / | | |
|
|
|
|
|
* | | | / / /Target/ /| | |
|
|
|
|
|
* | | | / / / / / / / | | |
|
|
|
|
|
* | | . - - - - - - - . | |
|
|
|
|
|
* | | | |
|
|
|
|
|
* | . _ _ _ _ _ _ _ _ _ _ . |
|
|
|
|
|
* | |
|
|
|
|
|
* . - - - - - - - - - - - - - - - - - .
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
switch (offset?.position || DEFAULT_POSITION) {
|
|
|
|
|
case "top":
|
|
|
|
|
return {
|
|
|
|
|
bottom:
|
|
|
|
|
bodyCoordinates.height -
|
|
|
|
|
coordinates.top -
|
|
|
|
|
offsetValues.top +
|
|
|
|
|
PADDING_HIGHLIGHT +
|
|
|
|
|
"px",
|
|
|
|
|
left: coordinates.left + offsetValues.left + PADDING_HIGHLIGHT + "px",
|
|
|
|
|
transform: "translateX(-50%)",
|
|
|
|
|
...extraStyles,
|
|
|
|
|
};
|
|
|
|
|
case "bottom":
|
|
|
|
|
return {
|
|
|
|
|
top:
|
|
|
|
|
coordinates.height +
|
|
|
|
|
coordinates.top +
|
|
|
|
|
offsetValues.top +
|
|
|
|
|
PADDING_HIGHLIGHT +
|
|
|
|
|
"px",
|
|
|
|
|
left: coordinates.left + offsetValues.left - PADDING_HIGHLIGHT + "px",
|
|
|
|
|
transform: "translateX(-50%)",
|
|
|
|
|
...extraStyles,
|
|
|
|
|
};
|
|
|
|
|
case "left":
|
|
|
|
|
return {
|
|
|
|
|
top: coordinates.top + offsetValues.top - PADDING_HIGHLIGHT + "px",
|
|
|
|
|
right:
|
|
|
|
|
bodyCoordinates.width -
|
|
|
|
|
coordinates.left -
|
|
|
|
|
offsetValues.left +
|
|
|
|
|
PADDING_HIGHLIGHT +
|
|
|
|
|
"px",
|
|
|
|
|
transform: "translateY(-50%)",
|
|
|
|
|
...extraStyles,
|
|
|
|
|
};
|
|
|
|
|
case "right":
|
|
|
|
|
return {
|
|
|
|
|
top: coordinates.top + offsetValues.top - PADDING_HIGHLIGHT + "px",
|
|
|
|
|
left:
|
|
|
|
|
coordinates.left +
|
|
|
|
|
coordinates.width +
|
|
|
|
|
offsetValues.left +
|
|
|
|
|
PADDING_HIGHLIGHT +
|
|
|
|
|
"px",
|
|
|
|
|
transform: "translateY(-50%)",
|
|
|
|
|
...extraStyles,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-30 08:31:16 +00:00
|
|
|
|
|
|
|
|
export function isElementVisible(el: HTMLElement) {
|
|
|
|
|
return !!(el?.offsetWidth || el?.offsetHeight || el.getClientRects().length);
|
|
|
|
|
}
|