Skip to content

Commit

Permalink
fix(checkbox): infinite loop trigger fix
Browse files Browse the repository at this point in the history
  • Loading branch information
thekhegay committed Nov 10, 2024
1 parent f1bf6cd commit 19aa51e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 26 deletions.
9 changes: 8 additions & 1 deletion projects/lib/checkbox/checkbox.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<label class="wr-checkbox__wrapper" [for]="id">
<input class="wr-checkbox__input" type="checkbox" [formControl]="formControl" [id]="id" />
<input
class="wr-checkbox__input"
type="checkbox"
[id]="id"
[disabled]="isDisabled()"
[ngModel]="inputValue()"
(ngModelChange)="writeValue($event)"
/>
@if (icon) {
<wr-icon class="wr-checkbox__icon" [name]="icon" />
} @else {
Expand Down
56 changes: 31 additions & 25 deletions projects/lib/checkbox/checkbox.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,39 @@
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
*/

import { coerceBooleanProperty } from '@angular/cdk/coercion';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
forwardRef,
HostBinding,
inject,
Input,
OnInit,
signal,
ViewEncapsulation,
} from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';

import { noop, takeUntil } from 'rxjs';
import { noop } from 'rxjs';

import { WrAbstractBase } from 'ngwr/cdk';
import { SafeAny } from 'ngwr/cdk/types';
import { generateRandomId } from 'ngwr/cdk/utils';
import { WrIconComponent, wrIconName } from 'ngwr/icon';

/**
* NGWR checkbox component.
*
* {@tutorial} [How to use wr-checkbox]{@link http://ngwr.dev/docs/components/checkbox}
*/
@Component({
standalone: true,
selector: 'wr-checkbox',
templateUrl: './checkbox.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
imports: [ReactiveFormsModule, WrIconComponent],
imports: [FormsModule, WrIconComponent],
providers: [
{
provide: NG_VALUE_ACCESSOR,
Expand All @@ -39,50 +47,48 @@ import { WrIconComponent, wrIconName } from 'ngwr/icon';
},
],
})
export class WrCheckboxComponent extends WrAbstractBase implements ControlValueAccessor, OnInit {
@Input({ required: true }) formControl!: FormControl;
export class WrCheckboxComponent extends WrAbstractBase implements ControlValueAccessor {
@Input() id: string = generateRandomId();
@Input() icon: wrIconName | null = null;

onChange: (value: boolean) => void = noop;
onTouched: () => void = noop;

@HostBinding('class')
get elClasses(): SafeAny {
return {
'wr-checkbox': true,
'wr-checkbox--checked': this.formControl.value,
'wr-checkbox--checked': this.inputValue(),
};
}

@HostBinding('attr.disabled')
get nativeDisabled(): '' | null {
return this.formControl.disabled ? '' : null;
return this.isDisabled() ? '' : null;
}

ngOnInit(): void {
this.formControl.valueChanges
.pipe(takeUntil(this.destroyed$))
.subscribe((isChecked: boolean) => this.onChange(isChecked));
}
protected readonly inputValue = signal<boolean | null>(null);
protected value?: boolean;

private readonly cdr = inject(ChangeDetectorRef);
protected readonly isDisabled = signal(false);

onChange: (value: boolean) => void = noop;
onTouched: () => void = noop;

registerOnChange(fn: () => void): void {
registerOnChange(fn: (value: boolean) => void): void {
this.onChange = fn;
}

registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}

writeValue(checked: boolean): void {
this.formControl.patchValue(checked, { emitEvent: false });
setDisabledState(isDisabled: boolean): void {
this.isDisabled.set(coerceBooleanProperty(isDisabled));
}

setDisabledState?(isDisabled: boolean): void {
if (isDisabled) {
this.formControl.disable();
} else {
this.formControl.enable();
}
writeValue(value: boolean): void {
this.value = value;
this.onChange(value);
this.inputValue.set(value);
this.cdr.markForCheck();
}
}

0 comments on commit 19aa51e

Please sign in to comment.