fixed carousel
This commit is contained in:
@@ -16,6 +16,7 @@ interface ContentCardCarouselProps {
|
||||
cards: ContentCardItem[]
|
||||
}
|
||||
|
||||
// correctly works
|
||||
function getVisibleCardCount() {
|
||||
if (typeof window === 'undefined') return 1
|
||||
if (window.matchMedia('(min-width: 1024px)').matches) return 3
|
||||
@@ -52,21 +53,26 @@ export default function ContentCardCarousel({ cards }: ContentCardCarouselProps)
|
||||
|
||||
const maxIndex = useMemo(() => Math.max(cards.length - visibleCards, 0), [cards.length, visibleCards])
|
||||
|
||||
// custom mod function because JS does not have working modulus
|
||||
function mod(n: number, m: number) {
|
||||
return ((n % m) + m) % m;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentIndex((previous) => Math.min(previous, maxIndex))
|
||||
}, [maxIndex])
|
||||
|
||||
// % of track width — matches flex slide sizes (100% / 50% / 33.333% per breakpoint)
|
||||
const trackOffsetPercent = cards.length > 0 ? (currentIndex * 100) / cards.length : 0
|
||||
const trackOffsetPercent = cards.length > 0 ? ((currentIndex) * -100) / visibleCards : 0
|
||||
|
||||
const next = () => {
|
||||
if (maxIndex === 0) return
|
||||
setCurrentIndex((previous) => (previous >= maxIndex ? 0 : previous + 1))
|
||||
setCurrentIndex(mod(Math.abs((currentIndex + 1)), (cards.length)))
|
||||
}
|
||||
|
||||
const previous = () => {
|
||||
if (maxIndex === 0) return
|
||||
setCurrentIndex((index) => (index <= 0 ? maxIndex : index - 1))
|
||||
setCurrentIndex(mod((currentIndex - 1), (cards.length)))
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -76,7 +82,7 @@ export default function ContentCardCarousel({ cards }: ContentCardCarouselProps)
|
||||
<div className="carousel-viewport relative overflow-hidden">
|
||||
<div
|
||||
className="carousel-track flex items-stretch transition-transform duration-500 ease-in-out"
|
||||
style={{ transform: `translate3d(-${trackOffsetPercent}%, 0, 0)` }}
|
||||
style={{ transform: `translate3d(${trackOffsetPercent}%, 0, 0)` }}
|
||||
>
|
||||
{cards.map((card, index) => {
|
||||
const isEdgeCard =
|
||||
@@ -97,15 +103,14 @@ export default function ContentCardCarousel({ cards }: ContentCardCarouselProps)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 w-12 bg-gradient-to-r from-white to-transparent dark:from-black" />
|
||||
<div className="pointer-events-none absolute inset-y-0 right-0 w-12 bg-gradient-to-l from-white to-transparent dark:from-black" />
|
||||
<div className="absolute inset-y-0 left-0 w-12 bg-linear-to-r from-white to-transparent dark:from-black" />
|
||||
<div className="absolute inset-y-0 right-0 w-12 bg-linear-to-l from-white to-transparent dark:from-black" />
|
||||
</div>
|
||||
|
||||
<div className="carousel-controls relative z-20 mt-6 flex justify-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={previous}
|
||||
disabled={maxIndex === 0}
|
||||
className="carousel-control-btn"
|
||||
aria-label="Show previous content cards"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user