ShellUI Logo
ShellUI

Carousel

Image and content carousel with navigation controls

The Carousel component provides a slideshow interface for cycling through content. It supports autoplay, looping, arrow navigation, and dot indicators — all controlled via parameters (no sub-components).

Installation

shellui add carousel

Basic Usage

<Carousel TotalSlides="3"
          @bind-CurrentSlide="currentSlide"
          ShowArrows="true"
          ShowDots="true">
  @switch (currentSlide)
  {
    case 0:
      <div class="flex items-center justify-center h-full p-6">
        <h2 class="text-2xl font-bold">Slide 1</h2>
      </div>
      break;
    case 1:
      <div class="flex items-center justify-center h-full p-6">
        <h2 class="text-2xl font-bold">Slide 2</h2>
      </div>
      break;
    case 2:
      <div class="flex items-center justify-center h-full p-6">
        <h2 class="text-2xl font-bold">Slide 3</h2>
      </div>
      break;
  }
</Carousel>

@code {
    private int currentSlide = 0;
}
<Carousel TotalSlides="@images.Count"
          @bind-CurrentSlide="current"
          Loop="true"
          AspectRatio="16/9">
  <img src="@images[current].Src"
       alt="@images[current].Alt"
       class="w-full h-full object-cover" />
</Carousel>

@code {
    private int current = 0;

    private List<ImageItem> images = new()
    {
        new("/images/slide1.jpg", "Mountain landscape"),
        new("/images/slide2.jpg", "Ocean sunset"),
        new("/images/slide3.jpg", "Forest trail")
    };

    record ImageItem(string Src, string Alt);
}

Autoplay

Enable automatic slide transitions:

<Carousel TotalSlides="4"
          @bind-CurrentSlide="slide"
          AutoPlay="true"
          AutoPlayInterval="5000"
          Loop="true"
          ShowDots="true"
          ShowArrows="false">
  <div class="flex items-center justify-center h-full p-8">
    <p class="text-lg">Auto-playing slide @(slide + 1)</p>
  </div>
</Carousel>

@code {
    private int slide = 0;
}

Custom Arrow Styling

<Carousel TotalSlides="3"
          @bind-CurrentSlide="current"
          ArrowClass="bg-primary text-primary-foreground hover:bg-primary/90"
          Class="rounded-xl overflow-hidden border">
  @* Slide content *@
</Carousel>

Handling Slide Changes

<Carousel TotalSlides="@slides.Count"
          @bind-CurrentSlide="activeSlide"
          OnSlideChanged="HandleSlideChanged">
  <div class="p-6">
    <h3 class="font-bold">@slides[activeSlide].Title</h3>
    <p class="text-muted-foreground">@slides[activeSlide].Description</p>
  </div>
</Carousel>

<p class="text-sm mt-2">Viewed slide: @lastViewed</p>

@code {
    private int activeSlide = 0;
    private int lastViewed = 0;

    private List<SlideData> slides = new()
    {
        new("Welcome", "Get started with ShellUI"),
        new("Features", "80 production-ready components"),
        new("Charts", "New in v0.2.0")
    };

    private void HandleSlideChanged(int index)
    {
        lastViewed = index;
    }

    record SlideData(string Title, string Description);
}

API Reference

PropertyTypeDefaultDescription
ChildContentRenderFragment?nullSlide content
CurrentSlideint0Active slide index (0-based)
CurrentSlideChangedEventCallback<int>Two-way binding callback
TotalSlidesint0Total number of slides
ShowArrowsbooltrueShow previous/next arrow buttons
ShowDotsbooltrueShow dot indicators
LoopbooltrueLoop back to start after last slide
AutoPlayboolfalseEnable automatic transitions
AutoPlayIntervalint3000Milliseconds between auto-play transitions
AspectRatiostring"16/9"CSS aspect ratio for the carousel container
Classstring""Additional CSS classes for outer container
ArrowClassstring""Additional CSS classes for arrow buttons
OnSlideChangedEventCallback<int>Fired when slide changes (in addition to CurrentSlideChanged)

Accessibility

The Carousel component includes:

  • role="region" with aria-roledescription="carousel"
  • aria-label on each navigation control
  • Keyboard navigation with arrow keys
  • Autoplay pauses on hover and focus
  • Implements IAsyncDisposable for proper timer cleanup

On this page