JSFiddle - React, Tailwind, and code Playground

by thelevicole

HTML

<div class="carousel-container">
  <div class="carousel">
    <img data-src="https://picsum.photos/100/300" />
    <img data-src="https://picsum.photos/200/300" />
    <img data-src="https://picsum.photos/300/300" />
    <img data-src="https://picsum.photos/400/300" />
    <img data-src="https://picsum.photos/500/300" />
  </div>
  <button class="carousel-prev">
    &#10094;
  </button>
  <button class="carousel-next">
    &#10095;
  </button>
</div>

CSS

/* Container styles */
.carousel-container {}

/* Hide all carousel slides by default */
.carousel-container .carousel > * {
  display: none;
}

/* Only show the active carousel slide */
.carousel-container .carousel > *.active {
  display: block;
}

JavaScript

class CarouselController {

    defaultSettings = {
        loop: true,
        delay: 5000,
        autoplay: true
    }

    /**
     * @param {object} settings
     */
    constructor(settings) {
        this.carousel = settings.element;
        delete settings.element;

        this.current = 0;
        this.hooks = {};
        this.settings = settings;

        if (!this.carousel) {
            throw 'A carousel element is required. For example: new CarouselController({ element: document.getElementById(\'carousel\') })';
        }

        /**
         * Sanitize `loop` setting
         */
        this.addFilter('setting.loop', value => {
            return String(value).toLowerCase() === 'true';
        });

        /**
         * Sanitize `delay` setting
         */
        this.addFilter('setting.delay', value => parseInt(value));

        /**
         * Sanitize `autoplay` setting
         */
        this.addFilter('setting.autoplay', value => {
            return String(value).toLowerCase() === 'true';
        });

        // Autoplay on init.
        if (this.getSetting('autoplay')) {
            this.play();
        }
    }

    /**
     * Get the carousel container element.
     * @returns {Element}
     */
    getCarousel() {
        return this.carousel;
    }

    /**
     * Get a setting value.
     * @param {string} name
     * @param defaultValue
     * @returns {*}
     */
    getSetting(name, defaultValue) {
        if (!defaultValue && name in this.defaultSettings) {
            defaultValue = this.defaultSettings[name]
        }

        /**
         * Apply value filters.
         * @example carousel.addFilter('setting.delay', function(value) { return value + 500; });
         */
        return this.applyFilters(`setting.${name}`, name in this.settings ? this.settings[name] : defaultValue);
    }

    /**
     * Get hooks by type and name. Ordered by priority.
     * @param {string} type
     * @param {string} name
     * @returns {array}
...