Skip to content

Commit

Permalink
Fixed #10145 - Add "loading" prop to Buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
yigitfindikli committed Apr 21, 2021
1 parent 96f54ba commit b037db9
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/app/components/button/button.css
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@
.p-buttonset .p-button:focus {
position: relative;
z-index: 1;
}

.p-button-label {
transition: all .2s;
}
96 changes: 79 additions & 17 deletions src/app/components/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {

@Input() iconPos: 'left' | 'right' | 'top' | 'bottom' = 'left';

@Input() loadingIcon: string = "pi pi-spinner pi-spin";

public _label: string;

public _icon: string;

public _loading: boolean = false;

public initialized: boolean;

Expand All @@ -26,15 +30,7 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
DomHandler.addMultipleClasses(this.el.nativeElement, this.getStyleClass());

if (this.icon) {
let iconElement = document.createElement("span");
iconElement.className = 'p-button-icon';
iconElement.setAttribute("aria-hidden", "true");
let iconPosClass = this.label ? 'p-button-icon-' + this.iconPos : null;
if (iconPosClass) {
DomHandler.addClass(iconElement, iconPosClass);
}
DomHandler.addMultipleClasses(iconElement, this.icon);
this.el.nativeElement.appendChild(iconElement);
this.createIconEl();
}

let labelElement = document.createElement("span");
Expand All @@ -57,6 +53,12 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
if (this.icon && !this.label) {
styleClass = styleClass + ' p-button-icon-only';
}

if (this.loading) {
styleClass = styleClass + ' p-disabled p-button-loading';
if (!this.icon && this.label)
styleClass = styleClass + ' p-button-loading-label-only';
}

return styleClass;
}
Expand All @@ -65,6 +67,47 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
let styleClass = this.getStyleClass();
this.el.nativeElement.className = styleClass + ' ' + this._initialStyleClass;
}

createIconEl() {
let iconElement = document.createElement("span");
iconElement.className = 'p-button-icon';
iconElement.setAttribute("aria-hidden", "true");
let iconPosClass = this.label ? 'p-button-icon-' + this.iconPos : null;

if (iconPosClass) {
DomHandler.addClass(iconElement, iconPosClass);
}

DomHandler.addMultipleClasses(iconElement, this.getIconClass());
let labelEl = DomHandler.findSingle(this.el.nativeElement, '.p-button-label')

if (labelEl)
this.el.nativeElement.insertBefore(iconElement, labelEl);
else
this.el.nativeElement.appendChild(iconElement)
}

getIconClass() {
return this.loading ? 'p-button-loading-icon ' + this.loadingIcon : this._icon;
}

setIconClass() {
let iconElement = DomHandler.findSingle(this.el.nativeElement, '.p-button-icon');
if (iconElement) {
if (this.iconPos)
iconElement.className = 'p-button-icon p-button-icon-' + this.iconPos + ' ' + this.getIconClass();
else
iconElement.className = 'p-button-icon ' + this.getIconClass();
}
else {
this.createIconEl();
}
}

removeIconElement() {
let iconElement = DomHandler.findSingle(this.el.nativeElement, '.p-button-icon');
this.el.nativeElement.removeChild(iconElement)
}

@Input() get label(): string {
return this._label;
Expand All @@ -87,11 +130,24 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
this._icon = val;

if (this.initialized) {
if (this.iconPos)
DomHandler.findSingle(this.el.nativeElement, '.p-button-icon').className = 'p-button-icon p-button-icon-' + this.iconPos + ' ' + this._icon;
else
DomHandler.findSingle(this.el.nativeElement, '.p-button-icon').className = 'p-button-icon ' + this._icon;
this.setIconClass();
this.setStyleClass();
}
}

@Input() get loading(): boolean {
return this._loading;
}

set loading(val: boolean) {
this._loading = val;

if (this.initialized) {
if (this.loading || this.icon)
this.setIconClass();
else
this.removeIconElement();

this.setStyleClass();
}
}
Expand All @@ -104,11 +160,13 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
@Component({
selector: 'p-button',
template: `
<button [attr.type]="type" [class]="styleClass" [ngStyle]="style" [disabled]="disabled"
<button [attr.type]="type" [class]="styleClass" [ngStyle]="style" [disabled]="disabled || loading"
[ngClass]="{'p-button p-component':true,
'p-button-icon-only': (icon && !label),
'p-disabled': disabled,
'p-button-vertical': (iconPos === 'top' || iconPos === 'bottom') && label}"
'p-button-vertical': (iconPos === 'top' || iconPos === 'bottom') && label,
'p-disabled': this.disabled || this.loading,
'p-button-loading': this.loading,
'p-button-loading-label-only': this.loading && !this.icon && this.label}"
(click)="onClick.emit($event)" (focus)="onFocus.emit($event)" (blur)="onBlur.emit($event)" pRipple>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
Expand All @@ -117,7 +175,7 @@ export class ButtonDirective implements AfterViewInit, OnDestroy {
'p-button-icon-right': iconPos === 'right' && label,
'p-button-icon-top': iconPos === 'top' && label,
'p-button-icon-bottom': iconPos === 'bottom' && label}"
[class]="icon" *ngIf="icon" [attr.aria-hidden]="true"></span>
[class]="loading ? 'p-button-loading-icon ' + loadingIcon : icon" *ngIf="icon||loading" [attr.aria-hidden]="true"></span>
<span class="p-button-label" [attr.aria-hidden]="icon && !label">{{label||'&nbsp;'}}</span>
<span [ngClass]="badgeStyleClass()" *ngIf="badge" [class]="badgeClass">{{badge}}</span>
</button>
Expand All @@ -139,6 +197,10 @@ export class Button implements AfterContentInit {

@Input() disabled: boolean;

@Input() loading: boolean = false;

@Input() loadingIcon: string = "pi pi-spinner pi-spin";

@Input() style: any;

@Input() styleClass: string;
Expand Down

0 comments on commit b037db9

Please sign in to comment.