An autogrowing textarea is a textarea element that automatically adjusts its height to the number of lines the user entered.
Here is a textarea component written for React that automatically adjusts its height no matter if it's controlled or uncontrolled.
Usage
JS
<Textarea autoHeight rows={4} />
Implementation
TS
interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {autoHeight?: boolean}function Textarea({value: valueFromProps,onChange: onChangeFromProps,defaultValue,autoHeight = false,rows: rowsFromProps = 3,...rest}: TextareaProps) {// Determine if component is used in a controlled or uncontrolled// fashion.const isControlled = typeof valueFromProps != 'undefined'const hasDefaultValue = typeof defaultValue != 'undefined'const [internalValue, setInternalValue] = useState(hasDefaultValue ? defaultValue : '')// If component is controlled, take the value from the props,// otherwise take it from the value we track ourselves.const value = isControlled ? valueFromProps : internalValue// The rows attribute is what will determine the height of our// textarea. Notice how we only automatically determine the// rows attribute if props.autoHeight is true. In this case// we also use props.rows to set the minimum number of rows.const rows = autoHeight ? Math.max(rowsFromProps, String(value).split('\n').length) : rowsFromProps// This a custom onChange handler that reports any changes// to props.onChange and also updates our internal value// in case the component is uncontrolled.const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>((e) => {if (onChangeFromProps) {onChangeFromProps(e)}if (!isControlled) {setInternalValue(e.target.value)}},[isControlled, onChangeFromProps])return <textarea rows={rows} value={value} onChange={onChange} {...rest} />}
View the demo on CodeSandbox.