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
JavaScript
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