Textarea
A bigger box for writing a few lines, like a note or a reply.
Examples
Up to 500 characters.
Auto grow
falsedefault
true
States
rest
filled
hover
focus-visible
invalid
disabled
Usage
When to use it
- Use
- A description, note or request that takes several lines.
- Use
- A message composer that grows with what is typed (autoGrow).
- Not for
- The answer is one line: a title, a handle, a link. Use Input.
- Not for
- It is the chat box of an AI conversation with a cost and a send button. Use Chat input.
Rules
8 rules
- Should
- Set autoGrow for a request or message so the whole text stays in view.
- Must
- Wrap a textarea that collects a value in Field with a FieldLabel. Because a placeholder is gone at the first keystroke, and the field loses its name with it.
- Must
- Show the count in a FieldDescription before the limit; never cut the text silently. Because maxLength drops pasted text past the limit with no message.
- Should
- Show an example answer as the placeholder, never the label.
- Must
- Pass aria-label when there is no visible label. Because some screen readers skip a placeholder as the name, and it vanishes once typing starts.
- Never
- Set an h-* class; use rows or autoGrow. Because autoGrow writes an inline height over it, and rows counts lines at the current type size.
- Must
- Expect 80px minimum and 240px maximum; never lift max-h on autoGrow. Because past 240px a long note pushes the Send button off a phone screen.
- Must
- Submit with a button or Ctrl+Enter; Enter adds a line. Because Enter in a textarea inserts a newline, so a form that waits for Enter never sends.
Accessibility
4 checks
- Name the textarea from FieldLabel or aria-label.
- Tab moves focus past it and never inserts a tab character.
- Invalid is only a border color; FieldError carries the message.
- base.css lifts the font to 16px on a coarse pointer so iOS does not zoom.
Edge cases
6 edge cases
- Long value with autoGrow
- Grows to 240px, then scrolls inside; measured on mount.
- Narrow container
- w-full and min-w-0, so it wraps at 160px.
- Right to left
- Text aligns to the start edge; the resize handle follows the direction.
- Touch
- The resize handle is small; use autoGrow on phones.
- Inside a form
- Enter adds a line and does not submit.
- Forced colors
- The border stays visible; the focus outline survives.
API
3 props
autoGrowbooleandefaultfalserowsnumberaria-invalidboolean
Tokens
12 tokens
--field- #f6f5f2
--line-strong- #cfcdc6
--fg- #0f0f0d
--fg-3- #6b6a63
--control- #85827a
--accent-line- #7c8700
--ring- var(--accent-line)
--line-focus- 2px
--danger- #d93636
--surface-2- #efeeea
--fg-disabled- #a6a49b
--radius-field- 12px