Skip to main content

Textarea

A controlled/uncontrolled multiline input supporting auto-growing height, character counting, error state, and robust accessibility semantics. Designed for form-heavy interfaces with dynamic content entry.


Usage

Basic usage

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

<Textarea placeholder="Write your message..." />

Controlled usage

const [value, setValue] = useState("");

<Textarea
value={value}
onChange={(e) => setValue(e.target.value)}
/>

Auto-grow textarea

<Textarea autoGrow placeholder="Auto resizing textarea" />

Character counter with max length

<Textarea maxLength={200} showCount />

Error state

<Textarea error helperId="desc-error" />
<p id="desc-error">This field is required</p>

Disabled and read-only

<Textarea disabled />
<Textarea readOnly value="Static content" />

Props

PropTypeDefaultDescription
valuestringControlled value
defaultValuestring""Initial uncontrolled value
onChangeChangeEventHandlerChange handler
showCountbooleanfalseDisplays character counter
autoGrowbooleantrueEnables height auto-resize
maxLengthnumberCharacter limit
errorbooleanfalseError styling + aria-invalid
helperIdstringaria-describedby target
disabledbooleanfalseDisabled state
readOnlybooleanfalseRead-only state
requiredbooleanfalseRequired input
rowsnumber3Initial row count
classNamestringStyling override

Variants

Growth variants

<Textarea autoGrow />
<Textarea autoGrow={false} />

Counter variants

<Textarea showCount />
<Textarea showCount maxLength={120} />

Validation variants

<Textarea error />
<Textarea required />

Control mode variants

<Textarea defaultValue="uncontrolled" />
<Textarea value="controlled" />

Available variants

  • Auto-grow textarea
  • Manual resize textarea
  • Character counter textarea
  • Max-length limited textarea
  • Error state textarea
  • Disabled textarea
  • Read-only textarea
  • Controlled textarea
  • Uncontrolled textarea

Guidelines

  • Use autoGrow for chat, comments, and message inputs
  • Disable autoGrow for structured forms
  • Pair error state with helper text
  • Avoid large maxLength values with autoGrow
  • Keep counter visible for strict character limits

States

  • Default
  • Hover
  • Focus-visible
  • Disabled
  • Read-only
  • Error
  • Auto-growing
  • Counter visible

Keyboard Interaction

  • Standard textarea typing behavior
  • Enter inserts newline
  • Tab navigates form order
  • Shift + Tab moves backward
  • Screen readers announce error and helper text

Accessibility

  • Native textarea semantics
  • aria-invalid when error
  • aria-describedby links helper text
  • Counter marked aria-hidden
  • Preserves scroll position during auto-grow
  • Supports required + disabled semantics

Design Tokens

TokenUsage
--nui-bg-surfaceBackground
--nui-bg-mutedDisabled bg
--nui-bg-subtleRead-only bg
--nui-fg-defaultText
--nui-fg-mutedCounter
--nui-fg-disabledDisabled text
--nui-border-defaultBorder
--nui-border-hoverHover border
--nui-color-primaryFocus border
--nui-color-dangerError border
--nui-brand-100Focus ring
--nui-radius-mdRadius
--nui-space-*Spacing
--nui-font-sansTypography

Best Practices

Do

  • Use autoGrow for conversational UI
  • Combine maxLength + counter for constrained inputs
  • Attach helper text via helperId
  • Keep textarea responsive for long content
  • Validate on blur for better UX

Don’t

  • Use autoGrow for extremely large inputs
  • Hide error messaging from screen readers
  • Mount multiple counters for same input
  • Force manual resize when autoGrow active
  • Use placeholder as primary label