You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.0 KiB
104 lines
4.0 KiB
import { Directive, ElementRef, Input, ComponentFactoryResolver, ViewContainerRef, Renderer2, AfterViewInit } from '@angular/core';
|
|
import { ThemePalette } from '@angular/material/core/common-behaviors/color';
|
|
import { MatSpinner } from '@angular/material/progress-spinner';
|
|
|
|
@Directive({
|
|
selector: '[loading]'
|
|
})
|
|
export class LoadingDirective implements AfterViewInit {
|
|
|
|
constructor(
|
|
private _elementRef: ElementRef,
|
|
private _componentFactoryResolver: ComponentFactoryResolver,
|
|
private _viewContainerRef: ViewContainerRef,
|
|
private _renderer: Renderer2
|
|
) {
|
|
const factory = this._componentFactoryResolver.resolveComponentFactory(MatSpinner);
|
|
this._spinner = this._viewContainerRef.createComponent(factory).injector.get(MatSpinner);
|
|
switch (this._elementRef.nativeElement.tagName) {
|
|
case 'BUTTON': {
|
|
this._spinner.diameter = 20;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ngAfterViewInit(): void {
|
|
switch (this._elementRef.nativeElement.tagName) {
|
|
case 'BUTTON': {
|
|
this._wrapper = this._elementRef.nativeElement.querySelector('.mat-button-wrapper');
|
|
if (this._value) {
|
|
this._renderer.setStyle(this._wrapper, 'height', '0');
|
|
this._renderer.setStyle(this._wrapper, 'display', 'block');
|
|
this._renderer.setStyle(this._wrapper, 'overflow', 'hidden');
|
|
}
|
|
this._overlay = this._renderer.createElement('span');
|
|
this._renderer.appendChild(this._elementRef.nativeElement, this._overlay);
|
|
this._renderer.appendChild(this._overlay, this._spinner._elementRef.nativeElement);
|
|
this._renderer.addClass(this._overlay, 'mat-button-wrapper');
|
|
break;
|
|
}
|
|
default: {
|
|
this._overlay = this._renderer.createElement('div');
|
|
this._renderer.setStyle(this._overlay, 'display', this._value ? 'flex' : 'none');
|
|
this._renderer.setStyle(this._overlay, 'position', 'absolute');
|
|
this._renderer.setStyle(this._overlay, 'top', 0);
|
|
this._renderer.setStyle(this._overlay, 'left', 0);
|
|
this._renderer.setStyle(this._overlay, 'bottom', 0);
|
|
this._renderer.setStyle(this._overlay, 'right', 0);
|
|
this._renderer.setStyle(this._overlay, 'z-index', 110);
|
|
this._renderer.setStyle(this._overlay, 'align-items', 'center');
|
|
this._renderer.setStyle(this._overlay, 'justify-content', 'center');
|
|
this._renderer.setStyle(this._overlay, 'background-color', 'rgba(0, 0, 0, 0.15)');
|
|
this._renderer.appendChild(this._elementRef.nativeElement, this._overlay);
|
|
this._renderer.appendChild(this._overlay, this._spinner._elementRef.nativeElement);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Input()
|
|
public set loading(value: boolean) {
|
|
this._value = value;
|
|
switch (this._elementRef.nativeElement.tagName) {
|
|
case 'BUTTON': {
|
|
if (value) {
|
|
if (this._wrapper) {
|
|
this._renderer.setStyle(this._wrapper, 'height', '0');
|
|
this._renderer.setStyle(this._wrapper, 'display', 'block');
|
|
this._renderer.setStyle(this._wrapper, 'overflow', 'hidden');
|
|
}
|
|
this._renderer.setStyle(this._spinner._elementRef.nativeElement, 'display', 'inline-block');
|
|
}
|
|
else {
|
|
this._renderer.setStyle(this._spinner._elementRef.nativeElement, 'display', 'none');
|
|
if (this._wrapper) {
|
|
this._renderer.removeStyle(this._wrapper, 'height');
|
|
this._renderer.removeStyle(this._wrapper, 'display');
|
|
this._renderer.removeStyle(this._wrapper, 'overflow');
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (value) {
|
|
this._overlay && this._renderer.setStyle(this._overlay, 'display', 'flex');
|
|
}
|
|
else {
|
|
this._overlay && this._renderer.setStyle(this._overlay, 'display', 'none');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
@Input()
|
|
public set color(color: ThemePalette) {
|
|
this._spinner.color = color;
|
|
}
|
|
|
|
private _wrapper: any;
|
|
private _overlay: any;
|
|
private _spinner: MatSpinner;
|
|
private _value: boolean;
|
|
}
|