> ## Documentation Index
> Fetch the complete documentation index at: https://araf.badr.co.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Textarea

> A multi-line text input for longer user content such as descriptions, comments, and messages — supports auto-resize and character count.

## Overview

<div style={{display:"flex",gap:"24px",flexWrap:"wrap",padding:"28px 24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",alignItems:"flex-start"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px"}}>
    <label style={{fontSize:"13px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Description</label>
    <div style={{border:"1px solid #D0D5DD",borderRadius:"8px",padding:"9px 13px",fontSize:"14px",color:"#667085",fontFamily:"Inter,sans-serif",background:"#fff",width:"180px",height:"76px",display:"flex",alignItems:"flex-start"}}>Enter a description...</div>
    <span style={{fontSize:"11px",color:"#71717a",fontFamily:"Inter,sans-serif"}}>Default</span>
  </div>

  <div style={{display:"flex",flexDirection:"column",gap:"6px"}}>
    <label style={{fontSize:"13px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Description</label>
    <div style={{border:"1px solid #0479CE",borderRadius:"8px",padding:"9px 13px",fontSize:"14px",color:"#101828",fontFamily:"Inter,sans-serif",background:"#fff",width:"180px",height:"76px",display:"flex",alignItems:"flex-start",boxShadow:"0 0 0 4px #CDE4F5"}}>Focused text...</div>
    <span style={{fontSize:"11px",color:"#71717a",fontFamily:"Inter,sans-serif"}}>Focus</span>
  </div>

  <div style={{display:"flex",flexDirection:"column",gap:"6px"}}>
    <label style={{fontSize:"13px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Bio</label>
    <div style={{border:"1px solid #DC2626",borderRadius:"8px",padding:"9px 13px",fontSize:"14px",color:"#101828",fontFamily:"Inter,sans-serif",background:"#fff",width:"180px",height:"76px",display:"flex",alignItems:"flex-start"}}>Short</div>
    <span style={{fontSize:"11px",color:"#B42318",fontFamily:"Inter,sans-serif"}}>⚠ Must be at least 20 characters</span>
  </div>

  <div style={{display:"flex",flexDirection:"column",gap:"6px"}}>
    <label style={{fontSize:"13px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Notes</label>
    <div style={{border:"1px solid #E5E7EB",borderRadius:"8px",padding:"9px 13px",fontSize:"14px",color:"#9ca3af",fontFamily:"Inter,sans-serif",background:"#F9FAFB",width:"180px",height:"76px",display:"flex",alignItems:"flex-start",cursor:"not-allowed"}}>Disabled</div>
    <span style={{fontSize:"11px",color:"#71717a",fontFamily:"Inter,sans-serif"}}>Disabled</span>
  </div>
</div>

**Textarea** extends the Input pattern to multi-line content. It supports labels, placeholder text, helper text, validation states, and optional character count display. It can auto-grow with content when `autoResize` is enabled.

***

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @araf-ds/core
  ```

  ```bash yarn theme={null}
  yarn add @araf-ds/core
  ```

  ```bash pnpm theme={null}
  pnpm add @araf-ds/core
  ```
</CodeGroup>

***

## Usage

```tsx theme={null}
import { Textarea } from "@araf-ds/core"

export default function Example() {
  return (
    <Textarea
      label="Description"
      placeholder="Enter a description..."
    />
  )
}
```

***

## Variants

### Default

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px",maxWidth:"320px"}}>
    <label style={{fontSize:"14px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Description</label>
    <div style={{border:"1px solid #D0D5DD",borderRadius:"8px",padding:"10px 14px",fontSize:"14px",color:"#667085",fontFamily:"Inter,sans-serif",background:"#fff",height:"88px",display:"flex",alignItems:"flex-start"}}>Enter a description...</div>
  </div>
</div>

```tsx theme={null}
<Textarea label="Description" placeholder="Enter a description..." />
```

### With Helper Text

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px",maxWidth:"320px"}}>
    <label style={{fontSize:"14px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Bio</label>
    <div style={{border:"1px solid #D0D5DD",borderRadius:"8px",padding:"10px 14px",fontSize:"14px",color:"#667085",fontFamily:"Inter,sans-serif",background:"#fff",height:"88px",display:"flex",alignItems:"flex-start"}}>Tell us about yourself...</div>
    <span style={{fontSize:"13px",color:"#667085",fontFamily:"Inter,sans-serif"}}>Maximum 240 characters</span>
  </div>
</div>

```tsx theme={null}
<Textarea
  label="Bio"
  placeholder="Tell us about yourself..."
  helperText="Maximum 240 characters"
/>
```

### Required Field

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px",maxWidth:"320px"}}>
    <label style={{fontSize:"14px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Message <span style={{color:"#DC2626"}}>\*</span></label>
    <div style={{border:"1px solid #D0D5DD",borderRadius:"8px",padding:"10px 14px",fontSize:"14px",color:"#667085",fontFamily:"Inter,sans-serif",background:"#fff",height:"88px",display:"flex",alignItems:"flex-start"}}>Write your message here...</div>
  </div>
</div>

```tsx theme={null}
<Textarea label="Message" required placeholder="Write your message here..." />
```

### Error State

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px",maxWidth:"320px"}}>
    <label style={{fontSize:"14px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Bio</label>
    <div style={{border:"1px solid #DC2626",borderRadius:"8px",padding:"10px 14px",fontSize:"14px",color:"#101828",fontFamily:"Inter,sans-serif",background:"#fff",height:"88px",display:"flex",alignItems:"flex-start"}}>Short bio.</div>
    <span style={{fontSize:"13px",color:"#B42318",fontFamily:"Inter,sans-serif"}}>Bio must be at least 20 characters</span>
  </div>
</div>

```tsx theme={null}
<Textarea
  label="Bio"
  state="error"
  helperText="Bio must be at least 20 characters"
/>
```

### With Character Count

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"6px",maxWidth:"320px"}}>
    <label style={{fontSize:"14px",fontWeight:500,color:"#344054",fontFamily:"Inter,sans-serif"}}>Tweet</label>
    <div style={{border:"1px solid #D0D5DD",borderRadius:"8px",padding:"10px 14px",fontSize:"14px",color:"#101828",fontFamily:"Inter,sans-serif",background:"#fff",height:"88px",display:"flex",alignItems:"flex-start"}}>What's happening today?</div>

    <div style={{display:"flex",justifyContent:"space-between"}}>
      <span style={{fontSize:"13px",color:"#667085",fontFamily:"Inter,sans-serif"}}>Keep it short and sweet</span>
      <span style={{fontSize:"13px",color:"#667085",fontFamily:"Inter,sans-serif"}}>22 / 280</span>
    </div>
  </div>
</div>

```tsx theme={null}
<Textarea
  label="Tweet"
  maxLength={280}
  showCount
  placeholder="What's happening?"
/>
```

***

## States

| State    | Border    | Ring          | Helper text color |
| -------- | --------- | ------------- | ----------------- |
| Default  | `#D0D5DD` | —             | `#667085`         |
| Focus    | `#0479CE` | `#CDE4F5` 4px | —                 |
| Error    | `#DC2626` | —             | `#B42318`         |
| Success  | `#039855` | —             | `#027A48`         |
| Disabled | `#E5E7EB` | —             | —                 |

```tsx theme={null}
<Textarea state="default" />
<Textarea state="error" helperText="This field is required" />
<Textarea state="success" helperText="Looks good!" />
<Textarea disabled />
```

<Note>
  Avoid hiding a textarea when it is unavailable. Use `disabled` so users can still see the field exists.
</Note>

***

## API Reference

<ParamField path="label" type="string">
  Label displayed above the textarea.
</ParamField>

<ParamField path="placeholder" type="string">
  Placeholder text shown when the field is empty.
</ParamField>

<ParamField path="helperText" type="string">
  Helper or error message displayed below the textarea.
</ParamField>

<ParamField path="state" type="string" default="default">
  Validation state. Values: `default` · `error` · `success` · `disabled`
</ParamField>

<ParamField path="rows" type="number" default="3">
  Initial number of visible rows.
</ParamField>

<ParamField path="autoResize" type="boolean" default="false">
  Automatically grows the height to fit content.
</ParamField>

<ParamField path="maxLength" type="number">
  Maximum character limit.
</ParamField>

<ParamField path="showCount" type="boolean" default="false">
  Displays a live character count below the textarea.
</ParamField>

<ParamField path="required" type="boolean" default="false">
  Marks the label with a required asterisk indicator.
</ParamField>

<ParamField path="disabled" type="boolean" default="false">
  Disables the textarea and applies the disabled visual style.
</ParamField>

<ParamField path="value" type="string">
  Controlled value of the textarea.
</ParamField>

<ParamField path="onChange" type="(e: ChangeEvent) => void">
  Change event handler.
</ParamField>

<ParamField path="className" type="string">
  Additional Tailwind classes for custom overrides.
</ParamField>

***

## Accessibility

* Textarea uses a native `<textarea>` element with semantic `<label>` association via `id`/`htmlFor`
* Error messages are linked via `aria-describedby` so screen readers announce them
* Required fields use the `required` HTML attribute in addition to the visual asterisk
* `disabled` uses the native `disabled` attribute — the element is excluded from tab order
* Character count updates are announced via `aria-live="polite"` when `showCount` is enabled
* Focus ring (`0 0 0 4px #CDE4F5`) meets WCAG 2.1 AA contrast requirements

***

## Do's & Don'ts

<CardGroup cols={2}>
  <Card title="Do" icon="check" iconType="solid" color="#16A34A">
    * Use Textarea for open-ended input (descriptions, comments, notes)
    * Always provide a visible label — never rely on placeholder alone
    * Use `helperText` to set character expectations before the user types
    * Use `showCount` + `maxLength` when length is enforced
  </Card>

  <Card title="Don't" icon="xmark" iconType="solid" color="#DC2626">
    * Don't use Textarea for short single-line inputs — use Input instead
    * Don't show error state until after the user has interacted with the field
    * Don't set a fixed height when content length is unpredictable — use `autoResize`
    * Don't use placeholder text as a substitute for a label
  </Card>
</CardGroup>
