Carousel
A slideshow component for cycling through a series of content panels with previous/next controls.
When to use
- Image galleries displaying a collection of photos or media.
- Product showcases highlighting multiple items in limited space.
- Testimonial sliders rotating customer quotes.
- Onboarding flows stepping through feature introductions.
When NOT to use
- For content that must be visible at all times — use a grid or list.
- For critical navigation — users may miss items they never scroll to.
- For single-item display — use a card or hero section.
Import
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from '@mihcm/ui/Carousel';Basic usage
<Carousel>
<CarouselContent>
<CarouselItem>Slide 1</CarouselItem>
<CarouselItem>Slide 2</CarouselItem>
<CarouselItem>Slide 3</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Vertical orientation
Pass orientation="vertical" to scroll vertically. Constrain the height on CarouselContent.
<Carousel orientation="vertical">
<CarouselContent className="h-[200px]">
<CarouselItem>…</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Multiple items per view
Control how many items are visible by setting a basis-* class on each CarouselItem.
<CarouselItem className="basis-1/3">…</CarouselItem>Use responsive basis classes for production layouts:
<CarouselItem className="basis-full sm:basis-1/2 lg:basis-1/3">…</CarouselItem>Porsche-style step carousel
For a carousel like the Porsche configurator reference, combine these pieces:
- Use a visible heading and a short description outside the scroll track.
- Use
opts={{ align: 'start', loop: true }}when the carousel should rewind. - Use responsive
basis-*classes to control visible slide count per breakpoint. - Add container padding around the carousel to reveal part of the next or previous slide.
- Use
useCarousel()to build pagination dots or progress indicators. - Keep pagination buttons real
<button>elements witharia-labelandaria-current.
<section aria-labelledby="workflow-carousel-heading">
<h2 id="workflow-carousel-heading">Related workflows</h2>
<Carousel opts={{ align: 'start', loop: true }} aria-label="Related workflows">
<CarouselContent>
{workflows.map((workflow) => (
<CarouselItem key={workflow.title} className="basis-full sm:basis-1/2 lg:basis-1/3">
<WorkflowCard {...workflow} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
<CarouselPagination />
</Carousel>
</section>Composition
- Wrap slides in
CarouselContent, each in aCarouselItem. PlaceCarouselPrevious/CarouselNextoutside the content. - Use
basis-1/NonCarouselItemto show multiple items per view. - Pass
opts={{ loop: true }}to enable infinite cycling. Without it, buttons disable at the edges. - Pass
opts={{ align: 'start' }}for card rails andopts={{ align: 'center' }}for hero-like galleries. - Use
useCarousel()for pagination, counters, selected slide state, and custom controls. orientation="vertical"requires a constrained height onCarouselContent.
Related
- ScrollArea — free-scroll containers without prev/next controls.
- Tabs — switching between distinct content panels.