@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
111 lines (110 loc) • 4.43 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { ExportNs } from '../../../esl-utils/environment/export-ns';
import { format } from '../../../esl-utils/misc/format';
import { attr, memoize, listen } from '../../../esl-utils/decorators';
import { ESLBaseElement } from '../../../esl-base-element/core';
import { indexToGroup } from '../../core/esl-carousel.utils';
import { ESLCarouselChangeEvent, ESLCarouselSlideEvent } from '../../core/esl-carousel.events';
/**
* {@link ESLCarousel} — Element for displaying dynamic textual information based on the carousel’s current state.
*
* Example:
* ```
* <esl-carousel-info format="Slide {current} of {total}"></esl-carousel-info>
* ```
*/
let ESLCarouselInfo = class ESLCarouselInfo extends ESLBaseElement {
/** Returns ESLCarousel instance based on `target` attr */
get $carousel() {
return this.$$find(this.carousel);
}
connectedCallback() {
super.connectedCallback();
this.update();
this.initA11y();
}
disconnectedCallback() {
super.disconnectedCallback();
memoize.clear(this, ['$carousel']);
}
attributeChangedCallback(name, oldValue, newValue) {
if (!this.connected)
return;
if (name === 'target') {
memoize.clear(this, ['$carousel']);
this.$$on(this._onSlideChange);
}
this.update();
}
/** Builds state object used for formatting */
get state() {
var _a;
if (!((_a = this.$carousel) === null || _a === void 0 ? void 0 : _a.renderer))
return {};
const { activeIndex, size, count } = this.$carousel.state;
const current = indexToGroup(activeIndex, count, size) + 1; // 1-based
const total = count ? Math.ceil(size / count) : 0;
const currentSlide = activeIndex + 1; // 1-based
const totalSlides = size;
const title = this.activeTitle;
const percent = total ? Math.round((current / total) * 100) : 0;
return { current, total, currentSlide, totalSlides, title, percent };
}
/** Title text for the active slide */
get activeTitle() {
var _a;
const $slide = (_a = this.$carousel) === null || _a === void 0 ? void 0 : _a.$activeSlide;
if (!$slide)
return '';
return ($slide.getAttribute('data-title') || $slide.getAttribute('title') || '').trim();
}
/** Updates rendered content according to format and current state */
update() {
if (!this.$carousel)
memoize.clear(this, '$carousel');
if (!this.$carousel)
return;
this.textContent = format(this.format, this.state);
}
/** Inits a11y of `ESLCarouselInfo` as a status container */
initA11y() {
if (!this.hasAttribute('role'))
this.$$attr('role', 'status');
if (!this.hasAttribute('aria-live'))
this.$$attr('aria-live', 'polite');
}
/** Handles carousel state changes */
_onSlideChange(e) {
if (this.$carousel === e.target)
this.update();
}
};
ESLCarouselInfo.is = 'esl-carousel-info';
ESLCarouselInfo.observedAttributes = ['format', 'target'];
__decorate([
attr({
name: 'target',
defaultValue: '::parent(.esl-carousel-nav-container)::find(esl-carousel)'
})
], ESLCarouselInfo.prototype, "carousel", void 0);
__decorate([
attr({ defaultValue: '{current} of {total}' })
], ESLCarouselInfo.prototype, "format", void 0);
__decorate([
memoize()
], ESLCarouselInfo.prototype, "$carousel", null);
__decorate([
listen({
event: `${ESLCarouselSlideEvent.AFTER} ${ESLCarouselChangeEvent.TYPE}`,
target: ($el) => $el.$carousel
})
], ESLCarouselInfo.prototype, "_onSlideChange", null);
ESLCarouselInfo = __decorate([
ExportNs('Carousel.Info')
], ESLCarouselInfo);
export { ESLCarouselInfo };