-
-
Save Hachikoi-the-creator/4d9ff83a2021fcb1596907d85be1eeb5 to your computer and use it in GitHub Desktop.
Build a carousel component like instagram purely in ReactJS, TS and TailwindCSS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Carousel from "./Carousel"; | |
import img1 from "path-to-local-image.jpg"; | |
import img2 from "path-to-local-image.jpg"; | |
import img3 from "path-to-local-image.jpg"; | |
export default function ImageCarousel() { | |
const slides = [img1, img2, img3]; | |
return ( | |
<div className="relative"> | |
<div className="max-w-lg"> | |
<Carousel slides={slides} /> | |
</div> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from "react"; | |
import { ChevronLeft, ChevronRight } from "react-feather"; | |
export default function Carousel({ | |
autoSlide = false, | |
autoSlideInterval = 3000, | |
slides, | |
}: { | |
autoSlide?: boolean; | |
autoSlideInterval?: number; | |
slides: string[]; | |
}) { | |
const [curr, setCurr] = useState(0); | |
const prev = () => | |
setCurr((curr) => (curr === 0 ? slides.length - 1 : curr - 1)); | |
const next = () => | |
setCurr((curr) => (curr === slides.length - 1 ? 0 : curr + 1)); | |
useEffect(() => { | |
if (!autoSlide) return; | |
const slideInterval = setInterval(next, autoSlideInterval); | |
return () => clearInterval(slideInterval); | |
}, []); | |
return ( | |
<div className="overflow-hidden relative"> | |
<div | |
className="flex transition-transform ease-out duration-500" | |
style={{ transform: `translateX(-${curr * 100}%)` }} | |
> | |
{slides.map((img) => ( | |
<img src={img} alt="" /> | |
))} | |
</div> | |
<div className="absolute inset-0 flex items-center justify-between p-4"> | |
<button | |
onClick={prev} | |
className="p-1 rounded-full shadow bg-white/80 text-gray-800 hover:bg-white" | |
> | |
<ChevronLeft size={40} /> | |
</button> | |
<button | |
onClick={next} | |
className="p-1 rounded-full shadow bg-white/80 text-gray-800 hover:bg-white" | |
> | |
<ChevronRight size={40} /> | |
</button> | |
</div> | |
<div className="absolute bottom-4 right-0 left-0"> | |
<div className="flex items-center justify-center gap-2"> | |
{slides.map((_, i) => ( | |
<div | |
className={` | |
transition-all w-3 h-3 bg-white rounded-full | |
${curr === i ? "p-2" : "bg-opacity-50"} | |
`} | |
/> | |
))} | |
</div> | |
</div> | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice