# Field: Matrix (category: special)

URL: https://docs.forms.saastro.io/docs/matrix

<FieldPreview name="matrix" description="Likert-style matrix grid" />

## Overview

`matrix` renders a table — one row per question, one column per choice on a shared scale. Each row is its own single-choice `radiogroup`. It's the classic Likert survey layout ("Agree / Neutral / Disagree" across several statements).

- **Rows** come from the `rows` prop: `{ key, label }[]`. The `key` identifies the row in the submitted value.
- **Columns** are the standard `options` array: `{ value, label }[]`.

## Value

The submitted value is an **object keyed by row `key`** (`valueKind: 'object'`), e.g. `{ quality: 'agree', support: 'neutral' }`. Rows the user never touches are simply absent.

## Usage

```tsx

const config = FormBuilder.create('survey')
  .addField('feedback', (f) =>
    f
      .type('matrix')
      .label('How much do you agree?')
      .prop('rows', [
        { key: 'quality', label: 'Product quality' },
        { key: 'support', label: 'Customer support' },
      ])
      .options([
        { value: 'agree', label: 'Agree' },
        { value: 'neutral', label: 'Neutral' },
        { value: 'disagree', label: 'Disagree' },
      ]),
  )
  .addStep('main', ['feedback'])
  .build();
```

`rows` has no fluent method — set it with `.prop('rows', [...])`. The columns use the normal `.options()`.

## Props

| Prop      | Type                                      | Default | Description                                     |
| --------- | ----------------------------------------- | ------- | ----------------------------------------------- |
| `rows`    | `Array<{ key: string; label: string }>`   | `[]`    | One row (question) each; `key` keys the value   |
| `options` | `Array<{ value: string; label: string }>` | `[]`    | The shared column scale                         |

The radio accent color reads the `--primary` CSS variable.
