Carousel

Overview

Carousel is a good way to show multiple contents in one place by alterning between them via a navigation-like. Best example is gallery photos from ecommerce product detail. AstroPine’s Carousel provide properties which will enabled you to deal with many customization cases. Here below are some examples of what you can achieved with this component:

By default, Carousel is aligned horizontally with navigation button in the middle and each one to the opposite side. Slides are images. We will see further that you can customize slides and put whatever contents you can.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel {slides} />

With Indicators

By setting indicator props to true, dot points will appeared at the bottom of the carousel. It displays the number of items the carousel contains. These are indicator props value: true, top, bottom (default value when true), left, right.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10
Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<div class="flex flex-col gap-y-6">
  <Carousel {slides} indicator />
  <Carousel {slides} indicator="top" />
</div>

With direction props, you will be able to slide items from carousel horizontally (by default) or vertically ! Below an example of the design.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<div class="flex flex-col gap-y-4">
  <Carousel {slides} indicator="right" direction="vertical" />
</div>

Loop

Loop props allow to return to first element when item is last and vice-versa.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10
Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import Carousel from "$components/carousel/Carousel.astro";
import type { CarouselExampleProps } from "$views/examples/carousel/props";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<div class="flex flex-col gap-y-6">
  <Carousel {slides} loop />
  <Carousel {slides} indicator="left" direction="vertical" loop />
</div>

Custom Slides

Default slot is for slides. Here is an example with our own image design.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";
import Image from "$components/image/Image.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel loop>
  {slides.map((image) => <Image src={image.src} alt={image.alt} />)}
</Carousel>

However, images are not the only slides you can put in carousel.

Be aware that it’s up to you to properly define your css class to have expected layout.

This is an example with just some section tag and dummy content inside as slides.

This is Slide 1

Lorem, ipsum dolor sit amet consectetur adipisicing elit. Doloremque voluptatem aliquid nam, quaerat eligendi quasi iste sed, placeat consequuntur enim ad quis tenetur praesentium impedit! Suscipit cumque natus ipsam earum.

This is Slide 2

Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis, perspiciatis.

This is Slide 3

Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum aliquid vel eligendi minus nesciunt rerum illo beatae eos dolor. Esse voluptatem excepturi eligendi ab rem, nam possimus sed sequi quaerat corrupti consequuntur molestias sint rerum repudiandae explicabo est necessitatibus non autem vitae hic illo officiis obcaecati asperiores maxime. Facere, eum?

This is Slide 4

Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus dolor dicta cumque nemo. Architecto quam odit obcaecati laboriosam sapiente inventore, dolorem iusto? Numquam velit sed minima culpa magni sapiente. Distinctio quas voluptatem sed dignissimos cumque id sequi ratione consequatur at, dicta iste repellat non! Quam quod totam aperiam magni repellat dolorum dolore mollitia illo, fugit qui possimus voluptatibus! Maiores eveniet consectetur voluptates nostrum magni doloribus in, ea autem itaque nam maxime minus necessitatibus illum ad?

This is Slide 5

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Veritatis magni, aperiam repellendus nisi itaque facere! Consequatur beatae voluptas reiciendis minus quidem inventore ea id harum dicta obcaecati aut nam sunt ipsum odit dolore doloribus iure nemo quasi, officia asperiores. Vero?

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel hideNavigations indicator>
  {
    slides.map((item, index) => (
      <div
        class={`min-w-full h-full flex flex-col gap-y-2 items-center p-2 md:p-6 ${item.color}`}
      >
        <h3>This is Slide {index + 1}</h3>
        <p class="text-sm flex items-start">{item.text}</p>
      </div>
    ))
  }
</Carousel>

Custom Navigations

Carousel allows you to customize navigations with slot which is name navigations. You will be able to use all alpine features bound to default navigations such as previous(), next() functions and disability. With this customization, you’ll have to deal with icons based on direction yourself. Below are some examples.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10
Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import InfoButton from "$components/button/info/InfoButton.astro";
import PrimaryButton from "$components/button/primary/PrimaryButton.astro";
import Carousel from "$components/carousel/Carousel.astro";
import Icon from "$components/icon/Icon.astro";
import type { CarouselExampleProps } from "$views/examples/carousel/props";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<div class="flex flex-col gap-y-4">
  <Carousel {slides} loop>
    <div slot="navigations">
      <PrimaryButton
        x-bind:disabled="!loop && areFirstSlidesToShow()"
        x-on:click="previous()"
        borderRadius="pill"
        class="absolute top-1/2 -translate-y-1/2 left-4"
      >
        <Icon name="arrow-left-line" size={6} fill="none" stroke="currentColor" />
      </PrimaryButton>
      <PrimaryButton
        x-bind:disabled="!loop && areLastSlidesToShow()"
        x-on:click="next()"
        borderRadius="pill"
        class="absolute top-1/2 -translate-y-1/2 right-4"
      >
        <Icon name="arrow-right-line" size={6} fill="none" stroke="currentColor" />
      </PrimaryButton>
    </div>
  </Carousel>

  <Carousel {slides} direction="vertical">
    <div slot="navigations">
      <InfoButton
        x-bind:disabled="!loop && areFirstSlidesToShow"
        x-on:click="previous()"
        borderRadius="pill"
        class="absolute left-1/2 -translate-x-1/2 top-4"
      >
        <span>Previous</span>
      </InfoButton>
      <InfoButton
        x-bind:disabled="!loop && areLastSlidesToShow"
        x-on:click="next()"
        borderRadius="pill"
        class="absolute left-1/2 -translate-x-1/2 bottom-4"
      >
        <span>Next</span>
      </InfoButton>
    </div>
  </Carousel>
</div>

Custom Indicators

Indicators can also be customize. Just set an html tag with slot name as indicators. As reminder, you’ll have to deal with indicators position based on direction yourself. Below an example with indicators as numbers.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";
import CarouselIndicators from "$components/carousel/CarouselIndicators.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel {slides} loop indicator>
  <CarouselIndicators indicator slot="indicators">
    {
      slides.map((image, index) => (
        <li>
          <button
            x-on:click={`setActiveIndex(Number(${index}))`}
            x-bind:disabled={`isActive(Number(${index}))`}
            class="cursor-pointer p-2 bg-white text-slate-700 disabled:bg-slate-900 disabled:text-white disabled:cursor-not-allowed"
          >
            <span>{index + 1}</span>
          </button>
        </li>
      ))
    }
  </CarouselIndicators>
</Carousel>

Multiple Slides

A great feature of carousel is to show multiple slides. Just set a number to slidesToShow props as shown in examples below. PS: For custom slides, it’s up to you to manage slide sizes.

Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel {slides} slidesToShow={2} />
Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import InfoButton from "$components/button/info/InfoButton.astro";
import Carousel from "$components/carousel/Carousel.astro";
import type { CarouselExampleProps } from "$views/examples/carousel/props";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel {slides} slidesToShow={3} direction="vertical" indicator="left" loop>
  <div slot="navigations">
    <InfoButton
      x-bind:disabled="!loop && areFirstSlidesToShow"
      x-on:click="previous()"
      borderRadius="pill"
      class="absolute left-1/2 -translate-x-1/2 top-4"
    >
      <span>Previous</span>
    </InfoButton>
    <InfoButton
      x-bind:disabled="!loop && areLastSlidesToShow"
      x-on:click="next()"
      borderRadius="pill"
      class="absolute left-1/2 -translate-x-1/2 bottom-4"
    >
      <span>Next</span>
    </InfoButton>
  </div>
</Carousel>
Photo of MountainsPhoto of Mountains 02Photo of Mountains 03Photo of Mountains 04Photo of Mountains 05Photo of Mountains 06Photo of Mountains 07Photo of Mountains 08Photo of Mountains 09Photo of Mountains 10

Copied !

---
import type { CarouselExampleProps } from "$views/examples/carousel/props";
import Carousel from "$components/carousel/Carousel.astro";
import Image from "$components/image/Image.astro";

type Props = CarouselExampleProps;
const { slides } = Astro.props;
---

<Carousel slidesToShow={3} loop>
  {
    slides.map((image) => (
      <Image class="w-1/3 h-full" src={image.src} alt={image.alt} />
    ))
  }
</Carousel>