Textarea
A labeled multi-line text area with configurable resize behavior, including an auto-grow mode, plus description and inline error.
Import
import { Textarea } from "@hyzer-labs/ui"Demo
let notes = $state('');
<Textarea name="notes" label="Round notes" bind:value={notes} />The default vertical grows with content as you type, and keeps the native
drag handle as a manual override. auto grows without a handle. Growth uses
CSS field-sizing: content where supported, with a JavaScript height-sync
fallback elsewhere, and rows sets the minimum height. none and both are fixed height with the matching handle.
<Textarea name="review" label="Course review" /><Textarea name="review" label="Course review" resize="none" /><Textarea name="review" label="Course review" resize="both" /><Textarea name="review" label="Course review" resize="auto" />description and error are announced with the field: both chain
into aria-describedby. Error and disabled are also field states. The
wrapper's data-state reflects them, and error wins.
What should first-timers know? Up to 500 characters.
Feedback can't be empty.
<Textarea
name="review"
label="Course review"
description="What should first-timers know? Up to 500 characters."
maxlength={500}
/>
<Textarea name="feedback" label="Feedback" error="Feedback can't be empty." />
<Textarea name="incident" label="What happened?" required />
<Textarea name="closed" label="Course conditions" disabled value="Hole 7 flooded after the storm." />Props
| Name | Type | Default | Note |
|---|---|---|---|
name | string | — | Required. Form field name. |
label | string | — | Required. Always in the DOM; sr-only with hideLabel. |
value | string | '' | Bindable. |
rows | number | 3 | |
resize | 'none' | 'vertical' | 'both' | 'auto' | 'vertical' | 'vertical' and 'auto' grow with content; 'vertical' keeps the drag handle, 'auto' hides it. rows is the minimum height. |
maxlength | number | — | |
description | string | — | Help text below the label. |
error | string | — | Inline error message; sets the error state. |
required | boolean | false | |
disabled | boolean | false | |
hideLabel | boolean | false | |
class | string | — | Merged after the hz-field class. |
Theme hooks
What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.
Root class: .hz-field
Data attributes
| Hook | Values | Styles |
|---|---|---|
data-state | 'default' | 'error' | 'disabled' | The universal field state hook, on the root. Precedence is fixed: error beats disabled. |
data-resize | 'none' | 'vertical' | 'both' | 'auto' | On the textarea. Default vertical; auto uses field-sizing: content. |
Part classes
| Hook | Values | Styles |
|---|---|---|
.hz-field-label | child element | The label. |
.hz-field-required | child element | The required marker. |
.hz-field-description | child element | The hint text. |
.hz-field-error | child element | The error message. |
Accessibility
The textarea is associated with its label via id/for. With hideLabel, the label stays in the DOM as screen-reader-only text.
description and error chain into aria-describedby, description first. required sets aria-required, and an error sets aria-invalid.
References: MDN: <textarea>