"use client"; import { ArrowUpIcon } from "lucide-react"; import { useEffect, useState, useCallback } from "react"; import { cn } from "../node/utils"; interface ScrollToProps { className?: string; showIcon?: boolean; offset?: number; onScrollToTop?: () => void; } export function ScrollTo({ className, showIcon = true, onScrollToTop }: ScrollToProps) { const [isVisible, setIsVisible] = useState(false); const checkScroll = useCallback(() => { const container = document.getElementById("scroll-container"); const scrollY = container ? container.scrollTop : window.scrollY; const scrollHeight = container ? container.scrollHeight : document.documentElement.scrollHeight; const threshold = scrollHeight * 0.3; const shouldShow = scrollY > threshold; if (shouldShow !== isVisible) { setIsVisible(shouldShow); } }, [isVisible]); useEffect(() => { let timeoutId: ReturnType; const handleScroll = () => { if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(checkScroll, 100); }; const container = document.getElementById("scroll-container") || window; container.addEventListener("scroll", handleScroll, { passive: true }); return () => { container.removeEventListener("scroll", handleScroll); if (timeoutId) clearTimeout(timeoutId); }; }, [checkScroll]); const scrollToTop = useCallback( (e: React.MouseEvent) => { e.preventDefault(); onScrollToTop?.(); history.replaceState(null, "", "#top"); const container = document.getElementById("scroll-container"); if (container) { container.scrollTo({ top: 0, behavior: "smooth" }); } else { window.scrollTo({ top: 0, behavior: "smooth" }); } }, [onScrollToTop] ); return (
{showIcon && } Scroll to Top
); }