Skip to main content
xriptxr

Textarea

Info:Form
18

A multi-line text input: styled, labelled, and resizable, in three sizes with an invalid state.

multiline text area text input comment box

Live demo

live · @xtyle/astro

Textarea

A composed message

Sizes

Resize & states

Tell us a little more — at least 20 characters.

Code-shaped

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.

Pair with Button (type="submit" / type="reset") inside a <form>; the form-associated element submits and resets natively.
Mirror the label / invalid / error surface of Field and Select so a form reads consistently across single-line and multi-line inputs.
For code-shaped content (expressions, snippets, config), set mono; native input attributes (spellcheck, inputmode, autocomplete, autocapitalize, autocorrect, enterkeyhint) set on the host are forwarded to the inner control, so spellcheck="false" on an expression field works.

Props

19 props, straight from the manifest.

PropTypeDefaultBindingsDescription
label string
html svelte astro
The visible field label. When empty, the binding falls back to aria-label and warns if neither is set.
value string
html svelte astro
The textarea's text content. Two-way bindable in Svelte.
rows number 3
html svelte astro
Initial visible height of the control, in text rows.
resize TextareaResize
none vertical horizontal both
vertical
html svelte astro
Which axes the user can drag to resize the control.
placeholder string
html svelte astro
Placeholder text shown while the control is empty.
mono boolean false
html svelte astro
Renders the control in the monospace stack (--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.
size Size
sm md lg
md
html svelte astro
Control size.
name string
html svelte astro
Form field name; submitted with the control's value.
disabled boolean false
html svelte astro
Disables interaction and excludes the value from form submission.
invalid boolean false
html svelte astro
Marks the control invalid: danger border and aria-invalid.
required boolean false
html svelte astro
Marks the field required; reflected as aria-required on the control.
requiredMessage html: required-message string Please fill out this field.
html svelte astro
The message the browser shows when 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.
error string
html svelte astro
Validation message rendered beneath the control and wired up via aria-describedby while invalid.
spellcheck "true" | "false"
html svelte astro
Forwarded to the inner control: turn the browser's own spell-checker off for prose it would only underline in red — a markup source, a code snippet, an identifier. Enumerated rather than boolean, so it needs an explicit spellcheck="false" — a bare spellcheck is the HTML spelling of on.
inputmode "text" | "numeric" | "decimal" | "tel" | "email" | "url" | "search" | "none"
html svelte astro
Forwarded to the inner control: which on-screen keyboard a touch device should raise. Purely a hint — it does not validate or restrict what can be typed.
autocomplete string
html svelte astro
Forwarded to the inner control: the autofill token the browser should match against, such as email, street-address, or off.
autocapitalize "off" | "none" | "on" | "sentences" | "words" | "characters"
html svelte astro
Forwarded to the inner control: whether a touch keyboard capitalizes as you type.
autocorrect "on" | "off"
html svelte astro
Forwarded to the inner control: the browser's own autocorrect. Non-standard but widely honored, and worth turning off wherever spellcheck is.
enterkeyhint "enter" | "done" | "go" | "next" | "previous" | "search" | "send"
html svelte astro
Forwarded to the inner control: what a touch keyboard's action key should read.

Events

What the component emits, and what rides along on event.detail. The name in the first column is the one addEventListener takes.

EventDetailBindingsDescription
input { value }
html svelte astro
The text changed as it was typed.
change
html svelte astro
The text settled.

Appearance

Variants

default

.xtyle-textarea

The standard control, neutral field chrome from .xtyle-control.

invalid

.xtyle-textarea--invalid

Error treatment: danger-colored border, label, and focus ring.

Sizes

sm

.xtyle-textarea--sm

Compact.

md

default
.xtyle-textarea

Default.

lg

.xtyle-textarea--lg

Large.

States

focus-visible

.xtyle-textarea__control:focus-visible

Keyboard focus: the shared .xtyle-control ring, recolored to danger while invalid.

invalid

.xtyle-textarea--invalid .xtyle-textarea__control

Failing validation: danger border on the control and a danger label.

disabled

.xtyle-textarea__control: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

Success:::part(root) .xtyle-textarea

The wrapper carrying the size, invalid, and resize classes; lays out label, control, and error.

--space-1 --font-sans

label

Success:::part(label) .xtyle-textarea__label

The field label, hidden when no label text is provided.

--text-sm --weight-medium --fg-1 --leading-normal

control

Success:::part(control) .xtyle-textarea__control

The native <textarea> inheriting .xtyle-control, with size, resize, and min-height applied.

--space-7 --leading-normal

error

Success:::part(error) .xtyle-textarea__error

The validation message shown beneath the control while invalid.

--text-sm --leading-normal --danger

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 18/18 consumed tokens produced default register: 310 tokens

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-medium

Slots

default
html astro

Initial textarea content, projected into the native control's value.

Accessibility

Renders a native <textarea>, so editing, selection, and screen-reader semantics come for free.
The label is wired to the control via for / id; with no label, the binding falls back to aria-label and warns when neither is present.
invalid sets aria-invalid="true"; when an error is present it is linked through aria-describedby.
required is reflected as aria-required on the control.
Focus is shown with the shared control ring plus a transparent outline that the forced-colors base rule promotes to a real system outline.

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>