@ -2,14 +2,15 @@
import {
Component ,
ElementRef ,
EventEmitter ,
Input ,
OnInit ,
Output ,
Renderer2 ,
ViewChild ,
effect ,
inject ,
input
input ,
output ,
signal ,
computed
} from '@angular/core' ;
import { ABP , StopPropagationDirective } from '@abp/ng.core' ;
@ -22,12 +23,12 @@ import { ABP, StopPropagationDirective } from '@abp/ng.core';
[ attr . type ] = "buttonType()"
[ attr . form ] = "formName()"
[ class ] = "buttonClass()"
[ disabled ] = "loading || disabled()"
( click . stop ) = "click.next($event); abpClick.nex t($event)"
( focus ) = "focus.next($event); abpFocus.nex t($event)"
( blur ) = "blur.next($event); abpBlur.nex t($event)"
[ disabled ] = "isLoading() || disabled()"
( click . stop ) = "click.emit($event); abpClick.emi t($event)"
( focus ) = "focus.emit($event); abpFocus.emi t($event)"
( blur ) = "blur.emit($event); abpBlur.emi t($event)"
>
< i [ class ] = " icon " class = "me-1" aria - hidden = "true" > < / i > < ng - content > < / n g - c o n t e n t >
< i [ class ] = " icon ( ) " class = "me-1" aria - hidden = "true" > < / i > < ng - content > < / n g - c o n t e n t >
< / button >
` ,
imports : [ StopPropagationDirective ] ,
@ -36,48 +37,48 @@ export class ButtonComponent implements OnInit {
private renderer = inject ( Renderer2 ) ;
readonly buttonId = input ( '' ) ;
readonly buttonClass = input ( 'btn btn-primary' ) ;
readonly buttonType = input ( 'button' ) ;
readonly formName = input < string > ( undefined ) ;
readonly iconClass = input < string > ( undefined ) ;
@Input ( )
loading = false ;
readonly formName = input < string | undefined > ( undefined ) ;
readonly iconClass = input < string | undefined > ( undefined ) ;
readonly loadingInput = input ( false , { alias : 'loading' } ) ;
readonly disabled = input < boolean | undefined > ( false ) ;
readonly attributes = input < ABP.Dictionary < string > | undefined > ( undefined ) ;
readonly attributes = input < ABP.Dictionary < string > > ( undefined ) ;
// Internal writable signal for loading state - can be set programmatically
private readonly _loading = signal ( false ) ;
@Output ( ) readonly click = new EventEmitter < MouseEvent > ( ) ;
// Computed that combines input and internal state
readonly isLoading = computed ( ( ) = > this . loadingInput ( ) || this . _loading ( ) ) ;
@Output ( ) readonly focus = new EventEmitter < FocusEvent > ( ) ;
@Output ( ) readonly blur = new EventEmitter < FocusEvent > ( ) ;
@Output ( ) readonly abpClick = new EventEmitter < MouseEvent > ( ) ;
@Output ( ) readonly abpFocus = new EventEmitter < FocusEvent > ( ) ;
// Getter/setter for backward compatibility (used by ModalComponent)
get loading ( ) : boolean {
return this . _loading ( ) ;
}
set loading ( value : boolean ) {
this . _loading . set ( value ) ;
}
@Output ( ) readonly abpBlur = new EventEmitter < FocusEvent > ( ) ;
readonly click = output < MouseEvent > ( ) ;
readonly focus = output < FocusEvent > ( ) ;
readonly blur = output < FocusEvent > ( ) ;
readonly abpClick = output < MouseEvent > ( ) ;
readonly abpFocus = output < FocusEvent > ( ) ;
readonly abpBlur = output < FocusEvent > ( ) ;
@ViewChild ( 'button' , { static : true } )
buttonRef ! : ElementRef < HTMLButtonElement > ;
get icon ( ) : string {
return ` ${ this . loading ? 'fa fa-spinner fa-spin' : this . iconClass ( ) || 'd-none' } ` ;
}
protected readonly icon = computed ( ( ) = > {
return this . isLoading ( ) ? 'fa fa-spinner fa-spin' : this . iconClass ( ) || 'd-none' ;
} ) ;
ngOnInit() {
const attributes = this . attributes ( ) ;
if ( attributes ) {
Object . keys ( attributes ) . forEach ( key = > {
const attributesValue = this . attributes ( ) ;
if ( attributesValue ? . [ key ] ) {
this . renderer . setAttribute ( this . buttonRef . nativeElement , key , attributesValue [ key ] ) ;
if ( attributes [ key ] ) {
this . renderer . setAttribute ( this . buttonRef . nativeElement , key , attributes [ key ] ) ;
}
} ) ;
}