Slider / Carousel Images in LWC

by Rijwan Mohmmed
slider-carousel-images-in-lwc

Hello friends, today we are going to discuss Slider / Carousel Images in LWC. Sliders and carousels have become popular ways to display images and content in an interactive way. Salesforce Lightning Web Components (LWC) make it easy to create slider/carousel components that can be used in Salesforce applications.

Also, check this: Expandable/Collapsible Sections in Lightning Screen Flow

Key Highlights :

  1. An image carousel is a container (slideshow) of images or info that users can select by clicking a button that directs them forward or backward in the slideshow.
  2. An image carousel makes a website more interactive by enhancing the user experience.
  3. The collection of images can be automatically changed using a timer or manually when the user clicks the displayed buttons.
  4. We create sliders by core javascript and CSS.

Code :

First, we create an LWC child component with sliders functionality.

LWCSliders.HTML :

<template>
	<div class="slds-is-relative container" style={maxWidth}>
		<template for:each={slidesData} for:item="slide">
			<a href={slide.link} key={slide.index} class={slide.slideClass} onmouseover={handleMouseOver}
				onmouseout={handleMouseOut}>
				<img src={slide.image} alt={slide.description} style={maxHeight} />
				<div if:false={hideSlideText} class="text-section slds-p-around_medium">
					<h3 class="slds-text-heading_large">{slide.heading}</h3>
					<div class="slds-text-heading_small">{slide.description}</div>
				</div>
			</a>
		</template>
		<a if:false={hideNavigationButtons} class="prev" onclick={slideBackward}>&#10094;</a>
		<a if:false={hideNavigationButtons} class="next" onclick={slideForward}>&#10095;</a>
	</div>
	<div if:false={hideNavigationDots} class="slds-text-align_center slds-p-around_medium">
		<template for:each={slidesData} for:item="slide">
			<span key={slide.index} class={slide.dotClass} data-id={slide.index} onclick={showSlide}></span>
		</template>
	</div>
</template>

LWCSliders.JS :

import { LightningElement, api } from 'lwc';

export default class LWCSliders extends LightningElement {

    @api autoScroll = false;
    @api customHeight = '500px';
    @api customWidth = '100%';
    @api hideNavigationButtons = false;
    @api hideNavigationDots = false;
    @api hideSlideNumber = false;
    @api hideSlideText = false;
    @api scrollDuration = 3000;

    slides = [];
    slideIndex = 1;
    timer;

    get maxWidth() {
        return `width: ${this.customWidth}`;
    }

    get maxHeight() {
        return `height: ${this.customHeight}; width:100%`;
    }

    @api
    get slidesData() {
        return this.slides;
    }

    set slidesData(data) {
        this.slides = data.map((slide, i) => {
            if (i === 0) {
                return {
                    ...slide,
                    index: i + 1,
                    slideClass: 'fade slds-show',
                    dotClass: 'dot active'
                };
            }
            return {
                ...slide,
                index: i + 1,
                slideClass: 'fade slds-hide',
                dotClass: 'dot'
            };
        });
    }

    connectedCallback() {
        if (this.autoScroll) {
            this.timer = window.setInterval(() => {
                this.handleSlideSelection(this.slideIndex + 1);
            }, Number(this.scrollDuration));
        }
    }

    handleMouseOver() {
        if (this.autoScroll) {
            window.clearInterval(this.timer);
        }
    }

    handleMouseOut() {
        if (this.autoScroll) {
            this.timer = window.setInterval(() => {
                this.handleSlideSelection(this.slideIndex + 1);
            }, Number(this.scrollDuration));
        }
    }

    disconnectedCallback() {
        if (this.autoScroll) {
            window.clearInterval(this.timer);
        }
    }

    showSlide(event) {
        const slideIndex = Number(event.target.dataset.id);
        this.handleSlideSelection(slideIndex);
    }

    slideBackward() {
        const slideIndex = this.slideIndex - 1;
        this.handleSlideSelection(slideIndex);
    }

    slideForward() {
        const slideIndex = this.slideIndex + 1;
        this.handleSlideSelection(slideIndex);
    }

    handleSlideSelection(index) {
        if (index > this.slides.length) {
            this.slideIndex = 1;
        } else if (index < 1) {
            this.slideIndex = this.slides.length;
        } else {
            this.slideIndex = index;
        }

        this.slides = this.slides.map((slide) => {
            if (this.slideIndex === slide.index) {
                return {
                    ...slide,
                    slideClass: 'fade slds-show',
                    dotClass: 'dot active'
                };
            }
            return {
                ...slide,
                slideClass: 'fade slds-hide',
                dotClass: 'dot'
            };
        });
    }
}

LWCSliders.CSS :

.container {
  margin: auto;
}

.text-section {
  position: absolute;
  color: #f2f2f2;
  font-size: 15px;
  bottom: 0px;
  width: 100%;
  text-align: center;
  background-color: rgba(0, 0, 0, 0.7);
}

a {
  text-decoration: none;
}

.prev,
.next {
  position: absolute;
  top: 50%;
  width: auto;
  padding: 16px;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  border-radius: 0 3px 3px 0;
}

.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

.slideNumbers {
  font-size: 12px;
  position: absolute;
  padding: 8px 12px;
  top: 0;
  color: #f2f2f2;
}

.dot {
  height: 15px;
  width: 15px;
  border-radius: 50%;
  cursor: pointer;
  background-color: #bbb;
  margin: 0 2px;
  display: inline-block;
}

.active,
.dot:hover {
  background-color: #717171;
}

.fade {
  animation-name: fade;
  animation-duration: 1.5s;
}

@keyframes fade {
  from {
    opacity: 0.4;
  }
  to {
    opacity: 1;
  }
}

@keyframes autoplay3 {
  0% {margin-top: 10em}
  4% {margin-top: 0em}
  31% {margin-top: 0em}
  35% {margin-top: -10em}
  64% {margin-top: -10em}
  68% {margin-top: -20em}
  96% {margin-top: -20em}
  100% {margin-top: -30em}
}

Now we create a parent component and we pass images and other parameters.

LWCParentSliders.HTML :

<template>
	<c-l-w-c-sliders slides-data={sliderData} custom-height="500px" custom-width="100%" auto-scroll={autoScroll}
		hide-slide-text hide-slide-number></c-l-w-c-sliders>
</template>

LWCParentSliders.JS :

import { LightningElement } from 'lwc';

export default class LWCParentSliders extends LightningElement {
    slider1Image = 'https://images.unsplash.com/photo-1500382017468-9049fed747ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80';
    slider1Link = '#';
    slider2Image = 'https://store-images.s-microsoft.com/image/apps.32256.14224494707314076.8116b5ee-01ee-49e4-827c-bc6739343224.90a3690d-d956-4e1a-a673-1871117b442a?mode=scale&q=90&h=720&w=1280';
    slider2Link = '#';
    slider3Image = 'https://www.virginexperiencedays.co.uk/content/img/product/large/the-view-from-the-12102928.jpg';
    slider3Link = '#';
    slider4Image = 'https://t-ec.bstatic.com/images/hotel/max1024x768/169/169160530.jpg';
    slider4Link = '#';
    autoScroll = true;

    get sliderData() {
        return [{
            "image": this.slider1Image,
            "link": this.slider1Link,
            "heading": "",
            "description": "",
        },
        {
            "image": this.slider2Image,
            "link": this.slider2Link,
            "heading": "",
            "description": "",
        },
        {
            "image": this.slider3Image,
            "link": this.slider3Link,
            "heading": "",
            "description": "",
        },
        {
            "image": this.slider4Image,
            "link": this.slider4Link,
            "heading": "",
            "description": "",
        },
        ]
    }
}

lWCParentSliders.js-meta.xml :

<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
	<apiVersion>57.0</apiVersion>
	<isExposed>true</isExposed>
	<targets>
		<target>lightning__HomePage</target>
	</targets>
</LightningComponentBundle>

Output :

Reference :

  1. LWC
What’s your Reaction?
+1
5
+1
3
+1
0
+1
0
+1
0
+1
1

You may also like

Leave a Comment