Textarea
A multi-line text input: styled, labelled, and resizable, in three sizes with an invalid state.
Live demo
Textarea is a styled multi-line text control. It renders a native <textarea> that inherits the shared .xtyle-control chrome, wrapped with an optional label and an error message slot.
The rows attribute sets the initial visible height and resize controls the user's drag handle (vertical by default, or none / horizontal / both). It exposes the same invalid / disabled / required and sm / md / lg size surface as the rest of the form family. The custom element is form-associated, so its value participates in native form submission, reset, and constraint validation; required and invalid reach the form itself, and an empty required textarea blocks the submit rather than only looking wrong.
When to use
How this component composes with the rest of the set.
Props
19 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
aria-label and warns if neither is set. | ||||
--font-mono) for code-shaped text: expressions, snippets, config, structured input. A presentational swap on an existing token, so it bakes into the zero-JS Astro markup too. | ||||
aria-invalid. | ||||
aria-required on the control. | ||||
required is unmet. The platform localizes its own constraint messages and this one is xtyle's, so an app that is not in English should set it. | ||||
aria-describedby while invalid. | ||||
spellcheck="false" — a bare spellcheck is the HTML spelling of on. | ||||
email, street-address, or off. | ||||
spellcheck is. | ||||
Events
What the component emits, and what rides along on event.detail. The name in the
first column is the one addEventListener takes.
| Event | Detail | Bindings | Description |
|---|---|---|---|
Appearance
Variants
default
The standard control, neutral field chrome from .xtyle-control.
invalid
Error treatment: danger-colored border, label, and focus ring.
Sizes
sm
Compact.
md
Default.
lg
Large.
States
focus-visible
Keyboard focus: the shared .xtyle-control ring, recolored to danger while invalid.
invalid
Failing validation: danger border on the control and a danger label.
disabled
Non-interactive: muted chrome inherited from .xtyle-control, no-drop cursor.
Anatomy
The named parts that make up the component. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.
root
The wrapper carrying the size, invalid, and resize classes; lays out label, control, and error.
label
The field label, hidden when no label text is provided.
control
The native <textarea> inheriting .xtyle-control, with size, resize, and min-height applied.
error
The validation message shown beneath the control while invalid.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--border-normal--danger--danger-bg--danger-text--fg-1--font-mono--font-sans--leading-normal--space-1--space-2--space-3--space-4--space-6--space-7--space-8--text-lg--text-sm--weight-mediumSlots
Initial textarea content, projected into the native control's value.
Accessibility
Code
Labelled, resizable, and invalid
A labelled control with custom rows, a fixed-height variant, and an invalid state with an error message.
<xtyle-textarea label="Bio" name="bio" rows="4" placeholder="Tell us about yourself…"></xtyle-textarea>
<xtyle-textarea label="Notes" rows="6" resize="none"></xtyle-textarea>
<xtyle-textarea
label="Summary"
size="lg"
invalid
error="A summary is required."
required
></xtyle-textarea><script lang="ts">
import { Textarea } from "@xtyle/svelte";
let bio = $state("");
</script>
<Textarea label="Bio" name="bio" rows={4} bind:value={bio} placeholder="Tell us about yourself…" />
<Textarea label="Notes" rows={6} resize="none" />
<Textarea label="Summary" size="lg" invalid error="A summary is required." required />---
import { Textarea } from "@xtyle/astro";
---
<Textarea label="Bio" name="bio" rows={4} placeholder="Tell us about yourself…" />
<Textarea label="Notes" rows={6} resize="none" />
<Textarea label="Summary" size="lg" invalid error="A summary is required." required />