Skip to content
TopClass UI

Textarea

A native textarea rendered on the server. Autosize and the live counter are the only parts that load in the browser.

split - size not measured yet

Textarea

split - size not measured yet

A native textarea rendered on the server. Autosize and the live counter are the only parts that load in the browser.

Install

Try it

size
invalid
fullWidth
rows
maxRows
autosize
showCount

The code

textarea.tsx
import { Textarea } from 'topclassui/textarea'

<div className="grid max-w-sm gap-1">
  <label htmlFor="textarea-playground" className="text-sm font-medium text-body">About you</label>
  <Textarea id="textarea-playground" name="bio" placeholder="Write a short paragraph" />
</div>

On its own it is server HTML; autosize or showCount is what loads the small client half.

Every state

6 states

Import from the package

topclassui/textarea
import { Textarea } from 'topclassui/textarea'

Install once:npm i topclassui@beta zod

Examples

  • maxLength is 5000 by default. Pass your own number, or maxLength={null} for no cap; the browser stops typing and pasting there.
  • With autosize the rows follow the text from rows up to maxRows, then it scrolls. maxRows alone grows nothing.
  • The counter reads 42 / 500 under the field: always with showCount, and with autosize alone from nine tenths of the cap. At the cap it turns bold; that is not an error.
  • With autosize or showCount the width belongs to a box around the textarea: use fullWidth, or size the parent.
  • With no script, what is typed is kept and sent, and a form reset is native.
basic
A short paragraph is enough
autosize
show-count
12 of 60 characters
12 of 12 characters
sizes
form
0 of 5,000 characters
row
0 of 5,000 characters
0 of 5,000 characters
long-content
skeleton
In Arabic, right to left
عدد الأحرف: ٢٤ من ٥٠٠

Props

The props of Textarea
PropTypeDefaultLimitsDescription
aria-labelstring--The name read out when no visible label names the control.
aria-labelledbystring--The id of the visible text that names the control.
idstring--The id a <label htmlFor> points at.
autosizebooleanfalse-Grows with the text from rows up to maxRows once the page has hydrated; loads the small client half.
fullWidthbooleanfalse-Stretches the textarea, and the box around it with autosize or showCount, to the width of its container.
invalidbooleanfalse-Marks the value as wrong: sets aria-invalid, and the border turns to danger and thickens.
maxLengthunknown5000-The character cap: your number, 5000 by default, or null for none; clamped to 0-2147483647 and rounded down.
maxRowsinteger, min 1, max 406min 1, max 40With autosize, the most lines it grows to before it scrolls; clamped to 1-40 and never under rows.
rowsinteger, min 1, max 403min 1, max 40The lines it shows, and the least it shrinks to with autosize; clamped to 1-40.
showCountbooleanfalse-Always shows the count against the cap under the field; with autosize alone it shows from nine tenths of it.
sizexs | sm | md | lg | xl | custom"md"-The shared control scale: the padding and the type step. custom emits no size classes.

Keyboard and accessibility

The keyboard of Textarea
KeysWhat it does
TabMoves the focus to the field, and on to the next control.
EnterStarts a new line; it never submits the form.
  • A name is required: a <label htmlFor> pointing at id, or aria-label, or aria-labelledby.
  • The counter is the field's description, so a screen reader reads it after the name. It is not a live region.
  • invalid sets aria-invalid, and the border turns to danger and thickens.

Right to left

The text starts at the right and the counter sits at the inline end, on the left. Set the direction to auto to let each text follow its first letter.

Server and client

Renders on the server; the interactive part is a client component that ships only when it is used.

Files: index.tsx, client.tsx.

On the chip: split - size not measured yet.