Skip to content

Textarea

A multi-line text input for comments, bios, and support messages — with the neobrutalist borders-and-shadows treatment.

import { Textarea } from "@/components/ui/textarea"

export function TextareaDemo() {

The textarea is a multi-line text input. It's a styled native <textarea> element — no wrapper library on either backend — that auto-grows with its content via CSS field-sizing: content, dressed in the neobrutalist recipe: thick borders, hard shadows, and bold type.

Reach for it when:

  • Comments and replies — freeform responses on posts, reviews, and tickets.
  • Bios and descriptions — profile bios, product descriptions, settings-form blurbs.
  • Feedback and support forms — bug reports and contact messages, anything longer than one line.

Installation

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/textarea.json
npx shadcn@latest add https://neobrutalism.com/r/base/textarea.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/textarea.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/textarea.json

Copy and paste the following code into your project.

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 border-2 bg-input px-3 py-2 text-sm shadow-sm transition-colors outline-none placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive",
        className
      )}
      {...props}
    />
  )
}

export { Textarea }

Update the import paths to match your project setup.

Usage

import { Textarea } from "@/components/ui/textarea"
<Textarea />

Examples

Field

Use Field, FieldLabel, and FieldDescription to create a textarea with a label and description.

import {
  Field,
  FieldDescription,

Disabled

Use the disabled prop to disable the textarea. To style the disabled state, add the data-disabled attribute to the Field component.

import { Field, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"

Invalid

Use the aria-invalid prop to mark the textarea as invalid. To style the invalid state, add the data-invalid attribute to the Field component.

import {
  Field,
  FieldDescription,

Button

Pair with Button to create a textarea with a submit button.

import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"

RTL

To enable RTL support in Neobrutalism.com, see the RTL configuration guide.

"use client"

import * as React from "react"

Accessibility

As a native form control, the textarea gets keyboard access for free — Tab focuses it, Enter inserts a newline rather than submitting the form — so no ARIA pattern applies. Always pair it with a visible label: FieldLabel handles the htmlFor wiring, as shown in the Field example. For validation, set aria-invalid on the textarea and reference the error message with aria-describedby so screen readers announce both.