Carousel

Media

Image and content carousel with navigation arrows.

Preview

Slide 1
Slide 2
Slide 3

Usage

example.jsx
import { Carousel } from "@/components/ui/carousel";

export default function Example() {
  return <Carousel />;
}

Source Code

Copy this file into components/ui/carousel.jsx in your project.

carousel.jsx
"use client";

import { forwardRef, useState } from "react";
import { cn } from "@/lib/utils";

const Carousel = forwardRef(({ className, items = [], ...props }, ref) => {
  const [current, setCurrent] = useState(0);
  const prev = () => setCurrent((c) => (c === 0 ? items.length - 1 : c - 1));
  const next = () => setCurrent((c) => (c === items.length - 1 ? 0 : c + 1));

  return (
    <div ref={ref} className={cn("relative overflow-hidden rounded-lg", className)} {...props}>
      <div className="flex transition-transform duration-300" style={{ transform: `translateX(-${current * 100}%)` }}>
        {items.map((item, i) => (
          <div key={i} className="w-full shrink-0">{item}</div>
        ))}
      </div>
      <button onClick={prev} className="absolute left-2 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-background/80 shadow-md backdrop-blur-sm hover:bg-background">
        <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" /></svg>
      </button>
      <button onClick={next} className="absolute right-2 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full bg-background/80 shadow-md backdrop-blur-sm hover:bg-background">
        <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /></svg>
      </button>
      <div className="absolute bottom-3 left-1/2 flex -translate-x-1/2 gap-1.5">
        {items.map((_, i) => (
          <button key={i} onClick={() => setCurrent(i)} className={cn("h-2 w-2 rounded-full transition-all", i === current ? "bg-white w-6" : "bg-white/50")} />
        ))}
      </div>
    </div>
  );
});
Carousel.displayName = "Carousel";

export { Carousel };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge