useAutoSizeTextArea
Hook que ajusta automaticamente a altura de uma textarea conforme seu conteúdo.
Visão Geral
O useAutoSizeTextArea é um hook que ajusta automaticamente a altura de uma <textarea> conforme seu conteúdo, evitando barras de rolagem e melhorando a usabilidade de campos de texto multi-linha.
Exemplo de Uso
import { useAutoSizeTextArea } from "@convertcompany/ui/hooks";
import { useRef, useState } from "react";
export default function Example() {
const [value, setValue] = useState("");
const textAreaRef = useRef<HTMLTextAreaElement>(null);
useAutoSizeTextArea({ textAreaRef, value });
return (
<textarea
ref={textAreaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Digite seu texto aqui..."
className="w-full p-3 border rounded-md resize-none"
/>
);
}
Parâmetros
| Propriedade | Tipo |
|---|---|
| textAreaRefReferência da textarea que será redimensionada automaticamente. | React.RefObject<HTMLTextAreaElement | null> |
| valueValor atual do campo, usado para recalcular a altura quando o conteúdo muda. | string |
Comportamento
- Ajuste automático: A altura da textarea é recalculada sempre que o
valuemuda - Altura mínima: A textarea mantém sua altura mínima inicial
- Performance: Usa
useLayoutEffectpara garantir que o ajuste aconteça antes da renderização - Sem barras de rolagem: A textarea cresce verticalmente conforme necessário
Casos de Uso
Textarea simples
import { useAutoSizeTextArea } from "@convertcompany/ui/hooks";
import { useRef, useState } from "react";
export default function SimpleTextarea() {
const [value, setValue] = useState("");
const textAreaRef = useRef<HTMLTextAreaElement>(null);
useAutoSizeTextArea({ textAreaRef, value });
return (
<textarea
ref={textAreaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Digite sua mensagem..."
className="w-full p-3 border rounded-md resize-none"
/>
);
}
Com formulário
import { useAutoSizeTextArea } from "@convertcompany/ui/hooks";
import { useRef, useState } from "react";
import { Button } from "@convertcompany/ui";
export default function FormWithTextarea() {
const [formData, setFormData] = useState({
title: "",
description: ""
});
const textAreaRef = useRef<HTMLTextAreaElement>(null);
useAutoSizeTextArea({
textAreaRef,
value: formData.description
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log("Dados do formulário:", formData);
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="title" className="block text-sm font-medium mb-2">
Título
</label>
<input
id="title"
type="text"
value={formData.title}
onChange={(e) => setFormData(prev => ({ ...prev, title: e.target.value }))}
className="w-full p-3 border rounded-md"
/>
</div>
<div>
<label htmlFor="description" className="block text-sm font-medium mb-2">
Descrição
</label>
<textarea
ref={textAreaRef}
id="description"
value={formData.description}
onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
placeholder="Digite a descrição..."
className="w-full p-3 border rounded-md resize-none"
rows={3}
/>
</div>
<Button type="submit">Enviar</Button>
</form>
);
}
Com limite de altura máxima
import { useAutoSizeTextArea } from "@convertcompany/ui/hooks";
import { useRef, useState } from "react";
export default function TextareaWithMaxHeight() {
const [value, setValue] = useState("");
const textAreaRef = useRef<HTMLTextAreaElement>(null);
useAutoSizeTextArea({ textAreaRef, value });
return (
<textarea
ref={textAreaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Digite seu texto..."
className="w-full p-3 border rounded-md resize-none max-h-32 overflow-y-auto"
style={{ minHeight: "60px" }}
/>
);
}
Considerações
- Referência obrigatória: O
textAreaRefdeve ser uma referência válida para uma<textarea> - Valor reativo: O hook reage a mudanças no
value, então certifique-se de passar o valor atual - CSS recomendado: Use
resize: nonepara evitar conflitos com o redimensionamento manual - Altura inicial: Defina uma altura inicial adequada com
rowsou CSS - Performance: O hook é otimizado para evitar re-renderizações desnecessárias
Implementação Técnica
O hook utiliza useLayoutEffect para garantir que o ajuste de altura aconteça antes da renderização visual, evitando flickering. O processo é:
- Reset da altura: Define
height: "auto"para calcular a altura natural - Cálculo da altura: Usa
scrollHeightpara obter a altura necessária - Aplicação: Define a altura calculada no elemento
useLayoutEffect(() => {
const textArea = textAreaRef.current;
if (textArea) {
textArea.style.height = "auto";
textArea.style.height = `${textArea.scrollHeight}px`;
}
}, [textAreaRef, value]);