Textarea
Multi-line input. Same fill, border, inner shadow, hover overlay, and focus ring as Input.
Basic
<Textarea placeholder="Type your message here…" />With an action bar
// Pattern: Textarea + an action bar below. The whole wrapper — textarea and
// action bar — shares one border + hover + focus + invalid state. The inner
// Textarea strips its own chrome so only the wrapper renders them.
//
// LEFT: context (model picker, tool toggles, scope)
// RIGHT: actions (upload, mic, and the primary Send button)
<div
className={cn(
"rounded-md border border-input bg-input-fill shadow-input-inner",
"transition-[box-shadow,border-color,background-image] duration-150 ease-out",
"hover:[background-image:linear-gradient(rgba(0,0,0,0.03),rgba(0,0,0,0.03))]",
"dark:hover:[background-image:linear-gradient(rgba(255,255,255,0.03),rgba(255,255,255,0.03))]",
"focus-within:shadow-ring-primary-input focus-within:border-focus",
"has-[[aria-invalid=true]]:border-[var(--border-destructive-50)]",
"has-[[aria-invalid=true]]:focus-within:shadow-ring-destructive-input"
)}
>
<Textarea
placeholder="Type your message here…"
className="!border-0 !bg-transparent !shadow-none resize-none
hover:!bg-none focus-visible:!shadow-none focus-visible:!border-transparent"
/>
{/* All controls share h-8 so the bar reads as a single row. */}
<div className="flex items-center justify-between gap-2 px-2 pb-2 ">
<div className="flex items-center gap-1">
<Button variant="outline" className="text-sm" iconTrailing={<Chevron />}>Claude Opus 4.6</Button>
<Button variant="ghost" className="text-sm" iconLeading={<Plus />}>Add</Button>
</div>
<div className="flex items-center gap-1">
<IconButton variant="ghost" aria-label="Attach file"><Paperclip /></IconButton>
<IconButton variant="ghost" aria-label="Record"><Mic /></IconButton>
<IconButton variant="primary" aria-label="Send"><ArrowUp /></IconButton>
</div>
</div>
</div>Rule: the action bar is two button groups — left for context (model picker, mode, scope) and right for actions (upload, mic, then the primary Send button). The Send button is the only Primary in the group and sits at the far right.
States
<>
<Textarea placeholder="Default" />
<Textarea disabled defaultValue="cannot edit" />
<Textarea readOnly defaultValue="read only" />
<Textarea invalid defaultValue="too short" />
</>Props
| Prop | Type | Default |
|---|---|---|
| invalid | boolean | false |
| disabled | boolean | false |
| readOnly | boolean | false |
| …rest | TextareaHTMLAttributes | — |
Source
packages/react/src/components/textarea.tsx · Figma node 2819:31165