Text Area

A multi-line text input component that supports different visual variants.

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function TextAreaDemo() {
  return (
    <TextArea
      aria-label="Bio"
      placeholder="Tell us about yourself"
      resizeable
    />
  );
}
Always give a TextArea an accessible name by either pairing it with a <label> via htmlFor or giving it an aria-label. Without one, assistive technology announces the field with no indication of what it is for.

Options

PropTypeDescriptionDefault
size"sm" | "md" | "lg"The size of the textarea. Affects padding and typography."md"
variant"default" | "warning" | "success" | "error"The visual variant, which determines color scheme."default"
heightnumberThe fixed height of the textarea in pixels, scaling with base rem size.104
refRef<HTMLTextAreaElement>A ref forwarded to the underlying <textarea> element.—
placeholderstringPlaceholder text for the textarea." "
maxLengthnumberThe maximum number of characters the user can enter.—
minLengthnumberThe minimum number of characters required for the field to be valid.—
disabledbooleanWhen true, prevents interaction.false
requiredbooleanWhen true, marks the textarea as required and appends an asterisk to the placeholder text.false
readOnlybooleanWhen true, makes the textarea read-only.false
resizeablebooleanWhen true, enables resizing the textarea.false

Any other props are forwarded to the underlying <textarea> element.

Unlike the TextInput component, TextArea does not support icons or a type prop, since neither of them apply to multi-line text.

Examples

Uncontrolled vs controlled

Render a TextArea in an uncontrolled fashion to let it keep track of its own value:

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function UncontrolledTextArea() {
  return <TextArea aria-label="About" placeholder="Enter some text" />;
}

If you need to control the value of the TextArea, you can do so via the value and onChange props:

import { useState } from "react";

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function ControlledTextArea() {
  const [value, setValue] = useState("");

  return (
    <TextArea
      aria-label="About"
      placeholder="Enter some text"
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}

Different sizes

The TextArea component can be rendered at sm, md, or lg size, defaulting to md. Size affects the padding and text styles of the textarea.

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function TextAreaSizes() {
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: "var(--vesper-spacing-4)",
      }}
    >
      <TextArea size="sm" placeholder="A small TextArea" aria-label="About" />
      <TextArea size="md" placeholder="A medium TextArea" aria-label="About" />
      <TextArea size="lg" placeholder="A large TextArea" aria-label="About" />
    </div>
  );
}

Setting the height

You can give a TextArea a fixed height in pixels via the height prop, which defaults to 104. The value is converted to rem, so the rendered height scales with the base font size.

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function TextAreaHeight() {
  return (
    <TextArea
      aria-label="Release notes"
      placeholder="Summarize what changed in this release"
      height={200}
    />
  );
}

Resizing the TextArea

By default, a TextArea does not resize. If you want to opt-into resizing behavior, you can pass resizeable={true} or just resizeable, which allows the TextArea to be resized along its block direction.

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function ResizeableTextArea() {
  return (
    <TextArea
      resizeable
      aria-label="Release notes"
      placeholder="Summarize what changed in this release"
    />
  );
}

Disabling the textarea

You can disable the underlying textarea by passing disabled={true} or just disabled as a prop:

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function DisabledTextArea() {
  return (
    <TextArea
      aria-label="Overview"
      placeholder="Add a brief outline of your project"
      disabled
    />
  );
}

Usage in forms

TextArea renders a native <textarea>, so it works with regular form submission and native validation via props like name, form, required, minLength, and maxLength:

import { Button } from "@tenstorrent/vesper/button";
import { TextArea } from "@tenstorrent/vesper/text-area";

export default function FeedbackForm() {
  return (
    <form action="/api/feedback" method="post">
      <TextArea
        name="feedback"
        aria-label="Feedback"
        placeholder="What could we do better?"
        minLength={20}
        maxLength={500}
        required
      />
      <Button type="submit">Submit</Button>
    </form>
  );
}

Accessing the underlying element

Use the ref prop when you need direct access to the underlying <textarea> element, eg. to focus it or read its selection:

import { useRef } from "react";

import { TextArea } from "@tenstorrent/vesper/text-area";

export default function BioField() {
  const ref = useRef<HTMLTextAreaElement>(null);

  return (
    <TextArea aria-label="Bio" placeholder="Tell us about yourself" ref={ref} />
  );
}