Textarea
A taller input.
Dependencies
Source Code
"use client";
import { useEffect, useRef, useState } from "react";
import { VariantProps } from "cva";
import { cn } from "@/lib/utils";
import { composeRefs } from "@/lib/compose-refs";
import { inputStyle } from "@/components/input";
interface TextareaProps extends React.ComponentPropsWithRef<"textarea"> {
invalid?: boolean;
variant?: VariantProps<typeof inputStyle>["variant"];
}
const Textarea = ({ className, invalid, variant, ...props }: TextareaProps) => {
return (
<textarea
data-invalid={invalid}
aria-invalid={invalid}
className={cn(
inputStyle({ variant }),
"h-auto resize-none py-2 leading-snug",
className
)}
{...props}
/>
);
};
// as soon as `field-sizing: content` is supported, we can remove this component and just use the Textarea
/**
* A textarea that resizes as you type.
*/
const TextareaResize = ({ ref, ...props }: TextareaProps) => {
const internalRef = useRef<HTMLTextAreaElement>(null);
const [internalValue, setInternalValue] = useState(props.value);
const value = props.value ?? internalValue;
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setInternalValue(event.target.value);
props.onChange?.(event);
};
useEffect(() => {
if (internalRef.current) {
internalRef.current.style.height = "auto";
internalRef.current.style.height = `${internalRef.current.scrollHeight}px`;
}
}, [value]);
return (
<Textarea
ref={composeRefs(ref, internalRef)}
{...props}
value={value}
onChange={handleChange}
/>
);
};
export { Textarea, TextareaResize };
API Reference
Extends the textarea
element.
Prop | Default | Type |
---|---|---|
|
|
|
| - |
|
Examples
Default
Minimal
Disabled
Resizable
This is a cross-browser solution for resizing the textarea.
When field-sizing: content
is supported, we can remove this component and just use the Textarea.
Best Practices
-
Sizing:
- Consider initial height based on expected content
- Allow resizing when appropriate
- Maintain consistent width with other inputs
-
Accessibility:
- Provide clear labels
- Consider character/word count indicators