TextArea

The TextArea component provides a multi-line text input with support for auto-resizing, character counting, validation states, and flexible sizing options.

Basics

A controlled TextArea with a label and description; rows sets how many lines it shows before scrolling.

Loading demo…

import { useState } from 'react'; import { Block, TextArea } from '@plocks/ui'; export function Demo() { const [value, setValue] = useState(''); return ( <Block fullWidth> <TextArea label="Message" placeholder="Enter your message" value={value} onChangeText={setValue} description="Provide helpful context for your request." rows={4} fullWidth /> </Block> ); }

Features

Showcases auto-resize, character counting, validation, disabled, and required helper scenarios.

Loading demo…

import { useState } from 'react'; import { Block, TextArea } from '@plocks/ui'; export function Demo() { const [autoResizeValue, setAutoResizeValue] = useState( 'Type more text to see auto-resize in action...\n\nAdd multiple lines to watch the text area grow and shrink with content.' ); const [counterValue, setCounterValue] = useState(''); const [errorValue, setErrorValue] = useState(''); return ( <Block fullWidth> <TextArea label="Auto-resize message" placeholder="Adjusts height between two and six rows based on content." value={autoResizeValue} onChangeText={setAutoResizeValue} autoResize minRows={2} maxRows={6} fullWidth /> <TextArea label="Support message" placeholder="Type to see the counter (max 100 characters)" value={counterValue} onChangeText={setCounterValue} maxLength={100} showCharCounter rows={3} fullWidth /> <TextArea label="Required response" placeholder="This field cannot be empty" value={errorValue} onChangeText={setErrorValue} error={errorValue.length > 0 ? undefined : 'A response is required before submission.'} required rows={3} fullWidth /> <TextArea label="Disabled text area" placeholder="Disabled state" value="This text area is disabled and cannot be edited." disabled rows={2} fullWidth /> <TextArea label="Required with helper" placeholder="Add details" required rows={2} helperText="Required fields display an asterisk and supporting guidance." fullWidth /> </Block> ); }

Variants

Compare the default, filled, outline, and unstyled field shells on TextArea.

Loading demo…

import { Column, TextArea } from '@plocks/ui'; const variants = ['default', 'filled', 'outline', 'unstyled'] as const; export function Demo() { return ( <Column gap="md" fullWidth> {variants.map(variant => ( <TextArea key={variant} variant={variant} label={`${variant} variant`} placeholder="Write a note" rows={2} /> ))} </Column> ); }

Sizes

Walks the full size scale, xs through 3xl, so the field matches the surrounding form density.

Loading demo…

import { Block, Text, TextArea } from '@plocks/ui'; const SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] as const; export function Demo() { return ( <Block fullWidth> {SIZES.map((size) => ( <Block key={size} fullWidth> <Text variant="small" c="secondary">{size}</Text> <TextArea size={size} rows={3} placeholder="Write a message" fullWidth /> </Block> ))} </Block> ); }

Validation

Validate on submit and pass the message to error: it replaces the helperText and marks the field invalid until the user edits it again.

Loading demo…

import { useState } from 'react'; import { Block, Button, TextArea } from '@plocks/ui'; export function Demo() { const [feedback, setFeedback] = useState(''); const [error, setError] = useState<string>(); const handleSubmit = () => { if (!feedback.trim()) { setError('Feedback is required.'); } else if (feedback.trim().length < 10) { setError('Feedback must be at least 10 characters.'); } }; return ( <Block fullWidth> <TextArea label="Feedback" placeholder="Share your thoughts (minimum 10 characters)" value={feedback} onChangeText={(value) => { setFeedback(value); setError(undefined); }} error={error} required rows={4} helperText="Tell us what went well and what could improve." fullWidth /> <Button variant="filled" onPress={handleSubmit}> Submit feedback </Button> </Block> ); }
Scan to open this page on your phoneplocks.dev/ui/TextArea