Textarea
A styled native textarea for multi-line text — error and disabled states, a focus border tint, and an optional auto-grow mode.
- Status
- Since
0.1.0- Accessibility pattern
- native textarea
Last updated
Install
Add Textarea from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/textareaUsage
import { Textarea } from "@/components/ui/textarea";
<Textarea placeholder="Tell us about your project…" />;Textarea is a thin wrapper over the native <textarea>, so every standard
attribute (value/defaultValue, onChange, name, rows, required,
readOnly, maxLength, …) works as expected, and its ref forwards to the
underlying element. It shares its border and token styling with
Input so the two fields look identical.
Examples
States
The field reflects disabled, readOnly, and aria-invalid. The invalid state
re-colors the border with the destructive token — pair it with a
visible error message for non-color-dependent feedback. It resizes vertically by
default; the last example below uses autoGrow to size to its content instead.
Sizes
sm / md / lg. A multiline field sizes by minimum height and padding rather than the fixed
control heights a single-line Input uses — a textarea grows with its
content, so a fixed height would be the wrong contract — and sm steps the type down a tier with it.
<Textarea size="sm" aria-label="Compact" />
<Textarea size="md" aria-label="Default" />
<Textarea size="lg" aria-label="Roomy" />Auto-grow
Pass autoGrow to grow the field to fit its content instead of scrolling, using
native CSS field-sizing: content. Set a starting height with rows and cap the
growth with a max-h-* utility via className. The first field below is a normal
fixed-height textarea (it scrolls); the second is the live autoGrow field — type
into it (or edit the text) and it grows line by line until it hits the max-h-40
cap, then scrolls.
<Textarea autoGrow rows={2} className="max-h-40" placeholder="Auto-grows…" />Playground
Try every size with the auto-grow, disabled, and invalid states, then copy the generated JSX.
<Textarea placeholder="Tell us about your project…" />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
autoGrow | boolean | false | When true, the field grows to fit its content instead of scrolling,
using native CSS field-sizing: content. Combine with rows for a
starting height and the max-h-* utility (via className) for a cap.
Falls back to a fixed, scrollable height in browsers without support. |
render | ComponentRenderFn<HTMLProps, FieldControlState> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | <textarea /> | Base UI's polymorphic render prop (§7.6). Defaults to a native <textarea>; pass an element
to swap the rendered node while keeping the Field wiring and the token chrome. |
size | "lg" | "md" | "sm" | 'md' | Density tier — sm compact, default, lg roomy. Multiline fields scale by
min-height + padding (register P1-04). |
Data attributes and CSS variables on Textarea
| Attribute | Values |
|---|---|
data-size | mirrors a prop or state value |
data-slot | "textarea" |
Accessibility
- Renders a native
<textarea>— always associate a visible<label>(wrap it or usehtmlFor/id); usearia-labelonly when a visible label is impossible. - The surface uses
outline-hidden— a transparent 2px outline, not a removed one — and replaces it with the text-field focus treatment: on focus the border re-colors with theringtoken (focus:border-ring/(--alpha-tint-border)). The darkened border is the sole focus cue in normal colours, matchingInput. Underforced-colors: activethe border tint is erased by the forced palette, and the transparent outline is what that palette repaints — which is why the outline is hidden rather than removed. - Set
aria-invalid(andaria-describedbypointing at the error text) to mark a field invalid; the styling is token-driven and never relies on color alone. Focus outranks invalid: while the textarea is focused the border carries theringtint, and the destructive tint returns on blur — the border is the field's only focus cue, so nothing else may hold it. - The resize handle and
autoGroware visual conveniences only — keyboard and screen-reader interaction is the standard native<textarea>behavior.
| Contract | States tested |
|---|---|
| Behaviour | default, disabled, error, invalid |
| Accessibility | invalid, semantic-html |
| Visual | default, focus, disabled, invalid, error, dark |