@covalent/core
Version:
Core Teradata UI Platform for layouts, icons, custom components and themes. This should be added as a dependency for any project that wants to use layouts, icons and themes for Angular Material.
781 lines (773 loc) • 34.9 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, Injectable, Optional, SkipSelf, ComponentFactoryResolver, Injector, Directive, Input, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i4 from '@angular/cdk/portal';
import { ComponentPortal, TemplatePortal, PortalModule } from '@angular/cdk/portal';
import * as i1$1 from '@angular/cdk/overlay';
import { OverlayConfig, Overlay, OverlayModule } from '@angular/cdk/overlay';
import * as i2 from '@angular/material/progress-bar';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import * as i3 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { tdFadeInOutAnimation } from '@covalent/core/common';
import { Subject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
var LoadingType;
(function (LoadingType) {
LoadingType["Circular"] = "circular";
LoadingType["Linear"] = "linear";
})(LoadingType || (LoadingType = {}));
var LoadingMode;
(function (LoadingMode) {
LoadingMode["Determinate"] = "determinate";
LoadingMode["Indeterminate"] = "indeterminate";
})(LoadingMode || (LoadingMode = {}));
var LoadingStrategy;
(function (LoadingStrategy) {
LoadingStrategy["Overlay"] = "overlay";
LoadingStrategy["Replace"] = "replace";
})(LoadingStrategy || (LoadingStrategy = {}));
var LoadingStyle;
(function (LoadingStyle) {
LoadingStyle["FullScreen"] = "fullscreen";
LoadingStyle["Overlay"] = "overlay";
LoadingStyle["None"] = "none";
})(LoadingStyle || (LoadingStyle = {}));
const TD_CIRCLE_DIAMETER = 40;
class TdLoadingComponent {
_elementRef;
_changeDetectorRef;
_mode = LoadingMode.Indeterminate;
_defaultMode = LoadingMode.Indeterminate;
_value = 0;
_circleDiameter = TD_CIRCLE_DIAMETER;
/**
* Flag for animation
*/
animation = false;
/**
* Content injected into loading component.
*/
content;
/**
* Sets mode of [TdLoadingComponent] to LoadingMode.Determinate or LoadingMode.Indeterminate
*/
set mode(mode) {
this._defaultMode = mode;
}
get mode() {
return this._mode;
}
/**
* Sets value of [TdLoadingComponent] if mode is 'LoadingMode.Determinate'
*/
set value(value) {
this._value = value;
// Check for changes for `OnPush` change detection
this._changeDetectorRef.markForCheck();
}
get value() {
return this._value;
}
style = LoadingStyle.None;
/**
* height: number
* Sets height of [TdLoadingComponent].
*/
height = 100;
/**
* type: LoadingType
* Sets type of [TdLoadingComponent] rendered.
*/
type = LoadingType.Circular;
/**
* color: primary' | 'accent' | 'warn'
* Sets theme color of [TdLoadingComponent] rendered.
*/
color = 'primary';
constructor(_elementRef, _changeDetectorRef) {
this._elementRef = _elementRef;
this._changeDetectorRef = _changeDetectorRef;
}
ngDoCheck() {
// When overlay is used and the host width has a value greater than 1px
// set the circle diameter when possible incase the loading component was rendered in a hidden state
if (this.isOverlay() && this._hostHeight() > 1 && this.animation) {
this._setCircleDiameter();
this._changeDetectorRef.markForCheck();
}
}
getHeight() {
// Ignore height if style is `overlay` or `fullscreen`.
// Add height if child elements have a height and style is `none`, else return default height.
if (this.isOverlay() || this.isFullScreen()) {
return undefined;
}
else {
return this.height ? `${this.height}px` : '150px';
}
}
getCircleDiameter() {
return this._circleDiameter;
}
getCircleStrokeWidth() {
// we calculate the stroke width by setting it as 10% of its diameter
const strokeWidth = this.getCircleDiameter() / 10;
return Math.abs(strokeWidth);
}
isCircular() {
return this.type === LoadingType.Circular;
}
isLinear() {
return this.type === LoadingType.Linear;
}
isFullScreen() {
return this.style === LoadingStyle.FullScreen;
}
isOverlay() {
return this.style === LoadingStyle.Overlay;
}
/**
* Starts in animation and returns an observable for completition event.
*/
show() {
/* need to switch back to the selected mode, so we have saved it in another variable
* and then recover it. (issue with protractor)
*/
this._mode = this._defaultMode;
// Set values before the animations starts
this._setCircleDiameter();
// Check for changes for `OnPush` change detection
this.animation = true;
this._changeDetectorRef.markForCheck();
}
/**
* Starts out animation and returns an observable for completition event.
*/
hide() {
this.animation = false;
/* need to switch back and forth from determinate/indeterminate so the setInterval()
* inside mat-progress-spinner stops and protractor doesnt timeout waiting to sync.
*/
this._mode = LoadingMode.Determinate;
// Check for changes for `OnPush` change detection
/* little hack to reset the loader value and animation before removing it from DOM
* else, the loader will appear with prev value when its registered again
* and will do an animation going prev value to 0.
*/
this.value = 0;
// Check for changes for `OnPush` change detection
this._changeDetectorRef.markForCheck();
}
/**
* Calculate the proper diameter for the circle and set it
*/
_setCircleDiameter() {
// we set a default diameter of 100 since this is the default in material
let diameter = TD_CIRCLE_DIAMETER;
// if height is provided, then we take that as diameter
if (this.height) {
diameter = this.height;
// else if its not provided, then we take the host height
}
else if (this.height === undefined) {
diameter = this._hostHeight();
}
// if the diameter is over TD_CIRCLE_DIAMETER, we set TD_CIRCLE_DIAMETER
if (diameter <= TD_CIRCLE_DIAMETER) {
this._circleDiameter = Math.floor(diameter);
}
else {
this._circleDiameter = TD_CIRCLE_DIAMETER;
}
}
/**
* Returns the host height of the loading component
*/
_hostHeight() {
if (this._elementRef.nativeElement) {
return (this._elementRef.nativeElement).getBoundingClientRect().height;
}
return 0;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: TdLoadingComponent, selector: "td-loading", ngImport: i0, template: "<div\n class=\"td-loading-wrapper\"\n [style.min-height]=\"getHeight()\"\n [class.td-overlay-circular]=\"(isOverlay() || isFullScreen()) && !isLinear()\"\n [class.td-overlay]=\"isOverlay() || isFullScreen()\"\n [class.td-fullscreen]=\"isFullScreen()\"\n>\n <div\n [@tdFadeInOut]=\"animation\"\n [style.min-height]=\"getHeight()\"\n class=\"td-loading\"\n >\n <mat-progress-spinner\n *ngIf=\"isCircular()\"\n [mode]=\"mode\"\n [value]=\"value\"\n [color]=\"color\"\n [diameter]=\"getCircleDiameter()\"\n [strokeWidth]=\"getCircleStrokeWidth()\"\n ></mat-progress-spinner>\n <mat-progress-bar\n *ngIf=\"isLinear()\"\n [mode]=\"mode\"\n [value]=\"value\"\n [color]=\"color\"\n ></mat-progress-bar>\n </div>\n <ng-template [cdkPortalOutlet]=\"content\"></ng-template>\n</div>\n", styles: [".td-loading-wrapper{position:relative;display:block}.td-loading-wrapper.td-fullscreen{position:inherit}.td-loading-wrapper .td-loading{box-sizing:border-box;display:flex;flex-direction:row;align-items:center;align-content:center;max-width:100%;justify-content:center;flex:1}.td-loading-wrapper.td-overlay .td-loading{position:absolute;margin:0;top:0;left:0;right:0;z-index:1000}.td-loading-wrapper.td-overlay .td-loading mat-progress-bar{position:absolute;top:0;left:0;right:0}.td-loading-wrapper.td-overlay-circular .td-loading{bottom:0}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i4.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [tdFadeInOutAnimation] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingComponent, decorators: [{
type: Component,
args: [{ selector: 'td-loading', animations: [tdFadeInOutAnimation], template: "<div\n class=\"td-loading-wrapper\"\n [style.min-height]=\"getHeight()\"\n [class.td-overlay-circular]=\"(isOverlay() || isFullScreen()) && !isLinear()\"\n [class.td-overlay]=\"isOverlay() || isFullScreen()\"\n [class.td-fullscreen]=\"isFullScreen()\"\n>\n <div\n [@tdFadeInOut]=\"animation\"\n [style.min-height]=\"getHeight()\"\n class=\"td-loading\"\n >\n <mat-progress-spinner\n *ngIf=\"isCircular()\"\n [mode]=\"mode\"\n [value]=\"value\"\n [color]=\"color\"\n [diameter]=\"getCircleDiameter()\"\n [strokeWidth]=\"getCircleStrokeWidth()\"\n ></mat-progress-spinner>\n <mat-progress-bar\n *ngIf=\"isLinear()\"\n [mode]=\"mode\"\n [value]=\"value\"\n [color]=\"color\"\n ></mat-progress-bar>\n </div>\n <ng-template [cdkPortalOutlet]=\"content\"></ng-template>\n</div>\n", styles: [".td-loading-wrapper{position:relative;display:block}.td-loading-wrapper.td-fullscreen{position:inherit}.td-loading-wrapper .td-loading{box-sizing:border-box;display:flex;flex-direction:row;align-items:center;align-content:center;max-width:100%;justify-content:center;flex:1}.td-loading-wrapper.td-overlay .td-loading{position:absolute;margin:0;top:0;left:0;right:0;z-index:1000}.td-loading-wrapper.td-overlay .td-loading mat-progress-bar{position:absolute;top:0;left:0;right:0}.td-loading-wrapper.td-overlay-circular .td-loading{bottom:0}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }] });
/**
* NOTE: @internal usage only.
*/
class TdLoadingFactory {
_componentFactoryResolver;
_overlay;
_injector;
constructor(_componentFactoryResolver, _overlay, _injector) {
this._componentFactoryResolver = _componentFactoryResolver;
this._overlay = _overlay;
this._injector = _injector;
}
/**
* Uses material `Overlay` services to create a DOM element and attach the loading component
* into it. Leveraging the state and configuration from it.
*
* Saves a reference in context to be called when registering/resolving the loading element.
*/
createFullScreenComponent(options) {
options.height = undefined;
options.style = LoadingStyle.FullScreen;
const loadingRef = this._initializeContext();
let loading = false;
let overlayRef;
loadingRef.observable
.pipe(distinctUntilChanged())
.subscribe((registered) => {
if (registered > 0 && !loading) {
loading = true;
overlayRef = this._createOverlay();
loadingRef.componentRef = overlayRef.attach(new ComponentPortal(TdLoadingComponent));
this._mapOptions(options, loadingRef.componentRef?.instance);
loadingRef.componentRef?.instance.show();
loadingRef.componentRef?.changeDetectorRef.detectChanges();
}
else if (registered <= 0 && loading) {
loading = false;
loadingRef.componentRef?.instance.hide();
loadingRef.componentRef?.destroy();
overlayRef.detach();
overlayRef.dispose();
}
});
return loadingRef;
}
/**
* Creates a loading component dynamically and attaches it into the given viewContainerRef.
* Leverages TemplatePortals from material to inject the template inside of it so it fits
* perfectly when overlaying it.
*
* Saves a reference in context to be called when registering/resolving the loading element.
*/
createOverlayComponent(options, viewContainerRef, templateRef) {
options.height = undefined;
options.style = LoadingStyle.Overlay;
const loadingRef = this._createComponent(options);
let loading = false;
if (loadingRef.componentRef) {
loadingRef.componentRef.instance.content = new TemplatePortal(templateRef, viewContainerRef);
viewContainerRef.clear();
viewContainerRef.insert(loadingRef.componentRef?.hostView, 0);
}
loadingRef.observable
.pipe(distinctUntilChanged())
.subscribe((registered) => {
if (registered > 0 && !loading) {
loading = true;
loadingRef.componentRef?.instance.show();
}
else if (registered <= 0 && loading) {
loading = false;
loadingRef.componentRef?.instance.hide();
}
});
return loadingRef;
}
/**
* Creates a loading component dynamically and attaches it into the given viewContainerRef.
* Replaces the template with the loading component depending if it was registered or resolved.
*
* Saves a reference in context to be called when registering/resolving the loading element.
*/
createReplaceComponent(options, viewContainerRef, templateRef, context) {
const nativeElement = (templateRef.elementRef.nativeElement);
options.height = nativeElement.nextElementSibling
? nativeElement.nextElementSibling.scrollHeight
: undefined;
options.style = LoadingStyle.None;
const loadingRef = this._createComponent(options);
let loading = false;
// passing context so when the template is attached, we can keep the reference of the variables
const contentRef = viewContainerRef.createEmbeddedView(templateRef, context);
loadingRef.observable
.pipe(distinctUntilChanged())
.subscribe((registered) => {
if (registered > 0 && !loading && loadingRef.componentRef) {
loading = true;
// detach the content and attach the loader if loader is there
const index = viewContainerRef.indexOf(loadingRef.componentRef.hostView);
if (index < 0) {
viewContainerRef.detach(viewContainerRef.indexOf(contentRef));
viewContainerRef.insert(loadingRef.componentRef.hostView, 0);
}
loadingRef.componentRef?.instance.show();
}
else if (registered <= 0 && loading && loadingRef.componentRef) {
loading = false;
loadingRef.componentRef?.instance.hide();
// detach loader and attach the content if content is there
const index = viewContainerRef.indexOf(contentRef);
if (index < 0) {
viewContainerRef.detach(viewContainerRef.indexOf(loadingRef.componentRef.hostView));
viewContainerRef.insert(contentRef, 0);
}
/**
* Need to call "markForCheck" and "detectChanges" on attached template, so its detected by parent component when attached
* with "OnPush" change detection
*/
contentRef.detectChanges();
contentRef.markForCheck();
}
});
return loadingRef;
}
/**
* Creates a fullscreen overlay for the loading usage.
*/
_createOverlay() {
const state = new OverlayConfig();
state.hasBackdrop = false;
state.positionStrategy = this._overlay
.position()
.global()
.centerHorizontally()
.centerVertically();
return this._overlay.create(state);
}
/**
* Creates a generic component dynamically waiting to be attached to a viewContainerRef.
*/
_createComponent(options) {
const compRef = this._initializeContext();
compRef.componentRef = this._componentFactoryResolver
.resolveComponentFactory(TdLoadingComponent)
.create(this._injector);
this._mapOptions(options, compRef.componentRef.instance);
return compRef;
}
/**
* Initialize context for loading component.
*/
_initializeContext() {
const subject = new Subject();
return {
observable: subject.asObservable(),
subject,
componentRef: undefined,
times: 0,
};
}
/**
* Maps configuration to the loading component instance.
*/
_mapOptions(options, instance) {
if (options.style) {
instance.style = options.style;
}
if (options.type !== undefined) {
instance.type = options.type;
}
if (options.height !== undefined) {
instance.height = options.height;
}
if (options.mode !== undefined) {
instance.mode = options.mode;
}
if (options.color !== undefined) {
instance.color = options.color;
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingFactory, deps: [{ token: i0.ComponentFactoryResolver }, { token: i1$1.Overlay }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingFactory });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingFactory, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i0.ComponentFactoryResolver }, { type: i1$1.Overlay }, { type: i0.Injector }] });
function LOADING_FACTORY_PROVIDER_FACTORY(parent, componentFactoryResolver, overlay, injector) {
return (parent || new TdLoadingFactory(componentFactoryResolver, overlay, injector));
}
const LOADING_FACTORY_PROVIDER = {
// If there is already a service available, use that. Otherwise, provide a new one.
provide: TdLoadingFactory,
deps: [
[new Optional(), new SkipSelf(), TdLoadingFactory],
ComponentFactoryResolver,
Overlay,
Injector,
],
useFactory: LOADING_FACTORY_PROVIDER_FACTORY,
};
class TdLoadingConfig {
name;
type;
mode;
color;
constructor(config) {
this.name = config.name;
if (!this.name) {
throw Error('Name is required for [TdLoading] configuration.');
}
this.mode = config.mode ? config.mode : LoadingMode.Indeterminate;
this.type = config.type ? config.type : LoadingType.Circular;
this.color = config.color ? config.color : 'primary';
}
}
class TdLoadingDirectiveConfig extends TdLoadingConfig {
strategy;
constructor(config) {
super(config);
this.strategy = config.strategy ? config.strategy : LoadingStrategy.Replace;
}
}
class TdLoadingService {
_loadingFactory;
_context = {};
_timeouts = {};
constructor(_loadingFactory) {
this._loadingFactory = _loadingFactory;
this.create({
name: 'td-loading-main',
});
}
/**
* params:
* - config: ILoadingDirectiveConfig
* - viewContainerRef: ViewContainerRef
* - templateRef: TemplateRef<Object>
*
* Creates an replace loading mask and attaches it to the viewContainerRef.
* Replaces the templateRef with the mask when a request is registered on it.
*
* NOTE: @internal usage only.
*/
createComponent(config, viewContainerRef, templateRef, context) {
const directiveConfig = new TdLoadingDirectiveConfig(config);
if (this._context[directiveConfig.name]) {
throw Error(`Name duplication: [TdLoading] directive has a name conflict with ${directiveConfig.name}.`);
}
if (directiveConfig.strategy === LoadingStrategy.Overlay) {
this._context[directiveConfig.name] =
this._loadingFactory.createOverlayComponent(directiveConfig, viewContainerRef, templateRef);
}
else {
this._context[directiveConfig.name] =
this._loadingFactory.createReplaceComponent(directiveConfig, viewContainerRef, templateRef, context);
}
return this._context[directiveConfig.name];
}
/**
* params:
* - config: ITdLoadingConfig
*
* Creates a fullscreen loading mask and attaches it to the DOM with the given configuration.
* Only displayed when the mask has a request registered on it.
*/
create(config) {
const fullscreenConfig = new TdLoadingConfig(config);
this.removeComponent(fullscreenConfig.name);
this._context[fullscreenConfig.name] =
this._loadingFactory.createFullScreenComponent(fullscreenConfig);
}
/**
* params:
* - name: string
*
* Removes `loading` component from service context.
*/
removeComponent(name) {
if (this._context[name]) {
this._context[name].subject.unsubscribe();
if (this._context[name].componentRef) {
this._context[name].componentRef?.destroy();
}
delete this._context[name];
}
}
/**
* params:
* - name: string
* - registers?: number
* returns: true if successful
*
* Resolves a request for the loading mask referenced by the name parameter.
* Can optionally pass registers argument to set a number of register calls.
*
* If no paramemeters are used, then default main mask will be used.
*
* e.g. loadingService.register()
*/
register(name = 'td-loading-main', registers = 1) {
// try registering into the service if the loading component has been instanciated or if it exists.
if (this._context[name]) {
registers = registers < 1 ? 1 : registers;
this._context[name].times += registers;
this._context[name].subject.next(this._context[name].times);
return true;
}
else {
// if it doesnt exist, set a timeout so its registered after change detection happens
// this in case "register" occured on the `ngOnInit` lifehook cycle.
if (!this._timeouts[name]) {
this._timeouts[name] = setTimeout(() => {
this.register(name, registers);
});
}
else {
// if it timeout occured and still doesnt exist, it means the tiemout wasnt needed so we clear it.
this._clearTimeout(name);
}
}
return false;
}
/**
* params:
* - name: string
* - resolves?: number
* returns: true if successful
*
* Resolves a request for the loading mask referenced by the name parameter.
* Can optionally pass resolves argument to set a number of resolve calls.
*
* If no paramemeters are used, then default main mask will be used.
*
* e.g. loadingService.resolve()
*/
resolve(name = 'td-loading-main', resolves = 1) {
// clear timeout if the loading component is "resolved" before its "registered"
this._clearTimeout(name);
if (this._context[name]) {
resolves = resolves < 1 ? 1 : resolves;
if (this._context[name].times) {
let times = this._context[name].times;
times -= resolves;
this._context[name].times = times < 0 ? 0 : times;
}
this._context[name].subject?.next(this._context[name].times);
return true;
}
return false;
}
/**
* params:
* - name: string
* returns: true if successful
*
* Resolves all request for the loading mask referenced by the name parameter.
*
* If no paramemeters are used, then default main mask will be used.
*
* e.g. loadingService.resolveAll()
*/
resolveAll(name = 'td-loading-main') {
// clear timeout if the loading component is "resolved" before its "registered"
this._clearTimeout(name);
if (this._context[name]) {
this._context[name].times = 0;
this._context[name].subject?.next(this._context[name].times);
return true;
}
return false;
}
/**
* params:
* - name: string
* - value: number
* returns: true if successful
*
* Set value on a loading mask referenced by the name parameter.
* Usage only available if its mode is 'determinate' and if loading is showing.
*/
setValue(name, value) {
if (this._context[name]) {
const instance = this._context[name].componentRef?.instance;
if (instance.mode === LoadingMode.Determinate && instance.animation) {
instance.value = value;
return true;
}
}
return false;
}
/**
* Clears timeout linked to the name.
* @param name Name of the loading component to be cleared
*/
_clearTimeout(name) {
clearTimeout(this._timeouts[name]);
delete this._timeouts[name];
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingService, deps: [{ token: TdLoadingFactory }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: TdLoadingFactory }] });
function LOADING_PROVIDER_FACTORY(parent, loadingFactory) {
return parent || new TdLoadingService(loadingFactory);
}
const LOADING_PROVIDER = {
// If there is already a service available, use that. Otherwise, provide a new one.
provide: TdLoadingService,
deps: [[new Optional(), new SkipSelf(), TdLoadingService], TdLoadingFactory],
useFactory: LOADING_PROVIDER_FACTORY,
};
/**
* Context class for variable reference
*/
class TdLoadingContext {
$implicit = undefined;
tdLoading = undefined;
}
// Constant for generation of the id for the next component
let TD_LOADING_NEXT_ID = 0;
class TdLoadingDirective {
_viewContainerRef;
_templateRef;
_loadingService;
_context = new TdLoadingContext();
_loadingRef;
/**
* tdLoading: string
* Name reference of the loading mask, used to register/resolve requests to the mask.
*/
name;
/**
* tdLoadingUntil?: any
* If its null, undefined or false it will be used to register requests to the mask.
* Else if its any value that can be resolved as true, it will resolve the mask.
* [name] is optional when using [until], but can still be used to register/resolve it manually.
*/
set until(until) {
if (!this.name) {
this.name = 'td-loading-until-' + TD_LOADING_NEXT_ID++;
}
this._context.$implicit = this._context.tdLoading = until;
if (!until) {
this._loadingService.register(this.name);
}
else {
this._loadingService.resolveAll(this.name);
}
}
/**
* tdLoadingType?: LoadingType or ['linear' | 'circular']
* Sets the type of loading mask depending on value.
* Defaults to [LoadingType.Circular | 'circular'].
*/
type = LoadingType.Circular;
/**
* tdLoadingMode?: LoadingMode or ['determinate' | 'indeterminate']
* Sets the mode of loading mask depending on value.
* Defaults to [LoadingMode.Indeterminate | 'indeterminate'].
*/
mode = LoadingMode.Indeterminate;
/**
* tdLoadingStrategy?: LoadingStrategy or ['replace' | 'overlay']
* Sets the strategy of loading mask depending on value.
* Defaults to [LoadingMode.Replace | 'replace'].
*/
strategy = LoadingStrategy.Replace;
/**
* tdLoadingColor?: "primary" | "accent" | "warn"
* Sets the theme color of the loading component. Defaults to "primary"
*/
color = 'primary';
constructor(_viewContainerRef, _templateRef, _loadingService) {
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this._loadingService = _loadingService;
}
/**
* Registers component in the DOM, so it will be available when calling resolve/register.
*/
ngOnInit() {
this._registerComponent();
}
/**
* Remove component when directive is destroyed.
*/
ngOnDestroy() {
this._loadingService.removeComponent(this.name);
this._loadingRef = undefined;
}
/**
* Creates [TdLoadingComponent] and attaches it to this directive's [ViewContainerRef].
* Passes this directive's [TemplateRef] to modify DOM depending on loading `strategy`.
*/
_registerComponent() {
if (!this.name) {
throw new Error('Name is needed to register loading directive');
}
// Check if `TdLoadingComponent` has been created before trying to add one again.
// There is a weird edge case when using `[routerLinkActive]` that calls the `ngOnInit` twice in a row
if (!this._loadingRef) {
this._loadingRef = this._loadingService.createComponent({
name: this.name,
type: this.type,
mode: this.mode,
color: this.color,
strategy: this.strategy,
}, this._viewContainerRef, this._templateRef, this._context);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }, { token: TdLoadingService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: TdLoadingDirective, selector: "[tdLoading]", inputs: { name: ["tdLoading", "name"], until: ["tdLoadingUntil", "until"], type: ["tdLoadingType", "type"], mode: ["tdLoadingMode", "mode"], strategy: ["tdLoadingStrategy", "strategy"], color: ["tdLoadingColor", "color"] }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TdLoadingDirective, decorators: [{
type: Directive,
args: [{
selector: '[tdLoading]',
}]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }, { type: TdLoadingService }], propDecorators: { name: [{
type: Input,
args: ['tdLoading']
}], until: [{
type: Input,
args: ['tdLoadingUntil']
}], type: [{
type: Input,
args: ['tdLoadingType']
}], mode: [{
type: Input,
args: ['tdLoadingMode']
}], strategy: [{
type: Input,
args: ['tdLoadingStrategy']
}], color: [{
type: Input,
args: ['tdLoadingColor']
}] } });
const TD_LOADING = [TdLoadingComponent, TdLoadingDirective];
class CovalentLoadingModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentLoadingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.1.2", ngImport: i0, type: CovalentLoadingModule, declarations: [TdLoadingComponent, TdLoadingDirective], imports: [CommonModule,
MatProgressBarModule,
MatProgressSpinnerModule,
OverlayModule,
PortalModule], exports: [TdLoadingComponent, TdLoadingDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentLoadingModule, providers: [LOADING_FACTORY_PROVIDER, LOADING_PROVIDER], imports: [CommonModule,
MatProgressBarModule,
MatProgressSpinnerModule,
OverlayModule,
PortalModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentLoadingModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule,
MatProgressBarModule,
MatProgressSpinnerModule,
OverlayModule,
PortalModule,
],
declarations: [TD_LOADING],
exports: [TD_LOADING],
providers: [LOADING_FACTORY_PROVIDER, LOADING_PROVIDER],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { CovalentLoadingModule, LOADING_FACTORY_PROVIDER, LOADING_FACTORY_PROVIDER_FACTORY, LOADING_PROVIDER, LOADING_PROVIDER_FACTORY, LoadingMode, LoadingStrategy, LoadingStyle, LoadingType, TD_CIRCLE_DIAMETER, TdLoadingComponent, TdLoadingConfig, TdLoadingContext, TdLoadingDirective, TdLoadingDirectiveConfig, TdLoadingFactory, TdLoadingService };
//# sourceMappingURL=covalent-core-loading.mjs.map