Skip to main content

Textarea

<zeno-textarea>FormsForm controlSource

A multi-line text field that can grow with its content.

import '@usezeno/tokens/css';
import '@usezeno/core/web-components';

Examples​

Basic​

The label attribute renders a label above the field. rows sets the height in lines.

<zeno-textarea label="Notes" placeholder="Add a note for your team" rows="4"></zeno-textarea>

Sizes and variants​

<zeno-textarea size="sm" label="Small" value="Small text"></zeno-textarea>
<zeno-textarea size="md" label="Medium" value="Medium text"></zeno-textarea>
<zeno-textarea size="lg" label="Large" value="Large text"></zeno-textarea>
<zeno-textarea variant="outlined" label="Outlined" value="The default variant"></zeno-textarea>
<zeno-textarea variant="filled" label="Filled" value="A filled background"></zeno-textarea>

Auto resize, counter and clear button​

With auto-resize the field grows with its text. maxlength limits the text and shows a counter. show-count shows a counter with no limit. With clearable, a clear button shows when the pointer is over the field or the field has focus.

<zeno-textarea label="Grows with the text" auto-resize rows="2" value="Type a few lines here."></zeno-textarea>
<zeno-textarea label="Short description" maxlength="80" value="A weekly report for the sales team."></zeno-textarea>
<zeno-textarea label="Comment" show-count clearable resize="none" value="Looks good to me."></zeno-textarea>

States​

The error text shows below the field. success and loading only change how the field looks.

<zeno-textarea label="Disabled" value="You cannot change this text." disabled></zeno-textarea>
<zeno-textarea label="Read only" value="You can select this text but not change it." readonly></zeno-textarea>
<zeno-textarea label="With an error" value="Too short" error="Write at least 20 characters."></zeno-textarea>
<zeno-textarea label="Success" value="This description is long enough." success></zeno-textarea>
<zeno-textarea label="Loading" loading></zeno-textarea>

In a form​

The value is sent under name. Submit the empty form to see the message for a required field.

Send Reset

Nothing submitted yet.

<form>
<zeno-textarea name="message" label="Message" rows="3" required></zeno-textarea>
<zeno-button type="submit">Send</zeno-button>
<zeno-button type="reset" variant="ghost">Reset</zeno-button>
<p data-result>Nothing submitted yet.</p>
</form>
const form = document.querySelector('form');
form.addEventListener('submit', event => {
event.preventDefault();
const sent = [...new FormData(form)].map(([name, value]) => name + '=' + value);
document.querySelector('[data-result]').textContent = 'Submitted: ' + sent.join('&');
});

Attributes and properties​

PropertyAttributeTypeDefaultDescription
variantvariantreflects'outlined' | 'filled' | 'underlined''outlined'
sizesizereflects'sm' | 'md' | 'lg''md'
placeholderplaceholderstring
rowsrowsnumber3
minlengthminlengthnumber
maxlengthmaxlengthnumber
resizeresizereflects'none' | 'vertical' | 'horizontal' | 'both''vertical'
autoResizeauto-resizereflectsbooleanfalse
autofocusautofocusreflectsbooleanfalse
clearableclearablereflectsbooleanfalse
loadingloadingreflectsbooleanfalse
successsuccessreflectsbooleanfalse
showCountshow-countreflectsbooleanfalse
valuevalueFormValue'' From FormFieldMixin.
namenamereflectsstring From FormFieldMixin.
requiredrequiredreflectsbooleanfalse From FormFieldMixin.
disableddisabledreflectsbooleanfalse From FormFieldMixin.
readonlyreadonlyreflectsbooleanfalse From FormFieldMixin.
errorerrorstringAn error to show, for example one a server returned. From FormFieldMixin.
labellabelstringA visible label. An outside <label for> works as well. From FormFieldMixin.
hideRequiredIndicatorhide-required-indicatorbooleanfalse From FormFieldMixin.
touchedbooleanfalseTrue once the user has left the control or a submit was refused. From FormFieldMixin.
dirtybooleanfalseTrue once the user has changed the value. From FormFieldMixin.
defaultValueFormValue''The value the control goes back to when its form is reset. From FormFieldMixin.
formread onlyHTMLFormElement | null From FormFieldMixin.
labelsread onlyNodeList From FormFieldMixin.
validityread onlyValidityState From FormFieldMixin.
validationMessageread onlystring From FormFieldMixin.
willValidateread onlyboolean From FormFieldMixin.
isDisabledread onlybooleanTrue when the element or an ancestor fieldset disables it. From FormFieldMixin.
invalidread onlybooleanTrue when the control should look invalid. From FormFieldMixin.
testIdstringTest ID for automated testing From ZenoElement.

Methods​

MethodDescription
focus(options?: FocusOptions): voidFocus the textarea element From ZenoElement.
blur(): voidBlur the textarea element From ZenoElement.
select(): voidSelect all text in the textarea
setSelectionRange(start: number, end: number, direction?: 'forward' | 'backward' | 'none'): voidSet selection range
checkValidity(): booleanReports whether the value is valid without showing anything. Use reportValidity() or validate() to show the result as well. From FormFieldMixin.
reportValidity(): boolean From FormFieldMixin.
setCustomValidity(message: string): void From FormFieldMixin.
validate(): booleanChecks validity and shows the result on the control. From FormFieldMixin.

Events​

EventDetailDescription
input{ value: FormValue }The value changed while typing.
change{ value: FormValue }The value was committed.
clearThe clear button was pressed.

Slots​

This element has no slots.

CSS parts​

Part
clear-button
count
error
footer
label
loading
textarea
wrapper

CSS custom properties​

This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.

The element's own source reads no tokens.

Types​

type FormValue = string | number | boolean | Date | null | undefined;

Accessibility​

Keyboard​

KeyWhat it does
TabMoves focus to the text field.
EnterAdds a new line. It does not submit the form.

Forms​

  • With a name, the element adds its value to the data of the form it is in, and is left out while it is disabled.
  • It is labelled by its label attribute or by a <label for> that points at its id.
  • It takes part in validation: checkValidity(), reportValidity() and setCustomValidity() work, and an invalid element blocks the submit and matches :invalid.
  • It follows a <fieldset disabled> around it and goes back to its first value when the form is reset.
  • The messages it writes itself, such as “Please fill out this field.”, are in English only.

Notes​

  • The control is a native <textarea>. Typing, selection and the keys come from it.
  • The label attribute renders a <label> for the field. Without it, the name comes from an outside <label for> or from aria-label on the element.
  • A required field shows * after the label. The mark is hidden from assistive technology, and the native required attribute is set on the field.
  • When the field is invalid, it has aria-invalid="true" and aria-describedby points at the error text.
  • disabled and readonly set the native attributes with the same names on the field.

Tests and known gaps​

  • Tested in a real browser by textarea.test.ts.
  • Checked with axe-core in the light and the dark theme.
  • Has no Storybook story.
34 of the 51 properties, methods, events, slots and parts above have no description in the source
  • the property variant
  • the property size
  • the property placeholder
  • the property rows
  • the property minlength
  • the property maxlength
  • the property resize
  • the property autoResize
  • the property autofocus
  • the property clearable
  • the property loading
  • the property success
  • the property showCount
  • the property value
  • the property name
  • the property required
  • the property disabled
  • the property readonly
  • the property hideRequiredIndicator
  • the property form
  • the property labels
  • the property validity
  • the property validationMessage
  • the property willValidate
  • the method reportValidity()
  • the method setCustomValidity()
  • the part clear-button
  • the part count
  • the part error
  • the part footer
  • the part label
  • the part loading
  • the part textarea
  • the part wrapper

Known gaps:

  • The variant type lists underlined, but the element has no styles for it. The element has styles for ghost, which the type does not list.
  • The clear button has tabindex="-1", so it cannot be reached with the keyboard.
  • The clear button label is the fixed English text “Clear textarea”. No attribute changes it.
  • While loading, the text is made transparent but the field can still be edited. The field has no aria-busy.
  • The success state is shown by the border colour only. No text or icon says that the value is good.
  • The character counter is not linked to the field and is not a live region, so assistive technology does not read it.
  • The counter shows whenever maxlength is set. It cannot be turned off for a field with a limit.