šŸ‡®šŸ‡³
šŸ‡®šŸ‡³
Republic Day Special Offer!Get 20% OFF on all courses
Enroll Now
P
Prakalpana
šŸ“šLearn
•Code Your Future
System Designā±ļø 14 min readšŸ“… Dec 26

UI System Design: Build Image Carousel/Slider

RM
Rohan Mehta•UI Lead at Amazon
šŸ“‘ Contents (6 sections)

šŸ“ŒProblem Statement

Build an image carousel like Instagram stories or product galleries.

šŸ“ŒRequirements

  • Swipe/touch support
  • Keyboard navigation
  • Auto-play option
  • Lazy loading
  • Thumbnails
  • Responsive
  • šŸ“ŒCore Implementation

    const Carousel = ({ images, autoPlay = false, interval = 3000 }) => {
    const [currentIndex, setCurrentIndex] = useState(0);
    const [isPlaying, setIsPlaying] = useState(autoPlay);
    const touchStartX = useRef(0);
    const touchEndX = useRef(0);
    useEffect(() => {
    if (!isPlaying) return;
    const timer = setInterval(() => {
    setCurrentIndex(prev => (prev + 1) % images.length);
    }, interval);
    return () => clearInterval(timer);
    }, [isPlaying, images.length, interval]);
    const goTo = (index) => {
    setCurrentIndex(index);
    setIsPlaying(false);
    };
    const next = () => goTo((currentIndex + 1) % images.length);
    const prev = () => goTo((currentIndex - 1 + images.length) % images.length);
    const handleTouchStart = (e) => {
    touchStartX.current = e.touches[0].clientX;
    };
    const handleTouchEnd = (e) => {
    touchEndX.current = e.changedTouches[0].clientX;
    const diff = touchStartX.current - touchEndX.current;
    if (Math.abs(diff) > 50) {
    diff > 0 ? next() : prev();
    }
    };
    return (
    <div
    className="carousel"
    onTouchStart={handleTouchStart}
    onTouchEnd={handleTouchEnd}
    onKeyDown={handleKeyDown}
    tabIndex={0}
    >
    <div
    className="carousel-track"
    style={{ transform: `translateX(-${currentIndex * 100}%)` }}
    >
    {images.map((img, index) => (
    <img
    key={index}
    src={img.src}
    alt={img.alt}
    loading={Math.abs(index - currentIndex) <= 1 ? 'eager' : 'lazy'}
    />
    ))}
    </div>
    <button onClick={prev} className="carousel-btn prev">‹</button>
    <button onClick={next} className="carousel-btn next">›</button>
    <div className="carousel-dots">
    {images.map((_, index) => (
    <button
    key={index}
    onClick={() => goTo(index)}
    className={`dot ${index === currentIndex ? 'active' : ''}`}
    />
    ))}
    </div>
    </div>
    );
    };

    šŸ“ŒCSS for Smooth Transitions

    .carousel {
    position: relative;
    overflow: hidden;
    }
    .carousel-track {
    display: flex;
    transition: transform 0.3s ease-out;
    }
    .carousel-track img {
    flex-shrink: 0;
    width: 100%;
    object-fit: cover;
    }

    šŸ“ŒKeyboard Navigation

    const handleKeyDown = (e) => {
    switch (e.key) {
    case 'ArrowLeft':
    prev();
    break;
    case 'ArrowRight':
    next();
    break;
    case ' ':
    e.preventDefault();
    setIsPlaying(prev => !prev);
    break;
    }
    };

    šŸ“ŒAccessibility

  • Use role="region" with aria-label
  • aria-live="polite" for announcements
  • Focus management
  • Pause on hover/focus
  • Asked at Amazon, Flipkart, and e-commerce companies.

    RM

    Written by

    Rohan Mehta

    UI Lead at Amazon

    šŸš€ Master System Design

    Join 500+ developers

    Explore Courses →
    Chat on WhatsApp