Open GabrielAtlas opened 2 months ago
Basically, the bug happens when you navigate through the next/Link component in an application made with NextJS where Keen Slider fails to update the slide. Watch the video as an example
https://github.com/user-attachments/assets/9aab7f78-0300-4538-a249-5f9b5fb90ebf
My Code:
'use client' import { useEffect, useState } from 'react' import Image from 'next/image' import { useCardapio } from '@/app/contexts/cardapio-context' import { useKeenSlider } from 'keen-slider/react' import fallbackIcon from '../../public/icons/popeyes-fallback-category-icon.svg' export default function CardapioFilters() { const { categories, isLoading } = useCardapio() const [currentSlide, setCurrentSlide] = useState(0) const [loaded, setLoaded] = useState(false) const [sliderRef, instanceRef] = useKeenSlider<HTMLDivElement>({ initial: 0, slideChanged(slider) { setCurrentSlide(slider.track.details.rel) }, created() { setLoaded(true) }, slides: { perView: 9, spacing: 10, }, breakpoints: { '(max-width: 500px)': { slides: { perView: 3, }, }, }, }) const [isFixed, setIsFixed] = useState<boolean>(false) const scrollThreshold = 360 // Height of the header is the threshold useEffect(() => { const handleScroll = () => { if (window.scrollY > scrollThreshold) { setIsFixed(true) } else { setIsFixed(false) } } window.addEventListener('scroll', handleScroll) return () => { window.removeEventListener('scroll', handleScroll) } }, []) useEffect(() => { setTimeout(() => instanceRef.current?.update(), 10) // FIX: Keen Slider Bug (On Switch between NextJS Link Navigation) }, [instanceRef]) const shouldArrowAppears = loaded && categories.length > 1 && instanceRef.current const slideCount = instanceRef.current?.track?.details?.slides?.length ?? 0 if (isLoading) return <div className="min-h-24 bg-neutral-200 animate-pulse w-full" /> return ( <div className={`min-h-24 bg-white w-full ${isFixed ? 'fixed top-0 md:top-[96px]' : 'block'}`} > <div className="mx-auto max-w-[1288px] px-6 md:px-0 w-full"> <div className="navigation-wrapper"> <div ref={sliderRef} className="keen-slider w-full pt-2"> {categories?.map((category, index) => { return ( <div key={`cardapio-category-${index}`} className="keen-slider__slide flex flex-col items-center gap-2 text-center" > <Image src={category.imagem?.url || fallbackIcon} width={48} height={48} className="opacity-30" alt="Plk Icon" /> <span className="font-bold opacity-50"> {category.nome.length >= 14 ? category.nome.split(' ')[0] : category.nome} </span> </div> ) })} </div> {shouldArrowAppears && ( <div className="hidden md:block"> <Arrow left onClick={(e: React.MouseEvent<SVGSVGElement, MouseEvent>) => { e.stopPropagation() if (instanceRef.current) instanceRef.current.prev() }} disabled={currentSlide === 0} /> <Arrow onClick={(e: React.MouseEvent<SVGSVGElement, MouseEvent>) => { e.stopPropagation() if (instanceRef.current) instanceRef.current.next() }} disabled={currentSlide === slideCount - 1} /> </div> )} </div> </div> </div> ) } function Arrow(props: { disabled: boolean left?: boolean onClick: (e: React.MouseEvent<SVGSVGElement, MouseEvent>) => void }) { const disabled = props.disabled ? ' arrow--disabled' : '' const arrowDirection = props.left ? 'arrow-cardapio-left' : 'arrow-cardapio-right' return ( <svg onClick={props.onClick} className={`arrow ${arrowDirection} ${disabled}`} xmlns="http://www.w3.org/2000/svg" width={40} height={40} viewBox="0 0 40 40" > {props.left && ( <> <circle className="arrow-circle" cx="20" cy="20" r="20" fill="#E5E5E5" /> <path className="arrow-path" d="M25.0019 10.9851C24.5119 10.4951 23.7219 10.4951 23.2319 10.9851L14.9219 19.2951C14.5319 19.6851 14.5319 20.3151 14.9219 20.7051L23.2319 29.0151C23.7219 29.5051 24.5119 29.5051 25.0019 29.0151C25.4919 28.5251 25.4919 27.7351 25.0019 27.2451L17.7619 19.9951L25.0119 12.7451C25.4919 12.2651 25.4919 11.4651 25.0019 10.9851Z" fill="#BDBDBD" /> </> )} {!props.left && ( <> <circle className="arrow-circle" cx="20" cy="20" r="20" fill="#E5E5E5" /> <path className="arrow-path" d="M14.9982 29.0151C15.4882 29.5051 16.2782 29.5051 16.7682 29.0151L25.0782 20.7051C25.4682 20.3151 25.4682 19.6851 25.0782 19.2951L16.7682 10.9851C16.2782 10.4951 15.4882 10.4951 14.9982 10.9851C14.5082 11.4751 14.5082 12.2651 14.9982 12.7551L22.2382 20.0051L14.9882 27.2551C14.5082 27.7351 14.5082 28.5351 14.9982 29.0151Z" fill="#BDBDBD" /> </> )} </svg> ) }
I agree. I have the same problem using NextJs 14.2.13
Basically, the bug happens when you navigate through the next/Link component in an application made with NextJS where Keen Slider fails to update the slide. Watch the video as an example
https://github.com/user-attachments/assets/9aab7f78-0300-4538-a249-5f9b5fb90ebf
My Code: