Skip to main content

Textarea

An advanced, accessible textarea component with auto-resizing, character counting, and built-in support for error, disabled, and read-only states. Ideal for forms where dynamic height and user feedback are needed.


Usage

Basic usage

import { Textarea } from '@nofinite/nui';

<Textarea placeholder="Write something..." />;

With typical interaction

<Textarea
maxLength={200}
showCount
autoGrow
placeholder="Type and watch it grow..."
onChange={(e) => console.log(e.target.value)}
/>

Variants

The Textarea component supports visual states rather than traditional variants:

<Textarea />
<Textarea error />
<Textarea disabled />
<Textarea readOnly />

Available states / visual variations:

  • default – normal textarea
  • error – displays a red border and subtle error shadow
  • disabled – grayed out and non-interactive
  • readOnly – non-editable but selectable content

Guidelines:

  • Use error for form validation feedback.
  • Use disabled for inactive fields.
  • Use readOnly when content should not be modified.

Sizes

Textarea supports dynamic height via autoGrow and a default of 3 rows. You can adjust height using the rows prop:

<Textarea rows={3} />
<Textarea rows={5} autoGrow />

Notes:

  • autoGrow overrides manual height to fit content.
  • Rows set the minimum visible height.

States

<Textarea disabled />
<Textarea readOnly />
<Textarea error />

State behavior:

  • disabled – prevents typing, visually muted.
  • readOnly – allows selection but no edits.
  • error – highlights border in red and applies shadow.
  • showCount – displays character counter at bottom-right.

Native Props / Composition

Textarea extends native <textarea> attributes:

<Textarea
id="comment"
name="comment"
placeholder="Enter your comment"
aria-describedby="helper-text"
maxLength={200}
rows={4}
onChange={handleChange}
/>

Supports className and style for custom styling:

<Textarea className="my-custom-textarea" style={{ width: '100%' }} />

Props

PropTypeDefaultDescription
showCountbooleanfalseDisplay character counter
autoGrowbooleantrueAutomatically resize height based on content
errorbooleanfalseApply error styling
helperIdstringID for aria-describedby linking help or error text
rowsnumber3Minimum number of visible rows
disabledbooleanfalseDisable typing
readOnlybooleanfalseMake content non-editable
requiredbooleanfalseMark field as required
maxLengthnumberMaximum number of characters allowed
valuestringControlled value
defaultValuestringInitial value for uncontrolled textarea
onChange(e: React.ChangeEvent<HTMLTextAreaElement>) => voidChange event handler
classNamestring""Additional CSS class names
...restReact.TextareaHTMLAttributes<HTMLTextAreaElement>Any other native textarea attributes

Behavior Notes

  • Automatically resizes height if autoGrow is true.
  • Supports both controlled (value) and uncontrolled (defaultValue) modes.
  • Character counter displays live count if showCount or maxLength is provided.
  • Error and disabled states are purely visual and interactive, consistent with native <textarea> behaviors.
<Textarea autoGrow maxLength={100} showCount error />

Accessibility

  • Renders as native <textarea>.
  • Supports keyboard interactions: typing, tabbing, focus.
  • aria-invalid applied when error is true.
  • aria-describedby can link to helper or error text.
  • Character counter is marked aria-hidden="true" to avoid screen reader clutter.
<Textarea aria-describedby="helper-text" error />

Layout

  • Block-level by default, fills available width.
  • Supports style={{ width: "100%" }} for full-width layout.
  • Can be placed inside flex/grid layouts and will respect container sizing.
<Textarea style={{ width: '100%' }} placeholder="Full-width textarea" />

Best Practices

Do

  • Use autoGrow for user-friendly expanding text input.
  • Combine with showCount and maxLength for character-limited inputs.
  • Apply error for form validation feedback.
  • Use helperId for linking descriptions or error messages.

Don’t

  • Overuse readOnly where input is expected.
  • Use disabled for hiding content — use visibility or conditional rendering instead.
  • Mix too many visual states in the same textarea (e.g., disabled + error).