Textarea
A multi-line field that grows with its content between a minimum and a cap.
import { Textarea } from "@arcadia/ui"lg Textarea in its own frame. Type a few lines: it grows, then scrolls past eight.It grows from minRows (3 by default) to a cap, maxRows or maxHeight (which wins), and scrolls past it: CSS field-sizing: content, with a measured fallback. sm and md are UI text; lg is conversation text, as in the composer. Focus shows through the border, never a ring.
Examples
rootStyle takes where the textarea sits (margins, self-alignment, flex and grid placement, size bounds) and the knobs below, each a token of its kind. A colour, a raw length or any other property is a type error: a look that comes up twice becomes a variant.
--textarea-py- TokenRef<Space>Default var(--space-1-5)
- Block padding (the min height counts it).
--textarea-px- TokenRef<Space>Default var(--space-2-5)
- Inline padding.
--textarea-font- TokenRef<FontSize>Default var(--font-size-base)
- Text size.
--textarea-lh- TokenRef<LineHeight>Default var(--line-height-base)
- Line height (one row of
minRowsandmaxRows). --textarea-tracking- TokenRef<Tracking>Default var(--tracking-base)
- Letter spacing.
--textarea-radius- TokenRef<Radius>Default var(--radius-row)
- Corner radius.
--textarea-bg- PaintDefault transparent
- Fill.
--textarea-fg- PaintDefault var(--text-1)
- Text colour.
--textarea-fg-disabled- PaintDefault var(--text-4)
- Text colour when disabled.
--textarea-placeholder- PaintDefault var(--text-3)
- Placeholder colour.
--textarea-border- PaintDefault var(--stroke-2)
- Frame colour (1px) at rest.
--textarea-border-hover- PaintDefault var(--stroke-1)
- Frame colour under the pointer.
--textarea-border-focus- PaintDefault var(--ring)
- Frame colour while focused.
--textarea-border-disabled- PaintDefault var(--stroke-4)
- Frame colour when disabled.
--textarea-halo- PaintDefault var(--fill-3)
- The halo (
--halo-width) around a focused frame.
--textarea-lh and --textarea-py also set a row's height for minRows and maxRows. Like Input, each state reads its own knob, and invalid always shows the danger frame.
A native <textarea>. Inside Field, the label, the hint and the error are wired by id (for, aria-describedby) and invalid or an error sets aria-invalid. Without a Field, name it with a <label htmlFor> or aria-label; a placeholder is not a label.
Pass required and say so in the label. Errors appear as they are set, so move focus back to the field on a bad submit to have the message read. In a native textarea Enter is a new line; a composer that sends on Enter should say so nearby and keep Shift+Enter for new lines.
- Enter
- A new line (a composer may send instead)
- ⇧⏎
- A new line in a composer
Textarea
size- "sm" | "md" | "lg"Default "md"
- sm and md are UI text (13/18); lg is conversation text (15/24), as in the composer.
variant- "default" | "ghost"Default "default"
ghostdrops fill and border (a composer inside its own frame).invalid- boolean
minRows- numberDefault 3
- Minimum height in lines. The field grows with its content from there.
maxRows- number
- Growth cap in lines; past it the field scrolls.
maxHeightwins when both are set. maxHeight- number | string
- Growth cap as a CSS length (
"min(420px, 50vh)") or px. onValueChange- (value: string) => void
- Called with the new text on every change (alongside
onChange). render- RenderProp
- Replaces the
<textarea>. rootStyle- TextareaStyle
- Typed StyleX override: where the textarea sits and its
--textarea-*knobs. className- string
- A product's hook class for its own layout rules. Being retired: new code places a textarea with
rootStyle; the call sites left are counted by ui.lint (kit-classname) and only go down. placeholder- string
- Placeholder at text-4.
disabled- boolean
- Dims the field.
Rest props go to <textarea> props.