@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
107 lines (106 loc) • 4.49 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 { prop, memoize } from '../../esl-utils/decorators';
import { ESLCarouselRenderer } from '../core/esl-carousel.renderer';
import { ESLDefaultCarouselRenderer } from './esl-carousel.default.renderer';
/**
* {@link ESLDefaultCarouselRenderer} extension to render slides as a multi-row grid.
* Only 2 rows layout available for now.
* Supports vertical-carousel mode, touch-move, slide siblings rendering.
*
* Provides and relies on the slide width provided with CSS custom property from renderer itself.
* (CSS Grid-based layout does not allow to provide a slide width in CSS relatively based on the container width)
*/
let ESLGridCarouselRenderer = class ESLGridCarouselRenderer extends ESLDefaultCarouselRenderer {
/** Multiplier for the index move on the slide move */
get INDEX_MOVE_MULTIPLIER() {
return this.ROWS;
}
/** Count of fake slides to fill the last "row" or incomplete carousel state */
get fakeSlidesCount() {
const slidesLength = this.$carousel.$slides.length;
if (slidesLength === 0)
return 0;
if (slidesLength < this.count) {
return this.count - slidesLength;
}
return slidesLength % this.ROWS;
}
/**
* @returns fake slides collection
* @see ESLGridCarouselRenderer.fakeSlidesCount
*/
get $fakeSlides() {
const length = this.fakeSlidesCount;
if (length === 0)
return [];
return Array.from({ length }, this.buildFakeSlide.bind(this));
}
/** All slides including {@link ESLGridCarouselRenderer.$fakeSlides} slides created in grid mode */
get $slides() {
return (this.$carousel.$slides || []).concat(this.$fakeSlides);
}
/** creates fake slide element */
buildFakeSlide() {
const $slide = document.createElement('div');
$slide.setAttribute('esl-carousel-fake-slide', '');
return $slide;
}
/**
* Processes binding of defined renderer to the carousel {@link ESLCarousel}.
* Prepare to renderer animation.
*/
onBind() {
memoize.clear(this, '$fakeSlides');
this.$area.append(...this.$fakeSlides);
super.onBind();
}
/**
* Processes unbinding of defined renderer from the carousel {@link ESLCarousel}.
* Clear animation.
*/
onUnbind() {
this.$fakeSlides.forEach((el) => el.remove());
super.onUnbind();
}
/**
* Normalize actual active index to the first slide in the current dimension ('row')
*/
normalizeIndex(index, params) {
return super.normalizeIndex(index - (index % this.ROWS), params);
}
/**
* @returns count of slides to be rendered (reserved) before the first slide does not include fake slides
*/
getReserveCount(back) {
const reserve = super.getReserveCount(back);
return reserve - (reserve % this.ROWS);
}
/** Sets min size for slides */
resize() {
if (!this.$area)
return;
const areaStyles = getComputedStyle(this.$area);
this.gap = parseFloat(this.vertical ? areaStyles.rowGap : areaStyles.columnGap);
const areaSize = parseFloat(this.vertical ? areaStyles.height : areaStyles.width);
const count = Math.floor(this.count / this.ROWS);
const slideSize = Math.floor((areaSize - this.gap * (count - 1)) / count);
this.$area.style.setProperty(ESLDefaultCarouselRenderer.SIZE_PROP, slideSize + 'px');
}
};
ESLGridCarouselRenderer.is = 'grid';
ESLGridCarouselRenderer.classes = ['esl-carousel-grid-renderer'];
__decorate([
prop(2, { readonly: true })
], ESLGridCarouselRenderer.prototype, "ROWS", void 0);
__decorate([
memoize()
], ESLGridCarouselRenderer.prototype, "$fakeSlides", null);
ESLGridCarouselRenderer = __decorate([
ESLCarouselRenderer.register
], ESLGridCarouselRenderer);
export { ESLGridCarouselRenderer };