rt-tab-carousel
Version:
Angular tab carousel component
614 lines (602 loc) • 32.9 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Directive, Input, Output, HostListener, Component, ChangeDetectionStrategy, NgModule } from '@angular/core';
import { BehaviorSubject, combineLatest, interval, Subscription, fromEvent, Observable } from 'rxjs';
import { map, distinctUntilChanged, first, debounceTime, startWith, filter } from 'rxjs/operators';
import { CommonModule, NgOptimizedImage } from '@angular/common';
class RtCarouselService {
_isLastTabVisible$;
_isFirstTabVisible$;
_scrollStep$ = new BehaviorSubject({});
_items = new BehaviorSubject({});
_currentSliderShift$ = new BehaviorSubject({});
_lastVisibleIndexEnd$ = new BehaviorSubject({});
_lastVisibleIndex$ = new BehaviorSubject({});
_selectedIndex = new BehaviorSubject({});
_activeClassTab = new BehaviorSubject({});
constructor() {
this._isFirstTabVisible$ = this._lastVisibleIndex$.asObservable().pipe(map(v => {
const res = {};
for (const key of Object.keys(v)) {
res[key] = v[key] === 0;
}
return res;
}));
this._isLastTabVisible$ = combineLatest([this._lastVisibleIndexEnd$.asObservable(), this._items.asObservable()]).pipe(map(([v, length]) => {
const res = {};
for (const key of Object.keys(v)) {
res[key] = v[key] === length[key]?.length - 1;
}
return res;
}));
}
setTab(related, value) {
const currValue = this._items.value;
this._items.next({
...currValue,
[related]: currValue[related]?.length ? [...currValue[related], value] : [value],
});
}
deleteTab(uuidCarousel, el) {
const currValue = this._items.value;
const index = currValue[uuidCarousel].findIndex(v => v === el);
if (index !== -1) {
currValue[uuidCarousel].splice(index, 1);
this._items.next(currValue);
}
}
amountTabs(related) {
return this._items.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]?.length));
}
tabs(related) {
return this._items.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
isFirstTabVisible(related) {
return this._isFirstTabVisible$.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
isLastTabVisible(related) {
return this._isLastTabVisible$.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
currentSliderShift(related) {
return this._currentSliderShift$.asObservable().pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
lastVisibleIndexEnd(related) {
return this._lastVisibleIndexEnd$.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
lastVisibleIndex(related) {
return this._lastVisibleIndex$.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
nextPart(related) {
if (!this._lastVisibleIndex$.value[related]) {
this._lastVisibleIndex$.next({ ...this._lastVisibleIndex$.value, [related]: 0 });
}
const scrollStep = this._scrollStep$.value[related];
const amount = this._items.value[related];
const nextStep = this._lastVisibleIndexEnd$.value[related] + scrollStep > amount?.length - 1
? amount?.length - 1
: this._lastVisibleIndexEnd$.value[related] + scrollStep;
this._items.value[related][nextStep]?.nativeElement.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'end',
});
this._currentSliderShift$.next({
...this._currentSliderShift$.value,
[related]: nextStep,
});
}
previousPart(related) {
if (this._lastVisibleIndex$.value[related] - this._scrollStep$.value[related] >= 0) {
this._currentSliderShift$.next({
...this._currentSliderShift$.value,
[related]: this._lastVisibleIndex$.value[related] - this._scrollStep$.value[related],
});
this._items.value[related][this._lastVisibleIndex$.value[related] - this._scrollStep$.value[related]].nativeElement.scrollIntoView({
behavior: 'smooth',
inline: 'start',
block: 'nearest',
});
}
else {
this._currentSliderShift$.next({
...this._currentSliderShift$.value,
[related]: 0,
});
this._items.value[related][0].nativeElement.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start',
});
}
}
setLastVisibleIndex(related, value) {
const currValue = this._lastVisibleIndex$.value;
this._lastVisibleIndex$.next({ ...currValue, [related]: value });
}
setLastVisibleIndexEnd(related, value) {
const currValue = this._lastVisibleIndexEnd$.value;
this._lastVisibleIndexEnd$.next({ ...currValue, [related]: value });
}
setScrollStep(related, value) {
const currValue = this._scrollStep$.value;
this._scrollStep$.next({ ...currValue, [related]: value });
}
selectTab(related, index) {
if (isNaN(+index)) {
return;
}
if (this._items.value?.[related]?.[+index]) {
this.applyActiveClassForTab(related, this._items.value[related][+index]);
const currentValues = this._selectedIndex.value;
this._selectedIndex.next({ ...currentValues, [related]: +index });
const el = this._items.value[related][+index].nativeElement;
el.scrollIntoView({ inline: 'nearest', block: 'nearest', behavior: 'smooth' });
}
else {
const className = this._activeClassTab.value[related];
const selectedIndexPreview = this._selectedIndex.value?.[related];
if (selectedIndexPreview) {
this._items.value?.[related]?.[selectedIndexPreview]?.nativeElement.classList.remove(className);
}
}
}
selectHTMLElement(related, el) {
this.applyActiveClassForTab(related, el);
const currentValues = this._selectedIndex.value;
const index = this._items.value[related].findIndex(v => v === el);
this._selectedIndex.next({ ...currentValues, [related]: index });
interval(10).pipe(first()).subscribe({
next: () => el.nativeElement.scrollIntoView({ inline: 'nearest', block: 'nearest', behavior: 'smooth' }),
});
}
selectedTab(related) {
return this._selectedIndex.pipe(distinctUntilChanged((prev, curr) => prev[related] === curr[related]), map(v => v[related]));
}
setActiveClassTab(related, className) {
const currValue = this._activeClassTab.value;
this._activeClassTab.next({ ...currValue, [related]: className });
}
destroyCarousel(related) {
this._items.value[related] = [];
this._selectedIndex.value[related] = null;
this._activeClassTab.value[related] = null;
this._scrollStep$.value[related] = null;
this._currentSliderShift$.value[related] = null;
this._lastVisibleIndexEnd$.value[related] = null;
this._lastVisibleIndex$.value[related] = null;
}
applyActiveClassForTab(related, el) {
const className = this._activeClassTab.value[related];
const selectedIndexPreview = this._selectedIndex.value[related];
if (selectedIndexPreview >= 0) {
this._items.value[related][selectedIndexPreview]?.nativeElement.classList.remove(className);
}
el.nativeElement.classList.add(className);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselService, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
class RtCarouselNextButtonDirective {
el;
renderer;
service;
activeClass;
autoHide = true;
uuidCarousel;
buttonHidden = new EventEmitter();
subscription = new Subscription();
constructor(el, renderer, service) {
this.el = el;
this.renderer = renderer;
this.service = service;
}
onClick() {
this.service.nextPart(this.uuidCarousel);
}
ngOnInit() {
this.subscription.add(this.service.isLastTabVisible(this.uuidCarousel).subscribe({
next: v => {
if (v) {
if (this.activeClass) {
this.renderer.removeClass(this.el.nativeElement, this.activeClass);
}
}
else if (v !== undefined) {
if (this.activeClass) {
this.renderer.addClass(this.el.nativeElement, this.activeClass);
}
}
},
}));
if (this.autoHide) {
this.subscription.add(combineLatest([
this.service.isFirstTabVisible(this.uuidCarousel).pipe(map(v => v || v === undefined)),
this.service.isLastTabVisible(this.uuidCarousel).pipe(map(v => v || v === undefined)),
])
.pipe(map(([first, last]) => first && last))
.subscribe({
next: v => {
this.renderer.setStyle(this.el.nativeElement, 'display', v ? 'none' : 'flex');
this.buttonHidden.emit(v);
},
}));
}
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselNextButtonDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: RtCarouselService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselNextButtonDirective, selector: "[rtCarouselNextButton]", inputs: { activeClass: "activeClass", autoHide: "autoHide", uuidCarousel: "uuidCarousel" }, outputs: { buttonHidden: "buttonHidden" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselNextButtonDirective, decorators: [{
type: Directive,
args: [{
selector: '[rtCarouselNextButton]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: RtCarouselService }]; }, propDecorators: { activeClass: [{
type: Input
}], autoHide: [{
type: Input
}], uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], buttonHidden: [{
type: Output
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
class RtCarouselNextButtonComponent {
uuidCarousel;
autoHide = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselNextButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselNextButtonComponent, selector: "rt-tab-carousel-next-button", inputs: { uuidCarousel: "uuidCarousel", autoHide: "autoHide" }, ngImport: i0, template: "<div\n rtCarouselNextButton\n [uuidCarousel]=\"uuidCarousel\"\n [activeClass]=\"'rt-carousel__shadow-right-array'\"\n [autoHide]=\"autoHide\"\n class=\"rt-carousel__next-part\"\n>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 16.58L13.3266 12L9 7.41L10.332 6L16 12L10.332 18L9 16.58Z\" fill=\"#777777\"/>\n </svg>\n\n</div>\n", styles: [".rt-carousel__shadow-right-array{box-shadow:-12px 0 12px -10px #000000b5;border-left:solid .3px;border-image:linear-gradient(to bottom,transparent,#b6b6b6,rgba(0,0,0,0)) 0 100%;align-items:center;display:flex;cursor:pointer;height:100%;width:35px}.rt-carousel__next-part{cursor:pointer;width:35px;align-items:center;display:flex;z-index:1;height:100%;transition:box-shadow .3s}\n"], dependencies: [{ kind: "directive", type: RtCarouselNextButtonDirective, selector: "[rtCarouselNextButton]", inputs: ["activeClass", "autoHide", "uuidCarousel"], outputs: ["buttonHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselNextButtonComponent, decorators: [{
type: Component,
args: [{ selector: 'rt-tab-carousel-next-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n rtCarouselNextButton\n [uuidCarousel]=\"uuidCarousel\"\n [activeClass]=\"'rt-carousel__shadow-right-array'\"\n [autoHide]=\"autoHide\"\n class=\"rt-carousel__next-part\"\n>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 16.58L13.3266 12L9 7.41L10.332 6L16 12L10.332 18L9 16.58Z\" fill=\"#777777\"/>\n </svg>\n\n</div>\n", styles: [".rt-carousel__shadow-right-array{box-shadow:-12px 0 12px -10px #000000b5;border-left:solid .3px;border-image:linear-gradient(to bottom,transparent,#b6b6b6,rgba(0,0,0,0)) 0 100%;align-items:center;display:flex;cursor:pointer;height:100%;width:35px}.rt-carousel__next-part{cursor:pointer;width:35px;align-items:center;display:flex;z-index:1;height:100%;transition:box-shadow .3s}\n"] }]
}], propDecorators: { uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], autoHide: [{
type: Input
}] } });
class RtCarouselPreviousButtonDirective {
el;
renderer;
service;
activeClass;
autoHide = true;
uuidCarousel;
buttonHidden = new EventEmitter();
subscription = new Subscription();
constructor(el, renderer, service) {
this.el = el;
this.renderer = renderer;
this.service = service;
}
onClick() {
this.service.previousPart(this.uuidCarousel);
}
ngOnInit() {
this.subscription.add(this.service.isFirstTabVisible(this.uuidCarousel).subscribe({
next: v => {
if (v) {
if (this.activeClass) {
this.renderer.removeClass(this.el.nativeElement, this.activeClass);
}
}
else if (v !== undefined) {
if (this.activeClass) {
this.renderer.addClass(this.el.nativeElement, this.activeClass);
}
}
},
}));
if (this.autoHide) {
this.subscription.add(combineLatest([
this.service.isFirstTabVisible(this.uuidCarousel).pipe(map(v => v || v === undefined)),
this.service.isLastTabVisible(this.uuidCarousel).pipe(map(v => v || v === undefined)),
])
.pipe(map(([first, last]) => first && last))
.subscribe({
next: v => {
this.renderer.setStyle(this.el.nativeElement, 'display', v ? 'none' : 'flex');
this.buttonHidden.emit(v);
},
}));
}
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselPreviousButtonDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: RtCarouselService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselPreviousButtonDirective, selector: "[rtCarouselPreviousButton]", inputs: { activeClass: "activeClass", autoHide: "autoHide", uuidCarousel: "uuidCarousel" }, outputs: { buttonHidden: "buttonHidden" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselPreviousButtonDirective, decorators: [{
type: Directive,
args: [{
selector: '[rtCarouselPreviousButton]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: RtCarouselService }]; }, propDecorators: { activeClass: [{
type: Input
}], autoHide: [{
type: Input
}], uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], buttonHidden: [{
type: Output
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
class RtCarouselPreviousButtonComponent {
uuidCarousel;
autoHide = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselPreviousButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselPreviousButtonComponent, selector: "rt-tab-carousel-previous-button", inputs: { uuidCarousel: "uuidCarousel", autoHide: "autoHide" }, ngImport: i0, template: " <div\n rtCarouselPreviousButton\n [uuidCarousel]=\"uuidCarousel\"\n [autoHide]=\"autoHide\"\n [activeClass]=\"'rt-carousel__shadow-left-array'\"\n class=\"rt-carousel__next-part\"\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 16.58L10.6734 12L15 7.41L13.668 6L8 12L13.668 18L15 16.58Z\" fill=\"#777777\"/>\n </svg>\n\n\n </div>\n", styles: [".rt-carousel__next-part{cursor:pointer;display:flex;z-index:1;height:100%;transition:box-shadow .3s;width:35px;align-items:center;justify-content:center}.rt-carousel__shadow-left-array{box-shadow:10px 0 10px -10px #000000b5;border-right:solid .3px;border-image:linear-gradient(to bottom,transparent,#878787,rgba(0,0,0,0)) 0 100%;z-index:11;height:100%;width:35px;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: RtCarouselPreviousButtonDirective, selector: "[rtCarouselPreviousButton]", inputs: ["activeClass", "autoHide", "uuidCarousel"], outputs: ["buttonHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselPreviousButtonComponent, decorators: [{
type: Component,
args: [{ selector: 'rt-tab-carousel-previous-button', changeDetection: ChangeDetectionStrategy.OnPush, template: " <div\n rtCarouselPreviousButton\n [uuidCarousel]=\"uuidCarousel\"\n [autoHide]=\"autoHide\"\n [activeClass]=\"'rt-carousel__shadow-left-array'\"\n class=\"rt-carousel__next-part\"\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 16.58L10.6734 12L15 7.41L13.668 6L8 12L13.668 18L15 16.58Z\" fill=\"#777777\"/>\n </svg>\n\n\n </div>\n", styles: [".rt-carousel__next-part{cursor:pointer;display:flex;z-index:1;height:100%;transition:box-shadow .3s;width:35px;align-items:center;justify-content:center}.rt-carousel__shadow-left-array{box-shadow:10px 0 10px -10px #000000b5;border-right:solid .3px;border-image:linear-gradient(to bottom,transparent,#878787,rgba(0,0,0,0)) 0 100%;z-index:11;height:100%;width:35px;align-items:center;justify-content:center}\n"] }]
}], propDecorators: { uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], autoHide: [{
type: Input
}] } });
class RtCarouselContainerDirective {
el;
renderer;
service;
cd;
scrollStep = 1;
uuidCarousel;
activeClass;
antiBounce = 5;
subscription = new Subscription();
firstDebounce = 1500;
constructor(el, renderer, service, cd) {
this.el = el;
this.renderer = renderer;
this.service = service;
this.cd = cd;
}
_selectedTab;
set selectedTab(value) {
this._selectedTab = value;
this.service.amountTabs(this.uuidCarousel).pipe(debounceTime(this.firstDebounce), first()).subscribe({
next: () => {
this.firstDebounce = 0;
this.service.selectTab(this.uuidCarousel, value);
},
});
}
ngOnInit() {
this.renderer.setStyle(this.el.nativeElement, 'display', 'flex');
this.renderer.setStyle(this.el.nativeElement, 'overflow', 'auto');
this.renderer.setStyle(this.el.nativeElement, 'z-index', '10');
this.renderer.setStyle(this.el.nativeElement, 'padding', '0 2px');
this.renderer.setStyle(this.el.nativeElement, 'align-items', 'center');
this.renderer.setStyle(this.el.nativeElement, 'gap', '6px');
this.renderer.setStyle(this.el.nativeElement, 'scrollbar-width', 'none');
this.renderer.addClass(this.el.nativeElement, 'rt-tab-carousel-container');
this.subscription.add(this.service.amountTabs(this.uuidCarousel)
.pipe(debounceTime(10))
.subscribe({
next: () => this.cd.detectChanges(),
}));
}
ngAfterViewInit() {
if (this.activeClass) {
this.service.setActiveClassTab(this.uuidCarousel, this.activeClass);
}
this.service.setScrollStep(this.uuidCarousel, this.scrollStep);
const style = this.renderer.createElement('style');
this.renderer.appendChild(this.el.nativeElement, style);
style.innerHTML = `::-webkit-scrollbar { width: 0; height: 0 }`;
this.service.amountTabs(this.uuidCarousel).pipe(debounceTime(1000), first()).subscribe({
next: () => {
this.initIndexes();
},
});
const resize$ = fromEvent(window, 'resize').pipe(startWith(null));
const scroll$ = fromEvent(this.el.nativeElement, 'scroll').pipe(startWith(null));
const mutationObserver$ = this.createMutationObserverObservable(this.el.nativeElement).pipe(startWith(null));
this.subscription.add(combineLatest([resize$, scroll$, mutationObserver$]).subscribe({
next: () => {
const currentItems = document.querySelectorAll(`.rt-carousel-tab-${this.uuidCarousel}`);
const scrollLeft = this.el.nativeElement.scrollLeft;
for (let i = 0; i < currentItems.length; i++) {
const child = currentItems[i];
if (child.offsetLeft - scrollLeft - this.el.nativeElement.offsetLeft + this.antiBounce >= 0) {
this.service.setLastVisibleIndex(this.uuidCarousel, i);
break;
}
}
for (let i = currentItems.length - 1; i >= 0; i--) {
const child = currentItems[i];
if (this.el.nativeElement.offsetLeft + this.el.nativeElement.offsetWidth >=
child.offsetLeft + child.offsetWidth - this.el.nativeElement.scrollLeft - this.antiBounce) {
this.service.setLastVisibleIndexEnd(this.uuidCarousel, i);
break;
}
}
},
}));
this.cd.detectChanges();
}
initIndexes() {
this.service
.tabs(this.uuidCarousel)
.pipe(filter(items => items && !!items.length), first())
.subscribe({
next: tabs => {
const currentItems = document.querySelectorAll(`.rt-carousel-tab-${this.uuidCarousel}`);
const scrollLeft = this.el.nativeElement.scrollLeft;
const firstTab = tabs[0].nativeElement;
const offsetLeft = firstTab.offsetLeft;
if (offsetLeft >= scrollLeft) {
this.service.setLastVisibleIndex(this.uuidCarousel, 0);
}
for (let i = currentItems.length - 1; i >= 0; i--) {
const child = currentItems[i];
if (this.el.nativeElement.offsetLeft + this.el.nativeElement.offsetWidth >=
child.offsetLeft + child.offsetWidth - this.el.nativeElement.scrollLeft - this.antiBounce) {
this.service.setLastVisibleIndexEnd(this.uuidCarousel, i);
break;
}
}
},
});
}
ngOnDestroy() {
const tabs = document.querySelectorAll(`.rt-carousel-tab-${this.uuidCarousel}`);
tabs.forEach(tab => {
tab.removeEventListener('scroll', () => {
});
tab.removeEventListener('click', () => {
});
});
this.service.destroyCarousel(this.uuidCarousel);
this.subscription.unsubscribe();
}
createMutationObserverObservable(target) {
return new Observable(observer => {
const observerInstance = new MutationObserver(mutationsList => {
observer.next(mutationsList);
});
observerInstance.observe(target, {
childList: true,
subtree: true,
});
return () => {
observerInstance.disconnect();
};
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselContainerDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: RtCarouselService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselContainerDirective, selector: "[rtCarouselContainer]", inputs: { scrollStep: "scrollStep", uuidCarousel: "uuidCarousel", activeClass: "activeClass", antiBounce: "antiBounce", selectedTab: "selectedTab" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselContainerDirective, decorators: [{
type: Directive,
args: [{
selector: '[rtCarouselContainer]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: RtCarouselService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { scrollStep: [{
type: Input
}], uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], activeClass: [{
type: Input
}], antiBounce: [{
type: Input
}], selectedTab: [{
type: Input
}] } });
class RtCarouselTabDirective {
el;
renderer;
service;
uuidCarousel;
subscription = new Subscription();
constructor(el, renderer, service) {
this.el = el;
this.renderer = renderer;
this.service = service;
}
_disabledTab;
get disabledTab() {
return !!this._disabledTab;
}
set disabledTab(value) {
this._disabledTab = value;
if (value) {
this.renderer.addClass(this.el.nativeElement, 'rt-tab-carousel-tab__disabled');
}
else {
this.renderer.removeClass(this.el.nativeElement, 'rt-tab-carousel-tab__disabled');
}
}
onClick() {
if (!this.disabledTab) {
this.service.selectHTMLElement(this.uuidCarousel, this.el);
}
}
ngOnInit() {
this.renderer.setStyle(this.el.nativeElement, 'white-space', 'nowrap');
this.renderer.setStyle(this.el.nativeElement, 'cursor', 'pointer');
this.renderer.addClass(this.el.nativeElement, `rt-carousel-tab-${this.uuidCarousel}`);
this.service.setTab(this.uuidCarousel, this.el);
}
ngOnDestroy() {
this.service.deleteTab(this.uuidCarousel, this.el);
this.subscription.unsubscribe();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselTabDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: RtCarouselService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.2", type: RtCarouselTabDirective, selector: "[rtCarouselTab]", inputs: { uuidCarousel: "uuidCarousel", disabledTab: "disabledTab" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselTabDirective, decorators: [{
type: Directive,
args: [{
selector: '[rtCarouselTab]',
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: RtCarouselService }]; }, propDecorators: { uuidCarousel: [{
type: Input,
args: [{ required: true }]
}], disabledTab: [{
type: Input
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
class RtCarouselModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselModule, declarations: [RtCarouselContainerDirective,
RtCarouselTabDirective,
RtCarouselPreviousButtonDirective,
RtCarouselNextButtonDirective,
RtCarouselPreviousButtonComponent,
RtCarouselNextButtonComponent], imports: [CommonModule, NgOptimizedImage], exports: [RtCarouselContainerDirective,
RtCarouselTabDirective,
RtCarouselNextButtonDirective,
RtCarouselPreviousButtonDirective,
RtCarouselNextButtonComponent,
RtCarouselPreviousButtonComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselModule, providers: [RtCarouselService], imports: [CommonModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: RtCarouselModule, decorators: [{
type: NgModule,
args: [{
declarations: [
RtCarouselContainerDirective,
RtCarouselTabDirective,
RtCarouselPreviousButtonDirective,
RtCarouselNextButtonDirective,
RtCarouselPreviousButtonComponent,
RtCarouselNextButtonComponent,
],
exports: [
RtCarouselContainerDirective,
RtCarouselTabDirective,
RtCarouselNextButtonDirective,
RtCarouselPreviousButtonDirective,
RtCarouselNextButtonComponent,
RtCarouselPreviousButtonComponent,
],
imports: [CommonModule, NgOptimizedImage],
providers: [RtCarouselService],
}]
}] });
/*
* Public API Surface of rt-tab-carousel
*/
/**
* Generated bundle index. Do not edit.
*/
export { RtCarouselContainerDirective, RtCarouselModule, RtCarouselNextButtonComponent, RtCarouselNextButtonDirective, RtCarouselPreviousButtonComponent, RtCarouselPreviousButtonDirective, RtCarouselService, RtCarouselTabDirective };
//# sourceMappingURL=rt-tab-carousel.mjs.map