gd-bs
Version:
Bootstrap JavaScript, TypeScript and Web Components library.
386 lines (385 loc) • 15.7 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Carousel = void 0;
var base_1 = require("../base");
var item_1 = require("./item");
var templates_1 = require("./templates");
/**
* Carousel
* @param props - The carousel properties.
*/
var _Carousel = /** @class */ (function (_super) {
__extends(_Carousel, _super);
// Constructor
function _Carousel(props, template, slideTemplate) {
if (template === void 0) { template = templates_1.HTML; }
var _this = _super.call(this, template, props) || this;
_this._eventId = null;
_this._indicators = null;
_this._pauseFlag = false;
_this._slides = null;
_this._toggle = false;
// Configure the carousel
_this.configure(slideTemplate);
// Configure the events
_this.configureEvents();
// Configure the parent
_this.configureParent();
return _this;
}
// Configure the card group
_Carousel.prototype.configure = function (slideTemplate) {
// Set the attributes
this.el.id = this.props.id == null ? "carousel" : this.props.id;
this.props.enableCrossfade ? this.el.classList.add("carousel-fade") : null;
// Render the indicators
this.renderIndicators();
// Render the controls
this.renderControls();
// Render the slides
this.renderSlides(slideTemplate);
// Set the dark theme
this.props.isDark ? this.setTheme(true) : null;
// Get the options
var options = this.props.options;
if (options) {
// See if the interval is set
if (options.interval) {
this.start(options.interval);
}
// See if the starting slide is set
if (options.slide) {
this.nextWhenVisible(options.slide);
}
}
// Call the event if it exists
this.props.onRendered ? this.props.onRendered(this.el, this.props) : null;
};
// Configures the events
_Carousel.prototype.configureEvents = function () {
var _this = this;
var el = this.el;
// Get the options
var options = this.props.options;
if (options) {
// See if the keyboard option is set
if (options.keyboard) {
// Add a keydown event
el.addEventListener("keydown", function (ev) {
// See if the left arrow was pressed
if (ev.code == "37") {
// Move to the previous slide
_this.previous();
}
// Else, see if the right arrow was pressed
else if (ev.code == "39") {
// Move tot he next slide
_this.next();
}
});
}
// See if the pause option is set
if (options.pause) {
// Set the mouse enter event
el.addEventListener("mouseenter", function () {
// See if automation exists
if (_this._eventId) {
// Pause the automation
_this.pause();
}
});
// Set the mouse exit event
el.addEventListener("mouseenter", function () {
// See if automation exists
if (_this._eventId) {
// Unpause the automation
_this.unpause();
}
});
}
}
};
// Moves to the another slides
_Carousel.prototype.moveToSlide = function (current, next, slideRight) {
var _this = this;
if (slideRight === void 0) { slideRight = true; }
// Do nothing if the toggle flag is set
if (this._toggle) {
return;
}
// Set the flag
this._toggle = true;
// Ensure the slides exist
if (current && next) {
// Animate the current slide out
next.el.classList.add(slideRight ? "carousel-item-next" : "carousel-item-prev");
current.el.classList.add(slideRight ? "carousel-item-start" : "carousel-item-end");
// Wait for the animation to complete
setTimeout(function () {
// Animate the next slide in
next.el.classList.add(slideRight ? "carousel-item-start" : "carousel-item-end");
// Wait for the animation to complete
setTimeout(function () {
// Update the classes
next.el.classList.add("active");
current.el.classList.remove("active", "carousel-item-start", "carousel-item-end");
next.el.classList.remove("carousel-item-next", "carousel-item-prev", "carousel-item-start", "carousel-item-end");
// Set the flag
_this._toggle = false;
}, 600);
}, 10);
}
};
// Renders the controls
_Carousel.prototype.renderControls = function () {
var _this = this;
// Get the controls
var nextControl = this.el.querySelector(".carousel-control-next");
var prevControl = this.el.querySelector(".carousel-control-prev");
// See if we are rendering controls
if (this.props.enableControls) {
// Configure the controls
nextControl ? nextControl.setAttribute("data-bs-target", "#" + this.el.id) : null;
prevControl ? prevControl.setAttribute("data-bs-target", "#" + this.el.id) : null;
// Set the click event
nextControl.addEventListener("click", function (ev) { ev.preventDefault(); _this.next(); });
prevControl.addEventListener("click", function (ev) { ev.preventDefault(); _this.previous(); });
}
else {
// Remove the controls
nextControl ? this.el.removeChild(nextControl) : null;
prevControl ? this.el.removeChild(prevControl) : null;
}
};
// Renders the indicators
_Carousel.prototype.renderIndicators = function () {
var _this = this;
// Clear the indicators
this._indicators = [];
// Get the indicators
var indicators = this.el.querySelector(".carousel-indicators");
if (indicators) {
// See if we are enabling indicators
if (this.props.enableIndicators) {
// Parse the items
var items = this.props.items || [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
// Create the item
var elItem = document.createElement("button");
elItem.setAttribute("data-bs-target", "#" + this.el.id);
elItem.setAttribute("aria-label", "Slide " + (i + 1));
elItem.setAttribute("data-bs-slide-to", i.toString());
item.isActive ? elItem.classList.add("active") : null;
elItem.addEventListener("click", function (ev) {
var elSlide = ev.currentTarget;
// Prevent the page from moving to the top
ev.preventDefault();
// Go to the slide
_this.nextWhenVisible(elSlide.getAttribute("data-bs-slide-to"));
});
// Add the item
indicators.appendChild(elItem);
this._indicators.push(elItem);
}
}
else {
// Remove the indicators
this.el.removeChild(indicators);
}
}
};
// Renders the slides
_Carousel.prototype.renderSlides = function (slideTemplate) {
// Clear the slides
this._slides = [];
// Get the indicators
var slides = this.el.querySelector(".carousel-inner");
if (slides) {
var hasActiveItem = false;
// Parse the items
var items = this.props.items || [];
for (var i = 0; i < items.length; i++) {
var slide = new item_1.CarouselItem(items[i], slideTemplate);
this._slides.push(slide);
// See if this is active
slide.isActive ? hasActiveItem = true : null;
// Create the item element
slides.appendChild(slide.el);
// Call the event
this.props.onSlideRendered ? this.props.onSlideRendered(slide.el, items[i]) : null;
}
// See if it doesn't have an active item
if (!hasActiveItem) {
// Set the first as active
var firstSlide = this._slides[0];
firstSlide ? firstSlide.el.classList.add("active") : null;
}
}
};
// Starts to move automatically
_Carousel.prototype.start = function (timeToWait) {
var _this = this;
if (timeToWait === void 0) { timeToWait = 5000; }
// Do nothing if the event already exists
if (this._eventId) {
return;
}
// Validate the time
if (timeToWait < 1000) {
timeToWait = 1000;
}
// Start the event
this._eventId = setInterval(function () {
// Do nothing if we have paused it
if (_this._pauseFlag) {
return;
}
// Move to the next slide
_this.next();
}, timeToWait);
};
/**
* Public Interface
*/
// Cycle the carousel
_Carousel.prototype.cycle = function () {
// Start the event
this.start(this.props.options && this.props.options.interval);
};
// Goes to the next slide
_Carousel.prototype.next = function () {
var currentSlide = null;
var nextSlide = null;
var options = this.props.options || {};
// Ensure there are multiple slides
if (this._slides.length < 2) {
return;
}
// Parse the slides
for (var i = 0; i < this._slides.length; i++) {
var slide = this._slides[i];
if (slide.isActive) {
// See if we are at the end and wrapping is disabled
if (i + 1 == this._slides.length && options.wrap == false) {
// Do nothing
return;
}
// Set the slides
currentSlide = slide;
nextSlide = this._slides[i + 1] || this._slides[0];
// Update the indicators
var indicator = this._indicators[i];
indicator ? indicator.classList.remove("active") : null;
var nextIndicator = this._indicators[i + 1] || this._indicators[0];
nextIndicator ? nextIndicator.classList.add("active") : null;
break;
}
}
// Move to the next slide
this.moveToSlide(currentSlide, nextSlide);
};
// Cycles the carousel to a particular frame
_Carousel.prototype.nextWhenVisible = function (idx) {
var currentSlide = null;
var nextSlide = this._slides[idx];
var slideRight = true;
// Ensure there are multiple slides
if (this._slides.length < 2) {
return;
}
// Parse the slides
for (var i = 0; i < this._slides.length; i++) {
var slide = this._slides[i];
// See if this slide is active
if (slide.isActive) {
// Do nothing if we selected the same slide
if (idx == i) {
return;
}
// Set the flag
slideRight = idx > i;
// Set the current slide
currentSlide = slide;
// Update the indicators
var indicator = this._indicators[i];
indicator ? indicator.classList.remove("active") : null;
var nextIndicator = this._indicators[idx];
nextIndicator ? nextIndicator.classList.add("active") : null;
break;
}
}
// Move to the next slide
this.moveToSlide(currentSlide, nextSlide, slideRight);
};
// Pauses the slide
_Carousel.prototype.pause = function () {
// Set the flag
this._pauseFlag = true;
};
// Goes to the previous slide
_Carousel.prototype.previous = function () {
var currentSlide = null;
var options = this.props.options || {};
var prevSlide = null;
// Ensure there are multiple slides
if (this._slides.length < 2) {
return;
}
// Parse the slides
for (var i = 0; i < this._slides.length; i++) {
var slide = this._slides[i];
if (slide.isActive) {
// See if we are at the end and wrapping is disabled
if (i - 1 < 0 && options.wrap == false) {
// Do nothing
return;
}
// Set the slides
currentSlide = slide;
prevSlide = this._slides[i - 1] || this._slides[this._slides.length - 1];
// Update the indicators
this._indicators[i].classList.remove("active");
(this._indicators[i - 1] || this._indicators[this._indicators.length - 1]).classList.add("active");
break;
}
}
// Move to the next slide
this.moveToSlide(currentSlide, prevSlide, false);
};
// Enables/Disables the dark theme
_Carousel.prototype.setTheme = function (isDark) {
// See if we are setting the dark theme
if (isDark) {
// Set the theme
this.el.classList.add("carousel-dark");
}
else {
// Set the theme
this.el.classList.remove("carousel-dark");
}
};
// Unpauses the carousel
_Carousel.prototype.unpause = function () {
// Set the flag
this._pauseFlag = false;
};
return _Carousel;
}(base_1.Base));
var Carousel = function (props, template, slideTemplate) { return new _Carousel(props, template, slideTemplate); };
exports.Carousel = Carousel;