ComponentsTextarea
Textarea
Collect several lines of text, such as a message or description.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import { Textarea } from "@dethink/components";Try the examples, then open the code to use them in your app.
With Field anatomy
Label and helper description wired through Field.
What should the next release improve?
Show sourceexamples/textarea/basic.tsx
"use client";
import {
Field,
FieldContent,
FieldControl,
FieldDescription,
FieldLabel,
Textarea,
} from "@dethink/components";
export function TextareaBasic() {
return (
<div className="mx-auto max-w-sm">
<Field id="ta-feedback">
<FieldContent>
<FieldLabel>Feedback</FieldLabel>
<FieldDescription>
What should the next release improve?
</FieldDescription>
</FieldContent>
<FieldControl asChild>
<Textarea name="feedback" rows={4} placeholder="Tell us anything…" />
</FieldControl>
</Field>
</div>
);
}States, sizes, and resize
Sizes, disabled, invalid, read-only, and resize=none.
Show sourceexamples/textarea/states.tsx
"use client";
import { Textarea } from "@dethink/components";
export function TextareaStates() {
return (
<div className="mx-auto grid max-w-lg gap-4 sm:grid-cols-2">
<Textarea
aria-label="Small"
controlSize="sm"
rows={2}
placeholder="Small"
/>
<Textarea
aria-label="Large"
controlSize="lg"
rows={2}
placeholder="Large"
/>
<Textarea
aria-label="Disabled"
disabled
rows={2}
defaultValue="Disabled content"
/>
<Textarea
aria-label="Invalid"
invalid
rows={2}
defaultValue="Too short"
/>
<Textarea
aria-label="No resize"
resize="none"
rows={2}
placeholder="resize=none"
/>
<Textarea
aria-label="Read-only"
readOnly
rows={2}
defaultValue="Read-only content"
/>
</div>
);
}Examples that combine components for common tasks.
Composer with character budget
The counter shifts from quiet meter to warning to error as the budget runs out, the field flips to invalid past the limit, and a live region keeps assistive tech in sync with the count.
Show sourceexamples/textarea/recipe-composer.tsx
"use client";
import { useState } from "react";
import {
Button,
Field,
FieldControl,
FieldError,
FieldLabel,
Textarea,
} from "@dethink/components";
const LIMIT = 240;
/**
* A social-style composer: the counter turns from quiet meter into an error
* as the budget runs out, and the field flips to invalid past the limit so
* assistive tech hears the same thing sighted users see.
*/
export function TextareaRecipeComposer() {
const [text, setText] = useState("");
const remaining = LIMIT - text.length;
const overBudget = remaining < 0;
return (
<form
className="mx-auto max-w-sm space-y-3"
onSubmit={(event) => event.preventDefault()}
>
<Field id="composer" invalid={overBudget}>
<FieldLabel>Share an update</FieldLabel>
<FieldControl asChild>
<Textarea
rows={4}
resize="none"
value={text}
onChange={(event) => setText(event.target.value)}
placeholder="What are you shipping this week?"
/>
</FieldControl>
{overBudget ? (
<FieldError>
Update is {-remaining} characters over the limit.
</FieldError>
) : null}
</Field>
<div className="flex items-center justify-between">
<p
aria-live="polite"
className={`text-sm tabular-nums ${
overBudget
? "text-destructive font-medium"
: remaining <= 40
? "text-warning"
: "text-muted-foreground"
}`}
>
{remaining} left
</p>
<Button size="sm" disabled={overBudget || text.length === 0}>
Post update
</Button>
</div>
</form>
);
}Textarea renders a real textarea element, so all native attributes apply.
| Prop | What it does | Default |
|---|---|---|
controlSize"sm" | "md" | "lg" | Sets the padding and text size to match Input. | "md" |
invalidboolean | Shows an error style and marks the field as invalid for screen readers. | false |
resize"none" | "vertical" | "horizontal" | "both" | Sets whether users can resize the field vertically, horizontally, both, or neither. | "vertical" |
…native textarea propsTextareaHTMLAttributes | Renders a real <textarea>: rows, name, disabled, readOnly, required, maxLength, and form behavior are native. | Not set |