@ngu/carousel
Version:
Angular Universal carousel
1 lines • 80 kB
Source Map (JSON)
{"version":3,"file":"ngu-carousel.mjs","sources":["../../../../../libs/ngu/carousel/src/lib/ngu-carousel/ngu-carousel.ts","../../../../../libs/ngu/carousel/src/lib/symbols.ts","../../../../../libs/ngu/carousel/src/lib/ngu-carousel.directive.ts","../../../../../libs/ngu/carousel/src/lib/ngu-carousel/ngu-carousel-hammer-manager.ts","../../../../../libs/ngu/carousel/src/lib/ngu-carousel/ngu-window-scroll-listener.ts","../../../../../libs/ngu/carousel/src/lib/ngu-carousel/ngu-carousel.component.ts","../../../../../libs/ngu/carousel/src/lib/ngu-carousel/ngu-carousel.component.html","../../../../../libs/ngu/carousel/src/lib/ngu-item/ngu-item.component.ts","../../../../../libs/ngu/carousel/src/lib/ngu-item/ngu-item.component.html","../../../../../libs/ngu/carousel/src/lib/ngu-tile/ngu-tile.component.ts","../../../../../libs/ngu/carousel/src/lib/ngu-tile/ngu-tile.component.html","../../../../../libs/ngu/carousel/src/public-api.ts","../../../../../libs/ngu/carousel/src/ngu-carousel.ts"],"sourcesContent":["import { signal } from '@angular/core';\n\nexport class NguCarouselStore {\n constructor(\n public touch = new Touch(),\n public vertical = new Vertical(),\n public interval?: CarouselInterval,\n public transform = new Transfrom(),\n public button?: NguButton,\n public visibleItems?: ItemsControl,\n public deviceType?: DeviceType,\n public type = 'fixed',\n public token = '',\n public items = 0,\n public load = 0,\n public deviceWidth = 0,\n public carouselWidth = 0,\n public itemWidth = 0,\n public slideItems = 0,\n public itemWidthPer = 0,\n public itemLength = 0,\n public currentSlide = 0,\n public easing = 'cubic-bezier(0, 0, 0.2, 1)',\n public speed = 200,\n public loop = false,\n public dexVal = 0,\n public touchTransform = 0,\n public isEnd = false,\n public readonly isFirst = signal(true),\n public readonly isLast = signal(false),\n public RTL = false,\n public point = true,\n public velocity = 1\n ) {}\n}\nexport type DeviceType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'all';\n\nexport type ButtonVisible = 'disabled' | 'hide';\n\nexport class ItemsControl {\n start: number;\n end: number;\n}\n\nexport class Vertical {\n enabled: boolean;\n height: number;\n // numHeight?: number;\n}\n\nexport class NguButton {\n visibility?: ButtonVisible;\n elastic?: number;\n}\n\nexport class Touch {\n active?: boolean;\n swipe: string;\n velocity: number;\n}\n\n// Interface is declared to prevent property-minification\n// See: https://github.com/uiuniversal/ngu-carousel/issues/322\ndeclare interface TransformInterface {\n xs: number;\n sm: number;\n md: number;\n lg: number;\n xl?: number;\n all: number;\n}\n\n// This is misspelled. Must be changed to `Transform`.\nexport class Transfrom implements TransformInterface {\n public xl? = 0;\n constructor(\n public xs = 0,\n public sm = 0,\n public md = 0,\n public lg = 0,\n public all = 0\n ) {}\n}\n\n// Interface is declared to prevent property-minification\n// See: https://github.com/uiuniversal/ngu-carousel/issues/322\ndeclare interface BreakpointsInterface {\n sm: number;\n md: number;\n lg: number;\n xl: number;\n}\n\n/**\n * Default values\n * {sm: 768, md: 992, lg: 1200, xl: 1200}\n *\n * Bootstrap values:\n * {sm: 576, md: 768, lg: 992, xl: 1200}\n */\nexport class Breakpoints implements BreakpointsInterface {\n constructor(\n public sm = 768,\n public md = 992,\n public lg = 1200,\n public xl = 1200\n ) {}\n}\n\nexport class NguCarouselConfig {\n grid: Transfrom;\n gridBreakpoints?: Breakpoints;\n slide?: number;\n speed?: number;\n interval?: CarouselInterval;\n animation?: Animate;\n point?: Point;\n type?: string;\n load?: number;\n custom?: Custom;\n loop?: boolean;\n touch?: boolean;\n easing?: string;\n RTL?: boolean;\n button?: NguButton;\n vertical?: Vertical;\n velocity?: number;\n}\n\nexport type Custom = 'banner';\nexport type Animate = 'lazy';\n\nexport interface Point {\n visible: boolean;\n hideOnSingleSlide?: boolean;\n}\n\nexport interface Animation {\n type?: Animate;\n animateStyles?: AnimationStyles;\n}\n\nexport interface AnimationStyles {\n style?: string;\n open?: string;\n close?: string;\n stagger?: number;\n}\n\nexport interface CarouselInterval {\n timing: number;\n initialDelay?: number;\n}\n\nexport class NguCarouselOutletContext<T> {\n /** Data for the node. */\n $implicit: T;\n\n /** Depth of the node. */\n level: number;\n\n /** Index location of the node. */\n index?: number;\n\n /** Length of the number of total dataNodes. */\n count?: number;\n\n constructor(data: T) {\n this.$implicit = data;\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport { InjectionToken, PLATFORM_ID, inject } from '@angular/core';\n\nexport const IS_BROWSER = new InjectionToken<boolean>('IS_BROWSER', {\n providedIn: 'root',\n factory: () => isPlatformBrowser(inject(PLATFORM_ID))\n});\n","import { Directive, TemplateRef, ViewContainerRef, inject } from '@angular/core';\n\n@Directive({\n selector: '[NguCarouselItem]'\n})\nexport class NguCarouselItemDirective {}\n\n@Directive({\n selector: '[NguCarouselNext]'\n})\nexport class NguCarouselNextDirective {}\n\n@Directive({\n selector: '[NguCarouselPrev]'\n})\nexport class NguCarouselPrevDirective {}\n\n@Directive({\n selector: '[NguCarouselPoint]'\n})\nexport class NguCarouselPointDirective {}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[nguCarouselDef]'\n})\nexport class NguCarouselDefDirective<T> {\n template = inject(TemplateRef);\n when?: (index: number, nodeData: T) => boolean;\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[nguCarouselOutlet]'\n})\nexport class NguCarouselOutlet {\n viewContainer = inject(ViewContainerRef);\n}\n","import { Injectable, NgZone, OnDestroy } from '@angular/core';\nimport { Observable, Subject, defer, fromEvent, map, shareReplay, takeUntil } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class NguHammerLoader {\n private _hammer$ = defer(() => import('hammerjs')).pipe(\n shareReplay({ bufferSize: 1, refCount: true })\n );\n\n load() {\n return this._hammer$;\n }\n}\n\n@Injectable()\nexport class NguCarouselHammerManager implements OnDestroy {\n private _destroy$ = new Subject<void>();\n\n constructor(private _ngZone: NgZone, private _nguHammerLoader: NguHammerLoader) {}\n\n ngOnDestroy(): void {\n this._destroy$.next();\n }\n\n createHammer(element: HTMLElement): Observable<HammerManager> {\n return this._nguHammerLoader.load().pipe(\n map(() =>\n // Note: The Hammer manager should be created outside of the Angular zone since it sets up\n // `pointermove` event listener which triggers change detection every time the pointer is moved.\n this._ngZone.runOutsideAngular(() => new Hammer(element))\n ),\n // Note: the dynamic import is always a microtask which may run after the view is destroyed.\n // `takeUntil` is used to prevent setting Hammer up if the view had been destroyed before\n // the HammerJS is loaded.\n takeUntil(this._destroy$)\n );\n }\n\n on(hammer: HammerManager, event: string) {\n return fromEvent(hammer, event).pipe(\n // Note: We have to re-enter the Angular zone because Hammer would trigger events outside of the\n // Angular zone (since we set it up with `runOutsideAngular`).\n enterNgZone(this._ngZone),\n takeUntil(this._destroy$)\n );\n }\n}\n\nfunction enterNgZone<T>(ngZone: NgZone) {\n return (source: Observable<T>) =>\n new Observable<T>(subscriber =>\n source.subscribe({\n next: value => ngZone.run(() => subscriber.next(value)),\n error: error => ngZone.run(() => subscriber.error(error)),\n complete: () => ngZone.run(() => subscriber.complete())\n })\n );\n}\n","import { Injectable, NgZone, OnDestroy, inject } from '@angular/core';\nimport { Subject, fromEvent } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\nimport { IS_BROWSER } from '../symbols';\n\n@Injectable({ providedIn: 'root' })\nexport class NguWindowScrollListener extends Subject<Event> implements OnDestroy {\n private readonly _destroy$ = new Subject<void>();\n\n constructor() {\n super();\n\n const isBrowser = inject(IS_BROWSER);\n const ngZone = inject(NgZone);\n // Note: this service is shared between multiple `NguCarousel` components and each instance\n // doesn't add new events listener for the `window`.\n if (isBrowser) {\n ngZone.runOutsideAngular(() =>\n fromEvent(window, 'scroll').pipe(takeUntil(this._destroy$)).subscribe(this)\n );\n }\n }\n\n ngOnDestroy(): void {\n this._destroy$.next();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n IterableChangeRecord,\n IterableChanges,\n IterableDiffer,\n IterableDiffers,\n NgIterable,\n NgZone,\n OnDestroy,\n Renderer2,\n TrackByFunction,\n computed,\n contentChild,\n contentChildren,\n effect,\n inject,\n input,\n output,\n viewChild,\n signal,\n untracked,\n ChangeDetectorRef,\n afterNextRender,\n AfterRenderPhase\n} from '@angular/core';\nimport { EMPTY, Subject, fromEvent, interval, merge, timer } from 'rxjs';\nimport { debounceTime, filter, map, startWith, switchMap, takeUntil } from 'rxjs/operators';\n\nimport { IS_BROWSER } from '../symbols';\nimport {\n NguCarouselDefDirective,\n NguCarouselNextDirective,\n NguCarouselOutlet,\n NguCarouselPrevDirective\n} from '../ngu-carousel.directive';\nimport {\n Breakpoints,\n NguCarouselConfig,\n NguCarouselOutletContext,\n NguCarouselStore,\n Transfrom\n} from './ngu-carousel';\nimport { NguCarouselHammerManager } from './ngu-carousel-hammer-manager';\nimport { NguWindowScrollListener } from './ngu-window-scroll-listener';\n\ntype DirectionSymbol = '' | '-';\n\ntype NguCarouselDataSource<T, U> = (U & NgIterable<T>) | null | undefined;\n\n// This will be provided through Terser global definitions by Angular CLI.\n// This is how Angular does tree-shaking internally.\ndeclare const ngDevMode: boolean;\n\nconst NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;\n\n@Component({\n selector: 'ngu-carousel',\n templateUrl: 'ngu-carousel.component.html',\n styleUrls: ['ngu-carousel.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [NguCarouselHammerManager],\n imports: [NguCarouselOutlet]\n})\nexport class NguCarousel<T, U extends NgIterable<T> = NgIterable<T>>\n extends NguCarouselStore\n implements OnDestroy\n{\n private _host = inject<ElementRef<HTMLElement>>(ElementRef);\n private _renderer = inject(Renderer2);\n private _differs = inject(IterableDiffers);\n private _isBrowser = inject(IS_BROWSER);\n private _ngZone = inject(NgZone);\n private _nguWindowScrollListener = inject(NguWindowScrollListener);\n private _nguCarouselHammerManager = inject(NguCarouselHammerManager);\n private _cdr = inject(ChangeDetectorRef);\n /** Public property that may be accessed outside of the component. */\n readonly activePoint = signal(0);\n readonly pointNumbers = signal<number[]>([]);\n\n readonly inputs = input.required<NguCarouselConfig>();\n readonly carouselLoad = output<number>();\n readonly onMove = output<this>();\n\n private _defDirectives = contentChildren(NguCarouselDefDirective);\n\n private _nodeOutlet = viewChild.required(NguCarouselOutlet);\n\n readonly nextButton = contentChild(NguCarouselNextDirective, { read: ElementRef });\n readonly prevButton = contentChild(NguCarouselPrevDirective, { read: ElementRef });\n\n readonly carouselMain1 = viewChild.required('ngucarousel', { read: ElementRef });\n readonly _nguItemsContainer = viewChild.required('nguItemsContainer', { read: ElementRef });\n readonly _touchContainer = viewChild.required('touchContainer', { read: ElementRef });\n\n private _arrayChanges: IterableChanges<T> | null = null;\n\n readonly dataSource = input.required({\n transform: (v: NguCarouselDataSource<T, U>) => v || ([] as never)\n });\n\n private _intervalController$ = new Subject<number>();\n\n private _hammer: HammerManager | null = null;\n\n private _withAnimation = true;\n\n private _directionSymbol: DirectionSymbol;\n\n private _carouselCssNode: HTMLStyleElement;\n\n private _dataDiffer: IterableDiffer<T>;\n\n private _styleid: string;\n\n private _pointIndex: number;\n\n private _destroy$ = new Subject<void>();\n\n /**\n * Tracking function that will be used to check the differences in data changes. Used similarly\n * to `ngFor` `trackBy` function. Optimize Items operations by identifying a Items based on its data\n * relative to the function to know if a Items should be added/removed/moved.\n * Accepts a function that takes two parameters, `index` and `item`.\n */\n readonly trackBy = input<TrackByFunction<T>>();\n readonly _trackByFn = computed(() => {\n const fn = this.trackBy();\n if (NG_DEV_MODE && fn != null && typeof fn !== 'function' && console?.warn) {\n console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}.`);\n }\n return fn || ((index: number, item: T) => item);\n });\n\n constructor() {\n super();\n this._dataDiffer = this._differs.find([]).create(this._trackByFn())!;\n\n afterNextRender(\n () => {\n this._inputValidation();\n\n this._carouselCssNode = this._createStyleElem();\n\n if (this._isBrowser) {\n this._carouselInterval();\n if (!this.vertical.enabled && this.inputs()?.touch) {\n this._setupHammer();\n }\n this._setupWindowResizeListener();\n this._onWindowScrolling();\n }\n },\n { phase: AfterRenderPhase.EarlyRead }\n );\n\n effect(() => {\n const _ = this._defDirectives();\n const data = this.dataSource();\n untracked(() => this._checkChanges(data));\n });\n\n effect(cleanup => {\n const prevButton = this.prevButton();\n untracked(() => {\n if (prevButton) {\n const preSub = fromEvent(prevButton.nativeElement, 'click')\n .pipe(takeUntil(this._destroy$))\n .subscribe(() => this._carouselScrollOne(0));\n cleanup(() => preSub.unsubscribe());\n }\n });\n });\n\n effect(cleanup => {\n const nextButton = this.nextButton();\n untracked(() => {\n if (nextButton) {\n const nextSub = fromEvent(nextButton.nativeElement, 'click')\n .pipe(takeUntil(this._destroy$))\n .subscribe(() => this._carouselScrollOne(1));\n cleanup(() => nextSub.unsubscribe());\n }\n });\n });\n }\n\n private _checkChanges(data: NguCarouselDataSource<T, U>) {\n // if (this.ngu_dirty) {\n // this.ngu_dirty = false;\n // const dataStream = this.dataSource;\n // if (!this._arrayChanges && !!dataStream) {\n // this._dataDiffer = this._differs\n // .find(dataStream)\n // .create((index: number, item: any) => this._trackByFn()(index, item))!;\n // }\n // }\n // if (this._dataDiffer) {\n // this._arrayChanges =\n // this._markedForCheck && this._arrayChanges\n // ? this._arrayChanges\n // : this._dataDiffer.diff(this.dataSource)!;\n // if (this._arrayChanges) {\n // this.renderNodeChanges(Array.from(this.dataSource()));\n // }\n // }\n this._arrayChanges = this._dataDiffer.diff(data);\n if (this._arrayChanges) {\n this.renderNodeChanges(Array.from(data as any));\n }\n }\n\n private renderNodeChanges(data: any[]) {\n if (!this._arrayChanges) return;\n this.isLast.set(this._pointIndex === this.currentSlide);\n const viewContainer = this._nodeOutlet().viewContainer;\n // this._markedForCheck = false;\n this._arrayChanges.forEachOperation(\n (\n item: IterableChangeRecord<any>,\n adjustedPreviousIndex: number | null,\n currentIndex: number | null\n ) => {\n const node = this._getNodeDef(data[currentIndex!], currentIndex!);\n if (node?.template) {\n if (item.previousIndex == null) {\n const context = new NguCarouselOutletContext<any>(data[currentIndex!]);\n context.index = currentIndex!;\n viewContainer.createEmbeddedView(node.template, context, currentIndex!);\n } else if (currentIndex == null) {\n viewContainer.remove(adjustedPreviousIndex!);\n } else {\n const view = viewContainer.get(adjustedPreviousIndex!);\n viewContainer.move(view!, currentIndex);\n }\n }\n }\n );\n this._updateItemIndexContext();\n\n if (this._host.nativeElement) {\n this._storeCarouselData();\n }\n }\n\n /**\n * Updates the index-related context for each row to reflect any changes in the index of the rows,\n * e.g. first/last/even/odd.\n */\n private _updateItemIndexContext() {\n const viewContainer = this._nodeOutlet().viewContainer;\n for (let renderIndex = 0, count = viewContainer.length; renderIndex < count; renderIndex++) {\n const viewRef = viewContainer.get(renderIndex) as any;\n const context = viewRef.context as any;\n context.count = count;\n context.first = renderIndex === 0;\n context.last = renderIndex === count - 1;\n context.even = renderIndex % 2 === 0;\n context.odd = !context.even;\n context.index = renderIndex;\n }\n }\n\n private _getNodeDef(data: any, i: number): NguCarouselDefDirective<any> | undefined {\n if (this._defDirectives()?.length === 1) {\n return this._defDirectives()[0];\n }\n\n const nodeDef: NguCarouselDefDirective<any> | undefined = (this._defDirectives() || []).find(\n def => !!def.when?.(i, data)\n );\n\n return nodeDef;\n }\n\n private _inputValidation() {\n const inputs = this.inputs();\n inputs.gridBreakpoints = inputs.gridBreakpoints ? inputs.gridBreakpoints : new Breakpoints();\n if (inputs.grid.xl === undefined) {\n inputs.grid.xl = inputs.grid.lg;\n }\n\n this.type = inputs.grid.all !== 0 ? 'fixed' : 'responsive';\n this.loop = inputs.loop || false;\n inputs.easing = inputs.easing || 'cubic-bezier(0, 0, 0.2, 1)';\n this.touch.active = inputs.touch || false;\n this.RTL = inputs.RTL ? true : false;\n this.interval = inputs.interval || undefined;\n this.velocity = typeof inputs.velocity === 'number' ? inputs.velocity : this.velocity;\n\n if (inputs.vertical && inputs.vertical.enabled) {\n this.vertical.enabled = inputs.vertical.enabled;\n this.vertical.height = inputs.vertical.height;\n }\n this._directionSymbol = this.RTL ? '' : '-';\n this.point =\n inputs.point && typeof inputs.point.visible !== 'undefined' ? inputs.point.visible : true;\n\n this._carouselSize();\n }\n\n ngOnDestroy() {\n this._hammer?.destroy();\n this._destroy$.next();\n }\n\n /** Get Touch input */\n private _setupHammer(): void {\n // Note: doesn't need to unsubscribe because streams are piped with `takeUntil` already.\n this._nguCarouselHammerManager\n .createHammer(this._touchContainer().nativeElement)\n .subscribe(hammer => {\n this._hammer = hammer;\n\n hammer.get('pan').set({ direction: Hammer.DIRECTION_HORIZONTAL });\n\n this._nguCarouselHammerManager.on(hammer, 'panstart').subscribe(() => {\n this.carouselWidth = this._nguItemsContainer().nativeElement.offsetWidth;\n this.touchTransform = this.transform[this.deviceType!]!;\n this.dexVal = 0;\n this._setStyle(this._nguItemsContainer().nativeElement, 'transition', '');\n });\n\n if (this.vertical.enabled) {\n this._nguCarouselHammerManager.on(hammer, 'panup').subscribe((ev: any) => {\n this._touchHandling('panleft', ev);\n });\n\n this._nguCarouselHammerManager.on(hammer, 'pandown').subscribe((ev: any) => {\n this._touchHandling('panright', ev);\n });\n } else {\n this._nguCarouselHammerManager.on(hammer, 'panleft').subscribe((ev: any) => {\n this._touchHandling('panleft', ev);\n });\n\n this._nguCarouselHammerManager.on(hammer, 'panright').subscribe((ev: any) => {\n this._touchHandling('panright', ev);\n });\n }\n\n this._nguCarouselHammerManager.on(hammer, 'panend pancancel').subscribe(({ velocity }) => {\n if (Math.abs(velocity) >= this.velocity) {\n this.touch.velocity = velocity;\n let direc = 0;\n if (!this.RTL) {\n direc = this.touch.swipe === 'panright' ? 0 : 1;\n } else {\n direc = this.touch.swipe === 'panright' ? 1 : 0;\n }\n this._carouselScrollOne(direc);\n } else {\n this.dexVal = 0;\n this._setStyle(\n this._nguItemsContainer().nativeElement,\n 'transition',\n 'transform 324ms cubic-bezier(0, 0, 0.2, 1)'\n );\n this._setStyle(this._nguItemsContainer().nativeElement, 'transform', '');\n }\n });\n\n this._nguCarouselHammerManager.on(hammer, 'hammer.input').subscribe(({ srcEvent }) => {\n // allow nested touch events to no propagate, this may have other side affects but works for now.\n // TODO: It is probably better to check the source element of the event and only apply the handle to the correct carousel\n srcEvent.stopPropagation();\n });\n });\n }\n\n /** handle touch input */\n private _touchHandling(e: string, ev: any): void {\n // vertical touch events seem to cause to panstart event with an odd delta\n // and a center of {x:0,y:0} so this will ignore them\n if (ev.center.x === 0) {\n return;\n }\n\n ev = Math.abs(this.vertical.enabled ? ev.deltaY : ev.deltaX);\n let valt = ev - this.dexVal;\n valt =\n this.type === 'responsive'\n ? (Math.abs(ev - this.dexVal) /\n (this.vertical.enabled ? this.vertical.height : this.carouselWidth)) *\n 100\n : valt;\n this.dexVal = ev;\n this.touch.swipe = e;\n this._setTouchTransfrom(e, valt);\n this._setTransformFromTouch();\n }\n\n private _setTouchTransfrom(e: string, valt: number) {\n const condition = this.RTL ? 'panright' : 'panleft';\n this.touchTransform = e === condition ? valt + this.touchTransform : this.touchTransform - valt;\n }\n\n private _setTransformFromTouch() {\n if (this.touchTransform < 0) {\n this.touchTransform = 0;\n }\n const type = this.type === 'responsive' ? '%' : 'px';\n this._setStyle(\n this._nguItemsContainer().nativeElement,\n 'transform',\n this.vertical.enabled\n ? `translate3d(0, ${this._directionSymbol}${this.touchTransform}${type}, 0)`\n : `translate3d(${this._directionSymbol}${this.touchTransform}${type}, 0, 0)`\n );\n }\n\n /** this fn used to disable the interval when it is not on the viewport */\n private _onWindowScrolling(): void {\n const { offsetTop, offsetHeight } = this._host.nativeElement;\n const { scrollY: windowScrollY, innerHeight: windowInnerHeight } = window;\n\n const isCarouselOnScreen =\n offsetTop <= windowScrollY + windowInnerHeight - offsetHeight / 4 &&\n offsetHeight + offsetHeight / 2 >= windowScrollY;\n\n if (isCarouselOnScreen) {\n this._intervalController$.next(1);\n } else {\n this._intervalController$.next(0);\n }\n }\n\n /** store data based on width of the screen for the carousel */\n private _storeCarouselData(): void {\n const inputs = this.inputs();\n const breakpoints = this.inputs().gridBreakpoints;\n this.deviceWidth = this._isBrowser ? window.innerWidth : breakpoints?.xl!;\n\n this.carouselWidth = this.carouselMain1().nativeElement.offsetWidth;\n\n if (this.type === 'responsive') {\n this.deviceType =\n this.deviceWidth >= breakpoints?.xl!\n ? 'xl'\n : this.deviceWidth >= breakpoints?.lg!\n ? 'lg'\n : this.deviceWidth >= breakpoints?.md!\n ? 'md'\n : this.deviceWidth >= breakpoints?.sm!\n ? 'sm'\n : 'xs';\n\n this.items = inputs.grid[this.deviceType]!;\n this.itemWidth = this.carouselWidth / this.items;\n } else {\n this.items = Math.trunc(this.carouselWidth / inputs.grid.all);\n this.itemWidth = inputs.grid.all;\n this.deviceType = 'all';\n }\n\n this.slideItems = +(inputs.slide! < this.items ? inputs.slide! : this.items);\n this.load = inputs.load! >= this.slideItems ? inputs.load! : this.slideItems;\n this.speed = inputs.speed && inputs.speed > -1 ? inputs.speed : 400;\n this._carouselPoint();\n }\n\n /** Used to reset the carousel */\n public reset(withoutAnimation?: boolean): void {\n withoutAnimation && (this._withAnimation = false);\n this._carouselCssNode.textContent = '';\n this.moveTo(0);\n this._carouselPoint();\n }\n\n /** Init carousel point */\n private _carouselPoint(): void {\n const Nos = Array.from(this.dataSource()).length - (this.items - this.slideItems);\n this._pointIndex = Math.ceil(Nos / this.slideItems);\n const pointers: number[] = [];\n\n if (this._pointIndex > 1 || !this.inputs().point?.hideOnSingleSlide) {\n for (let i = 0; i < this._pointIndex; i++) {\n pointers.push(i);\n }\n }\n this.pointNumbers.set(pointers);\n\n this._carouselPointActiver();\n if (this._pointIndex <= 1) {\n this._btnBoolean(1, 1);\n } else {\n if (this.currentSlide === 0 && !this.loop) {\n this._btnBoolean(1, 0);\n } else {\n this._btnBoolean(0, 0);\n }\n }\n }\n\n /** change the active point in carousel */\n private _carouselPointActiver(): void {\n const i = Math.ceil(this.currentSlide / this.slideItems);\n this.activePoint.set(i);\n }\n\n /** this function is used to scoll the carousel when point is clicked */\n public moveTo(slide: number, withoutAnimation?: boolean) {\n // slide = slide - 1;\n withoutAnimation && (this._withAnimation = false);\n if (this.activePoint() !== slide && slide < this._pointIndex) {\n let slideremains;\n const btns = this.currentSlide < slide ? 1 : 0;\n\n switch (slide) {\n case 0:\n this._btnBoolean(1, 0);\n slideremains = slide * this.slideItems;\n break;\n case this._pointIndex - 1:\n this._btnBoolean(0, 1);\n slideremains = Array.from(this.dataSource()).length - this.items;\n break;\n default:\n this._btnBoolean(0, 0);\n slideremains = slide * this.slideItems;\n }\n this._carouselScrollTwo(btns, slideremains, this.speed);\n }\n }\n\n /** set the style of the carousel based the inputs data */\n private _carouselSize(): void {\n const inputs = this.inputs();\n this.token = this._generateID();\n let dism = '';\n this._styleid = `.${this.token} > .ngucarousel > .ngu-container > .ngu-touch-container > .ngucarousel-items`;\n\n if (inputs.custom === 'banner') {\n this._renderer.addClass(this._host.nativeElement, 'banner');\n }\n\n if (inputs.animation === 'lazy') {\n dism += `${this._styleid} > .item {transition: transform .6s ease;}`;\n }\n\n const breakpoints = inputs.gridBreakpoints;\n\n let itemStyle = '';\n if (this.vertical.enabled) {\n const itemWidthXS = `${this._styleid} > .item {height: ${\n this.vertical.height / +inputs.grid.xs\n }px}`;\n const itemWidthSM = `${this._styleid} > .item {height: ${\n this.vertical.height / +inputs.grid.sm\n }px}`;\n const itemWidthMD = `${this._styleid} > .item {height: ${\n this.vertical.height / +inputs.grid.md\n }px}`;\n const itemWidthLG = `${this._styleid} > .item {height: ${\n this.vertical.height / +inputs.grid.lg\n }px}`;\n const itemWidthXL = `${this._styleid} > .item {height: ${\n this.vertical.height / +inputs.grid.xl!\n }px}`;\n\n itemStyle = `@media (max-width:${breakpoints?.sm! - 1}px){${itemWidthXS}}\n @media (max-width:${breakpoints?.sm}px){${itemWidthSM}}\n @media (min-width:${breakpoints?.md}px){${itemWidthMD}}\n @media (min-width:${breakpoints?.lg}px){${itemWidthLG}}\n @media (min-width:${breakpoints?.xl}px){${itemWidthXL}}`;\n } else if (this.type === 'responsive') {\n const itemWidthXS =\n inputs.type === 'mobile'\n ? `${this._styleid} .item {flex: 0 0 ${95 / +inputs.grid.xs}%; width: ${\n 95 / +inputs.grid.xs\n }%;}`\n : `${this._styleid} .item {flex: 0 0 ${100 / +inputs.grid.xs}%; width: ${\n 100 / +inputs.grid.xs\n }%;}`;\n\n const itemWidthSM = `${this._styleid} > .item {flex: 0 0 ${100 / +inputs.grid.sm}%; width: ${\n 100 / +inputs.grid.sm\n }%}`;\n const itemWidthMD = `${this._styleid} > .item {flex: 0 0 ${100 / +inputs.grid.md}%; width: ${\n 100 / +inputs.grid.md\n }%}`;\n const itemWidthLG = `${this._styleid} > .item {flex: 0 0 ${100 / +inputs.grid.lg}%; width: ${\n 100 / +inputs.grid.lg\n }%}`;\n const itemWidthXL = `${this._styleid} > .item {flex: 0 0 ${100 / +inputs.grid.xl!}%; width: ${\n 100 / +inputs.grid.xl!\n }%}`;\n\n itemStyle = `@media (max-width:${breakpoints?.sm! - 1}px){${itemWidthXS}}\n @media (min-width:${breakpoints?.sm}px){${itemWidthSM}}\n @media (min-width:${breakpoints?.md}px){${itemWidthMD}}\n @media (min-width:${breakpoints?.lg}px){${itemWidthLG}}\n @media (min-width:${breakpoints?.xl}px){${itemWidthXL}}`;\n } else {\n itemStyle = `${this._styleid} .item {flex: 0 0 ${inputs.grid.all}px; width: ${inputs.grid.all}px;}`;\n }\n\n this._renderer.addClass(this._host.nativeElement, this.token);\n if (this.vertical.enabled) {\n this._renderer.addClass(this._nguItemsContainer().nativeElement, 'nguvertical');\n this._renderer.setStyle(\n this.carouselMain1().nativeElement,\n 'height',\n `${this.vertical.height}px`\n );\n }\n\n this.RTL &&\n !this.vertical.enabled &&\n this._renderer.addClass(this._host.nativeElement, 'ngurtl');\n this._createStyleElem(`${dism} ${itemStyle}`);\n this._storeCarouselData();\n }\n\n /** logic to scroll the carousel step 1 */\n private _carouselScrollOne(Btn: number): void {\n let itemSpeed = this.speed;\n let currentSlide = 0;\n let touchMove = Math.ceil(this.dexVal / this.itemWidth);\n touchMove = isFinite(touchMove) ? touchMove : 0;\n this._setStyle(this._nguItemsContainer().nativeElement, 'transform', '');\n\n if (this._pointIndex === 1) {\n return;\n } else if (Btn === 0 && ((!this.loop && !this.isFirst()) || this.loop)) {\n const currentSlideD = this.currentSlide - this.slideItems;\n const MoveSlide = currentSlideD + this.slideItems;\n this._btnBoolean(0, 1);\n if (this.currentSlide === 0) {\n currentSlide = Array.from(this.dataSource()).length - this.items;\n itemSpeed = 400;\n this._btnBoolean(0, 1);\n } else if (this.slideItems >= MoveSlide) {\n currentSlide = 0;\n this._btnBoolean(1, 0);\n } else {\n this._btnBoolean(0, 0);\n if (touchMove > this.slideItems) {\n currentSlide = this.currentSlide - touchMove;\n itemSpeed = 200;\n } else {\n currentSlide = this.currentSlide - this.slideItems;\n }\n }\n this._carouselScrollTwo(Btn, currentSlide, itemSpeed);\n } else if (Btn === 1 && ((!this.loop && !this.isLast()) || this.loop)) {\n if (\n Array.from(this.dataSource()).length <= this.currentSlide + this.items + this.slideItems &&\n !this.isLast()\n ) {\n currentSlide = Array.from(this.dataSource()).length - this.items;\n this._btnBoolean(0, 1);\n } else if (this.isLast()) {\n currentSlide = 0;\n itemSpeed = 400;\n this._btnBoolean(1, 0);\n } else {\n this._btnBoolean(0, 0);\n if (touchMove > this.slideItems) {\n currentSlide = this.currentSlide + this.slideItems + (touchMove - this.slideItems);\n itemSpeed = 200;\n } else {\n currentSlide = this.currentSlide + this.slideItems;\n }\n }\n this._carouselScrollTwo(Btn, currentSlide, itemSpeed);\n }\n }\n\n /** logic to scroll the carousel step 2 */\n private _carouselScrollTwo(Btn: number, currentSlide: number, itemSpeed: number): void {\n if (this.dexVal !== 0) {\n const val = Math.abs(this.touch.velocity);\n let somt = Math.floor((this.dexVal / val / this.dexVal) * (this.deviceWidth - this.dexVal));\n somt = somt > itemSpeed ? itemSpeed : somt;\n itemSpeed = somt < 200 ? 200 : somt;\n this.dexVal = 0;\n }\n if (this._withAnimation) {\n this._setStyle(\n this._nguItemsContainer().nativeElement,\n 'transition',\n `transform ${itemSpeed}ms ${this.inputs().easing}`\n );\n this.inputs().animation &&\n this._carouselAnimator(\n Btn,\n currentSlide + 1,\n currentSlide + this.items,\n itemSpeed,\n Math.abs(this.currentSlide - currentSlide)\n );\n } else {\n this._setStyle(this._nguItemsContainer().nativeElement, 'transition', ``);\n }\n\n this.itemLength = Array.from(this.dataSource()).length;\n this._transformStyle(currentSlide);\n this.currentSlide = currentSlide;\n this.onMove.emit(this);\n this._carouselPointActiver();\n this._carouselLoadTrigger();\n this._withAnimation = true;\n }\n\n /** boolean function for making isFirst and isLast */\n private _btnBoolean(first: number, last: number) {\n this.isFirst.set(!!first);\n this.isLast.set(!!last);\n }\n\n private _transformString(grid: keyof Transfrom, slide: number): string {\n let collect = '';\n collect += `${this._styleid} { transform: translate3d(`;\n\n if (this.vertical.enabled) {\n this.transform[grid] = (this.vertical.height / this.inputs().grid[grid]!) * slide;\n collect += `0, -${this.transform[grid]}px, 0`;\n } else {\n this.transform[grid] = (100 / this.inputs().grid[grid]!) * slide;\n collect += `${this._directionSymbol}${this.transform[grid]}%, 0, 0`;\n }\n collect += `); }`;\n return collect;\n }\n\n /** set the transform style to scroll the carousel */\n private _transformStyle(slide: number): void {\n let slideCss = '';\n if (this.type === 'responsive') {\n const breakpoints = this.inputs().gridBreakpoints;\n slideCss = `@media (max-width: ${breakpoints?.sm! - 1}px) {${this._transformString(\n 'xs',\n slide\n )}}\n @media (min-width: ${breakpoints?.sm}px) {${this._transformString('sm', slide)} }\n @media (min-width: ${breakpoints?.md}px) {${this._transformString('md', slide)} }\n @media (min-width: ${breakpoints?.lg}px) {${this._transformString('lg', slide)} }\n @media (min-width: ${breakpoints?.xl}px) {${this._transformString('xl', slide)} }`;\n } else {\n this.transform.all = this.inputs().grid.all * slide;\n slideCss = `${this._styleid} { transform: translate3d(${this._directionSymbol}${this.transform.all}px, 0, 0);`;\n }\n this._carouselCssNode.textContent = slideCss;\n }\n\n /** this will trigger the carousel to load the items */\n private _carouselLoadTrigger(): void {\n if (typeof this.inputs().load === 'number') {\n Array.from(this.dataSource()).length - this.load <= this.currentSlide + this.items &&\n this.carouselLoad.emit(this.currentSlide);\n }\n }\n\n /** generate Class for each carousel to set specific style */\n private _generateID(): string {\n let text = '';\n const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\n for (let i = 0; i < 6; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return `ngucarousel${text}`;\n }\n\n /** handle the auto slide */\n private _carouselInterval(): void {\n const container = this.carouselMain1().nativeElement;\n if (this.interval && this.loop) {\n this._nguWindowScrollListener\n .pipe(\n // Note: do not use `debounceTime` since it may flush queued actions within the Angular zone.\n switchMap(() => timer(600)),\n takeUntil(this._destroy$)\n )\n .subscribe(() => {\n // Note: we don't run change detection on each `scroll` event, but we re-enter the\n // Angular zone once the DOM timer fires to be backwards compatible.\n // TODO: revisit later since we may not run change detection at all on this task.\n this._ngZone.run(() => this._onWindowScrolling());\n });\n\n const mapToZero = map(() => 0);\n const mapToOne = map(() => 1);\n\n const play$ = fromEvent(container, 'mouseleave').pipe(mapToOne);\n const pause$ = fromEvent(container, 'mouseenter').pipe(mapToZero);\n\n const touchPlay$ = fromEvent(container, 'touchstart').pipe(mapToOne);\n const touchPause$ = fromEvent(container, 'touchend').pipe(mapToZero);\n\n const interval$ = interval(this.inputs().interval?.timing!).pipe(mapToOne);\n\n const initialDelay = this.interval.initialDelay || 0;\n\n const carouselInterval$ = merge(\n play$,\n touchPlay$,\n pause$,\n touchPause$,\n this._intervalController$\n ).pipe(\n startWith(1),\n switchMap(val => {\n this._cdr.markForCheck();\n return val ? interval$ : EMPTY;\n })\n );\n\n timer(initialDelay)\n .pipe(\n switchMap(() => carouselInterval$),\n takeUntil(this._destroy$)\n )\n .subscribe(() => {\n this._carouselScrollOne(1);\n });\n }\n }\n\n /** animate the carousel items */\n private _carouselAnimator(\n direction: number,\n start: number,\n end: number,\n speed: number,\n length: number\n ): void {\n const viewContainer = this._nodeOutlet().viewContainer;\n\n let val = length < 5 ? length : 5;\n val = val === 1 ? 3 : val;\n const collectedIndexes: number[] = [];\n\n if (direction === 1) {\n for (let i = start - 1; i < end; i++) {\n collectedIndexes.push(i);\n val = val * 2;\n const viewRef = viewContainer.get(i) as any;\n const context = viewRef.context as any;\n context.animate = { value: true, params: { distance: val } };\n }\n } else {\n for (let i = end - 1; i >= start - 1; i--) {\n collectedIndexes.push(i);\n val = val * 2;\n const viewRef = viewContainer.get(i) as any;\n const context = viewRef.context as any;\n context.animate = { value: true, params: { distance: -val } };\n }\n }\n\n timer(speed * 0.7)\n .pipe(takeUntil(this._destroy$))\n .subscribe(() => this._removeAnimations(collectedIndexes));\n }\n\n private _removeAnimations(collectedIndexes: number[]) {\n const viewContainer = this._nodeOutlet().viewContainer;\n collectedIndexes.forEach(i => {\n const viewRef = viewContainer.get(i) as any;\n const context = viewRef.context as any;\n context.animate = { value: false, params: { distance: 0 } };\n });\n this._cdr.markForCheck();\n }\n\n /** Short form for setElementStyle */\n private _setStyle(el: any, prop: any, val: any): void {\n this._renderer.setStyle(el, prop, val);\n }\n\n /** For generating style tag */\n private _createStyleElem(datas?: string): HTMLStyleElement {\n const styleItem = this._renderer.createElement('style');\n if (datas) {\n const styleText = this._renderer.createText(datas);\n this._renderer.appendChild(styleItem, styleText);\n }\n this._renderer.appendChild(this._host.nativeElement, styleItem);\n return styleItem;\n }\n\n private _setupWindowResizeListener(): void {\n this._ngZone.runOutsideAngular(() =>\n fromEvent(window, 'resize')\n .pipe(\n debounceTime(500),\n filter(() => this.deviceWidth !== window.outerWidth),\n takeUntil(this._destroy$)\n )\n .subscribe(() => {\n this._setStyle(this._nguItemsContainer().nativeElement, 'transition', ``);\n // Re-enter the Angular zone only after `resize` events have been dispatched\n // and the timer has run (in `debounceTime`).\n this._ngZone.run(() => {\n this._storeCarouselData();\n // this._cdr.markForCheck();\n });\n })\n );\n }\n\n static ngAcceptInputType_dataSource: NguCarouselDataSource<any, any>;\n}\n","<div #ngucarousel class=\"ngucarousel\">\n <ng-content select=\"[NguCarouselPrev]\"></ng-content>\n <div class=\"ngu-container\">\n <div #touchContainer class=\"ngu-touch-container\">\n <div #nguItemsContainer class=\"ngucarousel-items\">\n <ng-container nguCarouselOutlet></ng-container>\n </div>\n </div>\n </div>\n <div class=\"nguclearFix\"></div>\n <ng-content select=\"[NguCarouselNext]\"></ng-content>\n</div>\n<ng-content select=\"[NguCarouselPoint]\"></ng-content>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'ngu-item',\n templateUrl: 'ngu-item.component.html',\n host: {\n class: 'item'\n }\n})\nexport class NguItemComponent {}\n","<ng-content></ng-content>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'ngu-tile',\n templateUrl: 'ngu-tile.component.html',\n styleUrls: ['ngu-tile.component.scss'],\n host: {\n class: 'item'\n }\n})\nexport class NguTileComponent {}\n","<div class=\"tile\">\n <ng-content></ng-content>\n</div>\n","/*\n * Public API Surface of carousel\n */\n\nexport { NguCarouselConfig } from './lib/ngu-carousel/ngu-carousel';\n\nexport { NguCarouselStore } from './lib/ngu-carousel/ngu-carousel';\n\nexport { NguCarousel } from './lib/ngu-carousel/ngu-carousel.component';\n\nexport { NguItemComponent } from './lib/ngu-item/ngu-item.component';\n\nexport { NguTileComponent } from './lib/ngu-tile/ngu-tile.component';\n\nexport {\n NguCarouselDefDirective,\n NguCarouselPointDirective,\n NguCarouselItemDirective,\n NguCarouselNextDirective,\n NguCarouselPrevDirective,\n NguCarouselOutlet\n} from './lib/ngu-carousel.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["takeUntil","map"],"mappings":"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