57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { useCallback, useEffect } from "react"
|
|
import { useMediaQuery } from "usehooks-ts"
|
|
|
|
import type { StepEnum } from "@/types/enums/step"
|
|
|
|
export default function useScrollToActiveSection(
|
|
step: StepEnum,
|
|
steps: StepEnum[],
|
|
isActive: boolean
|
|
) {
|
|
const isMobile = useMediaQuery("(max-width: 768px)")
|
|
|
|
const handleScroll = useCallback(() => {
|
|
if (!isMobile) {
|
|
return
|
|
}
|
|
|
|
const currentElement = document.querySelector<HTMLElement>(
|
|
`[data-step="${step}"]`
|
|
)
|
|
const prevOpenElement =
|
|
document.querySelector<HTMLElement>(`[data-open="true"]`)
|
|
|
|
const currentStepIndex = steps.indexOf(step)
|
|
const prevStep = prevOpenElement?.dataset.step as StepEnum
|
|
const prevStepIndex = steps.indexOf(prevStep)
|
|
|
|
if (currentElement) {
|
|
const BOOKING_WIDGET_OFFSET = 71
|
|
|
|
const prevElementContent = prevOpenElement?.querySelector("header + div")
|
|
|
|
let collapsedSpace = 0
|
|
if (prevElementContent && prevStepIndex < currentStepIndex) {
|
|
collapsedSpace = prevElementContent.clientHeight
|
|
}
|
|
|
|
const currentElementTop =
|
|
currentElement.getBoundingClientRect().top + window.scrollY
|
|
|
|
const scrollTarget = Math.round(
|
|
currentElementTop - BOOKING_WIDGET_OFFSET - collapsedSpace
|
|
)
|
|
|
|
window.scrollTo({
|
|
top: scrollTarget,
|
|
behavior: "smooth",
|
|
})
|
|
}
|
|
}, [step, steps, isMobile])
|
|
|
|
useEffect(() => {
|
|
if (!isActive) return
|
|
handleScroll()
|
|
}, [isActive, handleScroll])
|
|
}
|