Text Area renders one <textarea> and nothing else. The label above it, the
helper text below it and the id that connects them all belong to
FormField, which is why the anatomy below shows the two
together — and why TextAreaField, which is the two of them already composed,
is the component to render.
Anatomy
Section titled “Anatomy”-
Label what is being asked. It belongs toUp to 500 characters.Up to 500 characters.FormField, which also ties it to the field for a screen reader. -
Text area the field itself, and the whole of whatUp to 500 characters.Up to 500 characters.TextArearenders. The corner handle is the browser’s, not a prop. -
Helper text (optional) the rule or the example, alsoUp to 500 characters.Up to 500 characters.FormField’s. It is the only one of these that survives the first keystroke — a placeholder does not.
When to use
Section titled “When to use”A five-line box is a request for five lines. It suits a description, a comment, a note, an explanation of something the form could not ask for directly. A one-word answer in one reads as a mistake the reader has made, so ask for that in a single-line input, where the size of the field matches the size of the answer.
The field accepts plain text, and a newline is the only formatting it keeps. PDS has no rich text editor, so anything needing bold or a list has to be built outside the system. Where the answer is one of a known set, it belongs in a Combobox or a Select rather than in prose someone has to read.
A textarea and its label ship as one component
Section titled “A textarea and its label ship as one component”TextAreaField takes FormField’s props and the textarea’s props in one object
and splits them internally, so label, helperText, errorText and
warningText sit beside value, onChange and maxLength in a single call.
It also settles the id: it hands FormField whatever inputId or id you passed,
which is the one thing hand-composition gets wrong quietly, because a textarea
given its own id inside a FormField ends up with a label pointing somewhere
else.
Hand-composing a FormField around a textarea buys nothing the field component does not already do. The case for doing it anyway is on that page, and it is about what else sits in the input slot.
Change the height in CSS, not with the rows attribute
Section titled “Change the height in CSS, not with the rows attribute”A text area is 128 pixels tall, from a theme token the component applies after
the shared input styles. That beats the rows attribute, so passing rows
changes nothing about the rendered field. Set the height in your own
stylesheet.
The resize handle is the browser’s, and PDS does not remove it
Section titled “The resize handle is the browser’s, and PDS does not remove it”resize is CSS, not a prop. The corner handle is the browser’s default for a
<textarea>, and nothing in PDS removes it. Fix the height in your stylesheet
when layout stability matters, and leave it resizable when it doesn’t. That
decision lives in CSS, which is why you will not find a prop for it.
Constrain the resize where growth would break the layout or cover something beside the field, which a reader dragging the handle has no way to anticipate.
Do not reach for size to change the height
Section titled “Do not reach for size to change the height”size sets the padding and the type scale, the same two things it sets on every
input, and not the height. The height override lands after it, so sm and md
are both 128 pixels tall.
Accessibility
Section titled “Accessibility”A bare textarea reaches a screen reader unnamed
Section titled “A bare textarea reaches a screen reader unnamed”Text Area has no label prop, and it reads its id from FormField’s context.
That id is what the label’s for attribute points at, so a textarea rendered
outside either wrapper is an unnamed text box. Passing aria-label through to
the element names it without showing anything, which is the wrong trade for a
field asking for a paragraph.
The error state does not travel with the error text
Section titled “The error state does not travel with the error text”aria-invalid and the red border both come from Text Area’s own hasError,
which it reads from its props and not from FormField’s context. TextAreaField
does not derive one from the other either: it routes errorText to the label
half and hasError to the textarea, so a field given only errorText prints a
red message beside a box that still looks and announces as valid. Pass both.
Select and Combobox do read the error state from context, which is why this is worth checking on a textarea specifically and not on the others.
Nothing associates the message itself with the field. See FormField for what that costs and how to wire it.
Content
Section titled “Content”Say the limit before the reader reaches it
Section titled “Say the limit before the reader reaches it”maxLength is the element’s own attribute, so the browser enforces it in
silence: keystrokes past the limit do nothing, with no message and nothing
announced. Put the number in helper text, and add a counter when the limit is
tight enough that someone will hit it mid-sentence.
Helper text is also the only text around the field that survives the first keystroke. Anything the reader still needs while typing goes there rather than in the placeholder. Writing has the rest of the rules for both.
TextAreaField is the larger API of the two, and it is every prop below plus
the twelve FormField carries. Its table comes first.
| Name | Type |
|---|---|
label |
Renders |
inputId |
ID of the input element. Providing this will automatically link the label to the input. |
helperText |
Renders |
errorText |
Renders |
warningText |
Renders |
labelProps |
|
helperProps |
|
warningProps |
|
errorProps |
|
configField |
Whether to render the form field as a config field. This will render the helper text as a tooltip. |
configFieldInputWidth |
Override the width of the input area when |
rightActions |
Renders actions to the right of the label. |
hasError |
|
hasWarning |
|
hovered |
Visual state override. Forces the |
focused |
Visual state override. Forces the |
active |
Visual state override. Forces the |
checked |
Visual state override. Forces the |
mixed |
Visual state override. Forces the |
size |
Size of the input. If you need the HTML size attr, use inputSize. |
ComponentPropsWithoutRef<‘textarea’>.Text Area’s own props, which TextAreaField also accepts. Eight of them, and
five pin a visual state: hovered, focused, active, checked and mixed
force a styling state on permanently, for specimens and visual tests rather than
application code. checked and mixed arrive with the shared input type, and a
multi-line field has neither state to pin.
What you will actually pass comes from the element: value, onChange,
placeholder, maxLength, readOnly and the rest of a textarea’s own API.
| Name | Type |
|---|---|
hasError |
|
hasWarning |
|
hovered |
Visual state override. Forces the |
focused |
Visual state override. Forces the |
active |
Visual state override. Forces the |
checked |
Visual state override. Forces the |
mixed |
Visual state override. Forces the |
size |
Size of the input. If you need the HTML size attr, use inputSize. |
ComponentPropsWithoutRef<‘textarea’>.Was this page helpful?