---
title: Textarea
description: A multi-line field for comments, messages, and notes.
group: Components
order: 67
---

A multi-line field for comments, messages, and any note that needs a little more room.

```tsx
import { Textarea } from "@/components/ui/textarea"

export function Example() {
  return <Textarea placeholder="Type your message here." />
}
```

## Installation

```bash
npx @arctis-sh/@arctis-sh/ui@latest add textarea
```

## Usage

```tsx
import { Textarea } from "@/components/ui/textarea"
```

```tsx
<Textarea />
```

## With label

Add a label and short helper text when the field needs more context.

```tsx
import { Textarea } from "@/components/ui/textarea"

export function Example() {
  return (
    <div className="grid gap-2">
      <label
        htmlFor="message"
        className="text-sm font-medium tracking-wide"
      >
        Message
      </label>
      <p className="text-sm text-muted-foreground">
        What should we know?
      </p>
      <Textarea id="message" placeholder="Type your message here." />
    </div>
  )
}
```

## Disabled

Set `disabled` when the field is unavailable for input.

```tsx
import { Textarea } from "@/components/ui/textarea"

export function Example() {
  return (
    <div className="grid gap-2 opacity-60">
      <label
        htmlFor="message-disabled"
        className="text-sm font-medium tracking-wide"
      >
        Message
      </label>
      <Textarea id="message-disabled" placeholder="Type your message here." disabled />
    </div>
  )
}
```

## Invalid

Mark the control with `aria-invalid` when validation fails.

```tsx
import { Textarea } from "@/components/ui/textarea"

export function Example() {
  return (
    <div className="grid gap-2">
      <label
        htmlFor="message-invalid"
        className="text-sm font-medium tracking-wide text-destructive"
      >
        Message
      </label>
      <Textarea
        id="message-invalid"
        placeholder="Type your message here."
        aria-invalid
        defaultValue="Hmm"
      />
      <p className="text-sm text-destructive">
        Add a bit more detail.
      </p>
    </div>
  )
}
```

## Button

Place a small default button below the field and align it to the end.

```tsx
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"

export function Example() {
  return (
    <div className="grid gap-2">
      <Textarea placeholder="Type your message here." />
      <div className="flex justify-end">
        <Button type="button" size="sm">
          Send message
        </Button>
      </div>
    </div>
  )
}
```

## API Reference

### Textarea

| Prop | Type | Default |
| --- | --- | --- |
| placeholder | string | — |
| disabled | boolean | false |
| aria-invalid | boolean | — |
| rows | number | — |
| className | string | — |

Also accepts the other native `textarea` attributes (`id`, `name`, `value`, `defaultValue`, `onChange`, and so on).

```tsx
<Textarea placeholder="Write a short note…" />
```

## Source

```tsx
"use client";

import type { TextareaHTMLAttributes } from "react";
import { cn } from "@/lib/utils";

type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement>;

export function Textarea({ className, ...props }: TextareaProps) {
  return (
    <textarea
      className={cn(
        "flex min-h-16 w-full rounded-md border border-input bg-surface px-3 py-2 text-sm tracking-wide transition-colors duration-200 ease-out outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:opacity-40",
        "aria-invalid:border-destructive aria-invalid:bg-destructive/5",
        className,
      )}
      data-slot="textarea"
      {...props}
    />
  );
}
```
