AI Component
Textarea
Multi-line text input with optional auto-expand behavior — the foundation of chat input bars.
Preview
Source
Full component implementation using the design system tokens.
tsx
"use client";
import { useRef, useEffect } from "react";
export function DSTextarea({
label,
helperText,
error,
autoExpand = false,
...props
}: {
label?: string;
helperText?: string;
error?: string;
autoExpand?: boolean;
} & React.TextareaHTMLAttributes<HTMLTextAreaElement>) {
const ref = useRef<HTMLTextAreaElement>(null);
const hasError = !!error;
useEffect(() => {
if (autoExpand && ref.current) {
const el = ref.current;
const handleInput = () => {
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
};
el.addEventListener("input", handleInput);
return () => el.removeEventListener("input", handleInput);
}
}, [autoExpand]);
return (
<div className="flex flex-col gap-1.5 w-full">
{label && (
<label className="text-sm font-medium text-foreground">{label}</label>
)}
<textarea
ref={ref}
className={`w-full px-3 py-2 text-sm text-foreground bg-surface border rounded-lg outline-none transition-colors placeholder:text-tertiary resize-none ${
hasError
? "border-red-500 focus:border-red-500"
: "border-overlay/10 focus:border-accent"
} ${autoExpand ? "overflow-hidden" : ""}`}
rows={props.rows ?? 3}
{...props}
/>
{(helperText || error) && (
<p className={`text-xs ${hasError ? "text-red-500" : "text-tertiary"}`}>
{error || helperText}
</p>
)}
</div>
);
}Props
All available props with types and defaults.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Label text above the textarea |
helperText | string | — | Helper text below the textarea |
error | string | — | Error message |
autoExpand | boolean | false | Auto-grows height to fit content |
rows | number | 3 | Initial visible rows |
placeholder | string | — | Placeholder text |
Variants
Default
Standard multi-line input with label.
tsx
<DSTextarea
label="System prompt"
placeholder="You are a helpful assistant..."
rows={3}
/>Auto-expand
Grows with content — ideal for chat input bars.
tsx
<DSTextarea
placeholder="Type a message..."
autoExpand
rows={1}
/>Error
Validation error state.
Template must include {input} variable
tsx
<DSTextarea
label="Prompt template"
error="Template must include {input} variable"
/>Prompt Guide
Prompt Guide — Textarea
Use for
- Chat input bars (with autoExpand)
- System prompt editors
- Prompt template editors
- Feedback and comment inputs
Don't use for
- Single-line inputs — use Input component
- Code editors — use a dedicated code editor component
- Rich text — textarea is plain text only
AI Context
The Textarea with autoExpand is the chat input bar. Start at 1 row, grow as the user types, submit on Enter (Shift+Enter for newline). For system prompt editors, use a fixed height (rows=6+) with scroll. The auto-expand behavior uses a ref to measure scrollHeight — no layout thrashing.