Inputs
Textarea
Multi-line text field.
import { Textarea } from 'omaris' Examples
Basic
Same frame and states as Input, with rows instead of a height — for a note, an address, anything longer than a line.
<script lang="ts"> import { Textarea } from 'omaris'; let notes = $state('');</script><Textarea class="w-96 max-w-full" label="Delivery notes" placeholder="Gate code, floor, anything the driver should know" supportingText="The driver sees this." bind:value={notes}/> Autosize and counter
autosize grows the field with its content, up to maxRows, using a hidden mirror element — so the caret never scrolls out of view mid-sentence.
<script lang="ts"> import { Textarea } from 'omaris'; let bio = $state('Ships dashboards from Erbil.');</script><div class="flex w-full max-w-md flex-col gap-6"> <Textarea label="Bio" autosize rows={2} maxRows={8} counter maxlength={280} bind:value={bio} /> <Textarea label="Fixed at 3 rows" rows={3} value="This one does not grow." /></div> States
The supporting line becomes the error text when the field is invalid, so the reason is under the field and not in a toast.
<script lang="ts"> import { Textarea } from 'omaris';</script><Textarea class="w-72 max-w-full" label="Required" required placeholder="Say something" /><Textarea class="w-72 max-w-full" label="Invalid" invalid value="Too short" supportingText="At least 20 characters."/><Textarea class="w-72 max-w-full" label="Disabled" disabled value="Read only" /> When to use it
Use it for
- Text that runs past a line: delivery notes, a description, a reply, an address.
- A composer.
autosizewithrows={1}and amaxRowsgrows one line at a time.bind:linesswaps in a send button or shows a "shift+enter for a new line" hint. - A hard limit the person should see coming. Pass
counterwithmaxlength.
Not for
- One line, like a title, a name or a URL → Text Field.
- Bold, a list, a link → Rich Text Editor.
- Code, JSON, a query → Code Editor with
lang. It indents, closes brackets and colours. - Chat text with emoji → still this, with an Emoji Button beside it.
Do
- Match the Input next to it: same
variant, samesize. They share a frame and line up without adjustment. - Set
rowsto the length you expect:2for a note,6for a description. The default3is a guess. - Give
autosizeamaxRows, or a pasted essay pushes the submit button off the screen. - Put the reason in
supportingTextand setinvalid. The helper line becomes the error line.
Don't
- Autosize inside a grid of cards. The row below moves every time a line is added. Fix
rowsthere and let it scroll. - Expect the resize grip with
autosize. The box sizes itself, so the grip is removed. Withoutautosizethe grip is on, vertical only. - Use the placeholder for instructions needed after typing starts. That is
supportingText.
Quick reference
variant outline(default)filledghost
size smdefault(default)lg
--field-line is the line box the row maths are done in, so it has to be a real length rather than normal.
API
Textarea
Multi-line text field.
Shares the Input's frame — same three variants, same focus bloom, same label/supporting-text layout — so a form mixing the two lines up without fiddling.
autosize turns it into a composer: the box tracks how many lines the text actually occupies and grows a line at a time, smoothly, instead of scrolling inside a fixed rectangle. It starts at rows, never goes below it, and stops at maxRows — past which it scrolls like a normal textarea. Height comes from a mirror of the text rather than from poking the element's own height between measurements, so the growth can be transitioned without the flicker that trick usually brings.
import { Textarea } from 'omaris' Parts
Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.
root- No description in the source yet.
field- No description in the source yet.
well- Holds the control and, when autosizing, the mirror behind it.
control- No description in the source yet.
mirror- An invisible copy of the text, laid over the control at the same width and typography. Its height is the height the control wants — measured without ever resizing the control itself.
label- No description in the source yet.
support- No description in the source yet.
counter- No description in the source yet.
Props
variant Defaults to 'outline'
TextareaVariant outlinefilledghost
size Defaults to 'default'
TextareaSize smdefaultlg
label string required boolean Inside a Field, defaults to the field's.
supportingText string invalid boolean Inside a Field, defaults to the field's.
value bindableDefaults to ''
string counter Defaults to false
boolean Live n/maxlength count beside the supporting text.
autosize Defaults to false
boolean Grow with the text. The box starts at rows, gains a line as the text takes one, and scrolls once it reaches maxRows.
rows Defaults to 3
number Starting height, in lines — and the floor when autosize.
maxRows number Ceiling for autosize, in lines. Past this it scrolls.
lines bindableDefaults to 1
number Lines the text currently occupies. Bindable, and read-only in practice — useful for a "shift+enter for a new line" hint or for swapping a send button in once the composer has something in it.
class string classes TextareaClasses Per-part Tailwind overrides. class still covers the root.
supporting Snippet Richer supporting text — a link, a hint.
ref bindableDefaults to null
HTMLTextAreaElement | null