Skip to content

Instantly share code, notes, and snippets.

@kgmorales
Last active April 13, 2021 16:03
Show Gist options
  • Save kgmorales/de43d2099b128deeed5a605006fc868f to your computer and use it in GitHub Desktop.
Save kgmorales/de43d2099b128deeed5a605006fc868f to your computer and use it in GitHub Desktop.
Button.component.ts
import { Component, Input, Output, EventEmitter, HostListener, OnInit, OnDestroy, OnChanges } from '@angular/core';
import { Subject } from 'rxjs';
import { SiteDataService } from '../../core/services/site-data.service';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-button',
template: `<button *ngIf="value" [id]="buttonID ? buttonID : ''" [class]="buildBtnClasses(this.type, this.size, this.width, this.icon, this.additionalButtonClass)" [disabled]="loading || disabled" role="button">
<span class="btn-label" [style.visibility]="loading ? 'hidden':'visible'">
<app-dictionary-text [englishText]="value"></app-dictionary-text>
</span>
<span class="sr-only" *ngIf="addScreenReaderContent">{{addScreenReaderContent}}</span>
<app-loading-spinner class="button-loader" [loading]="loading" [circular]="true" [overlay]="false" size="small"></app-loading-spinner>
</button>`,
styles: [`
.button-loader {
display:inline-block;
}
`]
})
export class ButtonComponent implements OnInit, OnDestroy, OnChanges {
@Input() value: string;
@Input() addScreenReaderContent: string;
@Input() buttonID: string;
@Input() size = '';
@Input() type = '';
@Input() width = '';
@Input() icon = '';
@Input() additionalButtonClass = '';
@Input() disabled = false;
@Input() loading = false;
@Output() loadingChange = new EventEmitter<boolean>();
@Output() onClick = new EventEmitter<any>();
private unsubscribe$ = new Subject<void>();
valueLoaded = false;
btnClasses = {
type: {
'primary': 'btn-recommended',
'recommended': 'btn-recommended',
'secondary': 'btn-secondary',
'secondary-inverse': 'btn-secondary-inverse',
'simple': 'btn-simple',
'cta': 'btn-cta',
'update': 'btn-update',
'default': 'btn-default'
},
size: {
'small': 'btn-small',
'large': 'btn-large',
'jumbo': 'btn-jumbo'
},
width: {
'fixed': 'btn-wide-fixed',
'full': 'btn-wide-full'
},
icon: {
'left': 'btn-icon-left',
'right': 'btn-icon-right',
'plus-circle': 'btn-icon-plus-circle',
'check': 'btn-icon-check',
'calculator': 'btn-icon-calculator',
'file-search-dollar': 'btn-icon-file-search-dollar',
'printer': 'btn-icon-printer',
'envelope': 'btn-icon-envelope',
'minus': 'btn-icon-minus-circle',
'volume-up': 'btn-icon-volume-up',
'times-circle': 'btn-icon-times-circle',
'replay': 'btn-icon-replay',
'play': 'btn-icon-play',
'pencil': 'btn-icon-pencil',
'file-download': 'btn-icon-file-download',
'file-upload': 'btn-icon-file-upload',
'refresh': 'btn-icon-refresh',
'grid': 'btn-icon-grid',
'clock': 'btn-icon-clock'
}
}
constructor(private siteDataService: SiteDataService) { }
ngOnInit(): void {
this.siteDataService.loading.pipe(
takeUntil(this.unsubscribe$)
).subscribe(value => {
if (value === false) {
this.loadingChange.emit(false);
}
});
}
ngOnDestroy(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
ngOnChanges(): void {
this.buildBtnClasses(this.type, this.size, this.width, this.icon, this.additionalButtonClass);
}
@HostListener('click', ['$event']) clicked(event: Event): void {
if (!this.loading && !this.disabled) {
this.onClick.emit(event);
}
}
ifClassExists(input: string): string {
return typeof input === 'undefined' ? '' : input;
}
buildBtnClasses(type: string, size: string, width: string, icon: string, additionalButtonClass: string): string {
let classes = [
this.btnClasses.type[type] || this.btnClasses.type['default'],
this.btnClasses.size[size],
this.btnClasses.width[width],
this.btnClasses.icon[icon],
additionalButtonClass
].map(x => ifClassExists(x));
return `btn ${classes.filter(Boolean).join(' ')}`;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment