diff --git a/projects/components/src/checkbox/checkbox.component.test.ts b/projects/components/src/checkbox/checkbox.component.test.ts
index 20850401c..c10523773 100644
--- a/projects/components/src/checkbox/checkbox.component.test.ts
+++ b/projects/components/src/checkbox/checkbox.component.test.ts
@@ -1,4 +1,5 @@
import { fakeAsync } from '@angular/core/testing';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { createHostFactory, Spectator } from '@ngneat/spectator/jest';
import { CheckboxComponent } from './checkbox.component';
@@ -9,7 +10,7 @@ describe('Checkbox component', () => {
const createHost = createHostFactory({
component: CheckboxComponent,
- imports: [TraceCheckboxModule, RouterTestingModule],
+ imports: [TraceCheckboxModule, RouterTestingModule, ReactiveFormsModule],
providers: [],
declareComponent: false
});
@@ -52,12 +53,32 @@ describe('Checkbox component', () => {
// Click will toggle the values to true
spectator.click(inputElement);
- expect(spectator.component.checked).toBe(true);
+ expect(spectator.component.isChecked).toBe(true);
expect(checkboxChangeSpy).toHaveBeenCalledWith(true);
// Click will toggle the values to false
spectator.click(inputElement);
- expect(spectator.component.checked).toBe(false);
+ expect(spectator.component.isChecked).toBe(false);
expect(checkboxChangeSpy).toHaveBeenCalledWith(false);
}));
+
+ test('should work correctly with control value accessor', () => {
+ const formControl = new FormControl(false);
+ spectator = createHost(
+ `
+ `,
+ {
+ hostProps: {
+ formControl: formControl
+ }
+ }
+ );
+ expect(spectator.component.isChecked).toBe(false);
+
+ formControl.setValue(true);
+ expect(spectator.component.isChecked).toBe(true);
+
+ formControl.disable();
+ expect(spectator.component.isDisabled).toBe(true);
+ });
});
diff --git a/projects/components/src/checkbox/checkbox.component.ts b/projects/components/src/checkbox/checkbox.component.ts
index e47bced19..bc4cb2753 100644
--- a/projects/components/src/checkbox/checkbox.component.ts
+++ b/projects/components/src/checkbox/checkbox.component.ts
@@ -1,4 +1,5 @@
-import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
+import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatCheckboxChange } from '@angular/material/checkbox';
@Component({
@@ -8,31 +9,78 @@ import { MatCheckboxChange } from '@angular/material/checkbox';
template: `
- `
+ `,
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: CheckboxComponent,
+ multi: true
+ }
+ ]
})
-export class CheckboxComponent {
+export class CheckboxComponent implements ControlValueAccessor {
@Input()
public label?: string;
@Input()
- public checked: boolean | undefined;
+ public set checked(checked: boolean | undefined) {
+ this.isChecked = checked ?? false;
+ }
+
+ public get checked(): boolean {
+ return this.isChecked;
+ }
@Input()
- public disabled: boolean | undefined;
+ public set disabled(disabled: boolean | undefined) {
+ this.isDisabled = disabled ?? false;
+ }
+
+ public get disabled(): boolean {
+ return this.isDisabled;
+ }
@Output()
public readonly checkedChange: EventEmitter = new EventEmitter();
+ public isChecked: boolean = false;
+ public isDisabled: boolean = false;
+
+ private onTouched!: () => void;
+ private onChanged!: (value: boolean) => void;
+
+ public constructor(private readonly cdr: ChangeDetectorRef) {}
+
public onCheckboxChange(event: MatCheckboxChange): void {
- this.checked = event.checked;
- this.checkedChange.emit(this.checked);
+ this.isChecked = event.checked;
+ this.checkedChange.emit(this.isChecked);
+ this.onChanged(this.isChecked);
+ this.onTouched();
+ }
+
+ public registerOnChange(fn: (value: boolean) => void): void {
+ this.onChanged = fn;
+ }
+
+ public registerOnTouched(fn: () => void): void {
+ this.onTouched = fn;
+ }
+
+ public setDisabledState(isDisabled: boolean): void {
+ this.isDisabled = isDisabled;
+ this.cdr.markForCheck();
+ }
+
+ public writeValue(isChecked: boolean | undefined): void {
+ this.isChecked = isChecked ?? false;
+ this.cdr.markForCheck();
}
}