Skip to main content

Design system components

TextArea

Multi-line text field with label, error/helper text, and optional animated auto-grow.

Status: stable. Group: form. Markdown version: /design-system/components/text-area.md

When to use

TextArea is the multi-line counterpart to TextInput: label, control, helper and error text, plus an optional animated auto-grow mode bounded by minRows and maxRows.

When not to use

  • Do not use TextArea for single-line text. Use TextInput, which shares the label + helper contract but carries single-line UX and format validation.
  • Do not use TextArea for single-line values just to get more width; use TextInput and layout.

Look-alikes

  • TextInput: Do not use TextArea for single-line values just to get more width; use TextInput and layout.

Props

TextArea props
PropTypeDefaultDescriptionRequired
labelstringnoneVisible field label.Yes
valuestring""Value synced into the field; typing still works after it is set.No
errorstringnoneValidation error message; renders above the helper line.No
statusFieldStatusnoneSemantic state: colours the border and styles statusMessage. error overrides it.No
statusMessagestringnoneMessage under the field for status, above the helper line.No
actionsFieldAction[]noneIcon buttons at the end of the label row: each runs an operation or opens a menu.No
helperTextstringnoneHelper copy below the field.No
onChange(value: string) => voidnoneChange handler receiving the raw string value.No
animateResizebooleanfalseEnable smooth animated auto-growing (default: false)No
minRowsnumber2Minimum number of rows when animateResize is enabled.No
maxRowsnumber10Maximum number of rows when animateResize is enabled.No

Variants

No variant dimensions and no props with a fixed set of values.

Invalid combinations

The contract records no invalid combinations.

Keyboard

TextArea keyboard behaviour
KeyBehaviour
TabMoves focus to the control and on to the next focusable element. (standard)
Shift+TabMoves focus to the previous focusable element. (standard)

Rows marked (standard) name a key the contract lists without a description; the behaviour shown is the usual one for that key.

Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

TextArea rules
LevelRuleHow it is checked
MUSTARIA: Label association via htmlFor.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Error passed to FieldShell as the status message (an error HelperText with role=alert), linked with aria-invalid and aria-describedby; a consumer aria-describedby is merged after the status and helper ids, while a consumer aria-invalid replaces the computed value.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTRequired stories produce no axe violations at the configured severity.Automated by npm run test:stories:matrix:ci. WCAG 2.5.8.
MUSTThe accessibility tree (role, name, state) matches the committed snapshot for every required story.Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2.
MUSTThe component remains legible and operable under a real browser forced-colors: active pass.Automated by npm run test:stories:hc.
MUSTEvery documented keyboard interaction works as specified.Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2.
MUSTA human completed an end-to-end accessibility review of this component.Manual review, last on 2026-11-04.
SHOULDSize the empty state honestly: rows or minRows should suggest the expected answer length.Not stated in the contract.
SHOULDEnable animateResize for chat-like and note fields; growth is smooth and stops at maxRows.Not stated in the contract.
SHOULDState length expectations in helperText up front instead of failing after submit.Not stated in the contract.
SHOULDKeep the label a noun phrase (Message), matching the other fields.Not stated in the contract.
SHOULD NOTDo not rely on manual resize as the only escape hatch for long content when auto-grow is off; verify overflow scrolls.Not stated in the contract.

Install and import

  • Install: npm install @digitaltableteur/react (version 0.9.1, restricted access on npm).
  • Import: import { TextArea } from "@digitaltableteur/react";
  • Entry point: @digitaltableteur/react/forms exports it too.
  • Styles: import @digitaltableteur/react/style.css once at the app boundary.
  • Also available as the custom element <dt-text-area>; see the custom elements manifest.