This commit is contained in:
2026-01-19 17:43:23 +01:00
parent 40c553d6f6
commit 1f624f3d7f
3 changed files with 115 additions and 81 deletions

View File

@@ -276,9 +276,10 @@ export default async function ProductPage({ params }: ProductPageProps) {
</div> </div>
)} )}
<div className="flex flex-col lg:flex-row relative items-start"> <div className="relative">
<div className="space-y-20">
{/* Sidebar on Mobile (Above Content) */} {/* Sidebar on Mobile (Above Content) */}
<div className="w-full lg:hidden mb-20"> <div className="w-full lg:hidden">
<div className="space-y-10"> <div className="space-y-10">
{/* Request Quote Form */} {/* Request Quote Form */}
<div className="bg-white rounded-[40px] shadow-[0_32px_64px_-12px_rgba(0,0,0,0.08)] border border-neutral-dark/5 overflow-hidden"> <div className="bg-white rounded-[40px] shadow-[0_32px_64px_-12px_rgba(0,0,0,0.08)] border border-neutral-dark/5 overflow-hidden">
@@ -316,7 +317,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
</div> </div>
</div> </div>
<div className="flex-1 w-full"> <div className="w-full">
{/* Main Content Area */} {/* Main Content Area */}
<div className="max-w-none"> <div className="max-w-none">
<MDXRemote source={product.content} components={components} /> <MDXRemote source={product.content} components={components} />
@@ -347,6 +348,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
}} }}
/> />
</div> </div>
</div>
<ProductSidebar <ProductSidebar
productName={product.frontmatter.title} productName={product.frontmatter.title}

View File

@@ -1,6 +1,6 @@
'use client'; 'use client';
import { useState, useEffect } from 'react'; import { useEffect, useRef } from 'react';
import Image from 'next/image'; import Image from 'next/image';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import RequestQuoteForm from '@/components/RequestQuoteForm'; import RequestQuoteForm from '@/components/RequestQuoteForm';
@@ -13,30 +13,62 @@ interface ProductSidebarProps {
export default function ProductSidebar({ productName, productImage, datasheetPath }: ProductSidebarProps) { export default function ProductSidebar({ productName, productImage, datasheetPath }: ProductSidebarProps) {
const t = useTranslations('Products'); const t = useTranslations('Products');
const [isVisible, setIsVisible] = useState(false); const sidebarRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
// Show sidebar after scrolling down 400px (approx height of hero) if (!sidebarRef.current) return;
if (window.scrollY > 400) { const sidebar = sidebarRef.current;
setIsVisible(true); const container = sidebar.parentElement;
} else { if (!container) return;
setIsVisible(false);
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); let rafId: number;
// Check initial scroll position const onScroll = () => {
rafId = requestAnimationFrame(handleScroll);
};
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', handleScroll);
// Initial call
handleScroll(); handleScroll();
return () => window.removeEventListener('scroll', handleScroll); return () => {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', handleScroll);
cancelAnimationFrame(rafId);
};
}, []); }, []);
return ( return (
<div <div
className={`hidden lg:block fixed top-32 right-8 z-50 w-[350px] xl:w-[400px] transition-all duration-700 transform ${ ref={sidebarRef}
isVisible ? 'translate-x-0 opacity-100' : 'translate-x-[120%] opacity-0' 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"> <div className="space-y-6">
{/* Request Quote Form */} {/* Request Quote Form */}

File diff suppressed because one or more lines are too long