UNPKG

10.6 kBJavaScriptView Raw
1// todo: add animation
2import { Component, Input, Output, EventEmitter } from '@angular/core';
3import { isBs3, LinkedList } from '../utils';
4import { CarouselConfig } from './carousel.config';
5export var Direction;
6(function (Direction) {
7 Direction[Direction["UNKNOWN"] = 0] = "UNKNOWN";
8 Direction[Direction["NEXT"] = 1] = "NEXT";
9 Direction[Direction["PREV"] = 2] = "PREV";
10})(Direction || (Direction = {}));
11/**
12 * Base element to create carousel
13 */
14export var CarouselComponent = (function () {
15 function CarouselComponent(config) {
16 /** Will be emitted when active slide has been changed. Part of two-way-bindable [(activeSlide)] property */
17 this.activeSlideChange = new EventEmitter(false);
18 this._slides = new LinkedList();
19 this.destroyed = false;
20 Object.assign(this, config);
21 }
22 Object.defineProperty(CarouselComponent.prototype, "activeSlide", {
23 get: function () {
24 return this._currentActiveSlide;
25 },
26 /** Index of currently displayed slide(started for 0) */
27 set: function (index) {
28 if (this._slides.length && index !== this._currentActiveSlide) {
29 this._select(index);
30 }
31 },
32 enumerable: true,
33 configurable: true
34 });
35 Object.defineProperty(CarouselComponent.prototype, "interval", {
36 /**
37 * Delay of item cycling in milliseconds. If false, carousel won't cycle automatically.
38 */
39 get: function () {
40 return this._interval;
41 },
42 set: function (value) {
43 this._interval = value;
44 this.restartTimer();
45 },
46 enumerable: true,
47 configurable: true
48 });
49 Object.defineProperty(CarouselComponent.prototype, "slides", {
50 get: function () {
51 return this._slides.toArray();
52 },
53 enumerable: true,
54 configurable: true
55 });
56 Object.defineProperty(CarouselComponent.prototype, "isBs4", {
57 get: function () {
58 return !isBs3();
59 },
60 enumerable: true,
61 configurable: true
62 });
63 CarouselComponent.prototype.ngOnDestroy = function () {
64 this.destroyed = true;
65 };
66 /**
67 * Adds new slide. If this slide is first in collection - set it as active and starts auto changing
68 * @param slide
69 */
70 CarouselComponent.prototype.addSlide = function (slide) {
71 this._slides.add(slide);
72 if (this._slides.length === 1) {
73 this._currentActiveSlide = void 0;
74 this.activeSlide = 0;
75 this.play();
76 }
77 };
78 /**
79 * Removes specified slide. If this slide is active - will roll to another slide
80 * @param slide
81 */
82 CarouselComponent.prototype.removeSlide = function (slide) {
83 var _this = this;
84 var remIndex = this._slides.indexOf(slide);
85 if (this._currentActiveSlide === remIndex) {
86 // removing of active slide
87 var nextSlideIndex_1 = void 0;
88 if (this._slides.length > 1) {
89 // if this slide last - will roll to first slide, if noWrap flag is FALSE or to previous, if noWrap is TRUE
90 // in case, if this slide in middle of collection, index of next slide is same to removed
91 nextSlideIndex_1 = !this.isLast(remIndex) ? remIndex :
92 this.noWrap ? remIndex - 1 : 0;
93 }
94 this._slides.remove(remIndex);
95 // prevents exception with changing some value after checking
96 setTimeout(function () {
97 _this._select(nextSlideIndex_1);
98 }, 0);
99 }
100 else {
101 this._slides.remove(remIndex);
102 var currentSlideIndex_1 = this.getCurrentSlideIndex();
103 setTimeout(function () {
104 // after removing, need to actualize index of current active slide
105 _this._currentActiveSlide = currentSlideIndex_1;
106 _this.activeSlideChange.emit(_this._currentActiveSlide);
107 }, 0);
108 }
109 };
110 /**
111 * Rolling to next slide
112 * @param force: {boolean} if true - will ignore noWrap flag
113 */
114 CarouselComponent.prototype.nextSlide = function (force) {
115 if (force === void 0) { force = false; }
116 this.activeSlide = this.findNextSlideIndex(Direction.NEXT, force);
117 };
118 /**
119 * Rolling to previous slide
120 * @param force: {boolean} if true - will ignore noWrap flag
121 */
122 CarouselComponent.prototype.previousSlide = function (force) {
123 if (force === void 0) { force = false; }
124 this.activeSlide = this.findNextSlideIndex(Direction.PREV, force);
125 };
126 /**
127 * Rolling to specified slide
128 * @param index: {number} index of slide, which must be shown
129 */
130 CarouselComponent.prototype.selectSlide = function (index) {
131 this.activeSlide = index;
132 };
133 /**
134 * Starts a auto changing of slides
135 */
136 CarouselComponent.prototype.play = function () {
137 if (!this.isPlaying) {
138 this.isPlaying = true;
139 this.restartTimer();
140 }
141 };
142 /**
143 * Stops a auto changing of slides
144 */
145 CarouselComponent.prototype.pause = function () {
146 if (!this.noPause) {
147 this.isPlaying = false;
148 this.resetTimer();
149 }
150 };
151 /**
152 * Finds and returns index of currently displayed slide
153 * @returns {number}
154 */
155 CarouselComponent.prototype.getCurrentSlideIndex = function () {
156 return this._slides.findIndex(function (slide) { return slide.active; });
157 };
158 /**
159 * Defines, whether the specified index is last in collection
160 * @param index
161 * @returns {boolean}
162 */
163 CarouselComponent.prototype.isLast = function (index) {
164 return index + 1 >= this._slides.length;
165 };
166 /**
167 * Defines next slide index, depending of direction
168 * @param direction: Direction(UNKNOWN|PREV|NEXT)
169 * @param force: {boolean} if TRUE - will ignore noWrap flag, else will return undefined if next slide require wrapping
170 * @returns {any}
171 */
172 CarouselComponent.prototype.findNextSlideIndex = function (direction, force) {
173 var nextSlideIndex = 0;
174 if (!force && (this.isLast(this.activeSlide) && direction !== Direction.PREV && this.noWrap)) {
175 return void 0;
176 }
177 switch (direction) {
178 case Direction.NEXT:
179 // if this is last slide, not force, looping is disabled and need to going forward - select current slide, as a next
180 nextSlideIndex = (!this.isLast(this._currentActiveSlide)) ? this._currentActiveSlide + 1 :
181 (!force && this.noWrap) ? this._currentActiveSlide : 0;
182 break;
183 case Direction.PREV:
184 // if this is first slide, not force, looping is disabled and need to going backward - select current slide, as a next
185 nextSlideIndex = (this._currentActiveSlide > 0) ? this._currentActiveSlide - 1 :
186 (!force && this.noWrap) ? this._currentActiveSlide : this._slides.length - 1;
187 break;
188 default:
189 throw new Error('Unknown direction');
190 }
191 return nextSlideIndex;
192 };
193 /**
194 * Sets a slide, which specified through index, as active
195 * @param index
196 * @private
197 */
198 CarouselComponent.prototype._select = function (index) {
199 if (isNaN(index)) {
200 this.pause();
201 return;
202 }
203 var currentSlide = this._slides.get(this._currentActiveSlide);
204 if (currentSlide) {
205 currentSlide.active = false;
206 }
207 var nextSlide = this._slides.get(index);
208 if (nextSlide) {
209 this._currentActiveSlide = index;
210 nextSlide.active = true;
211 this.activeSlide = index;
212 this.activeSlideChange.emit(index);
213 }
214 };
215 /**
216 * Starts loop of auto changing of slides
217 */
218 CarouselComponent.prototype.restartTimer = function () {
219 var _this = this;
220 this.resetTimer();
221 var interval = +this.interval;
222 if (!isNaN(interval) && interval > 0) {
223 this.currentInterval = setInterval(function () {
224 var nInterval = +_this.interval;
225 if (_this.isPlaying && !isNaN(_this.interval) && nInterval > 0 && _this.slides.length) {
226 _this.nextSlide();
227 }
228 else {
229 _this.pause();
230 }
231 }, interval);
232 }
233 };
234 /**
235 * Stops loop of auto changing of slides
236 */
237 CarouselComponent.prototype.resetTimer = function () {
238 if (this.currentInterval) {
239 clearInterval(this.currentInterval);
240 this.currentInterval = void 0;
241 }
242 };
243 CarouselComponent.decorators = [
244 { type: Component, args: [{
245 selector: 'carousel',
246 template: "\n <div (mouseenter)=\"pause()\" (mouseleave)=\"play()\" (mouseup)=\"play()\" class=\"carousel slide\">\n <ol class=\"carousel-indicators\" *ngIf=\"slides.length > 1\">\n <li *ngFor=\"let slidez of slides; let i = index;\" [class.active]=\"slidez.active === true\" (click)=\"selectSlide(i)\"></li>\n </ol>\n <div class=\"carousel-inner\"><ng-content></ng-content></div>\n <a class=\"left carousel-control carousel-control-prev\" [class.disabled]=\"activeSlide === 0 && noWrap\" (click)=\"previousSlide()\" *ngIf=\"slides.length > 1\">\n <span class=\"icon-prev carousel-control-prev-icon\" aria-hidden=\"true\"></span>\n <span *ngIf=\"isBs4\" class=\"sr-only\">Previous</span>\n </a>\n <a class=\"right carousel-control carousel-control-next\" (click)=\"nextSlide()\" [class.disabled]=\"isLast(activeSlide) && noWrap\" *ngIf=\"slides.length > 1\">\n <span class=\"icon-next carousel-control-next-icon\" aria-hidden=\"true\"></span>\n <span class=\"sr-only\">Next</span>\n </a>\n </div>\n "
247 },] },
248 ];
249 /** @nocollapse */
250 CarouselComponent.ctorParameters = function () { return [
251 { type: CarouselConfig, },
252 ]; };
253 CarouselComponent.propDecorators = {
254 'noWrap': [{ type: Input },],
255 'noPause': [{ type: Input },],
256 'activeSlideChange': [{ type: Output },],
257 'activeSlide': [{ type: Input },],
258 'interval': [{ type: Input },],
259 };
260 return CarouselComponent;
261}());
262//# sourceMappingURL=carousel.component.js.map
\No newline at end of file