Textarea
A text box that eases to the height of what you write, with a count that rolls and turns amber near the limit.
Used forComments and repliesBio and description fieldsFeedback formsRelease notes and changelogs
Install with the shadcn CLI
Templates
Need the whole page?
43 Next.js landing pages, each designed from scratch. Try any of them live; one is $39, all of them $99, and 5 are free.
Where it’s used
Comments and replies
A box that starts at three lines and grows as the reply does.
Bio and description fields
A limit with a count that warns before it stops you.
Feedback forms
Long answers that scroll after ten lines instead of taking the page.
Release notes and changelogs
Writing in a card without a fixed height.
What it handles for you
Growing a textarea by resetting its height to auto to measure it flickers and jumps. A hidden mirror measures instead, so the real box only ever eases.
Eased growth
The box eases to each new height in 260ms, between minRows and maxRows.
A count that rolls
Each digit rolls the way the count moved; amber in the last 10%, red at the limit.
Same field as the rest
Label, hint, error and shake work exactly as in Input.
No layout reads per keystroke
One ResizeObserver on the mirror, not scrollHeight on every change.
Overview
Auto-growing textareas usually snap a line taller on every wrap, or reset their height to measure and flicker. This one measures a hidden copy of the text and eases the box to it between minRows and maxRows, then scrolls. With maxLength the count rolls digit by digit and turns amber in the last tenth.
States
- rest
- Three lines tall by default inside a 14px-radius hairline box.
- growing
- Each wrap eases the box to the mirror's height (260ms); past maxRows it scrolls.
- near limit
- With maxLength, the count turns amber at 90% and red at 100%.
- error
- Red line, the error replaces the hint, one shake.
Usage
Works with
Props
| Prop | Type | Description |
|---|---|---|
| minRows / maxRows | numberdefault 3 / 10 | Height range in lines; it scrolls past maxRows. |
| maxLength | number | Limit; shows a rolling count beside the label. |
| showCount | booleandefault true | Show the count when maxLength is set. |
| label / hint / error | ReactNode | As in Input. |
| onValueChange | (value: string) => void | The new text on every change. |
| ...textarea props | TextareaHTMLAttributes | Everything a native textarea takes, including ref. |
Accessibility and motion
- Shares field.tsx with every text control: one surface, one focus ring, one way of showing hints and errors.
- Reduced motion: the height changes at once.
- Pass textareaClassName to change type; the mirror takes the same classes.
Requirements
React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.
The CLI also installs Number roll, ui-interaction-motion.
Source
Registry item: /r/textarea.json


