Textarea
Multi-line text input with intent variants, sizes, label positions, character counter, auto-resize, and LTR/RTL support.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { Textarea } from "@tessinaui/ui";{/* Basic */}
<Textarea label="Description" placeholder="Write something…" />
{/* With character counter */}
<Textarea
label="Bio"
maxLength={160}
showCharacterCounter
placeholder="Tell us about yourself…"
/>
{/* Auto-resize, capped at 6 rows */}
<Textarea
label="Notes"
autoResize
minRows={2}
maxRows={6}
placeholder="Start typing — grows automatically…"
/>
{/* Validation state */}
<Textarea
label="Feedback"
intent="error"
supportingText="This field is required"
required
/>Examples
Default
A basic textarea with a label and placeholder.
Sizes
Five sizes from xs to xl scale padding and text.
Intents
Validation states — error, warning, success, and info — recolor the border, focus ring, and supporting text.
Character counter
Pair showCharacterCounter with maxLength to show a live current / max count.
Auto-resize
With autoResize, the height grows as you type — capped here at six rows before scrolling.
Label positions
Place the label outside-top, inside the container, or outside-left.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Padding and text scale |
intent | "none" | "error" | "warning" | "success" | "info" | "none" | Border and focus-ring colour |
rounded | "none" | "sm" | "md" | "lg" | "full" | "full" | Border radius |
resize | "none" | "vertical" | "horizontal" | "both" | "vertical" | CSS resize handle; ignored when autoResize is true |
labelPosition | "outside-top" | "inside" | "outside-left" | "outside-top" | Where the label is rendered relative to the textarea |
label | string | — | Label text |
required | boolean | — | Appends * to label and sets aria-required |
infoText | string | — | Inline hint rendered beside the label |
supportingText | string | — | Helper / validation message below the textarea |
showCharacterCounter | boolean | false | Shows current / max counter (requires maxLength) |
minRows | number | 3 | Minimum visible rows (maps to HTML rows attribute) |
maxRows | number | — | Maximum rows before scrolling (used with autoResize) |
autoResize | boolean | false | Grows height with content; disables the resize handle |
value | string | — | Controlled value |
defaultValue | string | — | Uncontrolled initial value |
onChange | ChangeEventHandler | — | Called on every keystroke |
disabled | boolean | — | Disables all interaction |
readOnly | boolean | — | Renders with muted background; not editable |
maxLength | number | — | Native character limit; used with showCharacterCounter |
dir | "ltr" | "rtl" | "ltr" | Text direction |
wrapperClassName | string | — | Class on the outermost wrapper div |
containerClassName | string | — | Class on the inner bordered container div |
All standard <textarea> HTML attributes (placeholder, name, rows, cols, autoFocus, spellCheck, etc.) are forwarded to the underlying element.
Notes
- Auto-resize: Sets
height: autoon each change to measurescrollHeight, then applies the result. Works in both controlled and uncontrolled modes. - Inside label: The label renders as small text at the top of the container; the textarea has no extra top padding since the label sits above the text flow naturally.
- Character counter turns red when
currentLength >= maxLength. - Read-only applies a subtle
bg-secondary/30background to signal non-editable content.
Tabs
Organise content into switchable panels with animated indicators, four variants, five sizes, five intents, icon/badge/closable support, vertical orientation, and full RTL/keyboard navigation.
Time Picker
Three time-picker variants — a drum-roll wheel, a typed HH:MM input field, and a button-triggered popover. Supports 12h/24h formats, seconds, configurable minute steps, all intent colours, RTL, and keyboard navigation.