A flexible component for displaying images or content in a horizontally scrollable, swipe-friendly slider.
embla-carousel-react
lucide-react1import * as React from 'react'
2
3import { Card, CardContent } from '@/components/ui/card'
4import {
5 Carousel,
6 CarouselContent,
7 CarouselItem,
8 CarouselNext,
9 CarouselPrevious,
10} from '@/components/ui/carousel'
11
12export function CarouselDemo() {
13 return (
14 <Carousel className="w-full max-w-xs">
15 <CarouselContent>
16 {Array.from({ length: 5 }).map((_, index) => (
17 <CarouselItem key={index}>
18 <div className="p-1">
19 <Card>
20 <CardContent className="flex aspect-square items-center justify-center p-6">
21 <span className="text-4xl font-semibold">
22 {index + 1}
23 </span>
24 </CardContent>
25 </Card>
26 </div>
27 </CarouselItem>
28 ))}
29 </CarouselContent>
30 <CarouselPrevious />
31 <CarouselNext />
32 </Carousel>
33 )
34}
35Install the following dependencies:
1import * as React from 'react'
2
3import { Card, CardContent } from '@/components/ui/card'
4import {
5 Carousel,
6 CarouselContent,
7 CarouselItem,
8 CarouselNext,
9 CarouselPrevious,
10} from '@/components/ui/carousel'
11
12export function CarouselOrientation() {
13 return (
14 <Carousel
15 opts={{
16 align: 'start',
17 }}
18 orientation="vertical"
19 className="w-full max-w-xs"
20 >
21 <CarouselContent className="-mt-1 h-[200px]">
22 {Array.from({ length: 5 }).map((_, index) => (
23 <CarouselItem key={index} className="pt-1 md:basis-1/2">
24 <div className="p-1">
25 <Card>
26 <CardContent className="flex min-h-[110px] min-w-[300px] items-center justify-center p-6">
27 <span className="text-3xl font-semibold">
28 {index + 1}
29 </span>
30 </CardContent>
31 </Card>
32 </div>
33 </CarouselItem>
34 ))}
35 </CarouselContent>
36 <CarouselPrevious />
37 <CarouselNext />
38 </Carousel>
39 )
40}
411import * as React from 'react'
2
3import { Card, CardContent } from '@/components/ui/card'
4import {
5 Carousel,
6 CarouselContent,
7 CarouselItem,
8 CarouselNext,
9 CarouselPrevious,
10} from '@/components/ui/carousel'
11
12export function CarouselSize() {
13 return (
14 <Carousel
15 opts={{
16 align: 'start',
17 }}
18 className="w-full max-w-sm"
19 >
20 <CarouselContent>
21 {Array.from({ length: 5 }).map((_, index) => (
22 <CarouselItem
23 key={index}
24 className="basis-1/2 md:basis-1/3 lg:basis-1/4"
25 >
26 <div className="p-1">
27 <Card>
28 <CardContent className="flex items-center justify-center p-2 md:p-6 lg:p-6">
29 <span className="text-3xl font-semibold">
30 {index + 1}
31 </span>
32 </CardContent>
33 </Card>
34 </div>
35 </CarouselItem>
36 ))}
37 </CarouselContent>
38 <CarouselPrevious />
39 <CarouselNext />
40 </Carousel>
41 )
42}
431import * as React from 'react'
2
3import { Card, CardContent } from '@/components/ui/card'
4import {
5 Carousel,
6 CarouselContent,
7 CarouselItem,
8 CarouselNext,
9 CarouselPrevious,
10} from '@/components/ui/carousel'
11
12export function CarouselSpacing() {
13 return (
14 <Carousel className="w-full max-w-sm">
15 <CarouselContent className="-ml-4">
16 {Array.from({ length: 5 }).map((_, index) => (
17 <CarouselItem
18 key={index}
19 className="pl-4 md:basis-1/2 lg:basis-1/3"
20 >
21 <div className="p-1">
22 <Card>
23 <CardContent className="flex aspect-square items-center justify-center p-2">
24 <span className="text-2xl font-semibold">
25 {index + 1}
26 </span>
27 </CardContent>
28 </Card>
29 </div>
30 </CarouselItem>
31 ))}
32 </CarouselContent>
33 <CarouselPrevious />
34 <CarouselNext />
35 </Carousel>
36 )
37}
381'use client'
2
3import * as React from 'react'
4import { toast } from 'sonner'
5
6import { Card, CardContent } from '@/components/ui/card'
7import {
8 Carousel,
9 type CarouselApi,
10 CarouselContent,
11 CarouselItem,
12 CarouselNext,
13 CarouselPrevious,
14} from '@/components/ui/carousel'
15
16export function CarouselApi() {
17 const [api, setApi] = React.useState<CarouselApi>()
18 const [current, setCurrent] = React.useState(0)
19 const [count, setCount] = React.useState(0)
20
21 React.useEffect(() => {
22 if (!api) {
23 return
24 }
25
26 setCount(api.scrollSnapList().length)
27 setCurrent(api.selectedScrollSnap() + 1)
28
29 api.on('select', () => {
30 setCurrent(api.selectedScrollSnap() + 1)
31 toast(`Slide changed to ${api.selectedScrollSnap() + 1}`)
32 })
33 }, [api])
34
35 return (
36 <div>
37 <Carousel setApi={setApi} className="w-full max-w-xs">
38 <CarouselContent>
39 {Array.from({ length: 5 }).map((_, index) => (
40 <CarouselItem key={index}>
41 <div className="p-1">
42 <Card>
43 <CardContent className="flex aspect-square items-center justify-center p-6">
44 <span className="text-4xl font-semibold">
45 {index + 1}
46 </span>
47 </CardContent>
48 </Card>
49 </div>
50 </CarouselItem>
51 ))}
52 </CarouselContent>
53 <CarouselPrevious />
54 <CarouselNext />
55 </Carousel>
56 <div className="text-muted-foreground py-2 text-center text-sm">
57 Slide {current} of {count}
58 </div>
59 </div>
60 )
61}
62





1'use client'
2
3import * as React from 'react'
4import Image from 'next/image'
5import Autoplay from 'embla-carousel-autoplay'
6
7import { Card, CardContent } from '@/components/ui/card'
8import {
9 Carousel,
10 CarouselContent,
11 CarouselItem,
12 CarouselNext,
13 CarouselPrevious,
14} from '@/components/ui/carousel'
15
16const imagesData = [
17 {
18 src: '/images/random-image/random-1.jpg',
19 alt: 'Random 1',
20 },
21 {
22 src: '/images/random-image/random-2.jpg',
23 alt: 'Random 2',
24 },
25 {
26 src: '/images/random-image/random-3.jpg',
27 alt: 'Random 3',
28 },
29 {
30 src: '/images/random-image/random-4.jpg',
31 alt: 'Random 4',
32 },
33 {
34 src: '/images/random-image/random-5.jpg',
35 alt: 'Random 5',
36 },
37 {
38 src: '/images/random-image/random-6.jpg',
39 alt: 'Random 6',
40 },
41]
42
43export function CarouselAutoplay() {
44 const plugin = React.useRef(
45 Autoplay({ delay: 1000, stopOnInteraction: true }),
46 )
47
48 return (
49 <Carousel
50 plugins={[plugin.current]}
51 className="w-full max-w-xs"
52 onMouseEnter={plugin.current.stop}
53 onMouseLeave={plugin.current.reset}
54 >
55 <CarouselContent>
56 {imagesData.map((_, index) => (
57 <CarouselItem key={index}>
58 <div className="p-1">
59 <Card>
60 <CardContent className="flex aspect-square items-center justify-center p-6">
61 <Image
62 src={imagesData[index].src}
63 alt={imagesData[index].alt}
64 width={200}
65 height={150}
66 className="object-cover"
67 />
68 </CardContent>
69 </Card>
70 </div>
71 </CarouselItem>
72 ))}
73 </CarouselContent>
74 <CarouselPrevious />
75 <CarouselNext />
76 </Carousel>
77 )
78}
79| Prop | Type | Default |
|---|---|---|
| opts | CarouselOptions | - |
| plugins | CarouselPlugin | - |
| orientation | horizontal,vertical | horizontal |
| setApi | (api: CarouselApi) => void | - |
| children | React.ReactNode | - |
| Prop | Type | Default |
|---|---|---|
| variant | Button variant | outline |
| size | Button size | icon |
| Prop | Type | Default |
|---|---|---|
| variant | Button variant | outline |
| size | Button size | icon |