Textarea
Multi-line text. The same outline, hover and focus ring as Input, with 12px corners, a 64px minimum and field-sizing: content, so it grows with what you type. Source: src/components/ui/textarea.tsx.
Default
Pair it with a Label. The minimum height is 64px, about three lines.
Auto-grow
Type into the first box: it grows a line at a time, then scrolls once it hits its max-h. Always cap it. The browser's resize handle still works; add resize-none to remove it.
Variants
Default draws the box; bare removes it for a textarea that lives inside a surface you draw, such as a reply box.
States
Same rules as Input: hover lifts the outline, focus rings it, disabled fades to 50% on a tint, aria-invalid goes destructive.
Validation and limits
No Field primitive exists, so the counter, message and aria wiring are composed by hand. Clear the box and tab away, or paste past 280 characters.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "bare" | "default" | bare strips the box and switches to field-sizing-fixed so a caller's auto-grow (the composer) controls height. Mirrored as data-variant. |
| aria-invalid | boolean | "true" | "false" | — | Destructive outline and ring. Render and link the message yourself. |
| ...props | ComponentProps<"textarea"> | — | Native attributes pass through (rows, maxLength, disabled, readOnly). className merges last; use it for max-h-* or resize-none. |
Best practices
When to use
- Text that may run past one line: descriptions, instructions, feedback.
- A composer with attachments and a send button is Input group with InputGroupTextarea, not a bare Textarea.
Behavior
- Let it grow, but always set a max-h so it scrolls instead of pushing the page.
- Show a counter when there is a hard limit; prefer a soft limit with a message over maxLength silently eating input.
- Enter makes a new line. If Enter should submit, say so and support Cmd/Ctrl+Enter.
Accessibility
- Label it, and link the hint, counter or error with aria-describedby.
- Use aria-live="polite" on the message so changes are announced without stealing focus.
Content
- The placeholder shows an example of a good answer, not the label repeated.
- Errors name the fix: Trim it to 280 characters.