Components

Textarea

A form textarea that auto-grows to fit its content, with optional rows and a max-rows cap.

php artisan blatui:add textarea
<div class="w-full max-w-sm">
    <x-ui.textarea placeholder="Type your message here." />
</div>

Autosize

Starts at two rows and grows to six before it scrolls.

{{-- Set maxRows to auto-grow with the content, then scroll once it hits the cap. --}}
<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="autosize-message">Your message</x-ui.label>
    <x-ui.textarea
        id="autosize-message"
        name="message"
        :rows="2"
        :max-rows="6"
        placeholder="Grows up to 6 rows as you type, then scrolls…"
    />
    <p class="text-muted-foreground text-sm">Starts at two rows and grows to six before it scrolls.</p>
</div>

Character Count

characters left

{{-- Live "characters left" counter backed by maxlength. --}}
<div x-data="{ text: '', max: 200 }" class="w-full max-w-md space-y-2">
    <x-ui.label for="ta-feedback">Your feedback</x-ui.label>
    <x-ui.textarea
        id="ta-feedback"
        x-model="text"
        maxlength="200"
        placeholder="Leave us some feedback…"
        aria-describedby="ta-count"
    />
    <p id="ta-count" class="text-muted-foreground text-right text-xs">
        <span x-text="max - text.length"></span> characters left
    </p>
</div>

Disabled

<div class="w-full max-w-sm">
    <x-ui.textarea placeholder="Type your message here." disabled />
</div>

Invalid

<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="bio-invalid">Bio</x-ui.label>
    <x-ui.textarea id="bio-invalid" aria-invalid="true" aria-describedby="bio-invalid-hint" placeholder="Tell us a little about yourself" />
    <p id="bio-invalid-hint" role="alert" class="text-destructive text-sm">Bio must be at least 10 characters.</p>
</div>

No Resize

{{-- Lock the manual resize handle with resize-none. --}}
<x-ui.textarea class="w-full max-w-md resize-none" placeholder="This textarea can't be resized." />

Read Only

{{-- A non-editable textarea. --}}
<x-ui.textarea readonly aria-label="Read-only content" class="bg-muted w-full max-w-md">The quick brown fox jumps over the lazy dog. This content is read-only and cannot be edited.</x-ui.textarea>

Sizes

{{-- size sets the min-height, padding and text size: sm · default · lg. --}}
<div class="grid w-full max-w-sm gap-4">
    <x-ui.textarea size="sm" placeholder="Small" />
    <x-ui.textarea placeholder="Default" />
    <x-ui.textarea size="lg" placeholder="Large" />
</div>

Utility Class

{{-- Raw <textarea> styled by the .blat-textarea foundations utility — native submit, no JS, and
     safe to nest inside another anonymous component's slot (no nested slot-component to compile). --}}
<textarea class="blat-textarea w-full max-w-sm" rows="3" placeholder="Your message…"></textarea>

With Button

<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="ta-send">Your message</x-ui.label>
    <x-ui.textarea id="ta-send" placeholder="Type your message here." />
    <x-ui.button class="w-fit">Send message</x-ui.button>
</div>

With Color

{{-- color brands the focus ring and text selection locally — focus the field to see it. --}}
<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="colored-note">Note</x-ui.label>
    <x-ui.textarea id="colored-note" color="#7c3aed" placeholder="Focus me to see the violet ring." />
</div>

With Label

<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="message">Your message</x-ui.label>
    <x-ui.textarea id="message" placeholder="Type your message here." />
</div>

With Text

Your message will be shared with the support team.

<div class="grid w-full max-w-sm gap-2">
    <x-ui.label for="ta-feedback">Your message</x-ui.label>
    <x-ui.textarea id="ta-feedback" placeholder="Type your message here." />
    <p class="text-muted-foreground text-sm">Your message will be shared with the support team.</p>
</div>

Using with Livewire

wire:model

The examples above are the frontend (Blade + Alpine) usage. Inside a Livewire component, bind wire:model for two-way state — same component, no wrappers. Full Livewire guide →

app/Livewire/Demo.php
use Livewire\Component;

class Demo extends Component
{
    public string $bio = '';

    public function render()
    {
        return view('livewire.demo');
    }
}
resources/views/livewire/demo.blade.php
<x-ui.textarea wire:model="bio" placeholder="About you" />

API Reference

Props, slots and exposed methods for <x-ui.textarea>.

Props

Prop Type Default Description
size string 'default' Minimum height, padding and text size of the field.
sm default lg
color string — CSS color that brands the focus ring and text selection locally, overriding the default ring/primary tokens.
rows int — Initial number of visible text rows (the native rows attribute). Unset uses the size-based min-height.
maxRows int — Caps auto-growth at this many rows, then scrolls. When set, the field switches from native field-sizing-content auto-grow to an Alpine-driven height that shrinks and grows with the content. Unlimited (native auto-grow) when not set.

Slots

Slot Description
default Initial text content rendered inside the textarea.