blob: 255365d49ab3358f159a01e58128c9300c756a11 [file] [log] [blame]
import { Component, ChangeDetectorRef, ElementRef, Injectable, ComponentFactoryResolver, SkipSelf, Optional, Injector, Directive, Input, ViewContainerRef, TemplateRef, NgModule } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { TdFadeInOutAnimation } from '@covalent/core/common';
import { TemplatePortal, ComponentPortal, PortalModule } from '@angular/cdk/portal';
import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
import { CommonModule } from '@angular/common';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/** @enum {string} */
const LoadingType = {
Circular: 'circular',
Linear: 'linear',
};
/** @enum {string} */
const LoadingMode = {
Determinate: 'determinate',
Indeterminate: 'indeterminate',
};
/** @enum {string} */
const LoadingStrategy = {
Overlay: 'overlay',
Replace: 'replace',
};
/** @enum {string} */
const LoadingStyle = {
FullScreen: 'fullscreen',
Overlay: 'overlay',
None: 'none',
};
const TD_CIRCLE_DIAMETER = 100;
class TdLoadingComponent {
/**
* @param {?} _elementRef
* @param {?} _changeDetectorRef
*/
constructor(_elementRef, _changeDetectorRef) {
this._elementRef = _elementRef;
this._changeDetectorRef = _changeDetectorRef;
this._animationIn = new Subject();
this._animationOut = new Subject();
this._mode = LoadingMode.Indeterminate;
this._defaultMode = LoadingMode.Indeterminate;
this._value = 0;
this._circleDiameter = TD_CIRCLE_DIAMETER;
/**
* Flag for animation
*/
this.animation = false;
this.style = LoadingStyle.None;
/**
* type: LoadingType
* Sets type of [TdLoadingComponent] rendered.
*/
this.type = LoadingType.Circular;
/**
* color: primary' | 'accent' | 'warn'
* Sets theme color of [TdLoadingComponent] rendered.
*/
this.color = 'primary';
}
/**
* Sets mode of [TdLoadingComponent] to LoadingMode.Determinate or LoadingMode.Indeterminate
* @param {?} mode
* @return {?}
*/
set mode(mode) {
this._defaultMode = mode;
}
/**
* @return {?}
*/
get mode() {
return this._mode;
}
/**
* Sets value of [TdLoadingComponent] if mode is 'LoadingMode.Determinate'
* @param {?} value
* @return {?}
*/
set value(value) {
this._value = value;
// Check for changes for `OnPush` change detection
this._changeDetectorRef.markForCheck();
}
/**
* @return {?}
*/
get value() {
return this._value;
}
/**
* @return {?}
*/
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) {
if (this.animation) {
this._setCircleDiameter();
this._changeDetectorRef.markForCheck();
}
}
}
/**
* @return {?}
*/
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';
}
}
/**
* @return {?}
*/
getCircleDiameter() {
return this._circleDiameter;
}
/**
* @return {?}
*/
getCircleStrokeWidth() {
// we calculate the stroke width by setting it as 10% of its diameter
let /** @type {?} */ strokeWidth = this.getCircleDiameter() / 10;
return Math.abs(strokeWidth);
}
/**
* @return {?}
*/
isCircular() {
return this.type === LoadingType.Circular;
}
/**
* @return {?}
*/
isLinear() {
return this.type === LoadingType.Linear;
}
/**
* @return {?}
*/
isFullScreen() {
return this.style === LoadingStyle.FullScreen;
}
/**
* @return {?}
*/
isOverlay() {
return this.style === LoadingStyle.Overlay;
}
/**
* @param {?} event
* @return {?}
*/
animationComplete(event) {
// Check to see if its "in" or "out" animation to execute the proper callback
if (!event.fromState) {
this.inAnimationCompleted();
}
else {
this.outAnimationCompleted();
}
}
/**
* @return {?}
*/
inAnimationCompleted() {
this._animationIn.next(undefined);
}
/**
* @return {?}
*/
outAnimationCompleted() {
/* 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();
this._animationOut.next(undefined);
}
/**
* Starts in animation and returns an observable for completition event.
* @return {?}
*/
startInAnimation() {
/* 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();
return this._animationIn.asObservable();
}
/**
* Starts out animation and returns an observable for completition event.
* @return {?}
*/
startOutAnimation() {
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
this._changeDetectorRef.markForCheck();
return this._animationOut.asObservable();
}
/**
* Calculate the proper diameter for the circle and set it
* @return {?}
*/
_setCircleDiameter() {
// we set a default diameter of 100 since this is the default in material
let /** @type {?} */ 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 && diameter <= TD_CIRCLE_DIAMETER) {
this._circleDiameter = Math.floor(diameter);
}
else {
this._circleDiameter = TD_CIRCLE_DIAMETER;
}
}
/**
* Returns the host height of the loading component
* @return {?}
*/
_hostHeight() {
if (/** @type {?} */ (this._elementRef.nativeElement)) {
return (/** @type {?} */ (this._elementRef.nativeElement)).getBoundingClientRect().height;
}
return 0;
}
}
TdLoadingComponent.decorators = [
{ type: Component, args: [{
selector: 'td-loading',
styles: [`.td-loading-wrapper{
position:relative;
display:block; }
.td-loading-wrapper.td-fullscreen{
position:inherit; }
.td-loading-wrapper .td-loading{
-webkit-box-sizing:border-box;
box-sizing:border-box;
display:-webkit-box;
display:-ms-flexbox;
display:flex;
-webkit-box-orient:horizontal;
-webkit-box-direction:normal;
-ms-flex-direction:row;
flex-direction:row;
-webkit-box-align:center;
-ms-flex-align:center;
align-items:center;
-ms-flex-line-pack:center;
align-content:center;
max-width:100%;
-webkit-box-pack:center;
-ms-flex-pack:center;
justify-content:center;
-webkit-box-flex:1;
-ms-flex:1;
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; }
`],
template: `<div class="td-loading-wrapper"
[style.min-height]="getHeight()"
[class.td-overlay-circular]="(isOverlay() || isFullScreen()) && !isLinear()"
[class.td-overlay]="isOverlay() || isFullScreen()"
[class.td-fullscreen]="isFullScreen()">
<div [@tdFadeInOut]="animation"
(@tdFadeInOut.done)="animationComplete($event)"
[style.min-height]="getHeight()"
class="td-loading">
<mat-progress-spinner *ngIf="isCircular()"
[mode]="mode"
[value]="value"
[color]="color"
[diameter]="getCircleDiameter()"
[strokeWidth]="getCircleStrokeWidth()">
</mat-progress-spinner>
<mat-progress-bar *ngIf="isLinear()"
[mode]="mode"
[value]="value"
[color]="color">
</mat-progress-bar>
</div>
<ng-template [cdkPortalHost]="content"></ng-template>
</div>`,
animations: [
TdFadeInOutAnimation(),
],
},] },
];
/** @nocollapse */
TdLoadingComponent.ctorParameters = () => [
{ type: ElementRef, },
{ type: ChangeDetectorRef, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @record
*/
/**
* @record
*/
/**
* NOTE: \@internal usage only.
*/
class TdLoadingFactory {
/**
* @param {?} _componentFactoryResolver
* @param {?} _overlay
* @param {?} _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.
* @param {?} options
* @return {?}
*/
createFullScreenComponent(options) {
(/** @type {?} */ (options)).height = undefined;
(/** @type {?} */ (options)).style = LoadingStyle.FullScreen;
let /** @type {?} */ loadingRef = this._initializeContext();
let /** @type {?} */ loading = false;
let /** @type {?} */ overlayRef;
loadingRef.observable
.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.startInAnimation();
loadingRef.componentRef.changeDetectorRef.detectChanges();
}
else if (registered <= 0 && loading) {
loading = false;
let /** @type {?} */ subs = loadingRef.componentRef.instance.startOutAnimation().subscribe(() => {
subs.unsubscribe();
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.
* @param {?} options
* @param {?} viewContainerRef
* @param {?} templateRef
* @return {?}
*/
createOverlayComponent(options, viewContainerRef, templateRef) {
(/** @type {?} */ (options)).height = undefined;
(/** @type {?} */ (options)).style = LoadingStyle.Overlay;
let /** @type {?} */ loadingRef = this._createComponent(options);
let /** @type {?} */ loading = false;
loadingRef.componentRef.instance.content = new TemplatePortal(templateRef, viewContainerRef);
viewContainerRef.clear();
viewContainerRef.insert(loadingRef.componentRef.hostView, 0);
loadingRef.observable
.subscribe((registered) => {
if (registered > 0 && !loading) {
loading = true;
loadingRef.componentRef.instance.startInAnimation();
}
else if (registered <= 0 && loading) {
loading = false;
loadingRef.componentRef.instance.startOutAnimation();
}
});
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.
* @param {?} options
* @param {?} viewContainerRef
* @param {?} templateRef
* @param {?} context
* @return {?}
*/
createReplaceComponent(options, viewContainerRef, templateRef, context) {
let /** @type {?} */ nativeElement = /** @type {?} */ (templateRef.elementRef.nativeElement);
(/** @type {?} */ (options)).height = nativeElement.nextElementSibling ?
nativeElement.nextElementSibling.scrollHeight : undefined;
(/** @type {?} */ (options)).style = LoadingStyle.None;
let /** @type {?} */ loadingRef = this._createComponent(options);
let /** @type {?} */ loading = false;
viewContainerRef.createEmbeddedView(templateRef, context);
loadingRef.observable
.subscribe((registered) => {
if (registered > 0 && !loading) {
loading = true;
let /** @type {?} */ index = viewContainerRef.indexOf(loadingRef.componentRef.hostView);
if (index < 0) {
viewContainerRef.clear();
viewContainerRef.insert(loadingRef.componentRef.hostView, 0);
}
loadingRef.componentRef.instance.startInAnimation();
}
else if (registered <= 0 && loading) {
loading = false;
let /** @type {?} */ subs = loadingRef.componentRef.instance.startOutAnimation().subscribe(() => {
subs.unsubscribe();
// passing context so when the template is re-attached, we can keep the reference of the variables
let /** @type {?} */ cdr = viewContainerRef.createEmbeddedView(templateRef, context);
viewContainerRef.detach(viewContainerRef.indexOf(loadingRef.componentRef.hostView));
/**
* Need to call "markForCheck" and "detectChanges" on attached template, so its detected by parent component when attached
* with "OnPush" change detection
*/
cdr.detectChanges();
cdr.markForCheck();
});
}
});
return loadingRef;
}
/**
* Creates a fullscreen overlay for the loading usage.
* @return {?}
*/
_createOverlay() {
let /** @type {?} */ 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.
* @param {?} options
* @return {?}
*/
_createComponent(options) {
let /** @type {?} */ 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.
* @return {?}
*/
_initializeContext() {
let /** @type {?} */ subject = new Subject();
return {
observable: subject.asObservable(),
subject: subject,
componentRef: undefined,
times: 0,
};
}
/**
* Maps configuration to the loading component instance.
* @param {?} options
* @param {?} instance
* @return {?}
*/
_mapOptions(options, instance) {
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;
}
}
}
TdLoadingFactory.decorators = [
{ type: Injectable },
];
/** @nocollapse */
TdLoadingFactory.ctorParameters = () => [
{ type: ComponentFactoryResolver, },
{ type: Overlay, },
{ type: Injector, },
];
/**
* @param {?} parent
* @param {?} componentFactoryResolver
* @param {?} overlay
* @param {?} injector
* @return {?}
*/
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,
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @record
*/
class TdLoadingConfig {
/**
* @param {?} config
*/
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';
}
}
/**
* @record
*/
class TdLoadingDirectiveConfig extends TdLoadingConfig {
/**
* @param {?} config
*/
constructor(config) {
super(config);
this.strategy = config.strategy ? config.strategy : LoadingStrategy.Replace;
}
}
class TdLoadingService {
/**
* @param {?} _loadingFactory
*/
constructor(_loadingFactory) {
this._loadingFactory = _loadingFactory;
this._context = {};
this._timeouts = {};
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.
* @param {?} config
* @param {?} viewContainerRef
* @param {?} templateRef
* @param {?} context
* @return {?}
*/
createComponent(config, viewContainerRef, templateRef, context) {
let /** @type {?} */ 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.
* @param {?} config
* @return {?}
*/
create(config) {
let /** @type {?} */ 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.
* @param {?} name
* @return {?}
*/
removeComponent(name) {
if (this._context[name]) {
this._context[name].subject.unsubscribe();
if (this._context[name].componentRef) {
this._context[name].componentRef.destroy();
}
this._context[name] = undefined;
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()
* @param {?=} name
* @param {?=} registers
* @return {?}
*/
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()
* @param {?=} name
* @param {?=} resolves
* @return {?}
*/
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 > 0) {
let /** @type {?} */ 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()
* @param {?=} name
* @return {?}
*/
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.
* @param {?} name
* @param {?} value
* @return {?}
*/
setValue(name, value) {
if (this._context[name]) {
let /** @type {?} */ 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
* @return {?}
*/
_clearTimeout(name) {
clearTimeout(this._timeouts[name]);
delete this._timeouts[name];
}
}
TdLoadingService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
TdLoadingService.ctorParameters = () => [
{ type: TdLoadingFactory, },
];
/**
* @param {?} parent
* @param {?} loadingFactory
* @return {?}
*/
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,
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Context class for variable reference
*/
class TdLoadingContext {
constructor() {
this.$implicit = undefined;
this.tdLoading = undefined;
}
}
// Constant for generation of the id for the next component
let TD_LOADING_NEXT_ID = 0;
class TdLoadingDirective {
/**
* @param {?} _viewContainerRef
* @param {?} _templateRef
* @param {?} _loadingService
*/
constructor(_viewContainerRef, _templateRef, _loadingService) {
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this._loadingService = _loadingService;
this._context = new TdLoadingContext();
/**
* tdLoadingColor?: "primary" | "accent" | "warn"
* Sets the theme color of the loading component. Defaults to "primary"
*/
this.color = 'primary';
}
/**
* tdLoading: string
* Name reference of the loading mask, used to register/resolve requests to the mask.
* @param {?} name
* @return {?}
*/
set name(name) {
if (!this._name) {
if (name) {
this._name = 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.
* @param {?} until
* @return {?}
*/
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'].
* @param {?} type
* @return {?}
*/
set type(type) {
switch (type) {
case LoadingType.Linear:
this._type = LoadingType.Linear;
break;
default:
this._type = LoadingType.Circular;
break;
}
}
/**
* tdLoadingMode?: LoadingMode or ['determinate' | 'indeterminate']
* Sets the mode of loading mask depending on value.
* Defaults to [LoadingMode.Indeterminate | 'indeterminate'].
* @param {?} mode
* @return {?}
*/
set mode(mode) {
switch (mode) {
case LoadingMode.Determinate:
this._mode = LoadingMode.Determinate;
break;
default:
this._mode = LoadingMode.Indeterminate;
break;
}
}
/**
* tdLoadingStrategy?: LoadingStrategy or ['replace' | 'overlay']
* Sets the strategy of loading mask depending on value.
* Defaults to [LoadingMode.Replace | 'replace'].
* @param {?} stategy
* @return {?}
*/
set strategy(stategy) {
switch (stategy) {
case LoadingStrategy.Overlay:
this._strategy = LoadingStrategy.Overlay;
break;
default:
this._strategy = LoadingStrategy.Replace;
break;
}
}
/**
* Registers component in the DOM, so it will be available when calling resolve/register.
* @return {?}
*/
ngOnInit() {
this._registerComponent();
}
/**
* Remove component when directive is destroyed.
* @return {?}
*/
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`.
* @return {?}
*/
_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);
}
}
}
TdLoadingDirective.decorators = [
{ type: Directive, args: [{
selector: '[tdLoading]',
},] },
];
/** @nocollapse */
TdLoadingDirective.ctorParameters = () => [
{ type: ViewContainerRef, },
{ type: TemplateRef, },
{ type: TdLoadingService, },
];
TdLoadingDirective.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',] },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const TD_LOADING = [
TdLoadingComponent,
TdLoadingDirective,
];
const TD_LOADING_ENTRY_COMPONENTS = [
TdLoadingComponent,
];
class CovalentLoadingModule {
}
CovalentLoadingModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
MatProgressBarModule,
MatProgressSpinnerModule,
OverlayModule,
PortalModule,
],
declarations: [
TD_LOADING,
],
exports: [
TD_LOADING,
],
providers: [
LOADING_FACTORY_PROVIDER,
LOADING_PROVIDER,
],
entryComponents: [
TD_LOADING_ENTRY_COMPONENTS,
],
},] },
];
/** @nocollapse */
CovalentLoadingModule.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Generated bundle index. Do not edit.
*/
export { CovalentLoadingModule, LoadingType, LoadingMode, LoadingStrategy, LoadingStyle, TD_CIRCLE_DIAMETER, TdLoadingComponent, TdLoadingContext, TdLoadingDirective, TdLoadingConfig, TdLoadingDirectiveConfig, TdLoadingService, LOADING_PROVIDER_FACTORY, LOADING_PROVIDER, TdLoadingFactory, LOADING_FACTORY_PROVIDER_FACTORY, LOADING_FACTORY_PROVIDER };
//# sourceMappingURL=covalent-core-loading.js.map