<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# TextArea

A labeled multi-line text field on the Field contract, a native `<textarea>`: pass `label`, and `error` from your server action or client check. `autoGrow` makes it grow with the text from `rows` lines up to `maxRows`.

```tsx
import { TextArea } from "@/components/ouro/text-field/text-area";
```

## Example

```tsx
<TextArea label="Notes" name="notes" description="Only you see these." />
<TextArea label="Message" name="message" autoGrow rows={2} maxRows={8} required error={errors?.message} />
// A chat composer: the box is the app's, and the textarea inside it has no frame.
<form className="flex items-end gap-2 rounded-xl border border-border p-2 focus-within:border-ring">
  <TextArea label="Message" hideLabel name="message" placeholder="Ask anything" variant="plain" autoGrow rows={1} maxRows={8} className="flex-1" />
  <Button type="submit">Send</Button>
</form>
```

## Usage

`variant="plain"` draws no frame, for a textarea inside a box your app draws, and `size="lg"` sets 20px text.

## Use instead when

- Use `TextField` instead for one line, and `Field` with `FieldControl` for a control that is not text.

## Props

Type: `TextAreaProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `autoGrow` | `boolean` |  | Grows with the content, from `rows` lines up to `maxRows`, instead of scrolling. Use it for messages and notes, so people see what they wrote. |
| `className` | `string` |  | Layout only: margins, width, grid placement (`mt-4`, `col-span-2`). Appearance classes warn in development; style fields in your theme. |
| `defaultValue` | `string` |  | The starting text, for an uncontrolled field. |
| `description` | `ReactNode` |  | Supporting text under the label, read after the label through `aria-describedby`. |
| `disabled` | `boolean` |  | Disables the field and fades it. |
| `error` | `ReadonlyErrorMessages` |  | What is wrong, from your server action or client check. The message (or several, as a list) shows under the field, which gets `aria-invalid`. A message is text or a React node (one with a link); an empty string or array means valid. |
| `hideLabel` | `boolean` |  | Hides the label visually; screen readers still read it as the field's name. |
| `label` (required) | `string` |  | What the field is for, shown above it and read as its name. Required: every control needs a name. To hide it visually, keep it and add `hideLabel`. A placeholder is not a label. |
| `maxRows` | `number` |  | With `autoGrow`, the most lines it grows to before it scrolls. Unset, it keeps growing. |
| `name` | `string` |  | The form field name the text submits under. |
| `onValueChange` | `FieldControlProps["onValueChange"]` |  | Called with the new text on every change. |
| `placeholder` | `string` |  | An example of what to write, shown while the field is empty. It is not a label; pass `label`, which stays visible. |
| `ref` | `Ref<HTMLTextAreaElement>` |  | The textarea element. |
| `required` | `boolean` |  | The field must be filled: it gets `required` and `aria-required`, and the label a marker. |
| `rows` | `number` | `3` | Lines of text it shows; with `autoGrow`, the fewest it shows. |
| `size` | `"md" \| "lg"` | `"md"` | Text size. `md` is 16px on phones and steps down to 14px from the `sm` breakpoint (640px). `lg` is 20px at every width. The font family is inherited, so set a display font on a parent. |
| `value` | `string` |  | The current text, for a controlled field; pair it with `onValueChange` or `onChange`. |
| `variant` | `"outline" \| "plain"` | `"outline"` | The frame. `outline` draws the bordered box. `plain` draws no border, background or padding, for a textarea inside a frame your app draws (a chat composer with its send button in the same box); it keeps the focus outline, and the error message still shows under it, but with no border to turn red, color your own frame for an invalid field. Any other string is a type error whose message names the fix. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` and `TextareaHTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `autoResize`: Not a prop. Ouro UI uses `autoGrow`: `<TextArea autoGrow>`.
- `autosize`: Not a prop. Ouro UI uses `autoGrow`: `<TextArea autoGrow>`.
- `errorMessage`: Not a prop. Ouro UI uses `error`: `<TextArea error="Required.">`.
- `helperText`: Not a prop. Ouro UI uses `description`: `<TextArea description="Only you see these.">`.
- `invalid`: Not a prop. `error` marks the field invalid: `<TextArea error="What is wrong">`.
- `isDisabled`: Not a prop. Ouro UI uses `disabled`: `<TextArea disabled>`.
- `isInvalid`: Not a prop. `error` marks the field invalid: `<TextArea error="What is wrong">`.
- `isRequired`: Not a prop. Ouro UI uses `required`: `<TextArea required>`.
- `minRows`: Not a prop. `rows` is the minimum: `<TextArea autoGrow rows={2} maxRows={8}>`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: TextArea merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `ErrorMessage`

One error message: text, or a React element for a message that carries a link or other markup.

```ts
type ErrorMessage = string | ReactElement;
```

### `FieldControlProps`

Props for `FieldControl`. `className` is for layout only.

```ts
type FieldControlProps = Omit<BaseField.Control.Props, "className"> & {
  className?: string | undefined;
  ref?: Ref<HTMLInputElement> | undefined;
};
```

### `ReadonlyErrorMessages`

A read-only message view accepted by fields and Form; mutable input arrays remain valid.

```ts
type ReadonlyErrorMessages = ErrorMessage | readonly ErrorMessage[];
```

[^layout-classes]: test:registry/ouro/components/ouro/text-field/text-area.test.tsx::TextArea > lets app layout classes win on the root verify:testExists(registry/ouro/components/ouro/text-field/text-area.test.tsx::TextArea > lets app layout classes win on the root)
