Likert-style matrix grid
Demo not found for field: matrix
/**
* Matrix Field Demo
*/
import { Form, FormBuilder } from '@saastro/forms';
import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';
const config = FormBuilder.create('matrix-demo')
.layout('manual')
.columns(12)
.addField('feedback', (f) =>
f
.type('matrix')
.label('How much do you agree?')
.helperText('Pick one option per row')
.prop('rows', [
{ key: 'quality', label: 'Product quality' },
{ key: 'support', label: 'Customer support' },
{ key: 'value', label: 'Value for money' },
])
.options([
{ value: 'agree', label: 'Agree' },
{ value: 'neutral', label: 'Neutral' },
{ value: 'disagree', label: 'Disagree' },
])
.columns({ default: 12 }),
)
.addStep('main', ['feedback'])
.build();
export default function MatrixDemo() {
const handleSubmit = (data: Record<string, unknown>) => {
console.log('Form submitted:', data);
};
return (
<TooltipProvider>
<FormProvider>
<Form config={config} onSubmit={handleSubmit} className="space-y-6" />
</FormProvider>
</TooltipProvider>
);
} 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
rowsprop:{ key, label }[]. Thekeyidentifies the row in the submitted value. - Columns are the standard
optionsarray:{ 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
import { FormBuilder } from '@saastro/forms';
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.