Field.Textarea
Field.Textarea is a native <textarea> for multi-line text inside a Field. Height is CSS only: rows sets the height and the drag floor, and maxRows sets the cap. Padding sits on the textarea, inside the shell. Pass onChange for the event or onValueChange for the new string, or both; without either, the textarea is read-only.
On this page
<Field.Root aria-label="Note">
<Field.Textarea value={note} onChange={(event) => setNote(event.target.value)} rows={3} />
</Field.Root>
Height
autoGrow uses field-sizing: content where the browser has it, and grows with no cap when maxRows is omitted. Browsers without field-sizing stay at rows and scroll inside. Do not set an inline height when autoGrow is on; it overrides the growth.
autoGrow with maxRows={6}.
<Field.Root aria-label="Note">
<Field.Textarea value={note} onChange={(event) => setNote(event.target.value)} autoGrow maxRows={6} />
</Field.Root>
maxRows without rows starts at min(3, maxRows).
Drag-resize with autoGrow off stops at rows and at maxRows.
Density and states
Compact, comfortable, and spacious.
Dark appearance, for the native scrollbar.
Label, description, error, invalid, and disabled.
Highlights
highlights draws ranges of the text as tokens, on a layer behind the textarea that copies its type, padding and scroll. Each range is { start, end }, with an optional kind set as data-kind, an anchorName a popover can sit at, and draw: false to keep only the anchor. useMentions sets it through getTextareaProps(), for mentions and slash commands. Tokens read field.token.bg and field.token.radius.
Accessible composition
Todae handles: The textarea takes id, name, aria-label, aria-labelledby and aria-describedby from Field.Root, and native disabled and aria-invalid from the Root or a surrounding Fieldset.
You supply: A name, through a Label whose htmlFor is the Root id or aria-label / aria-labelledby on the Root.
Watch for: An inline height with autoGrow on stops the growth. Without field-sizing, an autoGrow textarea stays at rows and scrolls.
When to use
Field.Textarea
When: Multi-line free text such as notes, messages or descriptions. rows sets the starting height, and autoGrow grows it up to maxRows with CSS only.
When not: Single-line values, use Field.TextInput. Separate tags or tokens, use Field.ChipInput. Rich text or formatting, not shipped.
Props
| Name | Type | Description |
|---|---|---|
value Required | string | Controlled value. |
onChange | (event: ChangeEvent<HTMLTextAreaElement>) => void | Native change handler. Optional when onValueChange is enough. |
onValueChange | (value: string) => void | Optional value callback. |
placeholder | string | Native placeholder. |
rows | number | Starting height in rows. Also the native rows attribute and the drag floor. Default: "3" |
maxRows | number | Caps autoGrow and drag-resize. Omitted means no cap. |
autoGrow | boolean | Grows with content up to maxRows using CSS only. No maxRows means no cap. Default: "false" |
highlights | readonly FieldTextareaHighlight[] | Ranges of the text, { start, end, kind?, anchorName?, draw? }, drawn as tokens on a layer behind it. useMentions' getTextareaProps sets it. |