TextArea
The <TextArea>
is a form component that allows users to enter and edit multiline text content with a keyboard. It consists of a textarea input field, a label, and optional help text that can also display error messages for validation feedback.
It behaves similarly to the <TextField>
component but is designed specifically for longer, multiline text input. The properties have identical behavior to those in <TextField>
.
You can also add all usual properties from the HTML textarea element.
Anatomy
A textarea consists of an input area that accepts multiline text, and a label which informs the user about the content they need to enter. <TextArea>
automatically manages the relationship between these elements and supports optional description and error message elements for providing context and validation feedback.
Appearance
The appearance of a component can be customized using the variant
and size
props. These props adjust the visual style and dimensions of the component, available values are based on the active theme.
Property | Type | Description |
---|---|---|
variant | - | The available variants of this component. |
size | - | The available sizes of this component. |
Usage
Use a <TextArea>
when users need to input longer text content that spans multiple lines, such as comments, descriptions, feedback, or any free-form text that cannot be effectively captured in a single-line text field.
The <TextArea>
is ideal for content like product descriptions, user reviews, messages, notes, or any scenario where users might need to write several sentences or paragraphs. It provides enough space for users to compose and review their text before submission.
When to use TextArea vs TextField
Choose <TextArea>
over <TextField>
when you expect users to enter more than a few words or when the content naturally spans multiple lines. Use <TextField>
for single-line inputs like names, emails, or short responses.
Use TextArea for longer text content like comments, descriptions, or feedback that spans multiple lines.
Don't use TextArea for short, single-line inputs like names or email addresses.
Labels and placeholders
Keep labels short and descriptive. The label should clearly indicate what type of content is expected. Avoid using placeholder text as a replacement for labels, as it disappears when users start typing and can cause accessibility issues.
Use clear, concise labels that describe the expected content.
Don't rely on placeholder text as the primary way to indicate what content is expected.
Sizing and rows
Set an appropriate initial height using the rows
prop to give users a visual hint about how much content is expected. For short responses, 3-4 rows is usually sufficient. For longer content like detailed feedback or descriptions, consider 6-8 rows or more.
Set an appropriate number of rows that matches the expected content length.
Don't use too few rows for content that typically requires more space, as it creates a poor user experience.
Props
aria-activedescendant?
string;
aria-autocomplete?
"none" | "inline" | "list" | "both";
aria-controls?
string;
aria-describedby?
string;
aria-details?
string;
aria-errormessage?
string;
aria-haspopup?
boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog";
aria-label?
string;
aria-labelledby?
string;
autoComplete?
string;
autoCorrect?
string;
autoFocus?
boolean;
defaultValue?
string;
"none"
description?
ReactNode;
dir?
string;
disabled?
boolean;
true
, the textarea is disabled."false"
enterKeyHint?
"enter" | "done" | "go" | "next" | "previous" | "search" | "send";
error?
boolean;
true
, the field is considered invalid and if set the errorMessage
is shown instead of the description
."false"
errorMessage?
ReactNode | ((v: ValidationResult) => ReactNode);
excludeFromTabOrder?
boolean;
form?
string;
<form>
element to associate the input with.
The value of this attribute must be the id of a <form>
in the same document.
See MDN.hidden?
boolean;
id?
string;
inert?
boolean;
inputMode?
"none" | "search" | "text" | "url" | "tel" | "email" | "numeric" | "decimal";
label?
ReactNode;
lang?
string;
maxLength?
number;
minLength?
number;
name?
string;
onAnimationEnd?
AnimationEventHandler<HTMLDivElement>;
onAnimationEndCapture?
AnimationEventHandler<HTMLDivElement>;
onAnimationIteration?
AnimationEventHandler<HTMLDivElement>;
onAnimationIterationCapture?
AnimationEventHandler<HTMLDivElement>;
onAnimationStart?
AnimationEventHandler<HTMLDivElement>;
onAnimationStartCapture?
AnimationEventHandler<HTMLDivElement>;
onAuxClick?
MouseEventHandler<HTMLDivElement>;
onAuxClickCapture?
MouseEventHandler<HTMLDivElement>;
onBeforeInput?
FormEventHandler<HTMLInputElement>;
onBlur?
(e: FocusEvent<HTMLInputElement, Element>) => void;
onChange?
(value: string) => void;
onClick?
MouseEventHandler<HTMLDivElement>;
onClickCapture?
MouseEventHandler<HTMLDivElement>;
onCompositionEnd?
CompositionEventHandler<HTMLInputElement>;
onCompositionStart?
CompositionEventHandler<HTMLInputElement>;
onCompositionUpdate?
CompositionEventHandler<HTMLInputElement>;
onContextMenu?
MouseEventHandler<HTMLDivElement>;
onContextMenuCapture?
MouseEventHandler<HTMLDivElement>;
onCopy?
ClipboardEventHandler<HTMLInputElement>;
onCut?
ClipboardEventHandler<HTMLInputElement>;
onDoubleClick?
MouseEventHandler<HTMLDivElement>;
onDoubleClickCapture?
MouseEventHandler<HTMLDivElement>;
onFocus?
(e: FocusEvent<HTMLInputElement, Element>) => void;
onFocusChange?
(isFocused: boolean) => void;
onGotPointerCapture?
PointerEventHandler<HTMLDivElement>;
onGotPointerCaptureCapture?
PointerEventHandler<HTMLDivElement>;
onInput?
FormEventHandler<HTMLInputElement>;
onKeyDown?
(e: KeyboardEvent) => void;
onKeyUp?
(e: KeyboardEvent) => void;
onLostPointerCapture?
PointerEventHandler<HTMLDivElement>;
onLostPointerCaptureCapture?
PointerEventHandler<HTMLDivElement>;
onMouseDown?
MouseEventHandler<HTMLDivElement>;
onMouseDownCapture?
MouseEventHandler<HTMLDivElement>;
onMouseEnter?
MouseEventHandler<HTMLDivElement>;
onMouseLeave?
MouseEventHandler<HTMLDivElement>;
onMouseMove?
MouseEventHandler<HTMLDivElement>;
onMouseMoveCapture?
MouseEventHandler<HTMLDivElement>;
onMouseOut?
MouseEventHandler<HTMLDivElement>;
onMouseOutCapture?
MouseEventHandler<HTMLDivElement>;
onMouseOver?
MouseEventHandler<HTMLDivElement>;
onMouseOverCapture?
MouseEventHandler<HTMLDivElement>;
onMouseUp?
MouseEventHandler<HTMLDivElement>;
onMouseUpCapture?
MouseEventHandler<HTMLDivElement>;
onPaste?
ClipboardEventHandler<HTMLInputElement>;
onPointerCancel?
PointerEventHandler<HTMLDivElement>;
onPointerCancelCapture?
PointerEventHandler<HTMLDivElement>;
onPointerDown?
PointerEventHandler<HTMLDivElement>;
onPointerDownCapture?
PointerEventHandler<HTMLDivElement>;
onPointerEnter?
PointerEventHandler<HTMLDivElement>;
onPointerLeave?
PointerEventHandler<HTMLDivElement>;
onPointerMove?
PointerEventHandler<HTMLDivElement>;
onPointerMoveCapture?
PointerEventHandler<HTMLDivElement>;
onPointerOut?
PointerEventHandler<HTMLDivElement>;
onPointerOutCapture?
PointerEventHandler<HTMLDivElement>;
onPointerOver?
PointerEventHandler<HTMLDivElement>;
onPointerOverCapture?
PointerEventHandler<HTMLDivElement>;
onPointerUp?
PointerEventHandler<HTMLDivElement>;
onPointerUpCapture?
PointerEventHandler<HTMLDivElement>;
onScroll?
UIEventHandler<HTMLDivElement>;
onScrollCapture?
UIEventHandler<HTMLDivElement>;
onSelect?
ReactEventHandler<HTMLInputElement>;
onTouchCancel?
TouchEventHandler<HTMLDivElement>;
onTouchCancelCapture?
TouchEventHandler<HTMLDivElement>;
onTouchEnd?
TouchEventHandler<HTMLDivElement>;
onTouchEndCapture?
TouchEventHandler<HTMLDivElement>;
onTouchMove?
TouchEventHandler<HTMLDivElement>;
onTouchMoveCapture?
TouchEventHandler<HTMLDivElement>;
onTouchStart?
TouchEventHandler<HTMLDivElement>;
onTouchStartCapture?
TouchEventHandler<HTMLDivElement>;
onTransitionCancel?
TransitionEventHandler<HTMLDivElement>;
onTransitionCancelCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionEnd?
TransitionEventHandler<HTMLDivElement>;
onTransitionEndCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionRun?
TransitionEventHandler<HTMLDivElement>;
onTransitionRunCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionStart?
TransitionEventHandler<HTMLDivElement>;
onTransitionStartCapture?
TransitionEventHandler<HTMLDivElement>;
onWheel?
WheelEventHandler<HTMLDivElement>;
onWheelCapture?
WheelEventHandler<HTMLDivElement>;
pattern?
string;
placeholder?
string;
"none"
readOnly?
boolean;
true
, the textarea is read-only."false"
ref?
Ref<HTMLTextAreaElement>;
ref.current
to null
(or call the ref with null
if you passed a callback ref).
@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}required?
boolean;
true
, the textarea is required."false"
rows?
number;
"none"
slot?
string | null;
null
value indicates that the local props completely override all props received from a parent.spellCheck?
string;
translate?
"yes" | "no";
type?
"search" | "text" | "url" | "tel" | "email" | "password" | (string & {});
validate?
(value: string) => true | ValidationError | null;
validationBehavior="native"
. For realtime validation, use the isInvalid
prop instead.validationBehavior?
"native" | "aria";
'native'
value?
string;
"none"
width?
WidthProp;
"full"