wip
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import RequestQuoteForm from '@/components/RequestQuoteForm';
|
||||
@@ -13,30 +13,62 @@ interface ProductSidebarProps {
|
||||
|
||||
export default function ProductSidebar({ productName, productImage, datasheetPath }: ProductSidebarProps) {
|
||||
const t = useTranslations('Products');
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const sidebarRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
// Show sidebar after scrolling down 400px (approx height of hero)
|
||||
if (window.scrollY > 400) {
|
||||
setIsVisible(true);
|
||||
} else {
|
||||
setIsVisible(false);
|
||||
if (!sidebarRef.current) return;
|
||||
const sidebar = sidebarRef.current;
|
||||
const container = sidebar.parentElement;
|
||||
if (!container) return;
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const sidebarHeight = sidebar.offsetHeight;
|
||||
|
||||
// Offset from top of viewport when sticky
|
||||
const stickyOffset = 128; // 8rem = top-32
|
||||
|
||||
let translateY = 0;
|
||||
|
||||
// If the top of the container has scrolled past our sticky offset
|
||||
if (containerRect.top < stickyOffset) {
|
||||
translateY = stickyOffset - containerRect.top;
|
||||
}
|
||||
|
||||
// Don't let it go past the bottom of the container
|
||||
const maxTranslateY = containerRect.height - sidebarHeight;
|
||||
if (translateY > maxTranslateY) {
|
||||
translateY = maxTranslateY;
|
||||
}
|
||||
|
||||
// Ensure translateY is never negative
|
||||
if (translateY < 0) translateY = 0;
|
||||
|
||||
sidebar.style.transform = `translateY(${translateY}px)`;
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
// Check initial scroll position
|
||||
handleScroll();
|
||||
let rafId: number;
|
||||
const onScroll = () => {
|
||||
rafId = requestAnimationFrame(handleScroll);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
window.addEventListener('resize', handleScroll);
|
||||
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
// Initial call
|
||||
handleScroll();
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', handleScroll);
|
||||
cancelAnimationFrame(rafId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`hidden lg:block fixed top-32 right-8 z-50 w-[350px] xl:w-[400px] transition-all duration-700 transform ${
|
||||
isVisible ? 'translate-x-0 opacity-100' : 'translate-x-[120%] opacity-0'
|
||||
}`}
|
||||
ref={sidebarRef}
|
||||
className="hidden lg:block absolute left-full ml-12 top-0 w-[350px] xl:w-[400px] z-30 will-change-transform"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
{/* Request Quote Form */}
|
||||
|
||||
Reference in New Issue
Block a user