# BaseGridEditorCVA

> _Since v0.13.0_

Base class for grid editors that also work as Angular form controls.

Combines `BaseGridEditor` with `ControlValueAccessor` so the same component
can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.

## What it provides

| Member | Purpose |
|--------|---------|
| `cvaValue` | Signal holding the value written by the form control |
| `disabledState` | Signal tracking `setDisabledState` calls |
| `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |
| `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |
| `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |

## Usage

```typescript
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { BaseGridEditorCVA } from '@toolbox-web/grid-angular';

@Component({
  selector: 'app-date-picker',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DatePickerComponent),
    multi: true,
  }],
  template: `
    <input
      type="date"
      [value]="displayValue()"
      [disabled]="disabledState()"
      (change)="commitBoth($event.target.value)"
      (keydown.escape)="cancelEdit()"
    />
  `
})
export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}
```

&gt; **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves
&gt; because `forwardRef(() => ConcreteClass)` must reference the concrete
&gt; component — this is an Angular limitation.

## Properties

| Property | Type | Description |
| -------- | ---- | ----------- |
| `cvaValue` | <code>WritableSignal&lt;TValue &#124; unknown&gt;</code> | Signal holding the value written by the form control via `writeValue()`. Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`). |
| `disabledState` | <code>WritableSignal&lt;boolean&gt;</code> | Signal tracking the disabled state set by the form control. Updated when `setDisabledState()` is called by Angular's forms module. |
| `displayValue` | <code>Signal&lt;TValue &#124; unknown&gt;</code> | Resolved display value. |

## Methods

### writeValue()

Called by Angular forms when the form control value changes programmatically.

```ts
writeValue(value: TValue | null): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `value` | <code>TValue &#124; unknown</code> |  |

***

### registerOnChange()

Called by Angular forms to register a change callback.

```ts
registerOnChange(fn: (value: TValue | null) => void): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `fn` | <code>(value: TValue &#124; unknown) =&gt; void</code> |  |

***

### registerOnTouched()

Called by Angular forms to register a touched callback.

```ts
registerOnTouched(fn: () => void): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `fn` | <code>() =&gt; void</code> |  |

***

### setDisabledState()

Called by Angular forms to set the disabled state.

```ts
setDisabledState(isDisabled: boolean): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `isDisabled` | <code>boolean</code> |  |

***

### commitBoth()

Commit a value through both the CVA (form control) and the grid.

- Calls the CVA `onChange` callback (updates the form control)
- Marks the control as touched
- Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)

Use this instead of `commitValue()` when your editor doubles as a form control.

```ts
commitBoth(value: TValue | null): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `value` | <code>TValue &#124; unknown</code> | The new value to commit |

***
