Interactive demo of textarea field
/**
* Textarea Field Demo - Interactive examples of textarea fields
*/
import { Form, FormBuilder } from '@saastro/forms';
import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';
const config = FormBuilder.create('textarea-demo')
.layout('manual')
.columns(12)
.addField('message', (f) =>
f
.type('textarea')
.label('Message')
.placeholder('Write your message here...')
.helperText('Share your thoughts with us')
.rows(4)
.required('Message is required')
.minLength(10, 'Message must be at least 10 characters')
.columns({ default: 12 }),
)
.addField('bio', (f) =>
f
.type('textarea')
.label('Bio')
.placeholder('Tell us about yourself...')
.helperText('Maximum 200 characters')
.rows(3)
.maxLength(200)
.optional()
.columns({ default: 12 }),
)
.addStep('main', ['message', 'bio'])
.build();
export default function TextareaDemo() {
const handleSubmit = (data: Record<string, unknown>) => {
console.log('Form submitted:', data);
alert('Form submitted! Check console for data.');
};
return (
<TooltipProvider>
<FormProvider>
<Form config={config} onSubmit={handleSubmit} className="space-y-4" />
</FormProvider>
</TooltipProvider>
);
} Overview
The textarea field provides a multi-line text input for longer content. It supports character counting, auto-resize, and configurable rows.
Usage
Basic Textarea
import { FormBuilder } from '@saastro/forms';
const config = FormBuilder.create('feedback')
.addField('message', (f) =>
f
.type('textarea')
.label('Your Message')
.placeholder('Write your message here...')
.required('Message is required')
.minLength(10, 'Message must be at least 10 characters'),
)
.addStep('main', ['message'])
.build();
With Character Limit
.addField('bio', (f) =>
f.type('textarea')
.label('Bio')
.placeholder('Tell us about yourself...')
.maxLength(500)
.helperText('Maximum 500 characters')
.rows(4)
)
With Rows Configuration
.addField('description', (f) =>
f.type('textarea')
.label('Description')
.rows(6)
.placeholder('Detailed description...')
)
JSON Configuration
{
"type": "textarea",
"label": "Message",
"placeholder": "Write your message...",
"rows": 4,
"maxLength": 500,
"schema": {
"required": true,
"minLength": 10,
"minLengthMessage": "Message must be at least 10 characters"
}
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'textarea' | - | Field type (required) |
label | string | - | Label text |
placeholder | string | - | Placeholder text |
helperText | string | - | Help text below field |
rows | number | 3 | Number of visible rows |
maxLength | number | - | Maximum character count (HTML attribute) |
size | 'sm' | 'md' | 'lg' | 'md' | Input size variant |
columns | Partial<Record<Breakpoint, number>> | - | Grid columns by breakpoint |
disabled | boolean | function | ConditionGroup | false | Disable the field |
hidden | boolean | function | ConditionGroup | Responsive | false | Hide the field |
Validation
Required with Minimum Length
.addField('feedback', (f) =>
f.type('textarea')
.label('Feedback')
.required('Feedback is required')
.minLength(20, 'Please provide at least 20 characters')
)
Maximum Length Validation
.addField('tweet', (f) =>
f.type('textarea')
.label('Tweet')
.maxLength(280)
.maxLengthValidation(280, 'Tweet cannot exceed 280 characters')
)
With Zod Schema
import { z } from 'zod';
.addField('essay', (f) =>
f.type('textarea')
.label('Essay')
.schema(z.string()
.min(100, 'Essay must be at least 100 characters')
.max(5000, 'Essay cannot exceed 5000 characters')
)
)
Styling
Custom Classes
.addField('message', (f) =>
f.type('textarea')
.label('Message')
.rows(4)
.required()
.classNames({
wrapper: 'bg-muted/30 p-4 rounded-lg',
input: 'min-h-[120px] resize-none',
label: 'text-lg font-medium',
error: 'text-destructive text-sm',
helper: 'text-muted-foreground text-xs',
})
)
Responsive Layout
.addField('description', (f) =>
f.type('textarea')
.label('Description')
.rows(5)
.columns({ default: 12, md: 8 })
.size('lg')
)
JSON Styling
{
"type": "textarea",
"label": "Message",
"rows": 4,
"wrapper_className": "bg-muted/30 p-4 rounded-lg",
"input_className": "min-h-[120px] resize-none",
"label_className": "text-lg font-medium",
"columns": { "default": 12 },
"size": "lg"
}
Related Fields
- Text - Single-line text input
- Input Group - Text input with prefix/suffix
Accessibility
- Native
<textarea>element for full accessibility - Proper labeling via
labelprop - Supports keyboard navigation
- Character count announced to screen readers