Getting Started
Components66
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Code Block
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- Form
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Questionnaire
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Trace
1
2
3
4
5
import { Card, CardContent } from "@/components/ui/card"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
export function CarouselDemo() {
return (
<Carousel className="w-full max-w-48 sm:max-w-xs">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center">
<span className="text-4xl font-medium tabular-nums">
{index + 1}
</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
)
}About#
The carousel component is built using the Embla Carousel library. The previous and next controls are round raised keys (the secondary Button, icon-sm) with a 40px hit area.
Installation#
pnpm dlx shadcn@latest add https://ui.ikramhasan.com/r/carousel.json
Usage#
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"<Carousel>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Examples#
Sizes#
To set the size of the items, use the basis utility class on the <CarouselItem />.
1
2
3
4
5
import { Card, CardContent } from "@/components/ui/card"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
export function CarouselSize() {
return (
<Carousel
opts={{ align: "start" }}
className="w-full max-w-48 sm:max-w-xs md:max-w-sm"
>
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="basis-1/2 lg:basis-1/3">
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center">
<span className="text-3xl font-medium tabular-nums">
{index + 1}
</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
)
}Spacing#
To set the spacing between the items, use a pl-[VALUE] utility on the <CarouselItem /> and a negative -ml-[VALUE] on the <CarouselContent />.
1
2
3
4
5
import { Card, CardContent } from "@/components/ui/card"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
export function CarouselSpacing() {
return (
<Carousel className="w-full max-w-48 sm:max-w-xs md:max-w-sm">
<CarouselContent className="-ml-1">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="basis-1/2 pl-1 lg:basis-1/3">
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center">
<span className="text-2xl font-medium tabular-nums">
{index + 1}
</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
)
}Orientation#
Use the orientation prop to set the orientation of the carousel.
1
2
3
4
5
import { Card, CardContent } from "@/components/ui/card"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
export function CarouselOrientation() {
return (
<Carousel
opts={{ align: "start" }}
orientation="vertical"
className="my-12 w-full max-w-xs"
>
<CarouselContent className="-mt-1 h-[270px]">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="basis-1/2 pt-1">
<div className="p-1">
<Card>
<CardContent className="flex items-center justify-center">
<span className="text-3xl font-medium tabular-nums">
{index + 1}
</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
)
}API#
Use a state and the setApi prop to get an instance of the carousel API.
1
2
3
4
5
Slide 0 of 0
"use client"
import * as React from "react"
import { Card, CardContent } from "@/components/ui/card"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
type CarouselApi,
} from "@/components/ui/carousel"
export function CarouselApiDemo() {
const [api, setApi] = React.useState<CarouselApi>()
const [current, setCurrent] = React.useState(0)
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (!api) {
return
}
const onSelect = () => {
setCount(api.scrollSnapList().length)
setCurrent(api.selectedScrollSnap() + 1)
}
onSelect()
api.on("select", onSelect)
api.on("reInit", onSelect)
return () => {
api.off("select", onSelect)
api.off("reInit", onSelect)
}
}, [api])
return (
<div className="mx-auto max-w-40 sm:max-w-xs">
<Carousel setApi={setApi} className="w-full max-w-xs">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<Card className="m-px">
<CardContent className="flex aspect-square items-center justify-center">
<span className="text-4xl font-medium tabular-nums">
{index + 1}
</span>
</CardContent>
</Card>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<div className="py-2 text-center text-sm text-muted-foreground tabular-nums">
Slide {current} of {count}
</div>
</div>
)
}Options#
Pass options to the carousel with the opts prop. See the Embla Carousel docs for more information.
<Carousel
opts={{
align: "start",
loop: true,
}}
>
...
</Carousel>Plugins#
Use the plugins prop to add plugins to the carousel.
import Autoplay from "embla-carousel-autoplay"
export function Example() {
return <Carousel plugins={[Autoplay({ delay: 2000 })]}>// ...</Carousel>
}See the Embla Carousel docs for more information on using plugins.
API Reference#
| Part | Props / notes |
|---|---|
Carousel | opts, plugins, orientation (horizontal · vertical), setApi. Left and right arrow keys move between slides. |
CarouselContent | The Embla viewport and its track. |
CarouselItem | One slide. Size it with basis-*. |
CarouselPrevious | A Button, secondary icon-sm by default, with all Button props. |
CarouselNext | The same, for the next slide. |
useCarousel | Returns api, scrollPrev, scrollNext, canScrollPrev and canScrollNext inside a Carousel. |