Textarea
The Textarea component is a multi-line text input for capturing longer form content such as comments, descriptions, and messages. It supports validation variants, multiple sizes, and optional resize behavior.
Import
import { Textarea } from '@nim-ui/components';Variants
Textarea comes in three variants to communicate validation state.
Textarea Variants
View Code
<Textarea variant="default" placeholder="Default textarea" /><Textarea variant="error" placeholder="Error textarea" /><Textarea variant="success" placeholder="Success textarea" />Sizes
Three size options are available: small, medium (default), and large.
Textarea Sizes
View Code
<Textarea size="sm" placeholder="Small textarea" /><Textarea size="md" placeholder="Medium textarea" /><Textarea size="lg" placeholder="Large textarea" />States
Disabled
Disabled State
View Code
<Textarea disabled placeholder="Disabled textarea" />Non-Resizable
Non-Resizable Textarea
View Code
<Textarea resize={false} placeholder="This textarea cannot be resized" />Custom Rows
Custom Row Count
View Code
<Textarea rows={2} placeholder="2 rows" /><Textarea rows={6} placeholder="6 rows" /><Textarea rows={10} placeholder="10 rows" />Props
| Name | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'error' | 'success' | 'default' | Visual style variant indicating validation state |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the textarea (affects padding and font size) |
resize | boolean | true | Whether the textarea can be resized by the user |
rows | number | 4 | Number of visible text rows |
placeholder | string | - | Placeholder text displayed when the textarea is empty |
disabled | boolean | false | Whether the textarea is disabled |
className | string | - | Additional CSS classes to apply |
The Textarea component also accepts all standard HTML textarea attributes (excluding the native size attribute, which is replaced by the component’s size prop).
Usage Examples
Comment Form
function CommentForm() { const [comment, setComment] = useState('');
const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); submitComment(comment); setComment(''); };
return ( <form onSubmit={handleSubmit} className="space-y-4"> <div> <label htmlFor="comment" className="block text-sm font-medium mb-1"> Your Comment </label> <Textarea id="comment" rows={4} placeholder="Write your comment..." value={comment} onChange={(e) => setComment(e.target.value)} /> </div> <Button type="submit">Post Comment</Button> </form> );}With Character Count
function DescriptionField() { const [value, setValue] = useState(''); const maxLength = 500;
return ( <div> <label htmlFor="description" className="block text-sm font-medium mb-1"> Description </label> <Textarea id="description" rows={6} placeholder="Describe your project..." value={value} onChange={(e) => setValue(e.target.value)} variant={value.length > maxLength ? 'error' : 'default'} /> <p className={`mt-1 text-sm ${value.length > maxLength ? 'text-red-500' : 'text-gray-500'}`}> {value.length}/{maxLength} characters </p> </div> );}Feedback Form
function FeedbackForm() { const [feedback, setFeedback] = useState(''); const [submitted, setSubmitted] = useState(false);
return ( <form onSubmit={handleSubmit} className="space-y-4"> <Textarea placeholder="Tell us what you think..." rows={5} resize={false} value={feedback} onChange={(e) => setFeedback(e.target.value)} variant={submitted ? 'success' : 'default'} /> <Button type="submit" disabled={!feedback.trim()}> Send Feedback </Button> </form> );}Accessibility
The Textarea component follows WAI-ARIA best practices:
- Uses semantic
<textarea>element - Supports all native textarea attributes including
aria-labelandaria-describedby - Visual variants communicate state but should be paired with text for screen readers
- Focus visible states for keyboard users
- Disabled state properly disables interaction and announces to assistive technology
Keyboard Support
| Key | Action |
|---|---|
| Tab | Moves focus to the textarea |
| Shift + Tab | Moves focus to previous focusable element |
Best Practices
- Always pair textareas with visible
<label>elements oraria-label - Use appropriate
rowsvalues to hint at expected content length - Provide character count when there is a maximum length
- Use the
errorvariant alongside visible error messages