Skip to contentAsheeUIAsheeUI

Textarea

Several lines of text, with the field family's label, description and message.

A textarea holds a value that does not fit on one line: a message, a note, a set of terms. It is an input that grew, so it keeps the family's four parts and its shared axes and adds the one decision a multi-line field has, how much of the value is visible at once.

That height is a starting point rather than a limit. The box is resizable downwards, and the value is never truncated to what fits.

Usage

import { Textarea } from "@asheeui/web";

<Textarea
  label="Delivery note"
  description="Shown to the customer."
  value={note}
  onChange={(event) => setNote(event.target.value)}
  rows={4}
/>

The value comes from the element, through the native onChange. Unlike Input, this component declares no onChangeText, so the event is the only handler, the value is on event.target.value. Every textarea attribute, placeholder, maxLength, name, disabled, reaches the element.

Rows

rows states how many text rows the box shows before anyone types. It resolves from the instance, then components.textarea.rows, then the framework's 4, so a product where every note is long restates it once.

Two rows suit a value of a sentence; eight suit one that is read before it is edited. The box grows when a reader drags its lower edge, and the value keeps going past the visible height either way.

Rounding

Two rules shape the corners. A radius of full is honoured exactly as it is on a single-line field, the same scale, the same shape, because a radius is the consumer's decision rather than the component's. And variant="underlined" resolves the radius to none, as it does on every field, since an underlined box with rounded corners is two vocabularies at once.

Props

size, variant, labelAlign and rows are registered by the component as md, bordered, left and 4. radius and color are not registered: they resolve from the application's defaultRadius and defaultColor, so the box rounds and leads with the same accent as the rest of the product. status is never read from configuration, a validation result belongs to one attempt, not to the design.

fullWidth decides whether the field fills its column, the default, or shrinks to its content with the label and message alongside. It resolves through the cascade, so components.textarea.fullWidth retunes every textarea at once.

enableVirtualKeyboard defaults to true, but the box opens an on-screen keyboard only when a KeyboardProvider sits above it; the options object states the treatment, size, variant, colour and rounding, for this field's keyboard alone, and the layout it opens, so { layout: "numeric" } gives one box a keypad while the rest of the form keeps the provider's alphabet. The layout returns to the provider's default when the keyboard closes. See Keyboard.

Accessibility

  • The control is a real <textarea>. label names it through htmlFor, and the description and message are attached with aria-describedby, so the field is announced with its name and its instructions.
  • status="error" sets aria-invalid, and the message element carries role="alert", so a failure is announced when it appears.
  • isLoading sets aria-busy and shows a spinner beside the label, which keeps its text.
  • rows is a statement about visible height only: the value is not truncated, and a reader hears all of it. Use maxLength when the value itself has a limit.

The label, description and message behave as the field anatomy describes.