Textarea (components/ui/textarea.tsx)¶
Overview¶
A customizable textarea component that provides multi-line text input with support for auto-resizing, character count, and validation features.
Features¶
- Auto-resize capability
- Character count
- Validation support
- Error state handling
- Placeholder text
- Disabled state
- Focus management
- Accessibility support
- Custom styling
- ARIA attributes
Dependencies¶
import * as React from 'react'
import { forwardRef } from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
Props¶
interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
error?: boolean | string;
autoResize?: boolean;
maxLength?: number;
showCount?: boolean;
className?: string;
value?: string;
onChange?: (value: string) => void;
}
Implementation¶
State Management¶
const [value, setValue] = useState(defaultValue || '');
const [isFocused, setIsFocused] = useState(false);
useEffect(() => {
if (autoResize) {
adjustHeight();
}
}, [value, autoResize]);
Methods¶
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
const newValue = event.target.value;
setValue(newValue);
onChange?.(newValue);
};
const handleFocus = () => setIsFocused(true);
const handleBlur = () => setIsFocused(false);
const adjustHeight = () => {
if (textareaRef.current) {
textareaRef.current.style.height = 'auto';
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
}
};
Unique Functionality¶
- Auto-resize handling
- Character counting
- Error state management
- Focus control
- Value management
- ARIA attributes
HTML Structure¶
<div className="relative">
<textarea
ref={textareaRef}
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
error && "border-destructive focus-visible:ring-destructive",
className
)}
value={value}
onChange={handleChange}
onFocus={handleFocus}
onBlur={handleBlur}
maxLength={maxLength}
{...props}
/>
{showCount && maxLength && (
<div className="absolute bottom-1.5 right-1.5 text-xs text-muted-foreground">
{value.length}/{maxLength}
</div>
)}
{error && typeof error === 'string' && (
<p className="mt-1 text-xs text-destructive">{error}</p>
)}
</div>
API Integration¶
No direct API integration required.
Components Used¶
No additional components used.
Notes¶
- Supports auto-resizing functionality
- Handles character count display
- Manages error states
- Provides focus management
- Maintains accessibility features
- Supports custom styling
- Uses semantic HTML elements