Textarea
A labeled multiline input, wired the same way as Input — label, hint, and error.
Last updated
Markdown is supported.
Show codeHide code
<Textarea label="Message" hint="Markdown is supported." placeholder="Write something…" />Add
npx @ava-ui/apogee add textarea
Pulls in Field (label / hint / error scaffold).
Usage
---
import Textarea from '@/components/apogee/Textarea/Textarea.astro'
<JsNote fallback="The box keeps its rows height and the resize handle.">
`resize="auto"` grows the box to its content on input in browsers without `field-sizing: content` (Chromium has it natively).
</JsNote>
---
<Textarea label="Message" />
Anatomy
Textarea renders a Field (label + hint/error scaffold) around a native
<textarea>:
- Field — label (with required asterisk), the control, then hint or error.
- Textarea — the native
<textarea>, sized bysizeandrows.
API
@composable — exposed to Content Editors in AVA. Any other native <textarea>
attribute (e.g. placeholder, disabled, maxlength, name) passes through.
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string |
auto-generated | Field id, shared by the label and the textarea. |
label |
string |
— | Field label. |
hint |
string |
— | Helper text below the field (hidden when error is set). |
error |
string |
— | Error text; sets aria-invalid and swaps in for hint. |
rows |
number |
4 |
Visible row count. |
value |
string |
— | Initial text; the default slot works too. |
resize |
'none' | 'vertical' | 'auto' |
'vertical' |
Resize handle, or auto to grow with the content (field-sizing: content; a small island elsewhere). |
size |
'small' | 'medium' | 'large' | 'xlarge' |
'medium' |
Padding and text size from the shared scale, 28 / 36 / 48 / 56px. |
variant |
'outline' | 'faded' | 'ghost' | 'headless' |
'outline' |
The box style: bordered, tinted, bare, or no box at all. |
hasError |
boolean |
false |
Marks the field invalid (aria-invalid, critical border) without an error message. |
required |
boolean |
false |
Marks the field required (native required + label asterisk). |
class |
string |
— | Extra classes on the Field wrapper, merged last. |
Sizes
Every size:
Show codeHide code
<Textarea label="Small" size="small" placeholder="Small" />
<Textarea label="Medium" placeholder="Medium" />
<Textarea label="Large" size="large" placeholder="Large" />Resize
Every resize value:
Grows as you type.
Show codeHide code
<Textarea label="None" resize="none" rows={2} />
<Textarea label="Vertical" resize="vertical" rows={2} />
<Textarea label="Auto" resize="auto" rows={2} />States
Bio is required.
Tell us about yourself.
Show codeHide code
<Textarea label="Disabled" disabled placeholder="Disabled" />
<Textarea label="Bio" error="Bio is required." />
<Textarea label="Bio" required hint="Tell us about yourself." />- Hover — border unchanged; no hover-specific style.
- Focus — visible
focus-visiblering (--border-primary). - Disabled — dimmed, not focusable, native
disabled. - Invalid (
errorset) —--background-criticalborder,aria-invalid="true", hint text replaced by the error message withrole="alert".
Examples
More rows for longer content:
<Textarea label="Notes" rows={8} />
Accessibility
- Real
<label for>/<textarea id>pairing viaField. aria-describedbypoints to the hint or error paragraph;aria-invalidis set whenerroris present.- The error paragraph has
role="alert"so it’s announced. - Focus ring is always visible on keyboard focus.
Tokens
| Token | Used for |
|---|---|
--border-neutral / --background-page / --foreground-neutral |
Field border, fill, text |
--foreground-neutral-faded |
Placeholder + hint text |
--foreground-critical |
Invalid border + error text |
--border-primary |
Focus border |
Do / Don’t
- Do pair every
Textareawith alabel— placeholder text is not a label. - Do use
hintfor format guidance,errorfor validation failures — not both at once (error takes over). - Don’t disable a field without explaining why elsewhere on the page.
- Don’t rely on
rowsalone for very long content — consider letting it grow or linking to a fuller editor.
Content
- Label is a short noun phrase, sentence case, no colon.
- Error copy states what’s wrong and how to fix it (“Bio is required.”).
- Hint text is one line, no ending period unless it’s a full sentence.
Related
InputA labeled text field with hint/error messaging, wired for accessibility — plus a pure-CSS floating label.
FieldThe labeled-field scaffold — label, control, and hint/error — wired for accessibility.
RichTextEditorA small WYSIWYG editor — a formatting toolbar over a contenteditable region, synced to a hidden field for form submission.