# CellCommitDetail

> _Since v0.4.0_

Event detail for cell value commit.

Fired immediately when a cell value is committed. The event is cancelable -
call `preventDefault()` to reject the change.

Use `setInvalid()` to mark the cell as invalid without canceling the commit.
Invalid cells can be styled via `cellClass` and will be highlighted.

## Properties

| Property | Type | Description |
| -------- | ---- | ----------- |
| `row` | <code>TRow</code> | The row object (not yet mutated if event is cancelable). |
| `rowId` | <code>string</code> | Stable row identifier (from getRowId). |
| `field` | <code>string</code> | Field name whose value changed. |
| `oldValue` | <code>unknown</code> | Previous value before change. |
| `value` | <code>unknown</code> | New value to be stored. |
| `rowIndex` | <code>number</code> | Index of the row in current data set. |
| `changedRows` | <code>TRow[]</code> | All rows that have at least one committed change (snapshot list). |
| `changedRowIds` | <code>string[]</code> | IDs of changed rows. |
| `firstTimeForRow` | <code>boolean</code> | True if this row just entered the changed set. |
| `updateRow` | <code>(changes: Partial&lt;TRow&gt;) =&gt; void</code> | Update other fields in this row. Convenience wrapper for grid.updateRow(rowId, changes, 'cascade'). Useful for cascade updates (e.g., calculating totals). |
| `setInvalid` | <code>(message: string) =&gt; void</code> | Mark this cell as invalid with an optional validation message. The cell remains editable but will be marked with `data-invalid` attribute. Use `cellClass` to apply custom styling to invalid cells. |

### Property Details

#### setInvalid

Mark this cell as invalid with an optional validation message.
The cell remains editable but will be marked with `data-invalid` attribute.
Use `cellClass` to apply custom styling to invalid cells.

Call with no message to mark as invalid, or pass a message for tooltips/display.
Call `clearInvalid()` on the plugin to remove the invalid state.

```typescript
grid.on('cell-commit', (detail) => {
  if (detail.field === 'email' && !isValidEmail(detail.value)) {
    detail.setInvalid('Please enter a valid email address');
  }
});
```

---
