Text Area

A multi-line text input field with size and variant options.

Anatomy

Import and assemble the component:

1import { TextArea } from "@raystack/apsara";
2
3<TextArea placeholder="Enter text" />

For labels, description, and error messages, wrap with Field:

1import { Field, TextArea } from "@raystack/apsara";
2
3<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("");
3
4 return (
5 <Field
6 label="Controlled TextArea"
7 description={`${value.length} characters`}
8 >
9 <TextArea
10 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("");
3
4 return (
5 <Field label="Bio" description={`${value.length} characters`}>
6 <TextArea
7 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:

SlotElement
text-areaThe <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