UIUpdated May 11, 2026

Textarea

Multi-line text input for product forms, feedback, notes, and longer user-generated content in PyColors UI.

UITextarea

Multi-line input for longer user intentLink to section

The Textarea component captures longer text than a standard Input.

Use it for:

  • feedback messages
  • support requests
  • product descriptions
  • notes
  • prompts
  • comments
  • longer form fields

Textarea follows the same field model as Input: label, helper text, error state, generated id, and accessible descriptions.

Core idea

Use Textarea when the user needs space to express intent, context, or explanation.

ImportLink to section

textarea-import.tsx
import { Textarea } from "@pycolors/ui";

Basic usageLink to section

Use a label to make the field clear and accessible.

basic-textarea.tsx
import { Textarea } from "@pycolors/ui";

export function BasicTextarea() {
  return (
    <Textarea
      label="Message"
      placeholder="Tell us what you are building..."
    />
  );
}

Label rule

Prefer a visible label. Use placeholder text for examples, not as the only field description.

When to use TextareaLink to section

Use Textarea when one line is not enough for the task.

Feedback

Capture user feedback, support details, and product requests.

Descriptions

Let users describe projects, products, workspaces, or templates.

Notes

Store internal notes, onboarding context, or review comments.

Helper textLink to section

Use helper text to explain what kind of answer is expected.

Describe the product, target users, and current constraints.

textarea-helper-text.tsx
import { Textarea } from "@pycolors/ui";

export function TextareaHelperText() {
  return (
    <Textarea
      label="Project description"
      helperText="Describe the product, target users, and current constraints."
      placeholder="A SaaS starter for founders who want to ship faster..."
    />
  );
}

Helper text rule

Helper text should reduce uncertainty. Keep it short, concrete, and connected to the task.

Error stateLink to section

Use the error prop for validation errors. It automatically sets aria-invalid, aria-errormessage, and error styling.

Launch notes must contain at least 20 characters.

textarea-error.tsx
import { Textarea } from "@pycolors/ui";

export function TextareaError() {
  return (
    <Textarea
      label="Launch notes"
      placeholder="Summarize the release..."
      error="Launch notes must contain at least 20 characters."
    />
  );
}

Validation rule

Error text should explain what failed and how to fix it. Avoid vague messages like “Invalid value”.

Required fieldsLink to section

Use required for mandatory fields. The label displays a destructive asterisk and the textarea receives aria-required.

Include the page, expected behavior, and what happened.

textarea-required.tsx
import { Textarea } from "@pycolors/ui";

export function TextareaRequired() {
  return (
    <Textarea
      required
      label="Support request"
      helperText="Include the page, expected behavior, and what happened."
      placeholder="I expected..."
    />
  );
}

SizesLink to section

Textarea supports three design-system sizes: sm, md, and lg.

textarea-sizes.tsx
import { Textarea } from "@pycolors/ui";

export function TextareaSizes() {
  return (
    <div className="grid gap-4">
      <Textarea
        size="sm"
        label="Small"
        placeholder="Compact notes..."
      />

      <Textarea
        size="md"
        label="Medium"
        placeholder="Default textarea..."
      />

      <Textarea
        size="lg"
        label="Large"
        placeholder="Longer product description..."
      />
    </div>
  );
}

Size guidanceLink to section

SizeBest for
smCompact notes, admin tables, dense forms
mdDefault forms and settings pages
lgLong descriptions, prompts, support messages

Resize behaviorLink to section

The resize prop controls how users can resize the field.

textarea-resize.tsx
import { Textarea } from "@pycolors/ui";

export function TextareaResize() {
  return (
    <div className="grid gap-4">
      <Textarea
        label="Vertical resize"
        resize="vertical"
        placeholder="Default behavior..."
      />

      <Textarea
        label="No resize"
        resize="none"
        placeholder="Fixed textarea..."
      />
    </div>
  );
}

Available resize optionsLink to section

ResizeBehavior
verticalUser can resize height
noneFixed size
horizontalUser can resize width
bothUser can resize width and height

Resize rule

Prefer vertical for most product forms. Avoid horizontal resize in constrained layouts.

Feedback formLink to section

Send feedback

Tell us what would make PyColors more useful.

Share the problem, context, and expected improvement.

feedback-form.tsx
import { Button, Textarea } from "@pycolors/ui";

export function FeedbackForm() {
  return (
    <div className="rounded-2xl border border-border/60 bg-card p-5">
      <div className="mb-4">
        <div className="text-sm font-medium text-foreground">
          Send feedback
        </div>
        <div className="mt-1 text-sm text-muted-foreground">
          Tell us what would make PyColors more useful.
        </div>
      </div>

      <Textarea
        label="Feedback"
        helperText="Share the problem, context, and expected improvement."
        placeholder="I would like..."
      />

      <div className="mt-4 flex justify-end">
        <Button>Send feedback</Button>
      </div>
    </div>
  );
}

Prompt fieldLink to section

Be specific about the audience, output format, and constraints.

prompt-textarea.tsx
import { Textarea } from "@pycolors/ui";

export function PromptTextarea() {
  return (
    <div className="rounded-2xl border border-border/60 bg-card p-5">
      <Textarea
        size="lg"
        resize="vertical"
        label="AI prompt"
        helperText="Be specific about the audience, output format, and constraints."
        placeholder="Generate a premium SaaS landing page section for..."
      />
    </div>
  );
}

Usage patternsLink to section

Use Textarea for longer answers

Use Input for short values. Use Textarea when the user needs to provide context, explanation, or multi-line content.

Keep labels explicit

The label should describe the content expected from the user, not the UI element itself.

Add helper text for complex fields

Use helper text when the field needs examples, constraints, or formatting guidance.

Validate with actionable errors

Error messages should explain what to change, not just that the value is invalid.

Choose resize intentionally

Use vertical resize for flexible content. Use no resize for controlled surfaces like sheets and compact cards.

Textarea vs InputLink to section

SituationUse
Name, email, URL, slugInput
Search queryInput
Short titleInput
Feedback messageTextarea
Product descriptionTextarea
Notes or commentsTextarea
AI promptTextarea

Decision rule

If the expected answer can fit naturally on one line, use Input. If the user needs to explain something, use Textarea.

APILink to section

PropTypeDefaultDescription
labelstringAccessible label displayed above the textarea
helperTextstringSupporting text shown when there is no error
errorstringError text and validation styling
size"sm" | "md" | "lg""md"Design-system size
resize"none" | "vertical" | horizontal" | "both""vertical"Native resize behavior
classNamestringAdditional Tailwind classes
...propsReact.TextareaHTMLAttributes<HTMLTextAreaElement>Native textarea attributes

TypeScript typesLink to section

textarea-types.ts
export type TextareaSize = "sm" | "md" | "lg";
export type TextareaResize = "none" | "vertical" | "horizontal" | "both";

export interface TextareaProps
  extends Omit<
      React.TextareaHTMLAttributes<HTMLTextAreaElement>,
      "size"
    >,
    VariantProps<typeof textareaVariants> {
  label?: string;
  helperText?: string;
  error?: string;
  size?: TextareaSize;
  resize?: TextareaResize;
}

AccessibilityLink to section

  • label is connected to the textarea with htmlFor.
  • A stable id is generated with React.useId when no id is provided.
  • helperText is connected with aria-describedby.
  • error is connected with aria-errormessage.
  • error sets aria-invalid.
  • required sets aria-required.
  • Do not rely on placeholder text as the only accessible description.

Accessibility rule

Every textarea should have a clear label. Helper text and error text should clarify the task, not replace the label.

Prefer / avoidLink to section

Prefer

  • visible labels
  • clear helper text for complex inputs
  • specific and actionable errors
  • vertical resize for longer content
  • textarea for explanation-heavy fields

Avoid

  • placeholder-only labels
  • vague errors like “Invalid value”
  • horizontal resize in responsive layouts
  • using textarea for short one-line values
  • asking for too much text without guidance

Common questionsLink to section