Skip to content

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-label and aria-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

KeyAction
TabMoves focus to the textarea
Shift + TabMoves focus to previous focusable element

Best Practices

  • Always pair textareas with visible <label> elements or aria-label
  • Use appropriate rows values to hint at expected content length
  • Provide character count when there is a maximum length
  • Use the error variant alongside visible error messages
  • Input - Single-line text input
  • Button - Interactive button for form submission
  • Select - Dropdown selection input