Textarea
A custom-styled textarea component extending HTMLTextAreaElement.
The component builds a [field-wrapper] span around the control - always, with or without a
label - and that span carries the field box; the <label> and the hint are its siblings.
Usage
<textarea is="root-textarea" placeholder="Write something..." data-label="Message"></textarea>
Resize
data-resize
names the axis the native handle may move on: vertical (the default),
horizontal, both or none. The [field-wrapper] takes
the control's own size, so whatever the user drags it to is the size of the box around it.
<textarea is="root-textarea" data-label="Vertical" data-resize="vertical"></textarea>
<textarea is="root-textarea" data-label="Horizontal" data-resize="horizontal"></textarea>
<textarea is="root-textarea" data-label="Both" data-resize="both"></textarea>
<textarea is="root-textarea" data-label="Fixed" data-resize="none"></textarea>
Hint and error
data-hint
holds the description and data-error the error message: both are authored once, and
data-invalid decides which one shows. With no data-error
the browser's own validationMessage stands in. One node carries both, wired to the control
through aria-describedby.
<textarea is="root-textarea" data-label="Bio" data-hint="A short bio" data-error="Too long"></textarea>
No-autofill
Add no-autofill to opt a field out of native autocomplete/autocorrect/
autocapitalize/spellcheck and the common password-manager browser extensions (1Password, LastPass,
Bitwarden) - none of which honor a single standard attribute.
<textarea is="root-textarea" no-autofill data-label="One-time note"></textarea>
Sizes
data-size
takes small and large; medium is the default and needs no value written. The
step moves the padding and the minimum height; the text stays at the base step at every size, which is the
floor under which iOS Safari zooms the viewport on focus.
<textarea is="root-textarea" data-size="small" data-label="Small" rows="2"></textarea>
<textarea is="root-textarea" data-label="Medium" rows="2"></textarea>
<textarea is="root-textarea" data-size="large" data-label="Large" rows="2"></textarea>
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
placeholder |
string |
- | Placeholder text |
rows |
number |
- | Visible rows |
data-resize |
'vertical' | 'horizontal' | 'both' | 'none' |
'vertical' |
Which axis the resize handle moves on |
no-autofill |
boolean |
false |
Opt out of autocomplete and password managers |
disabled |
boolean |
false |
Disables the textarea |
readonly |
boolean |
false |
Read-only state |
data-label |
string |
- | Label text; the component builds the <label> |
required |
boolean |
false |
Marks the field required and draws the asterisk |
data-hint |
string |
- | Description shown under the field |
data-error |
string |
- | Error message; falls back to validationMessage |
data-invalid |
'true' |
- | Shows the error instead of the description |
Events
Namespaced as <component>.<event>, bubbling and cancelable;
detail also carries the originating DOM event as originalEvent.
| Event | Detail | Description |
|---|---|---|
root-textarea.input |
{ value } |
Fired on input |
root-textarea.change |
{ value } |
Fired on change |
root-textarea.focus |
{ value } |
Fired on focus |
root-textarea.blur |
{ value } |
Fired on blur |
root-textarea.invalid |
{ value } |
Fired when the control fails constraint validation |
root-textarea.data-label.change |
{ value, oldValue } |
Fired when the label text changes |
Extends
HTMLTextAreaElement
- use with <textarea is="root-textarea">.