united-tattoo/components/scroll-to-section.tsx
Nicholai ad0e34bd7e
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
updated section scrolling
2025-09-26 00:34:25 -06:00

86 lines
2.5 KiB
TypeScript

"use client"
import { useEffect } from "react"
import { useLenis } from "./smooth-scroll-provider"
interface ScrollToSectionProps {
/**
* Offset from the top of the target element (e.g., for fixed navigation)
*/
offset?: number
}
export function ScrollToSection({ offset = 80 }: ScrollToSectionProps = {}) {
const lenis = useLenis()
useEffect(() => {
const handleAnchorClick = (e: Event) => {
const target = e.target as HTMLElement
// Find the closest anchor element (handles Next.js Link components)
const anchor = target.closest('a[href^="#"]') as HTMLAnchorElement
if (anchor) {
e.preventDefault()
const href = anchor.getAttribute("href")
const id = href?.slice(1)
const element = document.getElementById(id || "")
if (element) {
// Calculate position with offset for fixed navigation
const elementPosition = element.getBoundingClientRect().top + window.pageYOffset
const offsetPosition = elementPosition - offset
// Use Lenis scrollTo if available, otherwise fallback to window.scrollTo
if (lenis && typeof lenis.scrollTo === "function") {
lenis.scrollTo(offsetPosition)
} else {
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
})
}
}
}
}
// Add event listener with capture to ensure it runs before other handlers
document.addEventListener("click", handleAnchorClick, true)
return () => {
document.removeEventListener("click", handleAnchorClick, true)
}
}, [offset, lenis]) // Added lenis to dependency array
return null
}
// Hook for programmatic scrolling
export function useScrollToSection(offset: number = 80) {
const lenis = useLenis()
const scrollToSection = (targetId: string) => {
const element = document.getElementById(targetId)
if (!element) {
console.warn(`Element with id "${targetId}" not found`)
return
}
const elementPosition = element.getBoundingClientRect().top + window.pageYOffset
const offsetPosition = elementPosition - offset
// Use Lenis scrollTo if available, otherwise fallback to window.scrollTo
if (lenis && typeof lenis.scrollTo === "function") {
lenis.scrollTo(offsetPosition)
} else {
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
})
}
}
return { scrollToSection }
}