Skip to Content

TextAreaField

A multi-line text field that allows a user to enter a plain text value with a keyboard.

Usage

import { TextAreaField } from "@opengovsg/oui"
<TextAreaField label="Comments" />

The TextAreaField component provides a multi-line text input with built-in label, description, and error message support. It is built on React Aria's TextField and renders a <textarea> element instead of an <input>.

If the component does not have a visible label (by passing a label prop), an aria-label or aria-labelledby prop must be passed instead to identify it to assistive technology.

Examples

With Label and Description

Provide clear instructions to users with labels and descriptions.

Max 500 characters.

With Error Message

Combine isInvalid and errorMessage props to show validation errors.

Please enter at least 10 characters.

Sizes

Use the size prop to change the size of the text area field. Defaults to "md".

Controlled

Use the value and onChange props to control the text area value programmatically.

0 characters

Disabled

Use the isDisabled prop to disable the text area field.

Read Only

Use the isReadOnly prop to make the text area field read-only. The value can be selected but not modified.

Validation

TextAreaField supports React Aria's form validation system:

  • Built-in constraints: Use isRequired, minLength, or maxLength for native HTML validation. Errors display after the user commits a value or submits the form.
  • Custom validation: Use the validate prop to provide a function that returns an error message string, or null/true if valid.
  • Realtime validation: Use the isInvalid prop with errorMessage for immediate feedback as the user types.
  • Validation behavior: The validationBehavior prop controls enforcement — "native" (default) prevents form submission when invalid, while "aria" only marks the field via ARIA attributes and allows submission.

Events

TextAreaField supports the following event handlers, inherited from React Aria's TextField:

  • onFocus / onBlur — Called when the textarea gains or loses focus.
  • onFocusChange — Called when the focus state changes, receiving a boolean.
  • onChange — Called when the text value changes, receiving the new string value.
  • onCopy / onCut / onPaste — Called on clipboard operations.
  • onCompositionStart / onCompositionEnd — Called during IME composition for internationalized text input.
  • onKeyDown / onKeyUp — Called on keyboard events.
  • onSelect — Called when text is selected within the textarea.

Accessibility

  • Built with a native <textarea> element for full browser and assistive technology support.
  • Label, description, and error message are automatically linked to the textarea via aria-labelledby and aria-describedby.
  • Required and invalid states are exposed to assistive technology.
  • Supports keyboard interaction: text entry, clipboard shortcuts, and standard textarea navigation.
  • If no visible label is provided, an aria-label or aria-labelledby prop must be set.

Slots

  • base: The root container wrapper.
  • label: The label text element.
  • input: The textarea element.
  • description: The description text below the field.
  • error: The error message text.

Custom Styles

You can customize the TextAreaField component by passing custom Tailwind CSS classes to the component slots via the classNames prop.

Tell us what you think.

Props

TextAreaField

PropTypeDefaultDescription
labelReact.ReactNode-The label for the text area field
descriptionReact.ReactNode-The description text shown below the field
errorMessageReact.ReactNode | ((validation: ValidationResult) => React.ReactNode)-The error message to display when validation fails
valuestring-The current value (controlled)
defaultValuestring-The default value (uncontrolled)
onChange(value: string) => void-Callback fired when the value changes
size"xs" | "sm" | "md""md"The size of the component
variant"outline" | "unstyled""outline"The visual variant of the textarea
isDisabledbooleanfalseWhether the field is disabled
isReadOnlybooleanfalseWhether the field is read-only
isRequiredbooleanfalseWhether the field is required
isInvalidbooleanfalseWhether the field should display as invalid
minLengthnumber-The minimum number of characters required
maxLengthnumber-The maximum number of characters allowed
validate(value: string) => ValidationError | true | null | undefined-Custom validation function
autoCompletestring-Hints for browser autocomplete
namestring-The name of the input, used when submitting a form
validationBehavior"native" | "aria""native"Whether to use native HTML form validation or ARIA-based validation
onFocus(e: FocusEvent) => void-Called when the textarea receives focus
onBlur(e: FocusEvent) => void-Called when the textarea loses focus
onFocusChange(isFocused: boolean) => void-Called when the focus state changes
inputPropsPartial<TextAreaProps>-Additional props to pass to the textarea element
classNamesSlotsToClasses<"base" | "label" | "input" | "description" | "error">-Custom CSS classes for component slots