A multi-line input as one 380 by 64 box, where the edge and the text colour carry all five states and nothing else moves.
One component, five states
Textarea - State: Default · Filled · Focus · Disabled · Invalid - 380 × 64, radius.lg, 14/20 type, 12 of horizontal padding against 8 of vertical
Using the Textarea
Why is there no size axis?
Because a textarea has no sizes in the source - it is one box with min-h-16 and a width set by whatever it sits in. Height comes from the content rather than from a variant, so there is nothing to publish. If you need a taller box, resize the instance; you are changing a layout decision, not picking a variant.
What does Filled actually change?
The type colour, and only that. A placeholder is base.muted-foreground and typed text is base.foreground, which is the one thing telling a reader whether the field has been answered. The box, the edge and the padding are identical to Default, so the two variants exist purely to record that difference.
How does Focus differ from the rest of the kit?
The 1px edge itself moves to base.ring, and a 3px ring at half opacity appears outside it. Invalid does the same in base.destructive with its ring at 20%. Both come straight from the source - ring-ring/50 and ring-destructive/20. Input, its closest sibling, draws focus as a ring at full alpha over an unchanged edge, so the two are worth comparing before you build a form out of both.
What does Disabled change?
The fill goes to base.muted and the whole variant drops to 50%, while the base.input edge stays where it is. That last part matters in a form: Input is disabled the same way, so a stack of controls all reads as one kind of off rather than two. The source only dims, and adding the muted fill on top is the kit's own convention across every field it draws.
What is the 64 for?
It is a floor, not a height. The source writes min-h-16 together with field-sizing-content, so the box starts at 64 and grows as the writing does. It also sets no resize rule, which leaves the browser default in place: a grip in the corner the reader can drag. Penpot has neither typing nor dragging, so the file draws the empty state. Plan the floor from the component and the full box from the content you actually expect.
How tall should I make it?
Let the question decide. Two lines is right for a note or a reason; six is right when you know the answer is long, like a bug report; growing with the content is right almost everywhere else and is what the source does. Height is the only signal a reader gets about how much you expect them to write, and a 200-tall box under a yes-or-no question reliably gets nothing. Whatever you pick, the grip lets the reader overrule you, and that is worth leaving alone - turn resize off only when a taller box would break the layout around it.
Where do the label and the counter go?
Label above, description and counter below. The description under the box rather than under the label, because by the time someone reads it they are already looking at the box. A counter earns its place only when the limit is real and close - show it quietly, and let it turn base.destructive near the end rather than counting down from the start.
Does it work right to left?
Yes, with dir on an ancestor and no other change. The placeholder, the caret and every line move to the right edge on their own, and there is nothing anchored to a side - no icon, no addon, no clear button - so the component needs nothing new. The source's own docs carry an Arabic example. The one thing direction does not fix is the resize handle, which browsers park at the bottom-right either way; if that matters, turn resizing off and let the box grow instead.
Is there a usage frame?
No - this page in the file is the Components board and nothing else. The worked examples on this page are the kit's answer to that: a Field pairing, a submit button, a counter, a review box, and the three ways of choosing a height.