Textarea

A multi-line text control with focus, invalid, and disabled states.

Preview#

Controls
import { Textarea } from "raft-ui";

<Textarea />

States#

disabled wins over data-invalid. A disabled invalid textarea keeps the disabled border and removes the invalid ring because the user cannot edit it.

Counter#

Place TextareaCounter inside TextareaGroup to position it below the textarea. Pass the current value from your change handler and the intended limit explicitly. Omit native maxLength when the counter should show an over-limit state.

20/24

Auto grow#

Use field-sizing-content when the textarea should grow with its content. The component still keeps its default minimum height; pair content sizing with a max height for long drafts so the control scrolls instead of pushing the page indefinitely.

With Field#

Label, description, and error copy come from Field. Textarea stays a pure control while Field associates supporting copy and validation feedback with it.

Keep the summary under 120 characters.

API#WIP

data-invalid
boolean
Standalone invalid styling; the control mirrors it to aria-invalid. Inside Field, set Field invalid instead.
ref
Ref<HTMLTextAreaElement>
Forwarded to the underlying textarea (React 19 ref prop).
...props
TextareaHTMLAttributes
All native textarea attributes (value, onChange, rows, maxLength, placeholder, disabled, etc.).
children
ReactNode
Place Textarea and TextareaCounter as direct children. The counter sits below the control, aligned to its end.
...props
ComponentProps<"div">
Native div attributes for layout, width, and custom composition.
value
string
Text whose length is counted. Ignored when count is set.
count
number
Override the counted length directly.
limit
number
Shown after the slash; the counter turns red once length exceeds it.
getLength
(value: string) => number
Custom length function, for example Unicode code point counting.
...props
ComponentProps<"span">
Native span attributes for custom counter labeling or test hooks.