Carousel
Um carrossel com animação e gesto de arrastar construído com Embla.
"use client";
import { Card, CardContent } from "@blips/ui/components/card";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@blips/ui/components/carousel";
export default function CarouselDemo() {
return (
<Carousel className="w-full 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 p-6">
<span className="text-4xl font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
Sobre
O componente de carrossel é construído utilizando a biblioteca Embla Carousel.
Instalação
Uso
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@blips/ui/components/carousel"<Carousel>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Exemplos
Tamanhos
Para definir o tamanho dos itens, use a classe utilitária basis no <CarouselItem />.
import { Card, CardContent } from "@blips/ui/components/card";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@blips/ui/components/carousel";
import * as React from "react";
export default function CarouselSize() {
return (
<Carousel
opts={{
align: "start",
}}
className="w-full max-w-sm"
>
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="md:basis-1/2 lg:basis-1/3">
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-3xl font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
Espaçamento
Para definir o espaçamento entre os itens, use a classe pl-[VALOR] no <CarouselItem /> e um -ml-[VALOR] negativo no <CarouselContent />.
import { Card, CardContent } from "@blips/ui/components/card";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@blips/ui/components/carousel";
import * as React from "react";
export default function CarouselSpacing() {
return (
<Carousel className="w-full max-w-sm">
<CarouselContent className="-ml-1">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="pl-1 md:basis-1/2 lg:basis-1/3">
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-2xl font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
Orientação
Use a prop orientation para definir a orientação do carrossel.
import { Card, CardContent } from "@blips/ui/components/card";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@blips/ui/components/carousel";
import * as React from "react";
export default function CarouselOrientation() {
return (
<Carousel
opts={{
align: "start",
}}
orientation="vertical"
className="w-full max-w-xs"
>
<CarouselContent className="-mt-1 h-[200px]">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="pt-1 md:basis-1/2">
<div className="p-1">
<Card>
<CardContent className="flex items-center justify-center p-6">
<span className="text-3xl font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
Opções
Você pode passar opções para o carrossel usando a prop opts. Veja a documentação do Embla Carousel para mais informações.
<Carousel
opts={{
align: "start",
loop: true,
}}
>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
</Carousel>API
Use um state e a prop setApi para obter uma instância da API do carrossel.
import { type CarouselApi } from "@blips/ui/components/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>
)
}Eventos
Você pode escutar eventos usando a instância da api obtida de setApi.
import { type CarouselApi } from "@blips/ui/components/carousel"
export function Example() {
const [api, setApi] = React.useState<CarouselApi>()
React.useEffect(() => {
if (!api) {
return
}
api.on("select", () => {
// Faça algo ao selecionar.
})
}, [api])
return (
<Carousel setApi={setApi}>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
</Carousel>
)
}Veja a documentação do Embla Carousel para mais informações sobre o uso de eventos.
Plugins
Você pode usar a prop plugins para adicionar plugins ao carrossel.
import Autoplay from "embla-carousel-autoplay"
export function Example() {
return (
<Carousel
plugins={[
Autoplay({
delay: 2000,
}),
]}
>
// ...
</Carousel>
)
}Referência da API
Veja a documentação do Embla Carousel para mais informações sobre props e plugins.