93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
|
|
import type { OffsetType, PositionType } from "./walkthroughContext";
|
||
|
|
|
||
|
|
const DEFAULT_POSITION: PositionType = "top";
|
||
|
|
export const PADDING_HIGHLIGHT = 10;
|
||
|
|
|
||
|
|
type PositionCalculator = {
|
||
|
|
offset?: OffsetType;
|
||
|
|
targetId: string;
|
||
|
|
};
|
||
|
|
|
||
|
|
export function getPosition({ offset, targetId }: PositionCalculator) {
|
||
|
|
const target = document.querySelector(`#${targetId}`);
|
||
|
|
const bodyCoordinates = document.body.getBoundingClientRect();
|
||
|
|
if (!target) return null;
|
||
|
|
let coordinates;
|
||
|
|
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,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|