TextArea receives much longer user text input to complete a form.

TextArea

Usage

  • Use TextArea for longer, multi-line text such as descriptions, messages, notes, and feedback.
  • Use TextArea when input is expected to exceed a single line or when line breaks are essential to the value.
  • Use TextField instead for shorter, single-line values.
  • Size the height (rows) to the expected response length. Use three to five rows for most descriptions and messages.
  • Never use a single row (rows={1}) for multi-line text.
  • Provide a visible label (label) so users understand the purpose of the field at a glance.
  • Provide an accessible label (ariaLabel) when a visible label isn't possible.
  • Never use a placeholder in place of a visible label.

Appearance

  • Height (rows) — two rows by default. Raise it for longer content such as message bodies or instructions.
  • Vertical resize (resize="vertical") — the default. Lets the user make the field taller to review what they've written.
  • No resize (resize="none") — removes the handle. Use when the field sits in a fixed layout where a taller field would push other content out of place.
  • Horizontal resize (resize="horizontal") and both directions (resize="both") — use only when the field is not full width.
  • Full width (isFullWidth) — the default. Use for most forms, where the field aligns with the controls above and below it.
  • Fixed width (isFullWidth={false} with cols) — use when the field sits inline with other inputs or elements.

Behaviors

  • Base, hover, focus, and active states follow standard form-control styling; focus adds the standard 2px focus ring and updates the border color.
  • Disabled state (isDisabled) — blocks all interaction and updates the background and text color.
  • Critical state (isInvalid with error) — applies critical styling and renders the error message below the field.
  • Auto-grow (minRows with maxRows) — the field starts at the minimum rows and grows as the user types, then scrolls past the maximum. Use for prompts and messages where response length varies widely. The resize handle is hidden while auto-grow is on.
  • Submit on Enter (shouldSubmitOnEnter) — Enter submits the form and Shift+Enter inserts a new line. Reserve for chat-style inputs where the user sends each entry quickly.
  • State the Enter and Shift+Enter behavior in the description whenever shouldSubmitOnEnter is set.
  • Never use shouldSubmitOnEnter on a form field where line breaks are expected.

Content

  • Write labels as clear, concise nouns or noun phrases describing the expected content. Use a direct question for open-ended feedback where a full answer is expected.
  • Never use instructional phrases as a label.
  • Leave placeholder empty for most TextAreas — a blank field reads more clearly as unfilled.
  • Use placeholders to show an example response, starting with "e.g.". Never repeat the label as the placeholder.
  • Write description text as short, complete sentences explaining what the content is used for, what to include, or any length limit.
  • Show the remaining character count in the description when the field has a character limit.
  • Write errors as direct instructions naming the problem and how to resolve it. Never write vague errors such as "Invalid input", and never use "please".

Implementation Notes

  • label, description, and error accept rich content in place of a plain string: React takes a ReactNode directly; Ember takes the :label, :description, and :error named blocks. Use this for labels with optional indicators, and for descriptions or errors with inline links.
  • Setting error alone applies the invalid styling; isInvalid is not required alongside it.
  • Auto-grow turns on only when minRows is set; maxRows alone has no effect. minRows overrides rows for the initial height.
  • resize="horizontal" and resize="both" require isFullWidth={false}. On a full-width field, horizontal falls back to none and both falls back to vertical.
  • shouldSubmitOnEnter calls requestSubmit() on the enclosing form; it does nothing when the TextArea is not inside a form.
  • Passing value without onChange or onInput renders an uncontrolled field — the value is applied as the textarea's default.
  • onChange, onInput, onFocus, and onBlur receive the native DOM event in both frameworks, not a React synthetic event.
  • The component throws an accessibility error at render when none of label, ariaLabel, or ariaLabelledby is provided.
  • shouldAllowAutofill defaults to false, which disables browser autofill and password managers. Set it to true where autofill is wanted.
  • unsafe_textareaWrapperClassName applies additional classes to the element wrapping the textarea.
  • Ember invocation is <PlumaTextArea> with @argName args. Splattributes land on the textarea element, not the container.

On this page