Carousel
Componente para exibir conteúdo em sequência com navegação por setas. Baseado em Embla Carousel.
Múltiplos slides visíveis
Slides menores exibidos em grupo — usa basis fracionado para definir quantos aparecem por vez.
Mentorias
Financeiro
Agenda
Relatórios
Metas
Equipe
2 ou 3 slides visíveis
<Carousel opts={{ align: "start" }}>
<CarouselContent viewportClassName="overflow-visible" className="-ml-4">
{items.map((item) => (
<CarouselItem key={item} className="pl-4 basis-1/2 md:basis-1/3 shrink-0">
<div className="aspect-square rounded-[10px] bg-white shadow-[var(--shadow-card)]">
{/* conteúdo */}
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Loop infinito
Com opts={{ loop: true }} o carrossel reinicia automaticamente ao chegar no último slide.
Jan
Fev
Mar
Abr
Mai
Jun
Loop habilitado
<Carousel opts={{ align: "start", loop: true }}>
<CarouselContent viewportClassName="overflow-visible" className="-ml-4">
{items.map((item) => (
<CarouselItem key={item} className="pl-4 basis-[520px] shrink-0">
<div className="aspect-square rounded-[10px] bg-white shadow-[var(--shadow-card)]" />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Cards de conteúdo
Slides com estrutura de card real — badge, título, descrição e ação.
Mentorados ativos
Acompanhe o progresso com métricas em tempo real.
Ver mais →
Receita do mês
Visão consolidada de entradas e metas atingidas.
Ver mais →
Próximas sessões
Sessões agendadas para os próximos 7 dias.
Ver mais →
NPS da semana
Satisfação dos mentorados nas últimas avaliações.
Ver mais →
Card com badge, título e descrição
<CarouselItem className="pl-4 basis-[340px] shrink-0">
<div className="flex h-full flex-col justify-between rounded-[10px] bg-white p-[30px] shadow-[var(--shadow-card)]">
<div>
<span className="mb-3 inline-block rounded-full bg-muted px-3 py-1 text-xs font-semibold">
Badge
</span>
<h3 className="mb-2 text-base font-semibold">Título do card</h3>
<p className="text-sm text-muted-foreground">Descrição do conteúdo.</p>
</div>
<p className="mt-6 text-sm font-medium text-primary">Ver mais →</p>
</div>
</CarouselItem>Orientação vertical
Carousel com scroll vertical — útil para listas de itens em painéis laterais.
Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Carousel vertical
<Carousel orientation="vertical" opts={{ align: "start" }}>
<CarouselContent className="-mt-4 h-[560px]">
{items.map((item) => (
<CarouselItem key={item} className="pt-4 basis-full">
<div className="flex h-full items-center justify-center rounded-[10px] bg-white" />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Padrão de implementação
Snippets para os usos mais comuns do Carousel no projeto.
Carousel básico
<Carousel className="w-full max-w-xl">
<CarouselContent>
<CarouselItem>
<img src="/slide-1.jpg" alt="Slide 1" />
</CarouselItem>
<CarouselItem>
<img src="/slide-2.jpg" alt="Slide 2" />
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Com autoplay (plugin)
"use client"
import Autoplay from "embla-carousel-autoplay"
import { useRef } from "react"
export function CarouselAutoplay() {
const plugin = useRef(Autoplay({ delay: 3000 }))
return (
<Carousel plugins={[plugin.current]}>
<CarouselContent>...</CarouselContent>
</Carousel>
)
}Acesso à API do carousel
"use client"
import { useState } from "react"
import { type CarouselApi } from "@/components/ui/carousel"
export function CarouselControlled() {
const [api, setApi] = useState<CarouselApi>()
return (
<Carousel setApi={setApi}>
<CarouselContent>...</CarouselContent>
</Carousel>
)
}Props e uso
API dos sub-componentes do Carousel.
Props principais
orientation
"horizontal" | "vertical"
Direção do scroll. Padrão: horizontal.
opts
EmblaOptionsType
Opções do Embla Carousel (loop, align, etc).
plugins
EmblaPluginType[]
Plugins do Embla (autoplay, autoScroll, etc).
setApi
(api: CarouselApi) => void
Callback para acessar a API do carousel para controle externo.
CarouselItem basis
className: basis-*
Largura do slide via Tailwind. Ex: basis-1/2 para 2 slides visíveis.
Acessibilidade
O Embla Carousel não inclui atributos ARIA automaticamente. Para carousels de conteúdo importante, adicione role="region" e aria-label no container.
Os botões CarouselPrevious e CarouselNext têm textos sr-only embutidos ("Previous slide" / "Next slide").
Para carousels com autoplay, sempre forneça um controle de pause acessível.
MN Design System · Primary #5FC318 · Brand Green #AFF000 · Font: Inter