import { Component } from '@angular/core'; import { forwardRef, signal } from '@angular/core'; import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule, } from '@angular/forms'; @Component({ selector: 'quantity-control', standalone: true, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => QuantityControl), multi: true, }, ], template: '', }) class QuantityControl implements ControlValueAccessor { count = signal(0); disabled = signal(false); private changed: (value: number) => void = () => {}; private touched: () => void = () => {}; writeValue(value: unknown): void { this.count.set(typeof value === 'number' && Number.isInteger(value) ? value : 0); } registerOnChange(fn: (value: number) => void): void { this.changed = fn; } registerOnTouched(fn: () => void): void { this.touched = fn; } setDisabledState(value: boolean): void { this.disabled.set(value); } add(): void { if (this.disabled() || this.count() >= 20) return; this.count.update((v) => v + 1); this.changed(this.count()); this.touched(); } } @Component({ selector: 'bh-custom-controls', standalone: true, imports: [QuantityControl, ReactiveFormsModule], template: `

{{ quantity.value }} selected

`, }) export class App { quantity = new FormControl(2, { nonNullable: true }); }