Skip to content
Praesepe UI

forms

Textarea

Multi-line form control with rows or autosize, optional character counter, label, hint, error, and attribute forwarding.

Copied!

Examples

Basic textarea

Label, hint, and rows-based sizing.

Copied!

Keep it short and specific.

<x-ui.textarea
    name="bio"
    label="Bio"
    hint="Keep it short and specific."
    placeholder="Tell us about your product"
    rows="4"
    class="max-w-lg"
/>
<div class="w-full max-w-lg">
    <label for="bio-basic" class="mb-1.5 block text-sm font-medium text-fg">Bio</label>
    <textarea
        id="bio-basic"
        name="bio"
        rows="4"
        placeholder="Tell us about your product"
        aria-describedby="bio-basic-hint"
        class="min-h-24 w-full resize-y rounded-control border border-border bg-surface-raised px-3 py-2 text-sm text-fg shadow-sm placeholder:text-fg-subtle focus:border-border-strong"
    ></textarea>
    <p id="bio-basic-hint" class="mt-1.5 text-xs text-fg-muted">Keep it short and specific.</p>
</div>

Character counter

Live count / max linked through aria-describedby.

Copied!

0 / 120

<x-ui.textarea
    name="summary"
    label="Summary"
    maxlength="120"
    rows="3"
    class="max-w-lg"
/>
<div class="w-full max-w-lg" x-data="{ count: 0, max: 120 }">
    <label for="summary-counter" class="mb-1.5 block text-sm font-medium text-fg">Summary</label>
    <textarea
        id="summary-counter"
        name="summary"
        rows="3"
        maxlength="120"
        aria-describedby="summary-counter-counter"
        class="min-h-24 w-full resize-y rounded-control border border-border bg-surface-raised px-3 py-2 text-sm text-fg shadow-sm focus:border-border-strong"
        x-on:input="count = $event.target.value.length"
    ></textarea>
    <p id="summary-counter-counter" class="mt-1.5 text-right text-xs text-fg-subtle" aria-live="polite">
        <span x-text="count">0</span> / 120
    </p>
</div>

Validation error

Error text with aria-invalid.

Copied!

Please add at least 20 characters.

<x-ui.textarea
    name="notes"
    label="Notes"
    value="Too short"
    error="Please add at least 20 characters."
    rows="3"
    class="max-w-lg"
/>
<div class="w-full max-w-lg">
    <label for="notes-error" class="mb-1.5 block text-sm font-medium text-fg">Notes</label>
    <textarea
        id="notes-error"
        name="notes"
        rows="3"
        aria-invalid="true"
        aria-describedby="notes-error-error"
        class="min-h-24 w-full resize-y rounded-control border border-danger bg-surface-raised px-3 py-2 text-sm text-fg shadow-sm"
    >Too short</textarea>
    <p id="notes-error-error" class="mt-1.5 text-xs text-danger">Please add at least 20 characters.</p>
</div>

Props API

Component props
Prop Type Default Description
label string|null null Visible label linked via for/id.
hint string|null null Helper text referenced by aria-describedby.
error string|null null Validation message. Sets aria-invalid and contributes to aria-describedby.
rows int 4 Initial visible row count for the native textarea.
maxlength int|null null When set, shows a live count / max counter linked via aria-describedby.
autosize bool false Grow height to fit content via Alpine on input.

Accessibility notes

Architected with WCAG 2.2 AA patterns in mind. These notes document the exact keyboard and ARIA behavior for this component.

  • Label for, textarea id, hint, error, and optional counter ids are wired through aria-describedby.
  • Error state sets aria-invalid="true" on the textarea.
  • Character counter uses aria-live="polite" so assistive tech hears count updates without stealing focus.
  • Pass-through attributes (name, required, disabled, readonly, placeholder, x-model, wire:model) land on the textarea.
  • Keyboard: Tab focuses the control. Standard text editing keys apply.

Built by Praesepe

Architecture & custom software partner

Praesepe uses these exact UI primitives to ship SME dashboards, inventory systems, invoicing desks, and internal tools faster, without rebuilding a design system for every client.

  • Same Blade + Tailwind 4 + Alpine 3 stack you see in this docs site
  • Opinionated for Indonesian SME ops: invoices, stock, roles, approvals
  • Architected with WCAG 2.2 AA patterns in mind for keyboard and ARIA

Talk to the studio

WhatsApp: TODO Email the studio Visit Praesepe