# Textarea

Multi-line text entry, resizable vertically only.

- Group: Forms
- Import: `import { Textarea } from '@misoto22/folio'`
- Page: https://ui.misoto22.com/components/textarea/
- Related: input, field

## Anatomy

- **Control box** (required) — The <textarea>, on the same CONTROL_BASE as Input plus a min-h-24 floor. That floor is under rows, not over it: rows={2} still renders six rems tall.
- **Resize grip** — The browser’s own corner handle, constrained to resize-y — a reader can lengthen the box but cannot drag it past the measure or out of the page’s gutter.
- **Danger border** — The same pair isInvalid reads on Input: the invalid prop or an aria-invalid, including the one a Field sets when it has an error.

## Best practices

### Do

- Set rows to the answer you expect. It is the only thing that raises the resting height above the six-rem floor, and the size of the box is the clearest thing on the page about how long an answer should be.
- If there is a length limit, set maxLength AND say so in the hint: maxLength swallows the keystroke without explaining, and a paste one character too long is silently truncated.
- Keep Enter meaning newline. A textarea that submits on Enter has taken the one key the control exists to accept, and the reader loses the paragraph they were halfway through.

### Don’t

- There is no auto-grow. The height is whatever rows and min-h-24 settled on and it never follows the content, so a long answer is reviewed through a six-rem window unless the call site says otherwise.
- Do not put a required format in the Field’s hint and nothing else: hint and error share one slot, so the format vanishes the instant the field is wrong — which is the only moment anyone needed it.

## Textarea

Multi-line text entry. Resizes vertically only: horizontal resize lets a reader drag the control past the measure and past the page's own gutter.

### Props

- `invalid` — `boolean`. Paints the resting border with `--danger` and reflects `aria-invalid`.
- `ref` — `Ref<HTMLTextAreaElement>`.

Also accepts: `TextareaHTMLAttributes<HTMLTextAreaElement>`.

## Example — default

```tsx
import { Textarea } from '@misoto22/folio'

<Textarea className="max-w-md" rows={4} aria-label="Notes" placeholder="Tell us more…" />
```

## Example — rows and limits

```tsx
import { Field, Textarea } from '@misoto22/folio'

<Field
  label="Condition notes"
  hint={`${LIMIT - notes.length} characters left of ${LIMIT}.`}
  className="w-full max-w-sm"
>
  <Textarea
    rows={4}
    maxLength={LIMIT}
    value={notes}
    onChange={(event) => setNotes(event.target.value)}
  />
</Field>
```

## Example — invalid

```tsx
import { Field, Textarea } from '@misoto22/folio'

<Field
  label="Release notes"
  required
  error="Open with a line starting Added, Fixed or Changed — that first word groups the entry in the changelog."
  className="w-full max-w-sm"
>
  <Textarea rows={4} defaultValue="tidied up the release script a bit" />
</Field>
```
