useAutosizeTextArea

Grow a textarea with its content between a minimum and maximum number of rows.

useAutosizeTextArea sets a textarea's height from its content each time the value changes, within minRows and maxRows.

Import#

typescript
import { useAutosizeTextArea } from "@reactberry/system";

Usage#

typescript
"use client";

import { useState } from "react";
import { useAutosizeTextArea } from "@reactberry/system";

export default function MessageField() {
  const [value, setValue] = useState("");
  const [textarea, setTextarea] = useState<HTMLTextAreaElement | null>(null);

  useAutosizeTextArea(textarea, value, { minRows: 1, maxRows: 6 });

  return (
    <textarea
      ref={setTextarea}
      rows={1}
      value={value}
      onChange={(event) => setValue(event.target.value)}
      style={{ resize: "none", overflowY: "auto" }}
    />
  );
}

Examples#

Row limits#

Set minRows and maxRows to keep the field between a fixed number of rows. Past maxRows, the content scrolls.

Between 3 and 5 rows. Longer notes scroll.

API#

typescript
function useAutosizeTextArea(
  textareaRef: HTMLTextAreaElement | null,
  value: string,
  options?: { minRows?: number; maxRows?: number },
): void

Parameters#

PropTypeDefaultDescription
textareaRef*
HTMLTextAreaElement | null
—

The element itself, not a ref object. Use a callback ref stored in state, as above, so the hook runs once the element exists.

value*
string
—

The current text. The height is recalculated when it changes.

options.minRows
number
1

Minimum number of rows.

options.maxRows
number
10

Maximum number of rows.

Returns#

Nothing (void). The hook sets style.height on the textarea directly.

Notes#

  • Row height comes from the computed line-height. When it is normal, the hook uses 1.5 × font-size.
  • Padding and border are included in the height for box-sizing: border-box.
  • Above maxRows the height stops growing; set overflow-y: auto so the extra content can scroll.