57 lines
1.3 KiB
TypeScript
57 lines
1.3 KiB
TypeScript
import { useState, useRef, useCallback, useEffect } from 'react'
|
|
|
|
const SCROLL_INTERVAL_SECONDS = 3
|
|
|
|
interface AutoCarouselProps {
|
|
images: string[]
|
|
}
|
|
|
|
const AutoCarousel = ({ images }: AutoCarouselProps) => {
|
|
const [activeItem, setActiveItem] = useState<number>(0)
|
|
const ref = useRef<HTMLDivElement>(null)
|
|
|
|
const scroll = useCallback(() => {
|
|
setActiveItem((prev) => {
|
|
if (images.length - 1 > prev) return prev + 1
|
|
else return 0
|
|
})
|
|
}, [images.length])
|
|
|
|
const autoScroll = useCallback(
|
|
() => setInterval(scroll, SCROLL_INTERVAL_SECONDS * 1000),
|
|
[scroll]
|
|
)
|
|
|
|
useEffect(() => {
|
|
const play = autoScroll()
|
|
return () => clearInterval(play)
|
|
}, [autoScroll])
|
|
|
|
useEffect(() => {
|
|
const width = ref.current?.getBoundingClientRect().width
|
|
ref.current?.scroll({ left: activeItem * (width || 0) })
|
|
}, [activeItem])
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className="carousel carousel-center p-2 space-x-2 rounded-box"
|
|
>
|
|
{images.map((image, i) => (
|
|
<div
|
|
key={i}
|
|
className="carousel-item w-full h-fit my-auto justify-center"
|
|
>
|
|
<img
|
|
src={image}
|
|
alt={`${i}`}
|
|
className="object-contain rounded-xl size-fit"
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default AutoCarousel
|