NimUI
ComponentsPrimitives

Textarea

Multi-line text input for longer form content

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
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
Code
<Textarea size="sm" placeholder="Small textarea" />
<Textarea size="md" placeholder="Medium textarea" />
<Textarea size="lg" placeholder="Large textarea" />

States

Disabled

Disabled State
Code
<Textarea disabled placeholder="Disabled textarea" />

Non-Resizable

Non-Resizable Textarea
Code
<Textarea resize={false} placeholder="This textarea cannot be resized" />

Custom Rows

Custom Row Count
Code
<Textarea rows={2} placeholder="2 rows" />
<Textarea rows={6} placeholder="6 rows" />
<Textarea rows={10} placeholder="10 rows" />

Props

NameTypeDefaultDescription
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)
resizebooleantrueWhether the textarea can be resized by the user
rowsnumber4Number of visible text rows
placeholderstring-Placeholder text displayed when the textarea is empty
disabledbooleanfalseWhether the textarea is disabled
classNamestring-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

On this page