'next js carousel with tailwindcss
i have tried to implement a carousel logic from this sandbox: https://codesandbox.io/s/react-multi-item-carousel-uvmchp?file=/package.json but it does not work.
I'm using next js, querying the list in the index.js, then passings the props to the carousel components.
images don't seem to get hidden when they overflow.
anyone got any idea why this isnt working?
thanks in advance <3
Index.js
import Carousel from '../components/Carousel'
import groq from 'groq'
import client from '../client'
const Index = ({category}) => {
return (
<>
<h1 className="text-3xl font-bold underline">Welcome!</h1>
<div className="2xl:container 2xl:mx-auto 2xl:px-0 py-3 px-10">
<Carousel category={category}/>
</div>
</>
)
}
export async function getServerSideProps() {
const category = await client.fetch(groq`*[_type == 'category']{
title,
"catImage": mainImage
}`)
return {
props: {
category
}
}
}
export default Index
carouse.js
import { useState, useRef, useEffect } from 'react';
import client from '../client'
import imageUrlBuilder from '@sanity/image-url'
function urlFor (source) {
return imageUrlBuilder(client).image(source)
}
const Carousel = ({category}) => {
const maxScrollWidth = useRef(0);
const [currentIndex, setCurrentIndex] = useState(0);
const carousel = useRef(null);
const movePrev = () => {
if (currentIndex > 0) {
setCurrentIndex((prevState) => prevState - 1);
}
};
const moveNext = () => {
if (
carousel.current !== null &&
carousel.current.offsetWidth * currentIndex <= maxScrollWidth.current
) {
setCurrentIndex((prevState) => prevState + 1);
}
};
const isDisabled = (direction) => {
if (direction === 'prev') {
return currentIndex <= 0;
}
if (direction === 'next' && carousel.current !== null) {
return (
carousel.current.offsetWidth * currentIndex >= maxScrollWidth.current
);
}
return false;
};
useEffect(() => {
if (carousel !== null && carousel.current !== null) {
carousel.current.scrollLeft = carousel.current.offsetWidth * currentIndex;
}
}, [currentIndex]);
useEffect(() => {
maxScrollWidth.current = carousel.current
? carousel.current.scrollWidth - carousel.current.offsetWidth
: 0;
}, []);
return (
<div className="carousel my-12 mx-auto">
<h2 className="text-4xl leading-8 font-semibold mb-12 text-slate-700">
Epic category list
</h2>
<div className="relative overflow-hidden">
<div className="flex justify-between absolute top left w-full h-full">
<button
onClick={movePrev}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled('prev')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 19l-7-7 7-7"
/>
</svg>
<span className="sr-only">Prev</span>
</button>
<button
onClick={moveNext}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled('next')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 5l7 7-7 7"
/>
</svg>
<span className="sr-only">Next</span>
</button>
</div>
<div
ref={carousel}
className="carousel-container relative flex gap-1 overflow-hidden scroll-smooth snap-x snap-mandatory touch-pan-x z-0"
>
{category.map(({title = '', catImage, index}) => {
return (
<div
key={index}
className="carousel-item text-center relative w-64 h-64 snap-start"
>
<a
href="/"
className="h-full w-full aspect-square block bg-origin-padding bg-left-top bg-cover bg-no-repeat z-0"
style={{ backgroundImage: `url(${urlFor(catImage).url()})` }}
>
<img
src={urlFor(catImage).url()}
alt={title}
className="w-full aspect-square hidden"
/>
</a>
<a
href="/"
className="h-full w-full aspect-square block absolute top-0 left-0 transition-opacity duration-300 opacity-0 hover:opacity-100 bg-blue-800/75 z-10"
>
<h3 className="text-white py-6 px-3 mx-auto text-xl">
{title}
</h3>
</a>
</div>
);
})}
</div>
</div>
</div>
);
};
export default Carousel;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
