AppTextarea
A multi-line field for longer, free-form text — notes, descriptions, scope. The textarea counterpart to AppInput.
<app-textarea label="Notes" name="notes" rows="4"></app-textarea><app-textarea> is the shared multi-line field. Reach for it whenever a value can run past a single line — a note, a description, a scope of work, an address block. It carries the same label, hint, error, and required treatment as <app-input>, so a longer answer still reads as one consistent field alongside the rest of the form.
Its look comes entirely from the shared @webority/theme, so the Razor <app-textarea> and the React <AppTextarea> render identically — a field is a field on every Webority surface.
Playground
Every attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the field above it.
Basic
A labelled multi-line field with a placeholder. Give it a name and the label and control are wired together for you.
Show code
<app-textarea label="Notes" name="notes" rows="4" placeholder="Add any additional details…"></app-textarea>
Sizing
rows sets the initial visible height. Match it to the expected answer — a couple of lines for a short note, more for a full description.
Show code
<app-textarea label="Summary" name="summary" rows="2" placeholder="One or two lines…"></app-textarea> <app-textarea label="Description" name="description" rows="6" placeholder="A fuller description…"></app-textarea>
rows sets how tall the field opens; the browser still lets the user scroll or drag to resize. Size it for the typical answer, not the longest possible one.Auto-grow
Set auto-grow and the height tracks the content — the field never scrolls inside a fixed box. rows sets the starting height; it grows from there as the user types.
Show code
<app-textarea label="Notes" name="notes" auto-grow="true" rows="2" placeholder="Type a few lines…" />
auto-grow for the manual grabber.Character count
Set show-count for a live count under the field; add max-length to cap the input and show the denominator. The count turns red at the limit — the same contract as <app-input>.
Show code
<app-textarea label="Bio" name="bio" show-count="true" max-length="280" rows="3" placeholder="Up to 280 characters" />
max-length the counter shows the running length; with it, the field is capped and the count reads count / max, turning red at the limit.Validation
Show a hint for guidance and an error when validation fails. They share one slot below the field — the error replaces the hint and turns the field red.
Show code
<app-textarea label="Scope of work" name="scope" hint="Markdown supported."></app-textarea> <app-textarea label="Description" name="description" required error="Description is required."></app-textarea>
hint and error occupy the same line, so a set error hides the hint. Treat the hint as brief guidance, not a second label, and make the error say how to fix the problem.When to use
Use it when
- The value is free-form text that can run past a single line — a note, description, comment, or address block.
- You want the same labelled treatment (hint, error, required) as the rest of the form, for a longer answer.
- The user might write a few words or a few paragraphs and you can't predict which.
Reach for something else when
- The value is a single short line — a name, email, or reference. → AppInput
- The user picks from a fixed set of options. → AppSelect
- It is a search box that filters a list. → AppSearch
Best practices
Every option
The whole surface of the component, one cell per value — including states a normal example never shows: required, disabled, error + hint together, and a long value overflowing a fixed rows.
rows — every size
rows="2"
rows="4"
rows="6"
rows="10"
auto-grow — off vs on, with overflow content
(default) — fixed rows, scrolls
auto-grow — height fits the content
state
(default)requireddisablederrorhinterror + hint (error wins)required + errorhelp — label info-tip
(no help)help="…" — default help-labelhelp + custom help-labellabel — present vs omitted
(no label) — placeholder onlylabel="Notes"Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| label | string | — | The field label. Always set one — never rely on the placeholder. |
| name | string | — | Field name; also used as the id. |
| auto-grow | bool | — | Grow the height to fit the content as the user types. |
| show-count | bool | — | Show a live count / max-length under the field. |
| max-length | int | — | Character cap; the count turns red as it is approached. |
| rows | int | 4 | Initial visible height, in text rows. |
| placeholder | string | — | Placeholder text shown while the field is empty. |
| value | string | — | Pre-filled content of the textarea. |
| required | bool | false | Appends a required mark to the label. |
| hint | string | — | Helper text below the field. Hidden while an error is shown. |
| error | string | — | Error message. Turns the field red and replaces the hint. |
| help | string | — | Info-tip content shown beside the label (React help). |
| help-label | string | More information | aria-label for the info-tip button (React helpLabel). |
| id | string | — | Explicit control id. Defaults to name (React id). |
| class | string | — | Extra classes on the .field wrapper (React fieldClassName). |
| input-class | string | — | Extra classes on the control itself (the textarea) — the React className counterpart. The plain class attribute merges onto the .field wrapper instead. |