TextArea

A multi-line text input component for longer form content. Supports labels, hints, character counters, validation states, and multiple sizes. Available as compound components for maximum flexibility or as a pre-composed TextAreaInput for simple use cases.

Basic Usage

import { TextAreaInput } from '@/components'

<TextAreaInput placeholder="Share your thoughts..." />

With Label and Hint

Add a label and helper text to guide users.

<TextAreaInput
  label="Description"
  placeholder="Enter a description..."
  hint="Provide a detailed description of your project."
/>

Provide a detailed description of your project.

Sizes

The textarea comes in three sizes: X-Small (113px), Small (127px, default), and Medium (141px).

X-Small (113px)

Small (127px) - Default

Medium (141px)

X-Small

<TextAreaInput size="xs" label="X-Small TextArea" placeholder="X-Small size..." />

Small (Default)

<TextAreaInput size="sm" label="Small TextArea" placeholder="Small size..." />

Medium

<TextAreaInput size="md" label="Medium TextArea" placeholder="Medium size..." />

Character Counter

Display a character counter that automatically tracks the textarea's content. The counter will change color when approaching or exceeding the limit.

<TextAreaInput
  label="Bio"
  placeholder="Tell us about yourself..."
  hint="Keep it brief and engaging."
  maxLength={200}
  showCounter
/>
0/200

Keep it brief and engaging.

Counter with Warning Threshold

Set a custom warning threshold (default is 90%) to indicate when the user is approaching the limit.

<TextAreaInput
  label="Comment"
  placeholder="Write a comment..."
  maxLength={150}
  showCounter
  warningThreshold={80}
/>
137/150

Required Fields

Use the required prop to show a required indicator (blue asterisk).

<TextAreaInput
  label="Feedback"
  placeholder="Share your feedback..."
  hint="This field is required"
  required
/>

This field is required

Optional Fields

Use showOptionalBadge to indicate optional fields.

<TextAreaInput
  label="Additional Notes"
  placeholder="Any additional notes..."
  showOptionalBadge
/>

This field is optional

Error State

Show validation errors with the error prop. Pass a string to display an error message, or true for styling only.

Error with message

Description must be at least 50 characters

Error styling only

Please provide a valid message

Error with Message

<TextAreaInput
  label="Description"
  placeholder="Enter description..."
  error="Description must be at least 50 characters"
/>

Error Styling Only

<TextAreaInput
  label="Message"
  placeholder="Enter message..."
  error
  hint="Please provide a valid message"
/>

Disabled State

Disabled textareas cannot be interacted with.

Disabled empty

Disabled with value

<TextAreaInput label="Disabled" placeholder="Cannot edit..." disabled />

Resize Behavior

Control the resize behavior of the textarea.

Vertical resize (default)

No resize

Both directions

Vertical (Default)

<TextAreaInput label="Resizable" placeholder="Drag to resize..." resize="vertical" />

No Resize

<TextAreaInput label="Fixed" placeholder="Cannot resize..." resize="none" />

Both Directions

<TextAreaInput label="Free Resize" placeholder="Resize any direction..." resize="both" />

Compound Components

For maximum flexibility, use the compound component API to build custom textarea layouts.

import { TextArea } from '@/components'

<TextArea.Root size="sm" required maxLength={200}>
  <TextArea.Label>
    Project Description
    <TextArea.RequiredIndicator />
    <TextArea.InfoIcon />
  </TextArea.Label>
  <TextArea.Field>
    <TextArea.Native placeholder="Describe your project..." />
    <TextArea.Counter />
  </TextArea.Field>
  <TextArea.Hint>Provide a clear and concise description.</TextArea.Hint>
</TextArea.Root>
0/200

Provide a clear and concise description.

Controlled Input

Control the textarea value externally with validation feedback.

0/500

Minimum 20 characters required

Current length: 0
const [value, setValue] = useState('')
const isValid = value.length >= 20

<TextAreaInput
  label="Review"
  placeholder="Write your review..."
  value={value}
  onChange={(e) => setValue(e.target.value)}
  error={value.length > 0 && !isValid ? 'Review must be at least 20 characters' : undefined}
  hint={isValid ? 'Review looks good!' : 'Minimum 20 characters required'}
  maxLength={500}
  showCounter
  required
/>

All States Overview

X-Small (113px)

Default

0/200

This is a hint text to help users.

Disabled

0/200

This is a hint text to help users.

Error

0/200

This is a hint text to help users.

Small (127px)

Default

0/200

This is a hint text to help users.

Disabled

0/200

This is a hint text to help users.

Error

0/200

This is a hint text to help users.

Medium (141px)

Default

0/200

This is a hint text to help users.

Disabled

0/200

This is a hint text to help users.

Error

0/200

This is a hint text to help users.

Accessibility

  • Labels are properly associated with textareas via htmlFor/id
  • aria-describedby connects hint/error text to the textarea
  • aria-invalid is set when in error state
  • aria-required is set for required fields
  • aria-live="polite" on the counter for screen reader announcements
  • Focus states are clearly visible
  • Full keyboard navigation support

API Reference

TextAreaInput Props

PropTypeDefaultDescription
labelstring-Label text above the textarea
hintstring-Helper text below the textarea
errorboolean | stringfalseError state or error message
size'xs' | 'sm' | 'md''sm'Textarea size variant
maxLengthnumber-Maximum character limit
showCounterbooleanfalseShow character counter
warningThresholdnumber90Percentage at which counter shows warning
resize'none' | 'vertical' | 'horizontal' | 'both''vertical'Resize behavior
showOptionalBadgebooleanfalseShow "(Optional)" badge
showInfoIconbooleanfalseShow info icon in label
disabledbooleanfalseDisable the textarea
requiredbooleanfalseMark as required

All standard HTML textarea attributes are also supported.

Compound Components

ComponentDescription
TextArea.RootContainer that provides context (size, state, error, required, maxLength, value)
TextArea.LabelLabel element with proper association
TextArea.RequiredIndicatorBlue asterisk for required fields
TextArea.OptionalBadge"(Optional)" text badge
TextArea.InfoIconInfo icon in label row
TextArea.FieldTextarea field wrapper with border and states
TextArea.NativeThe actual <textarea> element
TextArea.CounterCharacter counter (auto-reads value from context)
TextArea.HintHint/error text below the field