Text Area
A multi-line text input field with size and variant options.
Anatomy
Import and assemble the component:
1import { TextArea } from "@raystack/apsara";23<TextArea placeholder="Enter text" />
For labels, description, and error messages, wrap with Field:
1import { Field, TextArea } from "@raystack/apsara";23<Field label="Bio" description="Tell us about yourself" error={errors.bio?.message}>4 <TextArea placeholder="Write something..." />5</Field>
Usage
A multi-line input. Set its size and starting height, then decide who owns the value.
Basic usage
A multi-line text input. It grows with rows rather than with content, so set a height that fits the answer you expect.
1<TextArea placeholder="Enter your text here" />
Size
TextArea comes in two sizes: large (default) and small.
1<Flex direction="column" gap={5} style={{ width: 400 }}>2 <TextArea placeholder="Large size (default)" />3 <TextArea placeholder="Small size" size="small" />4</Flex>
Visual variants
TextArea supports default and borderless visual variants.
1<Flex direction="column" gap={5} style={{ width: 400 }}>2 <TextArea placeholder="Default variant" />3 <TextArea placeholder="Borderless variant" variant="borderless" />4</Flex>
Custom rows
TextArea defaults to 3 visible rows. Use the rows prop to adjust.
1<Flex direction="column" gap={5} style={{ width: 400 }}>2 <TextArea placeholder="Default (3 rows)" />3 <TextArea placeholder="6 rows" rows={6} />4</Flex>
With Field
Use Field to add label, description, and error handling.
1<Flex direction="column" gap={5} style={{ width: 400 }}>2 <Field label="Bio" required={false} description="Tell us about yourself">3 <TextArea placeholder="Write something..." />4 </Field>5 <Field label="Comments" required error="This field is required">6 <TextArea placeholder="Enter comments" />7 </Field>8</Flex>
Controlled
Pass value with onChange to own the state, the same contract as a native textarea.
1(function ControlledExample() {2 const [value, setValue] = React.useState("");34 return (5 <Field6 label="Controlled TextArea"7 description={`${value.length} characters`}8 >9 <TextArea10 value={value}11 onChange={(e) => setValue(e.target.value)}12 placeholder="Type something..."13 />14 </Field>
Using onValueChange
onValueChange fires alongside onChange with the new string value and an eventDetails object, as on Input. eventDetails.event is the native input event. Use it when you don't need the React change event.
1(function TextAreaValueChangeExample() {2 const [value, setValue] = React.useState("");34 return (5 <Field label="Bio" description={`${value.length} characters`}>6 <TextArea7 value={value}8 onValueChange={setValue}9 placeholder="Tell us about yourself..."10 />11 </Field>12 );13})
API Reference
Renders a multi-line text input. For label, description, and error support, use with Field.
Prop
Type
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
text-area | The <textarea> element itself |
Accessibility
- Use with Field for automatic label association and error linking
- Required state is communicated via
aria-required - Invalid state is communicated via
aria-invalid - Content is scrollable when text exceeds the visible rows