v1.0.0

<bmx-textarea>

Multi-line text, with the same chrome as bmx-input and the same rules about when a problem may be shown - both come from src/components/field, so a form built from the two reads as one form rather than two components that happen to sit near each other.

29 properties · 5 events · 7 methods · 7 parts

Example

Show markup
<div class="row">
  <bmx-textarea label="Delivery notes" placeholder="Anything the driver should know" description="Grows as you type, up to eight rows." min-rows="3" max-rows="8"></bmx-textarea>
</div>
<div class="row">
  <bmx-textarea label="Feedback" counter="true" max-length="280" min-rows="3" description="Tell us what went wrong." required="true"></bmx-textarea>
</div>
<div class="row">
  <bmx-textarea label="Release notes" appearance="filled" autosize="false" resize="vertical" min-rows="4" description="Fixed height with a drag handle, for when you want to keep the layout still."></bmx-textarea>
</div>

WHAT IT ADDS

Autosizing. A textarea that stays at its initial height while the user types past the bottom of it is the single most common complaint about the native element, and every application ends up bolting the same twenty lines onto it. autosize is on by default here, bounded by minRows and maxRows, and the arithmetic lives in src/core/autosize.ts where its edge cases are unit tested.

WHAT IT DELIBERATELY DOES NOT HAVE

A mask. Masking is caret arithmetic over a single run of characters, and it has no useful meaning across line breaks - there is no pattern anyone wants to write for a paragraph. bmx-input has it; this does not, and the absence is a decision rather than an omission.

Prefix and suffix slots, for the same kind of reason: they belong beside a single line of text, not floating against a block of it.

ACCESSIBILITY

  • A real <textarea> labelled by a real <label>, so the platform supplies the role, the keyboard behaviour and the announcement.
  • The description and the error are wired through aria-describedby, in reading order, with absent parts dropped rather than left as empty ids.
  • The error lives in a live region present from the first render.
  • aria-invalid tracks the shown error, not the underlying validity, so a field the user has not reached yet is not announced as invalid.
  • Autosizing means the text never scrolls out of sight of a magnifier user until maxRows is reached, and the control keeps its own resize handle unless the author turns it off.

Properties

PropertyAttributeTypeDefaultDescription
appearance appearance BmxTextareaAppearance 'outline' Visual treatment.
autoFocus auto-focus boolean false Focus the field once it has rendered.
autocomplete autocomplete string Autocomplete hint.
autosize autosize boolean true Grow with the content. On by default, because the alternative is the behaviour everybody immediately writes JavaScript to replace. Turn it off for a fixed box the user resizes themselves.
counter counter boolean false Show a character counter. Pairs with maxLength.
description description string Help text below the field.
disabled disabled boolean false Disable the field.
errorText error-text string An error supplied by the consumer - a server response, typically.
fullWidth full-width boolean true Stretch to the width of the container. On by default: text wants room.
hideLabel hide-label boolean false Hide the label visually while keeping it for assistive technology.
label label string The field's label. Required unless the label slot is used.
maxLength max-length number Maximum length, in characters rather than UTF-16 code units. Enforced here rather than by the native attribute, which counts code units and would cut a user off at fifty emoji on a limit of a hundred while the counter still read fifty. Also drives the counter's limit.
maxRows max-rows number Never taller than this many rows. Beyond it the control scrolls.
messages property only BmxFieldMessages Replacements for the default wording, by reason. Accepts the JSON spelling of the object as well, for templates that can only write attributes. See src/core/markup.ts.
minLength min-length number Minimum length, in characters.
minRows min-rows number 3 Never shorter than this many rows.
name name string The field's name in the form it belongs to.
placeholder placeholder string Placeholder text. Never a substitute for a label.
readonly readonly boolean false Make the field read-only. It still submits and is still focusable.
required required boolean false Require a value.
resize resize BmxTextareaResize 'vertical' The control's own resize handle. vertical by default rather than both: a textarea dragged wider than its container is the fastest way to break a form layout, and it is the one direction autosizing does not already handle. Forced to none while autosize is on, since the two fight over the same property.
shape shape BmxShape 'rounded' Corner treatment. pill and circle are not meaningful on a block.
size size BmxSize 'md' Size step.
spellcheck spellcheck boolean true Spellchecking. On by default here, unlike bmx-input: this holds prose.
tone tone BmxTone 'primary' Semantic colour role, used for the focus ring. An error overrides it.
validateOn validate-on BmxValidateOn 'blur' When the field is willing to reveal a problem.
validator property only BmxAsyncCheck A consumer's own check, run once the value is structurally whole.
value value string '' The text in the control.
wrap wrap 'hard' | 'soft' | 'off' 'soft' Wrapping behaviour, as the native attribute takes it.

Events

EventDetailDescription
bmxBlur void Fired when the field loses focus.
bmxChange BmxTextareaChangeDetail Fired when the field is committed - on blur.
bmxFocus void Fired when the field gains focus.
bmxInput BmxTextareaChangeDetail Fired on every edit.
bmxValidityChange BmxTextareaValidityDetail Fired whenever the resolved validity changes.

Methods

MethodSignatureDescription
checkValidity checkValidity() => Promise<boolean> Validate now and return whether the field passed, without revealing it.
clear clear() => Promise<void> Empty the field.
refreshSize refreshSize() => Promise<void> Recompute the height now. For a value written around the component.
removeFocus removeFocus() => Promise<void> Remove focus from the field.
reportValidity reportValidity() => Promise<boolean> Validate, reveal any problem, and focus the field if it has one.
selectAll selectAll() => Promise<void> Select the field's contents.
setFocus setFocus(options?: FocusOptions) => Promise<void> Focus the field.

Slots

SlotDescription
description Rich help text, in place of the description property.
label Rich label content, in place of the label property.

CSS shadow parts

PartDescription
control The native textarea.
counter The character counter.
description The help text.
error The error message.
field The bordered box holding the textarea.
label The label element.
spinner

CSS custom properties

PropertyDescription
--bmx-textarea-background The field's background. Set by appearance; override for a one-off.
--bmx-textarea-border-color The field's border colour in its resting state.
--bmx-textarea-border-width Border width of the field.
--bmx-textarea-font-size The value's font size.
--bmx-textarea-label-font-size The label's font size.
--bmx-textarea-line-height Line height of the text. Also the row unit that minRows and maxRows count.
--bmx-textarea-padding-block Vertical padding inside the field.
--bmx-textarea-padding-inline Horizontal padding inside the field.
--bmx-textarea-placeholder-color Placeholder colour. Dimmer than the value, and still AA against the field.
--bmx-textarea-radius Corner radius of the field.
--bmx-textarea-stack-gap Space between the label, the field and the supporting text.
--bmx-textarea-support-font-size Font size of the description, error and counter.