# Textarea

A multi-line text field for free-form input such as notes, comments and justifications.

```tsx
import { Field, FieldLabel } from "@zenoxai/ui/components/field"
import { Textarea } from "@zenoxai/ui/components/textarea"

function TextareaDemo() {
  return (
    <Field className="max-w-sm">
      <FieldLabel htmlFor="incident-notes">Incident notes</FieldLabel>
      <Textarea
        id="incident-notes"
        placeholder="What did you observe, and when?"
      />
    </Field>
  )
}
```

## Usage

```tsx
import { Field, FieldLabel } from "@zenoxai/ui/components/field"
import { Textarea } from "@zenoxai/ui/components/textarea"

export function IncidentNotes() {
  return (
    <Field>
      <FieldLabel htmlFor="incident-notes">Incident notes</FieldLabel>
      <Textarea id="incident-notes" placeholder="What did you observe?" />
    </Field>
  )
}
```

Use a textarea when the answer can run past one line: incident notes, a suppression reason, a
comment. For a single line (a name, a domain, a search query), use an
[Input](/components/input). To attach buttons or addons inside the field's border, use
`InputGroupTextarea` from [Input Group](/components/input-group).

`Textarea` is a styled native `<textarea>` and accepts all its attributes. It grows with its
content from a 64px minimum (CSS `field-sizing: content`, in the browsers that support it). Set
a `max-h-*` class to cap the height; past it, the field scrolls. Where the field grows on its
own, the native resize grip is hidden; in browsers without `field-sizing` it stays, as the only
way to make the field taller.

## Examples

### With a description

Add a `FieldDescription` under the field for guidance the user needs before typing, and point
`aria-describedby` at it.

```tsx
import { Field, FieldDescription, FieldLabel } from "@zenoxai/ui/components/field"
import { Textarea } from "@zenoxai/ui/components/textarea"

function TextareaWithDescription() {
  return (
    <Field className="max-w-sm">
      <FieldLabel htmlFor="suppression-reason">Suppression reason</FieldLabel>
      <Textarea
        id="suppression-reason"
        aria-describedby="suppression-reason-description"
        placeholder="Why should this alert stop firing?"
      />
      <FieldDescription id="suppression-reason-description">
        Shown in the audit log next to your name.
      </FieldDescription>
    </Field>
  )
}
```

### Invalid

Set `aria-invalid` to draw the error border, and show the message in a `FieldError` linked
with `aria-describedby`. Say what to fix, not only what is wrong.

```tsx
import { Field, FieldError, FieldLabel } from "@zenoxai/ui/components/field"
import { Textarea } from "@zenoxai/ui/components/textarea"

function TextareaInvalid() {
  return (
    <Field className="max-w-sm">
      <FieldLabel htmlFor="takedown-justification">
        Takedown justification
      </FieldLabel>
      <Textarea
        id="takedown-justification"
        aria-invalid
        aria-describedby="takedown-justification-error"
        defaultValue="Phishing"
      />
      <FieldError id="takedown-justification-error">
        Describe the evidence in at least 20 characters.
      </FieldError>
    </Field>
  )
}
```

### Disabled

A disabled textarea is not focusable and is not submitted with the form. For text the user
must still be able to select and copy, use `readOnly` instead.

```tsx
import { Field, FieldLabel } from "@zenoxai/ui/components/field"
import { Textarea } from "@zenoxai/ui/components/textarea"

function TextareaDisabled() {
  return (
    <Field className="max-w-sm">
      <FieldLabel htmlFor="closing-summary">Closing summary</FieldLabel>
      <Textarea
        id="closing-summary"
        disabled
        defaultValue="False positive: the domain belongs to a partner and was added to the allow list."
      />
    </Field>
  )
}
```

### With a button

A comment box: the textarea and its submit button in a form. Use `aria-label` when the layout
has no room for a visible label and the purpose is clear from context.

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

function TextareaWithButton() {
  return (
    <form
      className="flex w-full max-w-sm flex-col items-end gap-2"
      onSubmit={(event) => event.preventDefault()}
    >
      <Textarea aria-label="Comment" placeholder="Add a comment for the team" />
      <Button type="submit" size="sm">
        Add comment
      </Button>
    </form>
  )
}
```

## Accessibility

- Every textarea needs a label: a `FieldLabel` (or `Label`) with `htmlFor`, or `aria-label`.
  A placeholder is not a label; it disappears as soon as the user types.
- `Field` does not connect descriptions and errors to the control. Give them an `id` and list
  it in the textarea's `aria-describedby`.
- The font is 16px below the `md` breakpoint so iOS Safari does not zoom in on focus.

## API reference

`import { ... } from "@zenoxai/ui/components/textarea"`

### Textarea

No props of its own.

