import { useEffect, useRef, useState } from "react"; import styles from "./styles.module.css"; import { EDirectionOnboarding } from "@/types"; interface OnboardingProps { targetRef: HTMLElement; isShow: boolean; direction?: EDirectionOnboarding; showBackground?: boolean; children: JSX.Element; classNameContainer?: string; } interface IBoardingCoordinates { top: number; left: number; } const getCoordinates = ( targetRef: HTMLElement, direction: EDirectionOnboarding, onboardingRef: React.RefObject ): IBoardingCoordinates => { if (targetRef && onboardingRef.current) { switch (direction) { case EDirectionOnboarding.LEFT: return { top: targetRef.offsetTop + targetRef.offsetHeight / 2 - onboardingRef.current.offsetHeight / 2, left: targetRef.offsetLeft - onboardingRef.current.offsetWidth, }; case EDirectionOnboarding.RIGHT: return { top: targetRef.offsetTop + targetRef.offsetHeight / 2 - onboardingRef.current.offsetHeight / 2, left: targetRef.offsetLeft + targetRef.offsetWidth, }; case EDirectionOnboarding.TOP: return { top: targetRef.offsetTop - onboardingRef.current.offsetHeight, left: targetRef.offsetLeft + targetRef.offsetWidth / 2 - onboardingRef.current.offsetWidth / 2, }; case EDirectionOnboarding.BOTTOM: return { top: targetRef.offsetTop + targetRef.offsetHeight, left: targetRef.offsetLeft + targetRef.offsetWidth / 2 - onboardingRef.current.offsetWidth / 2, }; } } return { top: 0, left: 0, }; }; const getClassNameContainer = ( direction: EDirectionOnboarding, showBackground: boolean, classNameContainer?: string ) => { return `${styles["onboarding-container"]} ${ styles[`direction-${direction}`] } ${showBackground ? styles["background"] : ""} ${classNameContainer}`; }; function Onboarding({ targetRef, isShow, direction = EDirectionOnboarding.TOP, showBackground = false, classNameContainer = "", children, }: OnboardingProps): JSX.Element { const onboardingRef = useRef(null); const [coordinates, setCoordinates] = useState({ top: 0, left: 0, }); useEffect(() => { if (!onboardingRef.current || !targetRef) { return; } setCoordinates(getCoordinates(targetRef, direction, onboardingRef)); }, [direction, targetRef, children]); if (!isShow) { return <>; } return (
{children}
); } export default Onboarding;