All hooks / Events and input

useAutosizeTextarea

474 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Grows a <textarea> to fit its text, up to maxRows lines, then scrolls. Returns a callback ref for the textarea. Set the minimum with the textarea's own rows attribute.

Resizes on typing and paste, when a controlled value changes from code (e.g. cleared after sending), and when the textarea's width changes and the text rewraps. Handles padding, borders, and box-sizing. Works the same in every browser; CSS field-sizing: content does this natively but is not supported everywhere yet.

Import

import { useAutosizeTextarea } from '@vincent.ri/react-tils'
// or only this hook
import { useAutosizeTextarea } from '@vincent.ri/react-tils/useAutosizeTextarea'

Usage

const [message, setMessage] = useState('')
const ref = useAutosizeTextarea({ maxRows: 8 })
return (
  <textarea ref={ref} rows={1} value={message} onChange={(e) => setMessage(e.target.value)} />
)

Live demo

Type several lines: it grows up to 5, then scrolls. Send clears it.

sent 0

When to use it

Chat inputs, comment boxes, or any text box that should grow with its content.

When not to

The textarea has a fixed height, or every browser you support has field-sizing: content.

API

function useAutosizeTextarea(options?: AutosizeTextareaOptions): (element: HTMLTextAreaElement | null) => void
ParameterDescription
optionsmaxRows. Optional.

Returns A callback ref. Pass it to the textarea's ref prop.

Types

export type AutosizeTextareaOptions = {
  /** Stop growing after this many lines and scroll instead. Default: no limit. */
  maxRows?: number | undefined;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
ResizeObserverWidely available64+79+69+13.1+64+13.4+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useTextareaAutosize, useAutoResize, react-textarea-autosize.