Forms
Textarea
A multi-line text input with autoresize, icons, variants, colors, sizes, and loading states.
Updated in v2.9.0
leadingSlot and trailingSlot now reserve room, so their content no longer sits on top of the text, and a button placed in one can be clicked, as in Input. While loading, the spinner is shown instead of a slot on the same side.Playground
Experiment with different props in real-time.
Basic Usage
<script lang="ts">
import { Textarea } from 'sv5ui';
</script>
<Textarea placeholder="Write something..." />Variants
5 visual styles.
<Textarea variant="outline" placeholder="Outline" />
<Textarea variant="none" placeholder="None" />
<Textarea variant="soft" placeholder="Soft" />
<Textarea variant="subtle" placeholder="Subtle" />
<Textarea variant="ghost" placeholder="Ghost" />Sizes
<Textarea size="xs" placeholder="Extra Small" />
<Textarea size="sm" placeholder="Small" />
<Textarea size="md" placeholder="Medium" />
<Textarea size="lg" placeholder="Large" />
<Textarea size="xl" placeholder="Extra Large" />With Icons
Add leading/trailing icons.
<!-- Leading icon -->
<Textarea leadingIcon="lucide:message-square" placeholder="Your message..." />
<!-- Trailing icon -->
<Textarea trailingIcon="lucide:send" placeholder="Type to send..." />
<!-- Both icons -->
<Textarea leadingIcon="lucide:edit-3" trailingIcon="lucide:check" placeholder="Edit note..." />Leading and Trailing Slots
For more than an icon, pass leadingSlot or trailingSlot. The textarea leaves room for the slot and lets the pointer reach it, so a button in one works. Slot content cannot be clicked while the textarea is disabled or loading.
Sent 0 replies
<script lang="ts">
import { Textarea, Button } from 'sv5ui';
let reply = $state('');
function send() {
// ...post it, then clear
reply = '';
}
</script>
<Textarea bind:value={reply} placeholder="Write a reply...">
{#snippet trailingSlot()}
<Button
icon="lucide:send"
size="xs"
variant="ghost"
aria-label="Send"
onclick={send}
/>
{/snippet}
</Textarea>
<!-- Disabled: the slot is still shown, but it no longer takes clicks -->
<Textarea disabled value="Replies are closed">
{#snippet trailingSlot()}
<Button
icon="lucide:send"
size="xs"
variant="ghost"
aria-label="Send"
onclick={send}
/>
{/snippet}
</Textarea>Autoresize
Auto-adjust height based on content. Use maxrows to limit.
<!-- Auto-grows as you type -->
<Textarea autoresize placeholder="Start typing and I'll grow..." />
<!-- Auto-grows with a max row limit -->
<Textarea autoresize maxrows={6} placeholder="I'll grow up to 6 rows..." />Custom Rows
Set initial visible rows.
<Textarea rows={1} placeholder="1 row" />
<Textarea rows={5} placeholder="5 rows" />
<Textarea rows={8} placeholder="8 rows" />Highlight
<Textarea highlight placeholder="Highlighted textarea" />Loading & Disabled
loading shows a spinner and disables the textarea. The spinner sits on the leading side, or on the trailing side with trailing, and takes the place of an icon or a slot there.
<Textarea loading placeholder="Loading..." />UI Slots
Use the ui prop to override classes on internal elements.
| Slot | Description |
|---|---|
root | Outermost wrapper |
base | Textarea element |
leading | Leading content wrapper |
leadingIcon | Leading icon |
trailing | Trailing content wrapper |
trailingIcon | Trailing icon |
<Textarea
placeholder="Custom styled"
leadingIcon="lucide:pencil"
ui={{
base: 'rounded-xl shadow-lg',
leading: 'pl-4',
leadingIcon: 'text-primary'
}}
/>Snippets
| Snippet | Description |
|---|---|
leadingSlot | Custom content before the text. The textarea reserves room for it and a control inside it can be clicked. Replaced by the spinner while loading |
trailingSlot | Custom content after the text. Same rules as leadingSlot; with trailing set, this is the side the spinner takes |
Props
| Prop | Type | Default |
|---|---|---|
value | string | - |
variant | 'outline' | 'soft' | 'subtle' | 'ghost' | 'none' | 'outline' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
rows | number | 3 |
autoresize | boolean | false |
maxrows | number | 0 |
highlight | boolean | false |
loading | boolean | false |
icon | string | - |
leadingIcon | string | - |
trailingIcon | string | - |
trailing | boolean | false |
disabled | boolean | false |
placeholder | string | - |
ref | HTMLTextAreaElement | null | - |
class | string | - |
ui | Record<Slot, Class> | - |