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.
JSXPine'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:
Default Carousel
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.
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function DefaultCarouselExample(props) {
const { slides } = props;
return <Carousel slides={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.
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function IndicatorsCarouselExample(props) {
const { slides } = props;
return (
<div class="flex flex-col gap-y-6">
<Carousel slides={slides} indicator />
<Carousel slides={slides} indicator="top" />
</div>
);
}
Carousel Direction
With direction props, you will be able to slide items from carousel horizontally (by default) or vertically !
Below an example of the design.
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function DirectionCarouselExample(props) {
const { slides } = props;
return (
<div class="flex flex-col gap-y-4">
<Carousel slides={slides} indicator="right" direction="vertical" />
</div>
);
}
Carousel Loop
Loop props allow to return to first element when item is last and vice-versa.
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function LoopCarouselExample(props) {
const { slides } = props;
return (
<div class="flex flex-col gap-y-6">
<Carousel slides={slides} loop />
<Carousel slides={slides} indicator="left" direction="vertical" loop />
</div>
);
}
Custom Slides
Default slot is for slides. Here is an example with our own image design.
Copied !
import { Carousel } from "$components/carousel.component";
import { Image } from "$components/image.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function CustomSlidesImageCarouselExample(props) {
const { slides } = props;
return (
<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 heading 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 heading harum dicta obcaecati aut nam sunt ipsum odit dolore doloribus iure nemo quasi, officia asperiores. Vero?
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: {color: string, text: string }[] }>}
*/
export function CustomSlidesCarouselExample(props) {
const { slides } = props;
return (
<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" safe>{item.text}</p>
</div>
))}
</Carousel>
);
}
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.
Copied !
import { Carousel, CarouselIndicators } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function DefaultCarouselExample(props) {
const { slides } = props;
return (
<Carousel
slides={slides}
indicators={
<CarouselIndicators>
{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>
}
loop
indicator
/>
);
}
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.
Copied !
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function MultipleSlidesWith2CarouselExample(props) {
const { slides } = props;
return <Carousel slides={slides} slidesToShow={2} />;
}
Copied !
import { InfoButton } from "$components/button.component";
import { Carousel } from "$components/carousel.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function MultipleSlidesWith3CarouselExample(props) {
const { slides } = props;
return (
<Carousel
slides={slides}
slidesToShow={3}
direction="vertical"
indicator="left"
navigations={
<div>
<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>
}
loop
/>
);
}
Copied !
import { Carousel } from "$components/carousel.component";
import { Image } from "$components/image.component";
/**
* @type {import("$common/props").JSXComponent<{ slides: import("$components/image.component").ImageType[] }>}
*/
export function MultipleCustomSlidesWith2CarouselExample(props) {
const { slides } = props;
return (
<Carousel slidesToShow={3} loop>
{slides.map((image) => (
<Image class="w-1/3 h-full" src={image.src} alt={image.alt} />
))}
</Carousel>
);
}