Skip to content

Now in the official shadcn registry directory.

Start free

Textarea

An auto-growing textarea with 3 variants, 3 sizes and 3 tones matching Input - the height follows the content via field-sizing.

form
A free styled version is available

Installation

Run the following command

npx shadcn@latest add @ai2/textarea

Dependencies, the @ai2/tokens theme and the component file are installed together.

Usage

TS
import { Textarea } from "@/components/ui/textarea"

<Textarea placeholder="Tell us what you are building…" />

All three axes are optional - omit them and you get the outline medium neutral textarea. It grows with its content by default, starting at a per-size minimum height.

Examples

Variants

The variants match Input one-to-one, so mixed forms stay visually consistent.

Sizes

Each size sets the minimum height, padding, radius and text scale; auto-grow still takes over once the content exceeds the floor.

Tones

The tone axis colors the border and focus ring with the success or danger token, giving controlled validation feedback without touching aria-invalid.

Auto-grow

Sizing is handled by CSS field-sizing-content - type into the preview above and watch the height follow.

Invalid state

Set aria-invalid on validation errors - the danger border and ring style is built in.

Disabled

The native disabled attribute halves the opacity and sets a not-allowed cursor. A following ai2 Label dims with it automatically.

Props

Textarea also accepts every native <textarea> prop.

PropTypeDefaultDescription
variant"outline" | "soft" | "ghost""outline"Visual style of the textarea, matching Input.
size"sm" | "md" | "lg""md"Minimum height, padding, radius and typography scale, aligned with Input.
tone"neutral" | "success" | "danger""neutral"Semantic validation color: success and danger recolor the border and focus ring.

ai2 Textarea: an auto-growing textarea for React forms

The ai2 Textarea is a shadcn-compatible textarea component for React, built on the native <textarea> element and styled with Tailwind CSS v4. Its height follows the content automatically through the CSS field-sizing-content property, so multi-line inputs grow as users type, with no resize handle and no JavaScript measuring.

Because it ships through the shadcn registry format, you install it with one CLI command, an MCP agent, or a copy-paste, and the source lands in your own project. You own the file; there is no runtime dependency on ai2 itself. The live example above is the exact component you get.

What is the ai2 Textarea?

It is a single Textarea component with a variant axis of three styles: outline (default, bordered), soft (filled surface that clears on focus) and ghost (transparent until hover), plus a size axis (sm, md, lg) and a tone axis (neutral, success, danger). The anatomy matches shadcn/ui, so existing snippets and AI agents keep working; all three props are additive.

The variants, sizes and tones match the ai2 Input one-to-one, so mixed forms with single-line and multi-line fields stay visually consistent. Styling comes from the ai2 token file, which means borders, surfaces and the focus ring follow your theme in both light and dark mode from day one.

Why use it

  • Auto-grow without JavaScript: field-sizing-content lets the browser size the textarea to its content, starting from a per-size minimum height (min-h-16 at the default md). There is no hidden mirror element, no resize observer and no layout jump.
  • Visual parity with Input: outline, soft and ghost use the same borders, surfaces and focus treatment as the ai2 Input, and the size and tone axes line up too, so a form that mixes both reads as one system.
  • Validation styling built in: Set aria-invalid and the danger border and ring appear automatically, with a stronger ring in dark mode. Accessibility state and visual state stay in sync by construction.
  • Native element underneath: It renders a real textarea, so labels, forms, autofill, spellcheck, maxLength and every other platform behavior work exactly as the browser intends.
  • Agent-readable metadata: The registry item describes the variant axis and intended use in plain words, so an MCP agent can find, inspect and install it without guessing.

Features

  • shadcn registry install: One command adds the component, its dependencies and the @ai2/tokens theme to your project.
  • Three axes via cva: 3 variants (outline, soft, ghost), 3 sizes (sm, md, lg) and 3 tones (neutral, success, danger) are defined in a class-variance-authority matrix, and the exported textareaVariants lets you reuse the exact styles elsewhere.
  • Focus-visible ring: A 3px ring and ring-colored border appear on focus, driven by the shared ring token rather than a hardcoded color.
  • Invalid state styling: aria-invalid switches the border and ring to the ai2 danger token, so error styling needs no extra class.
  • Motion from tokens: The color and box-shadow transition reads --motion-fast from the shared token file, matching every other ai2 component.
  • Data attributes for styling: The element exposes data-slot="textarea", data-variant and data-tone, so you can restyle specific variants from CSS without forking the component.

Production tips

  • Always pair with a label: Placeholders disappear on input. Use the ai2 Field or Label component so the purpose of the textarea stays visible and screen readers announce it.
  • Cap the growth for long input: Auto-grow is unbounded by default. For comment boxes that can get very long, add a max-h utility with overflow-y-auto so the field stops growing at a sane height.
  • Use tone for controlled validation color: tone="success" and tone="danger" recolor the border and focus ring without touching semantics. For actual errors prefer aria-invalid, which also announces the state to screen readers.
  • Drive aria-invalid from your form library: Wire aria-invalid to the field error state from react-hook-form or similar. You get correct semantics and the danger styling in one attribute.
  • Pick the variant per surface: outline reads best on plain backgrounds, soft on busy pages that need quieter fields, ghost inside toolbars and inline-edit contexts.
  • Set the starting height with rows: The native rows attribute still works and defines the initial height before content takes over, useful when you want a taller empty state than the size minimum.

Works with the rest of ai2

The textarea slots into the ai2 form stack. Wrap it in an ai2 Field for label, description and error wiring, or attach an ai2 Label directly. Use it next to the ai2 Input in the same form; the variants, sizes and tones match one-to-one.

Finish the flow with an ai2 Button to submit, and confirm the result with ai2 Sonner toasts. Everything shares one token source, so combinations stay visually consistent in both modes.

FAQs

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components