mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-22 12:15:43 +00:00
* feat(v4): update home page * fix * fix: cards * feat(v4): charts page * feat: update pages * feat: colors * fix * feat: add docs * feat: mdx work * fix * fix * fix: sidebar * fix: lint * feat: updates * feat: update components * feat: fix docs * fix: responsive * feat: implement cmdk * fix: update navigation menu demo * fix: code style * fix: themes * feat: implement blocks page * fix: docs config * refactor * fix: outputFileTracingIncludes * fix * fix: output * fix * fix: registry * refactor: move docs * debug: docs * debug * revert * fix: mjs * deps: pin fumadocs * debug * fix: downgrade next * fix: index page * refactor: move mdx components * fix: remove copy button * fix * was it zod * yes it was * remove copy page * fix: color page * fix: colors page * fix: meta colors * fix: copy button * feat: sync registry * fix: registry build script * feat: update port * feat: clean up examples * fix * fix: mobile nav * fix: blur for mobile * fix: sidebar nav * feat: update examples * fix: build scripts * feat: update components * feat: restyle * fix: types * fix: styles * fix: margins * fix: screenshots * fix * feat: update theme * fix: charts nav * fix: image * feat: optimize images * fix: menu * fix: card * fix: border * check * feat: implement charts page * fix: charts * fix: og images * feat: extend touch * fix: static * fix: sizing * fix: mobile screenshots * fix: page nav * fix * feat: update favicon * fix: theme selector * fix: feedback * fix: sink * docs: update * fix: styles * chore: update registry * fix: command * fix * fix: minor updates * fix: typography on smaller devices * fix: format * fix: remove unused icon * feat: update favicon * fix: typography * docs: typography page * fix: steps
302 lines
6.7 KiB
Plaintext
302 lines
6.7 KiB
Plaintext
---
|
|
title: Carousel
|
|
description: A carousel with motion and swipe built using Embla.
|
|
component: true
|
|
links:
|
|
doc: https://www.embla-carousel.com/get-started/react
|
|
api: https://www.embla-carousel.com/api
|
|
---
|
|
|
|
<ComponentPreview
|
|
name="carousel-demo"
|
|
title="Carousel"
|
|
description="A carousel with 5 items and a previous and next button."
|
|
/>
|
|
|
|
## About
|
|
|
|
The carousel component is built using the [Embla Carousel](https://www.embla-carousel.com/) library.
|
|
|
|
## Installation
|
|
|
|
<CodeTabs>
|
|
|
|
<TabsList>
|
|
<TabsTrigger value="cli">CLI</TabsTrigger>
|
|
<TabsTrigger value="manual">Manual</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="cli">
|
|
|
|
```bash
|
|
npx shadcn@latest add carousel
|
|
```
|
|
|
|
</TabsContent>
|
|
|
|
<TabsContent value="manual">
|
|
|
|
<Steps>
|
|
|
|
<Step>Install the following dependencies:</Step>
|
|
|
|
```bash
|
|
npm install embla-carousel-react
|
|
```
|
|
|
|
<Step>Copy and paste the following code into your project.</Step>
|
|
|
|
<ComponentSource name="carousel" title="components/ui/carousel.tsx" />
|
|
|
|
<Step>Update the import paths to match your project setup.</Step>
|
|
|
|
</Steps>
|
|
|
|
</TabsContent>
|
|
|
|
</CodeTabs>
|
|
|
|
## Usage
|
|
|
|
```tsx showLineNumbers
|
|
import {
|
|
Carousel,
|
|
CarouselContent,
|
|
CarouselItem,
|
|
CarouselNext,
|
|
CarouselPrevious,
|
|
} from "@/components/ui/carousel"
|
|
```
|
|
|
|
```tsx showLineNumbers
|
|
<Carousel>
|
|
<CarouselContent>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
</CarouselContent>
|
|
<CarouselPrevious />
|
|
<CarouselNext />
|
|
</Carousel>
|
|
```
|
|
|
|
## Examples
|
|
|
|
### Sizes
|
|
|
|
To set the size of the items, you can use the `basis` utility class on the `<CarouselItem />`.
|
|
|
|
<ComponentPreview
|
|
name="carousel-size"
|
|
title="Carousel"
|
|
description="A carousel with 3 active items of equal size."
|
|
/>
|
|
|
|
```tsx showLineNumbers {4-6}
|
|
// 33% of the carousel width.
|
|
<Carousel>
|
|
<CarouselContent>
|
|
<CarouselItem className="basis-1/3">...</CarouselItem>
|
|
<CarouselItem className="basis-1/3">...</CarouselItem>
|
|
<CarouselItem className="basis-1/3">...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
```tsx showLineNumbers {4-6}
|
|
// 50% on small screens and 33% on larger screens.
|
|
<Carousel>
|
|
<CarouselContent>
|
|
<CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
<CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
<CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
### Spacing
|
|
|
|
To set the spacing between the items, we use a `pl-[VALUE]` utility on the `<CarouselItem />` and a negative `-ml-[VALUE]` on the `<CarouselContent />`.
|
|
|
|
<Callout className="mt-6">
|
|
**Why:** I tried to use the `gap` property or a `grid` layout on the `
|
|
<CarouselContent />` but it required a lot of math and mental effort to get the
|
|
spacing right. I found `pl-[VALUE]` and `-ml-[VALUE]` utilities much easier to
|
|
use.
|
|
|
|
You can always adjust this in your own project if you need to.
|
|
|
|
</Callout>
|
|
|
|
<ComponentPreview
|
|
name="carousel-spacing"
|
|
title="Carousel"
|
|
description="A carousel with 3 items with a spacing of 1rem."
|
|
/>
|
|
|
|
```tsx showLineNumbers /-ml-4/ /pl-4/
|
|
<Carousel>
|
|
<CarouselContent className="-ml-4">
|
|
<CarouselItem className="pl-4">...</CarouselItem>
|
|
<CarouselItem className="pl-4">...</CarouselItem>
|
|
<CarouselItem className="pl-4">...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
```tsx showLineNumbers /-ml-2/ /pl-2/ /md:-ml-4/ /md:pl-4/
|
|
<Carousel>
|
|
<CarouselContent className="-ml-2 md:-ml-4">
|
|
<CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
|
|
<CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
|
|
<CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
### Orientation
|
|
|
|
Use the `orientation` prop to set the orientation of the carousel.
|
|
|
|
<ComponentPreview
|
|
name="carousel-orientation"
|
|
title="Carousel"
|
|
description="A vertical carousel."
|
|
/>
|
|
|
|
```tsx showLineNumbers /vertical | horizontal/
|
|
<Carousel orientation="vertical | horizontal">
|
|
<CarouselContent>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
## Options
|
|
|
|
You can pass options to the carousel using the `opts` prop. See the [Embla Carousel docs](https://www.embla-carousel.com/api/options/) for more information.
|
|
|
|
```tsx showLineNumbers {2-5}
|
|
<Carousel
|
|
opts={{
|
|
align: "start",
|
|
loop: true,
|
|
}}
|
|
>
|
|
<CarouselContent>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
```
|
|
|
|
## API
|
|
|
|
Use a state and the `setApi` props to get an instance of the carousel API.
|
|
|
|
<ComponentPreview
|
|
name="carousel-api"
|
|
title="Carousel"
|
|
description="A carousel with a slide counter."
|
|
/>
|
|
|
|
```tsx showLineNumbers {1,4,22}
|
|
import { type CarouselApi } from "@/components/ui/carousel"
|
|
|
|
export function Example() {
|
|
const [api, setApi] = React.useState<CarouselApi>()
|
|
const [current, setCurrent] = React.useState(0)
|
|
const [count, setCount] = React.useState(0)
|
|
|
|
React.useEffect(() => {
|
|
if (!api) {
|
|
return
|
|
}
|
|
|
|
setCount(api.scrollSnapList().length)
|
|
setCurrent(api.selectedScrollSnap() + 1)
|
|
|
|
api.on("select", () => {
|
|
setCurrent(api.selectedScrollSnap() + 1)
|
|
})
|
|
}, [api])
|
|
|
|
return (
|
|
<Carousel setApi={setApi}>
|
|
<CarouselContent>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
)
|
|
}
|
|
```
|
|
|
|
## Events
|
|
|
|
You can listen to events using the api instance from `setApi`.
|
|
|
|
```tsx showLineNumbers {1,4-14,16}
|
|
import { type CarouselApi } from "@/components/ui/carousel"
|
|
|
|
export function Example() {
|
|
const [api, setApi] = React.useState<CarouselApi>()
|
|
|
|
React.useEffect(() => {
|
|
if (!api) {
|
|
return
|
|
}
|
|
|
|
api.on("select", () => {
|
|
// Do something on select.
|
|
})
|
|
}, [api])
|
|
|
|
return (
|
|
<Carousel setApi={setApi}>
|
|
<CarouselContent>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
<CarouselItem>...</CarouselItem>
|
|
</CarouselContent>
|
|
</Carousel>
|
|
)
|
|
}
|
|
```
|
|
|
|
See the [Embla Carousel docs](https://www.embla-carousel.com/api/events/) for more information on using events.
|
|
|
|
## Plugins
|
|
|
|
You can use the `plugins` prop to add plugins to the carousel.
|
|
|
|
```ts showLineNumbers {1,6-10}
|
|
import Autoplay from "embla-carousel-autoplay"
|
|
|
|
export function Example() {
|
|
return (
|
|
<Carousel
|
|
plugins={[
|
|
Autoplay({
|
|
delay: 2000,
|
|
}),
|
|
]}
|
|
>
|
|
// ...
|
|
</Carousel>
|
|
)
|
|
}
|
|
```
|
|
|
|
<ComponentPreview
|
|
name="carousel-plugin"
|
|
title="Carousel"
|
|
description="A carousel with the autoplay plugin."
|
|
/>
|
|
|
|
See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/) for more information on using plugins.
|