Skip to contentVibraUI
Inputs & filters

Textarea

A multi-line text field that grows with what is typed into it.

Vibra puts the field on the card plane with its --input boundary in both modes, focuses it with the kit's solid 2px accent outline instead of a translucent ring, and goes to the muted plane when disabled — the same treatment as Input. It sizes to its content (field-sizing) from a 64px floor.

Install

npx shadcn@latest add @vibra/textarea

Needs the @vibra registry in your components.json — set it up once.

Examples

Grows, then scrolls

It grows with its text up to about six lines, then scrolls inside itself instead of pushing the page down.

Count inside the field

The count sits on the field's lower edge. Going over is allowed and said in words; a screen reader hears it when typing pauses.

Required, with an error

"Required" is a word in the label. Sending too little moves the focus to the field, which carries aria-invalid and the reason.

Read-only, with a reason

A sent invoice's memo: readable, selectable and in the Tab order, with a note saying why it is locked and what to do instead.

One entry per line

A list typed one per line in the code face, with spelling checks off, a count, and a bad line named by its number.

Insertable fields

A template's fields go in at the caret, and the focus comes back with the caret after what was inserted.

With a toolbar

Named tools on the field's lower edge, inside one boundary, with the author's face beside it. Enter starts a line; the button posts.

Saves as you type

No button: the draft saves when typing pauses, and one polite status line says where it stands.

Right to left

An Arabic reply with its count at the inline end of the field's lower edge.

Dependencies

Registry

Source

components/ui/textarea.tsx
import * as React from "react"
import { cn } from "@/lib/utils"

function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
  return (
    <textarea
      data-slot="textarea"
      className={cn(
        "flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-card px-2.5 py-2 text-base transition-colors focus-ring placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-muted disabled:opacity-50 aria-invalid:border-destructive md:text-sm",
        className
      )}
      {...props}
    />
  )
}

export { Textarea }