

<Preview name="BasicTextareaExample" />

## Overview [#overview]

The **Textarea** component provides a multi-line text input field with automatic height adjustment, size variants, and URL state management support. It's perfect for longer text entries like comments, descriptions, or messages.

## Usage [#usage]

```tsx
import { Textarea } from "@tilt-legal/cubitt-components/primitives";
```

```tsx
<Textarea placeholder="Enter your message..." />
```

***

## Examples [#examples]

### Basic [#basic]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="BasicTextareaExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Textarea } from "@tilt-legal/cubitt-components/primitives";

    export default function Example() {
      return (
        <div className="w-full max-w-sm">
          <Textarea placeholder="Enter your message..." />
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### States [#states]

Textarea supports disabled, read-only, and invalid states.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="TextareaStatesExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Textarea, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Example() {
      return (
        <div className="flex w-full max-w-sm flex-col gap-4">
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Disabled</Label>
            <Textarea disabled placeholder="Disabled textarea" />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Read-only</Label>
            <Textarea
              defaultValue="This textarea is read-only."
              readOnly
            />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Invalid</Label>
            <Textarea aria-invalid placeholder="Invalid textarea" />
          </div>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### Sizes [#sizes]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="TextareaSizesExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Textarea, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Example() {
      return (
        <div className="flex w-full max-w-sm flex-col gap-6">
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Small</Label>
            <Textarea size="sm" placeholder="Small size" />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Default</Label>
            <Textarea placeholder="Default size" />
          </div>
          <div className="flex flex-col gap-2">
            <Label className="text-sm">Large</Label>
            <Textarea size="lg" placeholder="Large size" />
          </div>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

### Auto-resize [#auto-resize]

Control the height behavior with `minRows` and `maxRows` props.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="TextareaRowsExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import { Textarea, Label } from "@tilt-legal/cubitt-components/primitives";

    export default function Example() {
      return (
        <div className="flex w-full max-w-sm flex-col gap-6">
          <div className="flex flex-col gap-2">
            <Label>3 rows (minRows)</Label>
            <Textarea minRows={3} placeholder="Minimum 3 rows..." />
          </div>
          <div className="flex flex-col gap-2">
            <Label>Auto-expanding (2-6 rows)</Label>
            <Textarea
              minRows={2}
              maxRows={6}
              placeholder="Type multiple lines to see auto-expansion..."
            />
          </div>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

***

## API Reference [#api-reference]

### Textarea [#textarea]

The textarea component with auto-resize and URL state management.

| Prop           | Type                                                                                        | Default     | Description                                                  |
| -------------- | ------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `value`        | `string`                                                                                    | —           | The controlled value of the textarea.                        |
| `defaultValue` | `string`                                                                                    | —           | The default value when uncontrolled.                         |
| `onChange`     | `(event: ChangeEvent<HTMLTextAreaElement>) => void`                                         | —           | Callback fired when the value changes.                       |
| `placeholder`  | `string`                                                                                    | —           | Placeholder text when empty.                                 |
| `size`         | `"sm"` \| `"md"` \| `"lg"`                                                                  | `"md"`      | The size variant of the textarea.                            |
| `variant`      | `"default"` \| `"inline"`                                                                   | `"default"` | The visual variant of the textarea.                          |
| `minRows`      | `number`                                                                                    | `2`         | Minimum number of visible text lines.                        |
| `maxRows`      | `number`                                                                                    | —           | Maximum number of visible text lines.                        |
| `resize`       | `true` \| `"none"` \| `"both"` \| `"horizontal"` \| `"vertical"` \| `"block"` \| `"inline"` | `"none"`    | Resize behavior of the textarea.                             |
| `disabled`     | `boolean`                                                                                   | `false`     | Whether the textarea is disabled.                            |
| `readOnly`     | `boolean`                                                                                   | `false`     | Whether the textarea is read-only.                           |
| `aria-invalid` | `boolean`                                                                                   | —           | Indicates validation state, applies error styling when true. |
| `spellCheck`   | `boolean`                                                                                   | `false`     | Enable spell checking.                                       |
| `className`    | `string`                                                                                    | —           | Additional CSS classes.                                      |

#### URL State Props [#url-state-props]

When provided with a `paramName`, the textarea will sync its value with URL parameters via TanStack Router search params.

| Prop                  | Type                      | Default | Description                                                                  |
| --------------------- | ------------------------- | ------- | ---------------------------------------------------------------------------- |
| `paramName`           | `string`                  | —       | URL parameter name for syncing state with URL. Enables URL state management. |
| `paramValue`          | `string`                  | —       | Controlled value for the URL parameter.                                      |
| `onUrlValueChange`    | `(value: string) => void` | —       | Callback when URL parameter value changes.                                   |
| `paramClearOnDefault` | `boolean`                 | `true`  | Remove URL param when value equals default.                                  |
| `paramDebounce`       | `number`                  | —       | Debounce URL updates in milliseconds (recommended for textareas).            |
| `paramThrottle`       | `number`                  | —       | Throttle URL updates in milliseconds.                                        |
