feat: enhance CategoryShowcaseScroll with manual scroll locking and improved layout adjustments
Some checks are pending
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions

This commit is contained in:
Najjar\NajjarV02 2026-05-20 18:21:20 +04:00
parent 8457493f49
commit 79f7f9e579

View File

@ -1,6 +1,6 @@
'use client';
import { useRef, useEffect, useState } from 'react';
import { useRef, useEffect, useState, useCallback } from 'react';
import Image from 'next/image';
import Link from 'next/link';
import { motion, useScroll, useTransform } from 'framer-motion';
@ -157,9 +157,12 @@ function CategorySticky() {
offset: ['start start', 'end end'],
});
const [activeIdx, setActiveIdx] = useState(0);
const manualLockUntil = useRef<number>(0);
useEffect(() => {
return scrollYProgress.on('change', (v) => {
/* honor manual click for a short window so scroll doesn't override */
if (Date.now() < manualLockUntil.current) return;
const idx = Math.min(
CATEGORIES.length - 1,
Math.max(0, Math.floor(v * CATEGORIES.length))
@ -168,6 +171,12 @@ function CategorySticky() {
});
}, [scrollYProgress]);
const handlePick = useCallback((i: number) => {
/* swap in place, no scroll. Lock scroll listener for 1.2s. */
manualLockUntil.current = Date.now() + 1200;
setActiveIdx(i);
}, []);
/* progress bar height */
const progressHeight = useTransform(scrollYProgress, [0, 1], ['0%', '100%']);
@ -176,17 +185,16 @@ function CategorySticky() {
ref={containerRef}
style={{
position: 'relative',
/* 65vh per category — total ~520vh feels responsive, not endless */
height: `${CATEGORIES.length * 65}vh`,
/* ~50vh per category scroll budget on top of sticky height */
height: `calc(100svh + ${CATEGORIES.length * 50}vh)`,
}}
>
<div
style={{
position: 'sticky',
top: '5.5rem',
/* fill the viewport — no empty area below the panel during sticky */
/* fill the entire viewport — no void below the panel */
height: 'calc(100svh - 6.5rem)',
maxHeight: '780px',
display: 'grid',
gridTemplateColumns: 'minmax(0, 0.95fr) minmax(0, 1.05fr)',
gap: 'clamp(1.5rem, 3vw, 2.5rem)',
@ -226,13 +234,7 @@ function CategorySticky() {
<button
key={c.id}
type="button"
onClick={() => {
const el = containerRef.current;
if (!el) return;
const rect = el.getBoundingClientRect();
const targetY = window.scrollY + rect.top + (rect.height * (i + 0.5)) / CATEGORIES.length;
window.scrollTo({ top: targetY - window.innerHeight / 2, behavior: 'smooth' });
}}
onClick={() => handlePick(i)}
style={{
display: 'flex',
alignItems: 'center',