UNPKG

ngx-progressbar

Version:

<p align="center"> <img height="200px" width="200px" style="text-align: center;" src="https://gitcdn.xyz/repo/MurhafSousli/ngx-progressbar/master/projects/ngx-progressbar-demo/src/assets/logo.svg"> <h1 align="center">Angular Progressbar</h1> </p>

411 lines (402 loc) 21.8 kB
import { Subject, Subscription, BehaviorSubject, combineLatest, timer, EMPTY, of } from 'rxjs'; import { filter, debounce, switchMap, tap, delay, finalize, takeUntil, map } from 'rxjs/operators'; import * as i0 from '@angular/core'; import { InjectionToken, Injectable, Optional, Inject, EventEmitter, Component, ChangeDetectionStrategy, Input, Output, NgModule } from '@angular/core'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; class NgProgressRef { constructor(customConfig, _onDestroyCallback) { this._onDestroyCallback = _onDestroyCallback; // Progress start source event (used to cancel finalizing delays) this._started = new Subject(); // Progress start event: stream that emits only when it hasn't already started this.started = this._started.pipe(filter(() => !this.isStarted)); // Progress ended source event this._completed = new Subject(); // Progress start event: stream that emits only when it has already started this.completed = this._completed.pipe(filter(() => this.isStarted)); // Stream that increments and updates the progress state this._trickling = new Subject(); // Stream that combines "_trickling" and "config" streams this._worker = Subscription.EMPTY; this._state = new BehaviorSubject({ active: false, value: 0 }); this._config = new BehaviorSubject(customConfig); this.state = this._state.asObservable(); this.config = this._config.asObservable(); this._worker = combineLatest([this._trickling, this._config]).pipe(debounce(([start, config]) => timer(start ? config.debounceTime : 0)), switchMap(([start, config]) => start ? this.onTrickling(config) : this.onComplete(config))).subscribe(); } // Get current progress state get snapshot() { return this._state.value; } // Check if progress has started get isStarted() { return this.snapshot.active; } /** * Start the progress */ start() { this._started.next(); this._trickling.next(true); } /** * Complete the progress */ complete() { this._trickling.next(false); } /** * Increment the progress */ inc(amount) { const n = this.snapshot.value; if (!this.isStarted) { this.start(); } else { if (typeof amount !== 'number') { amount = this._config.value.trickleFunc(n); } this.set(n + amount); } } /** * Set the progress */ set(n) { this.setState({ value: this.clamp(n), active: true }); } /** * Set config */ setConfig(config) { this._config.next(Object.assign(Object.assign({}, this._config.value), config)); } /** * Destroy progress reference */ destroy() { this._worker.unsubscribe(); this._trickling.complete(); this._state.complete(); this._config.complete(); this._started.complete(); this._completed.complete(); this._onDestroyCallback(); } /** * Set progress state */ setState(state) { this._state.next(Object.assign(Object.assign({}, this.snapshot), state)); } /** * Clamps a value to be between min and max */ clamp(n) { return Math.max(this._config.value.min, Math.min(this._config.value.max, n)); } /** * Keeps incrementing the progress */ onTrickling(config) { if (!this.isStarted) { this.set(this._config.value.min); } return timer(0, config.trickleSpeed).pipe(tap(() => this.inc())); } /** * Completes then resets the progress */ onComplete(config) { this._completed.next(); return !this.isStarted ? EMPTY : of({}).pipe( // Complete the progress tap(() => this.setState({ value: 100 })), // Deactivate the progress after a tiny delay delay(config.speed * 1.7), tap(() => this.setState({ active: false })), // Use a tiny delay before resetting delay(config.speed), // Force the progress to reset even it got cancelled finalize(() => this.setState({ value: 0 })), // Cancel any of the finalizing delays if the progress has started again takeUntil(this._started)); } } const NG_PROGRESS_CONFIG = new InjectionToken('ngProgressConfig'); const defaultConfig = { min: 8, max: 100, speed: 200, debounceTime: 0, trickleSpeed: 300, fixed: true, meteor: true, thick: false, spinner: true, ease: 'linear', color: '#1B95E0', direction: 'ltr+', spinnerPosition: 'right', trickleFunc: (n) => { if (n >= 0 && n < 20) return 10; if (n >= 20 && n < 50) return 4; if (n >= 50 && n < 80) return 2; if (n >= 80 && n < 99) return 0.5; return 0; } }; class NgProgress { constructor(config) { // Store progress bar instances this._instances = new Map(); this.config = config ? Object.assign(Object.assign({}, defaultConfig), config) : defaultConfig; } /** * Get or Create progress bar by ID */ ref(id = 'root', config) { if (this._instances.has(id)) { // Get ProgressRef instance const progressRef = this._instances.get(id); if (config) { progressRef.setConfig(Object.assign(Object.assign({}, this.config), config)); } return progressRef; } else { // Create new ProgressRef instance const progressRef = new NgProgressRef(Object.assign(Object.assign({}, this.config), config), this.deleteInstance(id)); return this._instances.set(id, progressRef).get(id); } } /** * Destroy all progress bar instances */ destroyAll() { this._instances.forEach((ref) => ref.destroy()); } /** * A destroyer function for each progress bar instance */ deleteInstance(id) { return () => { this._instances.delete(id); }; } } NgProgress.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgress, deps: [{ token: NG_PROGRESS_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); NgProgress.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgress, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgress, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_PROGRESS_CONFIG] }] }]; } }); class NgProgressComponent { constructor(_ngProgress) { this._ngProgress = _ngProgress; /** Creates a new instance if id is not already exists */ this.id = 'root'; /** Initializes inputs from the global config */ this.min = this._ngProgress.config.min; this.max = this._ngProgress.config.max; this.ease = this._ngProgress.config.ease; this.color = this._ngProgress.config.color; this.speed = this._ngProgress.config.speed; this.thick = this._ngProgress.config.thick; this.fixed = this._ngProgress.config.fixed; this.meteor = this._ngProgress.config.meteor; this.spinner = this._ngProgress.config.spinner; this.trickleSpeed = this._ngProgress.config.trickleSpeed; this.debounceTime = this._ngProgress.config.debounceTime; this.trickleFunc = this._ngProgress.config.trickleFunc; this.spinnerPosition = this._ngProgress.config.spinnerPosition; this.direction = this._ngProgress.config.direction; this.started = new EventEmitter(); this.completed = new EventEmitter(); } get isStarted() { var _a; return (_a = this.progressRef) === null || _a === void 0 ? void 0 : _a.isStarted; } ngOnChanges() { var _a; // Update progress bar config when inputs change (_a = this.progressRef) === null || _a === void 0 ? void 0 : _a.setConfig({ max: (this.max > 0 && this.max <= 100) ? this.max : 100, min: (this.min < 100 && this.min >= 0) ? this.min : 0, speed: this.speed, trickleSpeed: this.trickleSpeed, trickleFunc: this.trickleFunc, debounceTime: this.debounceTime }); } ngOnInit() { // Get progress bar service instance this.progressRef = this._ngProgress.ref(this.id, { max: this.max, min: this.min, speed: this.speed, trickleSpeed: this.trickleSpeed, debounceTime: this.debounceTime }); // Subscribe to progress state this.state$ = this.progressRef.state.pipe(map((state) => ({ active: state.active, transform: `translate3d(${state.value}%,0,0)` }))); // Subscribes to started and completed events on demand if (this.started.observed) { this._started = this.progressRef.started.subscribe(() => this.started.emit()); } if (this.completed.observed) { this._completed = this.progressRef.completed.subscribe(() => this.completed.emit()); } } ngOnDestroy() { var _a, _b, _c; (_a = this._started) === null || _a === void 0 ? void 0 : _a.unsubscribe(); (_b = this._completed) === null || _b === void 0 ? void 0 : _b.unsubscribe(); (_c = this.progressRef) === null || _c === void 0 ? void 0 : _c.destroy(); } start() { this.progressRef.start(); } complete() { this.progressRef.complete(); } inc(n) { this.progressRef.inc(n); } set(n) { this.progressRef.set(n); } } NgProgressComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgressComponent, deps: [{ token: NgProgress }], target: i0.ɵɵFactoryTarget.Component }); NgProgressComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.0", type: NgProgressComponent, selector: "ng-progress", inputs: { id: "id", min: "min", max: "max", ease: "ease", color: "color", speed: "speed", thick: "thick", fixed: "fixed", meteor: "meteor", spinner: "spinner", trickleSpeed: "trickleSpeed", debounceTime: "debounceTime", trickleFunc: "trickleFunc", spinnerPosition: "spinnerPosition", direction: "direction" }, outputs: { started: "started", completed: "completed" }, host: { attributes: { "role": "progressbar" }, properties: { "attr.spinnerPosition": "spinnerPosition", "attr.direction": "direction", "attr.thick": "thick", "attr.fixed": "fixed" } }, usesOnChanges: true, ngImport: i0, template: ` <ng-container *ngIf="state$ | async; let state"> <div class="ng-progress-bar" [attr.active]="state.active" [style.transition]="'opacity ' + speed + 'ms ' + ease"> <div class="ng-bar-placeholder"> <div class="ng-bar" [style.transform]="state.transform" [style.backgroundColor]="color" [style.transition]="state.active ? 'all ' + speed + 'ms ' + ease : 'none'"> <div *ngIf="meteor" class="ng-meteor" [style.boxShadow]="'0 0 10px '+ color + ', 0 0 5px ' + color"></div> </div> </div> <div *ngIf="spinner" class="ng-spinner"> <div class="ng-spinner-icon" [style.borderTopColor]="color" [style.borderLeftColor]="color"></div> </div> </div> </ng-container> `, isInline: true, styles: [":host{z-index:999999;pointer-events:none}:host[fixed=true] .ng-progress-bar,:host[fixed=true] .ng-spinner{position:fixed}:host[fixed=true] .ng-spinner{top:15px}:host[fixed=true][spinnerPosition=left] .ng-spinner{left:15px}:host[fixed=true][spinnerPosition=right] .ng-spinner{right:15px}:host[thick=true] .ng-spinner-icon{width:24px;height:24px;border-width:3px}:host[thick=true] .ng-bar-placeholder{height:3px!important}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=ltr-] .ng-meteor{transform:rotate(3deg)}:host[direction=\"ltr+\"][thick=true] .ng-meteor,:host[direction=ltr-][thick=true] .ng-meteor{transform:rotate(4deg)}:host[direction=\"ltr+\"] .ng-bar,:host[direction=\"rtl+\"] .ng-bar{margin-left:-100%}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=\"rtl+\"] .ng-meteor{right:0}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=rtl-] .ng-meteor{top:-3px}:host[direction=\"ltr+\"][thick=true] .ng-meteor,:host[direction=rtl-][thick=true] .ng-meteor{top:-4px}:host[direction=ltr-] .ng-meteor,:host[direction=\"rtl+\"] .ng-meteor{bottom:-3px}:host[direction=ltr-][thick=true] .ng-meteor,:host[direction=\"rtl+\"][thick=true] .ng-meteor{bottom:-4px}:host[direction=ltr-] .ng-bar-placeholder,:host[direction=\"rtl+\"] .ng-bar-placeholder{transform:rotate(180deg)}:host[direction=ltr-] .ng-spinner-icon,:host[direction=\"rtl+\"] .ng-spinner-icon{animation-directionection:reverse}:host[direction=\"rtl+\"] .ng-meteor,:host[direction=rtl-] .ng-meteor{transform:rotate(-3deg)}:host[direction=\"rtl+\"][thick=true] .ng-meteor,:host[direction=rtl-][thick=true] .ng-meteor{transform:rotate(-4deg)}:host[spinnerPosition=left] .ng-spinner{left:10px}:host[spinnerPosition=right] .ng-spinner{right:10px}.ng-progress-bar{position:relative;z-index:999999;top:0;left:0;width:100%;transform:scale(1);filter:alpha(opacity=0);opacity:0}.ng-progress-bar[active=true]{filter:alpha(opacity=100);opacity:1;transition:none}.ng-bar-placeholder{position:absolute;height:2px;width:100%}.ng-bar{width:100%;height:100%;transform:translate(-100%,0,0)}.ng-meteor{display:block;position:absolute;width:100px;height:100%;opacity:1}.ng-spinner{position:absolute;display:block;z-index:1031;top:10px}.ng-spinner-icon{width:18px;height:18px;box-sizing:border-box;-webkit-animation:spinner-animation .25s linear infinite;animation:spinner-animation .25s linear infinite;border:2px solid transparent;border-radius:50%}@-webkit-keyframes spinner-animation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spinner-animation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgressComponent, decorators: [{ type: Component, args: [{ selector: 'ng-progress', host: { 'role': 'progressbar', '[attr.spinnerPosition]': 'spinnerPosition', '[attr.direction]': 'direction', '[attr.thick]': 'thick', '[attr.fixed]': 'fixed' }, template: ` <ng-container *ngIf="state$ | async; let state"> <div class="ng-progress-bar" [attr.active]="state.active" [style.transition]="'opacity ' + speed + 'ms ' + ease"> <div class="ng-bar-placeholder"> <div class="ng-bar" [style.transform]="state.transform" [style.backgroundColor]="color" [style.transition]="state.active ? 'all ' + speed + 'ms ' + ease : 'none'"> <div *ngIf="meteor" class="ng-meteor" [style.boxShadow]="'0 0 10px '+ color + ', 0 0 5px ' + color"></div> </div> </div> <div *ngIf="spinner" class="ng-spinner"> <div class="ng-spinner-icon" [style.borderTopColor]="color" [style.borderLeftColor]="color"></div> </div> </div> </ng-container> `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{z-index:999999;pointer-events:none}:host[fixed=true] .ng-progress-bar,:host[fixed=true] .ng-spinner{position:fixed}:host[fixed=true] .ng-spinner{top:15px}:host[fixed=true][spinnerPosition=left] .ng-spinner{left:15px}:host[fixed=true][spinnerPosition=right] .ng-spinner{right:15px}:host[thick=true] .ng-spinner-icon{width:24px;height:24px;border-width:3px}:host[thick=true] .ng-bar-placeholder{height:3px!important}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=ltr-] .ng-meteor{transform:rotate(3deg)}:host[direction=\"ltr+\"][thick=true] .ng-meteor,:host[direction=ltr-][thick=true] .ng-meteor{transform:rotate(4deg)}:host[direction=\"ltr+\"] .ng-bar,:host[direction=\"rtl+\"] .ng-bar{margin-left:-100%}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=\"rtl+\"] .ng-meteor{right:0}:host[direction=\"ltr+\"] .ng-meteor,:host[direction=rtl-] .ng-meteor{top:-3px}:host[direction=\"ltr+\"][thick=true] .ng-meteor,:host[direction=rtl-][thick=true] .ng-meteor{top:-4px}:host[direction=ltr-] .ng-meteor,:host[direction=\"rtl+\"] .ng-meteor{bottom:-3px}:host[direction=ltr-][thick=true] .ng-meteor,:host[direction=\"rtl+\"][thick=true] .ng-meteor{bottom:-4px}:host[direction=ltr-] .ng-bar-placeholder,:host[direction=\"rtl+\"] .ng-bar-placeholder{transform:rotate(180deg)}:host[direction=ltr-] .ng-spinner-icon,:host[direction=\"rtl+\"] .ng-spinner-icon{animation-directionection:reverse}:host[direction=\"rtl+\"] .ng-meteor,:host[direction=rtl-] .ng-meteor{transform:rotate(-3deg)}:host[direction=\"rtl+\"][thick=true] .ng-meteor,:host[direction=rtl-][thick=true] .ng-meteor{transform:rotate(-4deg)}:host[spinnerPosition=left] .ng-spinner{left:10px}:host[spinnerPosition=right] .ng-spinner{right:10px}.ng-progress-bar{position:relative;z-index:999999;top:0;left:0;width:100%;transform:scale(1);filter:alpha(opacity=0);opacity:0}.ng-progress-bar[active=true]{filter:alpha(opacity=100);opacity:1;transition:none}.ng-bar-placeholder{position:absolute;height:2px;width:100%}.ng-bar{width:100%;height:100%;transform:translate(-100%,0,0)}.ng-meteor{display:block;position:absolute;width:100px;height:100%;opacity:1}.ng-spinner{position:absolute;display:block;z-index:1031;top:10px}.ng-spinner-icon{width:18px;height:18px;box-sizing:border-box;-webkit-animation:spinner-animation .25s linear infinite;animation:spinner-animation .25s linear infinite;border:2px solid transparent;border-radius:50%}@-webkit-keyframes spinner-animation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spinner-animation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }] }], ctorParameters: function () { return [{ type: NgProgress }]; }, propDecorators: { id: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], ease: [{ type: Input }], color: [{ type: Input }], speed: [{ type: Input }], thick: [{ type: Input }], fixed: [{ type: Input }], meteor: [{ type: Input }], spinner: [{ type: Input }], trickleSpeed: [{ type: Input }], debounceTime: [{ type: Input }], trickleFunc: [{ type: Input }], spinnerPosition: [{ type: Input }], direction: [{ type: Input }], started: [{ type: Output }], completed: [{ type: Output }] } }); class NgProgressModule { static withConfig(config) { return { ngModule: NgProgressModule, providers: [ { provide: NG_PROGRESS_CONFIG, useValue: config } ] }; } } NgProgressModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgressModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NgProgressModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.0", ngImport: i0, type: NgProgressModule, declarations: [NgProgressComponent], imports: [CommonModule], exports: [NgProgressComponent] }); NgProgressModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgressModule, imports: [CommonModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0", ngImport: i0, type: NgProgressModule, decorators: [{ type: NgModule, args: [{ declarations: [NgProgressComponent], exports: [NgProgressComponent], imports: [CommonModule] }] }] }); /* * Public API Surface of ngx-progressbar */ /** * Generated bundle index. Do not edit. */ export { NG_PROGRESS_CONFIG, NgProgress, NgProgressComponent, NgProgressModule, NgProgressRef }; //# sourceMappingURL=ngx-progressbar.mjs.map