---
title: Textarea
description: The multi-line control for long_text fields.
preview: textarea
---
# Textarea

A styled, vertically resizable `<textarea>`. `Field` renders it for `long_text`.

## Preview
<!-- preview: textarea -->

## Usage
```tsx
// { key: 'message', type: 'long_text', label: 'Message', help: 'A sentence or two is plenty.', maxLength: 500, required: true }
import { Form, Field, Textarea, Submit } from 'kibbleforms';

<Form schema={contact} client={kibble}>
  <Field name="message" />
  <Submit />
</Form>

// or inside a hand-built field:
<Textarea name="message" rows={6} />
```

## Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` | required | The field key. |
| `rows` | `number` | `4` | Initial rows; the control also has `min-h-28` and `resize-y`. |
| `className` | `string` | control classes | Merged onto the `<textarea>`. |
| …`<textarea>` attributes | | | Everything except `name`, `value`, `onChange`. `placeholder` and `autocomplete` default to the schema's values. |

Renders `<textarea data-kb="textarea">`. Long text is validated against `minLength`, `maxLength` (default 10 000) and `pattern` on submit; the server also counts links in text for spam scoring.

## Variants and states
Required, help, prefilled, error and disabled behave exactly like [Input](/docs/components/input.md#variants-and-states). Enter inserts a newline; it does not submit.

## Customization
- Same tokens as Input: `--kb-bg`, `--kb-fg`, `--kb-border`, `--kb-ring`, `--kb-error`, `--kb-muted-fg`, `--kb-radius`.
- `className="min-h-40 resize-none"` replaces the default height and resize behavior.
- CSS hook: `[data-kibble] [data-kb="textarea"]`.

## Accessibility
Same wiring as Input (`htmlFor`, `aria-describedby`, `aria-required`, `aria-invalid`).

## Related
[Input](/docs/components/input.md), [Field](/docs/components/field.md), [Schema: field types](/docs/schema.md)
