You're in the Library

Textarea

Multi-line text that grows with its content up to a maximum, with an optional character count. Give it a label prop or place it inside a Field.
Stable
Edit

Preview appears after the next Storybook update.

Textarea example
<Textarea />
Rendered with the real componentFrom the code
Light
Dark

When to use

Use it for

  • Free text longer than one line: pull request summaries, release notes, review comments.
  • showCount with maxLength when there is a hard limit.
  • appearance="inline" only to edit existing text in place, where the text is the page: a paragraph, a list item or a card title in a docs editor. It keeps the surrounding font, size and line height and shows a field on hover and focus.

Not for

  • A short single value: use Input.
  • Structured content (lists of tokens, key-value pairs): use dedicated fields.
  • appearance="inline" in a form, a dialog or a settings page: people scan forms for boxes, and an inline field there reads as plain text. Use the default field.

Do and don't

Every example is rendered with the real component, so it always matches what ships.

Do

Size it for the expected answer

rows sets the starting height; autosize grows it, so short boxes do not hide long answers.

Do

Inline only where the text already is

Swap the paragraph or list item for an inline Textarea holding the same text, so the page keeps its layout while it is edited. Name each one with aria-label.

Too long.
Don't

Hiding the limit until it is hit

Show the count while typing so users can edit before the error.

Don't

Inline fields in a form

Without a box, an empty form field reads as finished text. Forms use the default field with a visible label.

Accessibility

  • Native textarea through Base UI Field: label, description and error are wired for you.
  • Focus shows a 2px signal edge; invalid sets aria-invalid and a danger edge with a text error.
  • The visual counter is hidden from screen readers to avoid announcing every keystroke; maxLength is enforced natively.
  • On touch screens the text is 17px so iOS does not zoom on focus.
  • appearance="inline" is still a native, labelled textarea. Hover adds a fill and a hairline edge and focus the 2px DS ring, so the field never relies on color alone.
  • The inline placeholder uses the muted text color, checked at 4.5:1 on the canvas, surfaces and the hover fill.
  • Inline text inherits the page size, also on touch screens: keep the surrounding text at 16px or more so iOS does not zoom on focus.

Content guidelines

  • Placeholder shows an example answer, not instructions.
  • Use the hint for what makes a good answer.

From the code Generated from the component, not editable here.

Anatomy and tokens

Read from packages/react/src/components/Textarea/Textarea.module.css at build time. Every value is a token: open one to see its alias chain in both themes.

29 tokens18 semantic or component, change with theme and brand1 density, change with comfortable or compact10 from the shared scales

Motion and interaction

Textarea animates on hover. Try it in the preview at the top.

WhenWhat changesDurationEasing
HoverBorder, background and shadowmotion.duration.instant75 msmotion.easing.standardsettles in place

With reduced motion turned on, every change happens at once.

From the code Generated from the component, not editable here.

Props

Parsed from the TypeScript types in packages/react/src/components/Textarea/Textarea.tsx, so this table cannot drift from the code. It also accepts every native <HTMLTextAreaElement> attribute.

PropTypeDefaultDescription
labelstringnoneVisible label. When set, the Textarea wraps itself in a Field. Leave unset inside a Field.
hintReactNodenoneHelper text under the label.
errorReactNodenoneError message. Marks the textarea invalid and announces the message.
appearance'field' | 'inline''field'`field` (default) is the boxed form control. `inline` edits existing text in place: no border, no resize handle, the surrounding font, size and line height, and a height that always fits the content (`rows`, `maxRows` and `autosize` are ignored). Never use `inline` in a form.
rowsnumber3Minimum visible lines. Default 3. Ignored by `appearance="inline"`, which always fits its content.
maxRowsnumber12Grow with the content up to this many lines, then scroll. Default 12. Ignored by `appearance="inline"`.
autosizebooleantrueGrow with the content. Default true. When false the user can resize vertically. Ignored by `appearance="inline"`.
showCountbooleanfalseShow "used / maxLength" under the field. Needs maxLength.
hideLabelbooleannoneVisually hide the Field label. Only with `label`.
onValueChange(value: string) => voidnoneCalled with the new string value on every change.

Playground

Change the props and see the real Textarea update. Controls are generated from the TypeScript props; nothing here changes the system.

Code for these props
<Textarea label="Change summary" hint="Reviewers read this first. Say what changed and why." />

appearance

Workbench

For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Textarea in Storybook).

Embed Storybook stories here (7)

Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.

Default

WithCount

Invalid

Resizable

InAParagraph

InAList

AllStates

From the code Generated from the component, not editable here.

Changelog

  • New

    Textarea gets appearance="inline" for editing existing text in place: no border, no resize handle, the surrounding font, size and line height, a height that fits the content (field-sizing: content, measured without moving the page where it is not supported), a fill and hairline on hover and the DS focus ring on focus

    v1.0.0, Nov 11, 2026

  • Fix

    Component specs count height and width as the content box (a bordered table cell is its height plus its border), the Figma build draws an empty sized slot at its padding instead of 100px, and stories reach every Figma variant: a disabled control on IconButton, Input, Select, Combobox and Textarea, and Figma variant stories for AccordionItem, MenuItem, MenuCheckboxItem, MenuSubmenu and TableEmpty

    v1.0.0, Nov 11, 2026

  • Fix

    Component specs for Figma: inline custom properties set under a computed key or through a Base UI render element reach the CSS, a number held by a custom property and 1lh are read in calc() (a Textarea of 3 rows is 81px in Figma, as in code)

    v1.0.0, Nov 11, 2026

All release notes